/home/lnzliplg/www/include.tar
apr-1/apr_rmm.h000064400000011252151730340470007277 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_RMM_H
#define APR_RMM_H
/** 
 * @file apr_rmm.h
 * @brief APR-UTIL Relocatable Memory Management Routines
 */
/**
 * @defgroup APR_Util_RMM Relocatable Memory Management Routines
 * @ingroup APR_Util
 * @{
 */

#include "apr.h"
#include "apr_pools.h"
#include "apr_errno.h"
#include "apu.h"
#include "apr_anylock.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/** Structure to access Relocatable, Managed Memory */
typedef struct apr_rmm_t apr_rmm_t;

/** Fundamental allocation unit, within a specific apr_rmm_t */
typedef apr_size_t   apr_rmm_off_t;

/**
 * Initialize a relocatable memory block to be managed by the apr_rmm API.
 * @param rmm The relocatable memory block
 * @param lock An apr_anylock_t of the appropriate type of lock, or NULL
 *             if no locking is required.
 * @param membuf The block of relocatable memory to be managed
 * @param memsize The size of relocatable memory block to be managed
 * @param cont The pool to use for local storage and management
 * @remark Both @param membuf and @param memsize must be aligned
 * (for instance using APR_ALIGN_DEFAULT).
 */
APU_DECLARE(apr_status_t) apr_rmm_init(apr_rmm_t **rmm, apr_anylock_t *lock,
                                       void *membuf, apr_size_t memsize, 
                                       apr_pool_t *cont);

/**
 * Destroy a managed memory block.
 * @param rmm The relocatable memory block to destroy
 */
APU_DECLARE(apr_status_t) apr_rmm_destroy(apr_rmm_t *rmm);

/**
 * Attach to a relocatable memory block already managed by the apr_rmm API.
 * @param rmm The relocatable memory block
 * @param lock An apr_anylock_t of the appropriate type of lock
 * @param membuf The block of relocatable memory already under management
 * @param cont The pool to use for local storage and management
 */
APU_DECLARE(apr_status_t) apr_rmm_attach(apr_rmm_t **rmm, apr_anylock_t *lock,
                                         void *membuf, apr_pool_t *cont);

/**
 * Detach from the managed block of memory.
 * @param rmm The relocatable memory block to detach from
 */
APU_DECLARE(apr_status_t) apr_rmm_detach(apr_rmm_t *rmm);

/**
 * Allocate memory from the block of relocatable memory.
 * @param rmm The relocatable memory block
 * @param reqsize How much memory to allocate
 */
APU_DECLARE(apr_rmm_off_t) apr_rmm_malloc(apr_rmm_t *rmm, apr_size_t reqsize);

/**
 * Realloc memory from the block of relocatable memory.
 * @param rmm The relocatable memory block
 * @param entity The memory allocation to realloc
 * @param reqsize The new size
 */
APU_DECLARE(apr_rmm_off_t) apr_rmm_realloc(apr_rmm_t *rmm, void *entity, apr_size_t reqsize);

/**
 * Allocate memory from the block of relocatable memory and initialize it to zero.
 * @param rmm The relocatable memory block
 * @param reqsize How much memory to allocate
 */
APU_DECLARE(apr_rmm_off_t) apr_rmm_calloc(apr_rmm_t *rmm, apr_size_t reqsize);

/**
 * Free allocation returned by apr_rmm_malloc or apr_rmm_calloc.
 * @param rmm The relocatable memory block
 * @param entity The memory allocation to free
 */
APU_DECLARE(apr_status_t) apr_rmm_free(apr_rmm_t *rmm, apr_rmm_off_t entity);

/**
 * Retrieve the physical address of a relocatable allocation of memory
 * @param rmm The relocatable memory block
 * @param entity The memory allocation to free
 * @return address The address, aligned with APR_ALIGN_DEFAULT.
 */
APU_DECLARE(void *) apr_rmm_addr_get(apr_rmm_t *rmm, apr_rmm_off_t entity);

/**
 * Compute the offset of a relocatable allocation of memory
 * @param rmm The relocatable memory block
 * @param entity The physical address to convert to an offset
 */
APU_DECLARE(apr_rmm_off_t) apr_rmm_offset_get(apr_rmm_t *rmm, void *entity);

/**
 * Compute the required overallocation of memory needed to fit n allocs
 * @param n The number of alloc/calloc regions desired
 */
APU_DECLARE(apr_size_t) apr_rmm_overhead_get(int n);

#ifdef __cplusplus
}
#endif
/** @} */
#endif  /* ! APR_RMM_H */

apr-1/apr_memcache.h000064400000041510151730340470010246 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_MEMCACHE_H
#define APR_MEMCACHE_H

/**
 * @file apr_memcache.h
 * @brief Client interface for memcached
 * @remark To use this interface you must have a separate memcached
 * server running. See the memcached website at http://www.danga.com/memcached/
 * for more information.
 */

#include "apr.h"
#include "apr_pools.h"
#include "apr_time.h"
#include "apr_strings.h"
#include "apr_network_io.h"
#include "apr_ring.h"
#include "apr_buckets.h"
#include "apr_reslist.h"
#include "apr_hash.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @defgroup APR_Util_MC Memcached Client Routines
 * @ingroup APR_Util
 * @{
 */

/** Specifies the status of a memcached server */
typedef enum
{
    APR_MC_SERVER_LIVE, /**< Server is alive and responding to requests */
    APR_MC_SERVER_DEAD  /**< Server is not responding to requests */
} apr_memcache_server_status_t;

/** Opaque memcache client connection object */
typedef struct apr_memcache_conn_t apr_memcache_conn_t;

/** Memcache Server Info Object */
typedef struct apr_memcache_server_t apr_memcache_server_t;
struct apr_memcache_server_t
{
    const char *host; /**< Hostname of this Server */
    apr_port_t port; /**< Port of this Server */
    apr_memcache_server_status_t status; /**< @see apr_memcache_server_status_t */
#if APR_HAS_THREADS || defined(DOXYGEN)
    apr_reslist_t *conns; /**< Resource list of actual client connections */
#else
    apr_memcache_conn_t *conn;
#endif
    apr_pool_t *p; /** Pool to use for private allocations */
#if APR_HAS_THREADS
    apr_thread_mutex_t *lock;
#endif
    apr_time_t btime;
};

/* Custom hash callback function prototype, user for server selection.
* @param baton user selected baton
* @param data data to hash
* @param data_len length of data
*/
typedef apr_uint32_t (*apr_memcache_hash_func)(void *baton,
                                               const char *data,
                                               const apr_size_t data_len);

typedef struct apr_memcache_t apr_memcache_t;

/* Custom Server Select callback function prototype.
* @param baton user selected baton
* @param mc memcache instance, use mc->live_servers to select a node
* @param hash hash of the selected key.
*/
typedef apr_memcache_server_t* (*apr_memcache_server_func)(void *baton,
                                                 apr_memcache_t *mc,
                                                 const apr_uint32_t hash);

/** Container for a set of memcached servers */
struct apr_memcache_t
{
    apr_uint32_t flags; /**< Flags, Not currently used */
    apr_uint16_t nalloc; /**< Number of Servers Allocated */
    apr_uint16_t ntotal; /**< Number of Servers Added */
    apr_memcache_server_t **live_servers; /**< Array of Servers */
    apr_pool_t *p; /** Pool to use for allocations */
    void *hash_baton;
    apr_memcache_hash_func hash_func;
    void *server_baton;
    apr_memcache_server_func server_func;
};

/** Returned Data from a multiple get */
typedef struct
{
    apr_status_t status;
    const char* key;
    apr_size_t len;
    char *data;
    apr_uint16_t flags;
} apr_memcache_value_t;

/**
 * Creates a crc32 hash used to split keys between servers
 * @param mc The memcache client object to use
 * @param data Data to be hashed
 * @param data_len Length of the data to use
 * @return crc32 hash of data
 * @remark The crc32 hash is not compatible with old memcached clients.
 */
APU_DECLARE(apr_uint32_t) apr_memcache_hash(apr_memcache_t *mc,
                                            const char *data,
                                            const apr_size_t data_len);

/**
 * Pure CRC32 Hash. Used by some clients.
 */
APU_DECLARE(apr_uint32_t) apr_memcache_hash_crc32(void *baton,
                                                  const char *data,
                                                  const apr_size_t data_len);

/**
 * hash compatible with the standard Perl Client.
 */
APU_DECLARE(apr_uint32_t) apr_memcache_hash_default(void *baton,
                                                    const char *data,
                                                    const apr_size_t data_len);

/**
 * Picks a server based on a hash
 * @param mc The memcache client object to use
 * @param hash Hashed value of a Key
 * @return server that controls specified hash
 * @see apr_memcache_hash
 */
APU_DECLARE(apr_memcache_server_t *) apr_memcache_find_server_hash(apr_memcache_t *mc,
                                                                   const apr_uint32_t hash);

/**
 * server selection compatible with the standard Perl Client.
 */
APU_DECLARE(apr_memcache_server_t *) apr_memcache_find_server_hash_default(void *baton,
                                                                           apr_memcache_t *mc, 
                                                                           const apr_uint32_t hash);

/**
 * Adds a server to a client object
 * @param mc The memcache client object to use
 * @param server Server to add
 * @remark Adding servers is not thread safe, and should be done once at startup.
 * @warning Changing servers after startup may cause keys to go to
 * different servers.
 */
APU_DECLARE(apr_status_t) apr_memcache_add_server(apr_memcache_t *mc,
                                                  apr_memcache_server_t *server);


/**
 * Finds a Server object based on a hostname/port pair
 * @param mc The memcache client object to use
 * @param host Hostname of the server
 * @param port Port of the server
 * @return Server with matching Hostname and Port, or NULL if none was found.
 */
APU_DECLARE(apr_memcache_server_t *) apr_memcache_find_server(apr_memcache_t *mc,
                                                              const char *host,
                                                              apr_port_t port);

/**
 * Enables a Server for use again
 * @param mc The memcache client object to use
 * @param ms Server to Activate
 */
APU_DECLARE(apr_status_t) apr_memcache_enable_server(apr_memcache_t *mc,
                                                     apr_memcache_server_t *ms);


/**
 * Disable a Server
 * @param mc The memcache client object to use
 * @param ms Server to Disable
 */
APU_DECLARE(apr_status_t) apr_memcache_disable_server(apr_memcache_t *mc,
                                                      apr_memcache_server_t *ms);

/**
 * Creates a new Server Object
 * @param p Pool to use
 * @param host hostname of the server
 * @param port port of the server
 * @param min  minimum number of client sockets to open
 * @param smax soft maximum number of client connections to open
 * @param max  hard maximum number of client connections
 * @param ttl  time to live in microseconds of a client connection
 * @param ns   location of the new server object
 * @see apr_reslist_create
 * @remark min, smax, and max are only used when APR_HAS_THREADS
 */
APU_DECLARE(apr_status_t) apr_memcache_server_create(apr_pool_t *p,
                                                     const char *host,
                                                     apr_port_t port,
                                                     apr_uint32_t min,
                                                     apr_uint32_t smax,
                                                     apr_uint32_t max,
                                                     apr_uint32_t ttl,
                                                     apr_memcache_server_t **ns);
/**
 * Creates a new memcached client object
 * @param p Pool to use
 * @param max_servers maximum number of servers
 * @param flags Not currently used
 * @param mc   location of the new memcache client object
 */
APU_DECLARE(apr_status_t) apr_memcache_create(apr_pool_t *p,
                                              apr_uint16_t max_servers,
                                              apr_uint32_t flags,
                                              apr_memcache_t **mc);

/**
 * Gets a value from the server, allocating the value out of p
 * @param mc client to use
 * @param p Pool to use
 * @param key null terminated string containing the key
 * @param baton location of the allocated value
 * @param len   length of data at baton
 * @param flags any flags set by the client for this key
 * @return 
 */
APU_DECLARE(apr_status_t) apr_memcache_getp(apr_memcache_t *mc, 
                                            apr_pool_t *p,
                                            const char* key,
                                            char **baton,
                                            apr_size_t *len,
                                            apr_uint16_t *flags);


/**
 * Add a key to a hash for a multiget query
 *  if the hash (*value) is NULL it will be created
 * @param data_pool pool from where the hash and their items are created from
 * @param key null terminated string containing the key
 * @param values hash of keys and values that this key will be added to
 * @return
 */
APU_DECLARE(void) apr_memcache_add_multget_key(apr_pool_t *data_pool,
                                               const char* key,
                                               apr_hash_t **values);

/**
 * Gets multiple values from the server, allocating the values out of p
 * @param mc client to use
 * @param temp_pool Pool used for temporary allocations. May be cleared inside this
 *        call.
 * @param data_pool Pool used to allocate data for the returned values.
 * @param values hash of apr_memcache_value_t keyed by strings, contains the
 *        result of the multiget call.
 * @return
 */
APU_DECLARE(apr_status_t) apr_memcache_multgetp(apr_memcache_t *mc,
                                                apr_pool_t *temp_pool,
                                                apr_pool_t *data_pool,
                                                apr_hash_t *values);

/**
 * Sets a value by key on the server
 * @param mc client to use
 * @param key   null terminated string containing the key
 * @param baton data to store on the server
 * @param data_size   length of data at baton
 * @param timeout time in seconds for the data to live on the server
 * @param flags any flags set by the client for this key
 */
APU_DECLARE(apr_status_t) apr_memcache_set(apr_memcache_t *mc,
                                           const char *key,
                                           char *baton,
                                           const apr_size_t data_size,
                                           apr_uint32_t timeout,
                                           apr_uint16_t flags);

/**
 * Adds value by key on the server
 * @param mc client to use
 * @param key   null terminated string containing the key
 * @param baton data to store on the server
 * @param data_size   length of data at baton
 * @param timeout time for the data to live on the server
 * @param flags any flags set by the client for this key
 * @return APR_SUCCESS if the key was added, APR_EEXIST if the key 
 * already exists on the server.
 */
APU_DECLARE(apr_status_t) apr_memcache_add(apr_memcache_t *mc,
                                           const char *key,
                                           char *baton,
                                           const apr_size_t data_size,
                                           apr_uint32_t timeout,
                                           apr_uint16_t flags);

/**
 * Replaces value by key on the server
 * @param mc client to use
 * @param key   null terminated string containing the key
 * @param baton data to store on the server
 * @param data_size   length of data at baton
 * @param timeout time for the data to live on the server
 * @param flags any flags set by the client for this key
 * @return APR_SUCCESS if the key was added, APR_EEXIST if the key 
 * did not exist on the server.
 */
APU_DECLARE(apr_status_t) apr_memcache_replace(apr_memcache_t *mc,
                                               const char *key,
                                               char *baton,
                                               const apr_size_t data_size,
                                               apr_uint32_t timeout,
                                               apr_uint16_t flags);
/**
 * Deletes a key from a server
 * @param mc client to use
 * @param key   null terminated string containing the key
 * @param timeout time for the delete to stop other clients from adding
 */
APU_DECLARE(apr_status_t) apr_memcache_delete(apr_memcache_t *mc,
                                              const char *key,
                                              apr_uint32_t timeout);

/**
 * Increments a value
 * @param mc client to use
 * @param key   null terminated string containing the key
 * @param n     number to increment by
 * @param nv    new value after incrementing
 */
APU_DECLARE(apr_status_t) apr_memcache_incr(apr_memcache_t *mc, 
                                            const char *key,
                                            apr_int32_t n,
                                            apr_uint32_t *nv);

/**
 * Decrements a value
 * @param mc client to use
 * @param key   null terminated string containing the key
 * @param n     number to decrement by
 * @param new_value    new value after decrementing
 */
APU_DECLARE(apr_status_t) apr_memcache_decr(apr_memcache_t *mc, 
                                            const char *key,
                                            apr_int32_t n,
                                            apr_uint32_t *new_value);

/**
 * Query a server's version
 * @param ms    server to query
 * @param p     Pool to allocate answer from
 * @param baton location to store server version string
 * @param len   length of the server version string
 */
APU_DECLARE(apr_status_t) apr_memcache_version(apr_memcache_server_t *ms,
                                               apr_pool_t *p,
                                               char **baton);

typedef struct
{
    /** Version string of this server */
    const char *version;
    /** Process id of this server process */
    apr_uint32_t pid;
    /** Number of seconds this server has been running */
    apr_uint32_t uptime;
    /** current UNIX time according to the server */
    apr_time_t time;
    /** The size of a pointer on the current machine */
    apr_uint32_t pointer_size;
    /** Accumulated user time for this process */
    apr_time_t rusage_user;
    /** Accumulated system time for this process */
    apr_time_t rusage_system;
    /** Current number of items stored by the server */
    apr_uint32_t curr_items;
    /** Total number of items stored by this server */
    apr_uint32_t total_items;
    /** Current number of bytes used by this server to store items */
    apr_uint64_t bytes;
    /** Number of open connections */
    apr_uint32_t curr_connections;
    /** Total number of connections opened since the server started running */
    apr_uint32_t total_connections;
    /** Number of connection structures allocated by the server */
    apr_uint32_t connection_structures;
    /** Cumulative number of retrieval requests */
    apr_uint32_t cmd_get;
    /** Cumulative number of storage requests */
    apr_uint32_t cmd_set;
    /** Number of keys that have been requested and found present */
    apr_uint32_t get_hits;
    /** Number of items that have been requested and not found */
    apr_uint32_t get_misses;
    /** Number of items removed from cache because they passed their
        expiration time */
    apr_uint64_t evictions;
    /** Total number of bytes read by this server */
    apr_uint64_t bytes_read;
    /** Total number of bytes sent by this server */
    apr_uint64_t bytes_written;
    /** Number of bytes this server is allowed to use for storage. */
    apr_uint32_t limit_maxbytes;
    /** Number of threads the server is running (if built with threading) */
    apr_uint32_t threads; 
} apr_memcache_stats_t;

/**
 * Query a server for statistics
 * @param ms    server to query
 * @param p     Pool to allocate answer from
 * @param stats location of the new statistics structure
 */
APU_DECLARE(apr_status_t) apr_memcache_stats(apr_memcache_server_t *ms, 
                                             apr_pool_t *p,
                                             apr_memcache_stats_t **stats);


/** @} */

#ifdef __cplusplus
}
#endif

#endif /* APR_MEMCACHE_H */
apr-1/apr_date.h000064400000006742151730340470007431 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_DATE_H
#define APR_DATE_H

/**
 * @file apr_date.h
 * @brief APR-UTIL date routines
 */

/**
 * @defgroup APR_Util_Date Date routines
 * @ingroup APR_Util
 * @{
 */

/*
 * apr_date.h: prototypes for date parsing utility routines
 */

#include "apu.h"
#include "apr_time.h"

#ifdef __cplusplus
extern "C" {
#endif

/** A bad date. */
#define APR_DATE_BAD ((apr_time_t)0)

/**
 * Compare a string to a mask
 * @param data The string to compare
 * @param mask Mask characters (arbitrary maximum is 256 characters):
 * <PRE>
 *   '\@' - uppercase letter
 *   '\$' - lowercase letter
 *   '\&' - hex digit
 *   '#' - digit
 *   '~' - digit or space
 *   '*' - swallow remaining characters
 * </PRE>
 * @remark The mask tests for an exact match for any other character
 * @return 1 if the string matches, 0 otherwise
 */
APU_DECLARE(int) apr_date_checkmask(const char *data, const char *mask);

/**
 * Parses an HTTP date in one of three standard forms:
 * <PRE>
 *     Sun, 06 Nov 1994 08:49:37 GMT  ; RFC 822, updated by RFC 1123
 *     Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
 *     Sun Nov  6 08:49:37 1994       ; ANSI C's asctime() format
 * </PRE>
 * @param date The date in one of the three formats above
 * @return the apr_time_t number of microseconds since 1 Jan 1970 GMT, or
 *         0 if this would be out of range or if the date is invalid.
 */
APU_DECLARE(apr_time_t) apr_date_parse_http(const char *date);

/**
 * Parses a string resembling an RFC 822 date.  This is meant to be
 * leinent in its parsing of dates.  Hence, this will parse a wider 
 * range of dates than apr_date_parse_http.
 *
 * The prominent mailer (or poster, if mailer is unknown) that has
 * been seen in the wild is included for the unknown formats.
 * <PRE>
 *     Sun, 06 Nov 1994 08:49:37 GMT  ; RFC 822, updated by RFC 1123
 *     Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
 *     Sun Nov  6 08:49:37 1994       ; ANSI C's asctime() format
 *     Sun, 6 Nov 1994 08:49:37 GMT   ; RFC 822, updated by RFC 1123
 *     Sun, 06 Nov 94 08:49:37 GMT    ; RFC 822
 *     Sun, 6 Nov 94 08:49:37 GMT     ; RFC 822
 *     Sun, 06 Nov 94 08:49 GMT       ; Unknown [drtr\@ast.cam.ac.uk] 
 *     Sun, 6 Nov 94 08:49 GMT        ; Unknown [drtr\@ast.cam.ac.uk]
 *     Sun, 06 Nov 94 8:49:37 GMT     ; Unknown [Elm 70.85]
 *     Sun, 6 Nov 94 8:49:37 GMT      ; Unknown [Elm 70.85] 
 * </PRE>
 *
 * @param date The date in one of the formats above
 * @return the apr_time_t number of microseconds since 1 Jan 1970 GMT, or
 *         0 if this would be out of range or if the date is invalid.
 */
APU_DECLARE(apr_time_t) apr_date_parse_rfc(const char *date);

/** @} */
#ifdef __cplusplus
}
#endif

#endif	/* !APR_DATE_H */
apr-1/apr_md4.h000064400000010655151730340470007176 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/* This is derived from material copyright RSA Data Security, Inc.
 * Their notice is reproduced below in its entirety.
 *
 * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
 * rights reserved.
 *
 * License to copy and use this software is granted provided that it
 * is identified as the "RSA Data Security, Inc. MD4 Message-Digest
 * Algorithm" in all material mentioning or referencing this software
 * or this function.
 *
 * License is also granted to make and use derivative works provided
 * that such works are identified as "derived from the RSA Data
 * Security, Inc. MD4 Message-Digest Algorithm" in all material
 * mentioning or referencing the derived work.
 *
 * RSA Data Security, Inc. makes no representations concerning either
 * the merchantability of this software or the suitability of this
 * software for any particular purpose. It is provided "as is"
 * without express or implied warranty of any kind.
 *
 * These notices must be retained in any copies of any part of this
 * documentation and/or software.
 */

#ifndef APR_MD4_H
#define APR_MD4_H

#include "apu.h"
#include "apr_xlate.h"
/**
 * @file apr_md4.h
 * @brief APR-UTIL MD4 Library
 */
#ifdef __cplusplus
extern "C" {
#endif

/**
 * @defgroup APR_Util_MD4 MD4 Library
 * @ingroup APR_Util
 * @{
 */

/** The digestsize for MD4 */
#define APR_MD4_DIGESTSIZE 16

/** @see apr_md4_ctx_t */
typedef struct apr_md4_ctx_t apr_md4_ctx_t;

/** MD4 context. */
struct apr_md4_ctx_t {
    /** state (ABCD) */
    apr_uint32_t state[4];
    /** number of bits, modulo 2^64 (lsb first) */
    apr_uint32_t count[2];
    /** input buffer */
    unsigned char buffer[64];
#if APR_HAS_XLATE
    /** translation handle */
    apr_xlate_t *xlate;
#endif
};

/**
 * MD4 Initialize.  Begins an MD4 operation, writing a new context.
 * @param context The MD4 context to initialize.
 */
APU_DECLARE(apr_status_t) apr_md4_init(apr_md4_ctx_t *context);

#if APR_HAS_XLATE
/**
 * MDr4 translation setup.  Provides the APR translation handle to be used 
 * for translating the content before calculating the digest.
 * @param context The MD4 content to set the translation for.
 * @param xlate The translation handle to use for this MD4 context 
 */
APU_DECLARE(apr_status_t) apr_md4_set_xlate(apr_md4_ctx_t *context,
                                            apr_xlate_t *xlate);
#else
#define apr_md4_set_xlate(context, xlate) APR_ENOTIMPL
#endif

/**
 * MD4 block update operation.  Continue an MD4 message-digest operation, 
 * processing another message block, and updating the context.
 * @param context The MD4 content to update.
 * @param input next message block to update
 * @param inputLen The length of the next message block
 */
APU_DECLARE(apr_status_t) apr_md4_update(apr_md4_ctx_t *context,
                                         const unsigned char *input,
                                         apr_size_t inputLen);

/**
 * MD4 finalization.  Ends an MD4 message-digest operation, writing the 
 * message digest and zeroing the context
 * @param digest The final MD4 digest
 * @param context The MD4 content we are finalizing.
 */
APU_DECLARE(apr_status_t) apr_md4_final(
                                    unsigned char digest[APR_MD4_DIGESTSIZE],
                                    apr_md4_ctx_t *context);

/**
 * MD4 digest computation
 * @param digest The MD4 digest
 * @param input message block to use
 * @param inputLen The length of the message block
 */
APU_DECLARE(apr_status_t) apr_md4(unsigned char digest[APR_MD4_DIGESTSIZE],
                                  const unsigned char *input,
                                  apr_size_t inputLen);

/** @} */
#ifdef __cplusplus
}
#endif

#endif /* !APR_MD4_H */
apr-1/apr_proc_mutex.h000064400000015544151730340500010673 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_PROC_MUTEX_H
#define APR_PROC_MUTEX_H

/**
 * @file apr_proc_mutex.h
 * @brief APR Process Locking Routines
 */

#include "apr.h"
#include "apr_pools.h"
#include "apr_errno.h"
#include "apr_perms_set.h"
#include "apr_time.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @defgroup apr_proc_mutex Process Locking Routines
 * @ingroup APR 
 * @{
 */

/** 
 * Enumerated potential types for APR process locking methods
 * @warning Check APR_HAS_foo_SERIALIZE defines to see if the platform supports
 *          APR_LOCK_foo.  Only APR_LOCK_DEFAULT is portable.
 */
typedef enum {
    APR_LOCK_FCNTL,         /**< fcntl() */
    APR_LOCK_FLOCK,         /**< flock() */
    APR_LOCK_SYSVSEM,       /**< System V Semaphores */
    APR_LOCK_PROC_PTHREAD,  /**< POSIX pthread process-based locking */
    APR_LOCK_POSIXSEM,      /**< POSIX semaphore process-based locking */
    APR_LOCK_DEFAULT,       /**< Use the default process lock */
    APR_LOCK_DEFAULT_TIMED  /**< Use the default process timed lock */
} apr_lockmech_e;

/** Opaque structure representing a process mutex. */
typedef struct apr_proc_mutex_t apr_proc_mutex_t;

/*   Function definitions */

/**
 * Create and initialize a mutex that can be used to synchronize processes.
 * @param mutex the memory address where the newly created mutex will be
 *        stored.
 * @param fname A file name to use if the lock mechanism requires one.  This
 *        argument should always be provided.  The lock code itself will
 *        determine if it should be used.
 * @param mech The mechanism to use for the interprocess lock, if any; one of
 * <PRE>
 *            APR_LOCK_FCNTL
 *            APR_LOCK_FLOCK
 *            APR_LOCK_SYSVSEM
 *            APR_LOCK_POSIXSEM
 *            APR_LOCK_PROC_PTHREAD
 *            APR_LOCK_DEFAULT     pick the default mechanism for the platform
 * </PRE>
 * @param pool the pool from which to allocate the mutex.
 * @see apr_lockmech_e
 * @warning Check APR_HAS_foo_SERIALIZE defines to see if the platform supports
 *          APR_LOCK_foo.  Only APR_LOCK_DEFAULT is portable.
 */
APR_DECLARE(apr_status_t) apr_proc_mutex_create(apr_proc_mutex_t **mutex,
                                                const char *fname,
                                                apr_lockmech_e mech,
                                                apr_pool_t *pool);

/**
 * Re-open a mutex in a child process.
 * @param mutex The newly re-opened mutex structure.
 * @param fname A file name to use if the mutex mechanism requires one.  This
 *              argument should always be provided.  The mutex code itself will
 *              determine if it should be used.  This filename should be the 
 *              same one that was passed to apr_proc_mutex_create().
 * @param pool The pool to operate on.
 * @remark This function must be called to maintain portability, even
 *         if the underlying lock mechanism does not require it.
 */
APR_DECLARE(apr_status_t) apr_proc_mutex_child_init(apr_proc_mutex_t **mutex,
                                                    const char *fname,
                                                    apr_pool_t *pool);

/**
 * Acquire the lock for the given mutex. If the mutex is already locked,
 * the current thread will be put to sleep until the lock becomes available.
 * @param mutex the mutex on which to acquire the lock.
 */
APR_DECLARE(apr_status_t) apr_proc_mutex_lock(apr_proc_mutex_t *mutex);

/**
 * Attempt to acquire the lock for the given mutex. If the mutex has already
 * been acquired, the call returns immediately with APR_EBUSY. Note: it
 * is important that the APR_STATUS_IS_EBUSY(s) macro be used to determine
 * if the return value was APR_EBUSY, for portability reasons.
 * @param mutex the mutex on which to attempt the lock acquiring.
 */
APR_DECLARE(apr_status_t) apr_proc_mutex_trylock(apr_proc_mutex_t *mutex);

/**
 * Attempt to acquire the lock for the given mutex until timeout expires.
 * If the acquisition time outs, the call returns with APR_TIMEUP.
 * @param mutex the mutex on which to attempt the lock acquiring.
 * @param timeout the relative timeout (microseconds).
 * @note A negative or nul timeout means immediate attempt, returning
 *       APR_TIMEUP without blocking if it the lock is already acquired.
 */
APR_DECLARE(apr_status_t) apr_proc_mutex_timedlock(apr_proc_mutex_t *mutex,
                                               apr_interval_time_t timeout);

/**
 * Release the lock for the given mutex.
 * @param mutex the mutex from which to release the lock.
 */
APR_DECLARE(apr_status_t) apr_proc_mutex_unlock(apr_proc_mutex_t *mutex);

/**
 * Destroy the mutex and free the memory associated with the lock.
 * @param mutex the mutex to destroy.
 */
APR_DECLARE(apr_status_t) apr_proc_mutex_destroy(apr_proc_mutex_t *mutex);

/**
 * Destroy the mutex and free the memory associated with the lock.
 * @param mutex the mutex to destroy.
 * @note This function is generally used to kill a cleanup on an already
 *       created mutex
 */
APR_DECLARE(apr_status_t) apr_proc_mutex_cleanup(void *mutex);

/**
 * Return the name of the lockfile for the mutex, or NULL
 * if the mutex doesn't use a lock file
 */

APR_DECLARE(const char *) apr_proc_mutex_lockfile(apr_proc_mutex_t *mutex);

/**
 * Get the mechanism of the mutex, as it relates to the actual method
 * used for the underlying apr_proc_mutex_t.
 * @param mutex the mutex to get the mechanism from.
 */
APR_DECLARE(apr_lockmech_e) apr_proc_mutex_mech(apr_proc_mutex_t *mutex);

/**
 * Get the mechanism's name of the mutex, as it relates to the actual method
 * used for the underlying apr_proc_mutex_t.
 * @param mutex the mutex to get the mechanism's name from.
 */
APR_DECLARE(const char *) apr_proc_mutex_name(apr_proc_mutex_t *mutex);

/**
 * Display the name of the default mutex: APR_LOCK_DEFAULT
 */
APR_DECLARE(const char *) apr_proc_mutex_defname(void);

/**
 * Set mutex permissions.
 */
APR_PERMS_SET_IMPLEMENT(proc_mutex);

/**
 * Get the pool used by this proc_mutex.
 * @return apr_pool_t the pool
 */
APR_POOL_DECLARE_ACCESSOR(proc_mutex);

/** @} */

#ifdef __cplusplus
}
#endif

#endif  /* ! APR_PROC_MUTEX_H */
apr-1/apr_atomic.h000064400000014054151730340510007756 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_ATOMIC_H
#define APR_ATOMIC_H

/**
 * @file apr_atomic.h
 * @brief APR Atomic Operations
 */

#include "apr.h"
#include "apr_pools.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @defgroup apr_atomic Atomic Operations
 * @ingroup APR 
 * @{
 */

/**
 * this function is required on some platforms to initialize the
 * atomic operation's internal structures
 * @param p pool
 * @return APR_SUCCESS on successful completion
 * @remark Programs do NOT need to call this directly. APR will call this
 *         automatically from apr_initialize().
 * @internal
 */
APR_DECLARE(apr_status_t) apr_atomic_init(apr_pool_t *p);

/*
 * Atomic operations on 32-bit values
 * Note: Each of these functions internally implements a memory barrier
 * on platforms that require it
 */

/**
 * atomically read an apr_uint32_t from memory
 * @param mem the pointer
 */
APR_DECLARE(apr_uint32_t) apr_atomic_read32(volatile apr_uint32_t *mem);

/**
 * atomically set an apr_uint32_t in memory
 * @param mem pointer to the object
 * @param val value that the object will assume
 */
APR_DECLARE(void) apr_atomic_set32(volatile apr_uint32_t *mem, apr_uint32_t val);

/**
 * atomically add 'val' to an apr_uint32_t
 * @param mem pointer to the object
 * @param val amount to add
 * @return old value pointed to by mem
 */
APR_DECLARE(apr_uint32_t) apr_atomic_add32(volatile apr_uint32_t *mem, apr_uint32_t val);

/**
 * atomically subtract 'val' from an apr_uint32_t
 * @param mem pointer to the object
 * @param val amount to subtract
 */
APR_DECLARE(void) apr_atomic_sub32(volatile apr_uint32_t *mem, apr_uint32_t val);

/**
 * atomically increment an apr_uint32_t by 1
 * @param mem pointer to the object
 * @return old value pointed to by mem
 */
APR_DECLARE(apr_uint32_t) apr_atomic_inc32(volatile apr_uint32_t *mem);

/**
 * atomically decrement an apr_uint32_t by 1
 * @param mem pointer to the atomic value
 * @return zero if the value becomes zero on decrement, otherwise non-zero
 */
APR_DECLARE(int) apr_atomic_dec32(volatile apr_uint32_t *mem);

/**
 * compare an apr_uint32_t's value with 'cmp'.
 * If they are the same swap the value with 'with'
 * @param mem pointer to the value
 * @param with what to swap it with
 * @param cmp the value to compare it to
 * @return the old value of *mem
 */
APR_DECLARE(apr_uint32_t) apr_atomic_cas32(volatile apr_uint32_t *mem, apr_uint32_t with,
                              apr_uint32_t cmp);

/**
 * exchange an apr_uint32_t's value with 'val'.
 * @param mem pointer to the value
 * @param val what to swap it with
 * @return the old value of *mem
 */
APR_DECLARE(apr_uint32_t) apr_atomic_xchg32(volatile apr_uint32_t *mem, apr_uint32_t val);

/*
 * Atomic operations on 64-bit values
 * Note: Each of these functions internally implements a memory barrier
 * on platforms that require it
 */

/**
 * atomically read an apr_uint64_t from memory
 * @param mem the pointer
 */
APR_DECLARE(apr_uint64_t) apr_atomic_read64(volatile apr_uint64_t *mem);

/**
 * atomically set an apr_uint64_t in memory
 * @param mem pointer to the object
 * @param val value that the object will assume
 */
APR_DECLARE(void) apr_atomic_set64(volatile apr_uint64_t *mem, apr_uint64_t val);

/**
 * atomically add 'val' to an apr_uint64_t
 * @param mem pointer to the object
 * @param val amount to add
 * @return old value pointed to by mem
 */
APR_DECLARE(apr_uint64_t) apr_atomic_add64(volatile apr_uint64_t *mem, apr_uint64_t val);

/**
 * atomically subtract 'val' from an apr_uint64_t
 * @param mem pointer to the object
 * @param val amount to subtract
 */
APR_DECLARE(void) apr_atomic_sub64(volatile apr_uint64_t *mem, apr_uint64_t val);

/**
 * atomically increment an apr_uint64_t by 1
 * @param mem pointer to the object
 * @return old value pointed to by mem
 */
APR_DECLARE(apr_uint64_t) apr_atomic_inc64(volatile apr_uint64_t *mem);

/**
 * atomically decrement an apr_uint64_t by 1
 * @param mem pointer to the atomic value
 * @return zero if the value becomes zero on decrement, otherwise non-zero
 */
APR_DECLARE(int) apr_atomic_dec64(volatile apr_uint64_t *mem);

/**
 * compare an apr_uint64_t's value with 'cmp'.
 * If they are the same swap the value with 'with'
 * @param mem pointer to the value
 * @param with what to swap it with
 * @param cmp the value to compare it to
 * @return the old value of *mem
 */
APR_DECLARE(apr_uint64_t) apr_atomic_cas64(volatile apr_uint64_t *mem, apr_uint64_t with,
                              apr_uint64_t cmp);

/**
 * exchange an apr_uint64_t's value with 'val'.
 * @param mem pointer to the value
 * @param val what to swap it with
 * @return the old value of *mem
 */
APR_DECLARE(apr_uint64_t) apr_atomic_xchg64(volatile apr_uint64_t *mem, apr_uint64_t val);

/**
 * compare the pointer's value with cmp.
 * If they are the same swap the value with 'with'
 * @param mem pointer to the pointer
 * @param with what to swap it with
 * @param cmp the value to compare it to
 * @return the old value of the pointer
 */
APR_DECLARE(void*) apr_atomic_casptr(volatile void **mem, void *with, const void *cmp);

/**
 * exchange a pair of pointer values
 * @param mem pointer to the pointer
 * @param with what to swap it with
 * @return the old value of the pointer
 */
APR_DECLARE(void*) apr_atomic_xchgptr(volatile void **mem, void *with);

/** @} */

#ifdef __cplusplus
}
#endif

#endif	/* !APR_ATOMIC_H */
apr-1/apr_escape.h000064400000042356151730340510007750 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * @file apr_escape.h
 * @brief APR-UTIL Escaping
 */
#ifndef APR_ESCAPE_H
#define APR_ESCAPE_H
#include "apr.h"
#include "apr_general.h"
#ifdef __cplusplus
extern "C" {
#endif

/**
 * @defgroup APR_Util_Escaping Escape functions
 * @ingroup APR
 * @{
 */

/* Simple escape/unescape functions.
 *
 * The design goal of these functions are:
 *
 * - Avoid unnecessary work.
 *
 * In most cases the strings passed in do not need to be escaped at all. In
 * these cases the original string will be returned.
 *
 * - Lowest possible memory footprint.
 *
 * The amount of memory allocated for a given encoding is calculated based
 * on the exact amount of memory needed, and not the theoretical worst case
 * scenario.
 *
 */

/**
 * When passing a string to one of the escape functions, this value can be
 * passed to indicate a string-valued key, and have the length computed
 * automatically.
 */
#define APR_ESCAPE_STRING      (-1)

/**
 * Apply LDAP distinguished name escaping as per RFC4514.
 */
#define APR_ESCAPE_LDAP_DN     (0x01)

/**
 * Apply LDAP filter escaping as per RFC4515.
 */
#define APR_ESCAPE_LDAP_FILTER (0x02)

/**
 * Apply both RFC4514 and RFC4515 LDAP escaping.
 */
#define APR_ESCAPE_LDAP_ALL    (0x03)

/**
 * Perform shell escaping on the provided string.
 * 
 * Shell escaping causes characters to be prefixed with a '\' character.
 * @param escaped Optional buffer to write the encoded string, can be
 * NULL
 * @param str The original string
 * @param slen The length of the original string, or APR_ESCAPE_STRING
 * @param len If present, returns the length of the string
 * @return APR_SUCCESS, or APR_NOTFOUND if no changes to the string were
 * detected or the string was NULL
 */
APR_DECLARE(apr_status_t) apr_escape_shell(char *escaped, const char *str,
        apr_ssize_t slen, apr_size_t *len);

/**
 * Perform shell escaping on the provided string, returning the result
 * from the pool.
 *
 * Shell escaping causes characters to be prefixed with a '\' character.
 *
 * If no characters were escaped, the original string is returned.
 * @param p Pool to allocate from
 * @param str The original string
 * @return the encoded string, allocated from the pool, or the original
 * string if no escaping took place or the string was NULL.
 */
APR_DECLARE(const char *) apr_pescape_shell(apr_pool_t *p, const char *str)
        __attribute__((nonnull(1)));

/**
 * Unescapes a URL, leaving reserved characters intact.
 * @param escaped Optional buffer to write the encoded string, can be
 * NULL
 * @param url String to be unescaped
 * @param slen The length of the original url, or APR_ESCAPE_STRING
 * @param forbid Optional list of forbidden characters, in addition to
 * 0x00
 * @param reserved Optional list of reserved characters that will be
 * left unescaped
 * @param plus If non zero, '+' is converted to ' ' as per
 * application/x-www-form-urlencoded encoding
 * @param len If set, the length of the escaped string will be returned
 * @return APR_SUCCESS on success, APR_NOTFOUND if no characters are
 * decoded or the string is NULL, APR_EINVAL if a bad escape sequence is
 * found, APR_BADCH if a character on the forbid list is found.
 */
APR_DECLARE(apr_status_t) apr_unescape_url(char *escaped, const char *url,
        apr_ssize_t slen, const char *forbid, const char *reserved, int plus,
        apr_size_t *len);

/**
 * Unescapes a URL, leaving reserved characters intact, returning the
 * result from a pool.
 * @param p Pool to allocate from
 * @param url String to be unescaped in place
 * @param forbid Optional list of forbidden characters, in addition to
 * 0x00
 * @param reserved Optional list of reserved characters that will be
 * left unescaped
 * @param plus If non zero, '+' is converted to ' ' as per
 * application/x-www-form-urlencoded encoding
 * @return A string allocated from the pool on success, the original string
 * if no characters are decoded, or NULL if a bad escape sequence is found
 * or if a character on the forbid list is found, or if the original string
 * was NULL.
 */
APR_DECLARE(const char *) apr_punescape_url(apr_pool_t *p, const char *url,
        const char *forbid, const char *reserved, int plus)
        __attribute__((nonnull(1)));

/**
 * Escape a path segment, as defined in RFC1808.
 * @param escaped Optional buffer to write the encoded string, can be
 * NULL
 * @param str The original string
 * @param slen The length of the original string, or APR_ESCAPE_STRING
 * @param len If present, returns the length of the string
 * @return APR_SUCCESS, or APR_NOTFOUND if no changes to the string were
 * detected or the string was NULL
 */
APR_DECLARE(apr_status_t) apr_escape_path_segment(char *escaped,
        const char *str, apr_ssize_t slen, apr_size_t *len);

/**
 * Escape a path segment, as defined in RFC1808, returning the result from a
 * pool.
 * @param p Pool to allocate from
 * @param str String to be escaped
 * @return A string allocated from the pool on success, the original string
 * if no characters are encoded or the string is NULL.
 */
APR_DECLARE(const char *) apr_pescape_path_segment(apr_pool_t *p,
        const char *str) __attribute__((nonnull(1)));

/**
 * Converts an OS path to a URL, in an OS dependent way, as defined in RFC1808.
 * In all cases if a ':' occurs before the first '/' in the URL, the URL should
 * be prefixed with "./" (or the ':' escaped). In the case of Unix, this means
 * leaving '/' alone, but otherwise doing what escape_path_segment() does. For
 * efficiency reasons, we don't use escape_path_segment(), which is provided for
 * reference. Again, RFC 1808 is where this stuff is defined.
 *
 * If partial is set, os_escape_path() assumes that the path will be appended to
 * something with a '/' in it (and thus does not prefix "./").
 * @param escaped Optional buffer to write the encoded string, can be
 * NULL
 * @param path The original string
 * @param slen The length of the original string, or APR_ESCAPE_STRING
 * @param partial If non zero, suppresses the prepending of "./"
 * @param len If present, returns the length of the string
 * @return APR_SUCCESS, or APR_NOTFOUND if no changes to the string were
 * detected or if the string was NULL
 */
APR_DECLARE(apr_status_t) apr_escape_path(char *escaped, const char *path,
        apr_ssize_t slen, int partial, apr_size_t *len);

/**
 * Converts an OS path to a URL, in an OS dependent way, as defined in RFC1808,
 * returning the result from a pool.
 *
 * In all cases if a ':' occurs before the first '/' in the URL, the URL should
 * be prefixed with "./" (or the ':' escaped). In the case of Unix, this means
 * leaving '/' alone, but otherwise doing what escape_path_segment() does. For
 * efficiency reasons, we don't use escape_path_segment(), which is provided for
 * reference. Again, RFC 1808 is where this stuff is defined.
 *
 * If partial is set, os_escape_path() assumes that the path will be appended to
 * something with a '/' in it (and thus does not prefix "./").
 * @param p Pool to allocate from
 * @param str The original string
 * @param partial If non zero, suppresses the prepending of "./"
 * @return A string allocated from the pool on success, the original string
 * if no characters are encoded or if the string was NULL.
 */
APR_DECLARE(const char *) apr_pescape_path(apr_pool_t *p, const char *str,
        int partial) __attribute__((nonnull(1)));

/**
 * Urlencode a string, as defined in
 * http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1.
 * @param escaped Optional buffer to write the encoded string, can be
 * NULL
 * @param str The original string
 * @param slen The length of the original string, or APR_ESCAPE_STRING
 * @param len If present, returns the length of the string
 * @return APR_SUCCESS, or APR_NOTFOUND if no changes to the string were
 * detected or if the stirng was NULL
 */
APR_DECLARE(apr_status_t) apr_escape_urlencoded(char *escaped, const char *str,
        apr_ssize_t slen, apr_size_t *len);

/**
 * Urlencode a string, as defined in
 * http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1, returning
 * the result from a pool.
 * @param p Pool to allocate from
 * @param str String to be escaped
 * @return A string allocated from the pool on success, the original string
 * if no characters are encoded or if the string was NULL.
 */
APR_DECLARE(const char *) apr_pescape_urlencoded(apr_pool_t *p,
        const char *str) __attribute__((nonnull(1)));

/**
 * Apply entity encoding to a string. Characters are replaced as follows:
 * '<' becomes '\&lt;', '>' becomes '\&gt;', '&' becomes '\&amp;', the
 * double quote becomes '\&quot;" and the single quote becomes '\&apos;'.
 *
 * If toasc is not zero, any non ascii character will be encoded as
 * '%\#ddd;', where ddd is the decimal code of the character.
 * @param escaped Optional buffer to write the encoded string, can be
 * NULL
 * @param str The original string
 * @param slen The length of the original string, or APR_ESCAPE_STRING
 * @param toasc If non zero, encode non ascii characters
 * @param len If present, returns the length of the string
 * @return APR_SUCCESS, or APR_NOTFOUND if no changes to the string were
 * detected or the string was NULL
 */
APR_DECLARE(apr_status_t) apr_escape_entity(char *escaped, const char *str,
        apr_ssize_t slen, int toasc, apr_size_t *len);

/**
 * Apply entity encoding to a string, returning the result from a pool.
 * Characters are replaced as follows: '<' becomes '\&lt;', '>' becomes
 * '\&gt;', '&' becomes '\&amp;', the double quote becomes '\&quot;" and the
 * single quote becomes '\&apos;'.
 * @param p Pool to allocate from
 * @param str The original string
 * @param toasc If non zero, encode non ascii characters
 * @return A string allocated from the pool on success, the original string
 * if no characters are encoded or the string is NULL.
 */
APR_DECLARE(const char *) apr_pescape_entity(apr_pool_t *p, const char *str,
        int toasc) __attribute__((nonnull(1)));

/**
 * Decodes html entities or numeric character references in a string. If
 * the string to be unescaped is syntactically incorrect, then the
 * following fixups will be made:
 * unknown entities will be left undecoded;
 * references to unused numeric characters will be deleted.
 * In particular, &#00; will not be decoded, but will be deleted.
 * @param unescaped Optional buffer to write the encoded string, can be
 * NULL
 * @param str The original string
 * @param slen The length of the original string, or APR_ESCAPE_STRING
 * @param len If present, returns the length of the string
 * @return APR_SUCCESS, or APR_NOTFOUND if no changes to the string were
 * detected or the string was NULL
 */
APR_DECLARE(apr_status_t) apr_unescape_entity(char *unescaped, const char *str,
        apr_ssize_t slen, apr_size_t *len);

/**
 * Decodes html entities or numeric character references in a string. If
 * the string to be unescaped is syntactically incorrect, then the
 * following fixups will be made:
 * unknown entities will be left undecoded;
 * references to unused numeric characters will be deleted.
 * In particular, &#00; will not be decoded, but will be deleted.
 * @param p Pool to allocate from
 * @param str The original string
 * @return A string allocated from the pool on success, the original string
 * if no characters are encoded or the string is NULL.
 */
APR_DECLARE(const char *) apr_punescape_entity(apr_pool_t *p, const char *str)
        __attribute__((nonnull(1)));

/**
 * Escape control characters in a string, as performed by the shell's
 * 'echo' command. Characters are replaced as follows:
 * \\a alert (bell), \\b backspace, \\f form feed, \\n new line, \\r carriage
 * return, \\t horizontal tab, \\v vertical tab, \\ backslash.
 *
 * Any non ascii character will be encoded as '\\xHH', where HH is the hex
 * code of the character.
 *
 * If quote is not zero, the double quote character will also be escaped.
 * @param escaped Optional buffer to write the encoded string, can be
 * NULL
 * @param str The original string
 * @param slen The length of the original string, or APR_ESCAPE_STRING
 * @param quote If non zero, encode double quotes
 * @param len If present, returns the length of the string
 * @return APR_SUCCESS, or APR_NOTFOUND if no changes to the string were
 * detected or the string was NULL
 */
APR_DECLARE(apr_status_t) apr_escape_echo(char *escaped, const char *str,
        apr_ssize_t slen, int quote, apr_size_t *len);

/**
 * Escape control characters in a string, as performed by the shell's
 * 'echo' command, and return the results from a pool. Characters are
 * replaced as follows: \\a alert (bell), \\b backspace, \\f form feed,
 * \\n new line, \\r carriage return, \\t horizontal tab, \\v vertical tab,
 * \\ backslash.
 *
 * Any non ascii character will be encoded as '\\xHH', where HH is the hex
 * code of the character.
 *
 * If quote is not zero, the double quote character will also be escaped.
 * @param p Pool to allocate from
 * @param str The original string
 * @param quote If non zero, encode double quotes
 * @return A string allocated from the pool on success, the original string
 * if no characters are encoded or the string is NULL.
 */
APR_DECLARE(const char *) apr_pescape_echo(apr_pool_t *p, const char *str,
        int quote);

/**
 * Convert binary data to a hex encoding.
 * @param dest The destination buffer, can be NULL
 * @param src The original buffer
 * @param srclen The length of the original buffer
 * @param colon If not zero, insert colon characters between hex digits.
 * @param len If present, returns the length of the string
 * @return APR_SUCCESS, or APR_NOTFOUND if the string was NULL
 */
APR_DECLARE(apr_status_t) apr_escape_hex(char *dest, const void *src,
        apr_size_t srclen, int colon, apr_size_t *len);

/**
 * Convert binary data to a hex encoding, and return the results from a
 * pool.
 * @param p Pool to allocate from
 * @param src The original buffer
 * @param slen The length of the original buffer
 * @param colon If not zero, insert colon characters between hex digits.
 * @return A zero padded buffer allocated from the pool on success, or
 * NULL if src was NULL.
 */
APR_DECLARE(const char *) apr_pescape_hex(apr_pool_t *p, const void *src,
        apr_size_t slen, int colon) __attribute__((nonnull(1)));

/**
 * Convert hex encoded string to binary data.
 * @param dest The destination buffer, can be NULL
 * @param str The original buffer
 * @param slen The length of the original buffer
 * @param colon If not zero, ignore colon characters between hex digits.
 * @param len If present, returns the length of the string
 * @return APR_SUCCESS, or APR_NOTFOUND if the string was NULL, or APR_BADCH
 * if a non hex character is present.
 */
APR_DECLARE(apr_status_t) apr_unescape_hex(void *dest, const char *str,
        apr_ssize_t slen, int colon, apr_size_t *len);

/**
 * Convert hex encoding to binary data, and return the results from a pool.
 * If the colon character appears between pairs of hex digits, it will be
 * ignored.
 * @param p Pool to allocate from
 * @param str The original string
 * @param colon If not zero, ignore colon characters between hex digits.
 * @param len If present, returns the length of the final buffer
 * @return A buffer allocated from the pool on success, or NULL if src was
 * NULL, or a bad character was present.
 */
APR_DECLARE(const void *) apr_punescape_hex(apr_pool_t *p, const char *str,
        int colon, apr_size_t *len);

/**
 * Apply LDAP escaping to binary data. Characters from RFC4514 and RFC4515
 * are escaped with their hex equivalents.
 * @param dest The destination buffer, can be NULL
 * @param src The original buffer
 * @param srclen The length of the original buffer
 * @param flags APR_ESCAPE_LDAP_DN for RFC4514, APR_ESCAPE_LDAP_FILTER for
 * RFC4515, APR_ESCAPE_LDAP_ALL for both
 * @param len If present, returns the length of the string
 * @return APR_SUCCESS, or APR_NOTFOUND if the string was NULL
 */
APR_DECLARE(apr_status_t) apr_escape_ldap(char *dest, const void *src,
        apr_ssize_t srclen, int flags, apr_size_t *len);

/**
 * Apply LDAP escaping to binary data, and return the results from a
 * pool. Characters from RFC4514 and RFC4515 are escaped with their hex
 * equivalents.
 * @param p Pool to allocate from
 * @param src The original buffer
 * @param slen The length of the original buffer
 * @param flags APR_ESCAPE_LDAP_DN for RFC4514, APR_ESCAPE_LDAP_FILTER for
 * RFC4515, APR_ESCAPE_LDAP_ALL for both
 * @return A zero padded buffer allocated from the pool on success, or
 * NULL if src was NULL.
 */
APR_DECLARE(const char *) apr_pescape_ldap(apr_pool_t *p, const void *src,
        apr_ssize_t slen, int flags) __attribute__((nonnull(1)));

/** @} */
#ifdef __cplusplus
}
#endif

#endif	/* !APR_ESCAPE_H */
apr-1/apr_network_io.h000064400000110021151730340510010651 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_NETWORK_IO_H
#define APR_NETWORK_IO_H
/**
 * @file apr_network_io.h
 * @brief APR Network library
 */

#include "apr.h"
#include "apr_pools.h"
#include "apr_file_io.h"
#include "apr_errno.h"
#include "apr_inherit.h" 
#include "apr_perms_set.h"

#if APR_HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#if APR_HAVE_SYS_UN_H
#include <sys/un.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @defgroup apr_network_io Network Routines
 * @ingroup APR 
 * @{
 */

#ifndef APR_MAX_SECS_TO_LINGER
/** Maximum seconds to linger */
#define APR_MAX_SECS_TO_LINGER 30
#endif

#ifndef APRMAXHOSTLEN
/** Maximum hostname length */
#define APRMAXHOSTLEN 256
#endif

#ifndef APR_ANYADDR
/** Default 'any' address */
#define APR_ANYADDR "0.0.0.0"
#endif

/**
 * @defgroup apr_sockopt Socket option definitions
 * @{
 */
#define APR_SO_LINGER        1    /**< Linger */
#define APR_SO_KEEPALIVE     2    /**< Keepalive */
#define APR_SO_DEBUG         4    /**< Debug */
#define APR_SO_NONBLOCK      8    /**< Non-blocking IO */
#define APR_SO_REUSEADDR     16   /**< Reuse addresses */
#define APR_SO_SNDBUF        64   /**< Send buffer */
#define APR_SO_RCVBUF        128  /**< Receive buffer */
#define APR_SO_DISCONNECTED  256  /**< Disconnected */
#define APR_TCP_NODELAY      512  /**< For SCTP sockets, this is mapped
                                   * to STCP_NODELAY internally.
                                   */
#define APR_TCP_NOPUSH       1024 /**< No push */
#define APR_RESET_NODELAY    2048 /**< This flag is ONLY set internally
                                   * when we set APR_TCP_NOPUSH with
                                   * APR_TCP_NODELAY set to tell us that
                                   * APR_TCP_NODELAY should be turned on
                                   * again when NOPUSH is turned off
                                   */
#define APR_INCOMPLETE_READ 4096  /**< Set on non-blocking sockets
				   * (timeout != 0) on which the
				   * previous read() did not fill a buffer
				   * completely.  the next apr_socket_recv() 
                                   * will first call select()/poll() rather than
				   * going straight into read().  (Can also
				   * be set by an application to force a
				   * select()/poll() call before the next
				   * read, in cases where the app expects
				   * that an immediate read would fail.)
				   */
#define APR_INCOMPLETE_WRITE 8192 /**< like APR_INCOMPLETE_READ, but for write
                                   * @see APR_INCOMPLETE_READ
                                   */
#define APR_IPV6_V6ONLY     16384 /**< Don't accept IPv4 connections on an
                                   * IPv6 listening socket.
                                   */
#define APR_TCP_DEFER_ACCEPT 32768 /**< Delay accepting of new connections 
                                    * until data is available.
                                    * @see apr_socket_accept_filter
                                    */
#define APR_SO_BROADCAST     65536 /**< Allow broadcast
                                    */
#define APR_SO_FREEBIND     131072 /**< Allow binding to addresses not owned
                                    * by any interface
                                    */

/** @} */

/** Define what type of socket shutdown should occur. */
typedef enum {
    APR_SHUTDOWN_READ,          /**< no longer allow read request */
    APR_SHUTDOWN_WRITE,         /**< no longer allow write requests */
    APR_SHUTDOWN_READWRITE      /**< no longer allow read or write requests */
} apr_shutdown_how_e;

#define APR_IPV4_ADDR_OK  0x01  /**< @see apr_sockaddr_info_get() */
#define APR_IPV6_ADDR_OK  0x02  /**< @see apr_sockaddr_info_get() */

#if (!APR_HAVE_IN_ADDR)
/**
 * We need to make sure we always have an in_addr type, so APR will just
 * define it ourselves, if the platform doesn't provide it.
 */
struct in_addr {
    apr_uint32_t  s_addr; /**< storage to hold the IP# */
};
#endif

/** @def APR_INADDR_NONE
 * Not all platforms have a real INADDR_NONE.  This macro replaces
 * INADDR_NONE on all platforms.
 */
#ifdef INADDR_NONE
#define APR_INADDR_NONE INADDR_NONE
#else
#define APR_INADDR_NONE ((unsigned int) 0xffffffff)
#endif

/**
 * @def APR_INET
 * Not all platforms have these defined, so we'll define them here
 * The default values come from FreeBSD 4.1.1
 */
#define APR_INET     AF_INET
/** @def APR_UNSPEC
 * Let the system decide which address family to use
 */
#ifdef AF_UNSPEC
#define APR_UNSPEC   AF_UNSPEC
#else
#define APR_UNSPEC   0
#endif
#if APR_HAVE_IPV6
/** @def APR_INET6
* IPv6 Address Family. Not all platforms may have this defined.
*/

#define APR_INET6    AF_INET6
#endif

#if APR_HAVE_SOCKADDR_UN
#if defined (AF_UNIX)
#define APR_UNIX    AF_UNIX
#elif defined(AF_LOCAL)
#define APR_UNIX    AF_LOCAL
#else
#error "Neither AF_UNIX nor AF_LOCAL is defined"
#endif
#else /* !APR_HAVE_SOCKADDR_UN */
#if defined (AF_UNIX)
#define APR_UNIX    AF_UNIX
#elif defined(AF_LOCAL)
#define APR_UNIX    AF_LOCAL
#else
/* TODO: Use a smarter way to detect unique APR_UNIX value */
#define APR_UNIX    1234
#endif
#endif

/**
 * @defgroup IP_Proto IP Protocol Definitions for use when creating sockets
 * @{
 */
#define APR_PROTO_TCP       6   /**< TCP  */
#define APR_PROTO_UDP      17   /**< UDP  */
#define APR_PROTO_SCTP    132   /**< SCTP */
/** @} */

/**
 * Enum used to denote either the local and remote endpoint of a
 * connection.
 */
typedef enum {
    APR_LOCAL,   /**< Socket information for local end of connection */
    APR_REMOTE   /**< Socket information for remote end of connection */
} apr_interface_e;

/**
 * The specific declaration of inet_addr's ... some platforms fall back
 * inet_network (this is not good, but necessary)
 */

#if APR_HAVE_INET_ADDR
#define apr_inet_addr    inet_addr
#elif APR_HAVE_INET_NETWORK        /* only DGUX, as far as I know */
/**
 * @warning
 * not generally safe... inet_network() and inet_addr() perform
 * different functions */
#define apr_inet_addr    inet_network
#endif

/** A structure to represent sockets */
typedef struct apr_socket_t     apr_socket_t;
/**
 * A structure to encapsulate headers and trailers for apr_socket_sendfile
 */
typedef struct apr_hdtr_t       apr_hdtr_t;
/** A structure to represent in_addr */
typedef struct in_addr          apr_in_addr_t;
/** A structure to represent an IP subnet */
typedef struct apr_ipsubnet_t apr_ipsubnet_t;

/** @remark use apr_uint16_t just in case some system has a short that isn't 16 bits... */
typedef apr_uint16_t            apr_port_t;

/** @remark It's defined here as I think it should all be platform safe...
 * @see apr_sockaddr_t
 */
typedef struct apr_sockaddr_t apr_sockaddr_t;
/**
 * APRs socket address type, used to ensure protocol independence
 */
struct apr_sockaddr_t {
    /** The pool to use... */
    apr_pool_t *pool;
    /** The hostname */
    char *hostname;
    /** Either a string of the port number or the service name for the port */
    char *servname;
    /** The numeric port */
    apr_port_t port;
    /** The family */
    apr_int32_t family;
    /** How big is the sockaddr we're using? */
    apr_socklen_t salen;
    /** How big is the ip address structure we're using? */
    int ipaddr_len;
    /** How big should the address buffer be?  16 for v4 or 46 for v6
     *  used in inet_ntop... */
    int addr_str_len;
    /** This points to the IP address structure within the appropriate
     *  sockaddr structure.  */
    void *ipaddr_ptr;
    /** If multiple addresses were found by apr_sockaddr_info_get(), this 
     *  points to a representation of the next address. */
    apr_sockaddr_t *next;
    /** Union of either IPv4 or IPv6 sockaddr. */
    union {
        /** IPv4 sockaddr structure */
        struct sockaddr_in sin;
#if APR_HAVE_IPV6
        /** IPv6 sockaddr structure */
        struct sockaddr_in6 sin6;
#endif
#if APR_HAVE_SA_STORAGE
        /** Placeholder to ensure that the size of this union is not
         * dependent on whether APR_HAVE_IPV6 is defined. */
        struct sockaddr_storage sas;
#endif
#if APR_HAVE_SOCKADDR_UN
        /** Unix domain socket sockaddr structure */
        struct sockaddr_un unx;
#endif
    } sa;
};

#if APR_HAS_SENDFILE
/** 
 * Support reusing the socket on platforms which support it (from disconnect,
 * specifically Win32.
 * @remark Optional flag passed into apr_socket_sendfile() 
 */
#define APR_SENDFILE_DISCONNECT_SOCKET      1
#endif

/** A structure to encapsulate headers and trailers for apr_socket_sendfile */
struct apr_hdtr_t {
    /** An iovec to store the headers sent before the file. */
    struct iovec* headers;
    /** number of headers in the iovec */
    int numheaders;
    /** An iovec to store the trailers sent after the file. */
    struct iovec* trailers;
    /** number of trailers in the iovec */
    int numtrailers;
};

/* function definitions */

/**
 * Create a socket.
 * @param new_sock The new socket that has been set up.
 * @param family The address family of the socket (e.g., APR_INET).
 * @param type The type of the socket (e.g., SOCK_STREAM).
 * @param protocol The protocol of the socket (e.g., APR_PROTO_TCP).
 * @param cont The pool for the apr_socket_t and associated storage.
 * @note The pool will be used by various functions that operate on the
 *       socket. The caller must ensure that it is not used by other threads
 *       at the same time.
 */
APR_DECLARE(apr_status_t) apr_socket_create(apr_socket_t **new_sock, 
                                            int family, int type,
                                            int protocol,
                                            apr_pool_t *cont);

/**
 * Shutdown either reading, writing, or both sides of a socket.
 * @param thesocket The socket to close 
 * @param how How to shutdown the socket.  One of:
 * <PRE>
 *            APR_SHUTDOWN_READ         no longer allow read requests
 *            APR_SHUTDOWN_WRITE        no longer allow write requests
 *            APR_SHUTDOWN_READWRITE    no longer allow read or write requests 
 * </PRE>
 * @see apr_shutdown_how_e
 * @remark This does not actually close the socket descriptor, it just
 *      controls which calls are still valid on the socket.
 */
APR_DECLARE(apr_status_t) apr_socket_shutdown(apr_socket_t *thesocket,
                                              apr_shutdown_how_e how);

/**
 * Close a socket.
 * @param thesocket The socket to close 
 */
APR_DECLARE(apr_status_t) apr_socket_close(apr_socket_t *thesocket);

/**
 * Bind the socket to its associated port
 * @param sock The socket to bind 
 * @param sa The socket address to bind to
 * @remark This may be where we will find out if there is any other process
 *      using the selected port.
 */
APR_DECLARE(apr_status_t) apr_socket_bind(apr_socket_t *sock, 
                                          apr_sockaddr_t *sa);

/**
 * Listen to a bound socket for connections.
 * @param sock The socket to listen on 
 * @param backlog The number of outstanding connections allowed in the sockets
 *                listen queue.  If this value is less than zero, the listen
 *                queue size is set to zero.  
 */
APR_DECLARE(apr_status_t) apr_socket_listen(apr_socket_t *sock, 
                                            apr_int32_t backlog);

/**
 * Accept a new connection request
 * @param new_sock A copy of the socket that is connected to the socket that
 *                 made the connection request.  This is the socket which should
 *                 be used for all future communication.
 * @param sock The socket we are listening on.
 * @param connection_pool The pool for the new socket.
 * @note The pool will be used by various functions that operate on the
 *       socket. The caller must ensure that it is not used by other threads
 *       at the same time.
 */
APR_DECLARE(apr_status_t) apr_socket_accept(apr_socket_t **new_sock, 
                                            apr_socket_t *sock,
                                            apr_pool_t *connection_pool);

/**
 * Issue a connection request to a socket either on the same machine 
 * or a different one.
 * @param sock The socket we wish to use for our side of the connection 
 * @param sa The address of the machine we wish to connect to.
 */
APR_DECLARE(apr_status_t) apr_socket_connect(apr_socket_t *sock,
                                             apr_sockaddr_t *sa);

/**
 * Determine whether the receive part of the socket has been closed by
 * the peer (such that a subsequent call to apr_socket_read would
 * return APR_EOF), if the socket's receive buffer is empty.  This
 * function does not block waiting for I/O.
 *
 * @param sock The socket to check
 * @param atreadeof If APR_SUCCESS is returned, *atreadeof is set to
 *                  non-zero if a subsequent read would return APR_EOF
 * @return an error is returned if it was not possible to determine the
 *         status, in which case *atreadeof is not changed.
 */
APR_DECLARE(apr_status_t) apr_socket_atreadeof(apr_socket_t *sock,
                                               int *atreadeof);

/**
 * Create apr_sockaddr_t from hostname, address family, and port.
 * @param sa The new apr_sockaddr_t.
 * @param hostname The hostname or numeric address string to resolve/parse, or
 *               NULL to build an address that corresponds to 0.0.0.0 or ::
 *               or in case of APR_UNIX family it is absolute socket filename.
 * @param family The address family to use, or APR_UNSPEC if the system should 
 *               decide.
 * @param port The port number.
 * @param flags Special processing flags:
 * <PRE>
 *       APR_IPV4_ADDR_OK          first query for IPv4 addresses; only look
 *                                 for IPv6 addresses if the first query failed;
 *                                 only valid if family is APR_UNSPEC and hostname
 *                                 isn't NULL; mutually exclusive with
 *                                 APR_IPV6_ADDR_OK
 *       APR_IPV6_ADDR_OK          first query for IPv6 addresses; only look
 *                                 for IPv4 addresses if the first query failed;
 *                                 only valid if family is APR_UNSPEC and hostname
 *                                 isn't NULL and APR_HAVE_IPV6; mutually exclusive
 *                                 with APR_IPV4_ADDR_OK
 * </PRE>
 * @param p The pool for the apr_sockaddr_t and associated storage.
 */
APR_DECLARE(apr_status_t) apr_sockaddr_info_get(apr_sockaddr_t **sa,
                                          const char *hostname,
                                          apr_int32_t family,
                                          apr_port_t port,
                                          apr_int32_t flags,
                                          apr_pool_t *p);

/**
 * Copy apr_sockaddr_t src to dst on pool p.
 * @param dst The destination apr_sockaddr_t.
 * @param src The source apr_sockaddr_t.
 * @param p The pool for the apr_sockaddr_t and associated storage.
 */
APR_DECLARE(apr_status_t) apr_sockaddr_info_copy(apr_sockaddr_t **dst,
                                                 const apr_sockaddr_t *src,
                                                 apr_pool_t *p);

/**
 * Set the zone of an IPv6 link-local address object.
 * @param sa Socket address object
 * @param zone_id Zone ID (textual "eth0" or numeric "3").
 * @return Returns APR_EBADIP for non-IPv6 socket or an IPv6 address
 * which isn't link-local.
 */
APR_DECLARE(apr_status_t) apr_sockaddr_zone_set(apr_sockaddr_t *sa,
                                                const char *zone_id);


/**
 * Retrieve the zone of an IPv6 link-local address object.
 * @param sa Socket address object
 * @param name If non-NULL, set to the textual representation of the zone id
 * @param id If non-NULL, set to the integer zone id
 * @param p Pool from which *name is allocated if used.
 * @return Returns APR_EBADIP for non-IPv6 socket or socket without any zone id
 * set, or other error if the interface could not be mapped to a name.
 * @remark Both name and id may be NULL, neither are modified if
 * non-NULL in error cases.
 */
APR_DECLARE(apr_status_t) apr_sockaddr_zone_get(const apr_sockaddr_t *sa,
                                                const char **name,
                                                apr_uint32_t *id,
                                                apr_pool_t *p);                                                
    
/**
 * Look up the host name from an apr_sockaddr_t.
 * @param hostname The hostname.
 * @param sa The apr_sockaddr_t.
 * @param flags Special processing flags.
 * @remark Results can vary significantly between platforms
 * when processing wildcard socket addresses.
 */
APR_DECLARE(apr_status_t) apr_getnameinfo(char **hostname,
                                          apr_sockaddr_t *sa,
                                          apr_int32_t flags);

/**
 * Parse hostname/IP address with scope id and port.
 *
 * Any of the following strings are accepted:
 *   8080                  (just the port number)
 *   www.apache.org        (just the hostname)
 *   www.apache.org:8080   (hostname and port number)
 *   [fe80::1]:80          (IPv6 numeric address string only)
 *   [fe80::1%eth0]        (IPv6 numeric address string and scope id)
 *
 * Invalid strings:
 *                         (empty string)
 *   [abc]                 (not valid IPv6 numeric address string)
 *   abc:65536             (invalid port number)
 *
 * @param addr The new buffer containing just the hostname.  On output, *addr 
 *             will be NULL if no hostname/IP address was specfied.
 * @param scope_id The new buffer containing just the scope id.  On output, 
 *                 *scope_id will be NULL if no scope id was specified.
 * @param port The port number.  On output, *port will be 0 if no port was 
 *             specified.
 *             ### FIXME: 0 is a legal port (per RFC 1700). this should
 *             ### return something besides zero if the port is missing.
 * @param str The input string to be parsed.
 * @param p The pool from which *addr and *scope_id are allocated.
 * @remark If scope id shouldn't be allowed, check for scope_id != NULL in 
 *         addition to checking the return code.  If addr/hostname should be 
 *         required, check for addr == NULL in addition to checking the 
 *         return code.
 */
APR_DECLARE(apr_status_t) apr_parse_addr_port(char **addr,
                                              char **scope_id,
                                              apr_port_t *port,
                                              const char *str,
                                              apr_pool_t *p);

/**
 * Get name of the current machine
 * @param buf A buffer to store the hostname in.
 * @param len The maximum length of the hostname that can be stored in the
 *            buffer provided.  The suggested length is APRMAXHOSTLEN + 1.
 * @param cont The pool to use.
 * @remark If the buffer was not large enough, an error will be returned.
 */
APR_DECLARE(apr_status_t) apr_gethostname(char *buf, int len, apr_pool_t *cont);

/**
 * Return the data associated with the current socket
 * @param data The user data associated with the socket.
 * @param key The key to associate with the user data.
 * @param sock The currently open socket.
 */
APR_DECLARE(apr_status_t) apr_socket_data_get(void **data, const char *key,
                                              apr_socket_t *sock);

/**
 * Set the data associated with the current socket.
 * @param sock The currently open socket.
 * @param data The user data to associate with the socket.
 * @param key The key to associate with the data.
 * @param cleanup The cleanup to call when the socket is destroyed.
 */
APR_DECLARE(apr_status_t) apr_socket_data_set(apr_socket_t *sock, void *data,
                                              const char *key,
                                              apr_status_t (*cleanup)(void*));

/**
 * Send data over a network.
 * @param sock The socket to send the data over.
 * @param buf The buffer which contains the data to be sent. 
 * @param len On entry, the number of bytes to send; on exit, the number
 *            of bytes sent.
 * @remark
 * <PRE>
 * This functions acts like a blocking write by default.  To change 
 * this behavior, use apr_socket_timeout_set() or the APR_SO_NONBLOCK
 * socket option.
 *
 * It is possible for both bytes to be sent and an error to be returned.
 *
 * APR_EINTR is never returned.
 * </PRE>
 */
APR_DECLARE(apr_status_t) apr_socket_send(apr_socket_t *sock, const char *buf, 
                                          apr_size_t *len);

/**
 * Send multiple buffers over a network.
 * @param sock The socket to send the data over.
 * @param vec The array of iovec structs containing the data to send 
 * @param nvec The number of iovec structs in the array
 * @param len Receives the number of bytes actually written
 * @remark
 * <PRE>
 * This functions acts like a blocking write by default.  To change 
 * this behavior, use apr_socket_timeout_set() or the APR_SO_NONBLOCK
 * socket option.
 * The number of bytes actually sent is stored in argument 4.
 *
 * It is possible for both bytes to be sent and an error to be returned.
 *
 * APR_EINTR is never returned.
 * </PRE>
 */
APR_DECLARE(apr_status_t) apr_socket_sendv(apr_socket_t *sock, 
                                           const struct iovec *vec,
                                           apr_int32_t nvec, apr_size_t *len);

/**
 * @param sock The socket to send from
 * @param where The apr_sockaddr_t describing where to send the data
 * @param flags The flags to use
 * @param buf  The data to send
 * @param len  The length of the data to send
 */
APR_DECLARE(apr_status_t) apr_socket_sendto(apr_socket_t *sock, 
                                            apr_sockaddr_t *where,
                                            apr_int32_t flags, const char *buf, 
                                            apr_size_t *len);

/**
 * Read data from a socket.  On success, the address of the peer from
 * which the data was sent is copied into the @a from parameter, and the
 * @a len parameter is updated to give the number of bytes written to
 * @a buf.
 *
 * @param from Updated with the address from which the data was received
 * @param sock The socket to use
 * @param flags The flags to use
 * @param buf  The buffer to use
 * @param len  The length of the available buffer
 */

APR_DECLARE(apr_status_t) apr_socket_recvfrom(apr_sockaddr_t *from, 
                                              apr_socket_t *sock,
                                              apr_int32_t flags, char *buf, 
                                              apr_size_t *len);
 
#if APR_HAS_SENDFILE || defined(DOXYGEN)

/**
 * Send a file from an open file descriptor to a socket, along with 
 * optional headers and trailers
 * @param sock The socket to which we're writing
 * @param file The open file from which to read
 * @param hdtr A structure containing the headers and trailers to send
 * @param offset Offset into the file where we should begin writing
 * @param len (input)  - Number of bytes to send from the file 
 *            (output) - Number of bytes actually sent, 
 *                       including headers, file, and trailers
 * @param flags APR flags that are mapped to OS specific flags
 * @remark This functions acts like a blocking write by default.  To change 
 *         this behavior, use apr_socket_timeout_set() or the
 *         APR_SO_NONBLOCK socket option.
 * The number of bytes actually sent is stored in the len parameter.
 * The offset parameter is passed by reference for no reason; its
 * value will never be modified by the apr_socket_sendfile() function.
 */
APR_DECLARE(apr_status_t) apr_socket_sendfile(apr_socket_t *sock, 
                                              apr_file_t *file,
                                              apr_hdtr_t *hdtr,
                                              apr_off_t *offset,
                                              apr_size_t *len,
                                              apr_int32_t flags);

#endif /* APR_HAS_SENDFILE */

/**
 * Read data from a network.
 * @param sock The socket to read the data from.
 * @param buf The buffer to store the data in. 
 * @param len On entry, the number of bytes to receive; on exit, the number
 *            of bytes received.
 * @remark
 * <PRE>
 * This functions acts like a blocking read by default.  To change 
 * this behavior, use apr_socket_timeout_set() or the APR_SO_NONBLOCK
 * socket option.
 * The number of bytes actually received is stored in argument 3.
 *
 * It is possible for both bytes to be received and an APR_EOF or
 * other error to be returned.
 *
 * APR_EINTR is never returned.
 * </PRE>
 */
APR_DECLARE(apr_status_t) apr_socket_recv(apr_socket_t *sock, 
                                   char *buf, apr_size_t *len);

/**
 * Setup socket options for the specified socket
 * @param sock The socket to set up.
 * @param opt The option we would like to configure.  One of:
 * <PRE>
 *            APR_SO_DEBUG      --  turn on debugging information 
 *            APR_SO_KEEPALIVE  --  keep connections active
 *            APR_SO_LINGER     --  lingers on close if data is present
 *            APR_SO_NONBLOCK   --  Turns blocking on/off for socket
 *                                  When this option is enabled, use
 *                                  the APR_STATUS_IS_EAGAIN() macro to
 *                                  see if a send or receive function
 *                                  could not transfer data without
 *                                  blocking.
 *            APR_SO_REUSEADDR  --  The rules used in validating addresses
 *                                  supplied to bind should allow reuse
 *                                  of local addresses.
 *            APR_SO_SNDBUF     --  Set the SendBufferSize
 *            APR_SO_RCVBUF     --  Set the ReceiveBufferSize
 *            APR_SO_FREEBIND   --  Allow binding to non-local IP address.
 * </PRE>
 * @param on Value for the option.
 */
APR_DECLARE(apr_status_t) apr_socket_opt_set(apr_socket_t *sock,
                                             apr_int32_t opt, apr_int32_t on);

/**
 * Setup socket timeout for the specified socket
 * @param sock The socket to set up.
 * @param t Value for the timeout.
 * <PRE>
 *   t > 0  -- read and write calls return APR_TIMEUP if specified time
 *             elapsess with no data read or written
 *   t == 0 -- read and write calls never block
 *   t < 0  -- read and write calls block
 * </PRE>
 */
APR_DECLARE(apr_status_t) apr_socket_timeout_set(apr_socket_t *sock,
                                                 apr_interval_time_t t);

/**
 * Query socket options for the specified socket
 * @param sock The socket to query
 * @param opt The option we would like to query.  One of:
 * <PRE>
 *            APR_SO_DEBUG      --  turn on debugging information 
 *            APR_SO_KEEPALIVE  --  keep connections active
 *            APR_SO_LINGER     --  lingers on close if data is present
 *            APR_SO_NONBLOCK   --  Turns blocking on/off for socket
 *            APR_SO_REUSEADDR  --  The rules used in validating addresses
 *                                  supplied to bind should allow reuse
 *                                  of local addresses.
 *            APR_SO_SNDBUF     --  Set the SendBufferSize
 *            APR_SO_RCVBUF     --  Set the ReceiveBufferSize
 *            APR_SO_DISCONNECTED -- Query the disconnected state of the socket.
 *                                  (Currently only used on Windows)
 * </PRE>
 * @param on Socket option returned on the call.
 */
APR_DECLARE(apr_status_t) apr_socket_opt_get(apr_socket_t *sock, 
                                             apr_int32_t opt, apr_int32_t *on);

/**
 * Query socket timeout for the specified socket
 * @param sock The socket to query
 * @param t Socket timeout returned from the query.
 */
APR_DECLARE(apr_status_t) apr_socket_timeout_get(apr_socket_t *sock, 
                                                 apr_interval_time_t *t);

/**
 * Query the specified socket if at the OOB/Urgent data mark
 * @param sock The socket to query
 * @param atmark Is set to true if socket is at the OOB/urgent mark,
 *               otherwise is set to false.
 */
APR_DECLARE(apr_status_t) apr_socket_atmark(apr_socket_t *sock, 
                                            int *atmark);

/**
 * Return an address associated with a socket; either the address to
 * which the socket is bound locally or the address of the peer
 * to which the socket is connected.
 * @param sa The returned apr_sockaddr_t.
 * @param which Whether to retrieve the local or remote address
 * @param sock The socket to use
 */
APR_DECLARE(apr_status_t) apr_socket_addr_get(apr_sockaddr_t **sa,
                                              apr_interface_e which,
                                              apr_socket_t *sock);
 
/**
 * Return the IP address (in numeric address string format) in
 * an APR socket address.  APR will allocate storage for the IP address 
 * string from the pool of the apr_sockaddr_t.
 * @param addr The IP address.
 * @param sockaddr The socket address to reference.
 */
APR_DECLARE(apr_status_t) apr_sockaddr_ip_get(char **addr, 
                                              apr_sockaddr_t *sockaddr);

/**
 * Write the IP address (in numeric address string format) of the APR
 * socket address @a sockaddr into the buffer @a buf (of size @a buflen).
 * @param sockaddr The socket address to reference.
 */
APR_DECLARE(apr_status_t) apr_sockaddr_ip_getbuf(char *buf, apr_size_t buflen,
                                                 apr_sockaddr_t *sockaddr);

/**
 * See if the IP addresses in two APR socket addresses are
 * equivalent.  Appropriate logic is present for comparing
 * IPv4-mapped IPv6 addresses with IPv4 addresses.
 *
 * @param addr1 One of the APR socket addresses.
 * @param addr2 The other APR socket address.
 * @remark The return value will be non-zero if the addresses
 * are equivalent.
 */
APR_DECLARE(int) apr_sockaddr_equal(const apr_sockaddr_t *addr1,
                                    const apr_sockaddr_t *addr2);

/**
 * See if the IP address in an APR socket address refers to the wildcard
 * address for the protocol family (e.g., INADDR_ANY for IPv4).
 *
 * @param addr The APR socket address to examine.
 * @remark The return value will be non-zero if the address is
 * initialized and is the wildcard address.
 */
APR_DECLARE(int) apr_sockaddr_is_wildcard(const apr_sockaddr_t *addr);

/**
* Return the type of the socket.
* @param sock The socket to query.
* @param type The returned type (e.g., SOCK_STREAM).
*/
APR_DECLARE(apr_status_t) apr_socket_type_get(apr_socket_t *sock,
                                              int *type);
 
/**
 * Given an apr_sockaddr_t and a service name, set the port for the service
 * @param sockaddr The apr_sockaddr_t that will have its port set
 * @param servname The name of the service you wish to use
 */
APR_DECLARE(apr_status_t) apr_getservbyname(apr_sockaddr_t *sockaddr, 
                                            const char *servname);
/**
 * Build an ip-subnet representation from an IP address and optional netmask or
 * number-of-bits.
 * @param ipsub The new ip-subnet representation
 * @param ipstr The input IP address string
 * @param mask_or_numbits The input netmask or number-of-bits string, or NULL
 * @param p The pool to allocate from
 */
APR_DECLARE(apr_status_t) apr_ipsubnet_create(apr_ipsubnet_t **ipsub, 
                                              const char *ipstr, 
                                              const char *mask_or_numbits, 
                                              apr_pool_t *p);

/**
 * Test the IP address in an apr_sockaddr_t against a pre-built ip-subnet
 * representation.
 * @param ipsub The ip-subnet representation
 * @param sa The socket address to test
 * @return non-zero if the socket address is within the subnet, 0 otherwise
 */
APR_DECLARE(int) apr_ipsubnet_test(apr_ipsubnet_t *ipsub, apr_sockaddr_t *sa);

#if APR_HAS_SO_ACCEPTFILTER || defined(DOXYGEN)
/**
 * Set an OS level accept filter.
 * @param sock The socket to put the accept filter on.
 * @param name The accept filter
 * @param args Any extra args to the accept filter.  Passing NULL here removes
 *             the accept filter. 
 * @bug name and args should have been declared as const char *, as they are in
 * APR 2.0
 */
apr_status_t apr_socket_accept_filter(apr_socket_t *sock, char *name,
                                      char *args);
#endif

/**
 * Return the protocol of the socket.
 * @param sock The socket to query.
 * @param protocol The returned protocol (e.g., APR_PROTO_TCP).
 */
APR_DECLARE(apr_status_t) apr_socket_protocol_get(apr_socket_t *sock,
                                                  int *protocol);

/**
 * Get the pool used by the socket.
 */
APR_POOL_DECLARE_ACCESSOR(socket);

/**
 * Set a socket to be inherited by child processes.
 */
APR_DECLARE_INHERIT_SET(socket);

/**
 * Unset a socket from being inherited by child processes.
 */
APR_DECLARE_INHERIT_UNSET(socket);

/**
 * Set socket permissions.
 */
APR_PERMS_SET_IMPLEMENT(socket);

/**
 * @defgroup apr_mcast IP Multicast
 * @{
 */

/**
 * Join a Multicast Group
 * @param sock The socket to join a multicast group
 * @param join The address of the multicast group to join
 * @param iface Address of the interface to use.  If NULL is passed, the 
 *              default multicast interface will be used. (OS Dependent)
 * @param source Source Address to accept transmissions from (non-NULL 
 *               implies Source-Specific Multicast)
 */
APR_DECLARE(apr_status_t) apr_mcast_join(apr_socket_t *sock,
                                         apr_sockaddr_t *join,
                                         apr_sockaddr_t *iface,
                                         apr_sockaddr_t *source);

/**
 * Leave a Multicast Group.  All arguments must be the same as
 * apr_mcast_join.
 * @param sock The socket to leave a multicast group
 * @param addr The address of the multicast group to leave
 * @param iface Address of the interface to use.  If NULL is passed, the 
 *              default multicast interface will be used. (OS Dependent)
 * @param source Source Address to accept transmissions from (non-NULL 
 *               implies Source-Specific Multicast)
 */
APR_DECLARE(apr_status_t) apr_mcast_leave(apr_socket_t *sock,
                                          apr_sockaddr_t *addr,
                                          apr_sockaddr_t *iface,
                                          apr_sockaddr_t *source);

/**
 * Set the Multicast Time to Live (ttl) for a multicast transmission.
 * @param sock The socket to set the multicast ttl
 * @param ttl Time to live to Assign. 0-255, default=1
 * @remark If the TTL is 0, packets will only be seen by sockets on 
 * the local machine, and only when multicast loopback is enabled.
 */
APR_DECLARE(apr_status_t) apr_mcast_hops(apr_socket_t *sock,
                                         apr_byte_t ttl);

/**
 * Toggle IP Multicast Loopback
 * @param sock The socket to set multicast loopback
 * @param opt 0=disable, 1=enable
 */
APR_DECLARE(apr_status_t) apr_mcast_loopback(apr_socket_t *sock,
                                             apr_byte_t opt);


/**
 * Set the Interface to be used for outgoing Multicast Transmissions.
 * @param sock The socket to set the multicast interface on
 * @param iface Address of the interface to use for Multicast
 */
APR_DECLARE(apr_status_t) apr_mcast_interface(apr_socket_t *sock,
                                              apr_sockaddr_t *iface);

/** @} */

/** @} */

#ifdef __cplusplus
}
#endif

#endif  /* ! APR_NETWORK_IO_H */

apr-1/apr_env.h000064400000004071151730340510007270 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_ENV_H
#define APR_ENV_H
/**
 * @file apr_env.h
 * @brief APR Environment functions
 */
#include "apr_errno.h"
#include "apr_pools.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @defgroup apr_env Functions for manipulating the environment
 * @ingroup APR 
 * @{
 */

/**
 * Get the value of an environment variable
 * @param value the returned value, allocated from @a pool
 * @param envvar the name of the environment variable
 * @param pool where to allocate @a value and any temporary storage from
 */
APR_DECLARE(apr_status_t) apr_env_get(char **value, const char *envvar,
                                      apr_pool_t *pool);

/**
 * Set the value of an environment variable
 * @param envvar the name of the environment variable
 * @param value the value to set
 * @param pool where to allocate temporary storage from
 */
APR_DECLARE(apr_status_t) apr_env_set(const char *envvar, const char *value,
                                      apr_pool_t *pool);

/**
 * Delete a variable from the environment
 * @param envvar the name of the environment variable
 * @param pool where to allocate temporary storage from
 */
APR_DECLARE(apr_status_t) apr_env_delete(const char *envvar, apr_pool_t *pool);

/** @} */

#ifdef __cplusplus
}
#endif

#endif  /* ! APR_ENV_H */
apr-1/apu_want.h000064400000002713151730340510007455 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "apu.h"        /* configuration data */

/**
 * @file apu_want.h
 * @brief APR Standard Headers Support
 *
 * <PRE>
 * Features:
 *
 *   APU_WANT_DB:       <db.h>
 *
 * Typical usage:
 *
 *   #define APU_WANT_DB
 *   #include "apu_want.h"
 *
 * The appropriate headers will be included.
 *
 * Note: it is safe to use this in a header (it won't interfere with other
 *       headers' or source files' use of apu_want.h)
 * </PRE>
 */

/* --------------------------------------------------------------------- */

#ifdef APU_WANT_DB

#if APU_HAVE_DB
#include <db.h>
#endif

#undef APU_WANT_DB
#endif

/* --------------------------------------------------------------------- */
apr-1/apu_errno.h000064400000012504151730340510007630 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APU_ERRNO_H
#define APU_ERRNO_H

/**
 * @file apu_errno.h
 * @brief APR-Util Error Codes
 */

#include "apr.h"
#include "apr_errno.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @defgroup apu_errno Error Codes
 * @ingroup APR_Util
 * @{
 */

/**
 * @defgroup APR_Util_Error APR_Util Error Values
 * <PRE>
 * <b>APU ERROR VALUES</b>
 * APR_ENOKEY         The key provided was empty or NULL
 * APR_ENOIV          The initialisation vector provided was NULL
 * APR_EKEYTYPE       The key type was not recognised
 * APR_ENOSPACE       The buffer supplied was not big enough
 * APR_ECRYPT         An error occurred while encrypting or decrypting
 * APR_EPADDING       Padding was not supported
 * APR_EKEYLENGTH     The key length was incorrect
 * APR_ENOCIPHER      The cipher provided was not recognised
 * APR_ENODIGEST      The digest provided was not recognised
 * APR_ENOENGINE      The engine provided was not recognised
 * APR_EINITENGINE    The engine could not be initialised
 * APR_EREINIT        Underlying crypto has already been initialised
 * </PRE>
 *
 * <PRE>
 * <b>APR STATUS VALUES</b>
 * APR_INCHILD        Program is currently executing in the child
 * </PRE>
 * @{
 */
/** @see APR_STATUS_IS_ENOKEY */
#define APR_ENOKEY           (APR_UTIL_START_STATUS + 1)
/** @see APR_STATUS_IS_ENOIV */
#define APR_ENOIV            (APR_UTIL_START_STATUS + 2)
/** @see APR_STATUS_IS_EKEYTYPE */
#define APR_EKEYTYPE         (APR_UTIL_START_STATUS + 3)
/** @see APR_STATUS_IS_ENOSPACE */
#define APR_ENOSPACE         (APR_UTIL_START_STATUS + 4)
/** @see APR_STATUS_IS_ECRYPT */
#define APR_ECRYPT           (APR_UTIL_START_STATUS + 5)
/** @see APR_STATUS_IS_EPADDING */
#define APR_EPADDING         (APR_UTIL_START_STATUS + 6)
/** @see APR_STATUS_IS_EKEYLENGTH */
#define APR_EKEYLENGTH       (APR_UTIL_START_STATUS + 7)
/** @see APR_STATUS_IS_ENOCIPHER */
#define APR_ENOCIPHER        (APR_UTIL_START_STATUS + 8)
/** @see APR_STATUS_IS_ENODIGEST */
#define APR_ENODIGEST        (APR_UTIL_START_STATUS + 9)
/** @see APR_STATUS_IS_ENOENGINE */
#define APR_ENOENGINE        (APR_UTIL_START_STATUS + 10)
/** @see APR_STATUS_IS_EINITENGINE */
#define APR_EINITENGINE      (APR_UTIL_START_STATUS + 11)
/** @see APR_STATUS_IS_EREINIT */
#define APR_EREINIT          (APR_UTIL_START_STATUS + 12)
/** @} */

/**
 * @defgroup APU_STATUS_IS Status Value Tests
 * @warning For any particular error condition, more than one of these tests
 *      may match. This is because platform-specific error codes may not
 *      always match the semantics of the POSIX codes these tests (and the
 *      corresponding APR error codes) are named after. A notable example
 *      are the APR_STATUS_IS_ENOENT and APR_STATUS_IS_ENOTDIR tests on
 *      Win32 platforms. The programmer should always be aware of this and
 *      adjust the order of the tests accordingly.
 * @{
 */

/** @} */

/**
 * @addtogroup APR_Util_Error
 * @{
 */
/**
 * The key was empty or not provided
 */
#define APR_STATUS_IS_ENOKEY(s)        ((s) == APR_ENOKEY)
/**
 * The initialisation vector was not provided
 */
#define APR_STATUS_IS_ENOIV(s)        ((s) == APR_ENOIV)
/**
 * The key type was not recognised
 */
#define APR_STATUS_IS_EKEYTYPE(s)        ((s) == APR_EKEYTYPE)
/**
 * The buffer provided was not big enough
 */
#define APR_STATUS_IS_ENOSPACE(s)        ((s) == APR_ENOSPACE)
/**
 * An error occurred while encrypting or decrypting
 */
#define APR_STATUS_IS_ECRYPT(s)        ((s) == APR_ECRYPT)
/**
 * An error occurred while padding
 */
#define APR_STATUS_IS_EPADDING(s)        ((s) == APR_EPADDING)
/**
 * An error occurred with the key length
 */
#define APR_STATUS_IS_EKEYLENGTH(s)        ((s) == APR_EKEYLENGTH)
/**
 * The cipher provided was not recognised
 */
#define APR_STATUS_IS_ENOCIPHER(s)        ((s) == APR_ENOCIPHER)
/**
 * The digest provided was not recognised
 */
#define APR_STATUS_IS_ENODIGEST(s)        ((s) == APR_ENODIGEST)
/**
 * The engine provided was not recognised
 */
#define APR_STATUS_IS_ENOENGINE(s)        ((s) == APR_ENOENGINE)
/**
 * The engine could not be initialised
 */
#define APR_STATUS_IS_EINITENGINE(s)        ((s) == APR_EINITENGINE)
/**
 * Crypto has already been initialised
 */
#define APR_STATUS_IS_EREINIT(s)        ((s) == APR_EREINIT)
/** @} */

/**
 * This structure allows the underlying API error codes to be returned
 * along with plain text error messages that explain to us mere mortals
 * what really happened.
 */
typedef struct apu_err_t {
    const char *reason;
    const char *msg;
    int rc;
} apu_err_t;

/** @} */

#ifdef __cplusplus
}
#endif

#endif  /* ! APU_ERRNO_H */
apr-1/apr_buckets.h000064400000176225151730340510010153 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * @file apr_buckets.h
 * @brief APR-UTIL Buckets/Bucket Brigades
 */

#ifndef APR_BUCKETS_H
#define APR_BUCKETS_H

#if defined(APR_BUCKET_DEBUG) && !defined(APR_RING_DEBUG)
#define APR_RING_DEBUG
#endif

#include "apu.h"
#include "apr_network_io.h"
#include "apr_file_io.h"
#include "apr_general.h"
#include "apr_mmap.h"
#include "apr_errno.h"
#include "apr_ring.h"
#include "apr.h"
#if APR_HAVE_SYS_UIO_H
#include <sys/uio.h>	/* for struct iovec */
#endif
#if APR_HAVE_STDARG_H
#include <stdarg.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @defgroup APR_Util_Bucket_Brigades Bucket Brigades
 * @ingroup APR_Util
 * @{ 
 */

/** default bucket buffer size - 8KB minus room for memory allocator headers */
#define APR_BUCKET_BUFF_SIZE 8000

/** Determines how a bucket or brigade should be read */
typedef enum {
    APR_BLOCK_READ,   /**< block until data becomes available */
    APR_NONBLOCK_READ /**< return immediately if no data is available */
} apr_read_type_e;

/**
 * The one-sentence buzzword-laden overview: Bucket brigades represent
 * a complex data stream that can be passed through a layered IO
 * system without unnecessary copying. A longer overview follows...
 *
 * A bucket brigade is a doubly linked list (ring) of buckets, so we
 * aren't limited to inserting at the front and removing at the end.
 * Buckets are only passed around as members of a brigade, although
 * singleton buckets can occur for short periods of time.
 *
 * Buckets are data stores of various types. They can refer to data in
 * memory, or part of a file or mmap area, or the output of a process,
 * etc. Buckets also have some type-dependent accessor functions:
 * read, split, copy, setaside, and destroy.
 *
 * read returns the address and size of the data in the bucket. If the
 * data isn't in memory then it is read in and the bucket changes type
 * so that it can refer to the new location of the data. If all the
 * data doesn't fit in the bucket then a new bucket is inserted into
 * the brigade to hold the rest of it.
 *
 * split divides the data in a bucket into two regions. After a split
 * the original bucket refers to the first part of the data and a new
 * bucket inserted into the brigade after the original bucket refers
 * to the second part of the data. Reference counts are maintained as
 * necessary.
 *
 * setaside ensures that the data in the bucket has a long enough
 * lifetime. Sometimes it is convenient to create a bucket referring
 * to data on the stack in the expectation that it will be consumed
 * (output to the network) before the stack is unwound. If that
 * expectation turns out not to be valid, the setaside function is
 * called to move the data somewhere safer.
 *
 * copy makes a duplicate of the bucket structure as long as it's
 * possible to have multiple references to a single copy of the
 * data itself.  Not all bucket types can be copied.
 *
 * destroy maintains the reference counts on the resources used by a
 * bucket and frees them if necessary.
 *
 * Note: all of the above functions have wrapper macros (apr_bucket_read(),
 * apr_bucket_destroy(), etc), and those macros should be used rather
 * than using the function pointers directly.
 *
 * To write a bucket brigade, they are first made into an iovec, so that we
 * don't write too little data at one time.  Currently we ignore compacting the
 * buckets into as few buckets as possible, but if we really want good
 * performance, then we need to compact the buckets before we convert to an
 * iovec, or possibly while we are converting to an iovec.
 */

/*
 * Forward declaration of the main types.
 */

/** @see apr_bucket_brigade */
typedef struct apr_bucket_brigade apr_bucket_brigade;
/** @see apr_bucket */
typedef struct apr_bucket apr_bucket;
/** @see apr_bucket_alloc_t */
typedef struct apr_bucket_alloc_t apr_bucket_alloc_t;

/** @see apr_bucket_type_t */
typedef struct apr_bucket_type_t apr_bucket_type_t;

/**
 * Basic bucket type
 */
struct apr_bucket_type_t {
    /**
     * The name of the bucket type
     */
    const char *name;
    /** 
     * The number of functions this bucket understands.  Can not be less than
     * five.
     */
    int num_func;
    /**
     * Whether the bucket contains metadata (ie, information that
     * describes the regular contents of the brigade).  The metadata
     * is not returned by apr_bucket_read() and is not indicated by
     * the ->length of the apr_bucket itself.  In other words, an
     * empty bucket is safe to arbitrarily remove if and only if it
     * contains no metadata.  In this sense, "data" is just raw bytes
     * that are the "content" of the brigade and "metadata" describes
     * that data but is not a proper part of it.
     */
    enum {
        /** This bucket type represents actual data to send to the client. */
        APR_BUCKET_DATA = 0,
        /** This bucket type represents metadata. */
        APR_BUCKET_METADATA = 1
    } is_metadata;
    /**
     * Free the private data and any resources used by the bucket (if they
     *  aren't shared with another bucket).  This function is required to be
     *  implemented for all bucket types, though it might be a no-op on some
     *  of them (namely ones that never allocate any private data structures).
     * @param data The private data pointer from the bucket to be destroyed
     */
    void (*destroy)(void *data);

    /**
     * Read the data from the bucket. This is required to be implemented
     *  for all bucket types.
     * @param b The bucket to read from
     * @param str A place to store the data read.  Allocation should only be
     *            done if absolutely necessary. 
     * @param len The amount of data read.
     * @param block Should this read function block if there is more data that
     *              cannot be read immediately.
     */
    apr_status_t (*read)(apr_bucket *b, const char **str, apr_size_t *len, 
                         apr_read_type_e block);
    
    /**
     * Make it possible to set aside the data for at least as long as the
     *  given pool. Buckets containing data that could potentially die before
     *  this pool (e.g. the data resides on the stack, in a child pool of
     *  the given pool, or in a disjoint pool) must somehow copy, shift, or
     *  transform the data to have the proper lifetime.
     * @param e The bucket to convert
     * @remark Some bucket types contain data that will always outlive the
     *         bucket itself. For example no data (EOS and FLUSH), or the data
     *         resides in global, constant memory (IMMORTAL), or the data is on
     *      the heap (HEAP). For these buckets, apr_bucket_setaside_noop can
     *      be used.
     */
    apr_status_t (*setaside)(apr_bucket *e, apr_pool_t *pool);

    /**
     * Split one bucket in two at the specified position by duplicating
     *  the bucket structure (not the data) and modifying any necessary
     *  start/end/offset information.  If it's not possible to do this
     *  for the bucket type (perhaps the length of the data is indeterminate,
     *  as with pipe and socket buckets), then APR_ENOTIMPL is returned.
     * @param e The bucket to split
     * @param point The offset of the first byte in the new bucket
     */
    apr_status_t (*split)(apr_bucket *e, apr_size_t point);

    /**
     * Copy the bucket structure (not the data), assuming that this is
     *  possible for the bucket type. If it's not, APR_ENOTIMPL is returned.
     * @param e The bucket to copy
     * @param c Returns a pointer to the new bucket
     */
    apr_status_t (*copy)(apr_bucket *e, apr_bucket **c);

};

/**
 * apr_bucket structures are allocated on the malloc() heap and
 * their lifetime is controlled by the parent apr_bucket_brigade
 * structure. Buckets can move from one brigade to another e.g. by
 * calling APR_BRIGADE_CONCAT(). In general the data in a bucket has
 * the same lifetime as the bucket and is freed when the bucket is
 * destroyed; if the data is shared by more than one bucket (e.g.
 * after a split) the data is freed when the last bucket goes away.
 */
struct apr_bucket {
    /** Links to the rest of the brigade */
    APR_RING_ENTRY(apr_bucket) link;
    /** The type of bucket.  */
    const apr_bucket_type_t *type;
    /** The length of the data in the bucket.  This could have been implemented
     *  with a function, but this is an optimization, because the most
     *  common thing to do will be to get the length.  If the length is unknown,
     *  the value of this field will be (apr_size_t)(-1).
     */
    apr_size_t length;
    /** The start of the data in the bucket relative to the private base
     *  pointer.  The vast majority of bucket types allow a fixed block of
     *  data to be referenced by multiple buckets, each bucket pointing to
     *  a different segment of the data.  That segment starts at base+start
     *  and ends at base+start+length.  
     *  If the length == (apr_size_t)(-1), then start == -1.
     */
    apr_off_t start;
    /** type-dependent data hangs off this pointer */
    void *data;	
    /**
     * Pointer to function used to free the bucket. This function should
     * always be defined and it should be consistent with the memory
     * function used to allocate the bucket. For example, if malloc() is 
     * used to allocate the bucket, this pointer should point to free().
     * @param e Pointer to the bucket being freed
     */
    void (*free)(void *e);
    /** The freelist from which this bucket was allocated */
    apr_bucket_alloc_t *list;
};

/** A list of buckets */
struct apr_bucket_brigade {
    /** The pool to associate the brigade with.  The data is not allocated out
     *  of the pool, but a cleanup is registered with this pool.  If the 
     *  brigade is destroyed by some mechanism other than pool destruction,
     *  the destroying function is responsible for killing the cleanup.
     */
    apr_pool_t *p;
    /** The buckets in the brigade are on this list. */
    /*
     * The apr_bucket_list structure doesn't actually need a name tag
     * because it has no existence independent of struct apr_bucket_brigade;
     * the ring macros are designed so that you can leave the name tag
     * argument empty in this situation but apparently the Windows compiler
     * doesn't like that.
     */
    APR_RING_HEAD(apr_bucket_list, apr_bucket) list;
    /** The freelist from which this bucket was allocated */
    apr_bucket_alloc_t *bucket_alloc;
};


/**
 * Function called when a brigade should be flushed
 */
typedef apr_status_t (*apr_brigade_flush)(apr_bucket_brigade *bb, void *ctx);

/*
 * define APR_BUCKET_DEBUG if you want your brigades to be checked for
 * validity at every possible instant.  this will slow your code down
 * substantially but is a very useful debugging tool.
 */
#ifdef APR_BUCKET_DEBUG

#define APR_BRIGADE_CHECK_CONSISTENCY(b)				\
        APR_RING_CHECK_CONSISTENCY(&(b)->list, apr_bucket, link)

#define APR_BUCKET_CHECK_CONSISTENCY(e)					\
        APR_RING_CHECK_ELEM_CONSISTENCY((e), apr_bucket, link)

#else
/**
 * checks the ring pointers in a bucket brigade for consistency.  an
 * abort() will be triggered if any inconsistencies are found.
 *   note: this is a no-op unless APR_BUCKET_DEBUG is defined.
 * @param b The brigade
 */
#define APR_BRIGADE_CHECK_CONSISTENCY(b)
/**
 * checks the brigade a bucket is in for ring consistency.  an
 * abort() will be triggered if any inconsistencies are found.
 *   note: this is a no-op unless APR_BUCKET_DEBUG is defined.
 * @param e The bucket
 */
#define APR_BUCKET_CHECK_CONSISTENCY(e)
#endif


/**
 * Wrappers around the RING macros to reduce the verbosity of the code
 * that handles bucket brigades.
 */
/**
 * The magic pointer value that indicates the head of the brigade
 * @remark This is used to find the beginning and end of the brigade, eg:
 * <pre>
 *      while (e != APR_BRIGADE_SENTINEL(b)) {
 *          ...
 *          e = APR_BUCKET_NEXT(e);
 *      }
 * </pre>
 * @param  b The brigade
 * @return The magic pointer value
 */
#define APR_BRIGADE_SENTINEL(b)	APR_RING_SENTINEL(&(b)->list, apr_bucket, link)

/**
 * Determine if the bucket brigade is empty
 * @param b The brigade to check
 * @return true or false
 */
#define APR_BRIGADE_EMPTY(b)	APR_RING_EMPTY(&(b)->list, apr_bucket, link)

/**
 * Return the first bucket in a brigade
 * @param b The brigade to query
 * @return The first bucket in the brigade
 */
#define APR_BRIGADE_FIRST(b)	APR_RING_FIRST(&(b)->list)
/**
 * Return the last bucket in a brigade
 * @param b The brigade to query
 * @return The last bucket in the brigade
 */
#define APR_BRIGADE_LAST(b)	APR_RING_LAST(&(b)->list)

/**
 * Insert a single bucket at the front of a brigade
 * @param b The brigade to add to
 * @param e The bucket to insert
 */
#define APR_BRIGADE_INSERT_HEAD(b, e) do {				\
	apr_bucket *ap__b = (e);                                        \
	APR_RING_INSERT_HEAD(&(b)->list, ap__b, apr_bucket, link);	\
        APR_BRIGADE_CHECK_CONSISTENCY((b));				\
    } while (0)

/**
 * Insert a single bucket at the end of a brigade
 * @param b The brigade to add to
 * @param e The bucket to insert
 */
#define APR_BRIGADE_INSERT_TAIL(b, e) do {				\
	apr_bucket *ap__b = (e);					\
	APR_RING_INSERT_TAIL(&(b)->list, ap__b, apr_bucket, link);	\
        APR_BRIGADE_CHECK_CONSISTENCY((b));				\
    } while (0)

/**
 * Concatenate brigade b onto the end of brigade a, leaving brigade b empty
 * @param a The first brigade
 * @param b The second brigade
 */
#define APR_BRIGADE_CONCAT(a, b) do {					\
        APR_RING_CONCAT(&(a)->list, &(b)->list, apr_bucket, link);	\
        APR_BRIGADE_CHECK_CONSISTENCY((a));				\
    } while (0)

/**
 * Prepend brigade b onto the beginning of brigade a, leaving brigade b empty
 * @param a The first brigade
 * @param b The second brigade
 */
#define APR_BRIGADE_PREPEND(a, b) do {					\
        APR_RING_PREPEND(&(a)->list, &(b)->list, apr_bucket, link);	\
        APR_BRIGADE_CHECK_CONSISTENCY((a));				\
    } while (0)

/**
 * Insert a single bucket before a specified bucket
 * @param a The bucket to insert before
 * @param b The bucket to insert
 */
#define APR_BUCKET_INSERT_BEFORE(a, b) do {				\
	apr_bucket *ap__a = (a), *ap__b = (b);				\
	APR_RING_INSERT_BEFORE(ap__a, ap__b, link);			\
        APR_BUCKET_CHECK_CONSISTENCY(ap__a);				\
    } while (0)

/**
 * Insert a single bucket after a specified bucket
 * @param a The bucket to insert after
 * @param b The bucket to insert
 */
#define APR_BUCKET_INSERT_AFTER(a, b) do {				\
	apr_bucket *ap__a = (a), *ap__b = (b);				\
	APR_RING_INSERT_AFTER(ap__a, ap__b, link);			\
        APR_BUCKET_CHECK_CONSISTENCY(ap__a);				\
    } while (0)

/**
 * Get the next bucket in the list
 * @param e The current bucket
 * @return The next bucket
 */
#define APR_BUCKET_NEXT(e)	APR_RING_NEXT((e), link)
/**
 * Get the previous bucket in the list
 * @param e The current bucket
 * @return The previous bucket
 */
#define APR_BUCKET_PREV(e)	APR_RING_PREV((e), link)

/**
 * Remove a bucket from its bucket brigade
 * @param e The bucket to remove
 */
#define APR_BUCKET_REMOVE(e)	APR_RING_REMOVE((e), link)

/**
 * Initialize a new bucket's prev/next pointers
 * @param e The bucket to initialize
 */
#define APR_BUCKET_INIT(e)	APR_RING_ELEM_INIT((e), link)

/**
 * Determine if a bucket contains metadata.  An empty bucket is
 * safe to arbitrarily remove if and only if this is false.
 * @param e The bucket to inspect
 * @return true or false
 */
#define APR_BUCKET_IS_METADATA(e)    ((e)->type->is_metadata)

/**
 * Determine if a bucket is a FLUSH bucket
 * @param e The bucket to inspect
 * @return true or false
 */
#define APR_BUCKET_IS_FLUSH(e)       ((e)->type == &apr_bucket_type_flush)
/**
 * Determine if a bucket is an EOS bucket
 * @param e The bucket to inspect
 * @return true or false
 */
#define APR_BUCKET_IS_EOS(e)         ((e)->type == &apr_bucket_type_eos)
/**
 * Determine if a bucket is a FILE bucket
 * @param e The bucket to inspect
 * @return true or false
 */
#define APR_BUCKET_IS_FILE(e)        ((e)->type == &apr_bucket_type_file)
/**
 * Determine if a bucket is a PIPE bucket
 * @param e The bucket to inspect
 * @return true or false
 */
#define APR_BUCKET_IS_PIPE(e)        ((e)->type == &apr_bucket_type_pipe)
/**
 * Determine if a bucket is a SOCKET bucket
 * @param e The bucket to inspect
 * @return true or false
 */
#define APR_BUCKET_IS_SOCKET(e)      ((e)->type == &apr_bucket_type_socket)
/**
 * Determine if a bucket is a HEAP bucket
 * @param e The bucket to inspect
 * @return true or false
 */
#define APR_BUCKET_IS_HEAP(e)        ((e)->type == &apr_bucket_type_heap)
/**
 * Determine if a bucket is a TRANSIENT bucket
 * @param e The bucket to inspect
 * @return true or false
 */
#define APR_BUCKET_IS_TRANSIENT(e)   ((e)->type == &apr_bucket_type_transient)
/**
 * Determine if a bucket is a IMMORTAL bucket
 * @param e The bucket to inspect
 * @return true or false
 */
#define APR_BUCKET_IS_IMMORTAL(e)    ((e)->type == &apr_bucket_type_immortal)
#if APR_HAS_MMAP
/**
 * Determine if a bucket is a MMAP bucket
 * @param e The bucket to inspect
 * @return true or false
 */
#define APR_BUCKET_IS_MMAP(e)        ((e)->type == &apr_bucket_type_mmap)
#endif
/**
 * Determine if a bucket is a POOL bucket
 * @param e The bucket to inspect
 * @return true or false
 */
#define APR_BUCKET_IS_POOL(e)        ((e)->type == &apr_bucket_type_pool)

/*
 * General-purpose reference counting for the various bucket types.
 *
 * Any bucket type that keeps track of the resources it uses (i.e.
 * most of them except for IMMORTAL, TRANSIENT, and EOS) needs to
 * attach a reference count to the resource so that it can be freed
 * when the last bucket that uses it goes away. Resource-sharing may
 * occur because of bucket splits or buckets that refer to globally
 * cached data. */

/** @see apr_bucket_refcount */
typedef struct apr_bucket_refcount apr_bucket_refcount;
/**
 * The structure used to manage the shared resource must start with an
 * apr_bucket_refcount which is updated by the general-purpose refcount
 * code. A pointer to the bucket-type-dependent private data structure
 * can be cast to a pointer to an apr_bucket_refcount and vice versa.
 */
struct apr_bucket_refcount {
    /** The number of references to this bucket */
    int          refcount;
};

/*  *****  Reference-counted bucket types  *****  */

/** @see apr_bucket_heap */
typedef struct apr_bucket_heap apr_bucket_heap;
/**
 * A bucket referring to data allocated off the heap.
 */
struct apr_bucket_heap {
    /** Number of buckets using this memory */
    apr_bucket_refcount  refcount;
    /** The start of the data actually allocated.  This should never be
     * modified, it is only used to free the bucket.
     */
    char    *base;
    /** how much memory was allocated */
    apr_size_t  alloc_len;
    /** function to use to delete the data */
    void (*free_func)(void *data);
};

/** @see apr_bucket_pool */
typedef struct apr_bucket_pool apr_bucket_pool;
/**
 * A bucket referring to data allocated from a pool
 */
struct apr_bucket_pool {
    /** The pool bucket must be able to be easily morphed to a heap
     * bucket if the pool gets cleaned up before all references are
     * destroyed.  This apr_bucket_heap structure is populated automatically
     * when the pool gets cleaned up, and subsequent calls to pool_read()
     * will result in the apr_bucket in question being morphed into a
     * regular heap bucket.  (To avoid having to do many extra refcount
     * manipulations and b->data manipulations, the apr_bucket_pool
     * struct actually *contains* the apr_bucket_heap struct that it
     * will become as its first element; the two share their
     * apr_bucket_refcount members.)
     */
    apr_bucket_heap  heap;
    /** The block of data actually allocated from the pool.
     * Segments of this block are referenced by adjusting
     * the start and length of the apr_bucket accordingly.
     * This will be NULL after the pool gets cleaned up.
     */
    const char *base;
    /** The pool the data was allocated from.  When the pool
     * is cleaned up, this gets set to NULL as an indicator
     * to pool_read() that the data is now on the heap and
     * so it should morph the bucket into a regular heap
     * bucket before continuing.
     */
    apr_pool_t *pool;
    /** The freelist this structure was allocated from, which is
     * needed in the cleanup phase in order to allocate space on the heap
     */
    apr_bucket_alloc_t *list;
};

#if APR_HAS_MMAP
/** @see apr_bucket_mmap */
typedef struct apr_bucket_mmap apr_bucket_mmap;
/**
 * A bucket referring to an mmap()ed file
 */
struct apr_bucket_mmap {
    /** Number of buckets using this memory */
    apr_bucket_refcount  refcount;
    /** The mmap this sub_bucket refers to */
    apr_mmap_t *mmap;
};
#endif

/** @see apr_bucket_file */
typedef struct apr_bucket_file apr_bucket_file;
/**
 * A bucket referring to an file
 */
struct apr_bucket_file {
    /** Number of buckets using this memory */
    apr_bucket_refcount  refcount;
    /** The file this bucket refers to */
    apr_file_t *fd;
    /** The pool into which any needed structures should
     *  be created while reading from this file bucket */
    apr_pool_t *readpool;
#if APR_HAS_MMAP
    /** Whether this bucket should be memory-mapped if
     *  a caller tries to read from it */
    int can_mmap;
#endif /* APR_HAS_MMAP */
    /** File read block size */
    apr_size_t read_size;
};

/** @see apr_bucket_structs */
typedef union apr_bucket_structs apr_bucket_structs;
/**
 * A union of all bucket structures so we know what
 * the max size is.
 */
union apr_bucket_structs {
    apr_bucket      b;      /**< Bucket */
    apr_bucket_heap heap;   /**< Heap */
    apr_bucket_pool pool;   /**< Pool */
#if APR_HAS_MMAP
    apr_bucket_mmap mmap;   /**< MMap */
#endif
    apr_bucket_file file;   /**< File */
};

/**
 * The amount that apr_bucket_alloc() should allocate in the common case.
 * Note: this is twice as big as apr_bucket_structs to allow breathing
 * room for third-party bucket types.
 */
#define APR_BUCKET_ALLOC_SIZE  APR_ALIGN_DEFAULT(2*sizeof(apr_bucket_structs))

/*  *****  Bucket Brigade Functions  *****  */
/**
 * Create a new bucket brigade.  The bucket brigade is originally empty.
 * @param p The pool to associate with the brigade.  Data is not allocated out
 *          of the pool, but a cleanup is registered.
 * @param list The bucket allocator to use
 * @return The empty bucket brigade
 */
APU_DECLARE(apr_bucket_brigade *) apr_brigade_create(apr_pool_t *p,
                                                     apr_bucket_alloc_t *list);

/**
 * destroy an entire bucket brigade.  This includes destroying all of the
 * buckets within the bucket brigade's bucket list. 
 * @param b The bucket brigade to destroy
 */
APU_DECLARE(apr_status_t) apr_brigade_destroy(apr_bucket_brigade *b);

/**
 * empty out an entire bucket brigade.  This includes destroying all of the
 * buckets within the bucket brigade's bucket list.  This is similar to
 * apr_brigade_destroy(), except that it does not deregister the brigade's
 * pool cleanup function.
 * @param data The bucket brigade to clean up
 * @remark Generally, you should use apr_brigade_destroy().  This function
 *         can be useful in situations where you have a single brigade that
 *         you wish to reuse many times by destroying all of the buckets in
 *         the brigade and putting new buckets into it later.
 */
APU_DECLARE(apr_status_t) apr_brigade_cleanup(void *data);

/**
 * Move the buckets from the tail end of the existing brigade @a b into
 * the brigade @a a. If @a a is NULL a new brigade is created. Buckets
 * from @a e to the last bucket (inclusively) of brigade @a b are moved
 * from @a b to the returned brigade @a a.
 *
 * @param b The brigade to split
 * @param e The first bucket to move
 * @param a The brigade which should be used for the result or NULL if
 *          a new brigade should be created. The brigade @a a will be
 *          cleared if it is not empty.
 * @return The brigade supplied in @a a or a new one if @a a was NULL.
 * @warning Note that this function allocates a new brigade if @a a is
 * NULL so memory consumption should be carefully considered.
 */
APU_DECLARE(apr_bucket_brigade *) apr_brigade_split_ex(apr_bucket_brigade *b,
                                                       apr_bucket *e,
                                                       apr_bucket_brigade *a);

/**
 * Create a new bucket brigade and move the buckets from the tail end
 * of an existing brigade into the new brigade.  Buckets from 
 * @a e to the last bucket (inclusively) of brigade @a b
 * are moved from @a b to the returned brigade.
 * @param b The brigade to split 
 * @param e The first bucket to move
 * @return The new brigade
 * @warning Note that this function always allocates a new brigade
 * so memory consumption should be carefully considered.
 */
APU_DECLARE(apr_bucket_brigade *) apr_brigade_split(apr_bucket_brigade *b,
                                                    apr_bucket *e);

/**
 * Partition a bucket brigade at a given offset (in bytes from the start of
 * the brigade).  This is useful whenever a filter wants to use known ranges
 * of bytes from the brigade; the ranges can even overlap.
 * @param b The brigade to partition
 * @param point The offset at which to partition the brigade
 * @param after_point Returns a pointer to the first bucket after the partition
 * @return APR_SUCCESS on success, APR_INCOMPLETE if the contents of the
 * brigade were shorter than @a point, or an error code.
 * @remark if APR_INCOMPLETE is returned, @a after_point will be set to
 * the brigade sentinel.
 */
APU_DECLARE(apr_status_t) apr_brigade_partition(apr_bucket_brigade *b,
                                                apr_off_t point,
                                                apr_bucket **after_point);

/**
 * Return the total length of the brigade.
 * @param bb The brigade to compute the length of
 * @param read_all Read unknown-length buckets to force a size
 * @param length Returns the length of the brigade (up to the end, or up
 *               to a bucket read error), or -1 if the brigade has buckets
 *               of indeterminate length and read_all is 0.
 */
APU_DECLARE(apr_status_t) apr_brigade_length(apr_bucket_brigade *bb,
                                             int read_all,
                                             apr_off_t *length);

/**
 * Take a bucket brigade and store the data in a flat char*
 * @param bb The bucket brigade to create the char* from
 * @param c The char* to write into
 * @param len The maximum length of the char array. On return, it is the
 *            actual length of the char array.
 */
APU_DECLARE(apr_status_t) apr_brigade_flatten(apr_bucket_brigade *bb,
                                              char *c,
                                              apr_size_t *len);

/**
 * Creates a pool-allocated string representing a flat bucket brigade
 * @param bb The bucket brigade to create the char array from
 * @param c On return, the allocated char array
 * @param len On return, the length of the char array.
 * @param pool The pool to allocate the string from.
 */
APU_DECLARE(apr_status_t) apr_brigade_pflatten(apr_bucket_brigade *bb, 
                                               char **c,
                                               apr_size_t *len,
                                               apr_pool_t *pool);

/**
 * Split a brigade to represent one LF line.
 * @param bbOut The bucket brigade that will have the LF line appended to.
 * @param bbIn The input bucket brigade to search for a LF-line.
 * @param block The blocking mode to be used to split the line.
 * @param maxbytes The maximum bytes to read.  If this many bytes are seen
 *                 without a LF, the brigade will contain a partial line.
 */
APU_DECLARE(apr_status_t) apr_brigade_split_line(apr_bucket_brigade *bbOut,
                                                 apr_bucket_brigade *bbIn,
                                                 apr_read_type_e block,
                                                 apr_off_t maxbytes);

/**
 * Create an iovec of the elements in a bucket_brigade... return number 
 * of elements used.  This is useful for writing to a file or to the
 * network efficiently.
 * @param b The bucket brigade to create the iovec from
 * @param vec The iovec to create
 * @param nvec The number of elements in the iovec. On return, it is the
 *             number of iovec elements actually filled out.
 */
APU_DECLARE(apr_status_t) apr_brigade_to_iovec(apr_bucket_brigade *b, 
                                               struct iovec *vec, int *nvec);

/**
 * This function writes a list of strings into a bucket brigade. 
 * @param b The bucket brigade to add to
 * @param flush The flush function to use if the brigade is full
 * @param ctx The structure to pass to the flush function
 * @param va A list of strings to add
 * @return APR_SUCCESS or error code.
 */
APU_DECLARE(apr_status_t) apr_brigade_vputstrs(apr_bucket_brigade *b,
                                               apr_brigade_flush flush,
                                               void *ctx,
                                               va_list va);

/**
 * This function writes a string into a bucket brigade.
 *
 * The apr_brigade_write function attempts to be efficient with the
 * handling of heap buckets. Regardless of the amount of data stored
 * inside a heap bucket, heap buckets are a fixed size to promote their
 * reuse.
 *
 * If an attempt is made to write a string to a brigade that already 
 * ends with a heap bucket, this function will attempt to pack the
 * string into the remaining space in the previous heap bucket, before
 * allocating a new heap bucket.
 *
 * This function always returns APR_SUCCESS, unless a flush function is
 * passed, in which case the return value of the flush function will be
 * returned if used.
 * @param b The bucket brigade to add to
 * @param flush The flush function to use if the brigade is full
 * @param ctx The structure to pass to the flush function
 * @param str The string to add
 * @param nbyte The number of bytes to write
 * @return APR_SUCCESS or error code
 */
APU_DECLARE(apr_status_t) apr_brigade_write(apr_bucket_brigade *b,
                                            apr_brigade_flush flush, void *ctx,
                                            const char *str, apr_size_t nbyte);

/**
 * This function writes multiple strings into a bucket brigade.
 * @param b The bucket brigade to add to
 * @param flush The flush function to use if the brigade is full
 * @param ctx The structure to pass to the flush function
 * @param vec The strings to add (address plus length for each)
 * @param nvec The number of entries in iovec
 * @return APR_SUCCESS or error code
 */
APU_DECLARE(apr_status_t) apr_brigade_writev(apr_bucket_brigade *b,
                                             apr_brigade_flush flush,
                                             void *ctx,
                                             const struct iovec *vec,
                                             apr_size_t nvec);

/**
 * This function writes a string into a bucket brigade.
 * @param bb The bucket brigade to add to
 * @param flush The flush function to use if the brigade is full
 * @param ctx The structure to pass to the flush function
 * @param str The string to add
 * @return APR_SUCCESS or error code
 */
APU_DECLARE(apr_status_t) apr_brigade_puts(apr_bucket_brigade *bb,
                                           apr_brigade_flush flush, void *ctx,
                                           const char *str);

/**
 * This function writes a character into a bucket brigade.
 * @param b The bucket brigade to add to
 * @param flush The flush function to use if the brigade is full
 * @param ctx The structure to pass to the flush function
 * @param c The character to add
 * @return APR_SUCCESS or error code
 */
APU_DECLARE(apr_status_t) apr_brigade_putc(apr_bucket_brigade *b,
                                           apr_brigade_flush flush, void *ctx,
                                           const char c);

/**
 * This function writes an unspecified number of strings into a bucket brigade.
 * @param b The bucket brigade to add to
 * @param flush The flush function to use if the brigade is full
 * @param ctx The structure to pass to the flush function
 * @param ... The strings to add
 * @return APR_SUCCESS or error code
 */
APU_DECLARE_NONSTD(apr_status_t) apr_brigade_putstrs(apr_bucket_brigade *b,
                                                     apr_brigade_flush flush,
                                                     void *ctx, ...);

/**
 * Evaluate a printf and put the resulting string at the end 
 * of the bucket brigade.
 * @param b The brigade to write to
 * @param flush The flush function to use if the brigade is full
 * @param ctx The structure to pass to the flush function
 * @param fmt The format of the string to write
 * @param ... The arguments to fill out the format
 * @return APR_SUCCESS or error code
 */
APU_DECLARE_NONSTD(apr_status_t) apr_brigade_printf(apr_bucket_brigade *b, 
                                                    apr_brigade_flush flush,
                                                    void *ctx,
                                                    const char *fmt, ...)
        __attribute__((format(printf,4,5)));

/**
 * Evaluate a printf and put the resulting string at the end 
 * of the bucket brigade.
 * @param b The brigade to write to
 * @param flush The flush function to use if the brigade is full
 * @param ctx The structure to pass to the flush function
 * @param fmt The format of the string to write
 * @param va The arguments to fill out the format
 * @return APR_SUCCESS or error code
 */
APU_DECLARE(apr_status_t) apr_brigade_vprintf(apr_bucket_brigade *b, 
                                              apr_brigade_flush flush,
                                              void *ctx,
                                              const char *fmt, va_list va);

/**
 * Utility function to insert a file (or a segment of a file) onto the
 * end of the brigade.  The file is split into multiple buckets if it
 * is larger than the maximum size which can be represented by a
 * single bucket.
 * @param bb the brigade to insert into
 * @param f the file to insert
 * @param start the offset of the start of the segment
 * @param len the length of the segment of the file to insert
 * @param p pool from which file buckets are allocated
 * @return the last bucket inserted
 */
APU_DECLARE(apr_bucket *) apr_brigade_insert_file(apr_bucket_brigade *bb,
                                                  apr_file_t *f,
                                                  apr_off_t start,
                                                  apr_off_t len,
                                                  apr_pool_t *p);



/*  *****  Bucket freelist functions *****  */
/**
 * Create a bucket allocator.
 * @param p This pool's underlying apr_allocator_t is used to allocate memory
 *          for the bucket allocator.  When the pool is destroyed, the bucket
 *          allocator's cleanup routine will free all memory that has been
 *          allocated from it.
 * @remark  The reason the allocator gets its memory from the pool's
 *          apr_allocator_t rather than from the pool itself is because
 *          the bucket allocator will free large memory blocks back to the
 *          allocator when it's done with them, thereby preventing memory
 *          footprint growth that would occur if we allocated from the pool.
 * @warning The allocator must never be used by more than one thread at a time.
 */
APU_DECLARE_NONSTD(apr_bucket_alloc_t *) apr_bucket_alloc_create(apr_pool_t *p);

/**
 * Create a bucket allocator.
 * @param allocator This apr_allocator_t is used to allocate both the bucket
 *          allocator and all memory handed out by the bucket allocator.  The
 *          caller is responsible for destroying the bucket allocator and the
 *          apr_allocator_t -- no automatic cleanups will happen.
 * @warning The allocator must never be used by more than one thread at a time.
 */
APU_DECLARE_NONSTD(apr_bucket_alloc_t *) apr_bucket_alloc_create_ex(apr_allocator_t *allocator);

/**
 * Destroy a bucket allocator.
 * @param list The allocator to be destroyed
 */
APU_DECLARE_NONSTD(void) apr_bucket_alloc_destroy(apr_bucket_alloc_t *list);

/**
 * Get the aligned size corresponding to the requested size, but minus the
 * allocator(s) overhead such that the allocation would remain in the
 * same boundary.
 * @param list The allocator from which to the memory would be allocated.
 * @param size The requested size.
 * @return The corresponding aligned/floored size.
 */
APU_DECLARE_NONSTD(apr_size_t) apr_bucket_alloc_aligned_floor(apr_bucket_alloc_t *list,
                                                              apr_size_t size)
                         __attribute__((nonnull(1)));

/**
 * Allocate memory for use by the buckets.
 * @param size The amount to allocate.
 * @param list The allocator from which to allocate the memory.
 */
APU_DECLARE_NONSTD(void *) apr_bucket_alloc(apr_size_t size, apr_bucket_alloc_t *list);

/**
 * Free memory previously allocated with apr_bucket_alloc().
 * @param block The block of memory to be freed.
 */
APU_DECLARE_NONSTD(void) apr_bucket_free(void *block);


/*  *****  Bucket Functions  *****  */
/**
 * Free the resources used by a bucket. If multiple buckets refer to
 * the same resource it is freed when the last one goes away.
 * @see apr_bucket_delete()
 * @param e The bucket to destroy
 */
#define apr_bucket_destroy(e) do {					\
        apr_bucket *apr__d = (e);					\
        apr__d->type->destroy(apr__d->data);			       	\
        apr__d->free(apr__d);						\
    } while (0)

/**
 * Delete a bucket by removing it from its brigade (if any) and then
 * destroying it.
 * @remark This mainly acts as an aid in avoiding code verbosity.  It is
 * the preferred exact equivalent to:
 * <pre>
 *      APR_BUCKET_REMOVE(e);
 *      apr_bucket_destroy(e);
 * </pre>
 * @param e The bucket to delete
 */
#define apr_bucket_delete(e) do {					\
        apr_bucket *apr__b = (e);					\
        APR_BUCKET_REMOVE(apr__b);					\
        apr_bucket_destroy(apr__b);					\
    } while (0)

/**
 * Read some data from the bucket.
 *
 * The apr_bucket_read function returns a convenient amount of data
 * from the bucket provided, writing the address and length of the
 * data to the pointers provided by the caller. The function tries
 * as hard as possible to avoid a memory copy.
 *
 * Buckets are expected to be a member of a brigade at the time they
 * are read.
 *
 * In typical application code, buckets are read in a loop, and after
 * each bucket is read and processed, it is moved or deleted from the
 * brigade and the next bucket read.
 *
 * The definition of "convenient" depends on the type of bucket that
 * is being read, and is decided by APR. In the case of memory based
 * buckets such as heap and immortal buckets, a pointer will be
 * returned to the location of the buffer containing the complete
 * contents of the bucket.
 *
 * Some buckets, such as the socket bucket, might have no concept
 * of length. If an attempt is made to read such a bucket, the
 * apr_bucket_read function will read a convenient amount of data
 * from the socket. The socket bucket is magically morphed into a
 * heap bucket containing the just-read data, and a new socket bucket
 * is inserted just after this heap bucket.
 *
 * To understand why apr_bucket_read might do this, consider the loop
 * described above to read and process buckets. The current bucket
 * is magically morphed into a heap bucket and returned to the caller.
 * The caller processes the data, and deletes the heap bucket, moving
 * onto the next bucket, the new socket bucket. This process repeats,
 * giving the illusion of a bucket brigade that contains potentially
 * infinite amounts of data. It is up to the caller to decide at what
 * point to stop reading buckets.
 *
 * Some buckets, such as the file bucket, might have a fixed size,
 * but be significantly larger than is practical to store in RAM in
 * one go. As with the socket bucket, if an attempt is made to read
 * from a file bucket, the file bucket is magically morphed into a
 * heap bucket containing a convenient amount of data read from the
 * current offset in the file. During the read, the offset will be
 * moved forward on the file, and a new file bucket will be inserted
 * directly after the current bucket representing the remainder of the
 * file. If the heap bucket was large enough to store the whole
 * remainder of the file, no more file buckets are inserted, and the
 * file bucket will disappear completely.
 *
 * The pattern for reading buckets described above does create the
 * illusion that the code is willing to swallow buckets that might be
 * too large for the system to handle in one go. This however is just
 * an illusion: APR will always ensure that large (file) or infinite
 * (socket) buckets are broken into convenient bite sized heap buckets
 * before data is returned to the caller.
 *
 * There is a potential gotcha to watch for: if buckets are read in a
 * loop, and aren't deleted after being processed, the potentially large
 * bucket will slowly be converted into RAM resident heap buckets. If
 * the file is larger than available RAM, an out of memory condition
 * could be caused if the application is not careful to manage this.
 *
 * @param e The bucket to read from
 * @param str The location to store a pointer to the data in
 * @param len The location to store the amount of data read
 * @param block Whether the read function blocks
 */
#define apr_bucket_read(e,str,len,block) (e)->type->read(e, str, len, block)

/**
 * Setaside data so that stack data is not destroyed on returning from
 * the function
 * @param e The bucket to setaside
 * @param p The pool to setaside into
 */
#define apr_bucket_setaside(e,p) (e)->type->setaside(e,p)

/**
 * Split one bucket in two at the point provided.
 * 
 * Once split, the original bucket becomes the first of the two new buckets.
 * 
 * (It is assumed that the bucket is a member of a brigade when this
 * function is called).
 * @param e The bucket to split
 * @param point The offset to split the bucket at
 */
#define apr_bucket_split(e,point) (e)->type->split(e, point)

/**
 * Copy a bucket.
 * @param e The bucket to copy
 * @param c Returns a pointer to the new bucket
 */
#define apr_bucket_copy(e,c) (e)->type->copy(e, c)

/* Bucket type handling */

/**
 * This function simply returns APR_SUCCESS to denote that the bucket does
 * not require anything to happen for its setaside() function. This is
 * appropriate for buckets that have "immortal" data -- the data will live
 * at least as long as the bucket.
 * @param data The bucket to setaside
 * @param pool The pool defining the desired lifetime of the bucket data
 * @return APR_SUCCESS
 */ 
APU_DECLARE_NONSTD(apr_status_t) apr_bucket_setaside_noop(apr_bucket *data,
                                                          apr_pool_t *pool);

/**
 * A place holder function that signifies that the setaside function was not
 * implemented for this bucket
 * @param data The bucket to setaside
 * @param pool The pool defining the desired lifetime of the bucket data
 * @return APR_ENOTIMPL
 */ 
APU_DECLARE_NONSTD(apr_status_t) apr_bucket_setaside_notimpl(apr_bucket *data,
                                                             apr_pool_t *pool);

/**
 * A place holder function that signifies that the split function was not
 * implemented for this bucket
 * @param data The bucket to split
 * @param point The location to split the bucket
 * @return APR_ENOTIMPL
 */ 
APU_DECLARE_NONSTD(apr_status_t) apr_bucket_split_notimpl(apr_bucket *data,
                                                          apr_size_t point);

/**
 * A place holder function that signifies that the copy function was not
 * implemented for this bucket
 * @param e The bucket to copy
 * @param c Returns a pointer to the new bucket
 * @return APR_ENOTIMPL
 */
APU_DECLARE_NONSTD(apr_status_t) apr_bucket_copy_notimpl(apr_bucket *e,
                                                         apr_bucket **c);

/**
 * A place holder function that signifies that this bucket does not need
 * to do anything special to be destroyed.  That's only the case for buckets
 * that either have no data (metadata buckets) or buckets whose data pointer
 * points to something that's not a bucket-type-specific structure, as with
 * simple buckets where data points to a string and pipe buckets where data
 * points directly to the apr_file_t.
 * @param data The bucket data to destroy
 */ 
APU_DECLARE_NONSTD(void) apr_bucket_destroy_noop(void *data);

/**
 * There is no apr_bucket_destroy_notimpl, because destruction is required
 * to be implemented (it could be a noop, but only if that makes sense for
 * the bucket type)
 */

/* There is no apr_bucket_read_notimpl, because it is a required function
 */


/* All of the bucket types implemented by the core */
/**
 * The flush bucket type.  This signifies that all data should be flushed to
 * the next filter.  The flush bucket should be sent with the other buckets.
 */
APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_flush;
/**
 * The EOS bucket type.  This signifies that there will be no more data, ever.
 * All filters MUST send all data to the next filter when they receive a
 * bucket of this type
 */
APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_eos;
/**
 * The FILE bucket type.  This bucket represents a file on disk
 */
APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_file;
/**
 * The HEAP bucket type.  This bucket represents a data allocated from the
 * heap.
 */
APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_heap;
#if APR_HAS_MMAP
/**
 * The MMAP bucket type.  This bucket represents an MMAP'ed file
 */
APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_mmap;
#endif
/**
 * The POOL bucket type.  This bucket represents a data that was allocated
 * from a pool.  IF this bucket is still available when the pool is cleared,
 * the data is copied on to the heap.
 */
APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_pool;
/**
 * The PIPE bucket type.  This bucket represents a pipe to another program.
 */
APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_pipe;
/**
 * The IMMORTAL bucket type.  This bucket represents a segment of data that
 * the creator is willing to take responsibility for.  The core will do
 * nothing with the data in an immortal bucket
 */
APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_immortal;
/**
 * The TRANSIENT bucket type.  This bucket represents a data allocated off
 * the stack.  When the setaside function is called, this data is copied on
 * to the heap
 */
APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_transient;
/**
 * The SOCKET bucket type.  This bucket represents a socket to another machine
 */
APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_socket;


/*  *****  Simple buckets  *****  */

/**
 * Split a simple bucket into two at the given point.  Most non-reference
 * counting buckets that allow multiple references to the same block of
 * data (eg transient and immortal) will use this as their split function
 * without any additional type-specific handling.
 * @param b The bucket to be split
 * @param point The offset of the first byte in the new bucket
 * @return APR_EINVAL if the point is not within the bucket;
 *         APR_ENOMEM if allocation failed;
 *         or APR_SUCCESS
 */
APU_DECLARE_NONSTD(apr_status_t) apr_bucket_simple_split(apr_bucket *b,
                                                         apr_size_t point);

/**
 * Copy a simple bucket.  Most non-reference-counting buckets that allow
 * multiple references to the same block of data (eg transient and immortal)
 * will use this as their copy function without any additional type-specific
 * handling.
 * @param a The bucket to copy
 * @param b Returns a pointer to the new bucket
 * @return APR_ENOMEM if allocation failed;
 *         or APR_SUCCESS
 */
APU_DECLARE_NONSTD(apr_status_t) apr_bucket_simple_copy(apr_bucket *a,
                                                        apr_bucket **b);


/*  *****  Shared, reference-counted buckets  *****  */

/**
 * Initialize a bucket containing reference-counted data that may be
 * shared. The caller must allocate the bucket if necessary and
 * initialize its type-dependent fields, and allocate and initialize
 * its own private data structure. This function should only be called
 * by type-specific bucket creation functions.
 * @param b The bucket to initialize
 * @param data A pointer to the private data structure
 *             with the reference count at the start
 * @param start The start of the data in the bucket
 *              relative to the private base pointer
 * @param length The length of the data in the bucket
 * @return The new bucket, or NULL if allocation failed
 */
APU_DECLARE(apr_bucket *) apr_bucket_shared_make(apr_bucket *b, void *data,
				                 apr_off_t start, 
                                                 apr_size_t length);

/**
 * Decrement the refcount of the data in the bucket. This function
 * should only be called by type-specific bucket destruction functions.
 * @param data The private data pointer from the bucket to be destroyed
 * @return TRUE or FALSE; TRUE if the reference count is now
 *         zero, indicating that the shared resource itself can
 *         be destroyed by the caller.
 */
APU_DECLARE(int) apr_bucket_shared_destroy(void *data);

/**
 * Split a bucket into two at the given point, and adjust the refcount
 * to the underlying data. Most reference-counting bucket types will
 * be able to use this function as their split function without any
 * additional type-specific handling.
 * @param b The bucket to be split
 * @param point The offset of the first byte in the new bucket
 * @return APR_EINVAL if the point is not within the bucket;
 *         APR_ENOMEM if allocation failed;
 *         or APR_SUCCESS
 */
APU_DECLARE_NONSTD(apr_status_t) apr_bucket_shared_split(apr_bucket *b,
                                                         apr_size_t point);

/**
 * Copy a refcounted bucket, incrementing the reference count. Most
 * reference-counting bucket types will be able to use this function
 * as their copy function without any additional type-specific handling.
 * @param a The bucket to copy
 * @param b Returns a pointer to the new bucket
 * @return APR_ENOMEM if allocation failed;
           or APR_SUCCESS
 */
APU_DECLARE_NONSTD(apr_status_t) apr_bucket_shared_copy(apr_bucket *a,
                                                        apr_bucket **b);


/*  *****  Functions to Create Buckets of varying types  *****  */
/*
 * Each bucket type foo has two initialization functions:
 * apr_bucket_foo_make which sets up some already-allocated memory as a
 * bucket of type foo; and apr_bucket_foo_create which allocates memory
 * for the bucket, calls apr_bucket_make_foo, and initializes the
 * bucket's list pointers. The apr_bucket_foo_make functions are used
 * inside the bucket code to change the type of buckets in place;
 * other code should call apr_bucket_foo_create. All the initialization
 * functions change nothing if they fail.
 */

/**
 * Create an End of Stream bucket.  This indicates that there is no more data
 * coming from down the filter stack.  All filters should flush at this point.
 * @param list The freelist from which this bucket should be allocated
 * @return The new bucket, or NULL if allocation failed
 */
APU_DECLARE(apr_bucket *) apr_bucket_eos_create(apr_bucket_alloc_t *list);

/**
 * Make the bucket passed in an EOS bucket.  This indicates that there is no 
 * more data coming from down the filter stack.  All filters should flush at 
 * this point.
 * @param b The bucket to make into an EOS bucket
 * @return The new bucket, or NULL if allocation failed
 */
APU_DECLARE(apr_bucket *) apr_bucket_eos_make(apr_bucket *b);

/**
 * Create a flush  bucket.  This indicates that filters should flush their
 * data.  There is no guarantee that they will flush it, but this is the
 * best we can do.
 * @param list The freelist from which this bucket should be allocated
 * @return The new bucket, or NULL if allocation failed
 */
APU_DECLARE(apr_bucket *) apr_bucket_flush_create(apr_bucket_alloc_t *list);

/**
 * Make the bucket passed in a FLUSH  bucket.  This indicates that filters 
 * should flush their data.  There is no guarantee that they will flush it, 
 * but this is the best we can do.
 * @param b The bucket to make into a FLUSH bucket
 * @return The new bucket, or NULL if allocation failed
 */
APU_DECLARE(apr_bucket *) apr_bucket_flush_make(apr_bucket *b);

/**
 * Create a bucket referring to long-lived data.
 * @param buf The data to insert into the bucket
 * @param nbyte The size of the data to insert.
 * @param list The freelist from which this bucket should be allocated
 * @return The new bucket, or NULL if allocation failed
 */
APU_DECLARE(apr_bucket *) apr_bucket_immortal_create(const char *buf, 
                                                     apr_size_t nbyte,
                                                     apr_bucket_alloc_t *list);

/**
 * Make the bucket passed in a bucket refer to long-lived data
 * @param b The bucket to make into a IMMORTAL bucket
 * @param buf The data to insert into the bucket
 * @param nbyte The size of the data to insert.
 * @return The new bucket, or NULL if allocation failed
 */
APU_DECLARE(apr_bucket *) apr_bucket_immortal_make(apr_bucket *b, 
                                                   const char *buf, 
                                                   apr_size_t nbyte);

/**
 * Create a bucket referring to data on the stack.
 * @param buf The data to insert into the bucket
 * @param nbyte The size of the data to insert.
 * @param list The freelist from which this bucket should be allocated
 * @return The new bucket, or NULL if allocation failed
 */
APU_DECLARE(apr_bucket *) apr_bucket_transient_create(const char *buf, 
                                                      apr_size_t nbyte,
                                                      apr_bucket_alloc_t *list);

/**
 * Make the bucket passed in a bucket refer to stack data
 * @param b The bucket to make into a TRANSIENT bucket
 * @param buf The data to insert into the bucket
 * @param nbyte The size of the data to insert.
 * @return The new bucket, or NULL if allocation failed
 */
APU_DECLARE(apr_bucket *) apr_bucket_transient_make(apr_bucket *b, 
                                                    const char *buf,
                                                    apr_size_t nbyte);

/**
 * Create a bucket referring to memory on the heap. If the caller asks
 * for the data to be copied, this function always allocates 4K of
 * memory so that more data can be added to the bucket without
 * requiring another allocation. Therefore not all the data may be put
 * into the bucket. If copying is not requested then the bucket takes
 * over responsibility for free()ing the memory.
 * @param buf The buffer to insert into the bucket
 * @param nbyte The size of the buffer to insert.
 * @param free_func Function to use to free the data; NULL indicates that the
 *                  bucket should make a copy of the data
 * @param list The freelist from which this bucket should be allocated
 * @return The new bucket, or NULL if allocation failed
 */
APU_DECLARE(apr_bucket *) apr_bucket_heap_create(const char *buf, 
                                                 apr_size_t nbyte,
                                                 void (*free_func)(void *data),
                                                 apr_bucket_alloc_t *list);
/**
 * Make the bucket passed in a bucket refer to heap data
 * @param b The bucket to make into a HEAP bucket
 * @param buf The buffer to insert into the bucket
 * @param nbyte The size of the buffer to insert.
 * @param free_func Function to use to free the data; NULL indicates that the
 *                  bucket should make a copy of the data
 * @return The new bucket, or NULL if allocation failed
 */
APU_DECLARE(apr_bucket *) apr_bucket_heap_make(apr_bucket *b, const char *buf,
                                               apr_size_t nbyte,
                                               void (*free_func)(void *data));

/**
 * Create a bucket referring to memory allocated from a pool.
 *
 * @param buf The buffer to insert into the bucket
 * @param length The number of bytes referred to by this bucket
 * @param pool The pool the memory was allocated from
 * @param list The freelist from which this bucket should be allocated
 * @return The new bucket, or NULL if allocation failed
 */
APU_DECLARE(apr_bucket *) apr_bucket_pool_create(const char *buf, 
                                                 apr_size_t length,
                                                 apr_pool_t *pool,
                                                 apr_bucket_alloc_t *list);

/**
 * Make the bucket passed in a bucket refer to pool data
 * @param b The bucket to make into a pool bucket
 * @param buf The buffer to insert into the bucket
 * @param length The number of bytes referred to by this bucket
 * @param pool The pool the memory was allocated from
 * @return The new bucket, or NULL if allocation failed
 */
APU_DECLARE(apr_bucket *) apr_bucket_pool_make(apr_bucket *b, const char *buf,
                                               apr_size_t length, 
                                               apr_pool_t *pool);

#if APR_HAS_MMAP
/**
 * Create a bucket referring to mmap()ed memory.
 * @param mm The mmap to insert into the bucket
 * @param start The offset of the first byte in the mmap
 *              that this bucket refers to
 * @param length The number of bytes referred to by this bucket
 * @param list The freelist from which this bucket should be allocated
 * @return The new bucket, or NULL if allocation failed
 */
APU_DECLARE(apr_bucket *) apr_bucket_mmap_create(apr_mmap_t *mm, 
                                                 apr_off_t start,
                                                 apr_size_t length,
                                                 apr_bucket_alloc_t *list);

/**
 * Make the bucket passed in a bucket refer to an MMAP'ed file
 * @param b The bucket to make into a MMAP bucket
 * @param mm The mmap to insert into the bucket
 * @param start The offset of the first byte in the mmap
 *              that this bucket refers to
 * @param length The number of bytes referred to by this bucket
 * @return The new bucket, or NULL if allocation failed
 */
APU_DECLARE(apr_bucket *) apr_bucket_mmap_make(apr_bucket *b, apr_mmap_t *mm,
                                               apr_off_t start, 
                                               apr_size_t length);
#endif

/**
 * Create a bucket referring to a socket.
 * @param thissock The socket to put in the bucket
 * @param list The freelist from which this bucket should be allocated
 * @return The new bucket, or NULL if allocation failed
 */
APU_DECLARE(apr_bucket *) apr_bucket_socket_create(apr_socket_t *thissock,
                                                   apr_bucket_alloc_t *list);
/**
 * Make the bucket passed in a bucket refer to a socket
 * @param b The bucket to make into a SOCKET bucket
 * @param thissock The socket to put in the bucket
 * @return The new bucket, or NULL if allocation failed
 */
APU_DECLARE(apr_bucket *) apr_bucket_socket_make(apr_bucket *b, 
                                                 apr_socket_t *thissock);

/**
 * Create a bucket referring to a pipe.
 * @param thispipe The pipe to put in the bucket
 * @param list The freelist from which this bucket should be allocated
 * @return The new bucket, or NULL if allocation failed
 */
APU_DECLARE(apr_bucket *) apr_bucket_pipe_create(apr_file_t *thispipe,
                                                 apr_bucket_alloc_t *list);

/**
 * Make the bucket passed in a bucket refer to a pipe
 * @param b The bucket to make into a PIPE bucket
 * @param thispipe The pipe to put in the bucket
 * @return The new bucket, or NULL if allocation failed
 */
APU_DECLARE(apr_bucket *) apr_bucket_pipe_make(apr_bucket *b, 
                                               apr_file_t *thispipe);

/**
 * Create a bucket referring to a file.
 * @param fd The file to put in the bucket
 * @param offset The offset where the data of interest begins in the file
 * @param len The amount of data in the file we are interested in
 * @param p The pool into which any needed structures should be created
 *          while reading from this file bucket
 * @param list The freelist from which this bucket should be allocated
 * @return The new bucket, or NULL if allocation failed
 * @remark If the file is truncated such that the segment of the file
 * referenced by the bucket no longer exists, an attempt to read
 * from the bucket will fail with APR_EOF. 
 * @remark apr_brigade_insert_file() should generally be used to
 * insert files into brigades, since that function can correctly
 * handle large file issues.
 */
APU_DECLARE(apr_bucket *) apr_bucket_file_create(apr_file_t *fd,
                                                 apr_off_t offset,
                                                 apr_size_t len, 
                                                 apr_pool_t *p,
                                                 apr_bucket_alloc_t *list);

/**
 * Make the bucket passed in a bucket refer to a file
 * @param b The bucket to make into a FILE bucket
 * @param fd The file to put in the bucket
 * @param offset The offset where the data of interest begins in the file
 * @param len The amount of data in the file we are interested in
 * @param p The pool into which any needed structures should be created
 *          while reading from this file bucket
 * @return The new bucket, or NULL if allocation failed
 */
APU_DECLARE(apr_bucket *) apr_bucket_file_make(apr_bucket *b, apr_file_t *fd,
                                               apr_off_t offset,
                                               apr_size_t len, apr_pool_t *p);

/**
 * Enable or disable memory-mapping for a FILE bucket (default is enabled)
 * @param b The bucket
 * @param enabled Whether memory-mapping should be enabled
 * @return APR_SUCCESS normally, or an error code if the operation fails
 */
APU_DECLARE(apr_status_t) apr_bucket_file_enable_mmap(apr_bucket *b,
                                                      int enabled);

/**
 * Set the size of the read buffer allocated by a FILE bucket (default
 * is @a APR_BUCKET_BUFF_SIZE)
 * memory-mapping is disabled only)
 * @param b The bucket
 * @param size Size of the allocated buffers
 * @return APR_SUCCESS normally, or an error code if the operation fails
 * @remark Relevant/used only when memory-mapping is disabled (@see
 * apr_bucket_file_enable_mmap)
 */
APU_DECLARE(apr_status_t) apr_bucket_file_set_buf_size(apr_bucket *b,
                                                       apr_size_t size);

/** @} */
#ifdef __cplusplus
}
#endif

#endif /* !APR_BUCKETS_H */
apr-1/apr_want.h000064400000005616151730340520007460 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "apr.h"        /* configuration data */
/**
 * @file apr_want.h
 * @brief APR Standard Headers Support
 *
 * <PRE>
 * Features:
 *
 *   APR_WANT_STRFUNC:  strcmp, strcat, strcpy, etc
 *   APR_WANT_MEMFUNC:  memcmp, memcpy, etc
 *   APR_WANT_STDIO:    <stdio.h> and related bits
 *   APR_WANT_IOVEC:    struct iovec
 *   APR_WANT_BYTEFUNC: htons, htonl, ntohl, ntohs
 *
 * Typical usage:
 *
 *   \#define APR_WANT_STRFUNC
 *   \#define APR_WANT_MEMFUNC
 *   \#include "apr_want.h"
 *
 * The appropriate headers will be included.
 *
 * Note: it is safe to use this in a header (it won't interfere with other
 *       headers' or source files' use of apr_want.h)
 * </PRE>
 */

/* --------------------------------------------------------------------- */

#ifdef APR_WANT_STRFUNC

#if APR_HAVE_STRING_H
#include <string.h>
#endif
#if APR_HAVE_STRINGS_H
#include <strings.h>
#endif

#undef APR_WANT_STRFUNC
#endif

/* --------------------------------------------------------------------- */

#ifdef APR_WANT_MEMFUNC

#if APR_HAVE_STRING_H
#include <string.h>
#endif

#undef APR_WANT_MEMFUNC
#endif

/* --------------------------------------------------------------------- */

#ifdef APR_WANT_STDIO

#if APR_HAVE_STDIO_H
#include <stdio.h>
#endif

#undef APR_WANT_STDIO
#endif

/* --------------------------------------------------------------------- */

#ifdef APR_WANT_IOVEC

#if APR_HAVE_IOVEC

#if APR_HAVE_SYS_UIO_H
#include <sys/uio.h>
#endif

#else

#ifndef APR_IOVEC_DEFINED
#define APR_IOVEC_DEFINED
struct iovec
{
    void *iov_base;
    size_t iov_len;
};
#endif /* !APR_IOVEC_DEFINED */

#endif /* APR_HAVE_IOVEC */

#undef APR_WANT_IOVEC
#endif

/* --------------------------------------------------------------------- */

#ifdef APR_WANT_BYTEFUNC

/* Single Unix says they are in arpa/inet.h.  Linux has them in
 * netinet/in.h.  FreeBSD has them in arpa/inet.h but requires that
 * netinet/in.h be included first.
 */
#if APR_HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#if APR_HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif

#undef APR_WANT_BYTEFUNC
#endif

/* --------------------------------------------------------------------- */
apr-1/apr_sha1.h000064400000007454151730340520007345 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/* NIST Secure Hash Algorithm
 * 	heavily modified by Uwe Hollerbach uh@alumni.caltech edu
 * 	from Peter C. Gutmann's implementation as found in
 * 	Applied Cryptography by Bruce Schneier
 * 	This code is hereby placed in the public domain
 */

#ifndef APR_SHA1_H
#define APR_SHA1_H

#include "apu.h"
#include "apr_general.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @file apr_sha1.h
 * @brief APR-UTIL SHA1 library
 */

/** size of the SHA1 DIGEST */
#define APR_SHA1_DIGESTSIZE 20

/**
 * Define the Magic String prefix that identifies a password as being
 * hashed using our algorithm.
 */
#define APR_SHA1PW_ID "{SHA}"

/** length of the SHA Password */
#define APR_SHA1PW_IDLEN 5

/** @see apr_sha1_ctx_t */
typedef struct apr_sha1_ctx_t apr_sha1_ctx_t;

/** 
 * SHA1 context structure
 */
struct apr_sha1_ctx_t {
    /** message digest */
    apr_uint32_t digest[5];
    /** 64-bit bit counts */
    apr_uint32_t count_lo, count_hi;
    /** SHA data buffer */
    apr_uint32_t data[16];
    /** unprocessed amount in data */
    int local;
};

/**
 * Provide a means to SHA1 crypt/encode a plaintext password in a way which
 * makes password file compatible with those commonly use in netscape web
 * and ldap installations.
 * @param clear The plaintext password
 * @param len The length of the plaintext password
 * @param out The encrypted/encoded password
 * @note SHA1 support is useful for migration purposes, but is less
 *     secure than Apache's password format, since Apache's (MD5)
 *     password format uses a random eight character salt to generate
 *     one of many possible hashes for the same password.  Netscape
 *     uses plain SHA1 without a salt, so the same password
 *     will always generate the same hash, making it easier
 *     to break since the search space is smaller.
 */
APU_DECLARE(void) apr_sha1_base64(const char *clear, int len, char *out);

/**
 * Initialize the SHA digest
 * @param context The SHA context to initialize
 */
APU_DECLARE(void) apr_sha1_init(apr_sha1_ctx_t *context);

/**
 * Update the SHA digest
 * @param context The SHA1 context to update
 * @param input The buffer to add to the SHA digest
 * @param inputLen The length of the input buffer
 */
APU_DECLARE(void) apr_sha1_update(apr_sha1_ctx_t *context, const char *input,
                                unsigned int inputLen);

/**
 * Update the SHA digest with binary data
 * @param context The SHA1 context to update
 * @param input The buffer to add to the SHA digest
 * @param inputLen The length of the input buffer
 */
APU_DECLARE(void) apr_sha1_update_binary(apr_sha1_ctx_t *context,
                                       const unsigned char *input,
                                       unsigned int inputLen);

/**
 * Finish computing the SHA digest
 * @param digest the output buffer in which to store the digest
 * @param context The context to finalize
 */
APU_DECLARE(void) apr_sha1_final(unsigned char digest[APR_SHA1_DIGESTSIZE],
                               apr_sha1_ctx_t *context);

#ifdef __cplusplus
}
#endif

#endif	/* APR_SHA1_H */
apr-1/apr_optional_hooks.h000064400000007440151730340520011534 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * @file apr_optional_hooks.h
 * @brief Apache optional hook functions
 */


#ifndef APR_OPTIONAL_HOOK_H
#define APR_OPTIONAL_HOOK_H

#include "apr_tables.h"

#ifdef __cplusplus
extern "C" {
#endif
/** 
 * @defgroup APR_Util_OPT_HOOK Optional Hook Functions
 * @ingroup APR_Util_Hook
 * @{
 */
/**
 * Function to implement the APR_OPTIONAL_HOOK Macro
 * @internal
 * @see APR_OPTIONAL_HOOK
 *
 * @param szName The name of the hook
 * @param pfn A pointer to a function that will be called
 * @param aszPre a NULL-terminated array of strings that name modules whose hooks should precede this one
 * @param aszSucc a NULL-terminated array of strings that name modules whose hooks should succeed this one
 * @param nOrder an integer determining order before honouring aszPre and aszSucc (for example HOOK_MIDDLE)
 */


APU_DECLARE(void) apr_optional_hook_add(const char *szName,void (*pfn)(void),
					const char * const *aszPre,
					const char * const *aszSucc,
					int nOrder);

/**
 * Hook to an optional hook.
 *
 * @param ns The namespace prefix of the hook functions
 * @param name The name of the hook
 * @param pfn A pointer to a function that will be called
 * @param aszPre a NULL-terminated array of strings that name modules whose hooks should precede this one
 * @param aszSucc a NULL-terminated array of strings that name modules whose hooks should succeed this one
 * @param nOrder an integer determining order before honouring aszPre and aszSucc (for example HOOK_MIDDLE)
 */

#define APR_OPTIONAL_HOOK(ns,name,pfn,aszPre,aszSucc,nOrder) do { \
  ns##_HOOK_##name##_t *apu__hook = pfn; \
  apr_optional_hook_add(#name,(void (*)(void))apu__hook,aszPre, aszSucc, nOrder); \
} while (0)

/**
 * @internal
 * @param szName - the name of the function
 * @return the hook structure for a given hook
 */
APU_DECLARE(apr_array_header_t *) apr_optional_hook_get(const char *szName);

/**
 * Implement an optional hook that runs until one of the functions
 * returns something other than OK or DECLINE.
 *
 * @param ns The namespace prefix of the hook functions
 * @param link The linkage declaration prefix of the hook
 * @param ret The type of the return value of the hook
 * @param ret The type of the return value of the hook
 * @param name The name of the hook
 * @param args_decl The declaration of the arguments for the hook
 * @param args_use The names for the arguments for the hook
 * @param ok Success value
 * @param decline Decline value
 */
#define APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ns,link,ret,name,args_decl,args_use,ok,decline) \
link##_DECLARE(ret) ns##_run_##name args_decl \
    { \
    ns##_LINK_##name##_t *pHook; \
    int n; \
    ret rv; \
    apr_array_header_t *pHookArray=apr_optional_hook_get(#name); \
\
    if(!pHookArray) \
	return ok; \
\
    pHook=(ns##_LINK_##name##_t *)pHookArray->elts; \
    for(n=0 ; n < pHookArray->nelts ; ++n) \
	{ \
	rv=(pHook[n].pFunc)args_use; \
\
	if(rv != ok && rv != decline) \
	    return rv; \
	} \
    return ok; \
    }

/** @} */
#ifdef __cplusplus
}
#endif

#endif /* APR_OPTIONAL_HOOK_H */
apr-1/apr_thread_rwlock.h000064400000011236151730340520011332 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_THREAD_RWLOCK_H
#define APR_THREAD_RWLOCK_H

/**
 * @file apr_thread_rwlock.h
 * @brief APR Reader/Writer Lock Routines
 */

#include "apr.h"
#include "apr_pools.h"
#include "apr_errno.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

#if APR_HAS_THREADS

/**
 * @defgroup apr_thread_rwlock Reader/Writer Lock Routines
 * @ingroup APR 
 * @{
 */

/** Opaque read-write thread-safe lock. */
typedef struct apr_thread_rwlock_t apr_thread_rwlock_t;

/**
 * Note: The following operations have undefined results: unlocking a
 * read-write lock which is not locked in the calling thread; write
 * locking a read-write lock which is already locked by the calling
 * thread; destroying a read-write lock more than once; clearing or
 * destroying the pool from which a <b>locked</b> read-write lock is
 * allocated.
 */

/**
 * Create and initialize a read-write lock that can be used to synchronize
 * threads.
 * @param rwlock the memory address where the newly created readwrite lock
 *        will be stored.
 * @param pool the pool from which to allocate the mutex.
 */
APR_DECLARE(apr_status_t) apr_thread_rwlock_create(apr_thread_rwlock_t **rwlock,
                                                   apr_pool_t *pool);
/**
 * Acquire a shared-read lock on the given read-write lock. This will allow
 * multiple threads to enter the same critical section while they have acquired
 * the read lock.
 * @param rwlock the read-write lock on which to acquire the shared read.
 */
APR_DECLARE(apr_status_t) apr_thread_rwlock_rdlock(apr_thread_rwlock_t *rwlock);

/**
 * Attempt to acquire the shared-read lock on the given read-write lock. This
 * is the same as apr_thread_rwlock_rdlock(), only that the function fails
 * if there is another thread holding the write lock, or if there are any
 * write threads blocking on the lock. If the function fails for this case,
 * APR_EBUSY will be returned. Note: it is important that the
 * APR_STATUS_IS_EBUSY(s) macro be used to determine if the return value was
 * APR_EBUSY, for portability reasons.
 * @param rwlock the rwlock on which to attempt the shared read.
 */
APR_DECLARE(apr_status_t) apr_thread_rwlock_tryrdlock(apr_thread_rwlock_t *rwlock);

/**
 * Acquire an exclusive-write lock on the given read-write lock. This will
 * allow only one single thread to enter the critical sections. If there
 * are any threads currently holding the read-lock, this thread is put to
 * sleep until it can have exclusive access to the lock.
 * @param rwlock the read-write lock on which to acquire the exclusive write.
 */
APR_DECLARE(apr_status_t) apr_thread_rwlock_wrlock(apr_thread_rwlock_t *rwlock);

/**
 * Attempt to acquire the exclusive-write lock on the given read-write lock. 
 * This is the same as apr_thread_rwlock_wrlock(), only that the function fails
 * if there is any other thread holding the lock (for reading or writing),
 * in which case the function will return APR_EBUSY. Note: it is important
 * that the APR_STATUS_IS_EBUSY(s) macro be used to determine if the return
 * value was APR_EBUSY, for portability reasons.
 * @param rwlock the rwlock on which to attempt the exclusive write.
 */
APR_DECLARE(apr_status_t) apr_thread_rwlock_trywrlock(apr_thread_rwlock_t *rwlock);

/**
 * Release either the read or write lock currently held by the calling thread
 * associated with the given read-write lock.
 * @param rwlock the read-write lock to be released (unlocked).
 */
APR_DECLARE(apr_status_t) apr_thread_rwlock_unlock(apr_thread_rwlock_t *rwlock);

/**
 * Destroy the read-write lock and free the associated memory.
 * @param rwlock the rwlock to destroy.
 */
APR_DECLARE(apr_status_t) apr_thread_rwlock_destroy(apr_thread_rwlock_t *rwlock);

/**
 * Get the pool used by this thread_rwlock.
 * @return apr_pool_t the pool
 */
APR_POOL_DECLARE_ACCESSOR(thread_rwlock);

#endif  /* APR_HAS_THREADS */

/** @} */

#ifdef __cplusplus
}
#endif

#endif  /* ! APR_THREAD_RWLOCK_H */
apr-1/apr_general.h000064400000016531151730340520010122 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_GENERAL_H
#define APR_GENERAL_H

/**
 * @file apr_general.h
 * This is collection of oddballs that didn't fit anywhere else,
 * and might move to more appropriate headers with the release
 * of APR 1.0.
 * @brief APR Miscellaneous library routines
 */

#include "apr.h"
#include "apr_pools.h"
#include "apr_errno.h"

#if APR_HAVE_SIGNAL_H
#include <signal.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @defgroup apr_general Miscellaneous library routines
 * @ingroup APR 
 * This is collection of oddballs that didn't fit anywhere else,
 * and might move to more appropriate headers with the release
 * of APR 1.0.
 * @{
 */

/** FALSE */
#ifndef FALSE
#define FALSE 0
#endif
/** TRUE */
#ifndef TRUE
#define TRUE (!FALSE)
#endif

/** a space */
#define APR_ASCII_BLANK  '\040'
/** a carrige return */
#define APR_ASCII_CR     '\015'
/** a line feed */
#define APR_ASCII_LF     '\012'
/** a tab */
#define APR_ASCII_TAB    '\011'

/** signal numbers typedef */
typedef int               apr_signum_t;

/**
 * Finding offsets of elements within structures.
 * Taken from the X code... they've sweated portability of this stuff
 * so we don't have to.  Sigh...
 * @param p_type pointer type name
 * @param field  data field within the structure pointed to
 * @return offset
 */

#if defined(CRAY) || (defined(__arm) && !(defined(LINUX) || defined(__FreeBSD__)))
#ifdef __STDC__
#define APR_OFFSET(p_type,field) _Offsetof(p_type,field)
#else
#ifdef CRAY2
#define APR_OFFSET(p_type,field) \
        (sizeof(int)*((unsigned int)&(((p_type)NULL)->field)))

#else /* !CRAY2 */

#define APR_OFFSET(p_type,field) ((unsigned int)&(((p_type)NULL)->field))

#endif /* !CRAY2 */
#endif /* __STDC__ */
#else /* ! (CRAY || __arm) */

#define APR_OFFSET(p_type,field) \
        ((long) (((char *) (&(((p_type)NULL)->field))) - ((char *) NULL)))

#endif /* !CRAY */

/**
 * Finding offsets of elements within structures.
 * @param s_type structure type name
 * @param field  data field within the structure
 * @return offset
 */
#if defined(__has_builtin)
#if __has_builtin(__builtin_offsetof)
#define APR_OFFSETOF(s_type,field) __builtin_offsetof(s_type,field)
#endif
#endif /* __has_builtin */
#ifndef APR_OFFSETOF
#if defined(offsetof) && !defined(__cplusplus)
#define APR_OFFSETOF(s_type,field) offsetof(s_type,field)
#else
#define APR_OFFSETOF(s_type,field) APR_OFFSET(s_type*,field)
#endif
#endif /* ndef APR_OFFSETOF */

#ifndef DOXYGEN

/* A couple of prototypes for functions in case some platform doesn't 
 * have it
 */
#if (!APR_HAVE_STRCASECMP) && (APR_HAVE_STRICMP) 
#define strcasecmp(s1, s2) stricmp(s1, s2)
#elif (!APR_HAVE_STRCASECMP)
int strcasecmp(const char *a, const char *b);
#endif

#if (!APR_HAVE_STRNCASECMP) && (APR_HAVE_STRNICMP)
#define strncasecmp(s1, s2, n) strnicmp(s1, s2, n)
#elif (!APR_HAVE_STRNCASECMP)
int strncasecmp(const char *a, const char *b, size_t n);
#endif

#endif

/**
 * Alignment macros
 */

/* APR_ALIGN() is only to be used to align on a power of 2 boundary */
#define APR_ALIGN(size, boundary) \
    (((size) + ((boundary) - 1)) & ~((boundary) - 1))

/** Default alignment */
#define APR_ALIGN_DEFAULT(size) APR_ALIGN(size, 8)


/**
 * String and memory functions
 */

/* APR_STRINGIFY is defined here, and also in apr_release.h, so wrap it */
#ifndef APR_STRINGIFY
/** Properly quote a value as a string in the C preprocessor */
#define APR_STRINGIFY(n) APR_STRINGIFY_HELPER(n)
/** Helper macro for APR_STRINGIFY */
#define APR_STRINGIFY_HELPER(n) #n
#endif

#if (!APR_HAVE_MEMMOVE)
#define memmove(a,b,c) bcopy(b,a,c)
#endif

#if (!APR_HAVE_MEMCHR)
void *memchr(const void *s, int c, size_t n);
#endif

/** @} */

/**
 * @defgroup apr_library Library initialization and termination
 * @{
 */

/**
 * Setup any APR internal data structures.  This MUST be the first function 
 * called for any APR library. It is safe to call apr_initialize several
 * times as long as apr_terminate() is called the same number of times.
 * @remark See apr_app_initialize() if this is an application, rather than
 * a library consumer of apr.
 */
APR_DECLARE(apr_status_t) apr_initialize(void);

/**
 * Set up an application with normalized argc, argv (and optionally env) in
 * order to deal with platform-specific oddities, such as Win32 services,
 * code pages and signals.  This must be the first function called for any
 * APR program.
 * @param argc Pointer to the argc that may be corrected
 * @param argv Pointer to the argv that may be corrected
 * @param env Pointer to the env that may be corrected, may be NULL
 * @remark See apr_initialize() if this is a library consumer of apr.
 * Otherwise, this call is identical to apr_initialize(), and must be closed
 * with a call to apr_terminate() at the end of program execution.
 */
APR_DECLARE(apr_status_t) apr_app_initialize(int *argc, 
                                             char const * const * *argv, 
                                             char const * const * *env);

/**
 * Tear down any APR internal data structures which aren't torn down 
 * automatically. apr_terminate must be called once for every call to
 * apr_initialize() or apr_app_initialize().
 * @remark An APR program must call this function at termination once it 
 *         has stopped using APR services.  The APR developers suggest using
 *         @c atexit(apr_terminate) to ensure this is called.  When using APR
 *         from a language other than C that has problems with the calling
 *         convention, use apr_terminate2() instead.
 * @see apr_terminate2
 */
APR_DECLARE_NONSTD(void) apr_terminate(void);

/**
 * Tear down any APR internal data structures which aren't torn down 
 * automatically, same as apr_terminate()
 * @remark An APR program must call either the apr_terminate() or apr_terminate2
 *         function once it it has finished using APR services.  The APR 
 *         developers suggest using @c atexit(apr_terminate) to ensure this is done.
 *         apr_terminate2 exists to allow non-c language apps to tear down apr, 
 *         while apr_terminate() is recommended from c language applications.
 */
APR_DECLARE(void) apr_terminate2(void);

/** @} */

/**
 * @defgroup apr_random Random Functions
 * @{
 */

#if APR_HAS_RANDOM || defined(DOXYGEN)

/* TODO: I'm not sure this is the best place to put this prototype...*/
/**
 * Generate random bytes.
 * @param buf Buffer to fill with random bytes
 * @param length Length of buffer in bytes
 */
APR_DECLARE(apr_status_t) apr_generate_random_bytes(unsigned char * buf, 
                                                    apr_size_t length);

#endif
/** @} */

#ifdef __cplusplus
}
#endif

#endif  /* ! APR_GENERAL_H */
apr-1/apr_dso.h000064400000005214151730340520007266 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_DSO_DOT_H
#define APR_DSO_DOT_H

/**
 * @file apr_dso.h
 * @brief APR Dynamic Object Handling Routines
 */

#include "apr.h"
#include "apr_pools.h"
#include "apr_errno.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @defgroup apr_dso Dynamic Object Handling
 * @ingroup APR 
 * @{
 */

#if APR_HAS_DSO || defined(DOXYGEN)

/**
 * Structure for referencing dynamic objects
 */
typedef struct apr_dso_handle_t       apr_dso_handle_t;

/**
 * Structure for referencing symbols from dynamic objects
 */
typedef void *                        apr_dso_handle_sym_t;

/**
 * Load a DSO library.
 * @param res_handle Location to store new handle for the DSO.
 * @param path Path to the DSO library
 * @param ctx Pool to use.
 * @bug We aught to provide an alternative to RTLD_GLOBAL, which
 * is the only supported method of loading DSOs today.
 */
APR_DECLARE(apr_status_t) apr_dso_load(apr_dso_handle_t **res_handle, 
                                       const char *path, apr_pool_t *ctx);

/**
 * Close a DSO library.
 * @param handle handle to close.
 */
APR_DECLARE(apr_status_t) apr_dso_unload(apr_dso_handle_t *handle);

/**
 * Load a symbol from a DSO handle.
 * @param ressym Location to store the loaded symbol
 * @param handle handle to load the symbol from.
 * @param symname Name of the symbol to load.
 */
APR_DECLARE(apr_status_t) apr_dso_sym(apr_dso_handle_sym_t *ressym, 
                                      apr_dso_handle_t *handle,
                                      const char *symname);

/**
 * Report more information when a DSO function fails.
 * @param dso The dso handle that has been opened
 * @param buf Location to store the dso error
 * @param bufsize The size of the provided buffer
 */
APR_DECLARE(const char *) apr_dso_error(apr_dso_handle_t *dso, char *buf, apr_size_t bufsize);

#endif /* APR_HAS_DSO */

/** @} */

#ifdef __cplusplus
}
#endif

#endif
apr-1/apr_skiplist.h000064400000034305151730340520010346 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_SKIPLIST_H
#define APR_SKIPLIST_H
/**
 * @file apr_skiplist.h
 * @brief APR skip list implementation
 */

#include "apr.h"
#include "apr_portable.h"
#include <stdlib.h>

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @defgroup apr_skiplist Skip list implementation
 * Refer to http://en.wikipedia.org/wiki/Skip_list for information
 * about the purpose of and ideas behind skip lists.
 * @ingroup APR
 * @{
 */

/**
 * apr_skiplist_compare is the function type that must be implemented 
 * per object type that is used in a skip list for comparisons to maintain
 * order
 * */
typedef int (*apr_skiplist_compare) (void *, void *);

/**
 * apr_skiplist_freefunc is the function type that must be implemented
 * to handle elements as they are removed from a skip list.
 */
typedef void (*apr_skiplist_freefunc) (void *);

/** Opaque structure used to represent the skip list */
struct apr_skiplist;
/** Opaque structure used to represent the skip list */
typedef struct apr_skiplist apr_skiplist;

/** 
 * Opaque structure used to represent abstract nodes in the skip list
 * (an abstraction above the raw elements which are collected in the
 * skip list).
 */
struct apr_skiplistnode;
/** Opaque structure */
typedef struct apr_skiplistnode apr_skiplistnode;

/**
 * Allocate memory using the same mechanism as the skip list.
 * @param sl The skip list
 * @param size The amount to allocate
 * @remark If a pool was provided to apr_skiplist_init(), memory will
 * be allocated from the pool or from a free list maintained with
 * the skip list.  Otherwise, memory will be allocated using the
 * C standard library heap functions.
 */
APR_DECLARE(void *) apr_skiplist_alloc(apr_skiplist *sl, size_t size);

/**
 * Free memory using the same mechanism as the skip list.
 * @param sl The skip list
 * @param mem The object to free
 * @remark If a pool was provided to apr_skiplist_init(), memory will
 * be added to a free list maintained with the skip list and be available
 * to operations on the skip list or to other calls to apr_skiplist_alloc().
 * Otherwise, memory will be freed using the  C standard library heap
 * functions.
 */
APR_DECLARE(void) apr_skiplist_free(apr_skiplist *sl, void *mem);

/**
 * Allocate a new skip list
 * @param sl The pointer in which to return the newly created skip list
 * @param p The pool from which to allocate the skip list (optional).
 * @remark Unlike most APR functions, a pool is optional.  If no pool
 * is provided, the C standard library heap functions will be used instead.
 */
APR_DECLARE(apr_status_t) apr_skiplist_init(apr_skiplist **sl, apr_pool_t *p);

/**
 * Set the comparison functions to be used for searching the skip list.
 * @param sl The skip list
 * @param XXX1 FIXME
 * @param XXX2 FIXME
 *
 * @remark If existing comparison functions are being replaced, the index
 * will be replaced during this call.  That is a potentially expensive
 * operation.
 */
APR_DECLARE(void) apr_skiplist_set_compare(apr_skiplist *sl, apr_skiplist_compare XXX1,
                             apr_skiplist_compare XXX2);

/**
 * Set the indexing functions to the specified comparison functions and
 * rebuild the index.
 * @param sl The skip list
 * @param XXX1 FIXME
 * @param XXX2 FIXME
 *
 * @remark If an index already exists, it will not be replaced and the
 * comparison functions will not be changed.
 */
APR_DECLARE(void) apr_skiplist_add_index(apr_skiplist *sl, apr_skiplist_compare XXX1,
                        apr_skiplist_compare XXX2);

/**
 * Return the list maintained by the skip list abstraction.
 * @param sl The skip list
 */
APR_DECLARE(apr_skiplistnode *) apr_skiplist_getlist(apr_skiplist *sl);

/**
 * Return the next matching element in the skip list using the specified
 * comparison function.
 * @param sl The skip list
 * @param data The value to search for
 * @param iter A pointer to the returned skip list node representing the element
 * found
 * @param func The comparison function to use
 */
APR_DECLARE(void *) apr_skiplist_find_compare(apr_skiplist *sl,
                               void *data,
                               apr_skiplistnode **iter,
                               apr_skiplist_compare func);

/**
 * Return the next matching element in the skip list using the current comparison
 * function.
 * @param sl The skip list
 * @param data The value to search for
 * @param iter A pointer to the returned skip list node representing the element
 * found
 */
APR_DECLARE(void *) apr_skiplist_find(apr_skiplist *sl, void *data, apr_skiplistnode **iter);

/**
 * Return the last matching element in the skip list using the specified
 * comparison function.
 * @param sl The skip list
 * @param data The value to search for
 * @param iter A pointer to the returned skip list node representing the element
 * found
 * @param comp The comparison function to use
 */
APR_DECLARE(void *) apr_skiplist_last_compare(apr_skiplist *sl, void *data,
                                              apr_skiplistnode **iter,
                                              apr_skiplist_compare comp);

/**
 * Return the last matching element in the skip list using the current comparison
 * function.
 * @param sl The skip list
 * @param data The value to search for
 * @param iter A pointer to the returned skip list node representing the element
 * found
 */
APR_DECLARE(void *) apr_skiplist_last(apr_skiplist *sl, void *data,
                                      apr_skiplistnode **iter);

/**
 * Return the next element in the skip list.
 * @param sl The skip list
 * @param iter On entry, a pointer to the skip list node to start with; on return,
 * a pointer to the skip list node representing the element returned
 * @remark If iter points to a NULL value on entry, NULL will be returned.
 */
APR_DECLARE(void *) apr_skiplist_next(apr_skiplist *sl, apr_skiplistnode **iter);

/**
 * Return the previous element in the skip list.
 * @param sl The skip list
 * @param iter On entry, a pointer to the skip list node to start with; on return,
 * a pointer to the skip list node representing the element returned
 * @remark If iter points to a NULL value on entry, NULL will be returned.
 */
APR_DECLARE(void *) apr_skiplist_previous(apr_skiplist *sl, apr_skiplistnode **iter);

/**
 * Return the element of the skip list node
 * @param iter The skip list node
 */
APR_DECLARE(void *) apr_skiplist_element(apr_skiplistnode *iter);

/**
 * Insert an element into the skip list using the specified comparison function
 * if it does not already exist.
 * @param sl The skip list
 * @param data The element to insert
 * @param comp The comparison function to use for placement into the skip list
 */
APR_DECLARE(apr_skiplistnode *) apr_skiplist_insert_compare(apr_skiplist *sl,
                                          void *data, apr_skiplist_compare comp);

/**
 * Insert an element into the skip list using the existing comparison function
 * if it does not already exist.
 * @param sl The skip list
 * @param data The element to insert
 * @remark If no comparison function has been set for the skip list, the element
 * will not be inserted and NULL will be returned.
 */
APR_DECLARE(apr_skiplistnode *) apr_skiplist_insert(apr_skiplist* sl, void *data);

/**
 * Add an element into the skip list using the specified comparison function
 * allowing for duplicates.
 * @param sl The skip list
 * @param data The element to add
 * @param comp The comparison function to use for placement into the skip list
 */
APR_DECLARE(apr_skiplistnode *) apr_skiplist_add_compare(apr_skiplist *sl,
                                          void *data, apr_skiplist_compare comp);

/**
 * Add an element into the skip list using the existing comparison function
 * allowing for duplicates.
 * @param sl The skip list
 * @param data The element to insert
 * @remark If no comparison function has been set for the skip list, the element
 * will not be inserted and NULL will be returned.
 */
APR_DECLARE(apr_skiplistnode *) apr_skiplist_add(apr_skiplist* sl, void *data);

/**
 * Add an element into the skip list using the specified comparison function
 * removing the existing duplicates.
 * @param sl The skip list
 * @param data The element to insert
 * @param comp The comparison function to use for placement into the skip list
 * @param myfree A function to be called for each removed duplicate
 * @remark If no comparison function has been set for the skip list, the element
 * will not be inserted, none will be replaced, and NULL will be returned.
 */
APR_DECLARE(apr_skiplistnode *) apr_skiplist_replace_compare(apr_skiplist *sl,
                                    void *data, apr_skiplist_freefunc myfree,
                                    apr_skiplist_compare comp);

/**
 * Add an element into the skip list using the existing comparison function
 * removing the existing duplicates.
 * @param sl The skip list
 * @param data The element to insert
 * @param myfree A function to be called for each removed duplicate
 * @remark If no comparison function has been set for the skip list, the element
 * will not be inserted, none will be replaced, and NULL will be returned.
 */
APR_DECLARE(apr_skiplistnode *) apr_skiplist_replace(apr_skiplist *sl,
                                    void *data, apr_skiplist_freefunc myfree);

/**
 * Remove a node from the skip list.
 * @param sl The skip list
 * @param iter The skip list node to remove
 * @param myfree A function to be called for the removed element
 */
APR_DECLARE(int) apr_skiplist_remove_node(apr_skiplist *sl,
                                          apr_skiplistnode *iter,
                                          apr_skiplist_freefunc myfree);

/**
 * Remove an element from the skip list using the specified comparison function for
 * locating the element. In the case of duplicates, the 1st entry will be removed.
 * @param sl The skip list
 * @param data The element to remove
 * @param myfree A function to be called for each removed element
 * @param comp The comparison function to use for placement into the skip list
 * @remark If the element is not found, 0 will be returned.  Otherwise, the heightXXX
 * will be returned.
 */
APR_DECLARE(int) apr_skiplist_remove_compare(apr_skiplist *sl, void *data,
                               apr_skiplist_freefunc myfree, apr_skiplist_compare comp);

/**
 * Remove an element from the skip list using the existing comparison function for
 * locating the element. In the case of duplicates, the 1st entry will be removed.
 * @param sl The skip list
 * @param data The element to remove
 * @param myfree A function to be called for each removed element
 * @remark If the element is not found, 0 will be returned.  Otherwise, the heightXXX
 * will be returned.
 * @remark If no comparison function has been set for the skip list, the element
 * will not be removed and 0 will be returned.
 */
APR_DECLARE(int) apr_skiplist_remove(apr_skiplist *sl, void *data, apr_skiplist_freefunc myfree);

/**
 * Remove all elements from the skip list.
 * @param sl The skip list
 * @param myfree A function to be called for each removed element
 */
APR_DECLARE(void) apr_skiplist_remove_all(apr_skiplist *sl, apr_skiplist_freefunc myfree);

/**
 * Remove each element from the skip list.
 * @param sl The skip list
 * @param myfree A function to be called for each removed element
 */
APR_DECLARE(void) apr_skiplist_destroy(apr_skiplist *sl, apr_skiplist_freefunc myfree);

/**
 * Return the first element in the skip list, removing the element from the skip list.
 * @param sl The skip list
 * @param myfree A function to be called for the removed element
 * @remark NULL will be returned if there are no elements
 */
APR_DECLARE(void *) apr_skiplist_pop(apr_skiplist *sl, apr_skiplist_freefunc myfree);

/**
 * Return the first element in the skip list, leaving the element in the skip list.
 * @param sl The skip list
 * @remark NULL will be returned if there are no elements
 */
APR_DECLARE(void *) apr_skiplist_peek(apr_skiplist *sl);

/**
 * Return the size of the list (number of elements), in O(1).
 * @param sl The skip list
 */
APR_DECLARE(size_t) apr_skiplist_size(const apr_skiplist *sl);

/**
 * Return the height of the list (number of skip paths), in O(1).
 * @param sl The skip list
 */
APR_DECLARE(int) apr_skiplist_height(const apr_skiplist *sl);

/**
 * Return the predefined maximum height of the skip list.
 * @param sl The skip list
 */
APR_DECLARE(int) apr_skiplist_preheight(const apr_skiplist *sl);

/**
 * Set a predefined maximum height for the skip list.
 * @param sl The skip list
 * @param to The preheight to set, or a nul/negative value to disable.
 * @remark When a preheight is used, the height of each inserted element is
 * computed randomly up to this preheight instead of the current skip list's
 * height plus one used by the default implementation. Using a preheight can
 * probably ensure more fairness with long living elements (since with an
 * adaptative height, former elements may have been created with a low height,
 * hence a longest path to reach them while the skip list grows). On the other
 * hand, the default behaviour (preheight <= 0) with a growing and decreasing
 * maximum height is more adaptative/suitable for short living values.
 * @note Should be called before any insertion/add.
 */
APR_DECLARE(void) apr_skiplist_set_preheight(apr_skiplist *sl, int to);

/**
 * Merge two skip lists.  XXX SEMANTICS
 * @param sl1 One of two skip lists to be merged
 * @param sl2 The other of two skip lists to be merged
 */
APR_DECLARE(apr_skiplist *) apr_skiplist_merge(apr_skiplist *sl1, apr_skiplist *sl2);

/** @} */

#ifdef __cplusplus
}
#endif

#endif /* ! APR_SKIPLIST_H */
apr-1/apr_shm.h000064400000022413151730340520007270 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_SHM_H
#define APR_SHM_H

/**
 * @file apr_shm.h
 * @brief APR Shared Memory Routines
 */

#include "apr.h"
#include "apr_pools.h"
#include "apr_errno.h"
#include "apr_perms_set.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @defgroup apr_shm Shared Memory Routines
 * @ingroup APR 
 * @{
 */

/**
 * Private, platform-specific data struture representing a shared memory
 * segment.
 */
typedef struct apr_shm_t apr_shm_t;

/**
 * Create and make accessible a shared memory segment with default
 * properties.
 * @param m The shared memory structure to create.
 * @param reqsize The desired size of the segment.
 * @param filename The file to use for shared memory on platforms that
 *        require it.
 * @param pool the pool from which to allocate the shared memory
 *        structure.
 * @remark A note about Anonymous vs. Named shared memory segments:
 *         Not all plaforms support anonymous shared memory segments, but in
 *         some cases it is prefered over other types of shared memory
 *         implementations. Passing a NULL 'file' parameter to this function
 *         will cause the subsystem to use anonymous shared memory segments.
 *         If such a system is not available, APR_ENOTIMPL is returned.
 * @remark A note about allocation sizes:
 *         On some platforms it is necessary to store some metainformation
 *         about the segment within the actual segment. In order to supply
 *         the caller with the requested size it may be necessary for the
 *         implementation to request a slightly greater segment length
 *         from the subsystem. In all cases, the apr_shm_baseaddr_get()
 *         function will return the first usable byte of memory.
 * 
 */
APR_DECLARE(apr_status_t) apr_shm_create(apr_shm_t **m,
                                         apr_size_t reqsize,
                                         const char *filename,
                                         apr_pool_t *pool);

/**
 * Special processing flags for apr_shm_create_ex() and apr_shm_attach_ex().
 */
#define APR_SHM_NS_LOCAL    1 /* Create or attach to named shared memory
                               * segment in the "Local" namespace on
                               * Windows.  (Ignored on other platforms.)
                               * By default, the "Global" namespace is
                               * used for privileged processes and the
                               * "Local" namespace is used otherwise.
                               */
#define APR_SHM_NS_GLOBAL   2 /* Create or attach to named shared memory
                               * segment in the "Global" namespace on
                               * Windows.  (Ignored on other platforms.)
                               */

/**
 * Create and make accessible a shared memory segment with platform-
 * specific processing.
 * @param m The shared memory structure to create.
 * @param reqsize The desired size of the segment.
 * @param filename The file to use for shared memory on platforms that
 *        require it.
 * @param pool the pool from which to allocate the shared memory
 *        structure.
 * @param flags mask of APR_SHM_* (defined above)
 * @remark A note about Anonymous vs. Named shared memory segments:
 *         Not all plaforms support anonymous shared memory segments, but in
 *         some cases it is prefered over other types of shared memory
 *         implementations. Passing a NULL 'file' parameter to this function
 *         will cause the subsystem to use anonymous shared memory segments.
 *         If such a system is not available, APR_ENOTIMPL is returned.
 * @remark A note about allocation sizes:
 *         On some platforms it is necessary to store some metainformation
 *         about the segment within the actual segment. In order to supply
 *         the caller with the requested size it may be necessary for the
 *         implementation to request a slightly greater segment length
 *         from the subsystem. In all cases, the apr_shm_baseaddr_get()
 *         function will return the first usable byte of memory.
 * 
 */
APR_DECLARE(apr_status_t) apr_shm_create_ex(apr_shm_t **m,
                                            apr_size_t reqsize,
                                            const char *filename,
                                            apr_pool_t *pool,
                                            apr_int32_t flags);

/**
 * Remove named resource associated with a shared memory segment,
 * preventing attachments to the resource, but not destroying it.
 * @param filename The filename associated with shared-memory segment which
 *        needs to be removed
 * @param pool The pool used for file operations
 * @remark This function is only supported on platforms which support
 * name-based shared memory segments, and will return APR_ENOTIMPL on
 * platforms without such support.  Removing the file while the shm
 * is in use is not entirely portable, caller may use this to enhance
 * obscurity of the resource, but be prepared for the call to fail,
 * and for concurrent attempts to create a resource of the same name
 * to also fail.  The pool cleanup of apr_shm_create (apr_shm_destroy)
 * also removes the named resource.
 */
APR_DECLARE(apr_status_t) apr_shm_remove(const char *filename,
                                         apr_pool_t *pool);

/**
 * Delete named resource associated with a shared memory segment,
 * preventing attachments to the resource.
 * @param m The shared memory segment structure to delete.
 * @remark This function is only supported on platforms which support
 * name-based shared memory segments, and will return APR_ENOTIMPL on
 * platforms without such support.  Removing the file while the shm
 * is in use is not entirely portable, caller may use this to enhance
 * obscurity of the resource, but be prepared for the call to fail,
 * and for concurrent attempts to create a resource of the same name
 * to also fail.  The pool cleanup of apr_shm_create (apr_shm_destroy)
 * also removes the named resource.
 */
APR_DECLARE(apr_status_t) apr_shm_delete(apr_shm_t *m);

/**
 * Destroy a shared memory segment and associated memory.
 * @param m The shared memory segment structure to destroy.
 */
APR_DECLARE(apr_status_t) apr_shm_destroy(apr_shm_t *m);

/**
 * Attach to a shared memory segment that was created
 * by another process.
 * @param m The shared memory structure to create.
 * @param filename The file used to create the original segment.
 *        (This MUST match the original filename.)
 * @param pool the pool from which to allocate the shared memory
 *        structure for this process.
 */
APR_DECLARE(apr_status_t) apr_shm_attach(apr_shm_t **m,
                                         const char *filename,
                                         apr_pool_t *pool);

/**
 * Attach to a shared memory segment that was created
 * by another process, with platform-specific processing.
 * @param m The shared memory structure to create.
 * @param filename The file used to create the original segment.
 *        (This MUST match the original filename.)
 * @param pool the pool from which to allocate the shared memory
 *        structure for this process.
 * @param flags mask of APR_SHM_* (defined above)
 */
APR_DECLARE(apr_status_t) apr_shm_attach_ex(apr_shm_t **m,
                                            const char *filename,
                                            apr_pool_t *pool,
                                            apr_int32_t flags);

/**
 * Detach from a shared memory segment without destroying it.
 * @param m The shared memory structure representing the segment
 *        to detach from.
 */
APR_DECLARE(apr_status_t) apr_shm_detach(apr_shm_t *m);

/**
 * Retrieve the base address of the shared memory segment.
 * NOTE: This address is only usable within the callers address
 * space, since this API does not guarantee that other attaching
 * processes will maintain the same address mapping.
 * @param m The shared memory segment from which to retrieve
 *        the base address.
 * @return address, aligned by APR_ALIGN_DEFAULT.
 */
APR_DECLARE(void *) apr_shm_baseaddr_get(const apr_shm_t *m);

/**
 * Retrieve the length of a shared memory segment in bytes.
 * @param m The shared memory segment from which to retrieve
 *        the segment length.
 */
APR_DECLARE(apr_size_t) apr_shm_size_get(const apr_shm_t *m);

/**
 * Set shared memory permissions.
 */
APR_PERMS_SET_IMPLEMENT(shm);

/**
 * Get the pool used by this shared memory segment.
 */
APR_POOL_DECLARE_ACCESSOR(shm);

/** @} */ 

#ifdef __cplusplus
}
#endif

#endif  /* APR_SHM_T */
apr-1/apr_version.h000064400000012337151730340520010172 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_VERSION_H
#define APR_VERSION_H

/**
 * @file apr_version.h
 * @brief APR Versioning Interface
 * 
 * APR's Version
 *
 * There are several different mechanisms for accessing the version. There
 * is a string form, and a set of numbers; in addition, there are constants
 * which can be compiled into your application, and you can query the library
 * being used for its actual version.
 *
 * Note that it is possible for an application to detect that it has been
 * compiled against a different version of APR by use of the compile-time
 * constants and the use of the run-time query function.
 *
 * APR version numbering follows the guidelines specified in:
 *
 *     http://apr.apache.org/versioning.html
 */


#define APR_COPYRIGHT "Copyright 2025 The Apache Software Foundation."

/* The numeric compile-time version constants. These constants are the
 * authoritative version numbers for APR. 
 */

/** major version 
 * Major API changes that could cause compatibility problems for older
 * programs such as structure size changes.  No binary compatibility is
 * possible across a change in the major version.
 */
#define APR_MAJOR_VERSION       1

/** minor version
 * Minor API changes that do not cause binary compatibility problems.
 * Reset to 0 when upgrading APR_MAJOR_VERSION
 */
#define APR_MINOR_VERSION       7

/** patch level 
 * The Patch Level never includes API changes, simply bug fixes.
 * Reset to 0 when upgrading APR_MINOR_VERSION
 */
#define APR_PATCH_VERSION       6

/** 
 * The symbol APR_IS_DEV_VERSION is only defined for internal,
 * "development" copies of APR.  It is undefined for released versions
 * of APR.
 */
/* #undef APR_IS_DEV_VERSION */

/**
 * Check at compile time if the APR version is at least a certain
 * level.
 * @param major The major version component of the version checked
 * for (e.g., the "1" of "1.3.0").
 * @param minor The minor version component of the version checked
 * for (e.g., the "3" of "1.3.0").
 * @param patch The patch level component of the version checked
 * for (e.g., the "0" of "1.3.0").
 * @remark This macro is available with APR versions starting with
 * 1.3.0.
 */
#define APR_VERSION_AT_LEAST(major,minor,patch)                    \
(((major) < APR_MAJOR_VERSION)                                     \
 || ((major) == APR_MAJOR_VERSION && (minor) < APR_MINOR_VERSION) \
 || ((major) == APR_MAJOR_VERSION && (minor) == APR_MINOR_VERSION && (patch) <= APR_PATCH_VERSION))

#if defined(APR_IS_DEV_VERSION) || defined(DOXYGEN)
/** Internal: string form of the "is dev" flag */
#ifndef APR_IS_DEV_STRING
#define APR_IS_DEV_STRING "-dev"
#endif
#else
#define APR_IS_DEV_STRING ""
#endif

/* APR_STRINGIFY is defined here, and also in apr_general.h, so wrap it */
#ifndef APR_STRINGIFY
/** Properly quote a value as a string in the C preprocessor */
#define APR_STRINGIFY(n) APR_STRINGIFY_HELPER(n)
/** Helper macro for APR_STRINGIFY */
#define APR_STRINGIFY_HELPER(n) #n
#endif

/** The formatted string of APR's version */
#define APR_VERSION_STRING \
     APR_STRINGIFY(APR_MAJOR_VERSION) "." \
     APR_STRINGIFY(APR_MINOR_VERSION) "." \
     APR_STRINGIFY(APR_PATCH_VERSION) \
     APR_IS_DEV_STRING

/** An alternative formatted string of APR's version */
/* macro for Win32 .rc files using numeric csv representation */
#define APR_VERSION_STRING_CSV APR_MAJOR_VERSION ##, \
                             ##APR_MINOR_VERSION ##, \
                             ##APR_PATCH_VERSION


#ifndef APR_VERSION_ONLY

/* The C language API to access the version at run time, 
 * as opposed to compile time.  APR_VERSION_ONLY may be defined 
 * externally when preprocessing apr_version.h to obtain strictly 
 * the C Preprocessor macro declarations.
 */

#include "apr.h"

#ifdef __cplusplus
extern "C" {
#endif

/** 
 * The numeric version information is broken out into fields within this 
 * structure. 
 */
typedef struct {
    int major;      /**< major number */
    int minor;      /**< minor number */
    int patch;      /**< patch number */
    int is_dev;     /**< is development (1 or 0) */
} apr_version_t;

/**
 * Return APR's version information information in a numeric form.
 *
 *  @param pvsn Pointer to a version structure for returning the version
 *              information.
 */
APR_DECLARE(void) apr_version(apr_version_t *pvsn);

/** Return APR's version information as a string. */
APR_DECLARE(const char *) apr_version_string(void);

#ifdef __cplusplus
}
#endif

#endif /* ndef APR_VERSION_ONLY */

#endif /* ndef APR_VERSION_H */
apr-1/apr_thread_proc.h000064400000111470151730340530010776 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_THREAD_PROC_H
#define APR_THREAD_PROC_H

/**
 * @file apr_thread_proc.h
 * @brief APR Thread and Process Library
 */

#include "apr.h"
#include "apr_file_io.h"
#include "apr_pools.h"
#include "apr_errno.h"
#include "apr_perms_set.h"

#if APR_HAVE_STRUCT_RLIMIT
#include <sys/time.h>
#include <sys/resource.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @defgroup apr_thread_proc Threads and Process Functions
 * @ingroup APR 
 * @{
 */

typedef enum {
    APR_SHELLCMD,           /**< use the shell to invoke the program */
    APR_PROGRAM,            /**< invoke the program directly, no copied env */
    APR_PROGRAM_ENV,        /**< invoke the program, replicating our environment */
    APR_PROGRAM_PATH,       /**< find program on PATH, use our environment */
    APR_SHELLCMD_ENV        /**< use the shell to invoke the program,
                             *   replicating our environment
                             */
} apr_cmdtype_e;

typedef enum {
    APR_WAIT,           /**< wait for the specified process to finish */
    APR_NOWAIT          /**< do not wait -- just see if it has finished */
} apr_wait_how_e;

/* I am specifically calling out the values so that the macros below make
 * more sense.  Yes, I know I don't need to, but I am hoping this makes what
 * I am doing more clear.  If you want to add more reasons to exit, continue
 * to use bitmasks.
 */
typedef enum {
    APR_PROC_EXIT = 1,          /**< process exited normally */
    APR_PROC_SIGNAL = 2,        /**< process exited due to a signal */
    APR_PROC_SIGNAL_CORE = 4    /**< process exited and dumped a core file */
} apr_exit_why_e;

/** did we exit the process */
#define APR_PROC_CHECK_EXIT(x)        (x & APR_PROC_EXIT)
/** did we get a signal */
#define APR_PROC_CHECK_SIGNALED(x)    (x & APR_PROC_SIGNAL)
/** did we get core */
#define APR_PROC_CHECK_CORE_DUMP(x)   (x & APR_PROC_SIGNAL_CORE)

/** @see apr_procattr_io_set */
#define APR_NO_PIPE          0
/** @see apr_procattr_io_set and apr_file_pipe_create_ex */
#define APR_FULL_BLOCK       1
/** @see apr_procattr_io_set and apr_file_pipe_create_ex */
#define APR_FULL_NONBLOCK    2
/** @see apr_procattr_io_set */
#define APR_PARENT_BLOCK     3
/** @see apr_procattr_io_set */
#define APR_CHILD_BLOCK      4
/** @see apr_procattr_io_set */
#define APR_NO_FILE          8

/** @see apr_file_pipe_create_ex */
#define APR_READ_BLOCK       3
/** @see apr_file_pipe_create_ex */
#define APR_WRITE_BLOCK      4

/** @see apr_procattr_io_set 
 * @note Win32 only effective with version 1.2.12, portably introduced in 1.3.0
 */
#define APR_NO_FILE          8

/** @see apr_procattr_limit_set */
#define APR_LIMIT_CPU        0
/** @see apr_procattr_limit_set */
#define APR_LIMIT_MEM        1
/** @see apr_procattr_limit_set */
#define APR_LIMIT_NPROC      2
/** @see apr_procattr_limit_set */
#define APR_LIMIT_NOFILE     3

/**
 * @defgroup APR_OC Other Child Flags
 * @{
 */
#define APR_OC_REASON_DEATH         0     /**< child has died, caller must call
                                           * unregister still */
#define APR_OC_REASON_UNWRITABLE    1     /**< write_fd is unwritable */
#define APR_OC_REASON_RESTART       2     /**< a restart is occurring, perform
                                           * any necessary cleanup (including
                                           * sending a special signal to child)
                                           */
#define APR_OC_REASON_UNREGISTER    3     /**< unregister has been called, do
                                           * whatever is necessary (including
                                           * kill the child) */
#define APR_OC_REASON_LOST          4     /**< somehow the child exited without
                                           * us knowing ... buggy os? */
#define APR_OC_REASON_RUNNING       5     /**< a health check is occurring, 
                                           * for most maintainence functions
                                           * this is a no-op.
                                           */
/** @} */

/** The APR process type */
typedef struct apr_proc_t {
    /** The process ID */
    pid_t pid;
    /** Parent's side of pipe to child's stdin */
    apr_file_t *in;
    /** Parent's side of pipe to child's stdout */
    apr_file_t *out;
    /** Parent's side of pipe to child's stdouterr */
    apr_file_t *err;
#if APR_HAS_PROC_INVOKED || defined(DOXYGEN)
    /** Diagnositics/debugging string of the command invoked for 
     *  this process [only present if APR_HAS_PROC_INVOKED is true]
     * @remark Only enabled on Win32 by default.
     * @bug This should either always or never be present in release
     * builds - since it breaks binary compatibility.  We may enable
     * it always in APR 1.0 yet leave it undefined in most cases.
     */
    char *invoked;
#endif
#if defined(WIN32) || defined(DOXYGEN)
    /** (Win32 only) Creator's handle granting access to the process
     * @remark This handle is closed and reset to NULL in every case
     * corresponding to a waitpid() on Unix which returns the exit status.
     * Therefore Win32 correspond's to Unix's zombie reaping characteristics
     * and avoids potential handle leaks.
     */
    HANDLE hproc;
#endif
} apr_proc_t;

/**
 * The prototype for APR child errfn functions.  (See the description
 * of apr_procattr_child_errfn_set() for more information.)
 * It is passed the following parameters:
 * @param pool Pool associated with the apr_proc_t.  If your child
 *             error function needs user data, associate it with this
 *             pool.
 * @param err APR error code describing the error
 * @param description Text description of type of processing which failed
 */
typedef void (apr_child_errfn_t)(apr_pool_t *proc, apr_status_t err,
                                 const char *description);

/** Opaque Thread structure. */
typedef struct apr_thread_t           apr_thread_t;

/** Opaque Thread attributes structure. */
typedef struct apr_threadattr_t       apr_threadattr_t;

/** Opaque Process attributes structure. */
typedef struct apr_procattr_t         apr_procattr_t;

/** Opaque control variable for one-time atomic variables.  */
typedef struct apr_thread_once_t      apr_thread_once_t;

/** Opaque thread private address space. */
typedef struct apr_threadkey_t        apr_threadkey_t;

/** Opaque record of child process. */
typedef struct apr_other_child_rec_t  apr_other_child_rec_t;

/**
 * The prototype for any APR thread worker functions.
 */
typedef void *(APR_THREAD_FUNC *apr_thread_start_t)(apr_thread_t*, void*);

typedef enum {
    APR_KILL_NEVER,             /**< process is never killed (i.e., never sent
                                 * any signals), but it will be reaped if it exits
                                 * before the pool is cleaned up */
    APR_KILL_ALWAYS,            /**< process is sent SIGKILL on apr_pool_t cleanup */
    APR_KILL_AFTER_TIMEOUT,     /**< SIGTERM, wait 3 seconds, SIGKILL */
    APR_JUST_WAIT,              /**< wait forever for the process to complete */
    APR_KILL_ONLY_ONCE          /**< send SIGTERM and then wait */
} apr_kill_conditions_e;

/* LVE support */

#define LVE_APACHE_SUPPORT

APR_DECLARE(apr_status_t) apr_lve_environment_init(int lve_no_maxenter_value,
                                                   void *lve_ptr,
                                                   int (*lve_enter_flags_function_ptr)(void *, ...),
                                                   int (*lve_leave_function_ptr)(void *, ...),
                                                   char *suexec_string);

APR_DECLARE(apr_status_t) apr_lve_environment_init_group(int lve_no_maxenter_value,
                                                   void *lve_ptr,
                                                   int (*lve_enter_flags_function_ptr)(void *, ...),
                                                   int (*lve_leave_function_ptr)(void *, ...),
                                                   char *suexec_string,
                                                   int use_group);
                                                   
APR_DECLARE(apr_status_t) apr_lve_environment_init_group_minuid(int lve_no_maxenter_value,
                                                    void *lve_ptr,
                                                    int (*lve_enter_flags_function_ptr)(void *, ...),
                                                    int (*lve_leave_function_ptr)(void *, ...),
                                                    char *suexec_string,
                                                    int use_group,
                                                    int min_uid);

/* Thread Function definitions */

#if APR_HAS_THREADS

/**
 * Create and initialize a new threadattr variable
 * @param new_attr The newly created threadattr.
 * @param cont The pool to use
 */
APR_DECLARE(apr_status_t) apr_threadattr_create(apr_threadattr_t **new_attr, 
                                                apr_pool_t *cont);

/**
 * Set if newly created threads should be created in detached state.
 * @param attr The threadattr to affect 
 * @param on Non-zero if detached threads should be created.
 */
APR_DECLARE(apr_status_t) apr_threadattr_detach_set(apr_threadattr_t *attr, 
                                                    apr_int32_t on);

/**
 * Get the detach state for this threadattr.
 * @param attr The threadattr to reference
 * @return APR_DETACH if threads are to be detached, or APR_NOTDETACH
 * if threads are to be joinable. 
 */
APR_DECLARE(apr_status_t) apr_threadattr_detach_get(apr_threadattr_t *attr);

/**
 * Set the stack size of newly created threads.
 * @param attr The threadattr to affect 
 * @param stacksize The stack size in bytes
 */
APR_DECLARE(apr_status_t) apr_threadattr_stacksize_set(apr_threadattr_t *attr,
                                                       apr_size_t stacksize);

/**
 * Set the stack guard area size of newly created threads.
 * @param attr The threadattr to affect 
 * @param guardsize The stack guard area size in bytes
 * @note Thread library implementations commonly use a "guard area"
 * after each thread's stack which is not readable or writable such that
 * stack overflows cause a segfault; this consumes e.g. 4K of memory
 * and increases memory management overhead.  Setting the guard area
 * size to zero hence trades off reliable behaviour on stack overflow
 * for performance. */
APR_DECLARE(apr_status_t) apr_threadattr_guardsize_set(apr_threadattr_t *attr,
                                                       apr_size_t guardsize);

/**
 * Create a new thread of execution
 * @param new_thread The newly created thread handle.
 * @param attr The threadattr to use to determine how to create the thread
 * @param func The function to start the new thread in
 * @param data Any data to be passed to the starting function
 * @param cont The pool to use
 */
APR_DECLARE(apr_status_t) apr_thread_create(apr_thread_t **new_thread, 
                                            apr_threadattr_t *attr, 
                                            apr_thread_start_t func, 
                                            void *data, apr_pool_t *cont);

/**
 * stop the current thread
 * @param thd The thread to stop
 * @param retval The return value to pass back to any thread that cares
 */
APR_DECLARE(apr_status_t) apr_thread_exit(apr_thread_t *thd, 
                                          apr_status_t retval);

/**
 * block until the desired thread stops executing.
 * @param retval The return value from the dead thread.
 * @param thd The thread to join
 */
APR_DECLARE(apr_status_t) apr_thread_join(apr_status_t *retval, 
                                          apr_thread_t *thd); 

/**
 * force the current thread to yield the processor
 */
APR_DECLARE(void) apr_thread_yield(void);

/**
 * Initialize the control variable for apr_thread_once.  If this isn't
 * called, apr_initialize won't work.
 * @param control The control variable to initialize
 * @param p The pool to allocate data from.
 */
APR_DECLARE(apr_status_t) apr_thread_once_init(apr_thread_once_t **control,
                                               apr_pool_t *p);

/**
 * Run the specified function one time, regardless of how many threads
 * call it.
 * @param control The control variable.  The same variable should
 *                be passed in each time the function is tried to be
 *                called.  This is how the underlying functions determine
 *                if the function has ever been called before.
 * @param func The function to call.
 */
APR_DECLARE(apr_status_t) apr_thread_once(apr_thread_once_t *control,
                                          void (*func)(void));

/**
 * detach a thread
 * @param thd The thread to detach 
 */
APR_DECLARE(apr_status_t) apr_thread_detach(apr_thread_t *thd);

/**
 * Return user data associated with the current thread.
 * @param data The user data associated with the thread.
 * @param key The key to associate with the data
 * @param thread The currently open thread.
 */
APR_DECLARE(apr_status_t) apr_thread_data_get(void **data, const char *key,
                                             apr_thread_t *thread);

/**
 * Set user data associated with the current thread.
 * @param data The user data to associate with the thread.
 * @param key The key to use for associating the data with the thread
 * @param cleanup The cleanup routine to use when the thread is destroyed.
 * @param thread The currently open thread.
 */
APR_DECLARE(apr_status_t) apr_thread_data_set(void *data, const char *key,
                                             apr_status_t (*cleanup) (void *),
                                             apr_thread_t *thread);

/**
 * Create and initialize a new thread private address space
 * @param key The thread private handle.
 * @param dest The destructor to use when freeing the private memory.
 * @param cont The pool to use
 */
APR_DECLARE(apr_status_t) apr_threadkey_private_create(apr_threadkey_t **key, 
                                                    void (*dest)(void *),
                                                    apr_pool_t *cont);

/**
 * Get a pointer to the thread private memory
 * @param new_mem The data stored in private memory 
 * @param key The handle for the desired thread private memory 
 */
APR_DECLARE(apr_status_t) apr_threadkey_private_get(void **new_mem, 
                                                 apr_threadkey_t *key);

/**
 * Set the data to be stored in thread private memory
 * @param priv The data to be stored in private memory 
 * @param key The handle for the desired thread private memory 
 */
APR_DECLARE(apr_status_t) apr_threadkey_private_set(void *priv, 
                                                 apr_threadkey_t *key);

/**
 * Free the thread private memory
 * @param key The handle for the desired thread private memory 
 */
APR_DECLARE(apr_status_t) apr_threadkey_private_delete(apr_threadkey_t *key);

/**
 * Return the pool associated with the current threadkey.
 * @param data The user data associated with the threadkey.
 * @param key The key associated with the data
 * @param threadkey The currently open threadkey.
 */
APR_DECLARE(apr_status_t) apr_threadkey_data_get(void **data, const char *key,
                                                apr_threadkey_t *threadkey);

/**
 * Return the pool associated with the current threadkey.
 * @param data The data to set.
 * @param key The key to associate with the data.
 * @param cleanup The cleanup routine to use when the file is destroyed.
 * @param threadkey The currently open threadkey.
 */
APR_DECLARE(apr_status_t) apr_threadkey_data_set(void *data, const char *key,
                                                apr_status_t (*cleanup) (void *),
                                                apr_threadkey_t *threadkey);

#endif

/**
 * Create and initialize a new procattr variable
 * @param new_attr The newly created procattr. 
 * @param cont The pool to use
 */
APR_DECLARE(apr_status_t) apr_procattr_create(apr_procattr_t **new_attr,
                                                  apr_pool_t *cont);

/**
 * Determine if any of stdin, stdout, or stderr should be linked to pipes 
 * when starting a child process.
 * @param attr The procattr we care about. 
 * @param in Should stdin be a pipe back to the parent?
 * @param out Should stdout be a pipe back to the parent?
 * @param err Should stderr be a pipe back to the parent?
 * @note If APR_NO_PIPE, there will be no special channel, the child
 * inherits the parent's corresponding stdio stream.  If APR_NO_FILE is 
 * specified, that corresponding stream is closed in the child (and will
 * be INVALID_HANDLE_VALUE when inspected on Win32). This can have ugly 
 * side effects, as the next file opened in the child on Unix will fall
 * into the stdio stream fd slot!
 */
APR_DECLARE(apr_status_t) apr_procattr_io_set(apr_procattr_t *attr, 
                                             apr_int32_t in, apr_int32_t out,
                                             apr_int32_t err);

/**
 * Set the child_in and/or parent_in values to existing apr_file_t values.
 * @param attr The procattr we care about. 
 * @param child_in apr_file_t value to use as child_in. Must be a valid file.
 * @param parent_in apr_file_t value to use as parent_in. Must be a valid file.
 * @remark  This is NOT a required initializer function. This is
 *          useful if you have already opened a pipe (or multiple files)
 *          that you wish to use, perhaps persistently across multiple
 *          process invocations - such as a log file. You can save some 
 *          extra function calls by not creating your own pipe since this
 *          creates one in the process space for you.
 * @bug Note that calling this function with two NULL files on some platforms
 * creates an APR_FULL_BLOCK pipe, but this behavior is neither portable nor
 * is it supported.  @see apr_procattr_io_set instead for simple pipes.
 */
APR_DECLARE(apr_status_t) apr_procattr_child_in_set(struct apr_procattr_t *attr,
                                                  apr_file_t *child_in,
                                                  apr_file_t *parent_in);

/**
 * Set the child_out and parent_out values to existing apr_file_t values.
 * @param attr The procattr we care about. 
 * @param child_out apr_file_t value to use as child_out. Must be a valid file.
 * @param parent_out apr_file_t value to use as parent_out. Must be a valid file.
 * @remark This is NOT a required initializer function. This is
 *         useful if you have already opened a pipe (or multiple files)
 *         that you wish to use, perhaps persistently across multiple
 *         process invocations - such as a log file. 
 * @bug Note that calling this function with two NULL files on some platforms
 * creates an APR_FULL_BLOCK pipe, but this behavior is neither portable nor
 * is it supported.  @see apr_procattr_io_set instead for simple pipes.
 */
APR_DECLARE(apr_status_t) apr_procattr_child_out_set(struct apr_procattr_t *attr,
                                                   apr_file_t *child_out,
                                                   apr_file_t *parent_out);

/**
 * Set the child_err and parent_err values to existing apr_file_t values.
 * @param attr The procattr we care about. 
 * @param child_err apr_file_t value to use as child_err. Must be a valid file.
 * @param parent_err apr_file_t value to use as parent_err. Must be a valid file.
 * @remark This is NOT a required initializer function. This is
 *         useful if you have already opened a pipe (or multiple files)
 *         that you wish to use, perhaps persistently across multiple
 *         process invocations - such as a log file. 
 * @bug Note that calling this function with two NULL files on some platforms
 * creates an APR_FULL_BLOCK pipe, but this behavior is neither portable nor
 * is it supported.  @see apr_procattr_io_set instead for simple pipes.
 */
APR_DECLARE(apr_status_t) apr_procattr_child_err_set(struct apr_procattr_t *attr,
                                                   apr_file_t *child_err,
                                                   apr_file_t *parent_err);

/**
 * Set which directory the child process should start executing in.
 * @param attr The procattr we care about. 
 * @param dir Which dir to start in.  By default, this is the same dir as
 *            the parent currently resides in, when the createprocess call
 *            is made. 
 */
APR_DECLARE(apr_status_t) apr_procattr_dir_set(apr_procattr_t *attr, 
                                              const char *dir);

/**
 * Set what type of command the child process will call.
 * @param attr The procattr we care about. 
 * @param cmd The type of command.  One of:
 * <PRE>
 *            APR_SHELLCMD     --  Anything that the shell can handle
 *            APR_PROGRAM      --  Executable program   (default) 
 *            APR_PROGRAM_ENV  --  Executable program, copy environment
 *            APR_PROGRAM_PATH --  Executable program on PATH, copy env
 * </PRE>
 */
APR_DECLARE(apr_status_t) apr_procattr_cmdtype_set(apr_procattr_t *attr,
                                                  apr_cmdtype_e cmd);

/**
 * Determine if the child should start in detached state.
 * @param attr The procattr we care about. 
 * @param detach Should the child start in detached state?  Default is no. 
 */
APR_DECLARE(apr_status_t) apr_procattr_detach_set(apr_procattr_t *attr, 
                                                 apr_int32_t detach);

#if APR_HAVE_STRUCT_RLIMIT
/**
 * Set the Resource Utilization limits when starting a new process.
 * @param attr The procattr we care about. 
 * @param what Which limit to set, one of:
 * <PRE>
 *                 APR_LIMIT_CPU
 *                 APR_LIMIT_MEM
 *                 APR_LIMIT_NPROC
 *                 APR_LIMIT_NOFILE
 * </PRE>
 * @param limit Value to set the limit to.
 */
APR_DECLARE(apr_status_t) apr_procattr_limit_set(apr_procattr_t *attr, 
                                                apr_int32_t what,
                                                struct rlimit *limit);
#endif

/**
 * Specify an error function to be called in the child process if APR
 * encounters an error in the child prior to running the specified program.
 * @param attr The procattr describing the child process to be created.
 * @param errfn The function to call in the child process.
 * @remark At the present time, it will only be called from apr_proc_create()
 *         on platforms where fork() is used.  It will never be called on other
 *         platforms, on those platforms apr_proc_create() will return the error
 *         in the parent process rather than invoke the callback in the now-forked
 *         child process.
 */
APR_DECLARE(apr_status_t) apr_procattr_child_errfn_set(apr_procattr_t *attr,
                                                       apr_child_errfn_t *errfn);

/**
 * Specify that apr_proc_create() should do whatever it can to report
 * failures to the caller of apr_proc_create(), rather than find out in
 * the child.
 * @param attr The procattr describing the child process to be created.
 * @param chk Flag to indicate whether or not extra work should be done
 *            to try to report failures to the caller.
 * @remark This flag only affects apr_proc_create() on platforms where
 *         fork() is used.  This leads to extra overhead in the calling
 *         process, but that may help the application handle such
 *         errors more gracefully.
 */
APR_DECLARE(apr_status_t) apr_procattr_error_check_set(apr_procattr_t *attr,
                                                       apr_int32_t chk);

/**
 * Determine if the child should start in its own address space or using the 
 * current one from its parent
 * @param attr The procattr we care about. 
 * @param addrspace Should the child start in its own address space?  Default
 *                  is no on NetWare and yes on other platforms.
 */
APR_DECLARE(apr_status_t) apr_procattr_addrspace_set(apr_procattr_t *attr,
                                                       apr_int32_t addrspace);

/**
 * Set the username used for running process
 * @param attr The procattr we care about. 
 * @param username The username used
 * @param password User password if needed. Password is needed on WIN32
 *                 or any other platform having
 *                 APR_PROCATTR_USER_SET_REQUIRES_PASSWORD set.
 */
APR_DECLARE(apr_status_t) apr_procattr_user_set(apr_procattr_t *attr,
                                                const char *username,
                                                const char *password);

/**
 * Set the group used for running process
 * @param attr The procattr we care about. 
 * @param groupname The group name  used
 */
APR_DECLARE(apr_status_t) apr_procattr_group_set(apr_procattr_t *attr,
                                                 const char *groupname);


/**
 * Register permission set function
 * @param attr The procattr we care about. 
 * @param perms_set_fn Permission set callback
 * @param data Data to pass to permission callback function
 * @param perms Permissions to set
 */
APR_DECLARE(apr_status_t) apr_procattr_perms_set_register(apr_procattr_t *attr,
                                                 apr_perms_setfn_t *perms_set_fn,
                                                 void *data,
                                                 apr_fileperms_t perms);

#if APR_HAS_FORK
/**
 * This is currently the only non-portable call in APR.  This executes 
 * a standard unix fork.
 * @param proc The resulting process handle. 
 * @param cont The pool to use. 
 * @remark returns APR_INCHILD for the child, and APR_INPARENT for the parent
 * or an error.
 */
APR_DECLARE(apr_status_t) apr_proc_fork(apr_proc_t *proc, apr_pool_t *cont);
#endif

/**
 * Create a new process and execute a new program within that process.
 * @param new_proc The resulting process handle.
 * @param progname The program to run 
 * @param args the arguments to pass to the new program.  The first 
 *             one should be the program name.
 * @param env The new environment table for the new process.  This 
 *            should be a list of NULL-terminated strings. This argument
 *            is ignored for APR_PROGRAM_ENV, APR_PROGRAM_PATH, and
 *            APR_SHELLCMD_ENV types of commands.
 * @param attr the procattr we should use to determine how to create the new
 *         process
 * @param pool The pool to use.
 * @note This function returns without waiting for the new process to terminate;
 * use apr_proc_wait for that.
 */
APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *new_proc,
                                          const char *progname,
                                          const char * const *args,
                                          const char * const *env, 
                                          apr_procattr_t *attr, 
                                          apr_pool_t *pool);

/**
 * Wait for a child process to die
 * @param proc The process handle that corresponds to the desired child process 
 * @param exitcode The returned exit status of the child, if a child process 
 *                 dies, or the signal that caused the child to die.
 *                 On platforms that don't support obtaining this information, 
 *                 the status parameter will be returned as APR_ENOTIMPL.
 * @param exitwhy Why the child died, the bitwise or of:
 * <PRE>
 *            APR_PROC_EXIT         -- process terminated normally
 *            APR_PROC_SIGNAL       -- process was killed by a signal
 *            APR_PROC_SIGNAL_CORE  -- process was killed by a signal, and
 *                                     generated a core dump.
 * </PRE>
 * @param waithow How should we wait.  One of:
 * <PRE>
 *            APR_WAIT   -- block until the child process dies.
 *            APR_NOWAIT -- return immediately regardless of if the 
 *                          child is dead or not.
 * </PRE>
 * @remark The child's status is in the return code to this process.  It is one of:
 * <PRE>
 *            APR_CHILD_DONE     -- child is no longer running.
 *            APR_CHILD_NOTDONE  -- child is still running.
 * </PRE>
 */
APR_DECLARE(apr_status_t) apr_proc_wait(apr_proc_t *proc,
                                        int *exitcode, apr_exit_why_e *exitwhy,
                                        apr_wait_how_e waithow);

/**
 * Wait for any current child process to die and return information 
 * about that child.
 * @param proc Pointer to NULL on entry, will be filled out with child's 
 *             information 
 * @param exitcode The returned exit status of the child, if a child process 
 *                 dies, or the signal that caused the child to die.
 *                 On platforms that don't support obtaining this information, 
 *                 the status parameter will be returned as APR_ENOTIMPL.
 * @param exitwhy Why the child died, the bitwise or of:
 * <PRE>
 *            APR_PROC_EXIT         -- process terminated normally
 *            APR_PROC_SIGNAL       -- process was killed by a signal
 *            APR_PROC_SIGNAL_CORE  -- process was killed by a signal, and
 *                                     generated a core dump.
 * </PRE>
 * @param waithow How should we wait.  One of:
 * <PRE>
 *            APR_WAIT   -- block until the child process dies.
 *            APR_NOWAIT -- return immediately regardless of if the 
 *                          child is dead or not.
 * </PRE>
 * @param p Pool to allocate child information out of.
 * @bug Passing proc as a *proc rather than **proc was an odd choice
 * for some platforms... this should be revisited in 1.0
 */
APR_DECLARE(apr_status_t) apr_proc_wait_all_procs(apr_proc_t *proc,
                                                  int *exitcode,
                                                  apr_exit_why_e *exitwhy,
                                                  apr_wait_how_e waithow,
                                                  apr_pool_t *p);

#define APR_PROC_DETACH_FOREGROUND 0    /**< Do not detach */
#define APR_PROC_DETACH_DAEMONIZE 1     /**< Detach */

/**
 * Detach the process from the controlling terminal.
 * @param daemonize set to non-zero if the process should daemonize
 *                  and become a background process, else it will
 *                  stay in the foreground.
 */
APR_DECLARE(apr_status_t) apr_proc_detach(int daemonize);

/**
 * Register an other_child -- a child associated to its registered 
 * maintence callback.  This callback is invoked when the process
 * dies, is disconnected or disappears.
 * @param proc The child process to register.
 * @param maintenance maintenance is a function that is invoked with a 
 *                    reason and the data pointer passed here.
 * @param data Opaque context data passed to the maintenance function.
 * @param write_fd An fd that is probed for writing.  If it is ever unwritable
 *                 then the maintenance is invoked with reason 
 *                 OC_REASON_UNWRITABLE.
 * @param p The pool to use for allocating memory.
 * @bug write_fd duplicates the proc->out stream, it's really redundant
 * and should be replaced in the APR 1.0 API with a bitflag of which
 * proc->in/out/err handles should be health checked.
 * @bug no platform currently tests the pipes health.
 */
APR_DECLARE(void) apr_proc_other_child_register(apr_proc_t *proc, 
                                           void (*maintenance) (int reason, 
                                                                void *, 
                                                                int status),
                                           void *data, apr_file_t *write_fd,
                                           apr_pool_t *p);

/**
 * Stop watching the specified other child.  
 * @param data The data to pass to the maintenance function.  This is
 *             used to find the process to unregister.
 * @warning Since this can be called by a maintenance function while we're
 *          scanning the other_children list, all scanners should protect 
 *          themself by loading ocr->next before calling any maintenance 
 *          function.
 */
APR_DECLARE(void) apr_proc_other_child_unregister(void *data);

/**
 * Notify the maintenance callback of a registered other child process
 * that application has detected an event, such as death.
 * @param proc The process to check
 * @param reason The reason code to pass to the maintenance function
 * @param status The status to pass to the maintenance function
 * @remark An example of code using this behavior;
 * <pre>
 * rv = apr_proc_wait_all_procs(&proc, &exitcode, &status, APR_WAIT, p);
 * if (APR_STATUS_IS_CHILD_DONE(rv)) {
 * \#if APR_HAS_OTHER_CHILD
 *     if (apr_proc_other_child_alert(&proc, APR_OC_REASON_DEATH, status)
 *             == APR_SUCCESS) {
 *         ;  (already handled)
 *     }
 *     else
 * \#endif
 *         [... handling non-otherchild processes death ...]
 * </pre>
 */
APR_DECLARE(apr_status_t) apr_proc_other_child_alert(apr_proc_t *proc, 
                                                     int reason,
                                                     int status);

/**
 * Test one specific other child processes and invoke the maintenance callback 
 * with the appropriate reason code, if still running, or the appropriate reason 
 * code if the process is no longer healthy.
 * @param ocr The registered other child
 * @param reason The reason code (e.g. APR_OC_REASON_RESTART) if still running
 */
APR_DECLARE(void) apr_proc_other_child_refresh(apr_other_child_rec_t *ocr,
                                               int reason);

/**
 * Test all registered other child processes and invoke the maintenance callback 
 * with the appropriate reason code, if still running, or the appropriate reason 
 * code if the process is no longer healthy.
 * @param reason The reason code (e.g. APR_OC_REASON_RESTART) to running processes
 */
APR_DECLARE(void) apr_proc_other_child_refresh_all(int reason);

/** 
 * Terminate a process.
 * @param proc The process to terminate.
 * @param sig How to kill the process.
 */
APR_DECLARE(apr_status_t) apr_proc_kill(apr_proc_t *proc, int sig);

/**
 * Register a process to be killed when a pool dies.
 * @param a The pool to use to define the processes lifetime 
 * @param proc The process to register
 * @param how How to kill the process, one of:
 * <PRE>
 *         APR_KILL_NEVER         -- process is never sent any signals
 *         APR_KILL_ALWAYS        -- process is sent SIGKILL on apr_pool_t cleanup
 *         APR_KILL_AFTER_TIMEOUT -- SIGTERM, wait 3 seconds, SIGKILL
 *         APR_JUST_WAIT          -- wait forever for the process to complete
 *         APR_KILL_ONLY_ONCE     -- send SIGTERM and then wait
 * </PRE>
 */
APR_DECLARE(void) apr_pool_note_subprocess(apr_pool_t *a, apr_proc_t *proc,
                                           apr_kill_conditions_e how);

#if APR_HAS_THREADS 

#if (APR_HAVE_SIGWAIT || APR_HAVE_SIGSUSPEND) && !defined(OS2)

/**
 * Setup the process for a single thread to be used for all signal handling.
 * @warning This must be called before any threads are created
 */
APR_DECLARE(apr_status_t) apr_setup_signal_thread(void);

/**
 * Make the current thread listen for signals.  This thread will loop
 * forever, calling a provided function whenever it receives a signal.  That
 * functions should return 1 if the signal has been handled, 0 otherwise.
 * @param signal_handler The function to call when a signal is received
 * apr_status_t apr_signal_thread((int)(*signal_handler)(int signum))
 * @note Synchronous signals like SIGABRT/SIGSEGV/SIGBUS/... are ignored by
 * apr_signal_thread() and thus can't be waited by this function (they remain
 * handled by the operating system or its native signals interface).
 * @remark In APR version 1.6 and ealier, SIGUSR2 was part of these ignored
 * signals and thus was never passed in to the signal_handler. From APR 1.7
 * this is no more the case so SIGUSR2 can be handled in signal_handler and
 * acted upon like the other asynchronous signals.
 */
APR_DECLARE(apr_status_t) apr_signal_thread(int(*signal_handler)(int signum));

#endif /* (APR_HAVE_SIGWAIT || APR_HAVE_SIGSUSPEND) && !defined(OS2) */

/**
 * Get the child-pool used by the thread from the thread info.
 * @return apr_pool_t the pool
 */
APR_POOL_DECLARE_ACCESSOR(thread);

#endif /* APR_HAS_THREADS */

/** @} */

#ifdef __cplusplus
}
#endif

#endif  /* ! APR_THREAD_PROC_H */

apr-1/apr_ldap_init.h000064400000013224151730340530010445 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @file apr_ldap_init.h
 * @brief  APR-UTIL LDAP ldap_init() functions
 */
#ifndef APR_LDAP_INIT_H
#define APR_LDAP_INIT_H

/**
 * @addtogroup APR_Util_LDAP
 * @{
 */

#include "apr_ldap.h"

#if APR_HAS_LDAP

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */


/**
 * Macro to detect security related return values.
 */
#if defined(LDAP_INSUFFICIENT_ACCESS)
#define APU_LDAP_INSUFFICIENT_ACCESS LDAP_INSUFFICIENT_ACCESS
#elif defined(LDAP_INSUFFICIENT_RIGHTS)
#define APU_LDAP_INSUFFICIENT_ACCESS LDAP_INSUFFICIENT_RIGHTS
#elif defined(APR_HAS_MICROSOFT_LDAPSDK)
/* The macros above fail to contemplate that LDAP_RETCODE values
 * may be represented by an enum.  autoconf tests would be much
 * more robust.
 */
#define APU_LDAP_INSUFFICIENT_ACCESS LDAP_INSUFFICIENT_RIGHTS
#else
#error The security return codes must be added to support this LDAP toolkit.
#endif

#if defined(LDAP_SECURITY_ERROR)
#define APU_LDAP_SECURITY_ERROR LDAP_SECURITY_ERROR
#else
#define APU_LDAP_SECURITY_ERROR(n)	\
    (LDAP_INAPPROPRIATE_AUTH == n) ? 1 \
    : (LDAP_INVALID_CREDENTIALS == n) ? 1 \
    : (APU_LDAP_INSUFFICIENT_ACCESS == n) ? 1 \
    : 0
#endif


/**
 * APR LDAP SSL Initialise function
 *
 * This function initialises SSL on the underlying LDAP toolkit
 * if this is necessary.
 *
 * If a CA certificate is provided, this is set, however the setting
 * of certificates via this method has been deprecated and will be removed in
 * APR v2.0.
 *
 * The apr_ldap_set_option() function with the APR_LDAP_OPT_TLS_CERT option
 * should be used instead to set certificates.
 *
 * If SSL support is not available on this platform, or a problem
 * was encountered while trying to set the certificate, the function
 * will return APR_EGENERAL. Further LDAP specific error information
 * can be found in result_err.
 * @param pool The pool to use
 * @param cert_auth_file The name of the certificate to use, can be NULL
 * @param cert_file_type The type of certificate specified. See the
 * apr_ldap_set_option() APR_LDAP_OPT_TLS_CERT option for details.
 * @param result_err The returned result
 */
APU_DECLARE_LDAP(int) apr_ldap_ssl_init(apr_pool_t *pool,
                                        const char *cert_auth_file,
                                        int cert_file_type,
                                        apr_ldap_err_t **result_err);

/**
 * APR LDAP SSL De-Initialise function
 *
 * This function tears down any SSL certificate setup previously
 * set using apr_ldap_ssl_init(). It should be called to clean
 * up if a graceful restart of a service is attempted.
 * @todo currently we do not check whether apr_ldap_ssl_init()
 * has been called first - we probably should.
 */
APU_DECLARE_LDAP(int) apr_ldap_ssl_deinit(void);

/**
 * APR LDAP initialise function
 *
 * This function is responsible for initialising an LDAP
 * connection in a toolkit independant way. It does the
 * job of ldap_init() from the C api.
 *
 * It handles both the SSL and non-SSL case, and attempts
 * to hide the complexity setup from the user. This function
 * assumes that any certificate setup necessary has already
 * been done.
 *
 * If SSL or STARTTLS needs to be enabled, and the underlying
 * toolkit supports it, the following values are accepted for
 * secure:
 *
 * APR_LDAP_NONE: No encryption
 * APR_LDAP_SSL: SSL encryption (ldaps://)
 * APR_LDAP_STARTTLS: Force STARTTLS on ldap://
 * @remark The Novell toolkit is only able to set the SSL mode via this
 * function. To work around this limitation, set the SSL mode here if no
 * per connection client certificates are present, otherwise set secure
 * APR_LDAP_NONE here, then set the per connection client certificates,
 * followed by setting the SSL mode via apr_ldap_set_option(). As Novell
 * does not support per connection client certificates, this problem is
 * worked around while still being compatible with other LDAP toolkits.
 * @param pool The pool to use
 * @param ldap The LDAP handle
 * @param hostname The name of the host to connect to. This can be either a
 * DNS name, or an IP address.
 * @param portno The port to connect to
 * @param secure The security mode to set
 * @param result_err The returned result
 */
APU_DECLARE_LDAP(int) apr_ldap_init(apr_pool_t *pool,
                                    LDAP **ldap,
                                    const char *hostname,
                                    int portno,
                                    int secure,
                                    apr_ldap_err_t **result_err);

/**
 * APR LDAP info function
 *
 * This function returns a string describing the LDAP toolkit
 * currently in use. The string is placed inside result_err->reason.
 * @param pool The pool to use
 * @param result_err The returned result
 */
APU_DECLARE_LDAP(int) apr_ldap_info(apr_pool_t *pool,
                                    apr_ldap_err_t **result_err);

#ifdef __cplusplus
}
#endif

#endif /* APR_HAS_LDAP */

/** @} */

#endif /* APR_LDAP_URL_H */
apr-1/apr_xlate.h000064400000014410151730340530007615 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_XLATE_H
#define APR_XLATE_H

#include "apu.h"
#include "apr_pools.h"
#include "apr_errno.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @file apr_xlate.h
 * @brief APR I18N translation library
 */

/**
 * @defgroup APR_XLATE I18N translation library
 * @ingroup APR
 * @{
 */
/** Opaque translation buffer */
typedef struct apr_xlate_t            apr_xlate_t;

/**
 * Set up for converting text from one charset to another.
 * @param convset The handle to be filled in by this function
 * @param topage The name of the target charset
 * @param frompage The name of the source charset
 * @param pool The pool to use
 * @remark
 *  Specify APR_DEFAULT_CHARSET for one of the charset
 *  names to indicate the charset of the source code at
 *  compile time.  This is useful if there are literal
 *  strings in the source code which must be translated
 *  according to the charset of the source code.
 *  APR_DEFAULT_CHARSET is not useful if the source code
 *  of the caller was not encoded in the same charset as
 *  APR at compile time.
 *
 * @remark
 *  Specify APR_LOCALE_CHARSET for one of the charset
 *  names to indicate the charset of the current locale.
 *
 * @remark
 *  Return APR_EINVAL if unable to procure a convset, or APR_ENOTIMPL
 *  if charset transcoding is not available in this instance of
 *  apr-util at all (i.e., APR_HAS_XLATE is undefined).
 */
APU_DECLARE(apr_status_t) apr_xlate_open(apr_xlate_t **convset, 
                                         const char *topage, 
                                         const char *frompage, 
                                         apr_pool_t *pool);

/** 
 * This is to indicate the charset of the sourcecode at compile time
 * names to indicate the charset of the source code at
 * compile time.  This is useful if there are literal
 * strings in the source code which must be translated
 * according to the charset of the source code.
 */
#define APR_DEFAULT_CHARSET (const char *)0
/**
 * To indicate charset names of the current locale 
 */
#define APR_LOCALE_CHARSET (const char *)1

/**
 * Find out whether or not the specified conversion is single-byte-only.
 * @param convset The handle allocated by apr_xlate_open, specifying the 
 *                parameters of conversion
 * @param onoff Output: whether or not the conversion is single-byte-only
 * @remark
 *  Return APR_ENOTIMPL if charset transcoding is not available
 *  in this instance of apr-util (i.e., APR_HAS_XLATE is undefined).
 */
APU_DECLARE(apr_status_t) apr_xlate_sb_get(apr_xlate_t *convset, int *onoff);

/**
 * Convert a buffer of text from one codepage to another.
 * @param convset The handle allocated by apr_xlate_open, specifying 
 *                the parameters of conversion
 * @param inbuf The address of the source buffer
 * @param inbytes_left Input: the amount of input data to be translated
 *                     Output: the amount of input data not yet translated    
 * @param outbuf The address of the destination buffer
 * @param outbytes_left Input: the size of the output buffer
 *                      Output: the amount of the output buffer not yet used
 * @remark
 * Returns APR_ENOTIMPL if charset transcoding is not available
 * in this instance of apr-util (i.e., APR_HAS_XLATE is undefined).
 * Returns APR_INCOMPLETE if the input buffer ends in an incomplete
 * multi-byte character.
 *
 * To correctly terminate the output buffer for some multi-byte
 * character set encodings, a final call must be made to this function
 * after the complete input string has been converted, passing
 * the inbuf and inbytes_left parameters as NULL.  (Note that this
 * mode only works from version 1.1.0 onwards)
 */
APU_DECLARE(apr_status_t) apr_xlate_conv_buffer(apr_xlate_t *convset, 
                                                const char *inbuf, 
                                                apr_size_t *inbytes_left, 
                                                char *outbuf,
                                                apr_size_t *outbytes_left);

/* @see apr_file_io.h the comment in apr_file_io.h about this hack */
#ifdef APR_NOT_DONE_YET
/**
 * The purpose of apr_xlate_conv_char is to translate one character
 * at a time.  This needs to be written carefully so that it works
 * with double-byte character sets. 
 * @param convset The handle allocated by apr_xlate_open, specifying the
 *                parameters of conversion
 * @param inchar The character to convert
 * @param outchar The converted character
 */
APU_DECLARE(apr_status_t) apr_xlate_conv_char(apr_xlate_t *convset, 
                                              char inchar, char outchar);
#endif

/**
 * Convert a single-byte character from one charset to another.
 * @param convset The handle allocated by apr_xlate_open, specifying the 
 *                parameters of conversion
 * @param inchar The single-byte character to convert.
 * @warning This only works when converting between single-byte character sets.
 *          -1 will be returned if the conversion can't be performed.
 */
APU_DECLARE(apr_int32_t) apr_xlate_conv_byte(apr_xlate_t *convset, 
                                             unsigned char inchar);

/**
 * Close a codepage translation handle.
 * @param convset The codepage translation handle to close
 * @remark
 *  Return APR_ENOTIMPL if charset transcoding is not available
 *  in this instance of apr-util (i.e., APR_HAS_XLATE is undefined).
 */
APU_DECLARE(apr_status_t) apr_xlate_close(apr_xlate_t *convset);

/** @} */
#ifdef __cplusplus
}
#endif

#endif  /* ! APR_XLATE_H */
apr-1/apr_ldap_url.h000064400000007327151730340530010313 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @file apr_ldap_url.h
 * @brief  APR-UTIL LDAP ldap_init() functions
 */
#ifndef APR_LDAP_URL_H
#define APR_LDAP_URL_H

/**
 * @addtogroup APR_Util_LDAP
 * @{
 */

#if defined(DOXYGEN)
#include "apr_ldap.h"
#endif

#if APR_HAS_LDAP

#include "apu.h"
#include "apr_pools.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/** Structure to access an exploded LDAP URL */
typedef struct apr_ldap_url_desc_t {
    struct  apr_ldap_url_desc_t  *lud_next;
    char    *lud_scheme;
    char    *lud_host;
    int     lud_port;
    char    *lud_dn;
    char    **lud_attrs;
    int     lud_scope;
    char    *lud_filter;
    char    **lud_exts;
    int     lud_crit_exts;
} apr_ldap_url_desc_t;

#ifndef APR_LDAP_URL_SUCCESS
#define APR_LDAP_URL_SUCCESS          0x00    /* Success */
#define APR_LDAP_URL_ERR_MEM          0x01    /* can't allocate memory space */
#define APR_LDAP_URL_ERR_PARAM        0x02    /* parameter is bad */
#define APR_LDAP_URL_ERR_BADSCHEME    0x03    /* URL doesn't begin with "ldap[si]://" */
#define APR_LDAP_URL_ERR_BADENCLOSURE 0x04    /* URL is missing trailing ">" */
#define APR_LDAP_URL_ERR_BADURL       0x05    /* URL is bad */
#define APR_LDAP_URL_ERR_BADHOST      0x06    /* host port is bad */
#define APR_LDAP_URL_ERR_BADATTRS     0x07    /* bad (or missing) attributes */
#define APR_LDAP_URL_ERR_BADSCOPE     0x08    /* scope string is invalid (or missing) */
#define APR_LDAP_URL_ERR_BADFILTER    0x09    /* bad or missing filter */
#define APR_LDAP_URL_ERR_BADEXTS      0x0a    /* bad or missing extensions */
#endif

/**
 * Is this URL an ldap url? ldap://
 * @param url The url to test
 */
APU_DECLARE(int) apr_ldap_is_ldap_url(const char *url);

/**
 * Is this URL an SSL ldap url? ldaps://
 * @param url The url to test
 */
APU_DECLARE(int) apr_ldap_is_ldaps_url(const char *url);

/**
 * Is this URL an ldap socket url? ldapi://
 * @param url The url to test
 */
APU_DECLARE(int) apr_ldap_is_ldapi_url(const char *url);

/**
 * Parse an LDAP URL.
 * @param pool The pool to use
 * @param url_in The URL to parse
 * @param ludpp The structure to return the exploded URL
 * @param result_err The result structure of the operation
 */
APU_DECLARE(int) apr_ldap_url_parse_ext(apr_pool_t *pool,
                                        const char *url_in,
                                        apr_ldap_url_desc_t **ludpp,
                                        apr_ldap_err_t **result_err);

/**
 * Parse an LDAP URL.
 * @param pool The pool to use
 * @param url_in The URL to parse
 * @param ludpp The structure to return the exploded URL
 * @param result_err The result structure of the operation
 */
APU_DECLARE(int) apr_ldap_url_parse(apr_pool_t *pool,
                                    const char *url_in,
                                    apr_ldap_url_desc_t **ludpp,
                                    apr_ldap_err_t **result_err);

#ifdef __cplusplus
}
#endif

#endif /* APR_HAS_LDAP */

/** @} */

#endif /* APR_LDAP_URL_H */
apr-1/apr_siphash.h000064400000014016151730340530010141 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
   SipHash reference C implementation
   Copyright (c) 2012-2014 Jean-Philippe Aumasson
   <jeanphilippe.aumasson@gmail.com>
   Copyright (c) 2012-2014 Daniel J. Bernstein <djb@cr.yp.to>
   To the extent possible under law, the author(s) have dedicated all copyright
   and related and neighboring rights to this software to the public domain
   worldwide. This software is distributed without any warranty.
   You should have received a copy of the CC0 Public Domain Dedication along
   with this software. If not, see
   <http://creativecommons.org/publicdomain/zero/1.0/>.
 */

#ifndef APR_SIPHASH_H
#define APR_SIPHASH_H

#include "apr.h"
#include "apu.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @file apr_siphash.h
 * @brief APR-UTIL siphash library
 *        "SipHash-c-d is a family of pseudorandom functions (a.k.a. keyed
 *        hash functions) optimized for speed on short messages", designed by
 *        Jean-Philippe Aumasson and Daniel J. Bernstein. It generates a 64bit
 *        hash (or MAC) from the message and a 128bit key.
 *        See http://cr.yp.to/siphash/siphash-20120620.pdf for the details,
 *        c is the number of compression rounds, d the number of finalization
 *        rounds; we also define fast implementations for c = 2 with d = 4 (aka
 *        siphash-2-4), and c = 4 with d = 8 (aka siphash-4-8), as recommended
 *        parameters per the authors.
 */

/** size of the siphash digest */
#define APR_SIPHASH_DSIZE 8

/** size of the siphash key */
#define APR_SIPHASH_KSIZE 16


/**
 * @brief Computes SipHash-c-d, producing a 64bit (APR_SIPHASH_DSIZE) hash
 * from a message and a 128bit (APR_SIPHASH_KSIZE) secret key.
 * @param src The message
 * @param len The length of the message
 * @param key The secret key
 * @param c   The number of compression rounds
 * @param d   The number of finalization rounds
 * @return The hash value as a 64bit unsigned integer
 */
APU_DECLARE(apr_uint64_t) apr_siphash(const void *src, apr_size_t len,
                              const unsigned char key[APR_SIPHASH_KSIZE],
                                      unsigned int c, unsigned int d);

/**
 * @brief Computes SipHash-c-d, producing a 64bit (APR_SIPHASH_DSIZE) hash
 * from a message and a 128bit (APR_SIPHASH_KSIZE) secret key, into a possibly
 * unaligned buffer (using the little endian representation as defined by the
 * authors for interoperabilty) usable as a MAC.
 * @param out The output buffer (or MAC)
 * @param src The message
 * @param len The length of the message
 * @param key The secret key
 * @param c   The number of compression rounds
 * @param d   The number of finalization rounds
 * @return The hash value as a 64bit unsigned integer
 */
APU_DECLARE(void) apr_siphash_auth(unsigned char out[APR_SIPHASH_DSIZE],
                                   const void *src, apr_size_t len,
                             const unsigned char key[APR_SIPHASH_KSIZE],
                                   unsigned int c, unsigned int d);

/**
 * @brief Computes SipHash-2-4, producing a 64bit (APR_SIPHASH_DSIZE) hash
 * from a message and a 128bit (APR_SIPHASH_KSIZE) secret key.
 * @param src The message to hash
 * @param len The length of the message
 * @param key The secret key
 * @return The hash value as a 64bit unsigned integer
 */
APU_DECLARE(apr_uint64_t) apr_siphash24(const void *src, apr_size_t len,
                               const unsigned char key[APR_SIPHASH_KSIZE]);

/**
 * @brief Computes SipHash-2-4, producing a 64bit (APR_SIPHASH_DSIZE) hash
 * from a message and a 128bit (APR_SIPHASH_KSIZE) secret key, into a possibly
 * unaligned buffer (using the little endian representation as defined by the
 * authors for interoperabilty) usable as a MAC.
 * @param out The output buffer (or MAC)
 * @param src The message
 * @param len The length of the message
 * @param key The secret key
 * @return The hash value as a 64bit unsigned integer
 */
APU_DECLARE(void) apr_siphash24_auth(unsigned char out[APR_SIPHASH_DSIZE],
                                     const void *src, apr_size_t len,
                               const unsigned char key[APR_SIPHASH_KSIZE]);

/**
 * @brief Computes SipHash-4-8, producing a 64bit (APR_SIPHASH_DSIZE) hash
 * from a message and a 128bit (APR_SIPHASH_KSIZE) secret key.
 * @param src The message
 * @param len The length of the message
 * @param key The secret key
 * @return The hash value as a 64bit unsigned integer
 */
APU_DECLARE(apr_uint64_t) apr_siphash48(const void *src, apr_size_t len,
                               const unsigned char key[APR_SIPHASH_KSIZE]);

/**
 * @brief Computes SipHash-4-8, producing a 64bit (APR_SIPHASH_DSIZE) hash
 * from a message and a 128bit (APR_SIPHASH_KSIZE) secret key, into a possibly
 * unaligned buffer (using the little endian representation as defined by the
 * authors for interoperabilty) usable as a MAC.
 * @param out The output buffer (or MAC)
 * @param src The message
 * @param len The length of the message
 * @param key The secret key
 * @return The hash value as a 64bit unsigned integer
 */
APU_DECLARE(void) apr_siphash48_auth(unsigned char out[APR_SIPHASH_DSIZE],
                                     const void *src, apr_size_t len,
                               const unsigned char key[APR_SIPHASH_KSIZE]);

#ifdef __cplusplus
}
#endif

#endif  /* APR_SIPHASH_H */
apr-1/apr-x86_64.h000064400000043643151730340530007366 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


#ifndef APR_H
#define APR_H

/* GENERATED FILE WARNING!  DO NOT EDIT apr.h
 *
 * You must modify apr.h.in instead.
 *
 * And please, make an effort to stub apr.hw and apr.hnw in the process.
 */

/**
 * @file apr.h
 * @brief APR Platform Definitions
 * @remark This is a generated header generated from include/apr.h.in by
 * ./configure, or copied from include/apr.hw or include/apr.hnw 
 * for Win32 or Netware by those build environments, respectively.
 */

/**
 * @defgroup APR Apache Portability Runtime library
 * @{
 */
/**
 * @defgroup apr_platform Platform Definitions
 * @{
 * @warning
 * <strong><em>The actual values of macros and typedefs on this page<br>
 * are platform specific and should NOT be relied upon!</em></strong>
 */

/* So that we can use inline on some critical functions, and use
 * GNUC attributes (such as to get -Wall warnings for printf-like
 * functions).  Both __inline__ and __attribute__ exist for gcc >= 2.7,
 * other !__GNUC__ compilers may provide __attribute__ still.
 *
 * We've since discovered that the gcc shipped with NeXT systems
 * as "cc" is completely broken.  It claims to be __GNUC__ and so
 * on, but it doesn't implement half of the things that __GNUC__
 * means.  In particular it's missing inline and the __attribute__
 * stuff.  So we hack around it.  PR#1613. -djg
 */
#if defined(__GNUC__) \
    && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)) \
    && !defined(NEXT)
#define APR_INLINE  __inline__
#define APR_HAS_INLINE          1
#else  /* !__GNUC__ */
#define APR_INLINE
#define APR_HAS_INLINE          0
/* __has_attribute should always be a pre-defined macro, but not
 * necessarily __attribute__ (e.g. builtin), so check for both to
 * avoid overriding __attribute__.
 */
#if !(defined(__attribute__) || defined(__has_attribute)) || defined(__SUNPRO_C)
#define __attribute__(__x)
#endif
#endif /* !__GNUC__ */

#define APR_HAVE_ARPA_INET_H     1
#define APR_HAVE_CONIO_H         0
#define APR_HAVE_CRYPT_H         1
#define APR_HAVE_CTYPE_H         1
#define APR_HAVE_DIRENT_H        1
#define APR_HAVE_ERRNO_H         1
#define APR_HAVE_FCNTL_H         1
#define APR_HAVE_IO_H            0
#define APR_HAVE_LIMITS_H        1
#define APR_HAVE_NETDB_H         1
#define APR_HAVE_NETINET_IN_H    1
#define APR_HAVE_NETINET_SCTP_H  1
#define APR_HAVE_NETINET_SCTP_UIO_H 0
#define APR_HAVE_NETINET_TCP_H   1
#define APR_HAVE_PROCESS_H       0
#define APR_HAVE_PTHREAD_H       1
#define APR_HAVE_SEMAPHORE_H     1
#define APR_HAVE_SIGNAL_H        1
#define APR_HAVE_STDARG_H        1
#define APR_HAVE_STDDEF_H        1
#define APR_HAVE_STDINT_H        1
#define APR_HAVE_STDIO_H         1
#define APR_HAVE_STDLIB_H        1
#define APR_HAVE_STRING_H        1
#define APR_HAVE_STRINGS_H       1
#define APR_HAVE_INTTYPES_H      1
#define APR_HAVE_SYS_IOCTL_H     1
#define APR_HAVE_SYS_SENDFILE_H  1
#define APR_HAVE_SYS_SIGNAL_H    1
#define APR_HAVE_SYS_SOCKET_H    1
#define APR_HAVE_SYS_SOCKIO_H    0
#define APR_HAVE_SYS_SYSLIMITS_H 0
#define APR_HAVE_SYS_TIME_H      1
#define APR_HAVE_SYS_TYPES_H     1
#define APR_HAVE_SYS_UIO_H       1
#define APR_HAVE_SYS_UN_H        1
#define APR_HAVE_SYS_WAIT_H      1
#define APR_HAVE_TIME_H          1
#define APR_HAVE_UNISTD_H        1
#define APR_HAVE_WINDOWS_H       0
#define APR_HAVE_WINSOCK2_H      0

/** @} */
/** @} */

/* We don't include our conditional headers within the doxyblocks 
 * or the extern "C" namespace 
 */

#if APR_HAVE_WINDOWS_H && defined(WIN32)
/* If windows.h was already included, our preferences don't matter.
 * If not, include a restricted set of windows headers to our tastes.
 */
#ifndef _WINDOWS_

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#ifndef _WIN32_WINNT
/* Restrict the server to a subset of Windows XP header files by default
 */
#define _WIN32_WINNT 0x0501
#endif

#ifndef NOUSER
#define NOUSER
#endif
#ifndef NOMCX
#define NOMCX
#endif
#ifndef NOIME
#define NOIME
#endif

#include <windows.h>
/* 
 * Add a _very_few_ declarations missing from the restricted set of headers
 * (If this list becomes extensive, re-enable the required headers above!)
 * winsock headers were excluded by WIN32_LEAN_AND_MEAN, so include them now
 */
#define SW_HIDE             0
#ifndef _WIN32_WCE
#include <winsock2.h>
#include <ws2tcpip.h>
#include <mswsock.h>
#else
#include <winsock.h>
#endif

#endif /* ndef _WINDOWS_ */
#endif /* APR_HAVE_WINDOWS_H */

#if APR_HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif

#if APR_HAVE_STDDEF_H
#include <stddef.h>
#endif

#if APR_HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif

#if APR_HAVE_STDINT_H
#ifdef __cplusplus
/* C99 7.18.4 requires that stdint.h only exposes INT64_C 
 * and UINT64_C for C++ implementations if this is defined: */
#ifndef __STDC_CONSTANT_MACROS
#define __STDC_CONSTANT_MACROS
#endif
/* C++ needs this too for PRI*NN formats: */
#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif
#endif /* __cplusplus */
#include <stdint.h>
#endif

#if APR_HAVE_INTTYPES_H
#include <inttypes.h>
#endif

#if APR_HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif

#ifdef OS2
#define INCL_DOS
#define INCL_DOSERRORS
#include <os2.h>
#endif

/* header files for PATH_MAX, _POSIX_PATH_MAX */
#if APR_HAVE_LIMITS_H
#include <limits.h>
#else
#if APR_HAVE_SYS_SYSLIMITS_H
#include <sys/syslimits.h>
#endif
#endif

/* __APPLE__ is now the official pre-defined macro for macOS */
#ifdef __APPLE__
#undef DARWIN
#undef DARWIN_10
#define DARWIN
#define DARWIN_10
#endif /* __APPLE__ */

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @addtogroup apr_platform
 * @ingroup APR 
 * @{
 */

#define APR_HAVE_SHMEM_MMAP_TMP     1
#define APR_HAVE_SHMEM_MMAP_SHM     0
#define APR_HAVE_SHMEM_MMAP_ZERO    1
#define APR_HAVE_SHMEM_SHMGET_ANON  1
#define APR_HAVE_SHMEM_SHMGET       1
#define APR_HAVE_SHMEM_MMAP_ANON    1
#define APR_HAVE_SHMEM_BEOS         0

#define APR_USE_SHMEM_MMAP_TMP     1
#define APR_USE_SHMEM_MMAP_SHM     0
#define APR_USE_SHMEM_MMAP_ZERO    0
#define APR_USE_SHMEM_SHMGET_ANON  0
#define APR_USE_SHMEM_SHMGET       0
#define APR_USE_SHMEM_MMAP_ANON    1
#define APR_USE_SHMEM_BEOS         0

#define APR_USE_FLOCK_SERIALIZE           0 
#define APR_USE_SYSVSEM_SERIALIZE         1
#define APR_USE_POSIXSEM_SERIALIZE        0
#define APR_USE_FCNTL_SERIALIZE           0
#define APR_USE_PROC_PTHREAD_SERIALIZE    0 
#define APR_USE_PTHREAD_SERIALIZE         1 

#define APR_HAS_FLOCK_SERIALIZE           1
#define APR_HAS_SYSVSEM_SERIALIZE         1
#define APR_HAS_POSIXSEM_SERIALIZE        1
#define APR_HAS_FCNTL_SERIALIZE           1
#define APR_HAS_PROC_PTHREAD_SERIALIZE    1

#define APR_PROCESS_LOCK_IS_GLOBAL        0

#define APR_HAVE_CORKABLE_TCP   1 
#define APR_HAVE_GETRLIMIT      1
#define APR_HAVE_IN_ADDR        1
#define APR_HAVE_INET_ADDR      1
#define APR_HAVE_INET_NETWORK   1
#define APR_HAVE_IPV6           1
#define APR_HAVE_SOCKADDR_UN    1
#define APR_HAVE_MEMMOVE        1
#define APR_HAVE_SETRLIMIT      1
#define APR_HAVE_SIGACTION      1
#define APR_HAVE_SIGSUSPEND     1
#define APR_HAVE_SIGWAIT        1
#define APR_HAVE_SA_STORAGE     1
#define APR_HAVE_STRCASECMP     1
#define APR_HAVE_STRDUP         1
#define APR_HAVE_STRICMP        0
#define APR_HAVE_STRNCASECMP    1
#define APR_HAVE_STRNICMP       0
#define APR_HAVE_STRSTR         1
#define APR_HAVE_MEMCHR         1
#define APR_HAVE_STRUCT_RLIMIT  1
#define APR_HAVE_UNION_SEMUN    0
#define APR_HAVE_SCTP           0
#define APR_HAVE_IOVEC          1

/*  APR Feature Macros */
#define APR_HAS_SHARED_MEMORY     1
#define APR_HAS_THREADS           1
#define APR_HAS_SENDFILE          1
#define APR_HAS_MMAP              1
#define APR_HAS_FORK              1
#define APR_HAS_RANDOM            1
#define APR_HAS_OTHER_CHILD       1
#define APR_HAS_DSO               1
#define APR_HAS_SO_ACCEPTFILTER   0
#define APR_HAS_UNICODE_FS        0
#define APR_HAS_PROC_INVOKED      0
#define APR_HAS_USER              1
#define APR_HAS_LARGE_FILES       0
#define APR_HAS_XTHREAD_FILES     0
#define APR_HAS_OS_UUID           1
#define APR_HAS_TIMEDLOCKS        1

#define APR_PROCATTR_USER_SET_REQUIRES_PASSWORD 0

/* APR sets APR_FILES_AS_SOCKETS to 1 on systems where it is possible
 * to poll on files/pipes.
 */
#define APR_FILES_AS_SOCKETS      1

/* This macro indicates whether or not EBCDIC is the native character set.
 */
#define APR_CHARSET_EBCDIC        0

/* If we have a TCP implementation that can be "corked", what flag
 * do we use?
 */
#define APR_TCP_NOPUSH_FLAG       TCP_CORK

/* Is the TCP_NODELAY socket option inherited from listening sockets?
*/
#define APR_TCP_NODELAY_INHERITED 1

/* Is the O_NONBLOCK flag inherited from listening sockets?
*/
#define APR_O_NONBLOCK_INHERITED 0

/* Typedefs that APR needs. */

typedef  unsigned char           apr_byte_t;

typedef  short           apr_int16_t;
typedef  unsigned short  apr_uint16_t;

typedef  int             apr_int32_t;
typedef  unsigned int    apr_uint32_t;

#define APR_SIZEOF_VOIDP 8

/*
 * Darwin 10's default compiler (gcc42) builds for both 64 and
 * 32 bit architectures unless specifically told not to.
 * In those cases, we need to override types depending on how
 * we're being built at compile time.
 * NOTE: This is an ugly work-around for Darwin's
 * concept of universal binaries, a single package
 * (executable, lib, etc...) which contains both 32
 * and 64 bit versions. The issue is that if APR is
 * built universally, if something else is compiled
 * against it, some bit sizes will depend on whether
 * it is 32 or 64 bit. This is determined by the __LP64__
 * flag. Since we need to support both, we have to
 * handle OS X unqiuely.
 */
#ifdef DARWIN_10
#undef APR_SIZEOF_VOIDP
#undef APR_INT64_C
#undef APR_UINT64_C
#ifdef __LP64__
 typedef  long            apr_int64_t;
 typedef  unsigned long   apr_uint64_t;
 #define APR_SIZEOF_VOIDP     8
 #define APR_INT64_C(v)   (v ## L)
 #define APR_UINT64_C(v)  (v ## UL)
#else
 typedef  long long            apr_int64_t;
 typedef  unsigned long long   apr_uint64_t;
 #define APR_SIZEOF_VOIDP     4
 #define APR_INT64_C(v)   (v ## LL)
 #define APR_UINT64_C(v)  (v ## ULL)
#endif
#else
 typedef  int64_t           apr_int64_t;
 typedef  uint64_t          apr_uint64_t;

 /* Mechanisms to properly type numeric literals */
 #define APR_INT64_C(val) INT64_C(val)
 #define APR_UINT64_C(val) UINT64_C(val)
#endif

typedef  size_t          apr_size_t;
typedef  ssize_t         apr_ssize_t;
typedef  off_t           apr_off_t;
typedef  socklen_t       apr_socklen_t;
typedef  ino_t           apr_ino_t;

#if APR_SIZEOF_VOIDP == 8
typedef  apr_uint64_t            apr_uintptr_t;
#else
typedef  apr_uint32_t            apr_uintptr_t;
#endif

/* Are we big endian? */
#define APR_IS_BIGENDIAN	0

#ifdef INT16_MIN
#define APR_INT16_MIN   INT16_MIN
#else
#define APR_INT16_MIN   (-0x7fff - 1)
#endif

#ifdef INT16_MAX
#define APR_INT16_MAX  INT16_MAX
#else
#define APR_INT16_MAX   (0x7fff)
#endif

#ifdef UINT16_MAX
#define APR_UINT16_MAX  UINT16_MAX
#else
#define APR_UINT16_MAX  (0xffff)
#endif

#ifdef INT32_MIN
#define APR_INT32_MIN   INT32_MIN
#else
#define APR_INT32_MIN   (-0x7fffffff - 1)
#endif

#ifdef INT32_MAX
#define APR_INT32_MAX  INT32_MAX
#else
#define APR_INT32_MAX  0x7fffffff
#endif

#ifdef UINT32_MAX
#define APR_UINT32_MAX  UINT32_MAX
#else
#define APR_UINT32_MAX  (0xffffffffU)
#endif

#ifdef INT64_MIN
#define APR_INT64_MIN   INT64_MIN
#else
#define APR_INT64_MIN   (APR_INT64_C(-0x7fffffffffffffff) - 1)
#endif

#ifdef INT64_MAX
#define APR_INT64_MAX   INT64_MAX
#else
#define APR_INT64_MAX   APR_INT64_C(0x7fffffffffffffff)
#endif

#ifdef UINT64_MAX
#define APR_UINT64_MAX  UINT64_MAX
#else
#define APR_UINT64_MAX  APR_UINT64_C(0xffffffffffffffff)
#endif

#define APR_SIZE_MAX    (~((apr_size_t)0))


/* Definitions that APR programs need to work properly. */

/**
 * APR public API wrap for C++ compilers.
 */
#ifdef __cplusplus
#define APR_BEGIN_DECLS     extern "C" {
#define APR_END_DECLS       }
#else
#define APR_BEGIN_DECLS
#define APR_END_DECLS
#endif

/** 
 * Thread callbacks from APR functions must be declared with APR_THREAD_FUNC, 
 * so that they follow the platform's calling convention.
 * <PRE>
 *
 * void* APR_THREAD_FUNC my_thread_entry_fn(apr_thread_t *thd, void *data);
 *
 * </PRE>
 */
#define APR_THREAD_FUNC       

#if defined(DOXYGEN) || !defined(WIN32)

/**
 * 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().
 *
 * @remark Both the declaration and implementations must use the same macro.
 *
 * <PRE>
 * APR_DECLARE(rettype) apr_func(args)
 * </PRE>
 * @see APR_DECLARE_NONSTD @see APR_DECLARE_DATA
 * @remark Note that when APR compiles the library itself, it passes the 
 * symbol -DAPR_DECLARE_EXPORT to the compiler on some platforms (e.g. Win32) 
 * to export public symbols from the dynamic library build.\n
 * The user must define the APR_DECLARE_STATIC when compiling to target
 * the static APR library on some platforms (e.g. Win32.)  The public symbols 
 * are neither exported nor imported when APR_DECLARE_STATIC is defined.\n
 * By default, compiling an application and including the APR public
 * headers, without defining APR_DECLARE_STATIC, will prepare the code to be
 * linked to the dynamic library.
 */
#define APR_DECLARE(type)            type 

/**
 * The public APR functions using variable arguments are declared with 
 * APR_DECLARE_NONSTD(), as they must follow the C language calling convention.
 * @see APR_DECLARE @see APR_DECLARE_DATA
 * @remark Both the declaration and implementations must use the same macro.
 * <PRE>
 *
 * APR_DECLARE_NONSTD(rettype) apr_func(args, ...);
 *
 * </PRE>
 */
#define APR_DECLARE_NONSTD(type)     type

/**
 * The public APR variables are declared with AP_MODULE_DECLARE_DATA.
 * This assures the appropriate indirection is invoked at compile time.
 * @see APR_DECLARE @see APR_DECLARE_NONSTD
 * @remark Note that the declaration and implementations use different forms,
 * but both must include the macro.
 * 
 * <PRE>
 *
 * extern APR_DECLARE_DATA type apr_variable;\n
 * APR_DECLARE_DATA type apr_variable = value;
 *
 * </PRE>
 */
#define APR_DECLARE_DATA

#elif defined(APR_DECLARE_STATIC)
#define APR_DECLARE(type)            type __stdcall
#define APR_DECLARE_NONSTD(type)     type __cdecl
#define APR_DECLARE_DATA
#elif defined(APR_DECLARE_EXPORT)
#define APR_DECLARE(type)            __declspec(dllexport) type __stdcall
#define APR_DECLARE_NONSTD(type)     __declspec(dllexport) type __cdecl
#define APR_DECLARE_DATA             __declspec(dllexport)
#else
#define APR_DECLARE(type)            __declspec(dllimport) type __stdcall
#define APR_DECLARE_NONSTD(type)     __declspec(dllimport) type __cdecl
#define APR_DECLARE_DATA             __declspec(dllimport)
#endif

/* Define APR_SSIZE_T_FMT.  
 * If ssize_t is an integer we define it to be "d",
 * if ssize_t is a long int we define it to be "ld",
 * if ssize_t is neither we declare an error here.
 * I looked for a better way to define this here, but couldn't find one, so
 * to find the logic for this definition search for "ssize_t_fmt" in
 * configure.in.
 */

#define APR_SSIZE_T_FMT "ld"

/* And APR_SIZE_T_FMT */
#define APR_SIZE_T_FMT "lu"

/* And APR_OFF_T_FMT */
#define APR_OFF_T_FMT "ld"

/* And APR_PID_T_FMT */
#define APR_PID_T_FMT "d"

/* And APR_INT64_T_FMT */
#define APR_INT64_T_FMT PRId64

/* And APR_UINT64_T_FMT */
#define APR_UINT64_T_FMT PRIu64

/* And APR_UINT64_T_HEX_FMT */
#define APR_UINT64_T_HEX_FMT PRIx64

/*
 * Ensure we work with universal binaries on Darwin
 */
#ifdef DARWIN_10

#undef APR_HAS_LARGE_FILES
#undef APR_SIZEOF_VOIDP
#undef APR_INT64_T_FMT
#undef APR_UINT64_T_FMT
#undef APR_UINT64_T_HEX_FMT

#ifdef __LP64__
 #define APR_HAS_LARGE_FILES  0
 #define APR_SIZEOF_VOIDP     8
 #define APR_INT64_T_FMT      "ld"
 #define APR_UINT64_T_FMT     "lu"
 #define APR_UINT64_T_HEX_FMT "lx"
#else
 #define APR_HAS_LARGE_FILES  1
 #define APR_SIZEOF_VOIDP     4
 #define APR_INT64_T_FMT      "lld"
 #define APR_UINT64_T_FMT     "llu"
 #define APR_UINT64_T_HEX_FMT "llx"
#endif

#undef APR_IS_BIGENDIAN
#ifdef __BIG_ENDIAN__
 #define APR_IS_BIGENDIAN	1
#else
 #define APR_IS_BIGENDIAN	0
#endif

#undef APR_OFF_T_FMT
#define APR_OFF_T_FMT "lld"

#endif /* DARWIN_10 */

/* Does the proc mutex lock threads too */
#define APR_PROC_MUTEX_IS_GLOBAL      0

/* Local machine definition for console and log output. */
#define APR_EOL_STR              "\n"

#if APR_HAVE_SYS_WAIT_H
#ifdef WEXITSTATUS
#define apr_wait_t       int
#else
#define apr_wait_t       union wait
#define WEXITSTATUS(status)    (int)((status).w_retcode)
#define WTERMSIG(status)       (int)((status).w_termsig)
#endif /* !WEXITSTATUS */
#elif defined(__MINGW32__)
typedef int apr_wait_t;
#endif /* HAVE_SYS_WAIT_H */

#if defined(PATH_MAX)
#define APR_PATH_MAX       PATH_MAX
#elif defined(_POSIX_PATH_MAX)
#define APR_PATH_MAX       _POSIX_PATH_MAX
#else
#error no decision has been made on APR_PATH_MAX for your platform
#endif

#define APR_DSOPATH "LD_LIBRARY_PATH"

/** @} */

/* Definitions that only Win32 programs need to compile properly. */

/* XXX These simply don't belong here, perhaps in apr_portable.h
 * based on some APR_HAVE_PID/GID/UID?
 */
#ifdef __MINGW32__
#ifndef __GNUC__
typedef  int         pid_t;
#endif
typedef  int         uid_t;
typedef  int         gid_t;
#endif

#ifdef __cplusplus
}
#endif

#endif /* APR_H */
apr-1/apr_portable.h000064400000050027151730340530010314 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* This header file is where you should put ANY platform specific information.
 * This should be the only header file that programs need to include that 
 * actually has platform dependent code which refers to the .
 */
#ifndef APR_PORTABLE_H
#define APR_PORTABLE_H
/**
 * @file apr_portable.h
 * @brief APR Portability Routines
 */

#include "apr.h"
#include "apr_pools.h"
#include "apr_thread_proc.h"
#include "apr_file_io.h"
#include "apr_network_io.h"
#include "apr_errno.h"
#include "apr_global_mutex.h"
#include "apr_proc_mutex.h"
#include "apr_time.h"
#include "apr_dso.h"
#include "apr_shm.h"

#if APR_HAVE_DIRENT_H
#include <dirent.h>
#endif
#if APR_HAVE_FCNTL_H
#include <fcntl.h>
#endif
#if APR_HAVE_PTHREAD_H
#include <pthread.h>
#endif
#if APR_HAVE_SEMAPHORE_H
#include <semaphore.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @defgroup apr_portabile Portability Routines
 * @ingroup APR 
 * @{
 */

#ifdef WIN32
/* The primitives for Windows types */
typedef HANDLE                apr_os_file_t;
typedef HANDLE                apr_os_dir_t;
typedef SOCKET                apr_os_sock_t;
typedef HANDLE                apr_os_proc_mutex_t;
typedef HANDLE                apr_os_thread_t;
typedef HANDLE                apr_os_proc_t;
typedef DWORD                 apr_os_threadkey_t; 
typedef FILETIME              apr_os_imp_time_t;
typedef SYSTEMTIME            apr_os_exp_time_t;
typedef HANDLE                apr_os_dso_handle_t;
typedef HANDLE                apr_os_shm_t;

#elif defined(OS2)
typedef HFILE                 apr_os_file_t;
typedef HDIR                  apr_os_dir_t;
typedef int                   apr_os_sock_t;
typedef HMTX                  apr_os_proc_mutex_t;
typedef TID                   apr_os_thread_t;
typedef PID                   apr_os_proc_t;
typedef PULONG                apr_os_threadkey_t; 
typedef struct timeval        apr_os_imp_time_t;
typedef struct tm             apr_os_exp_time_t;
typedef HMODULE               apr_os_dso_handle_t;
typedef void*                 apr_os_shm_t;

#elif defined(__BEOS__)
#include <kernel/OS.h>
#include <kernel/image.h>

struct apr_os_proc_mutex_t {
	sem_id sem;
	int32  ben;
};

typedef int                   apr_os_file_t;
typedef DIR                   apr_os_dir_t;
typedef int                   apr_os_sock_t;
typedef struct apr_os_proc_mutex_t  apr_os_proc_mutex_t;
typedef thread_id             apr_os_thread_t;
typedef thread_id             apr_os_proc_t;
typedef int                   apr_os_threadkey_t;
typedef struct timeval        apr_os_imp_time_t;
typedef struct tm             apr_os_exp_time_t;
typedef image_id              apr_os_dso_handle_t;
typedef void*                 apr_os_shm_t;

#elif defined(NETWARE)
typedef int                   apr_os_file_t;
typedef DIR                   apr_os_dir_t;
typedef int                   apr_os_sock_t;
typedef NXMutex_t             apr_os_proc_mutex_t;
typedef NXThreadId_t          apr_os_thread_t;
typedef long                  apr_os_proc_t;
typedef NXKey_t               apr_os_threadkey_t; 
typedef struct timeval        apr_os_imp_time_t;
typedef struct tm             apr_os_exp_time_t;
typedef void *                apr_os_dso_handle_t;
typedef void*                 apr_os_shm_t;

#else
/* Any other OS should go above this one.  This is the lowest common
 * denominator typedefs for  all UNIX-like systems.  :)
 */

/** Basic OS process mutex structure. */
struct apr_os_proc_mutex_t {
#if APR_HAS_SYSVSEM_SERIALIZE || APR_HAS_FCNTL_SERIALIZE || APR_HAS_FLOCK_SERIALIZE
    /** Value used for SYS V Semaphore, FCNTL and FLOCK serialization */
    int crossproc;
#endif
#if APR_HAS_PROC_PTHREAD_SERIALIZE
    /** Value used for PTHREAD serialization */
    pthread_mutex_t *pthread_interproc;
#endif
#if APR_HAS_THREADS
    /* If no threads, no need for thread locks */
#if APR_USE_PTHREAD_SERIALIZE
    /** This value is currently unused within APR and Apache */ 
    pthread_mutex_t *intraproc;
#endif
#endif
#if APR_HAS_POSIXSEM_SERIALIZE
    /** Value used for POSIX semaphores serialization */
    sem_t *psem_interproc;
#endif
};

typedef int                   apr_os_file_t;        /**< native file */
typedef DIR                   apr_os_dir_t;         /**< native dir */
typedef int                   apr_os_sock_t;        /**< native dir */
typedef struct apr_os_proc_mutex_t  apr_os_proc_mutex_t; /**< native process
                                                          *   mutex
                                                          */
#if APR_HAS_THREADS && APR_HAVE_PTHREAD_H 
typedef pthread_t             apr_os_thread_t;      /**< native thread */
typedef pthread_key_t         apr_os_threadkey_t;   /**< native thread address
                                                     *   space */
#endif
typedef pid_t                 apr_os_proc_t;        /**< native pid */
typedef struct timeval        apr_os_imp_time_t;    /**< native timeval */
typedef struct tm             apr_os_exp_time_t;    /**< native tm */
/** @var apr_os_dso_handle_t
 * native dso types
 */
#if defined(HPUX) || defined(HPUX10) || defined(HPUX11)
#include <dl.h>
typedef shl_t                 apr_os_dso_handle_t;
#elif defined(DARWIN)
#include <mach-o/dyld.h>
typedef NSModule              apr_os_dso_handle_t;
#else
typedef void *                apr_os_dso_handle_t;
#endif
typedef void*                 apr_os_shm_t;         /**< native SHM */

#endif

/**
 * @typedef apr_os_sock_info_t
 * @brief alias for local OS socket
 */
/**
 * everything APR needs to know about an active socket to construct
 * an APR socket from it; currently, this is platform-independent
 */
struct apr_os_sock_info_t {
    apr_os_sock_t *os_sock; /**< always required */
    struct sockaddr *local; /**< NULL if not yet bound */
    struct sockaddr *remote; /**< NULL if not connected */
    int family;             /**< always required (APR_INET, APR_INET6, etc.) */
    int type;               /**< always required (SOCK_STREAM, SOCK_DGRAM, etc.) */
    int protocol;           /**< 0 or actual protocol (APR_PROTO_SCTP, APR_PROTO_TCP, etc.) */
};

typedef struct apr_os_sock_info_t apr_os_sock_info_t;

#if APR_PROC_MUTEX_IS_GLOBAL || defined(DOXYGEN)
/** Opaque global mutex type */
#define apr_os_global_mutex_t apr_os_proc_mutex_t
/** @return apr_os_global_mutex */
#define apr_os_global_mutex_get apr_os_proc_mutex_get
#else
    /** Thread and process mutex for those platforms where process mutexes
     *  are not held in threads.
     */
    struct apr_os_global_mutex_t {
        apr_pool_t *pool;
        apr_proc_mutex_t *proc_mutex;
#if APR_HAS_THREADS
        apr_thread_mutex_t *thread_mutex;
#endif /* APR_HAS_THREADS */
    };
    typedef struct apr_os_global_mutex_t apr_os_global_mutex_t;

APR_DECLARE(apr_status_t) apr_os_global_mutex_get(apr_os_global_mutex_t *ospmutex, 
                                                apr_global_mutex_t *pmutex);
#endif


/**
 * convert the file from apr type to os specific type.
 * @param thefile The os specific file we are converting to
 * @param file The apr file to convert.
 * @remark On Unix, it is only possible to get a file descriptor from 
 *         an apr file type.
 */
APR_DECLARE(apr_status_t) apr_os_file_get(apr_os_file_t *thefile,
                                          apr_file_t *file);

/**
 * convert the dir from apr type to os specific type.
 * @param thedir The os specific dir we are converting to
 * @param dir The apr dir to convert.
 */   
APR_DECLARE(apr_status_t) apr_os_dir_get(apr_os_dir_t **thedir, 
                                         apr_dir_t *dir);

/**
 * Convert the socket from an apr type to an OS specific socket
 * @param thesock The socket to convert.
 * @param sock The os specific equivalent of the apr socket..
 */
APR_DECLARE(apr_status_t) apr_os_sock_get(apr_os_sock_t *thesock,
                                          apr_socket_t *sock);

/**
 * Convert the proc mutex from apr type to os specific type
 * @param ospmutex The os specific proc mutex we are converting to.
 * @param pmutex The apr proc mutex to convert.
 */
APR_DECLARE(apr_status_t) apr_os_proc_mutex_get(apr_os_proc_mutex_t *ospmutex, 
                                                apr_proc_mutex_t *pmutex);

/**
 * Convert the proc mutex from apr type to os specific type, also
 * providing the mechanism used by the apr mutex.
 * @param ospmutex The os specific proc mutex we are converting to.
 * @param pmutex The apr proc mutex to convert.
 * @param mech The mechanism used by the apr proc mutex (if not NULL).
 * @remark Allows for disambiguation for platforms with multiple mechanisms
 *         available.
 */
APR_DECLARE(apr_status_t) apr_os_proc_mutex_get_ex(apr_os_proc_mutex_t *ospmutex, 
                                                   apr_proc_mutex_t *pmutex,
                                                   apr_lockmech_e *mech);

/**
 * Get the exploded time in the platforms native format.
 * @param ostime the native time format
 * @param aprtime the time to convert
 */
APR_DECLARE(apr_status_t) apr_os_exp_time_get(apr_os_exp_time_t **ostime,
                                 apr_time_exp_t *aprtime);

/**
 * Get the imploded time in the platforms native format.
 * @param ostime  the native time format
 * @param aprtime the time to convert
 */
APR_DECLARE(apr_status_t) apr_os_imp_time_get(apr_os_imp_time_t **ostime, 
                                              apr_time_t *aprtime);

/**
 * convert the shm from apr type to os specific type.
 * @param osshm The os specific shm representation
 * @param shm The apr shm to convert.
 */   
APR_DECLARE(apr_status_t) apr_os_shm_get(apr_os_shm_t *osshm,
                                         apr_shm_t *shm);

#if APR_HAS_THREADS || defined(DOXYGEN)
/** 
 * @defgroup apr_os_thread Thread portability Routines
 * @{ 
 */
/**
 * convert the thread to os specific type from apr type.
 * @param thethd The apr thread to convert
 * @param thd The os specific thread we are converting to
 */
APR_DECLARE(apr_status_t) apr_os_thread_get(apr_os_thread_t **thethd, 
                                            apr_thread_t *thd);

/**
 * convert the thread private memory key to os specific type from an apr type.
 * @param thekey The apr handle we are converting from.
 * @param key The os specific handle we are converting to.
 */
APR_DECLARE(apr_status_t) apr_os_threadkey_get(apr_os_threadkey_t *thekey,
                                               apr_threadkey_t *key);

/**
 * convert the thread from os specific type to apr type.
 * @param thd The apr thread we are converting to.
 * @param thethd The os specific thread to convert
 * @param cont The pool to use if it is needed.
 */
APR_DECLARE(apr_status_t) apr_os_thread_put(apr_thread_t **thd,
                                            apr_os_thread_t *thethd,
                                            apr_pool_t *cont);

/**
 * convert the thread private memory key from os specific type to apr type.
 * @param key The apr handle we are converting to.
 * @param thekey The os specific handle to convert
 * @param cont The pool to use if it is needed.
 */
APR_DECLARE(apr_status_t) apr_os_threadkey_put(apr_threadkey_t **key,
                                               apr_os_threadkey_t *thekey,
                                               apr_pool_t *cont);
/**
 * Get the thread ID
 */
APR_DECLARE(apr_os_thread_t) apr_os_thread_current(void);

/**
 * Compare two thread id's
 * @param tid1 1st Thread ID to compare
 * @param tid2 2nd Thread ID to compare
 * @return non-zero if the two threads are equal, zero otherwise
 */ 
APR_DECLARE(int) apr_os_thread_equal(apr_os_thread_t tid1, 
                                     apr_os_thread_t tid2);

/** @} */
#endif /* APR_HAS_THREADS */

/**
 * convert the file from os specific type to apr type.
 * @param file The apr file we are converting to.
 * @param thefile The os specific file to convert
 * @param flags The flags that were used to open this file.
 * @param cont The pool to use if it is needed.
 * @remark On Unix, it is only possible to put a file descriptor into
 *         an apr file type.
 */
APR_DECLARE(apr_status_t) apr_os_file_put(apr_file_t **file,
                                          apr_os_file_t *thefile,
                                          apr_int32_t flags, apr_pool_t *cont); 

/**
 * convert the file from os specific type to apr type.
 * @param file The apr file we are converting to.
 * @param thefile The os specific pipe to convert
 * @param cont The pool to use if it is needed.
 * @remark On Unix, it is only possible to put a file descriptor into
 *         an apr file type.
 */
APR_DECLARE(apr_status_t) apr_os_pipe_put(apr_file_t **file,
                                          apr_os_file_t *thefile,
                                          apr_pool_t *cont);

/**
 * convert the file from os specific type to apr type.
 * @param file The apr file we are converting to.
 * @param thefile The os specific pipe to convert
 * @param register_cleanup A cleanup will be registered on the apr_file_t
 *   to issue apr_file_close().
 * @param cont The pool to use if it is needed.
 * @remark On Unix, it is only possible to put a file descriptor into
 *         an apr file type.
 */
APR_DECLARE(apr_status_t) apr_os_pipe_put_ex(apr_file_t **file,
                                             apr_os_file_t *thefile,
                                             int register_cleanup,
                                             apr_pool_t *cont);

/**
 * convert the dir from os specific type to apr type.
 * @param dir The apr dir we are converting to.
 * @param thedir The os specific dir to convert
 * @param cont The pool to use when creating to apr directory.
 */
APR_DECLARE(apr_status_t) apr_os_dir_put(apr_dir_t **dir,
                                         apr_os_dir_t *thedir,
                                         apr_pool_t *cont); 

/**
 * Convert a socket from the os specific type to the APR type. If
 * sock points to NULL, a socket will be created from the pool
 * provided. If **sock does not point to NULL, the structure pointed
 * to by sock will be reused and updated with the given socket.
 * @param sock The pool to use.
 * @param thesock The socket to convert to.
 * @param cont The socket we are converting to an apr type.
 * @remark If it is a true socket, it is best to call apr_os_sock_make()
 *         and provide APR with more information about the socket.
 */
APR_DECLARE(apr_status_t) apr_os_sock_put(apr_socket_t **sock, 
                                          apr_os_sock_t *thesock, 
                                          apr_pool_t *cont);

/**
 * Create a socket from an existing descriptor and local and remote
 * socket addresses.
 * @param apr_sock The new socket that has been set up
 * @param os_sock_info The os representation of the socket handle and
 *        other characteristics of the socket
 * @param cont The pool to use
 * @remark If you only know the descriptor/handle or if it isn't really
 *         a true socket, use apr_os_sock_put() instead.
 */
APR_DECLARE(apr_status_t) apr_os_sock_make(apr_socket_t **apr_sock,
                                           apr_os_sock_info_t *os_sock_info,
                                           apr_pool_t *cont);

/**
 * Convert the proc mutex from os specific type to apr type
 * @param pmutex The apr proc mutex we are converting to.
 * @param ospmutex The os specific proc mutex to convert.
 * @param cont The pool to use if it is needed.
 */
APR_DECLARE(apr_status_t) apr_os_proc_mutex_put(apr_proc_mutex_t **pmutex,
                                                apr_os_proc_mutex_t *ospmutex,
                                                apr_pool_t *cont); 

/**
 * Convert the proc mutex from os specific type to apr type, using the
 * specified mechanism.
 * @param pmutex The apr proc mutex we are converting to.
 * @param ospmutex The os specific proc mutex to convert.
 * @param mech The apr mutex locking mechanism
 * @param register_cleanup Whether to destroy the os mutex with the apr
 *        one (either on explicit destroy or pool cleanup).
 * @param cont The pool to use if it is needed.
 * @remark Allows for disambiguation for platforms with multiple mechanisms
 *         available.
 */
APR_DECLARE(apr_status_t) apr_os_proc_mutex_put_ex(apr_proc_mutex_t **pmutex,
                                                apr_os_proc_mutex_t *ospmutex,
                                                apr_lockmech_e mech,
                                                int register_cleanup,
                                                apr_pool_t *cont); 

/**
 * Put the imploded time in the APR format.
 * @param aprtime the APR time format
 * @param ostime the time to convert
 * @param cont the pool to use if necessary
 */
APR_DECLARE(apr_status_t) apr_os_imp_time_put(apr_time_t *aprtime,
                                              apr_os_imp_time_t **ostime,
                                              apr_pool_t *cont); 

/**
 * Put the exploded time in the APR format.
 * @param aprtime the APR time format
 * @param ostime the time to convert
 * @param cont the pool to use if necessary
 */
APR_DECLARE(apr_status_t) apr_os_exp_time_put(apr_time_exp_t *aprtime,
                                              apr_os_exp_time_t **ostime,
                                              apr_pool_t *cont); 

/**
 * convert the shared memory from os specific type to apr type.
 * @param shm The apr shm representation of osshm
 * @param osshm The os specific shm identity
 * @param cont The pool to use if it is needed.
 * @remark On fork()ed architectures, this is typically nothing more than
 * the memory block mapped.  On non-fork architectures, this is typically
 * some internal handle to pass the mapping from process to process.
 */
APR_DECLARE(apr_status_t) apr_os_shm_put(apr_shm_t **shm,
                                         apr_os_shm_t *osshm,
                                         apr_pool_t *cont); 


#if APR_HAS_DSO || defined(DOXYGEN)
/** 
 * @defgroup apr_os_dso DSO (Dynamic Loading) Portability Routines
 * @{
 */
/**
 * convert the dso handle from os specific to apr
 * @param dso The apr handle we are converting to
 * @param thedso the os specific handle to convert
 * @param pool the pool to use if it is needed
 */
APR_DECLARE(apr_status_t) apr_os_dso_handle_put(apr_dso_handle_t **dso,
                                                apr_os_dso_handle_t thedso,
                                                apr_pool_t *pool);

/**
 * convert the apr dso handle into an os specific one
 * @param aprdso The apr dso handle to convert
 * @param dso The os specific dso to return
 */
APR_DECLARE(apr_status_t) apr_os_dso_handle_get(apr_os_dso_handle_t *dso,
                                                apr_dso_handle_t *aprdso);

/** @} */
#endif /* APR_HAS_DSO */


#if APR_HAS_OS_UUID
/**
 * Private: apr-util's apr_uuid module when supported by the platform
 */
APR_DECLARE(apr_status_t) apr_os_uuid_get(unsigned char *uuid_data);
#endif


/**
 * Get the name of the system default character set.
 * @param pool the pool to allocate the name from, if needed
 */
APR_DECLARE(const char*) apr_os_default_encoding(apr_pool_t *pool);


/**
 * Get the name of the current locale character set.
 * @param pool the pool to allocate the name from, if needed
 * @remark Defers to apr_os_default_encoding() if the current locale's
 * data can't be retrieved on this system.
 */
APR_DECLARE(const char*) apr_os_locale_encoding(apr_pool_t *pool);

/** @} */

#ifdef __cplusplus
}
#endif

#endif  /* ! APR_PORTABLE_H */
apr-1/apr_uri.h000064400000014675151730340530007314 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * apr_uri.h: External Interface of apr_uri.c
 */

/**
 * @file apr_uri.h
 * @brief APR-UTIL URI Routines
 */

#ifndef APR_URI_H
#define APR_URI_H

#include "apu.h"

#include "apr_network_io.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @defgroup APR_Util_URI URI
 * @ingroup APR_Util
 * @{
 */

#define APR_URI_FTP_DEFAULT_PORT         21 /**< default FTP port */
#define APR_URI_SSH_DEFAULT_PORT         22 /**< default SSH port */
#define APR_URI_TELNET_DEFAULT_PORT      23 /**< default telnet port */
#define APR_URI_GOPHER_DEFAULT_PORT      70 /**< default Gopher port */
#define APR_URI_HTTP_DEFAULT_PORT        80 /**< default HTTP port */
#define APR_URI_POP_DEFAULT_PORT        110 /**< default POP port */
#define APR_URI_NNTP_DEFAULT_PORT       119 /**< default NNTP port */
#define APR_URI_IMAP_DEFAULT_PORT       143 /**< default IMAP port */
#define APR_URI_PROSPERO_DEFAULT_PORT   191 /**< default Prospero port */
#define APR_URI_WAIS_DEFAULT_PORT       210 /**< default WAIS port */
#define APR_URI_LDAP_DEFAULT_PORT       389 /**< default LDAP port */
#define APR_URI_HTTPS_DEFAULT_PORT      443 /**< default HTTPS port */
#define APR_URI_RTSP_DEFAULT_PORT       554 /**< default RTSP port */
#define APR_URI_SNEWS_DEFAULT_PORT      563 /**< default SNEWS port */
#define APR_URI_ACAP_DEFAULT_PORT       674 /**< default ACAP port */
#define APR_URI_NFS_DEFAULT_PORT       2049 /**< default NFS port */
#define APR_URI_TIP_DEFAULT_PORT       3372 /**< default TIP port */
#define APR_URI_SIP_DEFAULT_PORT       5060 /**< default SIP port */

/** Flags passed to unparse_uri_components(): */
/** suppress "scheme://user\@site:port" */
#define APR_URI_UNP_OMITSITEPART    (1U<<0)
/** Just omit user */
#define APR_URI_UNP_OMITUSER        (1U<<1)
/** Just omit password */
#define APR_URI_UNP_OMITPASSWORD    (1U<<2)
/** omit "user:password\@" part */
#define APR_URI_UNP_OMITUSERINFO    (APR_URI_UNP_OMITUSER | \
                                     APR_URI_UNP_OMITPASSWORD)
/** Show plain text password (default: show XXXXXXXX) */
#define APR_URI_UNP_REVEALPASSWORD  (1U<<3)
/** Show "scheme://user\@site:port" only */
#define APR_URI_UNP_OMITPATHINFO    (1U<<4)
/** Omit the "?queryarg" from the path */
#define APR_URI_UNP_OMITQUERY       (1U<<5)

/** @see apr_uri_t */
typedef struct apr_uri_t apr_uri_t;

/**
 * A structure to encompass all of the fields in a uri
 */
struct apr_uri_t {
    /** scheme ("http"/"ftp"/...) */
    char *scheme;
    /** combined [user[:password]\@]host[:port] */
    char *hostinfo;
    /** user name, as in http://user:passwd\@host:port/ */
    char *user;
    /** password, as in http://user:passwd\@host:port/ */
    char *password;
    /** hostname from URI (or from Host: header) */
    char *hostname;
    /** port string (integer representation is in "port") */
    char *port_str;
    /** the request path (or NULL if only scheme://host was given) */
    char *path;
    /** Everything after a '?' in the path, if present */
    char *query;
    /** Trailing "#fragment" string, if present */
    char *fragment;

    /** structure returned from gethostbyname() */
    struct hostent *hostent;

    /** The port number, numeric, valid only if port_str != NULL */
    apr_port_t port;
    
    /** has the structure been initialized */
    unsigned is_initialized:1;

    /** has the DNS been looked up yet */
    unsigned dns_looked_up:1;
    /** has the dns been resolved yet */
    unsigned dns_resolved:1;
};

/* apr_uri.c */
/**
 * Return the default port for a given scheme.  The schemes recognized are
 * http, ftp, https, gopher, wais, nntp, snews, and prospero
 * @param scheme_str The string that contains the current scheme
 * @return The default port for this scheme
 */ 
APU_DECLARE(apr_port_t) apr_uri_port_of_scheme(const char *scheme_str);

/**
 * Unparse a apr_uri_t structure to an URI string.  Optionally 
 * suppress the password for security reasons.
 * @param p The pool to allocate out of
 * @param uptr All of the parts of the uri
 * @param flags How to unparse the uri.  One of:
 * <PRE>
 *    APR_URI_UNP_OMITSITEPART        Suppress "scheme://user\@site:port" 
 *    APR_URI_UNP_OMITUSER            Just omit user 
 *    APR_URI_UNP_OMITPASSWORD        Just omit password 
 *    APR_URI_UNP_OMITUSERINFO        Omit "user:password\@" part
 *    APR_URI_UNP_REVEALPASSWORD      Show plain text password (default: show XXXXXXXX)
 *    APR_URI_UNP_OMITPATHINFO        Show "scheme://user\@site:port" only 
 *    APR_URI_UNP_OMITQUERY           Omit "?queryarg" or "#fragment" 
 * </PRE>
 * @return The uri as a string
 */
APU_DECLARE(char *) apr_uri_unparse(apr_pool_t *p, 
                                    const apr_uri_t *uptr,
                                    unsigned flags);

/**
 * Parse a given URI, fill in all supplied fields of a apr_uri_t
 * structure. This eliminates the necessity of extracting host, port,
 * path, query info repeatedly in the modules.
 * @param p The pool to allocate out of
 * @param uri The uri to parse
 * @param uptr The apr_uri_t to fill out
 * @return APR_SUCCESS for success or error code
 */
APU_DECLARE(apr_status_t) apr_uri_parse(apr_pool_t *p, const char *uri, 
                                        apr_uri_t *uptr);

/**
 * Special case for CONNECT parsing: it comes with the hostinfo part only
 * @param p The pool to allocate out of
 * @param hostinfo The hostinfo string to parse
 * @param uptr The apr_uri_t to fill out
 * @return APR_SUCCESS for success or error code
 */
APU_DECLARE(apr_status_t) apr_uri_parse_hostinfo(apr_pool_t *p, 
                                                 const char *hostinfo, 
                                                 apr_uri_t *uptr);

/** @} */
#ifdef __cplusplus
}
#endif

#endif /* APR_URI_H */
apr-1/apr_errno.h000064400000153425151730340530007637 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_ERRNO_H
#define APR_ERRNO_H

/**
 * @file apr_errno.h
 * @brief APR Error Codes
 */

#include "apr.h"

#if APR_HAVE_ERRNO_H
#include <errno.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @defgroup apr_errno Error Codes
 * @ingroup APR
 * @{
 */

/**
 * Type for specifying an error or status code.
 */
typedef int apr_status_t;

/**
 * Return a human readable string describing the specified error.
 * @param statcode The error code to get a string for.
 * @param buf A buffer to hold the error string.
 * @param bufsize Size of the buffer to hold the string.
 */
APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
                                 apr_size_t bufsize);

#if defined(DOXYGEN)
/**
 * @def APR_FROM_OS_ERROR(os_err_type syserr)
 * Fold a platform specific error into an apr_status_t code.
 * @return apr_status_t
 * @param e The platform os error code.
 * @warning  macro implementation; the syserr argument may be evaluated
 *      multiple times.
 */
#define APR_FROM_OS_ERROR(e) (e == 0 ? APR_SUCCESS : e + APR_OS_START_SYSERR)

/**
 * @def APR_TO_OS_ERROR(apr_status_t statcode)
 * @return os_err_type
 * Fold an apr_status_t code back to the native platform defined error.
 * @param e The apr_status_t folded platform os error code.
 * @warning  macro implementation; the statcode argument may be evaluated
 *      multiple times.  If the statcode was not created by apr_get_os_error
 *      or APR_FROM_OS_ERROR, the results are undefined.
 */
#define APR_TO_OS_ERROR(e) (e == 0 ? APR_SUCCESS : e - APR_OS_START_SYSERR)

/** @def apr_get_os_error()
 * @return apr_status_t the last platform error, folded into apr_status_t, on most platforms
 * @remark This retrieves errno, or calls a GetLastError() style function, and
 *      folds it with APR_FROM_OS_ERROR.  Some platforms (such as OS2) have no
 *      such mechanism, so this call may be unsupported.  Do NOT use this
 *      call for socket errors from socket, send, recv etc!
 */

/** @def apr_set_os_error(e)
 * Reset the last platform error, unfolded from an apr_status_t, on some platforms
 * @param e The OS error folded in a prior call to APR_FROM_OS_ERROR()
 * @warning This is a macro implementation; the statcode argument may be evaluated
 *      multiple times.  If the statcode was not created by apr_get_os_error
 *      or APR_FROM_OS_ERROR, the results are undefined.  This macro sets
 *      errno, or calls a SetLastError() style function, unfolding statcode
 *      with APR_TO_OS_ERROR.  Some platforms (such as OS2) have no such
 *      mechanism, so this call may be unsupported.
 */

/** @def apr_get_netos_error()
 * Return the last socket error, folded into apr_status_t, on all platforms
 * @remark This retrieves errno or calls a GetLastSocketError() style function,
 *      and folds it with APR_FROM_OS_ERROR.
 */

/** @def apr_set_netos_error(e)
 * Reset the last socket error, unfolded from an apr_status_t
 * @param e The socket error folded in a prior call to APR_FROM_OS_ERROR()
 * @warning This is a macro implementation; the statcode argument may be evaluated
 *      multiple times.  If the statcode was not created by apr_get_os_error
 *      or APR_FROM_OS_ERROR, the results are undefined.  This macro sets
 *      errno, or calls a WSASetLastError() style function, unfolding
 *      socketcode with APR_TO_OS_ERROR.
 */

#endif /* defined(DOXYGEN) */

/**
 * APR_OS_START_ERROR is where the APR specific error values start.
 */
#define APR_OS_START_ERROR     20000
/**
 * 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.
 */
#define APR_OS_ERRSPACE_SIZE 50000
/**
 * APR_UTIL_ERRSPACE_SIZE is the size of the space that is reserved for
 * use within apr-util. This space is reserved above that used by APR
 * internally.
 * @note This number MUST be smaller than APR_OS_ERRSPACE_SIZE by a
 *       large enough amount that APR has sufficient room for its
 *       codes.
 */
#define APR_UTIL_ERRSPACE_SIZE 20000
/**
 * APR_OS_START_STATUS is where the APR specific status codes start.
 */
#define APR_OS_START_STATUS    (APR_OS_START_ERROR + APR_OS_ERRSPACE_SIZE)
/**
 * APR_UTIL_START_STATUS is where APR-Util starts defining its
 * status codes.
 */
#define APR_UTIL_START_STATUS   (APR_OS_START_STATUS + \
                           (APR_OS_ERRSPACE_SIZE - APR_UTIL_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.
 *
 * In general applications should try and create unique error codes. To try
 * and assist in finding suitable ranges of numbers to use, the following
 * ranges are known to be used by the listed applications. If your
 * application defines error codes please advise the range of numbers it
 * uses to dev@apr.apache.org for inclusion in this list.
 *
 * Ranges shown are in relation to APR_OS_START_USERERR
 *
 * Subversion - Defined ranges, of less than 100, at intervals of 5000
 *              starting at an offset of 5000, e.g.
 *               +5000 to 5100,  +10000 to 10100
 *
 * Apache HTTPD - +2000 to 2999
 */
#define APR_OS_START_USERERR    (APR_OS_START_STATUS + APR_OS_ERRSPACE_SIZE)
/**
 * APR_OS_START_USEERR is obsolete, defined for compatibility only.
 * Use APR_OS_START_USERERR instead.
 */
#define APR_OS_START_USEERR     APR_OS_START_USERERR
/**
 * APR_OS_START_CANONERR is where APR versions of errno values are defined
 *     on systems which don't have the corresponding errno.
 */
#define APR_OS_START_CANONERR  (APR_OS_START_USERERR \
                                 + (APR_OS_ERRSPACE_SIZE * 10))
/**
 * APR_OS_START_EAIERR folds EAI_ error codes from getaddrinfo() into
 *     apr_status_t values.
 */
#define APR_OS_START_EAIERR    (APR_OS_START_CANONERR + APR_OS_ERRSPACE_SIZE)
/**
 * APR_OS_START_SYSERR folds platform-specific system error values into
 *     apr_status_t values.
 */
#define APR_OS_START_SYSERR    (APR_OS_START_EAIERR + APR_OS_ERRSPACE_SIZE)

/**
 * @defgroup APR_ERROR_map APR Error Space
 * <PRE>
 * The following attempts to show the relation of the various constants
 * used for mapping APR Status codes.
 *
 *       0
 *
 *  20,000     APR_OS_START_ERROR
 *
 *         + APR_OS_ERRSPACE_SIZE (50,000)
 *
 *  70,000      APR_OS_START_STATUS
 *
 *         + APR_OS_ERRSPACE_SIZE - APR_UTIL_ERRSPACE_SIZE (30,000)
 *
 * 100,000      APR_UTIL_START_STATUS
 *
 *         + APR_UTIL_ERRSPACE_SIZE (20,000)
 *
 * 120,000      APR_OS_START_USERERR
 *
 *         + 10 x APR_OS_ERRSPACE_SIZE (50,000 * 10)
 *
 * 620,000      APR_OS_START_CANONERR
 *
 *         + APR_OS_ERRSPACE_SIZE (50,000)
 *
 * 670,000      APR_OS_START_EAIERR
 *
 *         + APR_OS_ERRSPACE_SIZE (50,000)
 *
 * 720,000      APR_OS_START_SYSERR
 *
 * </PRE>
 */

/** no error. */
#define APR_SUCCESS 0

/**
 * @defgroup APR_Error APR Error Values
 * <PRE>
 * <b>APR ERROR VALUES</b>
 * 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_ESYMNOTFOUND Could not find the requested symbol
 * APR_ENOTENOUGHENTROPY Not enough entropy to continue
 * </PRE>
 *
 * <PRE>
 * <b>APR STATUS VALUES</b>
 * 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.
 * APR_EPROC_UNKNOWN  The given process wasn't recognized by APR
 * </PRE>
 * @{
 */
/** @see APR_STATUS_IS_ENOSTAT */
#define APR_ENOSTAT        (APR_OS_START_ERROR + 1)
/** @see APR_STATUS_IS_ENOPOOL */
#define APR_ENOPOOL        (APR_OS_START_ERROR + 2)
/* empty slot: +3 */
/** @see APR_STATUS_IS_EBADDATE */
#define APR_EBADDATE       (APR_OS_START_ERROR + 4)
/** @see APR_STATUS_IS_EINVALSOCK */
#define APR_EINVALSOCK     (APR_OS_START_ERROR + 5)
/** @see APR_STATUS_IS_ENOPROC */
#define APR_ENOPROC        (APR_OS_START_ERROR + 6)
/** @see APR_STATUS_IS_ENOTIME */
#define APR_ENOTIME        (APR_OS_START_ERROR + 7)
/** @see APR_STATUS_IS_ENODIR */
#define APR_ENODIR         (APR_OS_START_ERROR + 8)
/** @see APR_STATUS_IS_ENOLOCK */
#define APR_ENOLOCK        (APR_OS_START_ERROR + 9)
/** @see APR_STATUS_IS_ENOPOLL */
#define APR_ENOPOLL        (APR_OS_START_ERROR + 10)
/** @see APR_STATUS_IS_ENOSOCKET */
#define APR_ENOSOCKET      (APR_OS_START_ERROR + 11)
/** @see APR_STATUS_IS_ENOTHREAD */
#define APR_ENOTHREAD      (APR_OS_START_ERROR + 12)
/** @see APR_STATUS_IS_ENOTHDKEY */
#define APR_ENOTHDKEY      (APR_OS_START_ERROR + 13)
/** @see APR_STATUS_IS_EGENERAL */
#define APR_EGENERAL       (APR_OS_START_ERROR + 14)
/** @see APR_STATUS_IS_ENOSHMAVAIL */
#define APR_ENOSHMAVAIL    (APR_OS_START_ERROR + 15)
/** @see APR_STATUS_IS_EBADIP */
#define APR_EBADIP         (APR_OS_START_ERROR + 16)
/** @see APR_STATUS_IS_EBADMASK */
#define APR_EBADMASK       (APR_OS_START_ERROR + 17)
/* empty slot: +18 */
/** @see APR_STATUS_IS_EDSOPEN */
#define APR_EDSOOPEN       (APR_OS_START_ERROR + 19)
/** @see APR_STATUS_IS_EABSOLUTE */
#define APR_EABSOLUTE      (APR_OS_START_ERROR + 20)
/** @see APR_STATUS_IS_ERELATIVE */
#define APR_ERELATIVE      (APR_OS_START_ERROR + 21)
/** @see APR_STATUS_IS_EINCOMPLETE */
#define APR_EINCOMPLETE    (APR_OS_START_ERROR + 22)
/** @see APR_STATUS_IS_EABOVEROOT */
#define APR_EABOVEROOT     (APR_OS_START_ERROR + 23)
/** @see APR_STATUS_IS_EBADPATH */
#define APR_EBADPATH       (APR_OS_START_ERROR + 24)
/** @see APR_STATUS_IS_EPATHWILD */
#define APR_EPATHWILD      (APR_OS_START_ERROR + 25)
/** @see APR_STATUS_IS_ESYMNOTFOUND */
#define APR_ESYMNOTFOUND   (APR_OS_START_ERROR + 26)
/** @see APR_STATUS_IS_EPROC_UNKNOWN */
#define APR_EPROC_UNKNOWN  (APR_OS_START_ERROR + 27)
/** @see APR_STATUS_IS_ENOTENOUGHENTROPY */
#define APR_ENOTENOUGHENTROPY (APR_OS_START_ERROR + 28)
/** @} */

/**
 * @defgroup APR_STATUS_IS Status Value Tests
 * @warning For any particular error condition, more than one of these tests
 *      may match. This is because platform-specific error codes may not
 *      always match the semantics of the POSIX codes these tests (and the
 *      corresponding APR error codes) are named after. A notable example
 *      are the APR_STATUS_IS_ENOENT and APR_STATUS_IS_ENOTDIR tests on
 *      Win32 platforms. The programmer should always be aware of this and
 *      adjust the order of the tests accordingly.
 * @{
 */
/**
 * APR was unable to perform a stat on the file
 * @warning always use this test, as platform-specific variances may meet this
 * more than one error code
 */
#define APR_STATUS_IS_ENOSTAT(s)        ((s) == APR_ENOSTAT)
/**
 * APR was not provided a pool with which to allocate memory
 * @warning always use this test, as platform-specific variances may meet this
 * more than one error code
 */
#define APR_STATUS_IS_ENOPOOL(s)        ((s) == APR_ENOPOOL)
/** APR was given an invalid date  */
#define APR_STATUS_IS_EBADDATE(s)       ((s) == APR_EBADDATE)
/** APR was given an invalid socket */
#define APR_STATUS_IS_EINVALSOCK(s)     ((s) == APR_EINVALSOCK)
/** APR was not given a process structure */
#define APR_STATUS_IS_ENOPROC(s)        ((s) == APR_ENOPROC)
/** APR was not given a time structure */
#define APR_STATUS_IS_ENOTIME(s)        ((s) == APR_ENOTIME)
/** APR was not given a directory structure */
#define APR_STATUS_IS_ENODIR(s)         ((s) == APR_ENODIR)
/** APR was not given a lock structure */
#define APR_STATUS_IS_ENOLOCK(s)        ((s) == APR_ENOLOCK)
/** APR was not given a poll structure */
#define APR_STATUS_IS_ENOPOLL(s)        ((s) == APR_ENOPOLL)
/** APR was not given a socket */
#define APR_STATUS_IS_ENOSOCKET(s)      ((s) == APR_ENOSOCKET)
/** APR was not given a thread structure */
#define APR_STATUS_IS_ENOTHREAD(s)      ((s) == APR_ENOTHREAD)
/** APR was not given a thread key structure */
#define APR_STATUS_IS_ENOTHDKEY(s)      ((s) == APR_ENOTHDKEY)
/** Generic Error which can not be put into another spot */
#define APR_STATUS_IS_EGENERAL(s)       ((s) == APR_EGENERAL)
/** There is no more shared memory available */
#define APR_STATUS_IS_ENOSHMAVAIL(s)    ((s) == APR_ENOSHMAVAIL)
/** The specified IP address is invalid */
#define APR_STATUS_IS_EBADIP(s)         ((s) == APR_EBADIP)
/** The specified netmask is invalid */
#define APR_STATUS_IS_EBADMASK(s)       ((s) == APR_EBADMASK)
/* empty slot: +18 */
/**
 * APR was unable to open the dso object.
 * For more information call apr_dso_error().
 */
#if defined(WIN32)
#define APR_STATUS_IS_EDSOOPEN(s)       ((s) == APR_EDSOOPEN \
                       || APR_TO_OS_ERROR(s) == ERROR_MOD_NOT_FOUND)
#else
#define APR_STATUS_IS_EDSOOPEN(s)       ((s) == APR_EDSOOPEN)
#endif
/** The given path was absolute. */
#define APR_STATUS_IS_EABSOLUTE(s)      ((s) == APR_EABSOLUTE)
/** The given path was relative. */
#define APR_STATUS_IS_ERELATIVE(s)      ((s) == APR_ERELATIVE)
/** The given path was neither relative nor absolute. */
#define APR_STATUS_IS_EINCOMPLETE(s)    ((s) == APR_EINCOMPLETE)
/** The given path was above the root path. */
#define APR_STATUS_IS_EABOVEROOT(s)     ((s) == APR_EABOVEROOT)
/** The given path was bad. */
#define APR_STATUS_IS_EBADPATH(s)       ((s) == APR_EBADPATH)
/** The given path contained wildcards. */
#define APR_STATUS_IS_EPATHWILD(s)      ((s) == APR_EPATHWILD)
/** Could not find the requested symbol.
 * For more information call apr_dso_error().
 */
#if defined(WIN32)
#define APR_STATUS_IS_ESYMNOTFOUND(s)   ((s) == APR_ESYMNOTFOUND \
                       || APR_TO_OS_ERROR(s) == ERROR_PROC_NOT_FOUND)
#else
#define APR_STATUS_IS_ESYMNOTFOUND(s)   ((s) == APR_ESYMNOTFOUND)
#endif
/** The given process was not recognized by APR. */
#define APR_STATUS_IS_EPROC_UNKNOWN(s)  ((s) == APR_EPROC_UNKNOWN)
/** APR could not gather enough entropy to continue. */
#define APR_STATUS_IS_ENOTENOUGHENTROPY(s) ((s) == APR_ENOTENOUGHENTROPY)

/** @} */

/**
 * @addtogroup APR_Error
 * @{
 */
/** @see APR_STATUS_IS_INCHILD */
#define APR_INCHILD        (APR_OS_START_STATUS + 1)
/** @see APR_STATUS_IS_INPARENT */
#define APR_INPARENT       (APR_OS_START_STATUS + 2)
/** @see APR_STATUS_IS_DETACH */
#define APR_DETACH         (APR_OS_START_STATUS + 3)
/** @see APR_STATUS_IS_NOTDETACH */
#define APR_NOTDETACH      (APR_OS_START_STATUS + 4)
/** @see APR_STATUS_IS_CHILD_DONE */
#define APR_CHILD_DONE     (APR_OS_START_STATUS + 5)
/** @see APR_STATUS_IS_CHILD_NOTDONE */
#define APR_CHILD_NOTDONE  (APR_OS_START_STATUS + 6)
/** @see APR_STATUS_IS_TIMEUP */
#define APR_TIMEUP         (APR_OS_START_STATUS + 7)
/** @see APR_STATUS_IS_INCOMPLETE */
#define APR_INCOMPLETE     (APR_OS_START_STATUS + 8)
/* empty slot: +9 */
/* empty slot: +10 */
/* empty slot: +11 */
/** @see APR_STATUS_IS_BADCH */
#define APR_BADCH          (APR_OS_START_STATUS + 12)
/** @see APR_STATUS_IS_BADARG */
#define APR_BADARG         (APR_OS_START_STATUS + 13)
/** @see APR_STATUS_IS_EOF */
#define APR_EOF            (APR_OS_START_STATUS + 14)
/** @see APR_STATUS_IS_NOTFOUND */
#define APR_NOTFOUND       (APR_OS_START_STATUS + 15)
/* empty slot: +16 */
/* empty slot: +17 */
/* empty slot: +18 */
/** @see APR_STATUS_IS_ANONYMOUS */
#define APR_ANONYMOUS      (APR_OS_START_STATUS + 19)
/** @see APR_STATUS_IS_FILEBASED */
#define APR_FILEBASED      (APR_OS_START_STATUS + 20)
/** @see APR_STATUS_IS_KEYBASED */
#define APR_KEYBASED       (APR_OS_START_STATUS + 21)
/** @see APR_STATUS_IS_EINIT */
#define APR_EINIT          (APR_OS_START_STATUS + 22)
/** @see APR_STATUS_IS_ENOTIMPL */
#define APR_ENOTIMPL       (APR_OS_START_STATUS + 23)
/** @see APR_STATUS_IS_EMISMATCH */
#define APR_EMISMATCH      (APR_OS_START_STATUS + 24)
/** @see APR_STATUS_IS_EBUSY */
#define APR_EBUSY          (APR_OS_START_STATUS + 25)
/** @} */

/**
 * @addtogroup APR_STATUS_IS
 * @{
 */
/**
 * Program is currently executing in the child
 * @warning
 * always use this test, as platform-specific variances may meet this
 * more than one error code */
#define APR_STATUS_IS_INCHILD(s)        ((s) == APR_INCHILD)
/**
 * Program is currently executing in the parent
 * @warning
 * always use this test, as platform-specific variances may meet this
 * more than one error code
 */
#define APR_STATUS_IS_INPARENT(s)       ((s) == APR_INPARENT)
/**
 * The thread is detached
 * @warning
 * always use this test, as platform-specific variances may meet this
 * more than one error code
 */
#define APR_STATUS_IS_DETACH(s)         ((s) == APR_DETACH)
/**
 * The thread is not detached
 * @warning
 * always use this test, as platform-specific variances may meet this
 * more than one error code
 */
#define APR_STATUS_IS_NOTDETACH(s)      ((s) == APR_NOTDETACH)
/**
 * The child has finished executing
 * @warning
 * always use this test, as platform-specific variances may meet this
 * more than one error code
 */
#define APR_STATUS_IS_CHILD_DONE(s)     ((s) == APR_CHILD_DONE)
/**
 * The child has not finished executing
 * @warning
 * always use this test, as platform-specific variances may meet this
 * more than one error code
 */
#define APR_STATUS_IS_CHILD_NOTDONE(s)  ((s) == APR_CHILD_NOTDONE)
/**
 * The operation did not finish before the timeout
 * @warning
 * always use this test, as platform-specific variances may meet this
 * more than one error code
 */
#define APR_STATUS_IS_TIMEUP(s)         ((s) == APR_TIMEUP)
/**
 * The operation was incomplete although some processing was performed
 * and the results are partially valid.
 * @warning
 * always use this test, as platform-specific variances may meet this
 * more than one error code
 */
#define APR_STATUS_IS_INCOMPLETE(s)     ((s) == APR_INCOMPLETE)
/* empty slot: +9 */
/* empty slot: +10 */
/* empty slot: +11 */
/**
 * Getopt found an option not in the option string
 * @warning
 * always use this test, as platform-specific variances may meet this
 * more than one error code
 */
#define APR_STATUS_IS_BADCH(s)          ((s) == APR_BADCH)
/**
 * Getopt found an option not in the option string and an argument was
 * specified in the option string
 * @warning
 * always use this test, as platform-specific variances may meet this
 * more than one error code
 */
#define APR_STATUS_IS_BADARG(s)         ((s) == APR_BADARG)
/**
 * APR has encountered the end of the file
 * @warning
 * always use this test, as platform-specific variances may meet this
 * more than one error code
 */
#define APR_STATUS_IS_EOF(s)            ((s) == APR_EOF)
/**
 * APR was unable to find the socket in the poll structure
 * @warning
 * always use this test, as platform-specific variances may meet this
 * more than one error code
 */
#define APR_STATUS_IS_NOTFOUND(s)       ((s) == APR_NOTFOUND)
/* empty slot: +16 */
/* empty slot: +17 */
/* empty slot: +18 */
/**
 * APR is using anonymous shared memory
 * @warning
 * always use this test, as platform-specific variances may meet this
 * more than one error code
 */
#define APR_STATUS_IS_ANONYMOUS(s)      ((s) == APR_ANONYMOUS)
/**
 * APR is using a file name as the key to the shared memory
 * @warning
 * always use this test, as platform-specific variances may meet this
 * more than one error code
 */
#define APR_STATUS_IS_FILEBASED(s)      ((s) == APR_FILEBASED)
/**
 * APR is using a shared key as the key to the shared memory
 * @warning
 * always use this test, as platform-specific variances may meet this
 * more than one error code
 */
#define APR_STATUS_IS_KEYBASED(s)       ((s) == APR_KEYBASED)
/**
 * Ininitalizer value.  If no option has been found, but
 * the status variable requires a value, this should be used
 * @warning
 * always use this test, as platform-specific variances may meet this
 * more than one error code
 */
#define APR_STATUS_IS_EINIT(s)          ((s) == APR_EINIT)
/**
 * 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.
 * @warning
 * always use this test, as platform-specific variances may meet this
 * more than one error code
 */
#define APR_STATUS_IS_ENOTIMPL(s)       ((s) == APR_ENOTIMPL)
/**
 * Two passwords do not match.
 * @warning
 * always use this test, as platform-specific variances may meet this
 * more than one error code
 */
#define APR_STATUS_IS_EMISMATCH(s)      ((s) == APR_EMISMATCH)
/**
 * The given lock was busy
 * @warning always use this test, as platform-specific variances may meet this
 * more than one error code
 */
#define APR_STATUS_IS_EBUSY(s)          ((s) == APR_EBUSY)

/** @} */

/**
 * @addtogroup APR_Error APR Error Values
 * @{
 */
/* APR CANONICAL ERROR VALUES */
/** @see APR_STATUS_IS_EACCES */
#ifdef EACCES
#define APR_EACCES EACCES
#else
#define APR_EACCES         (APR_OS_START_CANONERR + 1)
#endif

/** @see APR_STATUS_IS_EEXIST */
#ifdef EEXIST
#define APR_EEXIST EEXIST
#else
#define APR_EEXIST         (APR_OS_START_CANONERR + 2)
#endif

/** @see APR_STATUS_IS_ENAMETOOLONG */
#ifdef ENAMETOOLONG
#define APR_ENAMETOOLONG ENAMETOOLONG
#else
#define APR_ENAMETOOLONG   (APR_OS_START_CANONERR + 3)
#endif

/** @see APR_STATUS_IS_ENOENT */
#ifdef ENOENT
#define APR_ENOENT ENOENT
#else
#define APR_ENOENT         (APR_OS_START_CANONERR + 4)
#endif

/** @see APR_STATUS_IS_ENOTDIR */
#ifdef ENOTDIR
#define APR_ENOTDIR ENOTDIR
#else
#define APR_ENOTDIR        (APR_OS_START_CANONERR + 5)
#endif

/** @see APR_STATUS_IS_ENOSPC */
#ifdef ENOSPC
#define APR_ENOSPC ENOSPC
#else
#define APR_ENOSPC         (APR_OS_START_CANONERR + 6)
#endif

/** @see APR_STATUS_IS_ENOMEM */
#ifdef ENOMEM
#define APR_ENOMEM ENOMEM
#else
#define APR_ENOMEM         (APR_OS_START_CANONERR + 7)
#endif

/** @see APR_STATUS_IS_EMFILE */
#ifdef EMFILE
#define APR_EMFILE EMFILE
#else
#define APR_EMFILE         (APR_OS_START_CANONERR + 8)
#endif

/** @see APR_STATUS_IS_ENFILE */
#ifdef ENFILE
#define APR_ENFILE ENFILE
#else
#define APR_ENFILE         (APR_OS_START_CANONERR + 9)
#endif

/** @see APR_STATUS_IS_EBADF */
#ifdef EBADF
#define APR_EBADF EBADF
#else
#define APR_EBADF          (APR_OS_START_CANONERR + 10)
#endif

/** @see APR_STATUS_IS_EINVAL */
#ifdef EINVAL
#define APR_EINVAL EINVAL
#else
#define APR_EINVAL         (APR_OS_START_CANONERR + 11)
#endif

/** @see APR_STATUS_IS_ESPIPE */
#ifdef ESPIPE
#define APR_ESPIPE ESPIPE
#else
#define APR_ESPIPE         (APR_OS_START_CANONERR + 12)
#endif

/**
 * @see APR_STATUS_IS_EAGAIN
 * @warning use APR_STATUS_IS_EAGAIN instead of just testing this value
 */
#ifdef EAGAIN
#define APR_EAGAIN EAGAIN
#elif defined(EWOULDBLOCK)
#define APR_EAGAIN EWOULDBLOCK
#else
#define APR_EAGAIN         (APR_OS_START_CANONERR + 13)
#endif

/** @see APR_STATUS_IS_EINTR */
#ifdef EINTR
#define APR_EINTR EINTR
#else
#define APR_EINTR          (APR_OS_START_CANONERR + 14)
#endif

/** @see APR_STATUS_IS_ENOTSOCK */
#ifdef ENOTSOCK
#define APR_ENOTSOCK ENOTSOCK
#else
#define APR_ENOTSOCK       (APR_OS_START_CANONERR + 15)
#endif

/** @see APR_STATUS_IS_ECONNREFUSED */
#ifdef ECONNREFUSED
#define APR_ECONNREFUSED ECONNREFUSED
#else
#define APR_ECONNREFUSED   (APR_OS_START_CANONERR + 16)
#endif

/** @see APR_STATUS_IS_EINPROGRESS */
#ifdef EINPROGRESS
#define APR_EINPROGRESS EINPROGRESS
#else
#define APR_EINPROGRESS    (APR_OS_START_CANONERR + 17)
#endif

/**
 * @see APR_STATUS_IS_ECONNABORTED
 * @warning use APR_STATUS_IS_ECONNABORTED instead of just testing this value
 */

#ifdef ECONNABORTED
#define APR_ECONNABORTED ECONNABORTED
#else
#define APR_ECONNABORTED   (APR_OS_START_CANONERR + 18)
#endif

/** @see APR_STATUS_IS_ECONNRESET */
#ifdef ECONNRESET
#define APR_ECONNRESET ECONNRESET
#else
#define APR_ECONNRESET     (APR_OS_START_CANONERR + 19)
#endif

/** @see APR_STATUS_IS_ETIMEDOUT
 *  @deprecated */
#ifdef ETIMEDOUT
#define APR_ETIMEDOUT ETIMEDOUT
#else
#define APR_ETIMEDOUT      (APR_OS_START_CANONERR + 20)
#endif

/** @see APR_STATUS_IS_EHOSTUNREACH */
#ifdef EHOSTUNREACH
#define APR_EHOSTUNREACH EHOSTUNREACH
#else
#define APR_EHOSTUNREACH   (APR_OS_START_CANONERR + 21)
#endif

/** @see APR_STATUS_IS_ENETUNREACH */
#ifdef ENETUNREACH
#define APR_ENETUNREACH ENETUNREACH
#else
#define APR_ENETUNREACH    (APR_OS_START_CANONERR + 22)
#endif

/** @see APR_STATUS_IS_EFTYPE */
#ifdef EFTYPE
#define APR_EFTYPE EFTYPE
#else
#define APR_EFTYPE        (APR_OS_START_CANONERR + 23)
#endif

/** @see APR_STATUS_IS_EPIPE */
#ifdef EPIPE
#define APR_EPIPE EPIPE
#else
#define APR_EPIPE         (APR_OS_START_CANONERR + 24)
#endif

/** @see APR_STATUS_IS_EXDEV */
#ifdef EXDEV
#define APR_EXDEV EXDEV
#else
#define APR_EXDEV         (APR_OS_START_CANONERR + 25)
#endif

/** @see APR_STATUS_IS_ENOTEMPTY */
#ifdef ENOTEMPTY
#define APR_ENOTEMPTY ENOTEMPTY
#else
#define APR_ENOTEMPTY     (APR_OS_START_CANONERR + 26)
#endif

/** @see APR_STATUS_IS_EAFNOSUPPORT */
#ifdef EAFNOSUPPORT
#define APR_EAFNOSUPPORT EAFNOSUPPORT
#else
#define APR_EAFNOSUPPORT  (APR_OS_START_CANONERR + 27)
#endif

/** @see APR_STATUS_IS_EOPNOTSUPP */
#ifdef EOPNOTSUPP
#define APR_EOPNOTSUPP EOPNOTSUPP
#else
#define APR_EOPNOTSUPP    (APR_OS_START_CANONERR + 28)
#endif

/** @see APR_STATUS_IS_ERANGE */
#ifdef ERANGE
#define APR_ERANGE ERANGE
#else
#define APR_ERANGE          (APR_OS_START_CANONERR + 29)
#endif

/** @} */

#if defined(OS2) && !defined(DOXYGEN)

#define APR_FROM_OS_ERROR(e) (e == 0 ? APR_SUCCESS : e + APR_OS_START_SYSERR)
#define APR_TO_OS_ERROR(e)   (e == 0 ? APR_SUCCESS : e - APR_OS_START_SYSERR)

#define INCL_DOSERRORS
#define INCL_DOS

/* Leave these undefined.
 * OS2 doesn't rely on the errno concept.
 * The API calls always return a result codes which
 * should be filtered through APR_FROM_OS_ERROR().
 *
 * #define apr_get_os_error()   (APR_FROM_OS_ERROR(GetLastError()))
 * #define apr_set_os_error(e)  (SetLastError(APR_TO_OS_ERROR(e)))
 */

/* A special case, only socket calls require this;
 */
#define apr_get_netos_error()   (APR_FROM_OS_ERROR(errno))
#define apr_set_netos_error(e)  (errno = APR_TO_OS_ERROR(e))

/* And this needs to be greped away for good:
 */
#define APR_OS2_STATUS(e) (APR_FROM_OS_ERROR(e))

/* These can't sit in a private header, so in spite of the extra size,
 * they need to be made available here.
 */
#define SOCBASEERR              10000
#define SOCEPERM                (SOCBASEERR+1)             /* Not owner */
#define SOCESRCH                (SOCBASEERR+3)             /* No such process */
#define SOCEINTR                (SOCBASEERR+4)             /* Interrupted system call */
#define SOCENXIO                (SOCBASEERR+6)             /* No such device or address */
#define SOCEBADF                (SOCBASEERR+9)             /* Bad file number */
#define SOCEACCES               (SOCBASEERR+13)            /* Permission denied */
#define SOCEFAULT               (SOCBASEERR+14)            /* Bad address */
#define SOCEINVAL               (SOCBASEERR+22)            /* Invalid argument */
#define SOCEMFILE               (SOCBASEERR+24)            /* Too many open files */
#define SOCEPIPE                (SOCBASEERR+32)            /* Broken pipe */
#define SOCEOS2ERR              (SOCBASEERR+100)           /* OS/2 Error */
#define SOCEWOULDBLOCK          (SOCBASEERR+35)            /* Operation would block */
#define SOCEINPROGRESS          (SOCBASEERR+36)            /* Operation now in progress */
#define SOCEALREADY             (SOCBASEERR+37)            /* Operation already in progress */
#define SOCENOTSOCK             (SOCBASEERR+38)            /* Socket operation on non-socket */
#define SOCEDESTADDRREQ         (SOCBASEERR+39)            /* Destination address required */
#define SOCEMSGSIZE             (SOCBASEERR+40)            /* Message too long */
#define SOCEPROTOTYPE           (SOCBASEERR+41)            /* Protocol wrong type for socket */
#define SOCENOPROTOOPT          (SOCBASEERR+42)            /* Protocol not available */
#define SOCEPROTONOSUPPORT      (SOCBASEERR+43)            /* Protocol not supported */
#define SOCESOCKTNOSUPPORT      (SOCBASEERR+44)            /* Socket type not supported */
#define SOCEOPNOTSUPP           (SOCBASEERR+45)            /* Operation not supported on socket */
#define SOCEPFNOSUPPORT         (SOCBASEERR+46)            /* Protocol family not supported */
#define SOCEAFNOSUPPORT         (SOCBASEERR+47)            /* Address family not supported by protocol family */
#define SOCEADDRINUSE           (SOCBASEERR+48)            /* Address already in use */
#define SOCEADDRNOTAVAIL        (SOCBASEERR+49)            /* Can't assign requested address */
#define SOCENETDOWN             (SOCBASEERR+50)            /* Network is down */
#define SOCENETUNREACH          (SOCBASEERR+51)            /* Network is unreachable */
#define SOCENETRESET            (SOCBASEERR+52)            /* Network dropped connection on reset */
#define SOCECONNABORTED         (SOCBASEERR+53)            /* Software caused connection abort */
#define SOCECONNRESET           (SOCBASEERR+54)            /* Connection reset by peer */
#define SOCENOBUFS              (SOCBASEERR+55)            /* No buffer space available */
#define SOCEISCONN              (SOCBASEERR+56)            /* Socket is already connected */
#define SOCENOTCONN             (SOCBASEERR+57)            /* Socket is not connected */
#define SOCESHUTDOWN            (SOCBASEERR+58)            /* Can't send after socket shutdown */
#define SOCETOOMANYREFS         (SOCBASEERR+59)            /* Too many references: can't splice */
#define SOCETIMEDOUT            (SOCBASEERR+60)            /* Connection timed out */
#define SOCECONNREFUSED         (SOCBASEERR+61)            /* Connection refused */
#define SOCELOOP                (SOCBASEERR+62)            /* Too many levels of symbolic links */
#define SOCENAMETOOLONG         (SOCBASEERR+63)            /* File name too long */
#define SOCEHOSTDOWN            (SOCBASEERR+64)            /* Host is down */
#define SOCEHOSTUNREACH         (SOCBASEERR+65)            /* No route to host */
#define SOCENOTEMPTY            (SOCBASEERR+66)            /* Directory not empty */

/* APR CANONICAL ERROR TESTS */
#define APR_STATUS_IS_EACCES(s)         ((s) == APR_EACCES \
                || (s) == APR_OS_START_SYSERR + ERROR_ACCESS_DENIED \
                || (s) == APR_OS_START_SYSERR + ERROR_SHARING_VIOLATION)
#define APR_STATUS_IS_EEXIST(s)         ((s) == APR_EEXIST \
                || (s) == APR_OS_START_SYSERR + ERROR_OPEN_FAILED \
                || (s) == APR_OS_START_SYSERR + ERROR_FILE_EXISTS \
                || (s) == APR_OS_START_SYSERR + ERROR_ALREADY_EXISTS \
                || (s) == APR_OS_START_SYSERR + ERROR_ACCESS_DENIED)
#define APR_STATUS_IS_ENAMETOOLONG(s)   ((s) == APR_ENAMETOOLONG \
                || (s) == APR_OS_START_SYSERR + ERROR_FILENAME_EXCED_RANGE \
                || (s) == APR_OS_START_SYSERR + SOCENAMETOOLONG)
#define APR_STATUS_IS_ENOENT(s)         ((s) == APR_ENOENT \
                || (s) == APR_OS_START_SYSERR + ERROR_FILE_NOT_FOUND \
                || (s) == APR_OS_START_SYSERR + ERROR_PATH_NOT_FOUND \
                || (s) == APR_OS_START_SYSERR + ERROR_NO_MORE_FILES \
                || (s) == APR_OS_START_SYSERR + ERROR_OPEN_FAILED)
#define APR_STATUS_IS_ENOTDIR(s)        ((s) == APR_ENOTDIR)
#define APR_STATUS_IS_ENOSPC(s)         ((s) == APR_ENOSPC \
                || (s) == APR_OS_START_SYSERR + ERROR_DISK_FULL)
#define APR_STATUS_IS_ENOMEM(s)         ((s) == APR_ENOMEM)
#define APR_STATUS_IS_EMFILE(s)         ((s) == APR_EMFILE \
                || (s) == APR_OS_START_SYSERR + ERROR_TOO_MANY_OPEN_FILES)
#define APR_STATUS_IS_ENFILE(s)         ((s) == APR_ENFILE)
#define APR_STATUS_IS_EBADF(s)          ((s) == APR_EBADF \
                || (s) == APR_OS_START_SYSERR + ERROR_INVALID_HANDLE)
#define APR_STATUS_IS_EINVAL(s)         ((s) == APR_EINVAL \
                || (s) == APR_OS_START_SYSERR + ERROR_INVALID_PARAMETER \
                || (s) == APR_OS_START_SYSERR + ERROR_INVALID_FUNCTION)
#define APR_STATUS_IS_ESPIPE(s)         ((s) == APR_ESPIPE \
                || (s) == APR_OS_START_SYSERR + ERROR_NEGATIVE_SEEK)
#define APR_STATUS_IS_EAGAIN(s)         ((s) == APR_EAGAIN \
                || (s) == APR_OS_START_SYSERR + ERROR_NO_DATA \
                || (s) == APR_OS_START_SYSERR + SOCEWOULDBLOCK \
                || (s) == APR_OS_START_SYSERR + ERROR_LOCK_VIOLATION)
#define APR_STATUS_IS_EINTR(s)          ((s) == APR_EINTR \
                || (s) == APR_OS_START_SYSERR + SOCEINTR)
#define APR_STATUS_IS_ENOTSOCK(s)       ((s) == APR_ENOTSOCK \
                || (s) == APR_OS_START_SYSERR + SOCENOTSOCK)
#define APR_STATUS_IS_ECONNREFUSED(s)   ((s) == APR_ECONNREFUSED \
                || (s) == APR_OS_START_SYSERR + SOCECONNREFUSED)
#define APR_STATUS_IS_EINPROGRESS(s)    ((s) == APR_EINPROGRESS \
                || (s) == APR_OS_START_SYSERR + SOCEINPROGRESS)
#define APR_STATUS_IS_ECONNABORTED(s)   ((s) == APR_ECONNABORTED \
                || (s) == APR_OS_START_SYSERR + SOCECONNABORTED)
#define APR_STATUS_IS_ECONNRESET(s)     ((s) == APR_ECONNRESET \
                || (s) == APR_OS_START_SYSERR + SOCECONNRESET)
/* XXX deprecated */
#define APR_STATUS_IS_ETIMEDOUT(s)         ((s) == APR_ETIMEDOUT \
                || (s) == APR_OS_START_SYSERR + SOCETIMEDOUT)
#undef APR_STATUS_IS_TIMEUP
#define APR_STATUS_IS_TIMEUP(s)         ((s) == APR_TIMEUP \
                || (s) == APR_OS_START_SYSERR + SOCETIMEDOUT)
#define APR_STATUS_IS_EHOSTUNREACH(s)   ((s) == APR_EHOSTUNREACH \
                || (s) == APR_OS_START_SYSERR + SOCEHOSTUNREACH)
#define APR_STATUS_IS_ENETUNREACH(s)    ((s) == APR_ENETUNREACH \
                || (s) == APR_OS_START_SYSERR + SOCENETUNREACH)
#define APR_STATUS_IS_EFTYPE(s)         ((s) == APR_EFTYPE)
#define APR_STATUS_IS_EPIPE(s)          ((s) == APR_EPIPE \
                || (s) == APR_OS_START_SYSERR + ERROR_BROKEN_PIPE \
                || (s) == APR_OS_START_SYSERR + SOCEPIPE)
#define APR_STATUS_IS_EXDEV(s)          ((s) == APR_EXDEV \
                || (s) == APR_OS_START_SYSERR + ERROR_NOT_SAME_DEVICE)
#define APR_STATUS_IS_ENOTEMPTY(s)      ((s) == APR_ENOTEMPTY \
                || (s) == APR_OS_START_SYSERR + ERROR_DIR_NOT_EMPTY \
                || (s) == APR_OS_START_SYSERR + ERROR_ACCESS_DENIED)
#define APR_STATUS_IS_EAFNOSUPPORT(s)   ((s) == APR_AFNOSUPPORT \
                || (s) == APR_OS_START_SYSERR + SOCEAFNOSUPPORT)
#define APR_STATUS_IS_EOPNOTSUPP(s)     ((s) == APR_EOPNOTSUPP \
                || (s) == APR_OS_START_SYSERR + SOCEOPNOTSUPP)
#define APR_STATUS_IS_ERANGE(s)         ((s) == APR_ERANGE)

/*
    Sorry, too tired to wrap this up for OS2... feel free to
    fit the following into their best matches.

    { ERROR_NO_SIGNAL_SENT,     ESRCH           },
    { SOCEALREADY,              EALREADY        },
    { SOCEDESTADDRREQ,          EDESTADDRREQ    },
    { SOCEMSGSIZE,              EMSGSIZE        },
    { SOCEPROTOTYPE,            EPROTOTYPE      },
    { SOCENOPROTOOPT,           ENOPROTOOPT     },
    { SOCEPROTONOSUPPORT,       EPROTONOSUPPORT },
    { SOCESOCKTNOSUPPORT,       ESOCKTNOSUPPORT },
    { SOCEPFNOSUPPORT,          EPFNOSUPPORT    },
    { SOCEADDRINUSE,            EADDRINUSE      },
    { SOCEADDRNOTAVAIL,         EADDRNOTAVAIL   },
    { SOCENETDOWN,              ENETDOWN        },
    { SOCENETRESET,             ENETRESET       },
    { SOCENOBUFS,               ENOBUFS         },
    { SOCEISCONN,               EISCONN         },
    { SOCENOTCONN,              ENOTCONN        },
    { SOCESHUTDOWN,             ESHUTDOWN       },
    { SOCETOOMANYREFS,          ETOOMANYREFS    },
    { SOCELOOP,                 ELOOP           },
    { SOCEHOSTDOWN,             EHOSTDOWN       },
    { SOCENOTEMPTY,             ENOTEMPTY       },
    { SOCEPIPE,                 EPIPE           }
*/

#elif defined(WIN32) && !defined(DOXYGEN) /* !defined(OS2) */

#define APR_FROM_OS_ERROR(e) (e == 0 ? APR_SUCCESS : e + APR_OS_START_SYSERR)
#define APR_TO_OS_ERROR(e)   (e == 0 ? APR_SUCCESS : e - APR_OS_START_SYSERR)

#define apr_get_os_error()   (APR_FROM_OS_ERROR(GetLastError()))
#define apr_set_os_error(e)  (SetLastError(APR_TO_OS_ERROR(e)))

/* A special case, only socket calls require this:
 */
#define apr_get_netos_error()   (APR_FROM_OS_ERROR(WSAGetLastError()))
#define apr_set_netos_error(e)   (WSASetLastError(APR_TO_OS_ERROR(e)))

/* APR CANONICAL ERROR TESTS */
#define APR_STATUS_IS_EACCES(s)         ((s) == APR_EACCES \
                || (s) == APR_OS_START_SYSERR + ERROR_ACCESS_DENIED \
                || (s) == APR_OS_START_SYSERR + ERROR_CANNOT_MAKE \
                || (s) == APR_OS_START_SYSERR + ERROR_CURRENT_DIRECTORY \
                || (s) == APR_OS_START_SYSERR + ERROR_DRIVE_LOCKED \
                || (s) == APR_OS_START_SYSERR + ERROR_FAIL_I24 \
                || (s) == APR_OS_START_SYSERR + ERROR_LOCK_VIOLATION \
                || (s) == APR_OS_START_SYSERR + ERROR_LOCK_FAILED \
                || (s) == APR_OS_START_SYSERR + ERROR_NOT_LOCKED \
                || (s) == APR_OS_START_SYSERR + ERROR_NETWORK_ACCESS_DENIED \
                || (s) == APR_OS_START_SYSERR + ERROR_SHARING_VIOLATION)
#define APR_STATUS_IS_EEXIST(s)         ((s) == APR_EEXIST \
                || (s) == APR_OS_START_SYSERR + ERROR_FILE_EXISTS \
                || (s) == APR_OS_START_SYSERR + ERROR_ALREADY_EXISTS)
#define APR_STATUS_IS_ENAMETOOLONG(s)   ((s) == APR_ENAMETOOLONG \
                || (s) == APR_OS_START_SYSERR + ERROR_FILENAME_EXCED_RANGE \
                || (s) == APR_OS_START_SYSERR + WSAENAMETOOLONG)
#define APR_STATUS_IS_ENOENT(s)         ((s) == APR_ENOENT \
                || (s) == APR_OS_START_SYSERR + ERROR_FILE_NOT_FOUND \
                || (s) == APR_OS_START_SYSERR + ERROR_PATH_NOT_FOUND \
                || (s) == APR_OS_START_SYSERR + ERROR_OPEN_FAILED \
                || (s) == APR_OS_START_SYSERR + ERROR_NO_MORE_FILES)
#define APR_STATUS_IS_ENOTDIR(s)        ((s) == APR_ENOTDIR \
                || (s) == APR_OS_START_SYSERR + ERROR_PATH_NOT_FOUND \
                || (s) == APR_OS_START_SYSERR + ERROR_BAD_NETPATH \
                || (s) == APR_OS_START_SYSERR + ERROR_BAD_NET_NAME \
                || (s) == APR_OS_START_SYSERR + ERROR_BAD_PATHNAME \
                || (s) == APR_OS_START_SYSERR + ERROR_INVALID_DRIVE \
                || (s) == APR_OS_START_SYSERR + ERROR_DIRECTORY)
#define APR_STATUS_IS_ENOSPC(s)         ((s) == APR_ENOSPC \
                || (s) == APR_OS_START_SYSERR + ERROR_DISK_FULL)
#define APR_STATUS_IS_ENOMEM(s)         ((s) == APR_ENOMEM \
                || (s) == APR_OS_START_SYSERR + ERROR_ARENA_TRASHED \
                || (s) == APR_OS_START_SYSERR + ERROR_NOT_ENOUGH_MEMORY \
                || (s) == APR_OS_START_SYSERR + ERROR_INVALID_BLOCK \
                || (s) == APR_OS_START_SYSERR + ERROR_NOT_ENOUGH_QUOTA \
                || (s) == APR_OS_START_SYSERR + ERROR_OUTOFMEMORY)
#define APR_STATUS_IS_EMFILE(s)         ((s) == APR_EMFILE \
                || (s) == APR_OS_START_SYSERR + ERROR_TOO_MANY_OPEN_FILES)
#define APR_STATUS_IS_ENFILE(s)         ((s) == APR_ENFILE)
#define APR_STATUS_IS_EBADF(s)          ((s) == APR_EBADF \
                || (s) == APR_OS_START_SYSERR + ERROR_INVALID_HANDLE \
                || (s) == APR_OS_START_SYSERR + ERROR_INVALID_TARGET_HANDLE)
#define APR_STATUS_IS_EINVAL(s)         ((s) == APR_EINVAL \
                || (s) == APR_OS_START_SYSERR + ERROR_INVALID_ACCESS \
                || (s) == APR_OS_START_SYSERR + ERROR_INVALID_DATA \
                || (s) == APR_OS_START_SYSERR + ERROR_INVALID_FUNCTION \
                || (s) == APR_OS_START_SYSERR + ERROR_INVALID_HANDLE \
                || (s) == APR_OS_START_SYSERR + ERROR_INVALID_PARAMETER \
                || (s) == APR_OS_START_SYSERR + ERROR_NEGATIVE_SEEK)
#define APR_STATUS_IS_ESPIPE(s)         ((s) == APR_ESPIPE \
                || (s) == APR_OS_START_SYSERR + ERROR_SEEK_ON_DEVICE \
                || (s) == APR_OS_START_SYSERR + ERROR_NEGATIVE_SEEK)
#define APR_STATUS_IS_EAGAIN(s)         ((s) == APR_EAGAIN \
                || (s) == APR_OS_START_SYSERR + ERROR_NO_DATA \
                || (s) == APR_OS_START_SYSERR + ERROR_NO_PROC_SLOTS \
                || (s) == APR_OS_START_SYSERR + ERROR_NESTING_NOT_ALLOWED \
                || (s) == APR_OS_START_SYSERR + ERROR_MAX_THRDS_REACHED \
                || (s) == APR_OS_START_SYSERR + ERROR_LOCK_VIOLATION \
                || (s) == APR_OS_START_SYSERR + WSAEWOULDBLOCK)
#define APR_STATUS_IS_EINTR(s)          ((s) == APR_EINTR \
                || (s) == APR_OS_START_SYSERR + WSAEINTR)
#define APR_STATUS_IS_ENOTSOCK(s)       ((s) == APR_ENOTSOCK \
                || (s) == APR_OS_START_SYSERR + WSAENOTSOCK)
#define APR_STATUS_IS_ECONNREFUSED(s)   ((s) == APR_ECONNREFUSED \
                || (s) == APR_OS_START_SYSERR + WSAECONNREFUSED)
#define APR_STATUS_IS_EINPROGRESS(s)    ((s) == APR_EINPROGRESS \
                || (s) == APR_OS_START_SYSERR + WSAEINPROGRESS)
#define APR_STATUS_IS_ECONNABORTED(s)   ((s) == APR_ECONNABORTED \
                || (s) == APR_OS_START_SYSERR + WSAECONNABORTED)
#define APR_STATUS_IS_ECONNRESET(s)     ((s) == APR_ECONNRESET \
                || (s) == APR_OS_START_SYSERR + ERROR_NETNAME_DELETED \
                || (s) == APR_OS_START_SYSERR + WSAECONNRESET)
/* XXX deprecated */
#define APR_STATUS_IS_ETIMEDOUT(s)         ((s) == APR_ETIMEDOUT \
                || (s) == APR_OS_START_SYSERR + WSAETIMEDOUT \
                || (s) == APR_OS_START_SYSERR + WAIT_TIMEOUT)
#undef APR_STATUS_IS_TIMEUP
#define APR_STATUS_IS_TIMEUP(s)         ((s) == APR_TIMEUP \
                || (s) == APR_OS_START_SYSERR + WSAETIMEDOUT \
                || (s) == APR_OS_START_SYSERR + WAIT_TIMEOUT)
#define APR_STATUS_IS_EHOSTUNREACH(s)   ((s) == APR_EHOSTUNREACH \
                || (s) == APR_OS_START_SYSERR + WSAEHOSTUNREACH)
#define APR_STATUS_IS_ENETUNREACH(s)    ((s) == APR_ENETUNREACH \
                || (s) == APR_OS_START_SYSERR + WSAENETUNREACH)
#define APR_STATUS_IS_EFTYPE(s)         ((s) == APR_EFTYPE \
                || (s) == APR_OS_START_SYSERR + ERROR_EXE_MACHINE_TYPE_MISMATCH \
                || (s) == APR_OS_START_SYSERR + ERROR_INVALID_DLL \
                || (s) == APR_OS_START_SYSERR + ERROR_INVALID_MODULETYPE \
                || (s) == APR_OS_START_SYSERR + ERROR_BAD_EXE_FORMAT \
                || (s) == APR_OS_START_SYSERR + ERROR_INVALID_EXE_SIGNATURE \
                || (s) == APR_OS_START_SYSERR + ERROR_FILE_CORRUPT \
                || (s) == APR_OS_START_SYSERR + ERROR_BAD_FORMAT)
#define APR_STATUS_IS_EPIPE(s)          ((s) == APR_EPIPE \
                || (s) == APR_OS_START_SYSERR + ERROR_BROKEN_PIPE)
#define APR_STATUS_IS_EXDEV(s)          ((s) == APR_EXDEV \
                || (s) == APR_OS_START_SYSERR + ERROR_NOT_SAME_DEVICE)
#define APR_STATUS_IS_ENOTEMPTY(s)      ((s) == APR_ENOTEMPTY \
                || (s) == APR_OS_START_SYSERR + ERROR_DIR_NOT_EMPTY)
#define APR_STATUS_IS_EAFNOSUPPORT(s)   ((s) == APR_EAFNOSUPPORT \
                || (s) == APR_OS_START_SYSERR + WSAEAFNOSUPPORT)
#define APR_STATUS_IS_EOPNOTSUPP(s)     ((s) == APR_EOPNOTSUPP \
                || (s) == APR_OS_START_SYSERR + WSAEOPNOTSUPP)
#define APR_STATUS_IS_ERANGE(s)         ((s) == APR_ERANGE)

#elif defined(NETWARE) && defined(USE_WINSOCK) && !defined(DOXYGEN) /* !defined(OS2) && !defined(WIN32) */

#define APR_FROM_OS_ERROR(e) (e == 0 ? APR_SUCCESS : e + APR_OS_START_SYSERR)
#define APR_TO_OS_ERROR(e)   (e == 0 ? APR_SUCCESS : e - APR_OS_START_SYSERR)

#define apr_get_os_error()    (errno)
#define apr_set_os_error(e)   (errno = (e))

/* A special case, only socket calls require this: */
#define apr_get_netos_error()   (APR_FROM_OS_ERROR(WSAGetLastError()))
#define apr_set_netos_error(e)  (WSASetLastError(APR_TO_OS_ERROR(e)))

/* APR CANONICAL ERROR TESTS */
#define APR_STATUS_IS_EACCES(s)         ((s) == APR_EACCES)
#define APR_STATUS_IS_EEXIST(s)         ((s) == APR_EEXIST)
#define APR_STATUS_IS_ENAMETOOLONG(s)   ((s) == APR_ENAMETOOLONG)
#define APR_STATUS_IS_ENOENT(s)         ((s) == APR_ENOENT)
#define APR_STATUS_IS_ENOTDIR(s)        ((s) == APR_ENOTDIR)
#define APR_STATUS_IS_ENOSPC(s)         ((s) == APR_ENOSPC)
#define APR_STATUS_IS_ENOMEM(s)         ((s) == APR_ENOMEM)
#define APR_STATUS_IS_EMFILE(s)         ((s) == APR_EMFILE)
#define APR_STATUS_IS_ENFILE(s)         ((s) == APR_ENFILE)
#define APR_STATUS_IS_EBADF(s)          ((s) == APR_EBADF)
#define APR_STATUS_IS_EINVAL(s)         ((s) == APR_EINVAL)
#define APR_STATUS_IS_ESPIPE(s)         ((s) == APR_ESPIPE)

#define APR_STATUS_IS_EAGAIN(s)         ((s) == APR_EAGAIN \
                || (s) ==                       EWOULDBLOCK \
                || (s) == APR_OS_START_SYSERR + WSAEWOULDBLOCK)
#define APR_STATUS_IS_EINTR(s)          ((s) == APR_EINTR \
                || (s) == APR_OS_START_SYSERR + WSAEINTR)
#define APR_STATUS_IS_ENOTSOCK(s)       ((s) == APR_ENOTSOCK \
                || (s) == APR_OS_START_SYSERR + WSAENOTSOCK)
#define APR_STATUS_IS_ECONNREFUSED(s)   ((s) == APR_ECONNREFUSED \
                || (s) == APR_OS_START_SYSERR + WSAECONNREFUSED)
#define APR_STATUS_IS_EINPROGRESS(s)    ((s) == APR_EINPROGRESS \
                || (s) == APR_OS_START_SYSERR + WSAEINPROGRESS)
#define APR_STATUS_IS_ECONNABORTED(s)   ((s) == APR_ECONNABORTED \
                || (s) == APR_OS_START_SYSERR + WSAECONNABORTED)
#define APR_STATUS_IS_ECONNRESET(s)     ((s) == APR_ECONNRESET \
                || (s) == APR_OS_START_SYSERR + WSAECONNRESET)
/* XXX deprecated */
#define APR_STATUS_IS_ETIMEDOUT(s)       ((s) == APR_ETIMEDOUT \
                || (s) == APR_OS_START_SYSERR + WSAETIMEDOUT \
                || (s) == APR_OS_START_SYSERR + WAIT_TIMEOUT)
#undef APR_STATUS_IS_TIMEUP
#define APR_STATUS_IS_TIMEUP(s)         ((s) == APR_TIMEUP \
                || (s) == APR_OS_START_SYSERR + WSAETIMEDOUT \
                || (s) == APR_OS_START_SYSERR + WAIT_TIMEOUT)
#define APR_STATUS_IS_EHOSTUNREACH(s)   ((s) == APR_EHOSTUNREACH \
                || (s) == APR_OS_START_SYSERR + WSAEHOSTUNREACH)
#define APR_STATUS_IS_ENETUNREACH(s)    ((s) == APR_ENETUNREACH \
                || (s) == APR_OS_START_SYSERR + WSAENETUNREACH)
#define APR_STATUS_IS_ENETDOWN(s)       ((s) == APR_OS_START_SYSERR + WSAENETDOWN)
#define APR_STATUS_IS_EFTYPE(s)         ((s) == APR_EFTYPE)
#define APR_STATUS_IS_EPIPE(s)          ((s) == APR_EPIPE)
#define APR_STATUS_IS_EXDEV(s)          ((s) == APR_EXDEV)
#define APR_STATUS_IS_ENOTEMPTY(s)      ((s) == APR_ENOTEMPTY)
#define APR_STATUS_IS_EAFNOSUPPORT(s)   ((s) == APR_EAFNOSUPPORT \
                || (s) == APR_OS_START_SYSERR + WSAEAFNOSUPPORT)
#define APR_STATUS_IS_EOPNOTSUPP(s)     ((s) == APR_EOPNOTSUPP \
                || (s) == APR_OS_START_SYSERR + WSAEOPNOTSUPP)
#define APR_STATUS_IS_ERANGE(s)         ((s) == APR_ERANGE)

#else /* !defined(NETWARE) && !defined(OS2) && !defined(WIN32) */

/*
 *  os error codes are clib error codes
 */
#define APR_FROM_OS_ERROR(e)  (e)
#define APR_TO_OS_ERROR(e)    (e)

#define apr_get_os_error()    (errno)
#define apr_set_os_error(e)   (errno = (e))

/* A special case, only socket calls require this:
 */
#define apr_get_netos_error() (errno)
#define apr_set_netos_error(e) (errno = (e))

/**
 * @addtogroup APR_STATUS_IS
 * @{
 */

/** permission denied */
#define APR_STATUS_IS_EACCES(s)         ((s) == APR_EACCES)
/** file exists */
#define APR_STATUS_IS_EEXIST(s)         ((s) == APR_EEXIST)
/** path name is too long */
#define APR_STATUS_IS_ENAMETOOLONG(s)   ((s) == APR_ENAMETOOLONG)
/**
 * no such file or directory
 * @remark
 * EMVSCATLG can be returned by the automounter on z/OS for
 * paths which do not exist.
 */
#ifdef EMVSCATLG
#define APR_STATUS_IS_ENOENT(s)         ((s) == APR_ENOENT \
                                      || (s) == EMVSCATLG)
#else
#define APR_STATUS_IS_ENOENT(s)         ((s) == APR_ENOENT)
#endif
/** not a directory */
#define APR_STATUS_IS_ENOTDIR(s)        ((s) == APR_ENOTDIR)
/** no space left on device */
#ifdef EDQUOT
#define APR_STATUS_IS_ENOSPC(s)         ((s) == APR_ENOSPC \
                                      || (s) == EDQUOT)
#else
#define APR_STATUS_IS_ENOSPC(s)         ((s) == APR_ENOSPC)
#endif
/** not enough memory */
#define APR_STATUS_IS_ENOMEM(s)         ((s) == APR_ENOMEM)
/** too many open files */
#define APR_STATUS_IS_EMFILE(s)         ((s) == APR_EMFILE)
/** file table overflow */
#define APR_STATUS_IS_ENFILE(s)         ((s) == APR_ENFILE)
/** bad file # */
#define APR_STATUS_IS_EBADF(s)          ((s) == APR_EBADF)
/** invalid argument */
#define APR_STATUS_IS_EINVAL(s)         ((s) == APR_EINVAL)
/** illegal seek */
#define APR_STATUS_IS_ESPIPE(s)         ((s) == APR_ESPIPE)

/** operation would block */
#if !defined(EWOULDBLOCK) || !defined(EAGAIN)
#define APR_STATUS_IS_EAGAIN(s)         ((s) == APR_EAGAIN)
#elif (EWOULDBLOCK == EAGAIN)
#define APR_STATUS_IS_EAGAIN(s)         ((s) == APR_EAGAIN)
#else
#define APR_STATUS_IS_EAGAIN(s)         ((s) == APR_EAGAIN \
                                      || (s) == EWOULDBLOCK)
#endif

/** interrupted system call */
#define APR_STATUS_IS_EINTR(s)          ((s) == APR_EINTR)
/** socket operation on a non-socket */
#define APR_STATUS_IS_ENOTSOCK(s)       ((s) == APR_ENOTSOCK)
/** Connection Refused */
#define APR_STATUS_IS_ECONNREFUSED(s)   ((s) == APR_ECONNREFUSED)
/** operation now in progress */
#define APR_STATUS_IS_EINPROGRESS(s)    ((s) == APR_EINPROGRESS)

/**
 * Software caused connection abort
 * @remark
 * EPROTO on certain older kernels really means ECONNABORTED, so we need to
 * ignore it for them.  See discussion in new-httpd archives nh.9701 & nh.9603
 *
 * There is potentially a bug in Solaris 2.x x<6, and other boxes that
 * implement tcp sockets in userland (i.e. on top of STREAMS).  On these
 * systems, EPROTO can actually result in a fatal loop.  See PR#981 for
 * example.  It's hard to handle both uses of EPROTO.
 */
#ifdef EPROTO
#define APR_STATUS_IS_ECONNABORTED(s)    ((s) == APR_ECONNABORTED \
                                       || (s) == EPROTO)
#else
#define APR_STATUS_IS_ECONNABORTED(s)    ((s) == APR_ECONNABORTED)
#endif

/** Connection Reset by peer */
#define APR_STATUS_IS_ECONNRESET(s)      ((s) == APR_ECONNRESET)
/** Operation timed out
 *  @deprecated */
#define APR_STATUS_IS_ETIMEDOUT(s)      ((s) == APR_ETIMEDOUT)
/** no route to host */
#define APR_STATUS_IS_EHOSTUNREACH(s)    ((s) == APR_EHOSTUNREACH)
/** network is unreachable */
#define APR_STATUS_IS_ENETUNREACH(s)     ((s) == APR_ENETUNREACH)
/** inappropriate file type or format */
#define APR_STATUS_IS_EFTYPE(s)          ((s) == APR_EFTYPE)
/** broken pipe */
#define APR_STATUS_IS_EPIPE(s)           ((s) == APR_EPIPE)
/** cross device link */
#define APR_STATUS_IS_EXDEV(s)           ((s) == APR_EXDEV)
/** Directory Not Empty */
#define APR_STATUS_IS_ENOTEMPTY(s)       ((s) == APR_ENOTEMPTY || \
                                          (s) == APR_EEXIST)
/** Address Family not supported */
#define APR_STATUS_IS_EAFNOSUPPORT(s)    ((s) == APR_EAFNOSUPPORT)
/** Socket operation not supported */
#define APR_STATUS_IS_EOPNOTSUPP(s)      ((s) == APR_EOPNOTSUPP)

/** Numeric value not representable */
#define APR_STATUS_IS_ERANGE(s)         ((s) == APR_ERANGE)
/** @} */

#endif /* !defined(NETWARE) && !defined(OS2) && !defined(WIN32) */

/** @} */

#ifdef __cplusplus
}
#endif

#endif  /* ! APR_ERRNO_H */
apr-1/apr_user.h000064400000012276151730340530007466 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_USER_H
#define APR_USER_H

/**
 * @file apr_user.h
 * @brief APR User ID Services 
 */

#include "apr.h"
#include "apr_errno.h"
#include "apr_pools.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @defgroup apr_user User and Group ID Services
 * @ingroup APR 
 * @{
 */

/**
 * Structure for determining user ownership.
 */
#ifdef WIN32
typedef PSID                      apr_uid_t;
#else
typedef uid_t                     apr_uid_t;
#endif

/**
 * Structure for determining group ownership.
 */
#ifdef WIN32
typedef PSID                      apr_gid_t;
#else
typedef gid_t                     apr_gid_t;
#endif

#if APR_HAS_USER 

/**
 * Get the userid (and groupid) of the calling process
 * @param userid   Returns the user id
 * @param groupid  Returns the user's group id
 * @param p The pool from which to allocate working space
 * @remark This function is available only if APR_HAS_USER is defined.
 */
APR_DECLARE(apr_status_t) apr_uid_current(apr_uid_t *userid,
                                          apr_gid_t *groupid,
                                          apr_pool_t *p);

/**
 * Get the user name for a specified userid
 * @param username Pointer to new string containing user name (on output)
 * @param userid The userid
 * @param p The pool from which to allocate the string
 * @remark This function is available only if APR_HAS_USER is defined.
 */
APR_DECLARE(apr_status_t) apr_uid_name_get(char **username, apr_uid_t userid,
                                           apr_pool_t *p);

/**
 * Get the userid (and groupid) for the specified username
 * @param userid   Returns the user id
 * @param groupid  Returns the user's group id
 * @param username The username to look up
 * @param p The pool from which to allocate working space
 * @remark This function is available only if APR_HAS_USER is defined.
 */
APR_DECLARE(apr_status_t) apr_uid_get(apr_uid_t *userid, apr_gid_t *groupid,
                                      const char *username, apr_pool_t *p);

/**
 * Get the home directory for the named user
 * @param dirname Pointer to new string containing directory name (on output)
 * @param username The named user
 * @param p The pool from which to allocate the string
 * @remark This function is available only if APR_HAS_USER is defined.
 */
APR_DECLARE(apr_status_t) apr_uid_homepath_get(char **dirname, 
                                               const char *username, 
                                               apr_pool_t *p);

/**
 * Compare two user identifiers for equality.
 * @param left One uid to test
 * @param right Another uid to test
 * @return APR_SUCCESS if the apr_uid_t structures identify the same user,
 * APR_EMISMATCH if not, APR_BADARG if an apr_uid_t is invalid.
 * @remark This function is available only if APR_HAS_USER is defined.
 */
#if defined(WIN32)
APR_DECLARE(apr_status_t) apr_uid_compare(apr_uid_t left, apr_uid_t right);
#else
#define apr_uid_compare(left,right) (((left) == (right)) ? APR_SUCCESS : APR_EMISMATCH)
#endif

/**
 * Get the group name for a specified groupid
 * @param groupname Pointer to new string containing group name (on output)
 * @param groupid The groupid
 * @param p The pool from which to allocate the string
 * @remark This function is available only if APR_HAS_USER is defined.
 */
APR_DECLARE(apr_status_t) apr_gid_name_get(char **groupname, 
                                             apr_gid_t groupid, apr_pool_t *p);

/**
 * Get the groupid for a specified group name
 * @param groupid Pointer to the group id (on output)
 * @param groupname The group name to look up
 * @param p The pool from which to allocate the string
 * @remark This function is available only if APR_HAS_USER is defined.
 */
APR_DECLARE(apr_status_t) apr_gid_get(apr_gid_t *groupid, 
                                      const char *groupname, apr_pool_t *p);

/**
 * Compare two group identifiers for equality.
 * @param left One gid to test
 * @param right Another gid to test
 * @return APR_SUCCESS if the apr_gid_t structures identify the same group,
 * APR_EMISMATCH if not, APR_BADARG if an apr_gid_t is invalid.
 * @remark This function is available only if APR_HAS_USER is defined.
 */
#if defined(WIN32)
APR_DECLARE(apr_status_t) apr_gid_compare(apr_gid_t left, apr_gid_t right);
#else
#define apr_gid_compare(left,right) (((left) == (right)) ? APR_SUCCESS : APR_EMISMATCH)
#endif

#endif  /* ! APR_HAS_USER */

/** @} */

#ifdef __cplusplus
}
#endif

#endif  /* ! APR_USER_H */
apr-1/apr_hooks.h000064400000030564151730340530007633 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_HOOKS_H
#define APR_HOOKS_H

#include "apu.h"
/* For apr_array_header_t */
#include "apr_tables.h"

/**
 * @file apr_hooks.h
 * @brief Apache hook functions
 */

#ifdef __cplusplus
extern "C" {
#endif
/**
 * @defgroup APR_Util_Hook Hook Functions
 * @ingroup APR_Util
 * @{
 */

/**
 * @defgroup apr_hook_probes Hook probe capability
 * APR hooks provide a trace probe capability for capturing
 * the flow of control and return values with hooks.
 *
 * In order to use this facility, the application must define
 * the symbol APR_HOOK_PROBES_ENABLED and the four APR_HOOK_PROBE_
 * macros described below before including apr_hooks.h in files
 * that use the APR_IMPLEMENT_EXTERNAL_HOOK_* macros.
 *
 * This probe facility is not provided for APR optional hooks.
 * @{
 */

#ifdef APR_HOOK_PROBES_ENABLED
#define APR_HOOK_INT_DCL_UD void *ud = NULL
#else
/** internal implementation detail to avoid the ud declaration when
 * hook probes are not used
 */
#define APR_HOOK_INT_DCL_UD
/**
 * User-defined hook probe macro that is invoked when the hook
 * is run, before calling any hook functions.
 * @param ud A void * user data field that should be filled in by
 * this macro, and will be provided to the other hook probe macros.
 * @param ns The namespace prefix of the hook functions
 * @param name The name of the hook
 * @param args The argument list to the hook functions, with enclosing
 * parens.
 */
#define APR_HOOK_PROBE_ENTRY(ud,ns,name,args)
/**
 * User-defined hook probe macro that is invoked after the hook
 * has run.
 * @param ud A void * user data field that was filled in by the user-
 * provided APR_HOOK_PROBE_ENTRY().
 * @param ns The namespace prefix of the hook functions
 * @param name The name of the hook
 * @param rv The return value of the hook, or 0 if the hook is void.
 * @param args The argument list to the hook functions, with enclosing
 * parens.
 */
#define APR_HOOK_PROBE_RETURN(ud,ns,name,rv,args)
/**
 * User-defined hook probe macro that is invoked before calling a
 * hook function.
 * @param ud A void * user data field that was filled in by the user-
 * provided APR_HOOK_PROBE_ENTRY().
 * @param ns The namespace prefix of the hook functions
 * @param name The name of the hook
 * @param src The value of apr_hook_debug_current at the time the function
 * was hooked (usually the source file implementing the hook function).
 * @param args The argument list to the hook functions, with enclosing
 * parens.
 */
#define APR_HOOK_PROBE_INVOKE(ud,ns,name,src,args)
/**
 * User-defined hook probe macro that is invoked after calling a
 * hook function.
 * @param ud A void * user data field that was filled in by the user-
 * provided APR_HOOK_PROBE_ENTRY().
 * @param ns The namespace prefix of the hook functions
 * @param name The name of the hook
 * @param src The value of apr_hook_debug_current at the time the function
 * was hooked (usually the source file implementing the hook function).
 * @param rv The return value of the hook function, or 0 if the hook is void.
 * @param args The argument list to the hook functions, with enclosing
 * parens.
 */
#define APR_HOOK_PROBE_COMPLETE(ud,ns,name,src,rv,args)
#endif

/** @} */

/** macro to return the prototype of the hook function */    
#define APR_IMPLEMENT_HOOK_GET_PROTO(ns,link,name) \
link##_DECLARE(apr_array_header_t *) ns##_hook_get_##name(void)

/** macro to declare the hook correctly */    
#define APR_DECLARE_EXTERNAL_HOOK(ns,link,ret,name,args) \
typedef ret ns##_HOOK_##name##_t args; \
link##_DECLARE(void) ns##_hook_##name(ns##_HOOK_##name##_t *pf, \
                                      const char * const *aszPre, \
                                      const char * const *aszSucc, int nOrder); \
link##_DECLARE(ret) ns##_run_##name args; \
APR_IMPLEMENT_HOOK_GET_PROTO(ns,link,name); \
typedef struct ns##_LINK_##name##_t \
    { \
    ns##_HOOK_##name##_t *pFunc; \
    const char *szName; \
    const char * const *aszPredecessors; \
    const char * const *aszSuccessors; \
    int nOrder; \
    } ns##_LINK_##name##_t;

/** macro to declare the hook structure */    
#define APR_HOOK_STRUCT(members) \
static struct { members } _hooks;

/** macro to link the hook structure */
#define APR_HOOK_LINK(name) \
    apr_array_header_t *link_##name;

/** macro to implement the hook */
#define APR_IMPLEMENT_EXTERNAL_HOOK_BASE(ns,link,name) \
link##_DECLARE(void) ns##_hook_##name(ns##_HOOK_##name##_t *pf,const char * const *aszPre, \
                                      const char * const *aszSucc,int nOrder) \
    { \
    ns##_LINK_##name##_t *pHook; \
    if(!_hooks.link_##name) \
	{ \
	_hooks.link_##name=apr_array_make(apr_hook_global_pool,1,sizeof(ns##_LINK_##name##_t)); \
	apr_hook_sort_register(#name,&_hooks.link_##name); \
	} \
    pHook=apr_array_push(_hooks.link_##name); \
    pHook->pFunc=pf; \
    pHook->aszPredecessors=aszPre; \
    pHook->aszSuccessors=aszSucc; \
    pHook->nOrder=nOrder; \
    pHook->szName=apr_hook_debug_current; \
    if(apr_hook_debug_enabled) \
	apr_hook_debug_show(#name,aszPre,aszSucc); \
    } \
    APR_IMPLEMENT_HOOK_GET_PROTO(ns,link,name) \
    { \
        return _hooks.link_##name; \
    }

/**
 * Implement a hook that has no return code, and therefore runs all of the
 * registered functions
 * @param ns The namespace prefix of the hook functions
 * @param link The linkage declaration prefix of the hook
 * @param name The name of the hook
 * @param args_decl The declaration of the arguments for the hook
 * @param args_use The names for the arguments for the hook
 * @note The link prefix FOO corresponds to FOO_DECLARE() macros, which
 * provide export linkage from the module that IMPLEMENTs the hook, and
 * import linkage from external modules that link to the hook's module.
 */
#define APR_IMPLEMENT_EXTERNAL_HOOK_VOID(ns,link,name,args_decl,args_use) \
APR_IMPLEMENT_EXTERNAL_HOOK_BASE(ns,link,name) \
link##_DECLARE(void) ns##_run_##name args_decl \
    { \
    ns##_LINK_##name##_t *pHook; \
    int n; \
    APR_HOOK_INT_DCL_UD; \
\
    APR_HOOK_PROBE_ENTRY(ud, ns, name, args_use); \
\
    if(_hooks.link_##name) \
        { \
        pHook=(ns##_LINK_##name##_t *)_hooks.link_##name->elts; \
        for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \
            { \
            APR_HOOK_PROBE_INVOKE(ud, ns, name, (char *)pHook[n].szName, args_use); \
	    pHook[n].pFunc args_use; \
            APR_HOOK_PROBE_COMPLETE(ud, ns, name, (char *)pHook[n].szName, 0, args_use); \
            } \
        } \
\
    APR_HOOK_PROBE_RETURN(ud, ns, name, 0, args_use); \
\
    }

/* FIXME: note that this returns ok when nothing is run. I suspect it should
   really return decline, but that breaks Apache currently - Ben
*/
/**
 * Implement a hook that runs until one of the functions returns something
 * other than OK or DECLINE
 * @param ns The namespace prefix of the hook functions
 * @param link The linkage declaration prefix of the hook
 * @param ret Type to return
 * @param name The name of the hook
 * @param args_decl The declaration of the arguments for the hook
 * @param args_use The names for the arguments for the hook
 * @param ok Success value
 * @param decline Decline value
 * @note The link prefix FOO corresponds to FOO_DECLARE() macros, which
 * provide export linkage from the module that IMPLEMENTs the hook, and
 * import linkage from external modules that link to the hook's module.
 */
#define APR_IMPLEMENT_EXTERNAL_HOOK_RUN_ALL(ns,link,ret,name,args_decl,args_use,ok,decline) \
APR_IMPLEMENT_EXTERNAL_HOOK_BASE(ns,link,name) \
link##_DECLARE(ret) ns##_run_##name args_decl \
    { \
    ns##_LINK_##name##_t *pHook; \
    int n; \
    ret rv = ok; \
    APR_HOOK_INT_DCL_UD; \
\
    APR_HOOK_PROBE_ENTRY(ud, ns, name, args_use); \
\
    if(_hooks.link_##name) \
        { \
        pHook=(ns##_LINK_##name##_t *)_hooks.link_##name->elts; \
        for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \
            { \
            APR_HOOK_PROBE_INVOKE(ud, ns, name, (char *)pHook[n].szName, args_use); \
            rv=pHook[n].pFunc args_use; \
            APR_HOOK_PROBE_COMPLETE(ud, ns, name, (char *)pHook[n].szName, rv, args_use); \
            if(rv != ok && rv != decline) \
                break; \
            rv = ok; \
            } \
        } \
\
    APR_HOOK_PROBE_RETURN(ud, ns, name, rv, args_use); \
\
    return rv; \
    }


/**
 * Implement a hook that runs until the first function returns something
 * other than the value of decline
 * @param ns The namespace prefix of the hook functions
 * @param link The linkage declaration prefix of the hook
 * @param name The name of the hook
 * @param ret Type to return
 * @param args_decl The declaration of the arguments for the hook
 * @param args_use The names for the arguments for the hook
 * @param decline Decline value
 * @note The link prefix FOO corresponds to FOO_DECLARE() macros, which
 * provide export linkage from the module that IMPLEMENTs the hook, and
 * import linkage from external modules that link to the hook's module.
 */
#define APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(ns,link,ret,name,args_decl,args_use,decline) \
APR_IMPLEMENT_EXTERNAL_HOOK_BASE(ns,link,name) \
link##_DECLARE(ret) ns##_run_##name args_decl \
    { \
    ns##_LINK_##name##_t *pHook; \
    int n; \
    ret rv = decline; \
    APR_HOOK_INT_DCL_UD; \
\
    APR_HOOK_PROBE_ENTRY(ud, ns, name, args_use); \
\
    if(_hooks.link_##name) \
        { \
        pHook=(ns##_LINK_##name##_t *)_hooks.link_##name->elts; \
        for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \
            { \
            APR_HOOK_PROBE_INVOKE(ud, ns, name, (char *)pHook[n].szName, args_use); \
            rv=pHook[n].pFunc args_use; \
            APR_HOOK_PROBE_COMPLETE(ud, ns, name, (char *)pHook[n].szName, rv, args_use); \
\
            if(rv != decline) \
                break; \
            } \
        } \
\
    APR_HOOK_PROBE_RETURN(ud, ns, name, rv, args_use); \
\
    return rv; \
    }

    /* Hook orderings */
/** run this hook first, before ANYTHING */
#define APR_HOOK_REALLY_FIRST	(-10)
/** run this hook first */
#define APR_HOOK_FIRST		0
/** run this hook somewhere */
#define APR_HOOK_MIDDLE		10
/** run this hook after every other hook which is defined*/
#define APR_HOOK_LAST		20
/** run this hook last, after EVERYTHING */
#define APR_HOOK_REALLY_LAST	30

/**
 * The global pool used to allocate any memory needed by the hooks.
 */ 
APU_DECLARE_DATA extern apr_pool_t *apr_hook_global_pool;

/**
 * A global variable to determine if debugging information about the
 * hooks functions should be printed.
 */ 
APU_DECLARE_DATA extern int apr_hook_debug_enabled;

/**
 * The name of the module that is currently registering a function.
 */ 
APU_DECLARE_DATA extern const char *apr_hook_debug_current;

/**
 * Register a hook function to be sorted.
 * @param szHookName The name of the Hook the function is registered for
 * @param aHooks The array which stores all of the functions for this hook
 */
APU_DECLARE(void) apr_hook_sort_register(const char *szHookName, 
                                        apr_array_header_t **aHooks);
/**
 * Sort all of the registered functions for a given hook.
 */
APU_DECLARE(void) apr_hook_sort_all(void);

/**
 * Print all of the information about the current hook.  This is used for
 * debugging purposes.
 * @param szName The name of the hook
 * @param aszPre All of the functions in the predecessor array
 * @param aszSucc All of the functions in the successor array
 */
APU_DECLARE(void) apr_hook_debug_show(const char *szName,
                                      const char * const *aszPre,
                                      const char * const *aszSucc);

/**
 * Remove all currently registered functions.
 */
APU_DECLARE(void) apr_hook_deregister_all(void);

/** @} */
#ifdef __cplusplus
}
#endif

#endif /* APR_HOOKS_H */
apr-1/apr_sdbm.h000064400000013741151730340540007434 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * sdbm - ndbm work-alike hashed database library
 * based on Per-Ake Larson's Dynamic Hashing algorithms. BIT 18 (1978).
 * author: oz@nexus.yorku.ca
 * status: ex-public domain
 */

#ifndef APR_SDBM_H
#define APR_SDBM_H

#include "apu.h"
#include "apr_errno.h"
#include "apr_file_io.h"   /* for apr_fileperms_t */

/** 
 * @file apr_sdbm.h
 * @brief apr-util SDBM library
 */
/**
 * @defgroup APR_Util_DBM_SDBM SDBM library
 * @ingroup APR_Util_DBM
 * @{
 */

/**
 * Structure for referencing an sdbm
 */
typedef struct apr_sdbm_t apr_sdbm_t;

/**
 * Structure for referencing the datum record within an sdbm
 */
typedef struct {
    /** pointer to the data stored/retrieved */
    char *dptr;
    /** size of data */
    /* apr_ssize_t for release 2.0??? */
    int dsize;
} apr_sdbm_datum_t;

/* The extensions used for the database files */
/** SDBM Directory file extension */
#define APR_SDBM_DIRFEXT	".dir"
/** SDBM page file extension */
#define APR_SDBM_PAGFEXT	".pag"

/* flags to sdbm_store */
#define APR_SDBM_INSERT     0   /**< Insert */
#define APR_SDBM_REPLACE    1   /**< Replace */
#define APR_SDBM_INSERTDUP  2   /**< Insert with duplicates */

/**
 * Open an sdbm database by file name
 * @param db The newly opened database
 * @param name The sdbm file to open
 * @param mode The flag values (APR_READ and APR_BINARY flags are implicit)
 * <PRE>
 *           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
 * </PRE>
 * @param perms Permissions to apply to if created
 * @param p The pool to use when creating the sdbm
 * @remark The sdbm name is not a true file name, as sdbm appends suffixes 
 * for seperate data and index files.
 */
APU_DECLARE(apr_status_t) apr_sdbm_open(apr_sdbm_t **db, const char *name, 
                                        apr_int32_t mode, 
                                        apr_fileperms_t perms, apr_pool_t *p);

/**
 * Close an sdbm file previously opened by apr_sdbm_open
 * @param db The database to close
 */
APU_DECLARE(apr_status_t) apr_sdbm_close(apr_sdbm_t *db);

/**
 * Lock an sdbm database for concurency of multiple operations
 * @param db The database to lock
 * @param type The lock type
 * <PRE>
 *           APR_FLOCK_SHARED
 *           APR_FLOCK_EXCLUSIVE
 * </PRE>
 * @remark Calls to apr_sdbm_lock may be nested.  All apr_sdbm functions
 * perform implicit locking.  Since an APR_FLOCK_SHARED lock cannot be 
 * portably promoted to an APR_FLOCK_EXCLUSIVE lock, apr_sdbm_store and 
 * apr_sdbm_delete calls will fail if an APR_FLOCK_SHARED lock is held.
 * The apr_sdbm_lock call requires the database to be opened with the
 * APR_SHARELOCK mode value.
 */
APU_DECLARE(apr_status_t) apr_sdbm_lock(apr_sdbm_t *db, int type);

/**
 * Release an sdbm lock previously aquired by apr_sdbm_lock
 * @param db The database to unlock
 */
APU_DECLARE(apr_status_t) apr_sdbm_unlock(apr_sdbm_t *db);

/**
 * Fetch an sdbm record value by key
 * @param db The database 
 * @param value The value datum retrieved for this record
 * @param key The key datum to find this record
 */
APU_DECLARE(apr_status_t) apr_sdbm_fetch(apr_sdbm_t *db, 
                                         apr_sdbm_datum_t *value, 
                                         apr_sdbm_datum_t key);

/**
 * Store an sdbm record value by key
 * @param db The database 
 * @param key The key datum to store this record by
 * @param value The value datum to store in this record
 * @param opt The method used to store the record
 * <PRE>
 *           APR_SDBM_INSERT     return an error if the record exists
 *           APR_SDBM_REPLACE    overwrite any existing record for key
 * </PRE>
 */
APU_DECLARE(apr_status_t) apr_sdbm_store(apr_sdbm_t *db, apr_sdbm_datum_t key,
                                         apr_sdbm_datum_t value, int opt);

/**
 * Delete an sdbm record value by key
 * @param db The database 
 * @param key The key datum of the record to delete
 * @remark It is not an error to delete a non-existent record.
 */
APU_DECLARE(apr_status_t) apr_sdbm_delete(apr_sdbm_t *db, 
                                          const apr_sdbm_datum_t key);

/**
 * Retrieve the first record key from a dbm
 * @param db The database 
 * @param key The key datum of the first record
 * @remark The keys returned are not ordered.  To traverse the list of keys
 * for an sdbm opened with APR_SHARELOCK, the caller must use apr_sdbm_lock
 * prior to retrieving the first record, and hold the lock until after the
 * last call to apr_sdbm_nextkey.
 */
APU_DECLARE(apr_status_t) apr_sdbm_firstkey(apr_sdbm_t *db, apr_sdbm_datum_t *key);

/**
 * Retrieve the next record key from an sdbm
 * @param db The database 
 * @param key The key datum of the next record
 */
APU_DECLARE(apr_status_t) apr_sdbm_nextkey(apr_sdbm_t *db, apr_sdbm_datum_t *key);

/**
 * Returns true if the sdbm database opened for read-only access
 * @param db The database to test
 */
APU_DECLARE(int) apr_sdbm_rdonly(apr_sdbm_t *db);
/** @} */
#endif /* APR_SDBM_H */
apr-1/apr_optional.h000064400000005334151730340540010333 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_OPTIONAL_H
#define APR_OPTIONAL_H

#include "apu.h"
/** 
 * @file apr_optional.h
 * @brief APR-UTIL registration of functions exported by modules
 */
#ifdef __cplusplus
extern "C" {
#endif

/** 
 * @defgroup APR_Util_Opt Optional Functions
 * @ingroup APR_Util
 *
 * Typesafe registration and retrieval of functions that may not be present
 * (i.e. functions exported by optional modules)
 * @{
 */

/**
 * The type of an optional function.
 * @param name The name of the function
 */
#define APR_OPTIONAL_FN_TYPE(name) apr_OFN_##name##_t

/**
 * Declare an optional function.
 * @param ret The return type of the function
 * @param name The name of the function
 * @param args The function arguments (including brackets)
 */
#define APR_DECLARE_OPTIONAL_FN(ret,name,args) \
typedef ret (APR_OPTIONAL_FN_TYPE(name)) args

/**
 * XXX: This doesn't belong here, then!
 * Private function! DO NOT USE! 
 * @internal
 */

typedef void (apr_opt_fn_t)(void);
/** @internal */
APU_DECLARE_NONSTD(void) apr_dynamic_fn_register(const char *szName, 
                                                  apr_opt_fn_t *pfn);

/**
 * Register an optional function. This can be later retrieved, type-safely, by
 * name. Like all global functions, the name must be unique. Note that,
 * confusingly but correctly, the function itself can be static!
 * @param name The name of the function
 */
#define APR_REGISTER_OPTIONAL_FN(name) do { \
  APR_OPTIONAL_FN_TYPE(name) *apu__opt = name; \
  apr_dynamic_fn_register(#name,(apr_opt_fn_t *)apu__opt); \
} while (0)

/** @internal
 * Private function! DO NOT USE! 
 */
APU_DECLARE(apr_opt_fn_t *) apr_dynamic_fn_retrieve(const char *szName);

/**
 * Retrieve an optional function. Returns NULL if the function is not present.
 * @param name The name of the function
 */
#define APR_RETRIEVE_OPTIONAL_FN(name) \
	(APR_OPTIONAL_FN_TYPE(name) *)apr_dynamic_fn_retrieve(#name)

/** @} */
#ifdef __cplusplus
}
#endif

#endif /* APR_OPTIONAL_H */
apr-1/apr_thread_pool.h000064400000025540151730340540011007 0ustar00/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed
 * with this work for additional information regarding copyright
 * ownership.  The ASF licenses this file to you under the Apache
 * License, Version 2.0 (the "License"); you may not use this file
 * except in compliance with the License.  You may obtain a copy of
 * the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.  See the License for the specific language governing
 * permissions and limitations under the License.
 */

#ifndef APU_THREAD_POOL_H
#define APU_THREAD_POOL_H

#include "apu.h"
#include "apr_thread_proc.h"

/**
 * @file apr_thread_pool.h
 * @brief APR Thread Pool Library

 * @remarks This library implements a thread pool using apr_thread_t. A thread
 * pool is a set of threads that can be created in advance or on demand until a
 * maximum number. When a task is scheduled, the thread pool will find an idle
 * thread to handle the task. In case all existing threads are busy and the
 * number of tasks in the queue is higher than the adjustable threshold, the
 * pool will try to create a new thread to serve the task if the maximum number
 * has not been reached. Otherwise, the task will be put into a queue based on
 * priority, which can be valued from 0 to 255, with higher values being served
 * first. If there are tasks with the same priority, the new task might be put at
 * the top or at the bottom - it depends on which function is used to put the task.
 *
 * @remarks There may be the case where the thread pool can use up to the maximum
 * number of threads at peak load, but having those threads idle afterwards. A
 * maximum number of idle threads can be set so that the extra idling threads will
 * be terminated to save system resources.
 */
#if APR_HAS_THREADS

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @defgroup APR_Util_TP Thread Pool routines
 * @ingroup APR_Util
 * @{
 */

/** Opaque Thread Pool structure. */
typedef struct apr_thread_pool apr_thread_pool_t;

#define APR_THREAD_TASK_PRIORITY_LOWEST 0
#define APR_THREAD_TASK_PRIORITY_LOW 63
#define APR_THREAD_TASK_PRIORITY_NORMAL 127
#define APR_THREAD_TASK_PRIORITY_HIGH 191
#define APR_THREAD_TASK_PRIORITY_HIGHEST 255

/**
 * Create a thread pool
 * @param me The pointer in which to return the newly created apr_thread_pool
 * object, or NULL if thread pool creation fails.
 * @param init_threads The number of threads to be created initially, this number
 * will also be used as the initial value for the maximum number of idle threads.
 * @param max_threads The maximum number of threads that can be created
 * @param pool The pool to use
 * @return APR_SUCCESS if the thread pool was created successfully. Otherwise,
 * the error code.
 */
APU_DECLARE(apr_status_t) apr_thread_pool_create(apr_thread_pool_t **me,
                                                 apr_size_t init_threads,
                                                 apr_size_t max_threads,
                                                 apr_pool_t *pool);

/**
 * Destroy the thread pool and stop all the threads
 * @return APR_SUCCESS if all threads are stopped.
 */
APU_DECLARE(apr_status_t) apr_thread_pool_destroy(apr_thread_pool_t *me);

/**
 * Schedule a task to the bottom of the tasks of same priority.
 * @param me The thread pool
 * @param func The task function
 * @param param The parameter for the task function
 * @param priority The priority of the task.
 * @param owner Owner of this task.
 * @return APR_SUCCESS if the task had been scheduled successfully
 */
APU_DECLARE(apr_status_t) apr_thread_pool_push(apr_thread_pool_t *me,
                                               apr_thread_start_t func,
                                               void *param,
                                               apr_byte_t priority,
                                               void *owner);
/**
 * Schedule a task to be run after a delay
 * @param me The thread pool
 * @param func The task function
 * @param param The parameter for the task function
 * @param time Time in microseconds
 * @param owner Owner of this task.
 * @return APR_SUCCESS if the task had been scheduled successfully
 */
APU_DECLARE(apr_status_t) apr_thread_pool_schedule(apr_thread_pool_t *me,
                                                   apr_thread_start_t func,
                                                   void *param,
                                                   apr_interval_time_t time,
                                                   void *owner);

/**
 * Schedule a task to the top of the tasks of same priority.
 * @param me The thread pool
 * @param func The task function
 * @param param The parameter for the task function
 * @param priority The priority of the task.
 * @param owner Owner of this task.
 * @return APR_SUCCESS if the task had been scheduled successfully
 */
APU_DECLARE(apr_status_t) apr_thread_pool_top(apr_thread_pool_t *me,
                                              apr_thread_start_t func,
                                              void *param,
                                              apr_byte_t priority,
                                              void *owner);

/**
 * Cancel tasks submitted by the owner. If there is any task from the owner that
 * is currently running, the function will spin until the task finished.
 * @param me The thread pool
 * @param owner Owner of the task
 * @return APR_SUCCESS if the task has been cancelled successfully
 * @note The task function should not be calling cancel, otherwise the function
 * may get stuck forever. The function assert if it detect such a case.
 */
APU_DECLARE(apr_status_t) apr_thread_pool_tasks_cancel(apr_thread_pool_t *me,
                                                       void *owner);

/**
 * Get the current number of tasks waiting in the queue
 * @param me The thread pool
 * @return Number of tasks in the queue
 */
APU_DECLARE(apr_size_t) apr_thread_pool_tasks_count(apr_thread_pool_t *me);

/**
 * Get the current number of scheduled tasks waiting in the queue
 * @param me The thread pool
 * @return Number of scheduled tasks in the queue
 */
APU_DECLARE(apr_size_t) apr_thread_pool_scheduled_tasks_count(apr_thread_pool_t *me);

/**
 * Get the current number of threads
 * @param me The thread pool
 * @return Total number of threads
 */
APU_DECLARE(apr_size_t) apr_thread_pool_threads_count(apr_thread_pool_t *me);

/**
 * Get the current number of busy threads
 * @param me The thread pool
 * @return Number of busy threads
 */
APU_DECLARE(apr_size_t) apr_thread_pool_busy_count(apr_thread_pool_t *me);

/**
 * Get the current number of idle threads
 * @param me The thread pool
 * @return Number of idle threads
 */
APU_DECLARE(apr_size_t) apr_thread_pool_idle_count(apr_thread_pool_t *me);

/**
 * Access function for the maximum number of idle threads. Number of current
 * idle threads will be reduced to the new limit.
 * @param me The thread pool
 * @param cnt The number
 * @return The number of threads that were stopped.
 */
APU_DECLARE(apr_size_t) apr_thread_pool_idle_max_set(apr_thread_pool_t *me,
                                                     apr_size_t cnt);

/**
 * Get number of tasks that have run
 * @param me The thread pool
 * @return Number of tasks that have run
 */
APU_DECLARE(apr_size_t)
    apr_thread_pool_tasks_run_count(apr_thread_pool_t * me);

/**
 * Get high water mark of the number of tasks waiting to run
 * @param me The thread pool
 * @return High water mark of tasks waiting to run
 */
APU_DECLARE(apr_size_t)
    apr_thread_pool_tasks_high_count(apr_thread_pool_t * me);

/**
 * Get high water mark of the number of threads
 * @param me The thread pool
 * @return High water mark of threads in thread pool
 */
APU_DECLARE(apr_size_t)
    apr_thread_pool_threads_high_count(apr_thread_pool_t * me);

/**
 * Get the number of idle threads that were destroyed after timing out
 * @param me The thread pool
 * @return Number of idle threads that timed out
 */
APU_DECLARE(apr_size_t)
    apr_thread_pool_threads_idle_timeout_count(apr_thread_pool_t * me);

/**
 * Access function for the maximum number of idle threads
 * @param me The thread pool
 * @return The current maximum number
 */
APU_DECLARE(apr_size_t) apr_thread_pool_idle_max_get(apr_thread_pool_t *me);

/**
 * Access function for the maximum number of threads.
 * @param me The thread pool
 * @param cnt Number of threads
 * @return The original maximum number of threads
 */
APU_DECLARE(apr_size_t) apr_thread_pool_thread_max_set(apr_thread_pool_t *me,
                                                       apr_size_t cnt);

/**
 * Access function for the maximum wait time (in microseconds) of an
 * idling thread that exceeds the maximum number of idling threads.
 * A non-zero value allows for the reaping of idling threads to shrink
 * over time.  Which helps reduce thrashing.
 * @param me The thread pool
 * @param timeout The number of microseconds an idle thread should wait
 * till it reaps itself
 * @return The original maximum wait time
 */
APU_DECLARE(apr_interval_time_t)
    apr_thread_pool_idle_wait_set(apr_thread_pool_t * me,
                                  apr_interval_time_t timeout);

/**
 * Access function for the maximum wait time (in microseconds) of an
 * idling thread that exceeds the maximum number of idling threads
 * @param me The thread pool
 * @return The current maximum wait time
 */
APU_DECLARE(apr_interval_time_t)
    apr_thread_pool_idle_wait_get(apr_thread_pool_t * me);

/**
 * Access function for the maximum number of threads
 * @param me The thread pool
 * @return The current maximum number
 */
APU_DECLARE(apr_size_t) apr_thread_pool_thread_max_get(apr_thread_pool_t *me);

/**
 * Access function for the threshold of tasks in queue to trigger a new thread.
 * @param me The thread pool
 * @param cnt The new threshold
 * @return The original threshold
 */
APU_DECLARE(apr_size_t) apr_thread_pool_threshold_set(apr_thread_pool_t *me,
                                                      apr_size_t val);

/**
 * Access function for the threshold of tasks in queue to trigger a new thread.
 * @param me The thread pool
 * @return The current threshold
 */
APU_DECLARE(apr_size_t) apr_thread_pool_threshold_get(apr_thread_pool_t * me);

/**
 * Get owner of the task currently been executed by the thread.
 * @param thd The thread is executing a task
 * @param owner Pointer to receive owner of the task.
 * @return APR_SUCCESS if the owner is retrieved successfully
 */
APU_DECLARE(apr_status_t) apr_thread_pool_task_owner_get(apr_thread_t *thd,
                                                         void **owner);

/** @} */

#ifdef __cplusplus
}
#endif

#endif /* APR_HAS_THREADS */
#endif /* !APR_THREAD_POOL_H */
apr-1/apr_global_mutex.h000064400000016301151730340540011164 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_GLOBAL_MUTEX_H
#define APR_GLOBAL_MUTEX_H

/**
 * @file apr_global_mutex.h
 * @brief APR Global Locking Routines
 */

#include "apr.h"
#include "apr_proc_mutex.h"    /* only for apr_lockmech_e */
#include "apr_pools.h"
#include "apr_errno.h"
#if APR_PROC_MUTEX_IS_GLOBAL
#include "apr_proc_mutex.h"
#endif
#include "apr_time.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @defgroup APR_GlobalMutex Global Locking Routines
 * @ingroup APR 
 * @{
 */

#if !APR_PROC_MUTEX_IS_GLOBAL || defined(DOXYGEN)

/** Opaque global mutex structure. */
typedef struct apr_global_mutex_t apr_global_mutex_t;

/*   Function definitions */

/**
 * Create and initialize a mutex that can be used to synchronize both
 * processes and threads. Note: There is considerable overhead in using
 * this API if only cross-process or cross-thread mutual exclusion is
 * required. See apr_proc_mutex.h and apr_thread_mutex.h for more
 * specialized lock routines.
 * @param mutex the memory address where the newly created mutex will be
 *        stored.
 * @param fname A file name to use if the lock mechanism requires one.  This
 *        argument should always be provided.  The lock code itself will
 *        determine if it should be used.
 * @param mech The mechanism to use for the interprocess lock, if any; one of
 * <PRE>
 *            APR_LOCK_FCNTL
 *            APR_LOCK_FLOCK
 *            APR_LOCK_SYSVSEM
 *            APR_LOCK_POSIXSEM
 *            APR_LOCK_PROC_PTHREAD
 *            APR_LOCK_DEFAULT     pick the default mechanism for the platform
 *            APR_LOCK_DEFAULT_TIMED pick the default timed mechanism
 * </PRE>
 * @param pool the pool from which to allocate the mutex.
 * @warning Check APR_HAS_foo_SERIALIZE defines to see if the platform supports
 *          APR_LOCK_foo.  Only APR_LOCK_DEFAULT is portable.
 */
APR_DECLARE(apr_status_t) apr_global_mutex_create(apr_global_mutex_t **mutex,
                                                  const char *fname,
                                                  apr_lockmech_e mech,
                                                  apr_pool_t *pool);

/**
 * Re-open a mutex in a child process.
 * @param mutex The newly re-opened mutex structure.
 * @param fname A file name to use if the mutex mechanism requires one.  This
 *              argument should always be provided.  The mutex code itself will
 *              determine if it should be used.  This filename should be the 
 *              same one that was passed to apr_global_mutex_create().
 * @param pool The pool to operate on.
 * @remark This function must be called to maintain portability, even
 *         if the underlying lock mechanism does not require it.
 */
APR_DECLARE(apr_status_t) apr_global_mutex_child_init(
                              apr_global_mutex_t **mutex,
                              const char *fname,
                              apr_pool_t *pool);

/**
 * Acquire the lock for the given mutex. If the mutex is already locked,
 * the current thread will be put to sleep until the lock becomes available.
 * @param mutex the mutex on which to acquire the lock.
 */
APR_DECLARE(apr_status_t) apr_global_mutex_lock(apr_global_mutex_t *mutex);

/**
 * Attempt to acquire the lock for the given mutex. If the mutex has already
 * been acquired, the call returns immediately with APR_EBUSY. Note: it
 * is important that the APR_STATUS_IS_EBUSY(s) macro be used to determine
 * if the return value was APR_EBUSY, for portability reasons.
 * @param mutex the mutex on which to attempt the lock acquiring.
 */
APR_DECLARE(apr_status_t) apr_global_mutex_trylock(apr_global_mutex_t *mutex);

/**
 * Attempt to acquire the lock for the given mutex until timeout expires.
 * If the acquisition time outs, the call returns with APR_TIMEUP.
 * @param mutex the mutex on which to attempt the lock acquiring.
 * @param timeout the relative timeout (microseconds).
 * @note A negative or nul timeout means immediate attempt, returning
 *       APR_TIMEUP without blocking if it the lock is already acquired.
 */
APR_DECLARE(apr_status_t) apr_global_mutex_timedlock(apr_global_mutex_t *mutex,
                                                 apr_interval_time_t timeout);

/**
 * Release the lock for the given mutex.
 * @param mutex the mutex from which to release the lock.
 */
APR_DECLARE(apr_status_t) apr_global_mutex_unlock(apr_global_mutex_t *mutex);

/**
 * Destroy the mutex and free the memory associated with the lock.
 * @param mutex the mutex to destroy.
 */
APR_DECLARE(apr_status_t) apr_global_mutex_destroy(apr_global_mutex_t *mutex);

/**
 * Return the name of the lockfile for the mutex, or NULL
 * if the mutex doesn't use a lock file
 */
APR_DECLARE(const char *) apr_global_mutex_lockfile(apr_global_mutex_t *mutex);

/**
 * Get the mechanism of the mutex, as it relates to the actual method
 * used for the underlying apr_proc_mutex_t.
 * @param mutex the mutex to get the mechanism from.
 */
APR_DECLARE(apr_lockmech_e) apr_global_mutex_mech(apr_global_mutex_t *mutex);

/**
 * Get the mechanism's name of the mutex, as it relates to the actual method
 * used for the underlying apr_proc_mutex_t.
 * @param mutex the mutex to get the mechanism's name from.
 */
APR_DECLARE(const char *) apr_global_mutex_name(apr_global_mutex_t *mutex);

/**
 * Set mutex permissions.
 */
APR_PERMS_SET_IMPLEMENT(global_mutex);

/**
 * Get the pool used by this global_mutex.
 * @return apr_pool_t the pool
 */
APR_POOL_DECLARE_ACCESSOR(global_mutex);

#else /* APR_PROC_MUTEX_IS_GLOBAL */

/* Some platforms [e.g. Win32] have cross process locks that are truly
 * global locks, since there isn't the concept of cross-process locks.
 * Define these platforms in terms of an apr_proc_mutex_t.
 */

#define apr_global_mutex_t          apr_proc_mutex_t
#define apr_global_mutex_create     apr_proc_mutex_create
#define apr_global_mutex_child_init apr_proc_mutex_child_init
#define apr_global_mutex_lock       apr_proc_mutex_lock
#define apr_global_mutex_trylock    apr_proc_mutex_trylock
#define apr_global_mutex_unlock     apr_proc_mutex_unlock
#define apr_global_mutex_destroy    apr_proc_mutex_destroy
#define apr_global_mutex_lockfile   apr_proc_mutex_lockfile
#define apr_global_mutex_mech       apr_proc_mutex_mech
#define apr_global_mutex_name       apr_proc_mutex_name
#define apr_global_mutex_perms_set  apr_proc_mutex_perms_set
#define apr_global_mutex_pool_get   apr_proc_mutex_pool_get

#endif

/** @} */

#ifdef __cplusplus
}
#endif

#endif  /* ndef APR_GLOBAL_MUTEX_H */
apr-1/apr_anylock.h000064400000011672151730340540010150 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @file apr_anylock.h
 * @brief APR-Util transparent any lock flavor wrapper
 */
#ifndef APR_ANYLOCK_H
#define APR_ANYLOCK_H

#include "apr_proc_mutex.h"
#include "apr_thread_mutex.h"
#include "apr_thread_rwlock.h"

/** Structure that may contain any APR lock type */
typedef struct apr_anylock_t {
    /** Indicates what type of lock is in lock */
    enum tm_lock {
        apr_anylock_none,           /**< None */
        apr_anylock_procmutex,      /**< Process-based */
        apr_anylock_threadmutex,    /**< Thread-based */
        apr_anylock_readlock,       /**< Read lock */
        apr_anylock_writelock       /**< Write lock */
    } type;
    /** Union of all possible APR locks */
    union apr_anylock_u_t {
        apr_proc_mutex_t *pm;       /**< Process mutex */
#if APR_HAS_THREADS
        apr_thread_mutex_t *tm;     /**< Thread mutex */
        apr_thread_rwlock_t *rw;    /**< Read-write lock */
#endif
    } lock;
} apr_anylock_t;

#if APR_HAS_THREADS

/** Lock an apr_anylock_t structure */
#define APR_ANYLOCK_LOCK(lck)                \
    (((lck)->type == apr_anylock_none)         \
      ? APR_SUCCESS                              \
      : (((lck)->type == apr_anylock_threadmutex)  \
          ? apr_thread_mutex_lock((lck)->lock.tm)    \
          : (((lck)->type == apr_anylock_procmutex)    \
              ? apr_proc_mutex_lock((lck)->lock.pm)      \
              : (((lck)->type == apr_anylock_readlock)     \
                  ? apr_thread_rwlock_rdlock((lck)->lock.rw) \
                  : (((lck)->type == apr_anylock_writelock)    \
                      ? apr_thread_rwlock_wrlock((lck)->lock.rw) \
                      : APR_EINVAL)))))

#else /* APR_HAS_THREADS */

#define APR_ANYLOCK_LOCK(lck)                \
    (((lck)->type == apr_anylock_none)         \
      ? APR_SUCCESS                              \
          : (((lck)->type == apr_anylock_procmutex)    \
              ? apr_proc_mutex_lock((lck)->lock.pm)      \
                      : APR_EINVAL))

#endif /* APR_HAS_THREADS */

#if APR_HAS_THREADS

/** Try to lock an apr_anylock_t structure */
#define APR_ANYLOCK_TRYLOCK(lck)                \
    (((lck)->type == apr_anylock_none)            \
      ? APR_SUCCESS                                 \
      : (((lck)->type == apr_anylock_threadmutex)     \
          ? apr_thread_mutex_trylock((lck)->lock.tm)    \
          : (((lck)->type == apr_anylock_procmutex)       \
              ? apr_proc_mutex_trylock((lck)->lock.pm)      \
              : (((lck)->type == apr_anylock_readlock)        \
                  ? apr_thread_rwlock_tryrdlock((lck)->lock.rw) \
                  : (((lck)->type == apr_anylock_writelock)       \
                      ? apr_thread_rwlock_trywrlock((lck)->lock.rw) \
                          : APR_EINVAL)))))

#else /* APR_HAS_THREADS */

#define APR_ANYLOCK_TRYLOCK(lck)                \
    (((lck)->type == apr_anylock_none)            \
      ? APR_SUCCESS                                 \
          : (((lck)->type == apr_anylock_procmutex)       \
              ? apr_proc_mutex_trylock((lck)->lock.pm)      \
                          : APR_EINVAL))

#endif /* APR_HAS_THREADS */

#if APR_HAS_THREADS

/** Unlock an apr_anylock_t structure */
#define APR_ANYLOCK_UNLOCK(lck)              \
    (((lck)->type == apr_anylock_none)         \
      ? APR_SUCCESS                              \
      : (((lck)->type == apr_anylock_threadmutex)  \
          ? apr_thread_mutex_unlock((lck)->lock.tm)  \
          : (((lck)->type == apr_anylock_procmutex)    \
              ? apr_proc_mutex_unlock((lck)->lock.pm)    \
              : ((((lck)->type == apr_anylock_readlock) || \
                  ((lck)->type == apr_anylock_writelock))    \
                  ? apr_thread_rwlock_unlock((lck)->lock.rw)   \
                      : APR_EINVAL))))

#else /* APR_HAS_THREADS */

#define APR_ANYLOCK_UNLOCK(lck)              \
    (((lck)->type == apr_anylock_none)         \
      ? APR_SUCCESS                              \
          : (((lck)->type == apr_anylock_procmutex)    \
              ? apr_proc_mutex_unlock((lck)->lock.pm)    \
                      : APR_EINVAL))

#endif /* APR_HAS_THREADS */

#endif /* !APR_ANYLOCK_H */
apr-1/apr_support.h000064400000003142151730340540010215 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_SUPPORT_H
#define APR_SUPPORT_H

/**
 * @file apr_support.h
 * @brief APR Support functions
 */

#include "apr.h"
#include "apr_network_io.h"
#include "apr_file_io.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @defgroup apr_support Internal APR support functions
 * @ingroup APR 
 * @{
 */

/**
 * Wait for IO to occur or timeout.
 *
 * @param f The file to wait on.
 * @param s The socket to wait on if @a f is @c NULL.
 * @param for_read If non-zero wait for data to be available to read,
 *        otherwise wait for data to be able to be written. 
 * @return APR_TIMEUP if we run out of time.
 */
apr_status_t apr_wait_for_io_or_timeout(apr_file_t *f, apr_socket_t *s,
                                        int for_read);

/** @} */

#ifdef __cplusplus
}
#endif

#endif  /* ! APR_SUPPORT_H */
apr-1/apr_ldap.h000064400000013110151730340540007415 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * apr_ldap.h is generated from apr_ldap.h.in by configure -- do not edit apr_ldap.h
 */
/**
 * @file apr_ldap.h
 * @brief  APR-UTIL LDAP 
 */
#ifndef APU_LDAP_H
#define APU_LDAP_H

/**
 * @defgroup APR_Util_LDAP LDAP
 * @ingroup APR_Util
 * @{
 */

/* this will be defined if LDAP support was compiled into apr-util */
#define APR_HAS_LDAP		  1

/* identify the LDAP toolkit used */
#define APR_HAS_NETSCAPE_LDAPSDK  0
#define APR_HAS_SOLARIS_LDAPSDK   0
#define APR_HAS_NOVELL_LDAPSDK    0
#define APR_HAS_MOZILLA_LDAPSDK   0
#define APR_HAS_OPENLDAP_LDAPSDK  1
#define APR_HAS_MICROSOFT_LDAPSDK 0
#define APR_HAS_TIVOLI_LDAPSDK    0
#define APR_HAS_ZOS_LDAPSDK       0
#define APR_HAS_OTHER_LDAPSDK     0


/*
 * Handle the case when LDAP is enabled
 */
#if APR_HAS_LDAP

/*
 * The following #defines are DEPRECATED and should not be used for
 * anything. They remain to maintain binary compatibility.
 * The original code defined the OPENLDAP SDK as present regardless
 * of what really was there, which was way bogus. In addition, the
 * apr_ldap_url_parse*() functions have been rewritten specifically for
 * APR, so the APR_HAS_LDAP_URL_PARSE macro is forced to zero.
 */
#if APR_HAS_TIVOLI_LDAPSDK
#define APR_HAS_LDAP_SSL 0
#else
#define APR_HAS_LDAP_SSL 1
#endif
#define APR_HAS_LDAP_URL_PARSE      0

#if APR_HAS_OPENLDAP_LDAPSDK && !defined(LDAP_DEPRECATED) 
/* Ensure that the "deprecated" interfaces are still exposed
 * with OpenLDAP >= 2.3; these were exposed by default in earlier
 * releases. */
#define LDAP_DEPRECATED 1
#endif

/*
 * Include the standard LDAP header files.
 */

#include <lber.h>
#include <ldap.h>



/*
 * Detected standard functions
 */
#define APR_HAS_LDAPSSL_CLIENT_INIT 0
#define APR_HAS_LDAPSSL_CLIENT_DEINIT 0
#define APR_HAS_LDAPSSL_ADD_TRUSTED_CERT 0
#define APR_HAS_LDAP_START_TLS_S 1
#define APR_HAS_LDAP_SSLINIT 0
#define APR_HAS_LDAPSSL_INIT 0
#define APR_HAS_LDAPSSL_INSTALL_ROUTINES 0

/*
 * Make sure the secure LDAP port is defined
 */
#ifndef LDAPS_PORT
#define LDAPS_PORT 636  /* ldaps:/// default LDAP over TLS port */
#endif

/*
 * For ldap function calls that input a size limit on the number of returned elements
 * Some SDKs do not have the define for LDAP_DEFAULT_LIMIT (-1) or LDAP_NO_LIMIT (0)
 * LDAP_DEFAULT_LIMIT is preferred as it allows inheritance from whatever the SDK
 * or process is configured for.
 */
#ifdef LDAP_DEFAULT_LIMIT
#define APR_LDAP_SIZELIMIT LDAP_DEFAULT_LIMIT
#else
#ifdef LDAP_NO_LIMIT
#define APR_LDAP_SIZELIMIT LDAP_NO_LIMIT
#endif
#endif

#ifndef APR_LDAP_SIZELIMIT
#define APR_LDAP_SIZELIMIT 0 /* equivalent to LDAP_NO_LIMIT, and what goes on the wire */
#endif

/*
 * z/OS is missing some defines
 */
#ifndef LDAP_VERSION_MAX
#define LDAP_VERSION_MAX  LDAP_VERSION
#endif
#if APR_HAS_ZOS_LDAPSDK
#define LDAP_VENDOR_NAME "IBM z/OS"
#endif

/* Note: Macros defining const casting has been removed in APR v1.0,
 * pending real support for LDAP v2.0 toolkits.
 *
 * In the mean time, please use an LDAP v3.0 toolkit.
 */
#if LDAP_VERSION_MAX <= 2
#error Support for LDAP v2.0 toolkits has been removed from apr-util. Please use an LDAP v3.0 toolkit.
#endif 

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * This structure allows the C LDAP API error codes to be returned
 * along with plain text error messages that explain to us mere mortals
 * what really happened.
 */
typedef struct apr_ldap_err_t {
    const char *reason;
    const char *msg;
    int rc;
} apr_ldap_err_t;

#ifdef __cplusplus
}
#endif

/* The MS SDK returns LDAP_UNAVAILABLE when the backend has closed the connection
 * between LDAP calls. Protect with APR_HAS_MICROSOFT_LDAPSDK in case someone 
 * manually chooses another SDK on Windows 
 */
#if APR_HAS_MICROSOFT_LDAPSDK
#define APR_LDAP_IS_SERVER_DOWN(s)    ((s) == LDAP_SERVER_DOWN \
                                    || (s) == LDAP_UNAVAILABLE)
#else
#define APR_LDAP_IS_SERVER_DOWN(s)    ((s) == LDAP_SERVER_DOWN)
#endif

/* These symbols are not actually exported in a DSO build, but mapped into
 * a private exported function array for apr_ldap_stub to bind dynamically.
 * Rename them appropriately to protect the global namespace.
 */
#ifdef APU_DSO_LDAP_BUILD

#define apr_ldap_info apr__ldap_info
#define apr_ldap_init apr__ldap_init
#define apr_ldap_ssl_init apr__ldap_ssl_init
#define apr_ldap_ssl_deinit apr__ldap_ssl_deinit
#define apr_ldap_get_option apr__ldap_get_option
#define apr_ldap_set_option apr__ldap_set_option
#define apr_ldap_rebind_init apr__ldap_rebind_init
#define apr_ldap_rebind_add apr__ldap_rebind_add
#define apr_ldap_rebind_remove apr__ldap_rebind_remove

#define APU_DECLARE_LDAP(type) type
#else
#define APU_DECLARE_LDAP(type) APU_DECLARE(type)
#endif

#include "apr_ldap_url.h"
#include "apr_ldap_init.h"
#include "apr_ldap_option.h"
#include "apr_ldap_rebind.h"

#endif /* APR_HAS_LDAP */
/** @} */
#endif /* APU_LDAP_H */
apr-1/apr_poll.h000064400000051153151730340540007454 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_POLL_H
#define APR_POLL_H
/**
 * @file apr_poll.h
 * @brief APR Poll interface
 */
#include "apr.h"
#include "apr_pools.h"
#include "apr_errno.h"
#include "apr_inherit.h" 
#include "apr_file_io.h" 
#include "apr_network_io.h" 

#if APR_HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @defgroup apr_poll Poll Routines
 * @ingroup APR 
 * @{
 */

/**
 * @defgroup pollopts Poll options
 * @ingroup apr_poll
 * @{
 */
#define APR_POLLIN    0x001     /**< Can read without blocking */
#define APR_POLLPRI   0x002     /**< Priority data available */
#define APR_POLLOUT   0x004     /**< Can write without blocking */
#define APR_POLLERR   0x010     /**< Pending error */
#define APR_POLLHUP   0x020     /**< Hangup occurred */
#define APR_POLLNVAL  0x040     /**< Descriptor invalid */
/** @} */

/**
 * @defgroup pollflags Pollset Flags
 * @ingroup apr_poll
 * @{
 */
#define APR_POLLSET_THREADSAFE 0x001 /**< Adding or removing a descriptor is
                                      * thread-safe
                                      */
#define APR_POLLSET_NOCOPY     0x002 /**< Descriptors passed to apr_pollset_add()
                                      * are not copied
                                      */
#define APR_POLLSET_WAKEABLE   0x004 /**< Poll operations are interruptable by
                                      * apr_pollset_wakeup() or apr_pollcb_wakeup()
                                      */
#define APR_POLLSET_NODEFAULT  0x010 /**< Do not try to use the default method if
                                      * the specified non-default method cannot be
                                      * used
                                      */
/** @} */

/**
 * Pollset Methods
 */
typedef enum {
    APR_POLLSET_DEFAULT,        /**< Platform default poll method */
    APR_POLLSET_SELECT,         /**< Poll uses select method */
    APR_POLLSET_KQUEUE,         /**< Poll uses kqueue method */
    APR_POLLSET_PORT,           /**< Poll uses Solaris event port method */
    APR_POLLSET_EPOLL,          /**< Poll uses epoll method */
    APR_POLLSET_POLL,           /**< Poll uses poll method */
    APR_POLLSET_AIO_MSGQ        /**< Poll uses z/OS asio method */
} apr_pollset_method_e;

/** Used in apr_pollfd_t to determine what the apr_descriptor is */
typedef enum { 
    APR_NO_DESC,                /**< nothing here */
    APR_POLL_SOCKET,            /**< descriptor refers to a socket */
    APR_POLL_FILE,              /**< descriptor refers to a file */
    APR_POLL_LASTDESC           /**< @deprecated descriptor is the last one in the list */
} apr_datatype_e ;

/** Union of either an APR file or socket. */
typedef union {
    apr_file_t *f;              /**< file */
    apr_socket_t *s;            /**< socket */
} apr_descriptor;

/** @see apr_pollfd_t */
typedef struct apr_pollfd_t apr_pollfd_t;

/** Poll descriptor set. */
struct apr_pollfd_t {
    apr_pool_t *p;              /**< associated pool */
    apr_datatype_e desc_type;   /**< descriptor type */
    apr_int16_t reqevents;      /**< requested events */
    apr_int16_t rtnevents;      /**< returned events */
    apr_descriptor desc;        /**< @see apr_descriptor */
    void *client_data;          /**< allows app to associate context */
};


/* General-purpose poll API for arbitrarily large numbers of
 * file descriptors
 */

/** Opaque structure used for pollset API */
typedef struct apr_pollset_t apr_pollset_t;

/**
 * Set up a pollset object
 * @param pollset  The pointer in which to return the newly created object 
 * @param size The maximum number of descriptors that this pollset can hold
 * @param p The pool from which to allocate the pollset
 * @param flags Optional flags to modify the operation of the pollset.
 *
 * @remark If flags contains APR_POLLSET_THREADSAFE, then a pollset is
 *         created on which it is safe to make concurrent calls to
 *         apr_pollset_add(), apr_pollset_remove() and apr_pollset_poll()
 *         from separate threads.  This feature is only supported on some
 *         platforms; the apr_pollset_create() call will fail with
 *         APR_ENOTIMPL on platforms where it is not supported.
 * @remark If flags contains APR_POLLSET_WAKEABLE, then a pollset is
 *         created with an additional internal pipe object used for the
 *         apr_pollset_wakeup() call. The actual size of pollset is
 *         in that case @a size + 1. This feature is only supported on some
 *         platforms; the apr_pollset_create() call will fail with
 *         APR_ENOTIMPL on platforms where it is not supported.
 * @remark If flags contains APR_POLLSET_NOCOPY, then the apr_pollfd_t
 *         structures passed to apr_pollset_add() are not copied and
 *         must have a lifetime at least as long as the pollset.
 * @remark Some poll methods (including APR_POLLSET_KQUEUE,
 *         APR_POLLSET_PORT, and APR_POLLSET_EPOLL) do not have a
 *         fixed limit on the size of the pollset. For these methods,
 *         the size parameter controls the maximum number of
 *         descriptors that will be returned by a single call to
 *         apr_pollset_poll().
 */
APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset,
                                             apr_uint32_t size,
                                             apr_pool_t *p,
                                             apr_uint32_t flags);

/**
 * Set up a pollset object
 * @param pollset  The pointer in which to return the newly created object 
 * @param size The maximum number of descriptors that this pollset can hold
 * @param p The pool from which to allocate the pollset
 * @param flags Optional flags to modify the operation of the pollset.
 * @param method Poll method to use. See #apr_pollset_method_e.  If this
 *         method cannot be used, the default method will be used unless the
 *         APR_POLLSET_NODEFAULT flag has been specified.
 *
 * @remark If flags contains APR_POLLSET_THREADSAFE, then a pollset is
 *         created on which it is safe to make concurrent calls to
 *         apr_pollset_add(), apr_pollset_remove() and apr_pollset_poll()
 *         from separate threads.  This feature is only supported on some
 *         platforms; the apr_pollset_create_ex() call will fail with
 *         APR_ENOTIMPL on platforms where it is not supported.
 * @remark If flags contains APR_POLLSET_WAKEABLE, then a pollset is
 *         created with additional internal pipe object used for the
 *         apr_pollset_wakeup() call. The actual size of pollset is
 *         in that case size + 1. This feature is only supported on some
 *         platforms; the apr_pollset_create_ex() call will fail with
 *         APR_ENOTIMPL on platforms where it is not supported.
 * @remark If flags contains APR_POLLSET_NOCOPY, then the apr_pollfd_t
 *         structures passed to apr_pollset_add() are not copied and
 *         must have a lifetime at least as long as the pollset.
 * @remark Some poll methods (including APR_POLLSET_KQUEUE,
 *         APR_POLLSET_PORT, and APR_POLLSET_EPOLL) do not have a
 *         fixed limit on the size of the pollset. For these methods,
 *         the size parameter controls the maximum number of
 *         descriptors that will be returned by a single call to
 *         apr_pollset_poll().
 */
APR_DECLARE(apr_status_t) apr_pollset_create_ex(apr_pollset_t **pollset,
                                                apr_uint32_t size,
                                                apr_pool_t *p,
                                                apr_uint32_t flags,
                                                apr_pollset_method_e method);

/**
 * Destroy a pollset object
 * @param pollset The pollset to destroy
 */
APR_DECLARE(apr_status_t) apr_pollset_destroy(apr_pollset_t *pollset);

/**
 * Add a socket or file descriptor to a pollset
 * @param pollset The pollset to which to add the descriptor
 * @param descriptor The descriptor to add
 * @remark If you set client_data in the descriptor, that value
 *         will be returned in the client_data field whenever this
 *         descriptor is signalled in apr_pollset_poll().
 * @remark If the pollset has been created with APR_POLLSET_THREADSAFE
 *         and thread T1 is blocked in a call to apr_pollset_poll() for
 *         this same pollset that is being modified via apr_pollset_add()
 *         in thread T2, the currently executing apr_pollset_poll() call in
 *         T1 will either: (1) automatically include the newly added descriptor
 *         in the set of descriptors it is watching or (2) return immediately
 *         with APR_EINTR.  Option (1) is recommended, but option (2) is
 *         allowed for implementations where option (1) is impossible
 *         or impractical.
 * @remark If the pollset has been created with APR_POLLSET_NOCOPY, the 
 *         apr_pollfd_t structure referenced by descriptor will not be copied
 *         and must have a lifetime at least as long as the pollset.
 * @remark Do not add the same socket or file descriptor to the same pollset
 *         multiple times, even if the requested events differ for the 
 *         different calls to apr_pollset_add().  If the events of interest
 *         for a descriptor change, you must first remove the descriptor 
 *         from the pollset with apr_pollset_remove(), then add it again 
 *         specifying all requested events.
 */
APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset,
                                          const apr_pollfd_t *descriptor);

/**
 * Remove a descriptor from a pollset
 * @param pollset The pollset from which to remove the descriptor
 * @param descriptor The descriptor to remove
 * @remark If the descriptor is not found, APR_NOTFOUND is returned.
 * @remark If the pollset has been created with APR_POLLSET_THREADSAFE
 *         and thread T1 is blocked in a call to apr_pollset_poll() for
 *         this same pollset that is being modified via apr_pollset_remove()
 *         in thread T2, the currently executing apr_pollset_poll() call in
 *         T1 will either: (1) automatically exclude the newly added descriptor
 *         in the set of descriptors it is watching or (2) return immediately
 *         with APR_EINTR.  Option (1) is recommended, but option (2) is
 *         allowed for implementations where option (1) is impossible
 *         or impractical.
 * @remark apr_pollset_remove() cannot be used to remove a subset of requested
 *         events for a descriptor.  The reqevents field in the apr_pollfd_t
 *         parameter must contain the same value when removing as when adding.
 */
APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset,
                                             const apr_pollfd_t *descriptor);

/**
 * Block for activity on the descriptor(s) in a pollset
 * @param pollset The pollset to use
 * @param timeout The amount of time in microseconds to wait.  This is a
 *                maximum, not a minimum.  If a descriptor is signalled, the
 *                function will return before this time.  If timeout is
 *                negative, the function will block until a descriptor is
 *                signalled or until apr_pollset_wakeup() has been called.
 * @param num Number of signalled descriptors (output parameter)
 * @param descriptors Array of signalled descriptors (output parameter)
 * @remark APR_EINTR will be returned if the pollset has been created with
 *         APR_POLLSET_WAKEABLE, apr_pollset_wakeup() has been called while
 *         waiting for activity, and there were no signalled descriptors at the
 *         time of the wakeup call.
 * @remark Multiple signalled conditions for the same descriptor may be reported
 *         in one or more returned apr_pollfd_t structures, depending on the
 *         implementation.
 */
APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset,
                                           apr_interval_time_t timeout,
                                           apr_int32_t *num,
                                           const apr_pollfd_t **descriptors);

/**
 * Interrupt the blocked apr_pollset_poll() call.
 * @param pollset The pollset to use
 * @remark If the pollset was not created with APR_POLLSET_WAKEABLE the
 *         return value is APR_EINIT.
 */
APR_DECLARE(apr_status_t) apr_pollset_wakeup(apr_pollset_t *pollset);

/**
 * Poll the descriptors in the poll structure
 * @param aprset The poll structure we will be using. 
 * @param numsock The number of descriptors we are polling
 * @param nsds The number of descriptors signalled (output parameter)
 * @param timeout The amount of time in microseconds to wait.  This is a
 *                maximum, not a minimum.  If a descriptor is signalled, the
 *                function will return before this time.  If timeout is
 *                negative, the function will block until a descriptor is
 *                signalled or until apr_pollset_wakeup() has been called.
 * @remark The number of descriptors signalled is returned in the third argument. 
 *         This is a blocking call, and it will not return until either a 
 *         descriptor has been signalled or the timeout has expired. 
 * @remark The rtnevents field in the apr_pollfd_t array will only be filled-
 *         in if the return value is APR_SUCCESS.
 */
APR_DECLARE(apr_status_t) apr_poll(apr_pollfd_t *aprset, apr_int32_t numsock,
                                   apr_int32_t *nsds, 
                                   apr_interval_time_t timeout);

/**
 * Return a printable representation of the pollset method.
 * @param pollset The pollset to use
 */
APR_DECLARE(const char *) apr_pollset_method_name(apr_pollset_t *pollset);

/**
 * Return a printable representation of the default pollset method
 * (APR_POLLSET_DEFAULT).
 */
APR_DECLARE(const char *) apr_poll_method_defname(void);

/** Opaque structure used for pollcb API */
typedef struct apr_pollcb_t apr_pollcb_t;

/**
 * Set up a pollcb object
 * @param pollcb  The pointer in which to return the newly created object 
 * @param size The maximum number of descriptors that a single _poll can return.
 * @param p The pool from which to allocate the pollcb
 * @param flags Optional flags to modify the operation of the pollcb.
 *
 * @remark If flags contains APR_POLLSET_WAKEABLE, then a pollcb is
 *         created with an additional internal pipe object used for the
 *         apr_pollcb_wakeup() call. The actual size of pollcb is
 *         in that case @a size + 1.
 * @remark Pollcb is only supported on some platforms; the apr_pollcb_create()
 *         call will fail with APR_ENOTIMPL on platforms where it is not supported.
 */
APR_DECLARE(apr_status_t) apr_pollcb_create(apr_pollcb_t **pollcb,
                                            apr_uint32_t size,
                                            apr_pool_t *p,
                                            apr_uint32_t flags);

/**
 * Set up a pollcb object
 * @param pollcb  The pointer in which to return the newly created object 
 * @param size The maximum number of descriptors that a single _poll can return.
 * @param p The pool from which to allocate the pollcb
 * @param flags Optional flags to modify the operation of the pollcb.
 * @param method Poll method to use. See #apr_pollset_method_e.  If this
 *         method cannot be used, the default method will be used unless the
 *         APR_POLLSET_NODEFAULT flag has been specified.
 *
 * @remark If flags contains APR_POLLSET_WAKEABLE, then a pollcb is
 *         created with an additional internal pipe object used for the
 *         apr_pollcb_wakeup() call. The actual size of pollcb is
 *         in that case @a size + 1.
 * @remark Pollcb is only supported on some platforms; the apr_pollcb_create_ex()
 *         call will fail with APR_ENOTIMPL on platforms where it is not supported.
 */
APR_DECLARE(apr_status_t) apr_pollcb_create_ex(apr_pollcb_t **pollcb,
                                               apr_uint32_t size,
                                               apr_pool_t *p,
                                               apr_uint32_t flags,
                                               apr_pollset_method_e method);

/**
 * Add a socket or file descriptor to a pollcb
 * @param pollcb The pollcb to which to add the descriptor
 * @param descriptor The descriptor to add
 * @remark If you set client_data in the descriptor, that value will be
 *         returned in the client_data field whenever this descriptor is
 *         signalled in apr_pollcb_poll().
 * @remark Unlike the apr_pollset API, the descriptor is not copied, and users 
 *         must retain the memory used by descriptor, as the same pointer will
 *         be returned to them from apr_pollcb_poll.
 * @remark Do not add the same socket or file descriptor to the same pollcb
 *         multiple times, even if the requested events differ for the 
 *         different calls to apr_pollcb_add().  If the events of interest
 *         for a descriptor change, you must first remove the descriptor 
 *         from the pollcb with apr_pollcb_remove(), then add it again 
 *         specifying all requested events.
 */
APR_DECLARE(apr_status_t) apr_pollcb_add(apr_pollcb_t *pollcb,
                                         apr_pollfd_t *descriptor);
/**
 * Remove a descriptor from a pollcb
 * @param pollcb The pollcb from which to remove the descriptor
 * @param descriptor The descriptor to remove
 * @remark If the descriptor is not found, APR_NOTFOUND is returned.
 * @remark apr_pollcb_remove() cannot be used to remove a subset of requested
 *         events for a descriptor.  The reqevents field in the apr_pollfd_t
 *         parameter must contain the same value when removing as when adding.
 */
APR_DECLARE(apr_status_t) apr_pollcb_remove(apr_pollcb_t *pollcb,
                                            apr_pollfd_t *descriptor);

/**
 * Function prototype for pollcb handlers 
 * @param baton Opaque baton passed into apr_pollcb_poll()
 * @param descriptor Contains the notification for an active descriptor. 
 *                   The @a rtnevents member describes which events were triggered
 *                   for this descriptor.
 * @remark If the pollcb handler does not return APR_SUCCESS, the apr_pollcb_poll()
 *         call returns with the handler's return value.
 */
typedef apr_status_t (*apr_pollcb_cb_t)(void *baton, apr_pollfd_t *descriptor);

/**
 * Block for activity on the descriptor(s) in a pollcb
 * @param pollcb The pollcb to use
 * @param timeout The amount of time in microseconds to wait.  This is a
 *                maximum, not a minimum.  If a descriptor is signalled, the
 *                function will return before this time.  If timeout is
 *                negative, the function will block until a descriptor is
 *                signalled or until apr_pollcb_wakeup() has been called.
 * @param func Callback function to call for each active descriptor.
 * @param baton Opaque baton passed to the callback function.
 * @remark Multiple signalled conditions for the same descriptor may be reported
 *         in one or more calls to the callback function, depending on the
 *         implementation.
 * @remark APR_EINTR will be returned if the pollset has been created with
 *         APR_POLLSET_WAKEABLE and apr_pollcb_wakeup() has been called while
 *         waiting for activity.
 */
APR_DECLARE(apr_status_t) apr_pollcb_poll(apr_pollcb_t *pollcb,
                                          apr_interval_time_t timeout,
                                          apr_pollcb_cb_t func,
                                          void *baton);

/**
 * Interrupt the blocked apr_pollcb_poll() call.
 * @param pollcb The pollcb to use
 * @remark If the pollcb was not created with APR_POLLSET_WAKEABLE the
 *         return value is APR_EINIT.
 */
APR_DECLARE(apr_status_t) apr_pollcb_wakeup(apr_pollcb_t *pollcb);

/**
 * Return a printable representation of the pollcb method.
 * @param pollcb The pollcb to use
 */
APR_DECLARE(const char *) apr_pollcb_method_name(apr_pollcb_t *pollcb);

/** @} */

#ifdef __cplusplus
}
#endif

#endif  /* ! APR_POLL_H */

apr-1/apr_file_io.h000064400000125606151730340540010121 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_FILE_IO_H
#define APR_FILE_IO_H

/**
 * @file apr_file_io.h
 * @brief APR File I/O Handling
 */

#include "apr.h"
#include "apr_pools.h"
#include "apr_time.h"
#include "apr_errno.h"
#include "apr_file_info.h"
#include "apr_inherit.h"

#define APR_WANT_STDIO          /**< for SEEK_* */
#define APR_WANT_IOVEC          /**< for apr_file_writev */
#include "apr_want.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @defgroup apr_file_io File I/O Handling Functions
 * @ingroup APR 
 * @{
 */

/**
 * @defgroup apr_file_open_flags File Open Flags/Routines
 * @{
 */

/* Note to implementors: Values in the range 0x00100000--0x80000000
   are reserved for platform-specific values. */

#define APR_FOPEN_READ       0x00001  /**< Open the file for reading */
#define APR_FOPEN_WRITE      0x00002  /**< Open the file for writing */
#define APR_FOPEN_CREATE     0x00004  /**< Create the file if not there */
#define APR_FOPEN_APPEND     0x00008  /**< Append to the end of the file */
#define APR_FOPEN_TRUNCATE   0x00010  /**< Open the file and truncate
                                         to 0 length */
#define APR_FOPEN_BINARY     0x00020  /**< Open the file in binary mode
				         (This flag is ignored on UNIX 
					 because it has no meaning)*/
#define APR_FOPEN_EXCL       0x00040  /**< Open should fail if #APR_FOPEN_CREATE
                                         and file exists. */
#define APR_FOPEN_BUFFERED   0x00080  /**< Open the file for buffered I/O */
#define APR_FOPEN_DELONCLOSE 0x00100  /**< Delete the file after close */
#define APR_FOPEN_XTHREAD    0x00200  /**< Platform dependent tag to open
                                         the file for use across multiple
                                         threads */
#define APR_FOPEN_SHARELOCK  0x00400  /**< Platform dependent support for
                                         higher level locked read/write
                                         access to support writes across
                                         process/machines */
#define APR_FOPEN_NOCLEANUP  0x00800  /**< Do not register a cleanup
                                         when the file is opened. The
					 apr_os_file_t handle in apr_file_t
					 will not be closed when the pool
					 is destroyed. */
#define APR_FOPEN_SENDFILE_ENABLED 0x01000 /**< Advisory flag that this
                                             file should support
                                             apr_socket_sendfile operation */
#define APR_FOPEN_LARGEFILE   0x04000 /**< Platform dependent flag to enable
                                       * large file support, see WARNING below
                                       */
#define APR_FOPEN_SPARSE      0x08000 /**< Platform dependent flag to enable
                                       * sparse file support, see WARNING below
                                       */
#define APR_FOPEN_NONBLOCK    0x40000 /**< Platform dependent flag to enable
                                       * non blocking file io */


/* backcompat */
#define APR_READ             APR_FOPEN_READ       /**< @deprecated @see APR_FOPEN_READ */
#define APR_WRITE            APR_FOPEN_WRITE      /**< @deprecated @see APR_FOPEN_WRITE */   
#define APR_CREATE           APR_FOPEN_CREATE     /**< @deprecated @see APR_FOPEN_CREATE */   
#define APR_APPEND           APR_FOPEN_APPEND     /**< @deprecated @see APR_FOPEN_APPEND */   
#define APR_TRUNCATE         APR_FOPEN_TRUNCATE   /**< @deprecated @see APR_FOPEN_TRUNCATE */   
#define APR_BINARY           APR_FOPEN_BINARY     /**< @deprecated @see APR_FOPEN_BINARY */   
#define APR_EXCL             APR_FOPEN_EXCL       /**< @deprecated @see APR_FOPEN_EXCL */   
#define APR_BUFFERED         APR_FOPEN_BUFFERED   /**< @deprecated @see APR_FOPEN_BUFFERED */   
#define APR_DELONCLOSE       APR_FOPEN_DELONCLOSE /**< @deprecated @see APR_FOPEN_DELONCLOSE */   
#define APR_XTHREAD          APR_FOPEN_XTHREAD    /**< @deprecated @see APR_FOPEN_XTHREAD */   
#define APR_SHARELOCK        APR_FOPEN_SHARELOCK  /**< @deprecated @see APR_FOPEN_SHARELOCK */   
#define APR_FILE_NOCLEANUP   APR_FOPEN_NOCLEANUP  /**< @deprecated @see APR_FOPEN_NOCLEANUP */   
#define APR_SENDFILE_ENABLED APR_FOPEN_SENDFILE_ENABLED /**< @deprecated @see APR_FOPEN_SENDFILE_ENABLED */   
#define APR_LARGEFILE        APR_FOPEN_LARGEFILE  /**< @deprecated @see APR_FOPEN_LARGEFILE */   

/** @def APR_FOPEN_LARGEFILE 
 * @warning APR_FOPEN_LARGEFILE flag only has effect on some
 * platforms where sizeof(apr_off_t) == 4.  Where implemented, it
 * allows opening and writing to a file which exceeds the size which
 * can be represented by apr_off_t (2 gigabytes).  When a file's size
 * does exceed 2Gb, apr_file_info_get() will fail with an error on the
 * descriptor, likewise apr_stat()/apr_lstat() will fail on the
 * filename.  apr_dir_read() will fail with #APR_INCOMPLETE on a
 * directory entry for a large file depending on the particular
 * APR_FINFO_* flags.  Generally, it is not recommended to use this
 * flag.
 *
 * @def APR_FOPEN_SPARSE
 * @warning APR_FOPEN_SPARSE may, depending on platform, convert a
 * normal file to a sparse file.  Some applications may be unable
 * to decipher a sparse file, so it's critical that the sparse file
 * flag should only be used for files accessed only by APR or other
 * applications known to be able to decipher them.  APR does not
 * guarantee that it will compress the file into sparse segments
 * if it was previously created and written without the sparse flag.
 * On platforms which do not understand, or on file systems which
 * cannot handle sparse files, the flag is ignored by apr_file_open().
 *
 * @def APR_FOPEN_NONBLOCK
 * @warning APR_FOPEN_NONBLOCK is not implemented on all platforms.
 * Callers should be prepared for it to fail with #APR_ENOTIMPL.
 */

/** @} */

/**
 * @defgroup apr_file_seek_flags File Seek Flags
 * @{
 */

/* flags for apr_file_seek */
/** Set the file position */
#define APR_SET SEEK_SET
/** Current */
#define APR_CUR SEEK_CUR
/** Go to end of file */
#define APR_END SEEK_END
/** @} */

/**
 * @defgroup apr_file_attrs_set_flags File Attribute Flags
 * @{
 */

/* flags for apr_file_attrs_set */
#define APR_FILE_ATTR_READONLY   0x01          /**< File is read-only */
#define APR_FILE_ATTR_EXECUTABLE 0x02          /**< File is executable */
#define APR_FILE_ATTR_HIDDEN     0x04          /**< File is hidden */
/** @} */

/**
 * @defgroup apr_file_writev{_full} max iovec size
 * @{
 */
#if defined(DOXYGEN)
#define APR_MAX_IOVEC_SIZE 1024                /**< System dependent maximum 
                                                    size of an iovec array */
#elif defined(IOV_MAX)
#define APR_MAX_IOVEC_SIZE IOV_MAX
#elif defined(MAX_IOVEC)
#define APR_MAX_IOVEC_SIZE MAX_IOVEC
#else
#define APR_MAX_IOVEC_SIZE 1024
#endif
/** @} */

/** File attributes */
typedef apr_uint32_t apr_fileattrs_t;

/** Type to pass as whence argument to apr_file_seek. */
typedef int       apr_seek_where_t;

/**
 * Structure for referencing files.
 */
typedef struct apr_file_t         apr_file_t;

/* File lock types/flags */
/**
 * @defgroup apr_file_lock_types File Lock Types
 * @{
 */

#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. */
#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". */

#define APR_FLOCK_TYPEMASK      0x000F  /**< mask to extract lock type */
#define APR_FLOCK_NONBLOCK      0x0010  /**< do not block while acquiring the
                                           file lock */
/** @} */

/**
 * Open the specified file.
 * @param newf The opened file descriptor.
 * @param fname The full path to the file (using / on all systems)
 * @param flag Or'ed value of:
 * @li #APR_FOPEN_READ           open for reading
 * @li #APR_FOPEN_WRITE          open for writing
 * @li #APR_FOPEN_CREATE         create the file if not there
 * @li #APR_FOPEN_APPEND         file ptr is set to end prior to all writes
 * @li #APR_FOPEN_TRUNCATE       set length to zero if file exists
 * @li #APR_FOPEN_BINARY         not a text file
 * @li #APR_FOPEN_BUFFERED       buffer the data.  Default is non-buffered
 * @li #APR_FOPEN_EXCL           return error if #APR_FOPEN_CREATE and file exists
 * @li #APR_FOPEN_DELONCLOSE     delete the file after closing
 * @li #APR_FOPEN_XTHREAD        Platform dependent tag to open the file
 *                               for use across multiple threads
 * @li #APR_FOPEN_SHARELOCK      Platform dependent support for higher
 *                               level locked read/write access to support
 *                               writes across process/machines
 * @li #APR_FOPEN_NOCLEANUP      Do not register a cleanup with the pool 
 *                               passed in on the @a pool argument (see below)
 * @li #APR_FOPEN_SENDFILE_ENABLED  Open with appropriate platform semantics
 *                               for sendfile operations.  Advisory only,
 *                               apr_socket_sendfile does not check this flag
 * @li #APR_FOPEN_LARGEFILE      Platform dependent flag to enable large file
 *                               support, see WARNING below 
 * @li #APR_FOPEN_SPARSE         Platform dependent flag to enable sparse file
 *                               support, see WARNING below
 * @li #APR_FOPEN_NONBLOCK       Platform dependent flag to enable
 *                               non blocking file io
 * @param perm Access permissions for file.
 * @param pool The pool to use.
 * @remark If perm is #APR_FPROT_OS_DEFAULT and the file is being created,
 * appropriate default permissions will be used.
 * @remark By default, the returned file descriptor will not be
 * inherited by child processes created by apr_proc_create().  This
 * can be changed using apr_file_inherit_set().
 */
APR_DECLARE(apr_status_t) apr_file_open(apr_file_t **newf, const char *fname,
                                        apr_int32_t flag, apr_fileperms_t perm,
                                        apr_pool_t *pool);

/**
 * Close the specified file.
 * @param file The file descriptor to close.
 */
APR_DECLARE(apr_status_t) apr_file_close(apr_file_t *file);

/**
 * Delete the specified file.
 * @param path The full path to the file (using / on all systems)
 * @param pool The pool to use.
 * @remark If the file is open, it won't be removed until all
 * instances are closed.
 */
APR_DECLARE(apr_status_t) apr_file_remove(const char *path, apr_pool_t *pool);

/**
 * Rename the specified file.
 * @param from_path The full path to the original file (using / on all systems)
 * @param to_path The full path to the new file (using / on all systems)
 * @param pool The pool to use.
 * @warning If a file exists at the new location, then it will be
 * overwritten.  Moving files or directories across devices may not be
 * possible.
 */
APR_DECLARE(apr_status_t) apr_file_rename(const char *from_path, 
                                          const char *to_path,
                                          apr_pool_t *pool);

/**
 * Create a hard link to the specified file.
 * @param from_path The full path to the original file (using / on all systems)
 * @param to_path The full path to the new file (using / on all systems)
 * @remark Both files must reside on the same device.
 */
APR_DECLARE(apr_status_t) apr_file_link(const char *from_path, 
                                          const char *to_path);

/**
 * Copy the specified file to another file.
 * @param from_path The full path to the original file (using / on all systems)
 * @param to_path The full path to the new file (using / on all systems)
 * @param perms Access permissions for the new file if it is created.
 *     In place of the usual or'd combination of file permissions, the
 *     value #APR_FPROT_FILE_SOURCE_PERMS may be given, in which case the source
 *     file's permissions are copied.
 * @param pool The pool to use.
 * @remark The new file does not need to exist, it will be created if required.
 * @warning If the new file already exists, its contents will be overwritten.
 */
APR_DECLARE(apr_status_t) apr_file_copy(const char *from_path, 
                                        const char *to_path,
                                        apr_fileperms_t perms,
                                        apr_pool_t *pool);

/**
 * Append the specified file to another file.
 * @param from_path The full path to the source file (use / on all systems)
 * @param to_path The full path to the destination file (use / on all systems)
 * @param perms Access permissions for the destination file if it is created.
 *     In place of the usual or'd combination of file permissions, the
 *     value #APR_FPROT_FILE_SOURCE_PERMS may be given, in which case the source
 *     file's permissions are copied.
 * @param pool The pool to use.
 * @remark The new file does not need to exist, it will be created if required.
 * @remark Note that advanced filesystem permissions such as ACLs are not
 * duplicated by this API. The target permissions (including duplicating the
 * source file permissions) are assigned only when the target file does not yet
 * exist.
 */
APR_DECLARE(apr_status_t) apr_file_append(const char *from_path, 
                                          const char *to_path,
                                          apr_fileperms_t perms,
                                          apr_pool_t *pool);

/**
 * Are we at the end of the file
 * @param fptr The apr file we are testing.
 * @remark Returns #APR_EOF if we are at the end of file, #APR_SUCCESS otherwise.
 */
APR_DECLARE(apr_status_t) apr_file_eof(apr_file_t *fptr);

/**
 * Open standard error as an apr file pointer.
 * @param thefile The apr file to use as stderr.
 * @param pool The pool to allocate the file out of.
 * 
 * @remark The only reason that the apr_file_open_std* functions exist
 * is that you may not always have a stderr/out/in on Windows.  This
 * is generally a problem with newer versions of Windows and services.
 * 
 * @remark The other problem is that the C library functions generally work
 * differently on Windows and Unix.  So, by using apr_file_open_std*
 * functions, you can get a handle to an APR struct that works with
 * the APR functions which are supposed to work identically on all
 * platforms.
 */
APR_DECLARE(apr_status_t) apr_file_open_stderr(apr_file_t **thefile,
                                               apr_pool_t *pool);

/**
 * open standard output as an apr file pointer.
 * @param thefile The apr file to use as stdout.
 * @param pool The pool to allocate the file out of.
 * 
 * @remark See remarks for apr_file_open_stderr().
 */
APR_DECLARE(apr_status_t) apr_file_open_stdout(apr_file_t **thefile,
                                               apr_pool_t *pool);

/**
 * open standard input as an apr file pointer.
 * @param thefile The apr file to use as stdin.
 * @param pool The pool to allocate the file out of.
 * 
 * @remark See remarks for apr_file_open_stderr().
 */
APR_DECLARE(apr_status_t) apr_file_open_stdin(apr_file_t **thefile,
                                              apr_pool_t *pool);

/**
 * open standard error as an apr file pointer, with flags.
 * @param thefile The apr file to use as stderr.
 * @param flags The flags to open the file with. Only the 
 *              @li #APR_FOPEN_EXCL
 *              @li #APR_FOPEN_BUFFERED
 *              @li #APR_FOPEN_XTHREAD
 *              @li #APR_FOPEN_SHARELOCK 
 *              @li #APR_FOPEN_SENDFILE_ENABLED
 *              @li #APR_FOPEN_LARGEFILE
 *
 *              flags should be used. The #APR_FOPEN_WRITE flag will
 *              be set unconditionally.
 * @param pool The pool to allocate the file out of.
 * 
 * @remark See remarks for apr_file_open_stderr().
 */
APR_DECLARE(apr_status_t) apr_file_open_flags_stderr(apr_file_t **thefile,
                                                     apr_int32_t flags,
                                                     apr_pool_t *pool);

/**
 * open standard output as an apr file pointer, with flags.
 * @param thefile The apr file to use as stdout.
 * @param flags The flags to open the file with. Only the 
 *              @li #APR_FOPEN_EXCL
 *              @li #APR_FOPEN_BUFFERED
 *              @li #APR_FOPEN_XTHREAD
 *              @li #APR_FOPEN_SHARELOCK 
 *              @li #APR_FOPEN_SENDFILE_ENABLED
 *              @li #APR_FOPEN_LARGEFILE
 *
 *              flags should be used. The #APR_FOPEN_WRITE flag will
 *              be set unconditionally.
 * @param pool The pool to allocate the file out of.
 * 
 * @remark See remarks for apr_file_open_stderr().
 */
APR_DECLARE(apr_status_t) apr_file_open_flags_stdout(apr_file_t **thefile,
                                                     apr_int32_t flags,
                                                     apr_pool_t *pool);

/**
 * open standard input as an apr file pointer, with flags.
 * @param thefile The apr file to use as stdin.
 * @param flags The flags to open the file with. Only the 
 *              @li #APR_FOPEN_EXCL
 *              @li #APR_FOPEN_BUFFERED
 *              @li #APR_FOPEN_XTHREAD
 *              @li #APR_FOPEN_SHARELOCK 
 *              @li #APR_FOPEN_SENDFILE_ENABLED
 *              @li #APR_FOPEN_LARGEFILE
 *
 *              flags should be used. The #APR_FOPEN_WRITE flag will
 *              be set unconditionally.
 * @param pool The pool to allocate the file out of.
 * 
 * @remark See remarks for apr_file_open_stderr().
 */
APR_DECLARE(apr_status_t) apr_file_open_flags_stdin(apr_file_t **thefile,
                                                     apr_int32_t flags,
                                                     apr_pool_t *pool);

/**
 * Read data from the specified file.
 * @param thefile The file descriptor to read from.
 * @param buf The buffer to store the data to.
 * @param nbytes On entry, the number of bytes to read; on exit, the number
 * of bytes read.
 *
 * @remark apr_file_read() will read up to the specified number of
 * bytes, but never more.  If there isn't enough data to fill that
 * number of bytes, all of the available data is read.  The third
 * argument is modified to reflect the number of bytes read.  If a
 * char was put back into the stream via ungetc, it will be the first
 * character returned.
 *
 * @remark It is not possible for both bytes to be read and an #APR_EOF
 * or other error to be returned.  #APR_EINTR is never returned.
 */
APR_DECLARE(apr_status_t) apr_file_read(apr_file_t *thefile, void *buf,
                                        apr_size_t *nbytes);

/**
 * Write data to the specified file.
 * @param thefile The file descriptor to write to.
 * @param buf The buffer which contains the data.
 * @param nbytes On entry, the number of bytes to write; on exit, the number 
 *               of bytes written.
 *
 * @remark apr_file_write() will write up to the specified number of
 * bytes, but never more.  If the OS cannot write that many bytes, it
 * will write as many as it can.  The third argument is modified to
 * reflect the * number of bytes written.
 *
 * @remark It is possible for both bytes to be written and an error to
 * be returned.  #APR_EINTR is never returned.
 */
APR_DECLARE(apr_status_t) apr_file_write(apr_file_t *thefile, const void *buf,
                                         apr_size_t *nbytes);

/**
 * Write data from iovec array to the specified file.
 * @param thefile The file descriptor to write to.
 * @param vec The array from which to get the data to write to the file.
 * @param nvec The number of elements in the struct iovec array. This must 
 *             be smaller than #APR_MAX_IOVEC_SIZE.  If it isn't, the function 
 *             will fail with #APR_EINVAL.
 * @param nbytes The number of bytes written.
 *
 * @remark It is possible for both bytes to be written and an error to
 * be returned.  #APR_EINTR is never returned.
 *
 * @remark apr_file_writev() is available even if the underlying
 * operating system doesn't provide writev().
 */
APR_DECLARE(apr_status_t) apr_file_writev(apr_file_t *thefile,
                                          const struct iovec *vec,
                                          apr_size_t nvec, apr_size_t *nbytes);

/**
 * Read data from the specified file, ensuring that the buffer is filled
 * before returning.
 * @param thefile The file descriptor to read from.
 * @param buf The buffer to store the data to.
 * @param nbytes The number of bytes to read.
 * @param bytes_read If non-NULL, this will contain the number of bytes read.
 *
 * @remark apr_file_read_full() will read up to the specified number of
 * bytes, but never more.  If there isn't enough data to fill that
 * number of bytes, then the process/thread will block until it is
 * available or EOF is reached.  If a char was put back into the
 * stream via ungetc, it will be the first character returned.
 *
 * @remark It is possible for both bytes to be read and an error to be
 * returned.  And if *bytes_read is less than nbytes, an accompanying
 * error is _always_ returned.
 *
 * @remark #APR_EINTR is never returned.
 */
APR_DECLARE(apr_status_t) apr_file_read_full(apr_file_t *thefile, void *buf,
                                             apr_size_t nbytes,
                                             apr_size_t *bytes_read);

/**
 * Write data to the specified file, ensuring that all of the data is
 * written before returning.
 * @param thefile The file descriptor to write to.
 * @param buf The buffer which contains the data.
 * @param nbytes The number of bytes to write.
 * @param bytes_written If non-NULL, set to the number of bytes written.
 * 
 * @remark apr_file_write_full() will write up to the specified number of
 * bytes, but never more.  If the OS cannot write that many bytes, the
 * process/thread will block until they can be written. Exceptional
 * error such as "out of space" or "pipe closed" will terminate with
 * an error.
 *
 * @remark It is possible for both bytes to be written and an error to
 * be returned.  And if *bytes_written is less than nbytes, an
 * accompanying error is _always_ returned.
 *
 * @remark #APR_EINTR is never returned.
 */
APR_DECLARE(apr_status_t) apr_file_write_full(apr_file_t *thefile, 
                                              const void *buf,
                                              apr_size_t nbytes, 
                                              apr_size_t *bytes_written);


/**
 * Write data from iovec array to the specified file, ensuring that all of the
 * data is written before returning.
 * @param thefile The file descriptor to write to.
 * @param vec The array from which to get the data to write to the file.
 * @param nvec The number of elements in the struct iovec array. This must 
 *             be smaller than #APR_MAX_IOVEC_SIZE.  If it isn't, the function 
 *             will fail with #APR_EINVAL.
 * @param nbytes The number of bytes written.
 *
 * @remark apr_file_writev_full() is available even if the underlying
 * operating system doesn't provide writev().
 */
APR_DECLARE(apr_status_t) apr_file_writev_full(apr_file_t *thefile,
                                               const struct iovec *vec,
                                               apr_size_t nvec,
                                               apr_size_t *nbytes);
/**
 * Write a character into the specified file.
 * @param ch The character to write.
 * @param thefile The file descriptor to write to
 */
APR_DECLARE(apr_status_t) apr_file_putc(char ch, apr_file_t *thefile);

/**
 * Read a character from the specified file.
 * @param ch The character to read into
 * @param thefile The file descriptor to read from
 */
APR_DECLARE(apr_status_t) apr_file_getc(char *ch, apr_file_t *thefile);

/**
 * Put a character back onto a specified stream.
 * @param ch The character to write.
 * @param thefile The file descriptor to write to
 */
APR_DECLARE(apr_status_t) apr_file_ungetc(char ch, apr_file_t *thefile);

/**
 * Read a line from the specified file
 * @param str The buffer to store the string in. 
 * @param len The length of the string
 * @param thefile The file descriptor to read from
 * @remark The buffer will be NUL-terminated if any characters are stored.
 *         The newline at the end of the line will not be stripped.
 */
APR_DECLARE(apr_status_t) apr_file_gets(char *str, int len, 
                                        apr_file_t *thefile);

/**
 * Write the string into the specified file.
 * @param str The string to write. 
 * @param thefile The file descriptor to write to
 */
APR_DECLARE(apr_status_t) apr_file_puts(const char *str, apr_file_t *thefile);

/**
 * Flush the file's buffer.
 * @param thefile The file descriptor to flush
 */
APR_DECLARE(apr_status_t) apr_file_flush(apr_file_t *thefile);

/**
 * Transfer all file modified data and metadata to disk.
 * @param thefile The file descriptor to sync
 */
APR_DECLARE(apr_status_t) apr_file_sync(apr_file_t *thefile);

/**
 * Transfer all file modified data to disk.
 * @param thefile The file descriptor to sync
 */
APR_DECLARE(apr_status_t) apr_file_datasync(apr_file_t *thefile);

/**
 * Duplicate the specified file descriptor.
 * @param new_file The structure to duplicate into. 
 * @param old_file The file to duplicate.
 * @param p The pool to use for the new file.
 * @remark *new_file must point to a valid apr_file_t, or point to NULL.
 */         
APR_DECLARE(apr_status_t) apr_file_dup(apr_file_t **new_file,
                                       apr_file_t *old_file,
                                       apr_pool_t *p);

/**
 * Duplicate the specified file descriptor and close the original
 * @param new_file The old file that is to be closed and reused
 * @param old_file The file to duplicate
 * @param p        The pool to use for the new file
 *
 * @remark new_file MUST point at a valid apr_file_t. It cannot be NULL.
 */
APR_DECLARE(apr_status_t) apr_file_dup2(apr_file_t *new_file,
                                        apr_file_t *old_file,
                                        apr_pool_t *p);

/**
 * Move the specified file descriptor to a new pool
 * @param new_file Pointer in which to return the new apr_file_t
 * @param old_file The file to move
 * @param p        The pool to which the descriptor is to be moved
 * @remark Unlike apr_file_dup2(), this function doesn't do an
 *         OS dup() operation on the underlying descriptor; it just
 *         moves the descriptor's apr_file_t wrapper to a new pool.
 * @remark The new pool need not be an ancestor of old_file's pool.
 * @remark After calling this function, old_file may not be used
 */
APR_DECLARE(apr_status_t) apr_file_setaside(apr_file_t **new_file,
                                            apr_file_t *old_file,
                                            apr_pool_t *p);

/**
 * Give the specified apr file handle a new buffer 
 * @param thefile  The file handle that is to be modified
 * @param buffer   The buffer
 * @param bufsize  The size of the buffer
 * @remark It is possible to add a buffer to previously unbuffered
 *         file handles, the #APR_FOPEN_BUFFERED flag will be added to
 *         the file handle's flags. Likewise, with buffer=NULL and
 *         bufsize=0 arguments it is possible to make a previously
 *         buffered file handle unbuffered.
 */
APR_DECLARE(apr_status_t) apr_file_buffer_set(apr_file_t *thefile,
                                              char * buffer,
                                              apr_size_t bufsize);

/**
 * Get the size of any buffer for the specified apr file handle 
 * @param thefile  The file handle 
 */
APR_DECLARE(apr_size_t) apr_file_buffer_size_get(apr_file_t *thefile);

/**
 * Move the read/write file offset to a specified byte within a file.
 * @param thefile The file descriptor
 * @param where How to move the pointer, one of:
 *              @li #APR_SET  --  set the offset to offset
 *              @li #APR_CUR  --  add the offset to the current position 
 *              @li #APR_END  --  add the offset to the current file size 
 * @param offset The offset to move the pointer to.
 * @remark The third argument is modified to be the offset the pointer
          was actually moved to.
 */
APR_DECLARE(apr_status_t) apr_file_seek(apr_file_t *thefile, 
                                   apr_seek_where_t where,
                                   apr_off_t *offset);

/**
 * Create an anonymous pipe.
 * @param in The newly created pipe's file for reading.
 * @param out The newly created pipe's file for writing.
 * @param pool The pool to operate on.
 * @remark By default, the returned file descriptors will be inherited
 * by child processes created using apr_proc_create().  This can be
 * changed using apr_file_inherit_unset().
 * @bug  Some platforms cannot toggle between blocking and nonblocking,
 * and when passing a pipe as a standard handle to an application which
 * does not expect it, a non-blocking stream will fluxor the client app.
 * @deprecated @see apr_file_pipe_create_pools()
 */
APR_DECLARE(apr_status_t) apr_file_pipe_create(apr_file_t **in, 
                                               apr_file_t **out,
                                               apr_pool_t *pool);

/**
 * Create an anonymous pipe which portably supports async timeout options.
 * @param in The newly created pipe's file for reading.
 * @param out The newly created pipe's file for writing.
 * @param blocking one of these values defined in apr_thread_proc.h;
 *                 @li #APR_FULL_BLOCK
 *                 @li #APR_READ_BLOCK
 *                 @li #APR_WRITE_BLOCK
 *                 @li #APR_FULL_NONBLOCK
 * @param pool The pool to operate on.
 * @remark By default, the returned file descriptors will be inherited
 * by child processes created using apr_proc_create().  This can be
 * changed using apr_file_inherit_unset().
 * @remark Some platforms cannot toggle between blocking and nonblocking,
 * and when passing a pipe as a standard handle to an application which
 * does not expect it, a non-blocking stream will fluxor the client app.
 * Use this function rather than apr_file_pipe_create() to create pipes 
 * where one or both ends require non-blocking semantics.
 * @deprecated @see apr_file_pipe_create_pools()
 */
APR_DECLARE(apr_status_t) apr_file_pipe_create_ex(apr_file_t **in, 
                                                  apr_file_t **out, 
                                                  apr_int32_t blocking, 
                                                  apr_pool_t *pool);

/**
 * Create an anonymous pipe which portably supports async timeout options,
 * placing each side of the pipe in a different pool.
 * @param in The newly created pipe's file for reading.
 * @param out The newly created pipe's file for writing.
 * @param blocking one of these values defined in apr_thread_proc.h;
 *                 @li #APR_FULL_BLOCK
 *                 @li #APR_READ_BLOCK
 *                 @li #APR_WRITE_BLOCK
 *                 @li #APR_FULL_NONBLOCK
 * @param pool_in The pool for the reading pipe.
 * @param pool_out The pool for the writing pipe.
 * @remark By default, the returned file descriptors will be inherited
 * by child processes created using apr_proc_create().  This can be
 * changed using apr_file_inherit_unset().
 * @remark Some platforms cannot toggle between blocking and nonblocking,
 * and when passing a pipe as a standard handle to an application which
 * does not expect it, a non-blocking stream will fluxor the client app.
 * Use this function rather than apr_file_pipe_create() to create pipes
 * where one or both ends require non-blocking semantics.
 */
APR_DECLARE(apr_status_t) apr_file_pipe_create_pools(apr_file_t **in,
                                                     apr_file_t **out,
                                                     apr_int32_t blocking,
                                                     apr_pool_t *pool_in,
                                                     apr_pool_t *pool_out);

/**
 * Create a named pipe.
 * @param filename The filename of the named pipe
 * @param perm The permissions for the newly created pipe.
 * @param pool The pool to operate on.
 */
APR_DECLARE(apr_status_t) apr_file_namedpipe_create(const char *filename, 
                                                    apr_fileperms_t perm, 
                                                    apr_pool_t *pool);

/**
 * Get the timeout value for a pipe or manipulate the blocking state.
 * @param thepipe The pipe we are getting a timeout for.
 * @param timeout The current timeout value in microseconds. 
 */
APR_DECLARE(apr_status_t) apr_file_pipe_timeout_get(apr_file_t *thepipe, 
                                               apr_interval_time_t *timeout);

/**
 * Set the timeout value for a pipe or manipulate the blocking state.
 * @param thepipe The pipe we are setting a timeout on.
 * @param timeout The timeout value in microseconds.  Values < 0 mean wait 
 *        forever, 0 means do not wait at all.
 */
APR_DECLARE(apr_status_t) apr_file_pipe_timeout_set(apr_file_t *thepipe, 
                                                  apr_interval_time_t timeout);

/** file (un)locking functions. */

/**
 * Establish a lock on the specified, open file. The lock may be advisory
 * or mandatory, at the discretion of the platform. The lock applies to
 * the file as a whole, rather than a specific range. Locks are established
 * on a per-thread/process basis; a second lock by the same thread will not
 * block.
 * @param thefile The file to lock.
 * @param type The type of lock to establish on the file.
 */
APR_DECLARE(apr_status_t) apr_file_lock(apr_file_t *thefile, int type);

/**
 * Remove any outstanding locks on the file.
 * @param thefile The file to unlock.
 */
APR_DECLARE(apr_status_t) apr_file_unlock(apr_file_t *thefile);

/**accessor and general file_io functions. */

/**
 * return the file name of the current file.
 * @param new_path The path of the file.  
 * @param thefile The currently open file.
 */                     
APR_DECLARE(apr_status_t) apr_file_name_get(const char **new_path, 
                                            apr_file_t *thefile);
    
/**
 * Return the data associated with the current file.
 * @param data The user data associated with the file.  
 * @param key The key to use for retrieving data associated with this file.
 * @param file The currently open file.
 */                     
APR_DECLARE(apr_status_t) apr_file_data_get(void **data, const char *key, 
                                            apr_file_t *file);

/**
 * Set the data associated with the current file.
 * @param file The currently open file.
 * @param data The user data to associate with the file.  
 * @param key The key to use for associating data with the file.
 * @param cleanup The cleanup routine to use when the file is destroyed.
 */                     
APR_DECLARE(apr_status_t) apr_file_data_set(apr_file_t *file, void *data,
                                            const char *key,
                                            apr_status_t (*cleanup)(void *));

/**
 * Write a string to a file using a printf format.
 * @param fptr The file to write to.
 * @param format The format string
 * @param ... The values to substitute in the format string
 * @return The number of bytes written
 */ 
APR_DECLARE_NONSTD(int) apr_file_printf(apr_file_t *fptr, 
                                        const char *format, ...)
        __attribute__((format(printf,2,3)));

/**
 * set the specified file's permission bits.
 * @param fname The file (name) to apply the permissions to.
 * @param perms The permission bits to apply to the file.
 *
 * @warning Some platforms may not be able to apply all of the
 * available permission bits; #APR_INCOMPLETE will be returned if some
 * permissions are specified which could not be set.
 *
 * @warning Platforms which do not implement this feature will return
 * #APR_ENOTIMPL.
 */
APR_DECLARE(apr_status_t) apr_file_perms_set(const char *fname,
                                             apr_fileperms_t perms);

/**
 * Set attributes of the specified file.
 * @param fname The full path to the file (using / on all systems)
 * @param attributes Or'd combination of
 *            @li #APR_FILE_ATTR_READONLY   - make the file readonly
 *            @li #APR_FILE_ATTR_EXECUTABLE - make the file executable
 *            @li #APR_FILE_ATTR_HIDDEN     - make the file hidden
 * @param attr_mask Mask of valid bits in attributes.
 * @param pool the pool to use.
 * @remark This function should be used in preference to explicit manipulation
 *      of the file permissions, because the operations to provide these
 *      attributes are platform specific and may involve more than simply
 *      setting permission bits.
 * @warning Platforms which do not implement this feature will return
 *      #APR_ENOTIMPL.
 */
APR_DECLARE(apr_status_t) apr_file_attrs_set(const char *fname,
                                             apr_fileattrs_t attributes,
                                             apr_fileattrs_t attr_mask,
                                             apr_pool_t *pool);

/**
 * Set the mtime of the specified file.
 * @param fname The full path to the file (using / on all systems)
 * @param mtime The mtime to apply to the file.
 * @param pool The pool to use.
 * @warning Platforms which do not implement this feature will return
 *      #APR_ENOTIMPL.
 */
APR_DECLARE(apr_status_t) apr_file_mtime_set(const char *fname,
                                             apr_time_t mtime,
                                             apr_pool_t *pool);

/**
 * Create a new directory on the file system.
 * @param path the path for the directory to be created. (use / on all systems)
 * @param perm Permissions for the new directory.
 * @param pool the pool to use.
 */                        
APR_DECLARE(apr_status_t) apr_dir_make(const char *path, apr_fileperms_t perm, 
                                       apr_pool_t *pool);

/** Creates a new directory on the file system, but behaves like
 * 'mkdir -p'. Creates intermediate directories as required. No error
 * will be reported if PATH already exists.
 * @param path the path for the directory to be created. (use / on all systems)
 * @param perm Permissions for the new directory.
 * @param pool the pool to use.
 */
APR_DECLARE(apr_status_t) apr_dir_make_recursive(const char *path,
                                                 apr_fileperms_t perm,
                                                 apr_pool_t *pool);

/**
 * Remove directory from the file system.
 * @param path the path for the directory to be removed. (use / on all systems)
 * @param pool the pool to use.
 * @remark Removing a directory which is in-use (e.g., the current working
 * directory, or during apr_dir_read, or with an open file) is not portable.
 */                        
APR_DECLARE(apr_status_t) apr_dir_remove(const char *path, apr_pool_t *pool);

/**
 * get the specified file's stats.
 * @param finfo Where to store the information about the file.
 * @param wanted The desired apr_finfo_t fields, as a bit flag of APR_FINFO_* values 
 * @param thefile The file to get information about.
 */ 
APR_DECLARE(apr_status_t) apr_file_info_get(apr_finfo_t *finfo, 
                                            apr_int32_t wanted,
                                            apr_file_t *thefile);
    

/**
 * Truncate the file's length to the specified offset
 * @param fp The file to truncate
 * @param offset The offset to truncate to.
 * @remark The read/write file offset is repositioned to offset.
 */
APR_DECLARE(apr_status_t) apr_file_trunc(apr_file_t *fp, apr_off_t offset);

/**
 * Retrieve the flags that were passed into apr_file_open()
 * when the file was opened.
 * @return apr_int32_t the flags
 */
APR_DECLARE(apr_int32_t) apr_file_flags_get(apr_file_t *f);

/**
 * Get the pool used by the file.
 */
APR_POOL_DECLARE_ACCESSOR(file);

/**
 * Set a file to be inherited by child processes.
 *
 */
APR_DECLARE_INHERIT_SET(file);

/**
 * Unset a file from being inherited by child processes.
 */
APR_DECLARE_INHERIT_UNSET(file);

/**
 * Open a temporary file
 * @param fp The apr file to use as a temporary file.
 * @param templ The template to use when creating a temp file.
 * @param flags The flags to open the file with. If this is zero,
 *              the file is opened with 
 *              #APR_FOPEN_CREATE | #APR_FOPEN_READ | #APR_FOPEN_WRITE |
 *              #APR_FOPEN_EXCL | #APR_FOPEN_DELONCLOSE
 * @param p The pool to allocate the file out of.
 * @remark   
 * This function  generates  a unique temporary file name from template.  
 * The last six characters of template must be XXXXXX and these are replaced 
 * with a string that makes the filename unique. Since it will  be  modified,
 * template must not be a string constant, but should be declared as a character
 * array.  
 *
 */
APR_DECLARE(apr_status_t) apr_file_mktemp(apr_file_t **fp, char *templ,
                                          apr_int32_t flags, apr_pool_t *p);


/**
 * Find an existing directory suitable as a temporary storage location.
 * @param temp_dir The temp directory.
 * @param p The pool to use for any necessary allocations.
 * @remark   
 * This function uses an algorithm to search for a directory that an
 * an application can use for temporary storage.
 *
 */
APR_DECLARE(apr_status_t) apr_temp_dir_get(const char **temp_dir, 
                                           apr_pool_t *p);

/**
 * Get the specified file's stats.  The file is specified by file
 * descriptor. 
 * @param finfo Where to store the information about the file, which is
 * never touched if the call fails.
 * @param fd The file descriptor of the file to stat.
 * @param wanted The desired apr_finfo_t fields, as a bit flag of APR_FINFO_
                 values 
 * @param pool the pool to use to allocate the new file. 
 *
 * @note If @c APR_INCOMPLETE is returned all the fields in @a finfo may
 *       not be filled in, and you need to check the @c finfo->valid bitmask
 *       to verify that what you're looking for is there.
 */ 
APR_DECLARE(apr_status_t) apr_stat_fd(apr_finfo_t *finfo, apr_file_t *fd,
                                   apr_int32_t wanted, apr_pool_t *pool);

/** @} */

#ifdef __cplusplus
}
#endif

#endif  /* ! APR_FILE_IO_H */
apr-1/apr_allocator.h000064400000014111151730340540010457 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_ALLOCATOR_H
#define APR_ALLOCATOR_H

/**
 * @file apr_allocator.h
 * @brief APR Internal Memory Allocation
 */

#include "apr.h"
#include "apr_errno.h"
#define APR_WANT_MEMFUNC /**< For no good reason? */
#include "apr_want.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @defgroup apr_allocator Internal Memory Allocation
 * @ingroup APR 
 * @{
 */

/** the allocator structure */
typedef struct apr_allocator_t apr_allocator_t;
/** the structure which holds information about the allocation */
typedef struct apr_memnode_t apr_memnode_t;

/** basic memory node structure
 * @note The next, ref and first_avail fields are available for use by the
 *       caller of apr_allocator_alloc(), the remaining fields are read-only.
 *       The next field has to be used with caution and sensibly set when the
 *       memnode is passed back to apr_allocator_free().  See apr_allocator_free()
 *       for details.  
 *       The ref and first_avail fields will be properly restored by
 *       apr_allocator_free().
 */
struct apr_memnode_t {
    apr_memnode_t *next;            /**< next memnode */
    apr_memnode_t **ref;            /**< reference to self */
    apr_uint32_t   index;           /**< size */
    apr_uint32_t   free_index;      /**< how much free */
    char          *first_avail;     /**< pointer to first free memory */
    char          *endp;            /**< pointer to end of free memory */
};

/** The base size of a memory node - aligned.  */
#define APR_MEMNODE_T_SIZE APR_ALIGN_DEFAULT(sizeof(apr_memnode_t))

/** Symbolic constants */
#define APR_ALLOCATOR_MAX_FREE_UNLIMITED 0

/**
 * Create a new allocator
 * @param allocator The allocator we have just created.
 *
 */
APR_DECLARE(apr_status_t) apr_allocator_create(apr_allocator_t **allocator)
                          __attribute__((nonnull(1)));

/**
 * Destroy an allocator
 * @param allocator The allocator to be destroyed
 * @remark Any memnodes not given back to the allocator prior to destroying
 *         will _not_ be free()d.
 */
APR_DECLARE(void) apr_allocator_destroy(apr_allocator_t *allocator)
                  __attribute__((nonnull(1)));

/**
 * Allocate a block of mem from the allocator
 * @param allocator The allocator to allocate from
 * @param size The size of the mem to allocate (excluding the
 *        memnode structure)
 */
APR_DECLARE(apr_memnode_t *) apr_allocator_alloc(apr_allocator_t *allocator,
                                                 apr_size_t size)
                             __attribute__((nonnull(1)));

/**
 * Free a list of blocks of mem, giving them back to the allocator.
 * The list is typically terminated by a memnode with its next field
 * set to NULL.
 * @param allocator The allocator to give the mem back to
 * @param memnode The memory node to return
 */
APR_DECLARE(void) apr_allocator_free(apr_allocator_t *allocator,
                                     apr_memnode_t *memnode)
                  __attribute__((nonnull(1,2)));
 
/**
 * Get the true size that would be allocated for the given size (including
 * the header and alignment).
 * @param allocator The allocator from which to the memory would be allocated
 * @param size The size to align
 * @return The aligned size (or zero on apr_size_t overflow)
 */
APR_DECLARE(apr_size_t) apr_allocator_align(apr_allocator_t *allocator,
                                            apr_size_t size);

#include "apr_pools.h"

/**
 * Set the owner of the allocator
 * @param allocator The allocator to set the owner for
 * @param pool The pool that is to own the allocator
 * @remark Typically pool is the highest level pool using the allocator
 */
/*
 * XXX: see if we can come up with something a bit better.  Currently
 * you can make a pool an owner, but if the pool doesn't use the allocator
 * the allocator will never be destroyed.
 */
APR_DECLARE(void) apr_allocator_owner_set(apr_allocator_t *allocator,
                                          apr_pool_t *pool)
                  __attribute__((nonnull(1)));

/**
 * Get the current owner of the allocator
 * @param allocator The allocator to get the owner from
 */
APR_DECLARE(apr_pool_t *) apr_allocator_owner_get(apr_allocator_t *allocator)
                          __attribute__((nonnull(1)));

/**
 * Set the current threshold at which the allocator should start
 * giving blocks back to the system.
 * @param allocator The allocator to set the threshold on
 * @param size The threshold.  0 == unlimited.
 */
APR_DECLARE(void) apr_allocator_max_free_set(apr_allocator_t *allocator,
                                             apr_size_t size)
                  __attribute__((nonnull(1)));

#include "apr_thread_mutex.h"

#if APR_HAS_THREADS
/**
 * Set a mutex for the allocator to use
 * @param allocator The allocator to set the mutex for
 * @param mutex The mutex
 */
APR_DECLARE(void) apr_allocator_mutex_set(apr_allocator_t *allocator,
                                          apr_thread_mutex_t *mutex)
                  __attribute__((nonnull(1)));

/**
 * Get the mutex currently set for the allocator
 * @param allocator The allocator
 */
APR_DECLARE(apr_thread_mutex_t *) apr_allocator_mutex_get(
                                          apr_allocator_t *allocator)
                                  __attribute__((nonnull(1)));

#endif /* APR_HAS_THREADS */

/** @} */

#ifdef __cplusplus
}
#endif

#endif /* !APR_ALLOCATOR_H */
apr-1/apr_reslist.h000064400000016010151730340540010164 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_RESLIST_H
#define APR_RESLIST_H

/** 
 * @file apr_reslist.h
 * @brief APR-UTIL Resource List Routines
 */

#include "apr.h"
#include "apu.h"
#include "apr_pools.h"
#include "apr_errno.h"
#include "apr_time.h"

/**
 * @defgroup APR_Util_RL Resource List Routines
 * @ingroup APR_Util
 * @{
 */

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/** Opaque resource list object */
typedef struct apr_reslist_t apr_reslist_t;

/* Generic constructor called by resource list when it needs to create a
 * resource.
 * @param resource opaque resource
 * @param params flags
 * @param pool  Pool
 */
typedef apr_status_t (*apr_reslist_constructor)(void **resource, void *params,
                                                apr_pool_t *pool);

/* Generic destructor called by resource list when it needs to destroy a
 * resource.
 * @param resource opaque resource
 * @param params flags
 * @param pool  Pool
 */
typedef apr_status_t (*apr_reslist_destructor)(void *resource, void *params,
                                               apr_pool_t *pool);

/* Cleanup order modes */
#define APR_RESLIST_CLEANUP_DEFAULT  0       /**< default pool cleanup */
#define APR_RESLIST_CLEANUP_FIRST    1       /**< use pool pre cleanup */

/**
 * Create a new resource list with the following parameters:
 * @param reslist An address where the pointer to the new resource
 *                list will be stored.
 * @param min Allowed minimum number of available resources. Zero
 *            creates new resources only when needed.
 * @param smax Resources will be destroyed during reslist maintenance to
 *             meet this maximum restriction as they expire (reach their ttl).
 * @param hmax Absolute maximum limit on the number of total resources.
 * @param ttl If non-zero, sets the maximum amount of time in microseconds an
 *            unused resource is valid.  Any resource which has exceeded this
 *            time will be destroyed, either when encountered by
 *            apr_reslist_acquire() or during reslist maintenance.
 * @param con Constructor routine that is called to create a new resource.
 * @param de Destructor routine that is called to destroy an expired resource.
 * @param params Passed to constructor and deconstructor
 * @param pool The pool from which to create this resource list. Also the
 *             same pool that is passed to the constructor and destructor
 *             routines.
 * @remark If APR has been compiled without thread support, hmax will be
 *         automatically set to 1 and values of min and smax will be forced to
 *         1 for any non-zero value.
 */
APU_DECLARE(apr_status_t) apr_reslist_create(apr_reslist_t **reslist,
                                             int min, int smax, int hmax,
                                             apr_interval_time_t ttl,
                                             apr_reslist_constructor con,
                                             apr_reslist_destructor de,
                                             void *params,
                                             apr_pool_t *pool);

/**
 * Destroy the given resource list and all resources controlled by
 * this list.
 * FIXME: Should this block until all resources become available,
 *        or maybe just destroy all the free ones, or maybe destroy
 *        them even though they might be in use by something else?
 *        Currently it will abort if there are resources that haven't
 *        been released, so there is an assumption that all resources
 *        have been released to the list before calling this function.
 * @param reslist The reslist to destroy
 */
APU_DECLARE(apr_status_t) apr_reslist_destroy(apr_reslist_t *reslist);

/**
 * Retrieve a resource from the list, creating a new one if necessary.
 * If we have met our maximum number of resources, we will block
 * until one becomes available.
 * @param reslist The resource list.
 * @param resource An address where the pointer to the resource
 *                will be stored.
 */
APU_DECLARE(apr_status_t) apr_reslist_acquire(apr_reslist_t *reslist,
                                              void **resource);

/**
 * Return a resource back to the list of available resources.
 * @param reslist The resource list.
 * @param resource The resource to return to the list.
 */
APU_DECLARE(apr_status_t) apr_reslist_release(apr_reslist_t *reslist,
                                              void *resource);

/**
 * Set the timeout the acquire will wait for a free resource
 * when the maximum number of resources is exceeded.
 * @param reslist The resource list.
 * @param timeout Timeout to wait. The zero waits forever.
 */
APU_DECLARE(void) apr_reslist_timeout_set(apr_reslist_t *reslist,
                                          apr_interval_time_t timeout);

/**
 * Return the number of outstanding resources.
 * @param reslist The resource list.
 */
APU_DECLARE(apr_uint32_t) apr_reslist_acquired_count(apr_reslist_t *reslist);

/**
 * Invalidate a resource in the pool - e.g. a database connection
 * that returns a "lost connection" error and can't be restored.
 * Use this instead of apr_reslist_release if the resource is bad.
 * @param reslist The resource list.
 * @param resource The resource to invalidate.
 */
APU_DECLARE(apr_status_t) apr_reslist_invalidate(apr_reslist_t *reslist,
                                                 void *resource);

/**
 * Perform routine maintenance on the resource list. This call
 * may instantiate new resources or expire old resources.
 * @param reslist The resource list.
 */
APU_DECLARE(apr_status_t) apr_reslist_maintain(apr_reslist_t *reslist);

/**
 * Set reslist cleanup order.
 * @param reslist The resource list.
 * @param mode Cleanup order mode
 * <PRE>
 *           APR_RESLIST_CLEANUP_DEFAULT  default pool cleanup order
 *           APR_RESLIST_CLEANUP_FIRST    use pool pre cleanup
 * </PRE>
 * @remark If APR_RESLIST_CLEANUP_FIRST is used the destructors will
 * be called before child pools of the pool used to create the reslist
 * are destroyed. This allows to explicitly destroy the child pools
 * inside reslist destructors.
 */
APU_DECLARE(void) apr_reslist_cleanup_order_set(apr_reslist_t *reslist,
                                                apr_uint32_t mode);

#ifdef __cplusplus
}
#endif

/** @} */

#endif  /* ! APR_RESLIST_H */
apr-1/apu_version.h000064400000010314151730340540010170 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APU_VERSION_H
#define APU_VERSION_H

/**
 * @file apu_version.h
 * @brief APR-util Versioning Interface
 * 
 * APR-util's Version
 *
 * There are several different mechanisms for accessing the version. There
 * is a string form, and a set of numbers; in addition, there are constants
 * which can be compiled into your application, and you can query the library
 * being used for its actual version.
 *
 * Note that it is possible for an application to detect that it has been
 * compiled against a different version of APU by use of the compile-time
 * constants and the use of the run-time query function.
 *
 * APU version numbering follows the guidelines specified in:
 *
 *     http://apr.apache.org/versioning.html
 */


#define APU_COPYRIGHT "Copyright (c) 2000-2023 The Apache Software " \
                      "Foundation or its licensors, as applicable."

/* The numeric compile-time version constants. These constants are the
 * authoritative version numbers for APU. 
 */

/** major version 
 * Major API changes that could cause compatibility problems for older
 * programs such as structure size changes.  No binary compatibility is
 * possible across a change in the major version.
 */
#define APU_MAJOR_VERSION       1

/** minor version
 * Minor API changes that do not cause binary compatibility problems.
 * Reset to 0 when upgrading APU_MAJOR_VERSION
 */
#define APU_MINOR_VERSION       6

/** patch level 
 * The Patch Level never includes API changes, simply bug fixes.
 * Reset to 0 when upgrading APR_MINOR_VERSION
 */
#define APU_PATCH_VERSION       3

/** 
 * The symbol APU_IS_DEV_VERSION is only defined for internal,
 * "development" copies of APU.  It is undefined for released versions
 * of APU.
 */
/* #undef APU_IS_DEV_VERSION  */


#if defined(APU_IS_DEV_VERSION) || defined(DOXYGEN)
/** Internal: string form of the "is dev" flag */
#ifndef APU_IS_DEV_STRING
#define APU_IS_DEV_STRING "-dev"
#endif
#else
#define APU_IS_DEV_STRING ""
#endif


#ifndef APU_STRINGIFY
/** Properly quote a value as a string in the C preprocessor */
#define APU_STRINGIFY(n) APU_STRINGIFY_HELPER(n)
/** Helper macro for APU_STRINGIFY */
#define APU_STRINGIFY_HELPER(n) #n
#endif

/** The formatted string of APU's version */
#define APU_VERSION_STRING \
     APU_STRINGIFY(APU_MAJOR_VERSION) "." \
     APU_STRINGIFY(APU_MINOR_VERSION) "." \
     APU_STRINGIFY(APU_PATCH_VERSION) \
     APU_IS_DEV_STRING

/** An alternative formatted string of APR's version */
/* macro for Win32 .rc files using numeric csv representation */
#define APU_VERSION_STRING_CSV APU_MAJOR_VERSION ##, \
                             ##APU_MINOR_VERSION ##, \
                             ##APU_PATCH_VERSION


#ifndef APU_VERSION_ONLY

/* The C language API to access the version at run time, 
 * as opposed to compile time.  APU_VERSION_ONLY may be defined 
 * externally when preprocessing apr_version.h to obtain strictly 
 * the C Preprocessor macro declarations.
 */

#include "apr_version.h"

#include "apu.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * Return APR-util's version information information in a numeric form.
 *
 *  @param pvsn Pointer to a version structure for returning the version
 *              information.
 */
APU_DECLARE(void) apu_version(apr_version_t *pvsn);

/** Return APU's version information as a string. */
APU_DECLARE(const char *) apu_version_string(void);

#ifdef __cplusplus
}
#endif

#endif /* ndef APU_VERSION_ONLY */

#endif /* ndef APU_VERSION_H */
apr-1/apr_time.h000064400000016613151730340540007446 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_TIME_H
#define APR_TIME_H

/**
 * @file apr_time.h
 * @brief APR Time Library
 */

#include "apr.h"
#include "apr_errno.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @defgroup apr_time Time Routines
 * @ingroup APR 
 * @{
 */

/** month names */
APR_DECLARE_DATA extern const char apr_month_snames[12][4];
/** day names */
APR_DECLARE_DATA extern const char apr_day_snames[7][4];


/** number of microseconds since 00:00:00 January 1, 1970 UTC */
typedef apr_int64_t apr_time_t;


/** mechanism to properly type apr_time_t literals */
#define APR_TIME_C(val) APR_INT64_C(val)

/** mechanism to properly print apr_time_t values */
#define APR_TIME_T_FMT APR_INT64_T_FMT

/** intervals for I/O timeouts, in microseconds */
typedef apr_int64_t apr_interval_time_t;
/** short interval for I/O timeouts, in microseconds */
typedef apr_int32_t apr_short_interval_time_t;

/** number of microseconds per second */
#define APR_USEC_PER_SEC APR_TIME_C(1000000)

/** @return apr_time_t as a second */
#define apr_time_sec(time) ((time) / APR_USEC_PER_SEC)

/** @return apr_time_t as a usec */
#define apr_time_usec(time) ((time) % APR_USEC_PER_SEC)

/** @return apr_time_t as a msec */
#define apr_time_msec(time) (((time) / 1000) % 1000)

/** @return apr_time_t as a msec */
#define apr_time_as_msec(time) ((time) / 1000)

/** @return milliseconds as an apr_time_t */
#define apr_time_from_msec(msec) ((apr_time_t)(msec) * 1000)

/** @return seconds as an apr_time_t */
#define apr_time_from_sec(sec) ((apr_time_t)(sec) * APR_USEC_PER_SEC)

/** @return a second and usec combination as an apr_time_t */
#define apr_time_make(sec, usec) ((apr_time_t)(sec) * APR_USEC_PER_SEC \
                                + (apr_time_t)(usec))

/**
 * @return the current time
 */
APR_DECLARE(apr_time_t) apr_time_now(void);

/** @see apr_time_exp_t */
typedef struct apr_time_exp_t apr_time_exp_t;

/**
 * a structure similar to ANSI struct tm with the following differences:
 *  - tm_usec isn't an ANSI field
 *  - tm_gmtoff isn't an ANSI field (it's a BSDism)
 */
struct apr_time_exp_t {
    /** microseconds past tm_sec */
    apr_int32_t tm_usec;
    /** (0-61) seconds past tm_min */
    apr_int32_t tm_sec;
    /** (0-59) minutes past tm_hour */
    apr_int32_t tm_min;
    /** (0-23) hours past midnight */
    apr_int32_t tm_hour;
    /** (1-31) day of the month */
    apr_int32_t tm_mday;
    /** (0-11) month of the year */
    apr_int32_t tm_mon;
    /** year since 1900 */
    apr_int32_t tm_year;
    /** (0-6) days since Sunday */
    apr_int32_t tm_wday;
    /** (0-365) days since January 1 */
    apr_int32_t tm_yday;
    /** daylight saving time */
    apr_int32_t tm_isdst;
    /** seconds east of UTC */
    apr_int32_t tm_gmtoff;
};

/* Delayed the include to avoid a circular reference */
#include "apr_pools.h"

/**
 * Convert an ansi time_t to an apr_time_t
 * @param result the resulting apr_time_t
 * @param input the time_t to convert
 */
APR_DECLARE(apr_status_t) apr_time_ansi_put(apr_time_t *result, 
                                                    time_t input);

/**
 * Convert a time to its human readable components using an offset
 * from GMT.
 * @param result the exploded time
 * @param input the time to explode
 * @param offs the number of seconds offset to apply
 */
APR_DECLARE(apr_status_t) apr_time_exp_tz(apr_time_exp_t *result,
                                          apr_time_t input,
                                          apr_int32_t offs);

/**
 * Convert a time to its human readable components (GMT).
 * @param result the exploded time
 * @param input the time to explode
 */
APR_DECLARE(apr_status_t) apr_time_exp_gmt(apr_time_exp_t *result, 
                                           apr_time_t input);

/**
 * Convert a time to its human readable components in the local timezone.
 * @param result the exploded time
 * @param input the time to explode
 */
APR_DECLARE(apr_status_t) apr_time_exp_lt(apr_time_exp_t *result, 
                                          apr_time_t input);

/**
 * Convert time value from human readable format to a numeric apr_time_t
 * (elapsed microseconds since the epoch).
 * @param result the resulting imploded time
 * @param input the input exploded time
 */
APR_DECLARE(apr_status_t) apr_time_exp_get(apr_time_t *result, 
                                           apr_time_exp_t *input);

/**
 * Convert time value from human readable format to a numeric apr_time_t that
 * always represents GMT.
 * @param result the resulting imploded time
 * @param input the input exploded time
 */
APR_DECLARE(apr_status_t) apr_time_exp_gmt_get(apr_time_t *result, 
                                               apr_time_exp_t *input);

/**
 * Sleep for the specified number of micro-seconds.
 * @param t desired amount of time to sleep.
 * @warning May sleep for longer than the specified time. 
 */
APR_DECLARE(void) apr_sleep(apr_interval_time_t t);

/** length of a RFC822 Date */
#define APR_RFC822_DATE_LEN (30)
/**
 * apr_rfc822_date formats dates in the RFC822
 * format in an efficient manner.  It is a fixed length
 * format which requires APR_RFC822_DATA_LEN bytes of storage,
 * including the trailing NUL terminator.
 * @param date_str String to write to.
 * @param t the time to convert 
 */
APR_DECLARE(apr_status_t) apr_rfc822_date(char *date_str, apr_time_t t);

/** length of a CTIME date */
#define APR_CTIME_LEN (25)
/**
 * apr_ctime formats dates in the ctime() format
 * in an efficient manner.  It is a fixed length format
 * and requires APR_CTIME_LEN bytes of storage including
 * the trailing NUL terminator.
 * Unlike ANSI/ISO C ctime(), apr_ctime() does not include
 * a \\n at the end of the string.
 * @param date_str String to write to.
 * @param t the time to convert 
 */
APR_DECLARE(apr_status_t) apr_ctime(char *date_str, apr_time_t t);

/**
 * Formats the exploded time according to the format specified
 * @param s string to write to
 * @param retsize The length of the returned string
 * @param max The maximum length of the string
 * @param format The format for the time string
 * @param tm The time to convert
 */
APR_DECLARE(apr_status_t) apr_strftime(char *s, apr_size_t *retsize, 
                                       apr_size_t max, const char *format, 
                                       apr_time_exp_t *tm);

/**
 * Improve the clock resolution for the lifetime of the given pool.
 * Generally this is only desirable on benchmarking and other very
 * time-sensitive applications, and has no impact on most platforms.
 * @param p The pool to associate the finer clock resolution 
 */
APR_DECLARE(void) apr_time_clock_hires(apr_pool_t *p);

/** @} */

#ifdef __cplusplus
}
#endif

#endif  /* ! APR_TIME_H */
apr-1/apr_cstr.h000064400000026206151730340540007462 0ustar00/* ====================================================================
 *    Licensed to the Apache Software Foundation (ASF) under one
 *    or more contributor license agreements.  See the NOTICE file
 *    distributed with this work for additional information
 *    regarding copyright ownership.  The ASF licenses this file
 *    to you under the Apache License, Version 2.0 (the
 *    "License"); you may not use this file except in compliance
 *    with the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing,
 *    software distributed under the License is distributed on an
 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *    KIND, either express or implied.  See the License for the
 *    specific language governing permissions and limitations
 *    under the License.
 * ====================================================================
 */

/**
 * @file apr_cstr.h
 * @brief C string goodies.
 */

#ifndef APR_CSTR_H
#define APR_CSTR_H

#include <apr.h>          /* for apr_size_t */
#include <apr_pools.h>    /* for apr_pool_t */
#include <apr_tables.h>   /* for apr_array_header_t */

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @defgroup apr_cstr C (POSIX) locale string functions
 * @ingroup apr_strings
 *
 * The apr_cstr_* functions provide traditional C char * string text handling,
 * and notabilty they treat all text in the C (a.k.a. POSIX) locale using the
 * minimal POSIX character set, represented in either ASCII or a corresponding
 * EBCDIC subset.
 *
 * Character values outside of that set are treated as opaque bytes, and all
 * multi-byte character sequences are handled as individual distinct octets.
 *
 * Multi-byte characters sequences whose octets fall in the ASCII range cause
 * unexpected results, such as in the ISO-2022-JP code page where ASCII octets
 * occur within both shift-state and multibyte sequences.
 *
 * In the case of the UTF-8 encoding, all multibyte characters all fall outside
 * of the C/POSIX range of characters, so these functions are generally safe
 * to use on UTF-8 strings. The programmer must be aware that each octet may
 * not represent a distinct printable character in such encodings.
 *
 * The standard C99/POSIX string functions, rather than apr_cstr, should be
 * used in all cases where the current locale and encoding of the text is
 * significant.
 * @{
 */


/** Divide @a input into substrings, interpreting any char from @a sep
 * as a token separator.
 *
 * Return an array of copies of those substrings (plain const char*),
 * allocating both the array and the copies in @a pool.
 *
 * None of the elements added to the array contain any of the
 * characters in @a sep_chars, and none of the new elements are empty
 * (thus, it is possible that the returned array will have length
 * zero).
 *
 * If @a chop_whitespace is TRUE, then remove leading and trailing
 * whitespace from the returned strings.
 *
 * @since New in 1.6
 */
APR_DECLARE(apr_array_header_t *) apr_cstr_split(const char *input,
                                                 const char *sep_chars,
                                                 int chop_whitespace,
                                                 apr_pool_t *pool);

/** Like apr_cstr_split(), but append to existing @a array instead of
 * creating a new one.  Allocate the copied substrings in @a pool
 * (i.e., caller decides whether or not to pass @a array->pool as @a pool).
 *
 * @since New in 1.6
 */
APR_DECLARE(void) apr_cstr_split_append(apr_array_header_t *array,
                                        const char *input,
                                        const char *sep_chars,
                                        int chop_whitespace,
                                        apr_pool_t *pool);


/** Return @c TRUE iff @a str matches any of the elements of @a list, a list
 * of zero or more glob patterns.
 *
 * @since New in 1.6
 */
APR_DECLARE(int) apr_cstr_match_glob_list(const char *str,
                                          const apr_array_header_t *list);

/** Return @c TRUE iff @a str exactly matches any of the elements of @a list.
 *
 * @since New in 1.6
 */
APR_DECLARE(int) apr_cstr_match_list(const char *str,
                                     const apr_array_header_t *list);

/**
 * Get the next token from @a *str interpreting any char from @a sep as a
 * token separator.  Separators at the beginning of @a str will be skipped.
 * Returns a pointer to the beginning of the first token in @a *str or NULL
 * if no token is left.  Modifies @a str such that the next call will return
 * the next token.
 *
 * @note The content of @a *str may be modified by this function.
 *
 * @since New in 1.6.
 */
APR_DECLARE(char *) apr_cstr_tokenize(const char *sep, char **str);

/**
 * Return the number of line breaks in @a msg, allowing any kind of newline
 * termination (CR, LF, CRLF, or LFCR), even inconsistent.
 *
 * @since New in 1.6.
 */
APR_DECLARE(int) apr_cstr_count_newlines(const char *msg);

#if 0 /* XXX: stringbuf logic is not present in APR */
/**
 * Return a cstring which is the concatenation of @a strings (an array
 * of char *) each followed by @a separator (that is, @a separator
 * will also end the resulting string).  Allocate the result in @a pool.
 * If @a strings is empty, then return the empty string.
 *
 * @since New in 1.6.
 */
APR_DECLARE(char *) apr_cstr_join(const apr_array_header_t *strings,
                                  const char *separator,
                                  apr_pool_t *pool);
#endif

/**
 * Perform a case-insensitive comparison of two strings @a atr1 and @a atr2,
 * treating upper and lower case values of the 26 standard C/POSIX alphabetic
 * characters as equivalent. Extended latin characters outside of this set
 * are treated as unique octets, irrespective of the current locale.
 *
 * Returns in integer greater than, equal to, or less than 0,
 * according to whether @a str1 is considered greater than, equal to,
 * or less than @a str2.
 *
 * @since New in 1.6.
 */
APR_DECLARE(int) apr_cstr_casecmp(const char *str1, const char *str2);

/**
 * Perform a case-insensitive comparison of two strings @a atr1 and @a atr2,
 * treating upper and lower case values of the 26 standard C/POSIX alphabetic
 * characters as equivalent. Extended latin characters outside of this set
 * are treated as unique octets, irrespective of the current locale.
 *
 * Returns in integer greater than, equal to, or less than 0,
 * according to whether @a str1 is considered greater than, equal to,
 * or less than @a str2.
 *
 * @since New in 1.6.
 */
APR_DECLARE(int) apr_cstr_casecmpn(const char *str1,
                                   const char *str2,
                                   apr_size_t n);

/**
 * Parse the C string @a str into a 64 bit number, and return it in @a *n.
 * Assume that the number is represented in base @a base.
 * Raise an error if conversion fails (e.g. due to overflow), or if the
 * converted number is smaller than @a minval or larger than @a maxval.
 *
 * Leading whitespace in @a str is skipped in a locale-dependent way.
 * After that, the string may contain an optional '+' (positive, default)
 * or '-' (negative) character, followed by an optional '0x' prefix if
 * @a base is 0 or 16, followed by numeric digits appropriate for the base.
 * If there are any more characters after the numeric digits, an error is
 * returned.
 *
 * If @a base is zero, then a leading '0x' or '0X' prefix means hexadecimal,
 * else a leading '0' means octal (implemented, though not documented, in
 * apr_strtoi64() in APR 0.9.0 through 1.5.0), else use base ten.
 *
 * @since New in 1.6.
 */
APR_DECLARE(apr_status_t) apr_cstr_strtoi64(apr_int64_t *n, const char *str,
                                            apr_int64_t minval,
                                            apr_int64_t maxval,
                                            int base);

/**
 * Parse the C string @a str into a 64 bit number, and return it in @a *n.
 * Assume that the number is represented in base 10.
 * Raise an error if conversion fails (e.g. due to overflow).
 *
 * The behaviour otherwise is as described for apr_cstr_strtoi64().
 *
 * @since New in 1.6.
 */
APR_DECLARE(apr_status_t) apr_cstr_atoi64(apr_int64_t *n, const char *str);

/**
 * Parse the C string @a str into a 32 bit number, and return it in @a *n.
 * Assume that the number is represented in base 10.
 * Raise an error if conversion fails (e.g. due to overflow).
 *
 * The behaviour otherwise is as described for apr_cstr_strtoi64().
 *
 * @since New in 1.6.
 */
APR_DECLARE(apr_status_t) apr_cstr_atoi(int *n, const char *str);

/**
 * Parse the C string @a str into an unsigned 64 bit number, and return
 * it in @a *n. Assume that the number is represented in base @a base.
 * Raise an error if conversion fails (e.g. due to overflow), or if the
 * converted number is smaller than @a minval or larger than @a maxval.
 *
 * Leading whitespace in @a str is skipped in a locale-dependent way.
 * After that, the string may contain an optional '+' (positive, default)
 * or '-' (negative) character, followed by an optional '0x' prefix if
 * @a base is 0 or 16, followed by numeric digits appropriate for the base.
 * If there are any more characters after the numeric digits, an error is
 * returned.
 *
 * If @a base is zero, then a leading '0x' or '0X' prefix means hexadecimal,
 * else a leading '0' means octal (as implemented, though not documented, in
 * apr_strtoi64(), else use base ten.
 *
 * @warning The implementation returns APR_ERANGE if the parsed number
 * is greater than APR_INT64_MAX, even if it is not greater than @a maxval.
 *
 * @since New in 1.6.
 */
APR_DECLARE(apr_status_t) apr_cstr_strtoui64(apr_uint64_t *n, const char *str,
                                             apr_uint64_t minval,
                                             apr_uint64_t maxval,
                                             int base);

/**
 * Parse the C string @a str into an unsigned 64 bit number, and return
 * it in @a *n. Assume that the number is represented in base 10.
 * Raise an error if conversion fails (e.g. due to overflow).
 *
 * The behaviour otherwise is as described for apr_cstr_strtoui64(),
 * including the upper limit of APR_INT64_MAX.
 *
 * @since New in 1.6.
 */
APR_DECLARE(apr_status_t) apr_cstr_atoui64(apr_uint64_t *n, const char *str);

/**
 * Parse the C string @a str into an unsigned 32 bit number, and return
 * it in @a *n. Assume that the number is represented in base 10.
 * Raise an error if conversion fails (e.g. due to overflow).
 *
 * The behaviour otherwise is as described for apr_cstr_strtoui64(),
 * including the upper limit of APR_INT64_MAX.
 *
 * @since New in 1.6.
 */
APR_DECLARE(apr_status_t) apr_cstr_atoui(unsigned int *n, const char *str);

/**
 * Skip the common prefix @a prefix from the C string @a str, and return
 * a pointer to the next character after the prefix.
 * Return @c NULL if @a str does not start with @a prefix.
 *
 * @since New in 1.6.
 */
APR_DECLARE(const char *) apr_cstr_skip_prefix(const char *str,
                                               const char *prefix);

/** @} */

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif  /* SVN_STRING_H */
apr-1/apr_getopt.h000064400000013534151730340540010011 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_GETOPT_H
#define APR_GETOPT_H

/**
 * @file apr_getopt.h
 * @brief APR Command Arguments (getopt)
 */

#include "apr_pools.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @defgroup apr_getopt Command Argument Parsing
 * @ingroup APR 
 * @{
 */

/** 
 * An @c apr_getopt_t error callback function.
 *
 * @a arg is this @c apr_getopt_t's @c errarg member.
 */
typedef void (apr_getopt_err_fn_t)(void *arg, const char *err, ...);

/** @see apr_getopt_t */
typedef struct apr_getopt_t apr_getopt_t;

/**
 * Structure to store command line argument information.
 */ 
struct apr_getopt_t {
    /** context for processing */
    apr_pool_t *cont;
    /** function to print error message (NULL == no messages) */
    apr_getopt_err_fn_t *errfn;
    /** user defined first arg to pass to error message  */
    void *errarg;
    /** index into parent argv vector */
    int ind;
    /** character checked for validity */
    int opt;
    /** reset getopt */
    int reset;
    /** count of arguments */
    int argc;
    /** array of pointers to arguments */
    const char **argv;
    /** argument associated with option */
    char const* place;
    /** set to nonzero to support interleaving options with regular args */
    int interleave;
    /** start of non-option arguments skipped for interleaving */
    int skip_start;
    /** end of non-option arguments skipped for interleaving */
    int skip_end;
};

/** @see apr_getopt_option_t */
typedef struct apr_getopt_option_t apr_getopt_option_t;

/**
 * Structure used to describe options that getopt should search for.
 */
struct apr_getopt_option_t {
    /** long option name, or NULL if option has no long name */
    const char *name;
    /** option letter, or a value greater than 255 if option has no letter */
    int optch;
    /** nonzero if option takes an argument */
    int has_arg;
    /** a description of the option */
    const char *description;
};

/**
 * Initialize the arguments for parsing by apr_getopt().
 * @param os   The options structure created for apr_getopt()
 * @param cont The pool to operate on
 * @param argc The number of arguments to parse
 * @param argv The array of arguments to parse
 * @remark Arguments 3 and 4 are most commonly argc and argv from main(argc, argv)
 * The (*os)->errfn is initialized to fprintf(stderr... but may be overridden.
 */
APR_DECLARE(apr_status_t) apr_getopt_init(apr_getopt_t **os, apr_pool_t *cont,
                                      int argc, const char * const *argv);

/**
 * Parse the options initialized by apr_getopt_init().
 * @param os     The apr_opt_t structure returned by apr_getopt_init()
 * @param opts   A string of characters that are acceptable options to the 
 *               program.  Characters followed by ":" are required to have an 
 *               option associated
 * @param option_ch  The next option character parsed
 * @param option_arg The argument following the option character:
 * @return There are four potential status values on exit. They are:
 * <PRE>
 *             APR_EOF      --  No more options to parse
 *             APR_BADCH    --  Found a bad option character
 *             APR_BADARG   --  No argument followed the option flag
 *             APR_SUCCESS  --  The next option was found.
 * </PRE>
 */
APR_DECLARE(apr_status_t) apr_getopt(apr_getopt_t *os, const char *opts, 
                                     char *option_ch, const char **option_arg);

/**
 * Parse the options initialized by apr_getopt_init(), accepting long
 * options beginning with "--" in addition to single-character
 * options beginning with "-".
 * @param os     The apr_getopt_t structure created by apr_getopt_init()
 * @param opts   A pointer to a list of apr_getopt_option_t structures, which
 *               can be initialized with { "name", optch, has_args }.  has_args
 *               is nonzero if the option requires an argument.  A structure
 *               with an optch value of 0 terminates the list.
 * @param option_ch  Receives the value of "optch" from the apr_getopt_option_t
 *                   structure corresponding to the next option matched.
 * @param option_arg Receives the argument following the option, if any.
 * @return There are four potential status values on exit.   They are:
 * <PRE>
 *             APR_EOF      --  No more options to parse
 *             APR_BADCH    --  Found a bad option character
 *             APR_BADARG   --  No argument followed the option flag
 *             APR_SUCCESS  --  The next option was found.
 * </PRE>
 * When APR_SUCCESS is returned, os->ind gives the index of the first
 * non-option argument.  On error, a message will be printed to stdout unless
 * os->err is set to 0.  If os->interleave is set to nonzero, options can come
 * after arguments, and os->argv will be permuted to leave non-option arguments
 * at the end (the original argv is unaffected).
 */
APR_DECLARE(apr_status_t) apr_getopt_long(apr_getopt_t *os,
					  const apr_getopt_option_t *opts,
					  int *option_ch,
                                          const char **option_arg);
/** @} */

#ifdef __cplusplus
}
#endif

#endif  /* ! APR_GETOPT_H */
apr-1/apr_redis.h000064400000037173151730340540007622 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @file apr_redis.h
 * @brief Client interface for redis
 * @remark To use this interface you must have a separate redis
 * for more information.
 */

#ifndef APR_REDIS_H
#define APR_REDIS_H

#include "apr.h"
#include "apr_pools.h"
#include "apr_time.h"
#include "apr_strings.h"
#include "apr_network_io.h"
#include "apr_ring.h"
#include "apr_buckets.h"
#include "apr_reslist.h"
#include "apr_hash.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

#ifndef RC_DEFAULT_SERVER_PORT
#define RC_DEFAULT_SERVER_PORT 6379
#endif

#ifndef RC_DEFAULT_SERVER_MIN
#define RC_DEFAULT_SERVER_MIN 0
#endif

#ifndef RC_DEFAULT_SERVER_SMAX
#define RC_DEFAULT_SERVER_SMAX 1
#endif

#ifndef RC_DEFAULT_SERVER_TTL
#define RC_DEFAULT_SERVER_TTL 600
#endif

/**
 * @defgroup APR_Util_RC Redis Client Routines
 * @ingroup APR_Util
 * @{
 */

/** Specifies the status of a redis server */
typedef enum
{
    APR_RC_SERVER_LIVE, /**< Server is alive and responding to requests */
    APR_RC_SERVER_DEAD  /**< Server is not responding to requests */
} apr_redis_server_status_t;

/** Opaque redis client connection object */
typedef struct apr_redis_conn_t apr_redis_conn_t;

/** Redis Server Info Object */
typedef struct apr_redis_server_t apr_redis_server_t;
struct apr_redis_server_t
{
    const char *host; /**< Hostname of this Server */
    apr_port_t port; /**< Port of this Server */
    apr_redis_server_status_t status; /**< @see apr_redis_server_status_t */
#if APR_HAS_THREADS || defined(DOXYGEN)
    apr_reslist_t *conns; /**< Resource list of actual client connections */
#else
    apr_redis_conn_t *conn;
#endif
    apr_pool_t *p; /** Pool to use for private allocations */
#if APR_HAS_THREADS
    apr_thread_mutex_t *lock;
#endif
    apr_time_t btime;
    apr_uint32_t rwto;
    struct
    {
        int major;
        int minor;
        int patch;
        char *number;
    } version;
};

typedef struct apr_redis_t apr_redis_t;

/* Custom hash callback function prototype, user for server selection.
* @param baton user selected baton
* @param data data to hash
* @param data_len length of data
*/
typedef apr_uint32_t (*apr_redis_hash_func)(void *baton,
                                            const char *data,
                                            const apr_size_t data_len);
/* Custom Server Select callback function prototype.
* @param baton user selected baton
* @param rc redis instance, use rc->live_servers to select a node
* @param hash hash of the selected key.
*/
typedef apr_redis_server_t* (*apr_redis_server_func)(void *baton,
                                                 apr_redis_t *rc,
                                                 const apr_uint32_t hash);

/** Container for a set of redis servers */
struct apr_redis_t
{
    apr_uint32_t flags; /**< Flags, Not currently used */
    apr_uint16_t nalloc; /**< Number of Servers Allocated */
    apr_uint16_t ntotal; /**< Number of Servers Added */
    apr_redis_server_t **live_servers; /**< Array of Servers */
    apr_pool_t *p; /** Pool to use for allocations */
    void *hash_baton;
    apr_redis_hash_func hash_func;
    void *server_baton;
    apr_redis_server_func server_func;
};

/**
 * Creates a crc32 hash used to split keys between servers
 * @param rc The redis client object to use
 * @param data Data to be hashed
 * @param data_len Length of the data to use
 * @return crc32 hash of data
 * @remark The crc32 hash is not compatible with old redisd clients.
 */
APU_DECLARE(apr_uint32_t) apr_redis_hash(apr_redis_t *rc,
                                         const char *data,
                                         const apr_size_t data_len);

/**
 * Pure CRC32 Hash. Used by some clients.
 */
APU_DECLARE(apr_uint32_t) apr_redis_hash_crc32(void *baton,
                                               const char *data,
                                               const apr_size_t data_len);

/**
 * hash compatible with the standard Perl Client.
 */
APU_DECLARE(apr_uint32_t) apr_redis_hash_default(void *baton,
                                                 const char *data,
                                                 const apr_size_t data_len);

/**
 * Picks a server based on a hash
 * @param rc The redis client object to use
 * @param hash Hashed value of a Key
 * @return server that controls specified hash
 * @see apr_redis_hash
 */
APU_DECLARE(apr_redis_server_t *) apr_redis_find_server_hash(apr_redis_t *rc,
                                                             const apr_uint32_t hash);

/**
 * server selection compatible with the standard Perl Client.
 */
APU_DECLARE(apr_redis_server_t *) apr_redis_find_server_hash_default(void *baton,
                                                                      apr_redis_t *rc,
                                                                      const apr_uint32_t hash);

/**
 * Adds a server to a client object
 * @param rc The redis client object to use
 * @param server Server to add
 * @remark Adding servers is not thread safe, and should be done once at startup.
 * @warning Changing servers after startup may cause keys to go to
 * different servers.
 */
APU_DECLARE(apr_status_t) apr_redis_add_server(apr_redis_t *rc,
                                               apr_redis_server_t *server);


/**
 * Finds a Server object based on a hostname/port pair
 * @param rc The redis client object to use
 * @param host Hostname of the server
 * @param port Port of the server
 * @return Server with matching Hostname and Port, or NULL if none was found.
 */
APU_DECLARE(apr_redis_server_t *) apr_redis_find_server(apr_redis_t *rc,
                                                        const char *host,
                                                        apr_port_t port);

/**
 * Enables a Server for use again
 * @param rc The redis client object to use
 * @param rs Server to Activate
 */
APU_DECLARE(apr_status_t) apr_redis_enable_server(apr_redis_t *rc,
                                                  apr_redis_server_t *rs);


/**
 * Disable a Server
 * @param rc The redis client object to use
 * @param rs Server to Disable
 */
APU_DECLARE(apr_status_t) apr_redis_disable_server(apr_redis_t *rc,
                                                   apr_redis_server_t *rs);

/**
 * Creates a new Server Object
 * @param p Pool to use
 * @param host hostname of the server
 * @param port port of the server
 * @param min  minimum number of client sockets to open
 * @param smax soft maximum number of client connections to open
 * @param max  hard maximum number of client connections
 * @param ttl  time to live in microseconds of a client connection
 * @param rwto r/w timeout value in seconds of a client connection
 * @param ns   location of the new server object
 * @see apr_reslist_create
 * @remark min, smax, and max are only used when APR_HAS_THREADS
 */
APU_DECLARE(apr_status_t) apr_redis_server_create(apr_pool_t *p,
                                                  const char *host,
                                                  apr_port_t port,
                                                  apr_uint32_t min,
                                                  apr_uint32_t smax,
                                                  apr_uint32_t max,
                                                  apr_uint32_t ttl,
                                                  apr_uint32_t rwto,
                                                  apr_redis_server_t **ns);
/**
 * Creates a new redisd client object
 * @param p Pool to use
 * @param max_servers maximum number of servers
 * @param flags Not currently used
 * @param rc   location of the new redis client object
 */
APU_DECLARE(apr_status_t) apr_redis_create(apr_pool_t *p,
                                           apr_uint16_t max_servers,
                                           apr_uint32_t flags,
                                           apr_redis_t **rc);

/**
 * Gets a value from the server, allocating the value out of p
 * @param rc client to use
 * @param p Pool to use
 * @param key null terminated string containing the key
 * @param baton location of the allocated value
 * @param len   length of data at baton
 * @param flags any flags set by the client for this key
 * @return 
 */
APU_DECLARE(apr_status_t) apr_redis_getp(apr_redis_t *rc,
                                         apr_pool_t *p,
                                         const char* key,
                                         char **baton,
                                         apr_size_t *len,
                                         apr_uint16_t *flags);

/**
 * Sets a value by key on the server
 * @param rc client to use
 * @param key   null terminated string containing the key
 * @param baton data to store on the server
 * @param data_size   length of data at baton
 * @param flags any flags set by the client for this key
 */
APU_DECLARE(apr_status_t) apr_redis_set(apr_redis_t *rc,
                                        const char *key,
                                        char *baton,
                                        const apr_size_t data_size,
                                        apr_uint16_t flags);

/**
 * Sets a value by key on the server
 * @param rc client to use
 * @param key   null terminated string containing the key
 * @param baton data to store on the server
 * @param data_size   length of data at baton
 * @param timeout time in seconds for the data to live on the server
 * @param flags any flags set by the client for this key
 */
APU_DECLARE(apr_status_t) apr_redis_setex(apr_redis_t *rc,
                                          const char *key,
                                          char *baton,
                                          const apr_size_t data_size,
                                          apr_uint32_t timeout,
                                          apr_uint16_t flags);

/**
 * Deletes a key from a server
 * @param rc client to use
 * @param key   null terminated string containing the key
 * @param timeout time for the delete to stop other clients from adding
 */
APU_DECLARE(apr_status_t) apr_redis_delete(apr_redis_t *rc,
                                           const char *key,
                                           apr_uint32_t timeout);

/**
 * Query a server's version
 * @param rs    server to query
 * @param p     Pool to allocate answer from
 * @param baton location to store server version string
 */
APU_DECLARE(apr_status_t) apr_redis_version(apr_redis_server_t *rs,
                                            apr_pool_t *p,
                                            char **baton);

/**
 * Query a server's INFO
 * @param rs    server to query
 * @param p     Pool to allocate answer from
 * @param baton location to store server INFO response string
 */
APU_DECLARE(apr_status_t) apr_redis_info(apr_redis_server_t *rs,
                                         apr_pool_t *p,
                                         char **baton);

/**
 * Increments a value
 * @param rc client to use
 * @param key   null terminated string containing the key
 * @param inc     number to increment by
 * @param new_value    new value after incrementing
 */
APU_DECLARE(apr_status_t) apr_redis_incr(apr_redis_t *rc,
                                         const char *key,
                                         apr_int32_t inc,
                                         apr_uint32_t *new_value);
/**
 * Decrements a value
 * @param rc client to use
 * @param key   null terminated string containing the key
 * @param inc     number to decrement by
 * @param new_value    new value after decrementing
 */
APU_DECLARE(apr_status_t) apr_redis_decr(apr_redis_t *rc,
                                         const char *key,
                                         apr_int32_t inc,
                                         apr_uint32_t *new_value);


/**
 * Pings the server
 * @param rs Server to ping
 */
APU_DECLARE(apr_status_t) apr_redis_ping(apr_redis_server_t *rs);

/**
 * Gets multiple values from the server, allocating the values out of p
 * @param rc client to use
 * @param temp_pool Pool used for temporary allocations. May be cleared inside this
 *        call.
 * @param data_pool Pool used to allocate data for the returned values.
 * @param values hash of apr_redis_value_t keyed by strings, contains the
 *        result of the multiget call.
 * @return
 */
APU_DECLARE(apr_status_t) apr_redis_multgetp(apr_redis_t *rc,
                                             apr_pool_t *temp_pool,
                                             apr_pool_t *data_pool,
                                             apr_hash_t *values);

typedef enum
{
    APR_RS_SERVER_MASTER, /**< Server is a master */
    APR_RS_SERVER_SLAVE,  /**< Server is a slave */
    APR_RS_SERVER_UNKNOWN  /**< Server role is unknown */
} apr_redis_server_role_t;

typedef struct
{
/* # Server */
    /** Major version number of this server */
    apr_uint32_t major;
    /** Minor version number of this server */
    apr_uint32_t minor;
    /** Patch version number of this server */
    apr_uint32_t patch;
    /** Process id of this server process */
    apr_uint32_t process_id;
    /** Number of seconds this server has been running */
    apr_uint32_t uptime_in_seconds;
    /** Bitsize of the arch on the current machine */
    apr_uint32_t arch_bits;

/* # Clients */
    /** Number of connected clients */
    apr_uint32_t connected_clients;
    /** Number of blocked clients */
    apr_uint32_t blocked_clients;

/* # Memory */
    /** Max memory of this server */
    apr_uint64_t maxmemory;
    /** Amount of used memory */
    apr_uint64_t used_memory;
    /** Total memory available on this server */
    apr_uint64_t total_system_memory;

/* # Stats */
    /** Total connections received */
    apr_uint64_t total_connections_received;
    /** Total commands processed */
    apr_uint64_t total_commands_processed;
    /** Total commands rejected */
    apr_uint64_t rejected_connections;
    /** Total net input bytes */
    apr_uint64_t total_net_input_bytes;
    /** Total net output bytes */
    apr_uint64_t total_net_output_bytes;
    /** Keyspace hits */
    apr_uint64_t keyspace_hits;
    /** Keyspace misses */
    apr_uint64_t keyspace_misses;

/* # Replication */
    /** Role */
    apr_redis_server_role_t role;
    /** Number of connected slave */
    apr_uint32_t connected_slaves;

/* # CPU */
    /** Accumulated CPU user time for this process */
    apr_uint32_t used_cpu_sys;
    /** Accumulated CPU system time for this process */
    apr_uint32_t used_cpu_user;

/* # Cluster */
    /** Is cluster enabled */
    apr_uint32_t cluster_enabled;
} apr_redis_stats_t;

/**
 * Query a server for statistics
 * @param rs    server to query
 * @param p     Pool to allocate answer from
 * @param stats location of the new statistics structure
 */
APU_DECLARE(apr_status_t) apr_redis_stats(apr_redis_server_t *rs,
                                          apr_pool_t *p,
                                          apr_redis_stats_t **stats);

/** @} */

#ifdef __cplusplus
}
#endif

#endif /* APR_REDIS_H */
apr-1/apr_queue.h000064400000007760151730340540007637 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_QUEUE_H
#define APR_QUEUE_H

/**
 * @file apr_queue.h
 * @brief Thread Safe FIFO bounded queue
 * @note Since most implementations of the queue are backed by a condition
 * variable implementation, it isn't available on systems without threads.
 * Although condition variables are sometimes available without threads.
 */

#include "apu.h"
#include "apr_errno.h"
#include "apr_pools.h"

#if APR_HAS_THREADS

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @defgroup APR_Util_FIFO Thread Safe FIFO bounded queue
 * @ingroup APR_Util
 * @{
 */

/**
 * opaque structure
 */
typedef struct apr_queue_t apr_queue_t;

/** 
 * create a FIFO queue
 * @param queue The new queue
 * @param queue_capacity maximum size of the queue
 * @param a pool to allocate queue from
 */
APU_DECLARE(apr_status_t) apr_queue_create(apr_queue_t **queue, 
                                           unsigned int queue_capacity, 
                                           apr_pool_t *a);

/**
 * push/add an object to the queue, blocking if the queue is already full
 *
 * @param queue the queue
 * @param data the data
 * @returns APR_EINTR the blocking was interrupted (try again)
 * @returns APR_EOF the queue has been terminated
 * @returns APR_SUCCESS on a successful push
 */
APU_DECLARE(apr_status_t) apr_queue_push(apr_queue_t *queue, void *data);

/**
 * pop/get an object from the queue, blocking if the queue is already empty
 *
 * @param queue the queue
 * @param data the data
 * @returns APR_EINTR the blocking was interrupted (try again)
 * @returns APR_EOF if the queue has been terminated
 * @returns APR_SUCCESS on a successful pop
 */
APU_DECLARE(apr_status_t) apr_queue_pop(apr_queue_t *queue, void **data);

/**
 * push/add an object to the queue, returning immediately if the queue is full
 *
 * @param queue the queue
 * @param data the data
 * @returns APR_EINTR the blocking operation was interrupted (try again)
 * @returns APR_EAGAIN the queue is full
 * @returns APR_EOF the queue has been terminated
 * @returns APR_SUCCESS on a successful push
 */
APU_DECLARE(apr_status_t) apr_queue_trypush(apr_queue_t *queue, void *data);

/**
 * pop/get an object to the queue, returning immediately if the queue is empty
 *
 * @param queue the queue
 * @param data the data
 * @returns APR_EINTR the blocking operation was interrupted (try again)
 * @returns APR_EAGAIN the queue is empty
 * @returns APR_EOF the queue has been terminated
 * @returns APR_SUCCESS on a successful pop
 */
APU_DECLARE(apr_status_t) apr_queue_trypop(apr_queue_t *queue, void **data);

/**
 * returns the size of the queue.
 *
 * @warning this is not threadsafe, and is intended for reporting/monitoring
 * of the queue.
 * @param queue the queue
 * @returns the size of the queue
 */
APU_DECLARE(unsigned int) apr_queue_size(apr_queue_t *queue);

/**
 * interrupt all the threads blocking on this queue.
 *
 * @param queue the queue
 */
APU_DECLARE(apr_status_t) apr_queue_interrupt_all(apr_queue_t *queue);

/**
 * terminate the queue, sending an interrupt to all the
 * blocking threads
 *
 * @param queue the queue
 */
APU_DECLARE(apr_status_t) apr_queue_term(apr_queue_t *queue);

#ifdef __cplusplus
}
#endif

/** @} */

#endif /* APR_HAS_THREADS */

#endif /* APRQUEUE_H */
apr-1/apr_lib.h000064400000020356151730340540007255 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_LIB_H
#define APR_LIB_H

/**
 * @file apr_lib.h
 * This is collection of oddballs that didn't fit anywhere else,
 * and might move to more appropriate headers with the release
 * of APR 1.0.
 * @brief APR general purpose library routines
 */

#include "apr.h"
#include "apr_errno.h"

#if APR_HAVE_CTYPE_H
#include <ctype.h>
#endif
#if APR_HAVE_STDARG_H
#include <stdarg.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @defgroup apr_lib General Purpose Library Routines
 * @ingroup APR 
 * This is collection of oddballs that didn't fit anywhere else,
 * and might move to more appropriate headers with the release
 * of APR 1.0.
 * @{
 */

/** A constant representing a 'large' string. */
#define HUGE_STRING_LEN 8192

/*
 * Define the structures used by the APR general-purpose library.
 */

/** @see apr_vformatter_buff_t */
typedef struct apr_vformatter_buff_t apr_vformatter_buff_t;

/**
 * Structure used by the variable-formatter routines.
 */
struct apr_vformatter_buff_t {
    /** The current position */
    char *curpos;
    /** The end position of the format string */
    char *endpos;
};

/**
 * return the final element of the pathname
 * @param pathname The path to get the final element of
 * @return the final element of the path
 * @remark
 * <PRE>
 * For example:
 *                 "/foo/bar/gum"    -> "gum"
 *                 "/foo/bar/gum/"   -> ""
 *                 "gum"             -> "gum"
 *                 "bs\\path\\stuff" -> "stuff"
 * </PRE>
 */
APR_DECLARE(const char *) apr_filepath_name_get(const char *pathname);

/**
 * apr_killpg
 * Small utility macros to make things easier to read.  Not usually a
 * goal, to be sure..
 */

#ifdef WIN32
#define apr_killpg(x, y)
#else /* WIN32 */
#ifdef NO_KILLPG
#define apr_killpg(x, y)        (kill (-(x), (y)))
#else /* NO_KILLPG */
#define apr_killpg(x, y)        (killpg ((x), (y)))
#endif /* NO_KILLPG */
#endif /* WIN32 */

/**
 * apr_vformatter() is a generic printf-style formatting routine
 * with some extensions.
 * @param flush_func The function to call when the buffer is full
 * @param c The buffer to write to
 * @param fmt The format string
 * @param ap The arguments to use to fill out the format string.
 *
 * @remark
 * <PRE>
 * The extensions are:
 *
 * - %%pA takes a struct in_addr *, and prints it as a.b.c.d
 * - %%pI takes an apr_sockaddr_t * and prints it as a.b.c.d:port or
 * \[ipv6-address\]:port
 * - %%pT takes an apr_os_thread_t * and prints it in decimal
 * ('0' is printed if !APR_HAS_THREADS)
 * - %%pt takes an apr_os_thread_t * and prints it in hexadecimal
 * ('0' is printed if !APR_HAS_THREADS)
 * - %%pm takes an apr_status_t * and prints the appropriate error
 * string (from apr_strerror) corresponding to that error code.
 * - %%pp takes a void * and outputs it in hex
 * - %%pB takes a apr_uint32_t * as bytes and outputs it's apr_strfsize
 * - %%pF same as above, but takes a apr_off_t *
 * - %%pS same as above, but takes a apr_size_t *
 *
 * %%pA, %%pI, %%pT, %%pp are available from APR 1.0.0 onwards (and in 0.9.x).
 * %%pt is only available from APR 1.2.0 onwards.
 * %%pm, %%pB, %%pF and %%pS are only available from APR 1.3.0 onwards.
 *
 * The %%p hacks are to force gcc's printf warning code to skip
 * over a pointer argument without complaining.  This does
 * mean that the ANSI-style %%p (output a void * in hex format) won't
 * work as expected at all, but that seems to be a fair trade-off
 * for the increased robustness of having printf-warnings work.
 *
 * Additionally, apr_vformatter allows for arbitrary output methods
 * using the apr_vformatter_buff and flush_func.
 *
 * The apr_vformatter_buff has two elements curpos and endpos.
 * curpos is where apr_vformatter will write the next byte of output.
 * It proceeds writing output to curpos, and updating curpos, until
 * either the end of output is reached, or curpos == endpos (i.e. the
 * buffer is full).
 *
 * If the end of output is reached, apr_vformatter returns the
 * number of bytes written.
 *
 * When the buffer is full, the flush_func is called.  The flush_func
 * can return -1 to indicate that no further output should be attempted,
 * and apr_vformatter will return immediately with -1.  Otherwise
 * the flush_func should flush the buffer in whatever manner is
 * appropriate, re apr_pool_t nitialize curpos and endpos, and return 0.
 *
 * Note that flush_func is only invoked as a result of attempting to
 * write another byte at curpos when curpos >= endpos.  So for
 * example, it's possible when the output exactly matches the buffer
 * space available that curpos == endpos will be true when
 * apr_vformatter returns.
 *
 * apr_vformatter does not call out to any other code, it is entirely
 * self-contained.  This allows the callers to do things which are
 * otherwise "unsafe".  For example, apr_psprintf uses the "scratch"
 * space at the unallocated end of a block, and doesn't actually
 * complete the allocation until apr_vformatter returns.  apr_psprintf
 * would be completely broken if apr_vformatter were to call anything
 * that used this same pool.  Similarly http_bprintf() uses the "scratch"
 * space at the end of its output buffer, and doesn't actually note
 * that the space is in use until it either has to flush the buffer
 * or until apr_vformatter returns.
 * </PRE>
 */
APR_DECLARE(int) apr_vformatter(int (*flush_func)(apr_vformatter_buff_t *b),
			        apr_vformatter_buff_t *c, const char *fmt,
			        va_list ap);

/**
 * Display a prompt and read in the password from stdin.
 * @param prompt The prompt to display
 * @param pwbuf Buffer to store the password
 * @param bufsize The length of the password buffer.
 * @remark If the password entered must be truncated to fit in
 * the provided buffer, APR_ENAMETOOLONG will be returned.
 * Note that the bufsize paramater is passed by reference for no
 * reason; its value will never be modified by the apr_password_get()
 * function.
 */
APR_DECLARE(apr_status_t) apr_password_get(const char *prompt, char *pwbuf, 
                                           apr_size_t *bufsize);

/** @} */

/**
 * @defgroup apr_ctype ctype functions
 * These macros allow correct support of 8-bit characters on systems which
 * support 8-bit characters.  Pretty dumb how the cast is required, but
 * that's legacy libc for ya.  These new macros do not support EOF like
 * the standard macros do.  Tough.
 * @{
 */
/** @see isalnum */
#define apr_isalnum(c) (isalnum(((unsigned char)(c))))
/** @see isalpha */
#define apr_isalpha(c) (isalpha(((unsigned char)(c))))
/** @see iscntrl */
#define apr_iscntrl(c) (iscntrl(((unsigned char)(c))))
/** @see isdigit */
#define apr_isdigit(c) (isdigit(((unsigned char)(c))))
/** @see isgraph */
#define apr_isgraph(c) (isgraph(((unsigned char)(c))))
/** @see islower*/
#define apr_islower(c) (islower(((unsigned char)(c))))
/** @see isascii */
#ifdef isascii
#define apr_isascii(c) (isascii(((unsigned char)(c))))
#else
#define apr_isascii(c) (((c) & ~0x7f)==0)
#endif
/** @see isprint */
#define apr_isprint(c) (isprint(((unsigned char)(c))))
/** @see ispunct */
#define apr_ispunct(c) (ispunct(((unsigned char)(c))))
/** @see isspace */
#define apr_isspace(c) (isspace(((unsigned char)(c))))
/** @see isupper */
#define apr_isupper(c) (isupper(((unsigned char)(c))))
/** @see isxdigit */
#define apr_isxdigit(c) (isxdigit(((unsigned char)(c))))
/** @see tolower */
#define apr_tolower(c) (tolower(((unsigned char)(c))))
/** @see toupper */
#define apr_toupper(c) (toupper(((unsigned char)(c))))

/** @} */

#ifdef __cplusplus
}
#endif

#endif	/* ! APR_LIB_H */
apr-1/apr_ldap_rebind.h000064400000006140151730340540010745 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * The APR LDAP rebind functions provide an implementation of
 * a rebind procedure that can be used to allow clients to chase referrals,
 * using the same credentials used to log in originally.
 *
 * Use of this implementation is optional.
 *
 * @file apr_ldap_rebind.h
 * @brief Apache LDAP library
 */

#ifndef APU_LDAP_REBIND_H
#define APU_LDAP_REBIND_H

/**
 * @addtogroup APR_Util_LDAP
 * @{
 **/

#if defined(DOXYGEN)
#include "apr_ldap.h"
#endif

/*
 * Handle the case when LDAP is enabled
 */
#if APR_HAS_LDAP

/**
 * APR LDAP initialize rebind lock
 *
 * This function creates the lock for controlling access to the xref list..
 * @param pool Pool to use when creating the xref_lock.
 */
APU_DECLARE_LDAP(apr_status_t) apr_ldap_rebind_init(apr_pool_t *pool);


/**
 * APR LDAP rebind_add function
 *
 * This function creates a cross reference entry for the specified ldap
 * connection. The rebind callback function will look up this ldap 
 * connection so it can retrieve the bindDN and bindPW for use in any 
 * binds while referrals are being chased.
 *
 * This function will add the callback to the LDAP handle passed in.
 *
 * A cleanup is registered within the pool provided to remove this
 * entry when the pool is removed. Alternatively apr_ldap_rebind_remove()
 * can be called to explicitly remove the entry at will.
 *
 * @param pool The pool to use
 * @param ld The LDAP connectionhandle
 * @param bindDN The bind DN to be used for any binds while chasing 
 *               referrals on this ldap connection.
 * @param bindPW The bind Password to be used for any binds while 
 *               chasing referrals on this ldap connection.
 */
APU_DECLARE_LDAP(apr_status_t) apr_ldap_rebind_add(apr_pool_t *pool,
                                                   LDAP *ld,
                                                   const char *bindDN,
                                                   const char *bindPW);

/**
 * APR LDAP rebind_remove function
 *
 * This function removes the rebind cross reference entry for the
 * specified ldap connection.
 *
 * If not explicitly removed, this function will be called automatically
 * when the pool is cleaned up.
 *
 * @param ld The LDAP connectionhandle
 */
APU_DECLARE_LDAP(apr_status_t) apr_ldap_rebind_remove(LDAP *ld);

#endif /* APR_HAS_LDAP */

/** @} */

#endif /* APU_LDAP_REBIND_H */

apr-1/apr_signal.h000064400000005311151730340540007756 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_SIGNAL_H
#define APR_SIGNAL_H

/**
 * @file apr_signal.h
 * @brief APR Signal Handling
 */

#include "apr.h"
#include "apr_pools.h"

#if APR_HAVE_SIGNAL_H
#include <signal.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @defgroup apr_signal Signal Handling
 * @ingroup APR
 * @{
 */

#if APR_HAVE_SIGACTION || defined(DOXYGEN)

#if defined(DARWIN) && !defined(__cplusplus) && !defined(_ANSI_SOURCE)
/* work around Darwin header file bugs
 *   http://www.opensource.apple.com/bugs/X/BSD%20Kernel/2657228.html
 */
#undef SIG_DFL
#undef SIG_IGN
#undef SIG_ERR
#define SIG_DFL (void (*)(int))0
#define SIG_IGN (void (*)(int))1
#define SIG_ERR (void (*)(int))-1
#endif

/** Function prototype for signal handlers */
typedef void apr_sigfunc_t(int);

/**
 * Set the signal handler function for a given signal
 * @param signo The signal (eg... SIGWINCH)
 * @param func the function to get called
 */
APR_DECLARE(apr_sigfunc_t *) apr_signal(int signo, apr_sigfunc_t * func);

#if defined(SIG_IGN) && !defined(SIG_ERR)
#define SIG_ERR ((apr_sigfunc_t *) -1)
#endif

#else /* !APR_HAVE_SIGACTION */
#define apr_signal(a, b) signal(a, b)
#endif


/**
 * Get the description for a specific signal number
 * @param signum The signal number
 * @return The description of the signal
 */
APR_DECLARE(const char *) apr_signal_description_get(int signum);

/**
 * APR-private function for initializing the signal package
 * @internal
 * @param pglobal The internal, global pool
 */
void apr_signal_init(apr_pool_t *pglobal);

/**
 * Block the delivery of a particular signal
 * @param signum The signal number
 * @return status
 */
APR_DECLARE(apr_status_t) apr_signal_block(int signum);

/**
 * Enable the delivery of a particular signal
 * @param signum The signal number
 * @return status
 */
APR_DECLARE(apr_status_t) apr_signal_unblock(int signum);

/** @} */

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* APR_SIGNAL_H */
apr-1/apr_hash.h000064400000024122151730340540007425 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_HASH_H
#define APR_HASH_H

/**
 * @file apr_hash.h
 * @brief APR Hash Tables
 */

#include "apr_pools.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @defgroup apr_hash Hash Tables
 * @ingroup APR 
 * @{
 */

/**
 * When passing a key to apr_hash_set or apr_hash_get, this value can be
 * passed to indicate a string-valued key, and have apr_hash compute the
 * length automatically.
 *
 * @remark apr_hash will use strlen(key) for the length. The NUL terminator
 *         is not included in the hash value (why throw a constant in?).
 *         Since the hash table merely references the provided key (rather
 *         than copying it), apr_hash_this() will return the NUL-term'd key.
 */
#define APR_HASH_KEY_STRING     (-1)

/**
 * Abstract type for hash tables.
 */
typedef struct apr_hash_t apr_hash_t;

/**
 * Abstract type for scanning hash tables.
 */
typedef struct apr_hash_index_t apr_hash_index_t;

/**
 * Callback functions for calculating hash values.
 * @param key The key.
 * @param klen The length of the key, or APR_HASH_KEY_STRING to use the string 
 *             length. If APR_HASH_KEY_STRING then returns the actual key length.
 */
typedef unsigned int (*apr_hashfunc_t)(const char *key, apr_ssize_t *klen);

/**
 * The default hash function.
 */
APR_DECLARE_NONSTD(unsigned int) apr_hashfunc_default(const char *key,
                                                      apr_ssize_t *klen);

/**
 * Create a hash table.
 * @param pool The pool to allocate the hash table out of
 * @return The hash table just created
  */
APR_DECLARE(apr_hash_t *) apr_hash_make(apr_pool_t *pool);

/**
 * Create a hash table with a custom hash function
 * @param pool The pool to allocate the hash table out of
 * @param hash_func A custom hash function.
 * @return The hash table just created
  */
APR_DECLARE(apr_hash_t *) apr_hash_make_custom(apr_pool_t *pool, 
                                               apr_hashfunc_t hash_func);

/**
 * Make a copy of a hash table
 * @param pool The pool from which to allocate the new hash table
 * @param h The hash table to clone
 * @return The hash table just created
 * @remark Makes a shallow copy
 */
APR_DECLARE(apr_hash_t *) apr_hash_copy(apr_pool_t *pool,
                                        const apr_hash_t *h);

/**
 * Associate a value with a key in a hash table.
 * @param ht The hash table
 * @param key Pointer to the key
 * @param klen Length of the key. Can be APR_HASH_KEY_STRING to use the string length.
 * @param val Value to associate with the key
 * @remark If the value is NULL the hash entry is deleted. The key is stored as is,
 *         and so must have a lifetime at least as long as the hash table's pool.
 */
APR_DECLARE(void) apr_hash_set(apr_hash_t *ht, const void *key,
                               apr_ssize_t klen, const void *val);

/**
 * Look up the value associated with a key in a hash table.
 * @param ht The hash table
 * @param key Pointer to the key
 * @param klen Length of the key. Can be APR_HASH_KEY_STRING to use the string length.
 * @return Returns NULL if the key is not present.
 */
APR_DECLARE(void *) apr_hash_get(apr_hash_t *ht, const void *key,
                                 apr_ssize_t klen);

/**
 * Start iterating over the entries in a hash table.
 * @param p The pool to allocate the apr_hash_index_t iterator. If this
 *          pool is NULL, then an internal, non-thread-safe iterator is used.
 * @param ht The hash table
 * @return The iteration state
 * @remark  There is no restriction on adding or deleting hash entries during
 * an iteration (although the results may be unpredictable unless all you do
 * is delete the current entry) and multiple iterations can be in
 * progress at the same time.
 *
 * @par Example:
 *
 * @code
 * int sum_values(apr_pool_t *p, apr_hash_t *ht)
 * {
 *     apr_hash_index_t *hi;
 *     void *val;
 *     int sum = 0;
 *     for (hi = apr_hash_first(p, ht); hi; hi = apr_hash_next(hi)) {
 *         apr_hash_this(hi, NULL, NULL, &val);
 *         sum += *(int *)val;
 *     }
 *     return sum;
 * }
 * @endcode
 */
APR_DECLARE(apr_hash_index_t *) apr_hash_first(apr_pool_t *p, apr_hash_t *ht);

/**
 * Continue iterating over the entries in a hash table.
 * @param hi The iteration state
 * @return a pointer to the updated iteration state.  NULL if there are no more  
 *         entries.
 */
APR_DECLARE(apr_hash_index_t *) apr_hash_next(apr_hash_index_t *hi);

/**
 * Get the current entry's details from the iteration state.
 * @param hi The iteration state
 * @param key Return pointer for the pointer to the key.
 * @param klen Return pointer for the key length.
 * @param val Return pointer for the associated value.
 * @remark The return pointers should point to a variable that will be set to the
 *         corresponding data, or they may be NULL if the data isn't interesting.
 */
APR_DECLARE(void) apr_hash_this(apr_hash_index_t *hi, const void **key, 
                                apr_ssize_t *klen, void **val);

/**
 * Get the current entry's key from the iteration state.
 * @param hi The iteration state
 * @return The pointer to the key
 */
APR_DECLARE(const void*) apr_hash_this_key(apr_hash_index_t *hi);

/**
 * Get the current entry's key length from the iteration state.
 * @param hi The iteration state
 * @return The key length
 */
APR_DECLARE(apr_ssize_t) apr_hash_this_key_len(apr_hash_index_t *hi);

/**
 * Get the current entry's value from the iteration state.
 * @param hi The iteration state
 * @return The pointer to the value
 */
APR_DECLARE(void*) apr_hash_this_val(apr_hash_index_t *hi);

/**
 * Get the number of key/value pairs in the hash table.
 * @param ht The hash table
 * @return The number of key/value pairs in the hash table.
 */
APR_DECLARE(unsigned int) apr_hash_count(apr_hash_t *ht);

/**
 * Clear any key/value pairs in the hash table.
 * @param ht The hash table
 */
APR_DECLARE(void) apr_hash_clear(apr_hash_t *ht);

/**
 * Merge two hash tables into one new hash table. The values of the overlay
 * hash override the values of the base if both have the same key.  Both
 * hash tables must use the same hash function.
 * @param p The pool to use for the new hash table
 * @param overlay The table to add to the initial table
 * @param base The table that represents the initial values of the new table
 * @return A new hash table containing all of the data from the two passed in
 */
APR_DECLARE(apr_hash_t *) apr_hash_overlay(apr_pool_t *p,
                                           const apr_hash_t *overlay, 
                                           const apr_hash_t *base);

/**
 * Merge two hash tables into one new hash table. If the same key
 * is present in both tables, call the supplied merge function to
 * produce a merged value for the key in the new table.  Both
 * hash tables must use the same hash function.
 * @param p The pool to use for the new hash table
 * @param h1 The first of the tables to merge
 * @param h2 The second of the tables to merge
 * @param merger A callback function to merge values, or NULL to
 *  make values from h1 override values from h2 (same semantics as
 *  apr_hash_overlay())
 * @param data Client data to pass to the merger function
 * @return A new hash table containing all of the data from the two passed in
 */
APR_DECLARE(apr_hash_t *) apr_hash_merge(apr_pool_t *p,
                                         const apr_hash_t *h1,
                                         const apr_hash_t *h2,
                                         void * (*merger)(apr_pool_t *p,
                                                     const void *key,
                                                     apr_ssize_t klen,
                                                     const void *h1_val,
                                                     const void *h2_val,
                                                     const void *data),
                                         const void *data);

/**
 * Declaration prototype for the iterator callback function of apr_hash_do().
 *
 * @param rec The data passed as the first argument to apr_hash_[v]do()
 * @param key The key from this iteration of the hash table
 * @param klen The key length from this iteration of the hash table
 * @param value The value from this iteration of the hash table
 * @remark Iteration continues while this callback function returns non-zero.
 * To export the callback function for apr_hash_do() it must be declared 
 * in the _NONSTD convention.
 */
typedef int (apr_hash_do_callback_fn_t)(void *rec, const void *key,
                                                   apr_ssize_t klen,
                                                   const void *value);

/** 
 * Iterate over a hash table running the provided function once for every
 * element in the hash table. The @p comp function will be invoked for
 * every element in the hash table.
 *
 * @param comp The function to run
 * @param rec The data to pass as the first argument to the function
 * @param ht The hash table to iterate over
 * @return FALSE if one of the comp() iterations returned zero; TRUE if all
 *            iterations returned non-zero
 * @see apr_hash_do_callback_fn_t
 */
APR_DECLARE(int) apr_hash_do(apr_hash_do_callback_fn_t *comp,
                             void *rec, const apr_hash_t *ht);

/**
 * Get a pointer to the pool which the hash table was created in
 */
APR_POOL_DECLARE_ACCESSOR(hash);

/** @} */

#ifdef __cplusplus
}
#endif

#endif	/* !APR_HASH_H */
apr-1/apr_dbd.h000064400000056545151730340540007251 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* Overview of what this is and does:
 * http://www.apache.org/~niq/dbd.html
 */

#ifndef APR_DBD_H
#define APR_DBD_H

#include "apu.h"
#include "apr_pools.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @file apr_dbd.h
 * @brief APR-UTIL DBD library
 */
/**
 * @defgroup APR_Util_DBD DBD routines
 * @ingroup APR_Util
 * @{
 */

/**
 * Mapping of C to SQL types, used for prepared statements.
 * @remarks
 * For apr_dbd_p[v]query/select functions, in and out parameters are always
 * const char * (i.e. regular nul terminated strings). LOB types are passed
 * with four (4) arguments: payload, length, table and column, all as const
 * char *, where table and column are reserved for future use by Oracle.
 * @remarks
 * For apr_dbd_p[v]bquery/select functions, in and out parameters are
 * described next to each enumeration constant and are generally native binary
 * types or some APR data type. LOB types are passed with four (4) arguments:
 * payload (char*), length (apr_size_t*), table (char*) and column (char*).
 * Table and column are reserved for future use by Oracle.
 */
typedef enum {
    APR_DBD_TYPE_NONE,
    APR_DBD_TYPE_TINY,       /**< \%hhd : in, out: char* */
    APR_DBD_TYPE_UTINY,      /**< \%hhu : in, out: unsigned char* */
    APR_DBD_TYPE_SHORT,      /**< \%hd  : in, out: short* */
    APR_DBD_TYPE_USHORT,     /**< \%hu  : in, out: unsigned short* */
    APR_DBD_TYPE_INT,        /**< \%d   : in, out: int* */
    APR_DBD_TYPE_UINT,       /**< \%u   : in, out: unsigned int* */
    APR_DBD_TYPE_LONG,       /**< \%ld  : in, out: long* */
    APR_DBD_TYPE_ULONG,      /**< \%lu  : in, out: unsigned long* */
    APR_DBD_TYPE_LONGLONG,   /**< \%lld : in, out: apr_int64_t* */
    APR_DBD_TYPE_ULONGLONG,  /**< \%llu : in, out: apr_uint64_t* */
    APR_DBD_TYPE_FLOAT,      /**< \%f   : in, out: float* */
    APR_DBD_TYPE_DOUBLE,     /**< \%lf  : in, out: double* */
    APR_DBD_TYPE_STRING,     /**< \%s   : in: char*, out: char** */
    APR_DBD_TYPE_TEXT,       /**< \%pDt : in: char*, out: char** */
    APR_DBD_TYPE_TIME,       /**< \%pDi : in: char*, out: char** */
    APR_DBD_TYPE_DATE,       /**< \%pDd : in: char*, out: char** */
    APR_DBD_TYPE_DATETIME,   /**< \%pDa : in: char*, out: char** */
    APR_DBD_TYPE_TIMESTAMP,  /**< \%pDs : in: char*, out: char** */
    APR_DBD_TYPE_ZTIMESTAMP, /**< \%pDz : in: char*, out: char** */
    APR_DBD_TYPE_BLOB,       /**< \%pDb : in: char* apr_size_t* char* char*, out: apr_bucket_brigade* */
    APR_DBD_TYPE_CLOB,       /**< \%pDc : in: char* apr_size_t* char* char*, out: apr_bucket_brigade* */
    APR_DBD_TYPE_NULL        /**< \%pDn : in: void*, out: void** */
} apr_dbd_type_e;

/* These are opaque structs.  Instantiation is up to each backend */
typedef struct apr_dbd_driver_t apr_dbd_driver_t;
typedef struct apr_dbd_t apr_dbd_t;
typedef struct apr_dbd_transaction_t apr_dbd_transaction_t;
typedef struct apr_dbd_results_t apr_dbd_results_t;
typedef struct apr_dbd_row_t apr_dbd_row_t;
typedef struct apr_dbd_prepared_t apr_dbd_prepared_t;

/** apr_dbd_init: perform once-only initialisation.  Call once only.
 *
 *  @param pool - pool to register any shutdown cleanups, etc
 */
APU_DECLARE(apr_status_t) apr_dbd_init(apr_pool_t *pool);

/** apr_dbd_get_driver: get the driver struct for a name
 *
 *  @param pool - (process) pool to register cleanup
 *  @param name - driver name
 *  @param driver - pointer to driver struct.
 *  @return APR_SUCCESS for success
 *  @return APR_ENOTIMPL for no driver (when DSO not enabled)
 *  @return APR_EDSOOPEN if DSO driver file can't be opened
 *  @return APR_ESYMNOTFOUND if the driver file doesn't contain a driver
 */
APU_DECLARE(apr_status_t) apr_dbd_get_driver(apr_pool_t *pool, const char *name,
                                             const apr_dbd_driver_t **driver);

/** apr_dbd_open_ex: open a connection to a backend
 *
 *  @param driver - driver struct.
 *  @param pool - working pool
 *  @param params - arguments to driver (implementation-dependent)
 *  @param handle - pointer to handle to return
 *  @param error - descriptive error.
 *  @return APR_SUCCESS for success
 *  @return APR_EGENERAL if driver exists but connection failed
 *  @remarks PostgreSQL: the params is passed directly to the PQconnectdb()
 *  function (check PostgreSQL documentation for more details on the syntax).
 *  @remarks SQLite2: the params is split on a colon, with the first part used
 *  as the filename and second part converted to an integer and used as file
 *  mode.
 *  @remarks SQLite3: the params is passed directly to the sqlite3_open()
 *  function as a filename to be opened (check SQLite3 documentation for more
 *  details).
 *  @remarks Oracle: the params can have "user", "pass", "dbname" and "server"
 *  keys, each followed by an equal sign and a value. Such key/value pairs can
 *  be delimited by space, CR, LF, tab, semicolon, vertical bar or comma.
 *  @remarks MySQL: the params can have "host", "port", "user", "pass",
 *  "dbname", "sock", "flags" "fldsz", "group" and "reconnect" keys, each
 *  followed by an equal sign and a value. Such key/value pairs can be
 *  delimited by space, CR, LF, tab, semicolon, vertical bar or comma. For
 *  now, "flags" can only recognise CLIENT_FOUND_ROWS (check MySQL manual for
 *  details). The value associated with "fldsz" determines maximum amount of
 *  memory (in bytes) for each of the fields in the result set of prepared
 *  statements. By default, this value is 1 MB. The value associated with
 *  "group" determines which group from configuration file to use (see
 *  MYSQL_READ_DEFAULT_GROUP option of mysql_options() in MySQL manual).
 *  Reconnect is set to 1 by default (i.e. true).
 */
APU_DECLARE(apr_status_t) apr_dbd_open_ex(const apr_dbd_driver_t *driver,
                                          apr_pool_t *pool, const char *params,
                                          apr_dbd_t **handle,
                                          const char **error);

/** apr_dbd_open: open a connection to a backend
 *
 *  @param driver - driver struct.
 *  @param pool - working pool
 *  @param params - arguments to driver (implementation-dependent)
 *  @param handle - pointer to handle to return
 *  @return APR_SUCCESS for success
 *  @return APR_EGENERAL if driver exists but connection failed
 *  @see apr_dbd_open_ex
 */
APU_DECLARE(apr_status_t) apr_dbd_open(const apr_dbd_driver_t *driver,
                                       apr_pool_t *pool, const char *params,
                                       apr_dbd_t **handle);

/** apr_dbd_close: close a connection to a backend
 *
 *  @param driver - driver struct.
 *  @param handle - handle to close
 *  @return APR_SUCCESS for success or error status
 */
APU_DECLARE(apr_status_t) apr_dbd_close(const apr_dbd_driver_t *driver,
                                        apr_dbd_t *handle);

/* apr-function-shaped versions of things */

/** apr_dbd_name: get the name of the driver
 *
 *  @param driver - the driver
 *  @return - name
 */
APU_DECLARE(const char*) apr_dbd_name(const apr_dbd_driver_t *driver);

/** apr_dbd_native_handle: get native database handle of the underlying db
 *
 *  @param driver - the driver
 *  @param handle - apr_dbd handle
 *  @return - native handle
 */
APU_DECLARE(void*) apr_dbd_native_handle(const apr_dbd_driver_t *driver,
                                         apr_dbd_t *handle);

/** check_conn: check status of a database connection
 *
 *  @param driver - the driver
 *  @param pool - working pool
 *  @param handle - the connection to check
 *  @return APR_SUCCESS or error
 */
APU_DECLARE(int) apr_dbd_check_conn(const apr_dbd_driver_t *driver, apr_pool_t *pool,
                                    apr_dbd_t *handle);

/** apr_dbd_set_dbname: select database name.  May be a no-op if not supported.
 *
 *  @param driver - the driver
 *  @param pool - working pool
 *  @param handle - the connection
 *  @param name - the database to select
 *  @return 0 for success or error code
 */
APU_DECLARE(int) apr_dbd_set_dbname(const apr_dbd_driver_t *driver, apr_pool_t *pool,
                                    apr_dbd_t *handle, const char *name);

/** apr_dbd_transaction_start: start a transaction.  May be a no-op.
 *
 *  @param driver - the driver
 *  @param pool - a pool to use for error messages (if any).
 *  @param handle - the db connection
 *  @param trans - ptr to a transaction.  May be null on entry
 *  @return 0 for success or error code
 *  @remarks Note that transaction modes, set by calling
 *  apr_dbd_transaction_mode_set(), will affect all query/select calls within
 *  a transaction. By default, any error in query/select during a transaction
 *  will cause the transaction to inherit the error code and any further
 *  query/select calls will fail immediately. Put transaction in "ignore
 *  errors" mode to avoid that. Use "rollback" mode to do explicit rollback.
 */
APU_DECLARE(int) apr_dbd_transaction_start(const apr_dbd_driver_t *driver,
                                           apr_pool_t *pool,
                                           apr_dbd_t *handle,
                                           apr_dbd_transaction_t **trans);

/** apr_dbd_transaction_end: end a transaction
 *  (commit on success, rollback on error).
 *  May be a no-op.
 *
 *  @param driver - the driver
 *  @param handle - the db connection
 *  @param trans - the transaction.
 *  @return 0 for success or error code
 */
APU_DECLARE(int) apr_dbd_transaction_end(const apr_dbd_driver_t *driver,
                                         apr_pool_t *pool,
                                         apr_dbd_transaction_t *trans);

#define APR_DBD_TRANSACTION_COMMIT        0x00  /**< commit the transaction */
#define APR_DBD_TRANSACTION_ROLLBACK      0x01  /**< rollback the transaction */
#define APR_DBD_TRANSACTION_IGNORE_ERRORS 0x02  /**< ignore transaction errors */

/** apr_dbd_transaction_mode_get: get the mode of transaction
 *
 *  @param driver - the driver
 *  @param trans  - the transaction
 *  @return mode of transaction
 */
APU_DECLARE(int) apr_dbd_transaction_mode_get(const apr_dbd_driver_t *driver,
                                              apr_dbd_transaction_t *trans);

/** apr_dbd_transaction_mode_set: set the mode of transaction
 *
 *  @param driver - the driver
 *  @param trans  - the transaction
 *  @param mode   - new mode of the transaction
 *  @return the mode of transaction in force after the call
 */
APU_DECLARE(int) apr_dbd_transaction_mode_set(const apr_dbd_driver_t *driver,
                                              apr_dbd_transaction_t *trans,
                                              int mode);

/** apr_dbd_query: execute an SQL query that doesn't return a result set
 *
 *  @param driver - the driver
 *  @param handle - the connection
 *  @param nrows - number of rows affected.
 *  @param statement - the SQL statement to execute
 *  @return 0 for success or error code
 */
APU_DECLARE(int) apr_dbd_query(const apr_dbd_driver_t *driver, apr_dbd_t *handle,
                               int *nrows, const char *statement);

/** apr_dbd_select: execute an SQL query that returns a result set
 *
 *  @param driver - the driver
 *  @param pool - pool to allocate the result set
 *  @param handle - the connection
 *  @param res - pointer to result set pointer.  May point to NULL on entry
 *  @param statement - the SQL statement to execute
 *  @param random - 1 to support random access to results (seek any row);
 *                  0 to support only looping through results in order
 *                    (async access - faster)
 *  @return 0 for success or error code
 */
APU_DECLARE(int) apr_dbd_select(const apr_dbd_driver_t *driver, apr_pool_t *pool,
                                apr_dbd_t *handle, apr_dbd_results_t **res,
                                const char *statement, int random);

/** apr_dbd_num_cols: get the number of columns in a results set
 *
 *  @param driver - the driver
 *  @param res - result set.
 *  @return number of columns
 */
APU_DECLARE(int) apr_dbd_num_cols(const apr_dbd_driver_t *driver,
                                  apr_dbd_results_t *res);

/** apr_dbd_num_tuples: get the number of rows in a results set
 *  of a synchronous select
 *
 *  @param driver - the driver
 *  @param res - result set.
 *  @return number of rows, or -1 if the results are asynchronous
 */
APU_DECLARE(int) apr_dbd_num_tuples(const apr_dbd_driver_t *driver,
                                    apr_dbd_results_t *res);

/** apr_dbd_get_row: get a row from a result set
 *
 *  @param driver - the driver
 *  @param pool - pool to allocate the row
 *  @param res - result set pointer
 *  @param row - pointer to row pointer.  May point to NULL on entry
 *  @param rownum - row number (counting from 1), or -1 for "next row".
 *                  Ignored if random access is not supported.
 *  @return 0 for success, -1 for rownum out of range or data finished
 */
APU_DECLARE(int) apr_dbd_get_row(const apr_dbd_driver_t *driver, apr_pool_t *pool,
                                 apr_dbd_results_t *res, apr_dbd_row_t **row,
                                 int rownum);

/** apr_dbd_get_entry: get an entry from a row
 *
 *  @param driver - the driver
 *  @param row - row pointer
 *  @param col - entry number
 *  @return value from the row, or NULL if col is out of bounds.
 */
APU_DECLARE(const char*) apr_dbd_get_entry(const apr_dbd_driver_t *driver,
                                           apr_dbd_row_t *row, int col);

/** apr_dbd_get_name: get an entry name from a result set
 *
 *  @param driver - the driver
 *  @param res - result set pointer
 *  @param col - entry number
 *  @return name of the entry, or NULL if col is out of bounds.
 */
APU_DECLARE(const char*) apr_dbd_get_name(const apr_dbd_driver_t *driver,
                                          apr_dbd_results_t *res, int col);


/** apr_dbd_error: get current error message (if any)
 *
 *  @param driver - the driver
 *  @param handle - the connection
 *  @param errnum - error code from operation that returned an error
 *  @return the database current error message, or message for errnum
 *          (implementation-dependent whether errnum is ignored)
 */
APU_DECLARE(const char*) apr_dbd_error(const apr_dbd_driver_t *driver,
                                       apr_dbd_t *handle, int errnum);

/** apr_dbd_escape: escape a string so it is safe for use in query/select
 *
 *  @param driver - the driver
 *  @param pool - pool to alloc the result from
 *  @param string - the string to escape
 *  @param handle - the connection
 *  @return the escaped, safe string
 */
APU_DECLARE(const char*) apr_dbd_escape(const apr_dbd_driver_t *driver,
                                        apr_pool_t *pool, const char *string,
                                        apr_dbd_t *handle);

/** apr_dbd_prepare: prepare a statement
 *
 *  @param driver - the driver
 *  @param pool - pool to alloc the result from
 *  @param handle - the connection
 *  @param query - the SQL query
 *  @param label - A label for the prepared statement.
 *                 use NULL for temporary prepared statements
 *                 (eg within a Request in httpd)
 *  @param statement - statement to prepare.  May point to null on entry.
 *  @return 0 for success or error code
 *  @remarks To specify parameters of the prepared query, use \%s, \%d etc.
 *  (see below for full list) in place of database specific parameter syntax
 *  (e.g.  for PostgreSQL, this would be $1, $2, for SQLite3 this would be ?
 *  etc.).  For instance: "SELECT name FROM customers WHERE name=%s" would be
 *  a query that this function understands.
 *  @remarks Here is the full list of format specifiers that this function
 *  understands and what they map to in SQL: \%hhd (TINY INT), \%hhu (UNSIGNED
 *  TINY INT), \%hd (SHORT), \%hu (UNSIGNED SHORT), \%d (INT), \%u (UNSIGNED
 *  INT), \%ld (LONG), \%lu (UNSIGNED LONG), \%lld (LONG LONG), \%llu
 *  (UNSIGNED LONG LONG), \%f (FLOAT, REAL), \%lf (DOUBLE PRECISION), \%s
 *  (VARCHAR), \%pDt (TEXT), \%pDi (TIME), \%pDd (DATE), \%pDa (DATETIME),
 *  \%pDs (TIMESTAMP), \%pDz (TIMESTAMP WITH TIME ZONE), \%pDb (BLOB), \%pDc
 *  (CLOB) and \%pDn (NULL). Not all databases have support for all these
 *  types, so the underlying driver will attempt the "best match" where
 *  possible. A \% followed by any letter not in the above list will be
 *  interpreted as VARCHAR (i.e. \%s).
 */
APU_DECLARE(int) apr_dbd_prepare(const apr_dbd_driver_t *driver, apr_pool_t *pool,
                                 apr_dbd_t *handle, const char *query,
                                 const char *label,
                                 apr_dbd_prepared_t **statement);


/** apr_dbd_pquery: query using a prepared statement + args
 *
 *  @param driver - the driver
 *  @param pool - working pool
 *  @param handle - the connection
 *  @param nrows - number of rows affected.
 *  @param statement - the prepared statement to execute
 *  @param nargs - ignored (for backward compatibility only)
 *  @param args - args to prepared statement
 *  @return 0 for success or error code
 */
APU_DECLARE(int) apr_dbd_pquery(const apr_dbd_driver_t *driver, apr_pool_t *pool,
                                apr_dbd_t *handle, int *nrows,
                                apr_dbd_prepared_t *statement, int nargs,
                                const char **args);

/** apr_dbd_pselect: select using a prepared statement + args
 *
 *  @param driver - the driver
 *  @param pool - working pool
 *  @param handle - the connection
 *  @param res - pointer to query results.  May point to NULL on entry
 *  @param statement - the prepared statement to execute
 *  @param random - Whether to support random-access to results
 *  @param nargs - ignored (for backward compatibility only)
 *  @param args - args to prepared statement
 *  @return 0 for success or error code
 */
APU_DECLARE(int) apr_dbd_pselect(const apr_dbd_driver_t *driver, apr_pool_t *pool,
                                 apr_dbd_t *handle, apr_dbd_results_t **res,
                                 apr_dbd_prepared_t *statement, int random,
                                 int nargs, const char **args);

/** apr_dbd_pvquery: query using a prepared statement + args
 *
 *  @param driver - the driver
 *  @param pool - working pool
 *  @param handle - the connection
 *  @param nrows - number of rows affected.
 *  @param statement - the prepared statement to execute
 *  @param ... - varargs list
 *  @return 0 for success or error code
 */
APU_DECLARE_NONSTD(int) apr_dbd_pvquery(const apr_dbd_driver_t *driver, 
                                        apr_pool_t *pool,
                                        apr_dbd_t *handle, int *nrows,
                                        apr_dbd_prepared_t *statement, ...);

/** apr_dbd_pvselect: select using a prepared statement + args
 *
 *  @param driver - the driver
 *  @param pool - working pool
 *  @param handle - the connection
 *  @param res - pointer to query results.  May point to NULL on entry
 *  @param statement - the prepared statement to execute
 *  @param random - Whether to support random-access to results
 *  @param ... - varargs list
 *  @return 0 for success or error code
 */
APU_DECLARE_NONSTD(int) apr_dbd_pvselect(const apr_dbd_driver_t *driver,
                                         apr_pool_t *pool, apr_dbd_t *handle,
                                         apr_dbd_results_t **res,
                                         apr_dbd_prepared_t *statement,
                                         int random, ...);

/** apr_dbd_pbquery: query using a prepared statement + binary args
 *
 *  @param driver - the driver
 *  @param pool - working pool
 *  @param handle - the connection
 *  @param nrows - number of rows affected.
 *  @param statement - the prepared statement to execute
 *  @param args - binary args to prepared statement
 *  @return 0 for success or error code
 */
APU_DECLARE(int) apr_dbd_pbquery(const apr_dbd_driver_t *driver,
                                 apr_pool_t *pool, apr_dbd_t *handle,
                                 int *nrows, apr_dbd_prepared_t *statement,
                                 const void **args);

/** apr_dbd_pbselect: select using a prepared statement + binary args
 *
 *  @param driver - the driver
 *  @param pool - working pool
 *  @param handle - the connection
 *  @param res - pointer to query results.  May point to NULL on entry
 *  @param statement - the prepared statement to execute
 *  @param random - Whether to support random-access to results
 *  @param args - binary args to prepared statement
 *  @return 0 for success or error code
 */
APU_DECLARE(int) apr_dbd_pbselect(const apr_dbd_driver_t *driver,
                                  apr_pool_t *pool,
                                  apr_dbd_t *handle, apr_dbd_results_t **res,
                                  apr_dbd_prepared_t *statement, int random,
                                  const void **args);

/** apr_dbd_pvbquery: query using a prepared statement + binary args
 *
 *  @param driver - the driver
 *  @param pool - working pool
 *  @param handle - the connection
 *  @param nrows - number of rows affected.
 *  @param statement - the prepared statement to execute
 *  @param ... - varargs list of binary args
 *  @return 0 for success or error code
 */
APU_DECLARE_NONSTD(int) apr_dbd_pvbquery(const apr_dbd_driver_t *driver,
                                         apr_pool_t *pool,
                                         apr_dbd_t *handle, int *nrows,
                                         apr_dbd_prepared_t *statement, ...);

/** apr_dbd_pvbselect: select using a prepared statement + binary args
 *
 *  @param driver - the driver
 *  @param pool - working pool
 *  @param handle - the connection
 *  @param res - pointer to query results.  May point to NULL on entry
 *  @param statement - the prepared statement to execute
 *  @param random - Whether to support random-access to results
 *  @param ... - varargs list of binary args
 *  @return 0 for success or error code
 */
APU_DECLARE_NONSTD(int) apr_dbd_pvbselect(const apr_dbd_driver_t *driver,
                                          apr_pool_t *pool, apr_dbd_t *handle,
                                          apr_dbd_results_t **res,
                                          apr_dbd_prepared_t *statement,
                                          int random, ...);

/** apr_dbd_datum_get: get a binary entry from a row
 *
 *  @param driver - the driver
 *  @param row - row pointer
 *  @param col - entry number
 *  @param type - type of data to get
 *  @param data - pointer to data, allocated by the caller
 *  @return APR_SUCCESS on success, APR_ENOENT if data is NULL or APR_EGENERAL
 */
APU_DECLARE(apr_status_t) apr_dbd_datum_get(const apr_dbd_driver_t *driver,
                                            apr_dbd_row_t *row, int col,
                                            apr_dbd_type_e type, void *data);

/** @} */

#ifdef __cplusplus
}
#endif

#endif
apr-1/apr_uuid.h000064400000004066151730340540007455 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @file apr_uuid.h
 * @brief APR UUID library
 */
#ifndef APR_UUID_H
#define APR_UUID_H

#include "apu.h"
#include "apr_errno.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @defgroup APR_UUID UUID Handling
 * @ingroup APR
 * @{
 */

/**
 * we represent a UUID as a block of 16 bytes.
 */

typedef struct {
    unsigned char data[16]; /**< the actual UUID */
} apr_uuid_t;

/** UUIDs are formatted as: 00112233-4455-6677-8899-AABBCCDDEEFF */
#define APR_UUID_FORMATTED_LENGTH 36


/**
 * Generate and return a (new) UUID
 * @param uuid The resulting UUID
 */ 
APU_DECLARE(void) apr_uuid_get(apr_uuid_t *uuid);

/**
 * Format a UUID into a string, following the standard format
 * @param buffer The buffer to place the formatted UUID string into. It must
 *               be at least APR_UUID_FORMATTED_LENGTH + 1 bytes long to hold
 *               the formatted UUID and a null terminator
 * @param uuid The UUID to format
 */ 
APU_DECLARE(void) apr_uuid_format(char *buffer, const apr_uuid_t *uuid);

/**
 * Parse a standard-format string into a UUID
 * @param uuid The resulting UUID
 * @param uuid_str The formatted UUID
 */ 
APU_DECLARE(apr_status_t) apr_uuid_parse(apr_uuid_t *uuid, const char *uuid_str);

/** @} */
#ifdef __cplusplus
}
#endif

#endif /* APR_UUID_H */
apr-1/apr_xml.h000064400000030306151730340550007304 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * @file apr_xml.h
 * @brief APR-UTIL XML Library
 */
#ifndef APR_XML_H
#define APR_XML_H

/**
 * @defgroup APR_Util_XML XML 
 * @ingroup APR_Util
 * @{
 */
#include "apr_pools.h"
#include "apr_tables.h"
#include "apr_file_io.h"

#include "apu.h"
#if APR_CHARSET_EBCDIC
#include "apr_xlate.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @package Apache XML library
 */

/* -------------------------------------------------------------------- */

/* ### these will need to move at some point to a more logical spot */

/** @see apr_text */
typedef struct apr_text apr_text;

/** Structure to keep a linked list of pieces of text */
struct apr_text {
    /** The current piece of text */
    const char *text;
    /** a pointer to the next piece of text */
    struct apr_text *next;
};

/** @see apr_text_header */
typedef struct apr_text_header apr_text_header;

/** A list of pieces of text */
struct apr_text_header {
    /** The first piece of text in the list */
    apr_text *first;
    /** The last piece of text in the list */
    apr_text *last;
};

/**
 * Append a piece of text to the end of a list
 * @param p The pool to allocate out of
 * @param hdr The text header to append to
 * @param text The new text to append
 */
APU_DECLARE(void) apr_text_append(apr_pool_t *p, apr_text_header *hdr,
                                  const char *text);


/* --------------------------------------------------------------------
**
** XML PARSING
*/

/*
** Qualified namespace values
**
** APR_XML_NS_DAV_ID
**    We always insert the "DAV:" namespace URI at the head of the
**    namespace array. This means that it will always be at ID==0,
**    making it much easier to test for.
**
** APR_XML_NS_NONE
**    This special ID is used for two situations:
**
**    1) The namespace prefix begins with "xml" (and we do not know
**       what it means). Namespace prefixes with "xml" (any case) as
**       their first three characters are reserved by the XML Namespaces
**       specification for future use. mod_dav will pass these through
**       unchanged. When this identifier is used, the prefix is LEFT in
**       the element/attribute name. Downstream processing should not
**       prepend another prefix.
**
**    2) The element/attribute does not have a namespace.
**
**       a) No prefix was used, and a default namespace has not been
**          defined.
**       b) No prefix was used, and the default namespace was specified
**          to mean "no namespace". This is done with a namespace
**          declaration of:  xmlns=""
**          (this declaration is typically used to override a previous
**          specification for the default namespace)
**
**       In these cases, we need to record that the elem/attr has no
**       namespace so that we will not attempt to prepend a prefix.
**       All namespaces that are used will have a prefix assigned to
**       them -- mod_dav will never set or use the default namespace
**       when generating XML. This means that "no prefix" will always
**       mean "no namespace".
**
**    In both cases, the XML generation will avoid prepending a prefix.
**    For the first case, this means the original prefix/name will be
**    inserted into the output stream. For the latter case, it means
**    the name will have no prefix, and since we never define a default
**    namespace, this means it will have no namespace.
**
** Note: currently, mod_dav understands the "xmlns" prefix and the
**     "xml:lang" attribute. These are handled specially (they aren't
**     left within the XML tree), so the APR_XML_NS_NONE value won't ever
**     really apply to these values.
*/
#define APR_XML_NS_DAV_ID	0	/**< namespace ID for "DAV:" */
#define APR_XML_NS_NONE		-10	/**< no namespace for this elem/attr */

#define APR_XML_NS_ERROR_BASE	-100	/**< used only during processing */
/** Is this namespace an error? */
#define APR_XML_NS_IS_ERROR(e)	((e) <= APR_XML_NS_ERROR_BASE)

/** @see apr_xml_attr */
typedef struct apr_xml_attr apr_xml_attr;
/** @see apr_xml_elem */
typedef struct apr_xml_elem apr_xml_elem;
/** @see apr_xml_doc */
typedef struct apr_xml_doc apr_xml_doc;

/** apr_xml_attr: holds a parsed XML attribute */
struct apr_xml_attr {
    /** attribute name */
    const char *name;
    /** index into namespace array */
    int ns;

    /** attribute value */
    const char *value;

    /** next attribute */
    struct apr_xml_attr *next;
};

/** apr_xml_elem: holds a parsed XML element */
struct apr_xml_elem {
    /** element name */
    const char *name;
    /** index into namespace array */
    int ns;
    /** xml:lang for attrs/contents */
    const char *lang;

    /** cdata right after start tag */
    apr_text_header first_cdata;
    /** cdata after MY end tag */
    apr_text_header following_cdata;

    /** parent element */
    struct apr_xml_elem *parent;	
    /** next (sibling) element */
    struct apr_xml_elem *next;	
    /** first child element */
    struct apr_xml_elem *first_child;
    /** first attribute */
    struct apr_xml_attr *attr;		

    /* used only during parsing */
    /** last child element */
    struct apr_xml_elem *last_child;
    /** namespaces scoped by this elem */
    struct apr_xml_ns_scope *ns_scope;

    /* used by modules during request processing */
    /** Place for modules to store private data */
    void *priv;
};

/** Is this XML element empty? */
#define APR_XML_ELEM_IS_EMPTY(e) ((e)->first_child == NULL && \
                                  (e)->first_cdata.first == NULL)

/** apr_xml_doc: holds a parsed XML document */
struct apr_xml_doc {
    /** root element */
    apr_xml_elem *root;	
    /** array of namespaces used */
    apr_array_header_t *namespaces;
};

/** Opaque XML parser structure */
typedef struct apr_xml_parser apr_xml_parser;

/**
 * Create an XML parser
 * @param pool The pool for allocating the parser and the parse results.
 * @return The new parser.
 */
APU_DECLARE(apr_xml_parser *) apr_xml_parser_create(apr_pool_t *pool);

/**
 * Parse a File, producing a xml_doc
 * @param p      The pool for allocating the parse results.
 * @param parser A pointer to *parser (needed so calling function can get
 *               errors), will be set to NULL on successful completion.
 * @param ppdoc  A pointer to *apr_xml_doc (which has the parsed results in it)
 * @param xmlfd  A file to read from.
 * @param buffer_length Buffer length which would be suitable 
 * @return Any errors found during parsing.
 */
APU_DECLARE(apr_status_t) apr_xml_parse_file(apr_pool_t *p,
                                             apr_xml_parser **parser,
                                             apr_xml_doc **ppdoc,
                                             apr_file_t *xmlfd,
                                             apr_size_t buffer_length);


/**
 * Feed input into the parser
 * @param parser The XML parser for parsing this data.
 * @param data The data to parse.
 * @param len The length of the data.
 * @return Any errors found during parsing.
 * @remark Use apr_xml_parser_geterror() to get more error information.
 */
APU_DECLARE(apr_status_t) apr_xml_parser_feed(apr_xml_parser *parser,
                                              const char *data,
                                              apr_size_t len);

/**
 * Terminate the parsing and return the result
 * @param parser The XML parser for parsing this data.
 * @param pdoc The resulting parse information. May be NULL to simply
 *             terminate the parsing without fetching the info.
 * @return Any errors found during the final stage of parsing.
 * @remark Use apr_xml_parser_geterror() to get more error information.
 */
APU_DECLARE(apr_status_t) apr_xml_parser_done(apr_xml_parser *parser,
                                              apr_xml_doc **pdoc);

/**
 * Fetch additional error information from the parser.
 * @param parser The XML parser to query for errors.
 * @param errbuf A buffer for storing error text.
 * @param errbufsize The length of the error text buffer.
 * @return The error buffer
 */
APU_DECLARE(char *) apr_xml_parser_geterror(apr_xml_parser *parser,
                                            char *errbuf,
                                            apr_size_t errbufsize);


/**
 * Converts an XML element tree to flat text 
 * @param p The pool to allocate out of
 * @param elem The XML element to convert
 * @param style How to covert the XML.  One of:
 * <PRE>
 *     APR_XML_X2T_FULL                start tag, contents, end tag 
 *     APR_XML_X2T_INNER               contents only 
 *     APR_XML_X2T_LANG_INNER          xml:lang + inner contents 
 *     APR_XML_X2T_FULL_NS_LANG        FULL + ns defns + xml:lang 
 *     APR_XML_X2T_PARSED              original prefixes
 * </PRE>
 * @param namespaces The namespace of the current XML element
 * @param ns_map Namespace mapping
 * @param pbuf Buffer to put the converted text into
 * @param psize Size of the converted text
 */
APU_DECLARE(void) apr_xml_to_text(apr_pool_t *p, const apr_xml_elem *elem,
                                  int style, apr_array_header_t *namespaces,
                                  int *ns_map, const char **pbuf,
                                  apr_size_t *psize);

/* style argument values: */
#define APR_XML_X2T_FULL         0	/**< start tag, contents, end tag */
#define APR_XML_X2T_INNER        1	/**< contents only */
#define APR_XML_X2T_LANG_INNER   2	/**< xml:lang + inner contents */
#define APR_XML_X2T_FULL_NS_LANG 3	/**< FULL + ns defns + xml:lang */
#define APR_XML_X2T_PARSED       4	/**< original prefixes */

/**
 * empty XML element
 * @param p The pool to allocate out of
 * @param elem The XML element to empty
 * @return the string that was stored in the XML element
 */
APU_DECLARE(const char *) apr_xml_empty_elem(apr_pool_t *p,
                                             const apr_xml_elem *elem);

/**
 * quote an XML string
 * Replace '\<', '\>', and '\&' with '\&lt;', '\&gt;', and '\&amp;'.
 * @param p The pool to allocate out of
 * @param s The string to quote
 * @param quotes If quotes is true, then replace '&quot;' with '\&quot;'.
 * @return The quoted string
 * @note If the string does not contain special characters, it is not
 * duplicated into the pool and the original string is returned.
 */
APU_DECLARE(const char *) apr_xml_quote_string(apr_pool_t *p, const char *s,
                                               int quotes);

/**
 * Quote an XML element
 * @param p The pool to allocate out of
 * @param elem The element to quote
 */
APU_DECLARE(void) apr_xml_quote_elem(apr_pool_t *p, apr_xml_elem *elem);

/* manage an array of unique URIs: apr_xml_insert_uri() and APR_XML_URI_ITEM() */

/**
 * return the URI's (existing) index, or insert it and return a new index 
 * @param uri_array array to insert into
 * @param uri The uri to insert
 * @return int The uri's index
 */
APU_DECLARE(int) apr_xml_insert_uri(apr_array_header_t *uri_array,
                                    const char *uri);

/** Get the URI item for this XML element */
#define APR_XML_GET_URI_ITEM(ary, i) (((const char * const *)(ary)->elts)[i])

#if APR_CHARSET_EBCDIC
/**
 * Convert parsed tree in EBCDIC 
 * @param p The pool to allocate out of
 * @param pdoc The apr_xml_doc to convert.
 * @param xlate The translation handle to use.
 * @return Any errors found during conversion.
 */
APU_DECLARE(apr_status_t) apr_xml_parser_convert_doc(apr_pool_t *p,
                                                     apr_xml_doc *pdoc,
                                                     apr_xlate_t *convset);
#endif

#ifdef __cplusplus
}
#endif
/** @} */
#endif /* APR_XML_H */
apr-1/apr_random.h000064400000011654151730340550007771 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_RANDOM_H
#define APR_RANDOM_H

/**
 * @file apr_random.h
 * @brief APR PRNG routines
 */

#include "apr_pools.h"
#include "apr_thread_proc.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @defgroup apr_random PRNG Routines
 * @ingroup APR
 * @{
 */

typedef struct apr_crypto_hash_t apr_crypto_hash_t;

typedef void apr_crypto_hash_init_t(apr_crypto_hash_t *hash);
typedef void apr_crypto_hash_add_t(apr_crypto_hash_t *hash, const void *data,
                                   apr_size_t bytes);
typedef void apr_crypto_hash_finish_t(apr_crypto_hash_t *hash,
                                      unsigned char *result);


/* FIXME: make this opaque */
struct apr_crypto_hash_t {
    apr_crypto_hash_init_t *init;
    apr_crypto_hash_add_t *add;
    apr_crypto_hash_finish_t *finish;
    apr_size_t size;
    void *data;
};

/**
 * Allocate and initialize the SHA-256 context
 * @param p The pool to allocate from
 */
APR_DECLARE(apr_crypto_hash_t *) apr_crypto_sha256_new(apr_pool_t *p);

/** Opaque PRNG structure. */
typedef struct apr_random_t apr_random_t;

/**
 * Initialize a PRNG state
 * @param g The PRNG state
 * @param p The pool to allocate from
 * @param pool_hash Pool hash functions
 * @param key_hash Key hash functions
 * @param prng_hash PRNG hash functions
 */
APR_DECLARE(void) apr_random_init(apr_random_t *g, apr_pool_t *p,
                                  apr_crypto_hash_t *pool_hash,
                                  apr_crypto_hash_t *key_hash,
                                  apr_crypto_hash_t *prng_hash);
/**
 * Allocate and initialize (apr_crypto_sha256_new) a new PRNG state.
 * @param p The pool to allocate from
 */
APR_DECLARE(apr_random_t *) apr_random_standard_new(apr_pool_t *p);

/**
 * Mix the randomness pools.
 * @param g The PRNG state
 * @param entropy_ Entropy buffer
 * @param bytes Length of entropy_ in bytes
 */
APR_DECLARE(void) apr_random_add_entropy(apr_random_t *g,
                                         const void *entropy_,
                                         apr_size_t bytes);
/**
 * Generate cryptographically insecure random bytes.
 * @param g The RNG state
 * @param random Buffer to fill with random bytes
 * @param bytes Length of buffer in bytes
 */
APR_DECLARE(apr_status_t) apr_random_insecure_bytes(apr_random_t *g,
                                                    void *random,
                                                    apr_size_t bytes);

/**
 * Generate cryptographically secure random bytes.
 * @param g The RNG state
 * @param random Buffer to fill with random bytes
 * @param bytes Length of buffer in bytes
 */
APR_DECLARE(apr_status_t) apr_random_secure_bytes(apr_random_t *g,
                                                  void *random,
                                                  apr_size_t bytes);
/**
 * Ensures that E bits of conditional entropy are mixed into the PRNG
 * before any further randomness is extracted.
 * @param g The RNG state
 */
APR_DECLARE(void) apr_random_barrier(apr_random_t *g);

/**
 * Return APR_SUCCESS if the cryptographic PRNG has been seeded with
 * enough data, APR_ENOTENOUGHENTROPY otherwise.
 * @param r The RNG state
 */
APR_DECLARE(apr_status_t) apr_random_secure_ready(apr_random_t *r);

/**
 * Return APR_SUCCESS if the PRNG has been seeded with enough data,
 * APR_ENOTENOUGHENTROPY otherwise.
 * @param r The PRNG state
 */
APR_DECLARE(apr_status_t) apr_random_insecure_ready(apr_random_t *r);

/**
 * Mix the randomness pools after forking.
 * @param proc The resulting process handle from apr_proc_fork()
 * @remark Call this in the child after forking to mix the randomness
 * pools. Note that its generally a bad idea to fork a process with a
 * real PRNG in it - better to have the PRNG externally and get the
 * randomness from there. However, if you really must do it, then you
 * should supply all your entropy to all the PRNGs - don't worry, they
 * won't produce the same output.
 * @remark Note that apr_proc_fork() calls this for you, so only weird
 * applications need ever call it themselves.
 * @internal
 */
APR_DECLARE(void) apr_random_after_fork(apr_proc_t *proc);

/** @} */

#ifdef __cplusplus
}
#endif

#endif /* !APR_RANDOM_H */
apr-1/apr_thread_cond.h000064400000012625151730340550010762 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_THREAD_COND_H
#define APR_THREAD_COND_H

/**
 * @file apr_thread_cond.h
 * @brief APR Condition Variable Routines
 */

#include "apr.h"
#include "apr_pools.h"
#include "apr_errno.h"
#include "apr_time.h"
#include "apr_thread_mutex.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

#if APR_HAS_THREADS || defined(DOXYGEN)

/**
 * @defgroup apr_thread_cond Condition Variable Routines
 * @ingroup APR 
 * @{
 */

/** Opaque structure for thread condition variables */
typedef struct apr_thread_cond_t apr_thread_cond_t;

/**
 * Note: destroying a condition variable (or likewise, destroying or
 * clearing the pool from which a condition variable was allocated) if
 * any threads are blocked waiting on it gives undefined results.
 */

/**
 * Create and initialize a condition variable that can be used to signal
 * and schedule threads in a single process.
 * @param cond the memory address where the newly created condition variable
 *        will be stored.
 * @param pool the pool from which to allocate the condition.
 */
APR_DECLARE(apr_status_t) apr_thread_cond_create(apr_thread_cond_t **cond,
                                                 apr_pool_t *pool);

/**
 * Put the active calling thread to sleep until signaled to wake up. Each
 * condition variable must be associated with a mutex, and that mutex must
 * be locked before  calling this function, or the behavior will be
 * undefined. As the calling thread is put to sleep, the given mutex
 * will be simultaneously released; and as this thread wakes up the lock
 * is again simultaneously acquired.
 * @param cond the condition variable on which to block.
 * @param mutex the mutex that must be locked upon entering this function,
 *        is released while the thread is asleep, and is again acquired before
 *        returning from this function.
 * @remark Spurious wakeups may occur. Before and after every call to wait on
 * a condition variable, the caller should test whether the condition is already
 * met.
 */
APR_DECLARE(apr_status_t) apr_thread_cond_wait(apr_thread_cond_t *cond,
                                               apr_thread_mutex_t *mutex);

/**
 * Put the active calling thread to sleep until signaled to wake up or
 * the timeout is reached. Each condition variable must be associated
 * with a mutex, and that mutex must be locked before calling this
 * function, or the behavior will be undefined. As the calling thread
 * is put to sleep, the given mutex will be simultaneously released;
 * and as this thread wakes up the lock is again simultaneously acquired.
 * @param cond the condition variable on which to block.
 * @param mutex the mutex that must be locked upon entering this function,
 *        is released while the thread is asleep, and is again acquired before
 *        returning from this function.
 * @param timeout The amount of time in microseconds to wait. This is 
 *        a maximum, not a minimum. If the condition is signaled, we 
 *        will wake up before this time, otherwise the error APR_TIMEUP
 *        is returned.
 */
APR_DECLARE(apr_status_t) apr_thread_cond_timedwait(apr_thread_cond_t *cond,
                                                    apr_thread_mutex_t *mutex,
                                                    apr_interval_time_t timeout);

/**
 * Signals a single thread, if one exists, that is blocking on the given
 * condition variable. That thread is then scheduled to wake up and acquire
 * the associated mutex. Although it is not required, if predictable scheduling
 * is desired, that mutex must be locked while calling this function.
 * @param cond the condition variable on which to produce the signal.
 * @remark If no threads are waiting on the condition variable, nothing happens.
 */
APR_DECLARE(apr_status_t) apr_thread_cond_signal(apr_thread_cond_t *cond);

/**
 * Signals all threads blocking on the given condition variable.
 * Each thread that was signaled is then scheduled to wake up and acquire
 * the associated mutex. This will happen in a serialized manner.
 * @param cond the condition variable on which to produce the broadcast.
 * @remark If no threads are waiting on the condition variable, nothing happens.
 */
APR_DECLARE(apr_status_t) apr_thread_cond_broadcast(apr_thread_cond_t *cond);

/**
 * Destroy the condition variable and free the associated memory.
 * @param cond the condition variable to destroy.
 */
APR_DECLARE(apr_status_t) apr_thread_cond_destroy(apr_thread_cond_t *cond);

/**
 * Get the pool used by this thread_cond.
 * @return apr_pool_t the pool
 */
APR_POOL_DECLARE_ACCESSOR(thread_cond);

#endif /* APR_HAS_THREADS */

/** @} */

#ifdef __cplusplus
}
#endif

#endif  /* ! APR_THREAD_COND_H */
apr-1/apr_dbm.h000064400000020627151730340550007253 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_DBM_H
#define APR_DBM_H

#include "apu.h"
#include "apr.h"
#include "apr_errno.h"
#include "apr_pools.h"
#include "apr_file_info.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @file apr_dbm.h
 * @brief APR-UTIL DBM library
 */
/** 
 * @defgroup APR_Util_DBM DBM routines
 * @ingroup APR_Util
 * @{
 */
/**
 * Structure for referencing a dbm
 */
typedef struct apr_dbm_t apr_dbm_t;

/**
 * Structure for referencing the datum record within a dbm
 */
typedef struct
{
    /** pointer to the 'data' to retrieve/store in the DBM */
    char *dptr;
    /** size of the 'data' to retrieve/store in the DBM */
    apr_size_t dsize;
} apr_datum_t;

/* modes to open the DB */
#define APR_DBM_READONLY        1       /**< open for read-only access */
#define APR_DBM_READWRITE       2       /**< open for read-write access */
#define APR_DBM_RWCREATE        3       /**< open for r/w, create if needed */
#define APR_DBM_RWTRUNC         4       /**< open for r/w, truncating an existing
                                          DB if present */
/**
 * Open a dbm file by file name and type of DBM
 * @param dbm The newly opened database
 * @param type The type of the DBM (not all may be available at run time)
 * <pre>
 *  db   for Berkeley DB files
 *  gdbm for GDBM files
 *  ndbm for NDBM files
 *  sdbm for SDBM files (always available)
 *  default for the default DBM type
 *  </pre>
 * @param name The dbm file name to open
 * @param mode The flag value
 * <PRE>
 *           APR_DBM_READONLY   open for read-only access
 *           APR_DBM_READWRITE  open for read-write access
 *           APR_DBM_RWCREATE   open for r/w, create if needed
 *           APR_DBM_RWTRUNC    open for r/w, truncate if already there
 * </PRE>
 * @param perm Permissions to apply to if created
 * @param cntxt The pool to use when creating the dbm
 * @remark The dbm name may not be a true file name, as many dbm packages
 * append suffixes for seperate data and index files.
 * @bug In apr-util 0.9 and 1.x, the type arg was case insensitive.  This
 * was highly inefficient, and as of 2.x the dbm name must be provided in
 * the correct case (lower case for all bundled providers)
 */

APU_DECLARE(apr_status_t) apr_dbm_open_ex(apr_dbm_t **dbm, const char* type, 
                                       const char *name, 
                                       apr_int32_t mode, apr_fileperms_t perm,
                                       apr_pool_t *cntxt);


/**
 * Open a dbm file by file name
 * @param dbm The newly opened database
 * @param name The dbm file name to open
 * @param mode The flag value
 * <PRE>
 *           APR_DBM_READONLY   open for read-only access
 *           APR_DBM_READWRITE  open for read-write access
 *           APR_DBM_RWCREATE   open for r/w, create if needed
 *           APR_DBM_RWTRUNC    open for r/w, truncate if already there
 * </PRE>
 * @param perm Permissions to apply to if created
 * @param cntxt The pool to use when creating the dbm
 * @remark The dbm name may not be a true file name, as many dbm packages
 * append suffixes for seperate data and index files.
 */
APU_DECLARE(apr_status_t) apr_dbm_open(apr_dbm_t **dbm, const char *name, 
                                       apr_int32_t mode, apr_fileperms_t perm,
                                       apr_pool_t *cntxt);

/**
 * Close a dbm file previously opened by apr_dbm_open
 * @param dbm The database to close
 */
APU_DECLARE(void) apr_dbm_close(apr_dbm_t *dbm);

/**
 * Fetch a dbm record value by key
 * @param dbm The database 
 * @param key The key datum to find this record
 * @param pvalue The value datum retrieved for this record
 */
APU_DECLARE(apr_status_t) apr_dbm_fetch(apr_dbm_t *dbm, apr_datum_t key,
                                        apr_datum_t *pvalue);
/**
 * Store a dbm record value by key
 * @param dbm The database 
 * @param key The key datum to store this record by
 * @param value The value datum to store in this record
 */
APU_DECLARE(apr_status_t) apr_dbm_store(apr_dbm_t *dbm, apr_datum_t key, 
                                        apr_datum_t value);

/**
 * Delete a dbm record value by key
 * @param dbm The database 
 * @param key The key datum of the record to delete
 * @remark It is not an error to delete a non-existent record.
 */
APU_DECLARE(apr_status_t) apr_dbm_delete(apr_dbm_t *dbm, apr_datum_t key);

/**
 * Search for a key within the dbm
 * @param dbm The database 
 * @param key The datum describing a key to test
 */
APU_DECLARE(int) apr_dbm_exists(apr_dbm_t *dbm, apr_datum_t key);

/**
 * Retrieve the first record key from a dbm
 * @param dbm The database 
 * @param pkey The key datum of the first record
 */
APU_DECLARE(apr_status_t) apr_dbm_firstkey(apr_dbm_t *dbm, apr_datum_t *pkey);

/**
 * Retrieve the next record key from a dbm
 * @param dbm The database 
 * @param pkey The key datum of the next record
 */
APU_DECLARE(apr_status_t) apr_dbm_nextkey(apr_dbm_t *dbm, apr_datum_t *pkey);

/**
 * Proactively toss any memory associated with the apr_datum_t.
 * @param dbm The database 
 * @param data The datum to free.
 */
APU_DECLARE(void) apr_dbm_freedatum(apr_dbm_t *dbm, apr_datum_t data);

/**
 * Report more information when an apr_dbm function fails.
 * @param dbm The database
 * @param errcode A DBM-specific value for the error (for logging). If this
 *                isn't needed, it may be NULL.
 * @param errbuf Location to store the error text
 * @param errbufsize The size of the provided buffer
 * @return The errbuf parameter, for convenience.
 */
APU_DECLARE(char *) apr_dbm_geterror(apr_dbm_t *dbm, int *errcode,
                                     char *errbuf, apr_size_t errbufsize);
/**
 * If the specified file/path were passed to apr_dbm_open(), return the
 * actual file/path names which would be (created and) used. At most, two
 * files may be used; used2 may be NULL if only one file is used.
 * @param pool The pool for allocating used1 and used2.
 * @param type The type of DBM you require info on @see apr_dbm_open_ex
 * @param pathname The path name to generate used-names from.
 * @param used1 The first pathname used by the apr_dbm implementation.
 * @param used2 The second pathname used by apr_dbm. If only one file is
 *              used by the specific implementation, this will be set to NULL.
 * @return An error if the specified type is invalid.
 * @remark The dbm file(s) don't need to exist. This function only manipulates
 *      the pathnames.
 */
APU_DECLARE(apr_status_t) apr_dbm_get_usednames_ex(apr_pool_t *pool,
                                                   const char *type,
                                                   const char *pathname,
                                                   const char **used1,
                                                   const char **used2);

/**
 * If the specified file/path were passed to apr_dbm_open(), return the
 * actual file/path names which would be (created and) used. At most, two
 * files may be used; used2 may be NULL if only one file is used.
 * @param pool The pool for allocating used1 and used2.
 * @param pathname The path name to generate used-names from.
 * @param used1 The first pathname used by the apr_dbm implementation.
 * @param used2 The second pathname used by apr_dbm. If only one file is
 *              used by the specific implementation, this will be set to NULL.
 * @remark The dbm file(s) don't need to exist. This function only manipulates
 *      the pathnames.
 */
APU_DECLARE(void) apr_dbm_get_usednames(apr_pool_t *pool,
                                        const char *pathname,
                                        const char **used1,
                                        const char **used2);

/** @} */
#ifdef __cplusplus
}
#endif

#endif	/* !APR_DBM_H */
apr-1/apr_md5.h000064400000014316151730340550007174 0ustar00/*
 * This is work is derived from material Copyright RSA Data Security, Inc.
 *
 * The RSA copyright statement and Licence for that original material is
 * included below. This is followed by the Apache copyright statement and
 * licence for the modifications made to that material.
 */

/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
   rights reserved.

   License to copy and use this software is granted provided that it
   is identified as the "RSA Data Security, Inc. MD5 Message-Digest
   Algorithm" in all material mentioning or referencing this software
   or this function.

   License is also granted to make and use derivative works provided
   that such works are identified as "derived from the RSA Data
   Security, Inc. MD5 Message-Digest Algorithm" in all material
   mentioning or referencing the derived work.

   RSA Data Security, Inc. makes no representations concerning either
   the merchantability of this software or the suitability of this
   software for any particular purpose. It is provided "as is"
   without express or implied warranty of any kind.

   These notices must be retained in any copies of any part of this
   documentation and/or software.
 */

/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_MD5_H
#define APR_MD5_H

#include "apu.h"
#include "apr_xlate.h"

#ifdef __cplusplus
extern "C" {
#endif
/**
 * @file apr_md5.h
 * @brief APR MD5 Routines
 */

/**
 * @defgroup APR_MD5 MD5 Routines
 * @ingroup APR
 * @{
 */

/** The MD5 digest size */
#define APR_MD5_DIGESTSIZE 16

/** @see apr_md5_ctx_t */
typedef struct apr_md5_ctx_t apr_md5_ctx_t;

/** MD5 context. */
struct apr_md5_ctx_t {
    /** state (ABCD) */
    apr_uint32_t state[4];
    /** number of bits, modulo 2^64 (lsb first) */
    apr_uint32_t count[2];
    /** input buffer */
    unsigned char buffer[64];
    /** translation handle 
     *  ignored if xlate is unsupported
     */
    apr_xlate_t *xlate;
};

/**
 * MD5 Initialize.  Begins an MD5 operation, writing a new context.
 * @param context The MD5 context to initialize.
 */
APU_DECLARE(apr_status_t) apr_md5_init(apr_md5_ctx_t *context);

/**
 * MD5 translation setup.  Provides the APR translation handle to be used 
 * for translating the content before calculating the digest.
 * @param context The MD5 content to set the translation for.
 * @param xlate The translation handle to use for this MD5 context 
 */
APU_DECLARE(apr_status_t) apr_md5_set_xlate(apr_md5_ctx_t *context,
                                            apr_xlate_t *xlate);

/**
 * MD5 block update operation.  Continue an MD5 message-digest operation, 
 * processing another message block, and updating the context.
 * @param context The MD5 content to update.
 * @param input next message block to update
 * @param inputLen The length of the next message block
 */
APU_DECLARE(apr_status_t) apr_md5_update(apr_md5_ctx_t *context,
                                         const void *input,
                                         apr_size_t inputLen);

/**
 * MD5 finalization.  Ends an MD5 message-digest operation, writing the 
 * message digest and zeroing the context
 * @param digest The final MD5 digest
 * @param context The MD5 content we are finalizing.
 */
APU_DECLARE(apr_status_t) apr_md5_final(unsigned char digest[APR_MD5_DIGESTSIZE],
                                        apr_md5_ctx_t *context);

/**
 * MD5 in one step
 * @param digest The final MD5 digest
 * @param input The message block to use
 * @param inputLen The length of the message block
 */
APU_DECLARE(apr_status_t) apr_md5(unsigned char digest[APR_MD5_DIGESTSIZE],
                                  const void *input,
                                  apr_size_t inputLen);

/**
 * Encode a password using an MD5 algorithm
 * @param password The password to encode
 * @param salt The salt string to use for the encoding
 * @param result The string to store the encoded password in
 * @param nbytes The size of the result buffer
 */
APU_DECLARE(apr_status_t) apr_md5_encode(const char *password, const char *salt,
                                         char *result, apr_size_t nbytes);

/**
 * Encode a password using the bcrypt algorithm
 * @param password The password to encode
 * @param count The cost of the encoding, possible values are 4 to 31
 * @param salt Pointer to binary data to be used as salt for the encoding
 * @param salt_len The size of the salt data (must be >= 16)
 * @param out The string to store the encoded password in
 * @param out_len The size of the result buffer (must be >= 61)
 */
APU_DECLARE(apr_status_t) apr_bcrypt_encode(const char *pw,
                                            unsigned int count,
                                            const unsigned char *salt,
                                            apr_size_t salt_len,
                                            char *out, apr_size_t out_len);

/**
 * Validate hashes created by APR-supported algorithms: md5, bcrypt, and sha1.
 * hashes created by crypt are supported only on platforms that provide
 * crypt(3), so don't rely on that function unless you know that your
 * application will be run only on platforms that support it.  On platforms
 * that don't support crypt(3), this falls back to a clear text string
 * comparison.
 * @param passwd The password to validate
 * @param hash The password to validate against
 */
APU_DECLARE(apr_status_t) apr_password_validate(const char *passwd, 
                                                const char *hash);


/** @} */
#ifdef __cplusplus
}
#endif

#endif /* !APR_MD5_H */
apr-1/apr_thread_mutex.h000064400000010622151730340550011174 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_THREAD_MUTEX_H
#define APR_THREAD_MUTEX_H

/**
 * @file apr_thread_mutex.h
 * @brief APR Thread Mutex Routines
 */

#include "apr.h"
#include "apr_errno.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

#if APR_HAS_THREADS || defined(DOXYGEN)

/**
 * @defgroup apr_thread_mutex Thread Mutex Routines
 * @ingroup APR 
 * @{
 */

/** Opaque thread-local mutex structure */
typedef struct apr_thread_mutex_t apr_thread_mutex_t;

#define APR_THREAD_MUTEX_DEFAULT  0x0   /**< platform-optimal lock behavior */
#define APR_THREAD_MUTEX_NESTED   0x1   /**< enable nested (recursive) locks */
#define APR_THREAD_MUTEX_UNNESTED 0x2   /**< disable nested locks */
#define APR_THREAD_MUTEX_TIMED    0x4   /**< enable timed locks */

/* Delayed the include to avoid a circular reference */
#include "apr_pools.h"
#include "apr_time.h"

/**
 * Create and initialize a mutex that can be used to synchronize threads.
 * @param mutex the memory address where the newly created mutex will be
 *        stored.
 * @param flags Or'ed value of:
 * <PRE>
 *           APR_THREAD_MUTEX_DEFAULT   platform-optimal lock behavior.
 *           APR_THREAD_MUTEX_NESTED    enable nested (recursive) locks.
 *           APR_THREAD_MUTEX_UNNESTED  disable nested locks (non-recursive).
 * </PRE>
 * @param pool the pool from which to allocate the mutex.
 * @warning Be cautious in using APR_THREAD_MUTEX_DEFAULT.  While this is the
 * most optimal mutex based on a given platform's performance characteristics,
 * it will behave as either a nested or an unnested lock.
 */
APR_DECLARE(apr_status_t) apr_thread_mutex_create(apr_thread_mutex_t **mutex,
                                                  unsigned int flags,
                                                  apr_pool_t *pool);
/**
 * Acquire the lock for the given mutex. If the mutex is already locked,
 * the current thread will be put to sleep until the lock becomes available.
 * @param mutex the mutex on which to acquire the lock.
 */
APR_DECLARE(apr_status_t) apr_thread_mutex_lock(apr_thread_mutex_t *mutex);

/**
 * Attempt to acquire the lock for the given mutex. If the mutex has already
 * been acquired, the call returns immediately with APR_EBUSY. Note: it
 * is important that the APR_STATUS_IS_EBUSY(s) macro be used to determine
 * if the return value was APR_EBUSY, for portability reasons.
 * @param mutex the mutex on which to attempt the lock acquiring.
 */
APR_DECLARE(apr_status_t) apr_thread_mutex_trylock(apr_thread_mutex_t *mutex);

/**
 * Attempt to acquire the lock for the given mutex until timeout expires.
 * If the acquisition time outs, the call returns with APR_TIMEUP.
 * @param mutex the mutex on which to attempt the lock acquiring.
 * @param timeout the relative timeout (microseconds).
 * @note A timeout negative or nul means immediate attempt, returning
 *       APR_TIMEUP without blocking if it the lock is already acquired.
 */
APR_DECLARE(apr_status_t) apr_thread_mutex_timedlock(apr_thread_mutex_t *mutex,
                                                 apr_interval_time_t timeout);

/**
 * Release the lock for the given mutex.
 * @param mutex the mutex from which to release the lock.
 */
APR_DECLARE(apr_status_t) apr_thread_mutex_unlock(apr_thread_mutex_t *mutex);

/**
 * Destroy the mutex and free the memory associated with the lock.
 * @param mutex the mutex to destroy.
 */
APR_DECLARE(apr_status_t) apr_thread_mutex_destroy(apr_thread_mutex_t *mutex);

/**
 * Get the pool used by this thread_mutex.
 * @return apr_pool_t the pool
 */
APR_POOL_DECLARE_ACCESSOR(thread_mutex);

#endif /* APR_HAS_THREADS */

/** @} */

#ifdef __cplusplus
}
#endif

#endif  /* ! APR_THREAD_MUTEX_H */
apr-1/apr_base64.h000064400000007404151730340550007573 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * The apr_vsnprintf/apr_snprintf functions are based on, and used with the
 * permission of, the  SIO stdio-replacement strx_* functions by Panos
 * Tsirigotis <panos@alumni.cs.colorado.edu> for xinetd.
 */

/**
 * @file apr_base64.h
 * @brief APR-UTIL Base64 Encoding
 */
#ifndef APR_BASE64_H
#define APR_BASE64_H

#include "apu.h"
#include "apr_general.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @defgroup APR_Util_Base64 Base64 Encoding
 * @ingroup APR_Util
 * @{
 */

/* Simple BASE64 encode/decode functions.
 * 
 * As we might encode binary strings, hence we require the length of
 * the incoming plain source. And return the length of what we decoded.
 *
 * The decoding function takes any non valid char (i.e. whitespace, \0
 * or anything non A-Z,0-9 etc as terminal.
 * 
 * plain strings/binary sequences are not assumed '\0' terminated. Encoded
 * strings are neither. But probably should.
 *
 */

/**
 * Given the length of an un-encoded string, get the length of the
 * encoded string.
 * @param len the length of an unencoded string.
 * @return the length of the string after it is encoded, including the
 * trailing \0
 */ 
APU_DECLARE(int) apr_base64_encode_len(int len);

/**
 * Encode a text string using base64encoding.
 * @param coded_dst The destination string for the encoded string.
 * @param plain_src The original string in plain text
 * @param len_plain_src The length of the plain text string
 * @return the length of the encoded string
 */ 
APU_DECLARE(int) apr_base64_encode(char * coded_dst, const char *plain_src, 
                                 int len_plain_src);

/**
 * Encode an EBCDIC string using base64encoding.
 * @param coded_dst The destination string for the encoded string.
 * @param plain_src The original string in plain text
 * @param len_plain_src The length of the plain text string
 * @return the length of the encoded string
 */ 
APU_DECLARE(int) apr_base64_encode_binary(char * coded_dst, 
                                        const unsigned char *plain_src,
                                        int len_plain_src);

/**
 * Determine the maximum buffer length required to decode the plain text
 * string given the encoded string.
 * @param coded_src The encoded string
 * @return the maximum required buffer length for the plain text string
 */ 
APU_DECLARE(int) apr_base64_decode_len(const char * coded_src);

/**
 * Decode a string to plain text
 * @param plain_dst The destination string for the plain text
 * @param coded_src The encoded string 
 * @return the length of the plain text string
 */ 
APU_DECLARE(int) apr_base64_decode(char * plain_dst, const char *coded_src);

/**
 * Decode an EBCDIC string to plain text
 * @param plain_dst The destination string for the plain text
 * @param coded_src The encoded string 
 * @return the length of the plain text string
 */ 
APU_DECLARE(int) apr_base64_decode_binary(unsigned char * plain_dst, 
                                        const char *coded_src);

/** @} */
#ifdef __cplusplus
}
#endif

#endif	/* !APR_BASE64_H */
apr-1/apr_inherit.h000064400000004133151730340550010145 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_INHERIT_H
#define APR_INHERIT_H

/**
 * @file apr_inherit.h 
 * @brief APR File Handle Inheritance Helpers
 * @remark This internal header includes internal declaration helpers 
 * for other headers to declare apr_foo_inherit_[un]set functions.
 */

/**
 * Prototype for type-specific declarations of apr_foo_inherit_set 
 * functions.  
 * @remark Doxygen unwraps this macro (via doxygen.conf) to provide 
 * actual help for each specific occurrence of apr_foo_inherit_set.
 * @remark the linkage is specified for APR. It would be possible to expand
 *       the macros to support other linkages.
 */
#define APR_DECLARE_INHERIT_SET(type) \
    APR_DECLARE(apr_status_t) apr_##type##_inherit_set( \
                                          apr_##type##_t *the##type)

/**
 * Prototype for type-specific declarations of apr_foo_inherit_unset 
 * functions.  
 * @remark Doxygen unwraps this macro (via doxygen.conf) to provide 
 * actual help for each specific occurrence of apr_foo_inherit_unset.
 * @remark the linkage is specified for APR. It would be possible to expand
 *       the macros to support other linkages.
 */
#define APR_DECLARE_INHERIT_UNSET(type) \
    APR_DECLARE(apr_status_t) apr_##type##_inherit_unset( \
                                          apr_##type##_t *the##type)

#endif	/* ! APR_INHERIT_H */
apr-1/apr_perms_set.h000064400000003565151730340560010515 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_PERMS_SET_H
#define APR_PERMS_SET_H

/**
 * @file apr_perms_set.h
 * @brief APR Process Locking Routines
 */

#include "apr.h"
#include "apr_pools.h"
#include "apr_errno.h"
#include "apr_user.h"
#include "apr_file_info.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @defgroup apr_perms_set Object permission set functions
 * @ingroup APR 
 * @{
 */

/** Permission set callback function. */
typedef apr_status_t (apr_perms_setfn_t)(void *object, apr_fileperms_t perms,
                                         apr_uid_t uid, apr_gid_t gid);

#define APR_PERMS_SET_IMPLEMENT(type) \
    APR_DECLARE(apr_status_t) apr_##type##_perms_set \
        (void *the##type, apr_fileperms_t perms, \
         apr_uid_t uid, apr_gid_t gid)

#define APR_PERMS_SET_ENOTIMPL(type) \
    APR_DECLARE(apr_status_t) apr_##type##_perms_set \
        (void *the##type, apr_fileperms_t perms, \
         apr_uid_t uid, apr_gid_t gid) \
        { return APR_ENOTIMPL ; }

#define APR_PERMS_SET_FN(type) apr_##type##_perms_set


/** @} */

#ifdef __cplusplus
}
#endif

#endif  /* ! APR_PERMS_SET */
apr-1/apr.h000064400000001174151730340560006426 0ustar00/* This file is here to prevent a file conflict on multiarch systems.  A
 * conflict will occur because apr.h has arch-specific definitions.
 *
 * DO NOT INCLUDE THE NEW FILE DIRECTLY -- ALWAYS INCLUDE THIS ONE INSTEAD. */

#if defined(__i386__)
#include "apr-i386.h"
#elif defined(__ia64__)
#include "apr-ia64.h"
#elif defined(__powerpc64__)
#include "apr-ppc64.h"
#elif defined(__powerpc__)
#include "apr-ppc.h"
#elif defined(__s390x__)
#include "apr-s390x.h"
#elif defined(__s390__)
#include "apr-s390.h"
#elif defined(__x86_64__)
#include "apr-x86_64.h"
#else
#error "This apr-devel package does not work your architecture?"
#endif
apr-1/apr_file_info.h000064400000042260151730340560010441 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_FILE_INFO_H
#define APR_FILE_INFO_H

/**
 * @file apr_file_info.h
 * @brief APR File Information
 */

#include "apr.h"
#include "apr_user.h"
#include "apr_pools.h"
#include "apr_tables.h"
#include "apr_time.h"
#include "apr_errno.h"

#if APR_HAVE_SYS_UIO_H
#include <sys/uio.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @defgroup apr_file_info File Information
 * @ingroup APR 
 * @{
 */

/* Many applications use the type member to determine the
 * existance of a file or initialization of the file info,
 * so the APR_NOFILE value must be distinct from APR_UNKFILE.
 */

/** apr_filetype_e values for the filetype member of the 
 * apr_file_info_t structure
 * @warning Not all of the filetypes below can be determined.
 * For example, a given platform might not correctly report 
 * a socket descriptor as APR_SOCK if that type isn't 
 * well-identified on that platform.  In such cases where
 * a filetype exists but cannot be described by the recognized
 * flags below, the filetype will be APR_UNKFILE.  If the
 * filetype member is not determined, the type will be APR_NOFILE.
 */

typedef enum {
    APR_NOFILE = 0,     /**< no file type determined */
    APR_REG,            /**< a regular file */
    APR_DIR,            /**< a directory */
    APR_CHR,            /**< a character device */
    APR_BLK,            /**< a block device */
    APR_PIPE,           /**< a FIFO / pipe */
    APR_LNK,            /**< a symbolic link */
    APR_SOCK,           /**< a [unix domain] socket */
    APR_UNKFILE = 127   /**< a file of some other unknown type */
} apr_filetype_e; 

/**
 * @defgroup apr_file_permissions File Permissions flags 
 * @{
 */

#define APR_FPROT_USETID      0x8000 /**< Set user id */
#define APR_FPROT_UREAD       0x0400 /**< Read by user */
#define APR_FPROT_UWRITE      0x0200 /**< Write by user */
#define APR_FPROT_UEXECUTE    0x0100 /**< Execute by user */

#define APR_FPROT_GSETID      0x4000 /**< Set group id */
#define APR_FPROT_GREAD       0x0040 /**< Read by group */
#define APR_FPROT_GWRITE      0x0020 /**< Write by group */
#define APR_FPROT_GEXECUTE    0x0010 /**< Execute by group */

#define APR_FPROT_WSTICKY     0x2000 /**< Sticky bit */
#define APR_FPROT_WREAD       0x0004 /**< Read by others */
#define APR_FPROT_WWRITE      0x0002 /**< Write by others */
#define APR_FPROT_WEXECUTE    0x0001 /**< Execute by others */

#define APR_FPROT_OS_DEFAULT  0x0FFF /**< use OS's default permissions */

/* additional permission flags for apr_file_copy  and apr_file_append */
#define APR_FPROT_FILE_SOURCE_PERMS 0x1000 /**< Copy source file's permissions */
    
/* backcompat */
#define APR_USETID     APR_FPROT_USETID     /**< @deprecated @see APR_FPROT_USETID     */
#define APR_UREAD      APR_FPROT_UREAD      /**< @deprecated @see APR_FPROT_UREAD      */
#define APR_UWRITE     APR_FPROT_UWRITE     /**< @deprecated @see APR_FPROT_UWRITE     */
#define APR_UEXECUTE   APR_FPROT_UEXECUTE   /**< @deprecated @see APR_FPROT_UEXECUTE   */
#define APR_GSETID     APR_FPROT_GSETID     /**< @deprecated @see APR_FPROT_GSETID     */
#define APR_GREAD      APR_FPROT_GREAD      /**< @deprecated @see APR_FPROT_GREAD      */
#define APR_GWRITE     APR_FPROT_GWRITE     /**< @deprecated @see APR_FPROT_GWRITE     */
#define APR_GEXECUTE   APR_FPROT_GEXECUTE   /**< @deprecated @see APR_FPROT_GEXECUTE   */
#define APR_WSTICKY    APR_FPROT_WSTICKY    /**< @deprecated @see APR_FPROT_WSTICKY    */
#define APR_WREAD      APR_FPROT_WREAD      /**< @deprecated @see APR_FPROT_WREAD      */
#define APR_WWRITE     APR_FPROT_WWRITE     /**< @deprecated @see APR_FPROT_WWRITE     */
#define APR_WEXECUTE   APR_FPROT_WEXECUTE   /**< @deprecated @see APR_FPROT_WEXECUTE   */
#define APR_OS_DEFAULT APR_FPROT_OS_DEFAULT /**< @deprecated @see APR_FPROT_OS_DEFAULT */
#define APR_FILE_SOURCE_PERMS APR_FPROT_FILE_SOURCE_PERMS /**< @deprecated @see APR_FPROT_FILE_SOURCE_PERMS */
    
/** @} */


/**
 * Structure for referencing directories.
 */
typedef struct apr_dir_t          apr_dir_t;
/**
 * Structure for determining file permissions.
 */
typedef apr_int32_t               apr_fileperms_t;
#if (defined WIN32) || (defined NETWARE)
/**
 * Structure for determining the device the file is on.
 */
typedef apr_uint32_t              apr_dev_t;
#else
/**
 * Structure for determining the device the file is on.
 */
typedef dev_t                     apr_dev_t;
#endif

/**
 * @defgroup apr_file_stat Stat Functions
 * @{
 */
/** file info structure */
typedef struct apr_finfo_t        apr_finfo_t;

#define APR_FINFO_LINK   0x00000001 /**< Stat the link not the file itself if it is a link */
#define APR_FINFO_MTIME  0x00000010 /**< Modification Time */
#define APR_FINFO_CTIME  0x00000020 /**< Creation or inode-changed time */
#define APR_FINFO_ATIME  0x00000040 /**< Access Time */
#define APR_FINFO_SIZE   0x00000100 /**< Size of the file */
#define APR_FINFO_CSIZE  0x00000200 /**< Storage size consumed by the file */
#define APR_FINFO_DEV    0x00001000 /**< Device */
#define APR_FINFO_INODE  0x00002000 /**< Inode */
#define APR_FINFO_NLINK  0x00004000 /**< Number of links */
#define APR_FINFO_TYPE   0x00008000 /**< Type */
#define APR_FINFO_USER   0x00010000 /**< User */
#define APR_FINFO_GROUP  0x00020000 /**< Group */
#define APR_FINFO_UPROT  0x00100000 /**< User protection bits */
#define APR_FINFO_GPROT  0x00200000 /**< Group protection bits */
#define APR_FINFO_WPROT  0x00400000 /**< World protection bits */
#define APR_FINFO_ICASE  0x01000000 /**< if dev is case insensitive */
#define APR_FINFO_NAME   0x02000000 /**< ->name in proper case */

#define APR_FINFO_MIN    0x00008170 /**< type, mtime, ctime, atime, size */
#define APR_FINFO_IDENT  0x00003000 /**< dev and inode */
#define APR_FINFO_OWNER  0x00030000 /**< user and group */
#define APR_FINFO_PROT   0x00700000 /**<  all protections */
#define APR_FINFO_NORM   0x0073b170 /**<  an atomic unix apr_stat() */
#define APR_FINFO_DIRENT 0x02000000 /**<  an atomic unix apr_dir_read() */

/**
 * The file information structure.  This is analogous to the POSIX
 * stat structure.
 */
struct apr_finfo_t {
    /** Allocates memory and closes lingering handles in the specified pool */
    apr_pool_t *pool;
    /** The bitmask describing valid fields of this apr_finfo_t structure 
     *  including all available 'wanted' fields and potentially more */
    apr_int32_t valid;
    /** The access permissions of the file.  Mimics Unix access rights. */
    apr_fileperms_t protection;
    /** The type of file.  One of APR_REG, APR_DIR, APR_CHR, APR_BLK, APR_PIPE, 
     * APR_LNK or APR_SOCK.  If the type is undetermined, the value is APR_NOFILE.
     * If the type cannot be determined, the value is APR_UNKFILE.
     */
    apr_filetype_e filetype;
    /** The user id that owns the file */
    apr_uid_t user;
    /** The group id that owns the file */
    apr_gid_t group;
    /** The inode of the file. */
    apr_ino_t inode;
    /** The id of the device the file is on. */
    apr_dev_t device;
    /** The number of hard links to the file. */
    apr_int32_t nlink;
    /** The size of the file */
    apr_off_t size;
    /** The storage size consumed by the file */
    apr_off_t csize;
    /** The time the file was last accessed */
    apr_time_t atime;
    /** The time the file was last modified */
    apr_time_t mtime;
    /** The time the file was created, or the inode was last changed */
    apr_time_t ctime;
    /** The pathname of the file (possibly unrooted) */
    const char *fname;
    /** The file's name (no path) in filesystem case */
    const char *name;
    /** Unused */
    struct apr_file_t *filehand;
};

/**
 * get the specified file's stats.  The file is specified by filename, 
 * instead of using a pre-opened file.
 * @param finfo Where to store the information about the file, which is
 * never touched if the call fails.
 * @param fname The name of the file to stat.
 * @param wanted The desired apr_finfo_t fields, as a bit flag of APR_FINFO_
                 values 
 * @param pool the pool to use to allocate the new file. 
 *
 * @note If @c APR_INCOMPLETE is returned all the fields in @a finfo may
 *       not be filled in, and you need to check the @c finfo->valid bitmask
 *       to verify that what you're looking for is there.
 */ 
APR_DECLARE(apr_status_t) apr_stat(apr_finfo_t *finfo, const char *fname,
                                   apr_int32_t wanted, apr_pool_t *pool);

/** @} */
/**
 * @defgroup apr_dir Directory Manipulation Functions
 * @{
 */

/**
 * Open the specified directory.
 * @param new_dir The opened directory descriptor.
 * @param dirname The full path to the directory (use / on all systems)
 * @param pool The pool to use.
 */                        
APR_DECLARE(apr_status_t) apr_dir_open(apr_dir_t **new_dir, 
                                       const char *dirname, 
                                       apr_pool_t *pool);

/**
 * close the specified directory. 
 * @param thedir the directory descriptor to close.
 */                        
APR_DECLARE(apr_status_t) apr_dir_close(apr_dir_t *thedir);

/**
 * Read the next entry from the specified directory. 
 * @param finfo the file info structure and filled in by apr_dir_read
 * @param wanted The desired apr_finfo_t fields, as a bit flag of APR_FINFO_
                 values 
 * @param thedir the directory descriptor returned from apr_dir_open
 * @remark No ordering is guaranteed for the entries read.
 *
 * @note If @c APR_INCOMPLETE is returned all the fields in @a finfo may
 *       not be filled in, and you need to check the @c finfo->valid bitmask
 *       to verify that what you're looking for is there. When no more
 *       entries are available, APR_ENOENT is returned.
 */                        
APR_DECLARE(apr_status_t) apr_dir_read(apr_finfo_t *finfo, apr_int32_t wanted,
                                       apr_dir_t *thedir);

/**
 * Rewind the directory to the first entry.
 * @param thedir the directory descriptor to rewind.
 */                        
APR_DECLARE(apr_status_t) apr_dir_rewind(apr_dir_t *thedir);
/** @} */

/**
 * @defgroup apr_filepath Filepath Manipulation Functions
 * @{
 */

/** Cause apr_filepath_merge to fail if addpath is above rootpath 
 * @bug in APR 0.9 and 1.x, this flag's behavior is undefined
 * if the rootpath is NULL or empty.  In APR 2.0 this should be
 * changed to imply NOTABSOLUTE if the rootpath is NULL or empty.
 */
#define APR_FILEPATH_NOTABOVEROOT   0x01

/** internal: Only meaningful with APR_FILEPATH_NOTABOVEROOT */
#define APR_FILEPATH_SECUREROOTTEST 0x02

/** Cause apr_filepath_merge to fail if addpath is above rootpath,
 * even given a rootpath /foo/bar and an addpath ../bar/bash
 */
#define APR_FILEPATH_SECUREROOT     0x03

/** Fail apr_filepath_merge if the merged path is relative */
#define APR_FILEPATH_NOTRELATIVE    0x04

/** Fail apr_filepath_merge if the merged path is absolute */
#define APR_FILEPATH_NOTABSOLUTE    0x08

/** Return the file system's native path format (e.g. path delimiters
 * of ':' on MacOS9, '\' on Win32, etc.) */
#define APR_FILEPATH_NATIVE         0x10

/** Resolve the true case of existing directories and file elements
 * of addpath, (resolving any aliases on Win32) and append a proper 
 * trailing slash if a directory
 */
#define APR_FILEPATH_TRUENAME       0x20

/**
 * Extract the rootpath from the given filepath
 * @param rootpath the root file path returned with APR_SUCCESS or APR_EINCOMPLETE
 * @param filepath the pathname to parse for its root component
 * @param flags the desired rules to apply, from
 * <PRE>
 *      APR_FILEPATH_NATIVE    Use native path separators (e.g. '\' on Win32)
 *      APR_FILEPATH_TRUENAME  Tests that the root exists, and makes it proper
 * </PRE>
 * @param p the pool to allocate the new path string from
 * @remark on return, filepath points to the first non-root character in the
 * given filepath.  In the simplest example, given a filepath of "/foo", 
 * returns the rootpath of "/" and filepath points at "foo".  This is far 
 * more complex on other platforms, which will canonicalize the root form
 * to a consistant format, given the APR_FILEPATH_TRUENAME flag, and also
 * test for the validity of that root (e.g., that a drive d:/ or network 
 * share //machine/foovol/). 
 * The function returns APR_ERELATIVE if filepath isn't rooted (an
 * error), APR_EINCOMPLETE if the root path is ambiguous (but potentially
 * legitimate, e.g. "/" on Windows is incomplete because it doesn't specify
 * the drive letter), or APR_EBADPATH if the root is simply invalid.
 * APR_SUCCESS is returned if filepath is an absolute path.
 */
APR_DECLARE(apr_status_t) apr_filepath_root(const char **rootpath, 
                                            const char **filepath, 
                                            apr_int32_t flags,
                                            apr_pool_t *p);

/**
 * Merge additional file path onto the previously processed rootpath
 * @param newpath the merged paths returned
 * @param rootpath the root file path (NULL uses the current working path)
 * @param addpath the path to add to the root path
 * @param flags the desired APR_FILEPATH_ rules to apply when merging
 * @param p the pool to allocate the new path string from
 * @remark if the flag APR_FILEPATH_TRUENAME is given, and the addpath 
 * contains wildcard characters ('*', '?') on platforms that don't support 
 * such characters within filenames, the paths will be merged, but the 
 * result code will be APR_EPATHWILD, and all further segments will not
 * reflect the true filenames including the wildcard and following segments.
 */                        
APR_DECLARE(apr_status_t) apr_filepath_merge(char **newpath, 
                                             const char *rootpath,
                                             const char *addpath, 
                                             apr_int32_t flags,
                                             apr_pool_t *p);

/**
 * Split a search path into separate components
 * @param pathelts the returned components of the search path
 * @param liststr the search path (e.g., <tt>getenv("PATH")</tt>)
 * @param p the pool to allocate the array and path components from
 * @remark empty path components do not become part of @a pathelts.
 * @remark the path separator in @a liststr is system specific;
 * e.g., ':' on Unix, ';' on Windows, etc.
 */
APR_DECLARE(apr_status_t) apr_filepath_list_split(apr_array_header_t **pathelts,
                                                  const char *liststr,
                                                  apr_pool_t *p);

/**
 * Merge a list of search path components into a single search path
 * @param liststr the returned search path; may be NULL if @a pathelts is empty
 * @param pathelts the components of the search path
 * @param p the pool to allocate the search path from
 * @remark emtpy strings in the source array are ignored.
 * @remark the path separator in @a liststr is system specific;
 * e.g., ':' on Unix, ';' on Windows, etc.
 */
APR_DECLARE(apr_status_t) apr_filepath_list_merge(char **liststr,
                                                  apr_array_header_t *pathelts,
                                                  apr_pool_t *p);

/**
 * Return the default file path (for relative file names)
 * @param path the default path string returned
 * @param flags optional flag APR_FILEPATH_NATIVE to retrieve the
 *              default file path in os-native format.
 * @param p the pool to allocate the default path string from
 */
APR_DECLARE(apr_status_t) apr_filepath_get(char **path, apr_int32_t flags,
                                           apr_pool_t *p);

/**
 * Set the default file path (for relative file names)
 * @param path the default path returned
 * @param p the pool to allocate any working storage
 */
APR_DECLARE(apr_status_t) apr_filepath_set(const char *path, apr_pool_t *p);

/** The FilePath character encoding is unknown */
#define APR_FILEPATH_ENCODING_UNKNOWN  0

/** The FilePath character encoding is locale-dependent */
#define APR_FILEPATH_ENCODING_LOCALE   1

/** The FilePath character encoding is UTF-8 */
#define APR_FILEPATH_ENCODING_UTF8     2

/**
 * Determine the encoding used internally by the FilePath functions
 * @param style points to a variable which receives the encoding style flag
 * @param p the pool to allocate any working storage
 * @remark Use apr_os_locale_encoding() and/or apr_os_default_encoding()
 * to get the name of the path encoding if it's not UTF-8.
 */
APR_DECLARE(apr_status_t) apr_filepath_encoding(int *style, apr_pool_t *p);
/** @} */

/** @} */

#ifdef __cplusplus
}
#endif

#endif  /* ! APR_FILE_INFO_H */
apr-1/apr_tables.h000064400000045632151730340560007767 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_TABLES_H
#define APR_TABLES_H

/**
 * @file apr_tables.h
 * @brief APR Table library
 */

#include "apr.h"
#include "apr_pools.h"

#if APR_HAVE_STDARG_H
#include <stdarg.h>     /* for va_list */
#endif

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @defgroup apr_tables Table and Array Functions
 * @ingroup APR 
 * Arrays are used to store data which is referenced sequentially or
 * as a stack.  Functions are provided to push and pop individual
 * elements as well as to operate on the entire array.
 *
 * Tables are used to store data which can be referenced by key.
 * Limited capabilities are provided for tables with multiple elements
 * which share a key; while key lookup will return only a single
 * element, iteration is available.  Additionally, a table can be
 * compressed to resolve duplicates.
 *
 * Both arrays and tables may store string or binary data; some features,
 * such as concatenation or merging of elements, work only for string
 * data.
 * @{
 */

/** the table abstract data type */
typedef struct apr_table_t apr_table_t;

/** @see apr_array_header_t */
typedef struct apr_array_header_t apr_array_header_t;

/** An opaque array type */
struct apr_array_header_t {
    /** The pool the array is allocated out of */
    apr_pool_t *pool;
    /** The amount of memory allocated for each element of the array */
    int elt_size;
    /** The number of active elements in the array */
    int nelts;
    /** The number of elements allocated in the array */
    int nalloc;
    /** The elements in the array */
    char *elts;
};

/**
 * The (opaque) structure for string-content tables.
 */
typedef struct apr_table_entry_t apr_table_entry_t;

/** The type for each entry in a string-content table */
struct apr_table_entry_t {
    /** The key for the current table entry */
    char *key;          /* maybe NULL in future;
                         * check when iterating thru table_elts
                         */
    /** The value for the current table entry */
    char *val;

    /** A checksum for the key, for use by the apr_table internals */
    apr_uint32_t key_checksum;
};

/**
 * Get the elements from a table.
 * @param t The table
 * @return An array containing the contents of the table
 */
APR_DECLARE(const apr_array_header_t *) apr_table_elts(const apr_table_t *t);

/**
 * Determine if the table is empty (either NULL or having no elements).
 * @param t The table to check
 * @return True if empty, False otherwise
 */
APR_DECLARE(int) apr_is_empty_table(const apr_table_t *t);

/**
 * Determine if the array is empty (either NULL or having no elements).
 * @param a The array to check
 * @return True if empty, False otherwise
 */
APR_DECLARE(int) apr_is_empty_array(const apr_array_header_t *a);

/**
 * Create an array.
 * @param p The pool to allocate the memory out of
 * @param nelts the number of elements in the initial array
 * @param elt_size The size of each element in the array.
 * @return The new array
 */
APR_DECLARE(apr_array_header_t *) apr_array_make(apr_pool_t *p,
                                                 int nelts, int elt_size);

/**
 * Add a new element to an array (as a first-in, last-out stack).
 * @param arr The array to add an element to.
 * @return Location for the new element in the array.
 * @remark If there are no free spots in the array, then this function will
 *         allocate new space for the new element.
 */
APR_DECLARE(void *) apr_array_push(apr_array_header_t *arr);

/** A helper macro for accessing a member of an APR array.
 *
 * @param ary the array
 * @param i the index into the array to return
 * @param type the type of the objects stored in the array
 *
 * @return the item at index i
 */
#define APR_ARRAY_IDX(ary,i,type) (((type *)(ary)->elts)[i])

/** A helper macro for pushing elements into an APR array.
 *
 * @param ary the array
 * @param type the type of the objects stored in the array
 *
 * @return the location where the new object should be placed
 */
#define APR_ARRAY_PUSH(ary,type) (*((type *)apr_array_push(ary)))

/**
 * Remove an element from an array (as a first-in, last-out stack).
 * @param arr The array to remove an element from.
 * @return Location of the element in the array.
 * @remark If there are no elements in the array, NULL is returned.
 */
APR_DECLARE(void *) apr_array_pop(apr_array_header_t *arr);

/**
 * Remove all elements from an array.
 * @param arr The array to remove all elements from.
 * @remark As the underlying storage is allocated from a pool, no
 * memory is freed by this operation, but is available for reuse.
 */
APR_DECLARE(void) apr_array_clear(apr_array_header_t *arr);

/**
 * Concatenate two arrays together.
 * @param dst The destination array, and the one to go first in the combined 
 *            array
 * @param src The source array to add to the destination array
 */
APR_DECLARE(void) apr_array_cat(apr_array_header_t *dst,
			        const apr_array_header_t *src);

/**
 * Copy the entire array.
 * @param p The pool to allocate the copy of the array out of
 * @param arr The array to copy
 * @return An exact copy of the array passed in
 * @remark The alternate apr_array_copy_hdr() copies only the header, and arranges 
 *         for the elements to be copied if (and only if) the code subsequently
 *         does a push or arraycat.
 */
APR_DECLARE(apr_array_header_t *) apr_array_copy(apr_pool_t *p,
                                      const apr_array_header_t *arr);
/**
 * Copy the headers of the array, and arrange for the elements to be copied if
 * and only if the code subsequently does a push or arraycat.
 * @param p The pool to allocate the copy of the array out of
 * @param arr The array to copy
 * @return An exact copy of the array passed in
 * @remark The alternate apr_array_copy() copies the *entire* array.
 */
APR_DECLARE(apr_array_header_t *) apr_array_copy_hdr(apr_pool_t *p,
                                      const apr_array_header_t *arr);

/**
 * Append one array to the end of another, creating a new array in the process.
 * @param p The pool to allocate the new array out of
 * @param first The array to put first in the new array.
 * @param second The array to put second in the new array.
 * @return A new array containing the data from the two arrays passed in.
*/
APR_DECLARE(apr_array_header_t *) apr_array_append(apr_pool_t *p,
                                      const apr_array_header_t *first,
                                      const apr_array_header_t *second);

/**
 * Generate a new string from the apr_pool_t containing the concatenated 
 * sequence of substrings referenced as elements within the array.  The string 
 * will be empty if all substrings are empty or null, or if there are no 
 * elements in the array.  If sep is non-NUL, it will be inserted between 
 * elements as a separator.
 * @param p The pool to allocate the string out of
 * @param arr The array to generate the string from
 * @param sep The separator to use
 * @return A string containing all of the data in the array.
 */
APR_DECLARE(char *) apr_array_pstrcat(apr_pool_t *p,
				      const apr_array_header_t *arr,
				      const char sep);

/**
 * Make a new table.
 * @param p The pool to allocate the pool out of
 * @param nelts The number of elements in the initial table.
 * @return The new table.
 * @warning This table can only store text data
 */
APR_DECLARE(apr_table_t *) apr_table_make(apr_pool_t *p, int nelts);

/**
 * Create a new table and copy another table into it.
 * @param p The pool to allocate the new table out of
 * @param t The table to copy
 * @return A copy of the table passed in
 * @warning The table keys and respective values are not copied
 */
APR_DECLARE(apr_table_t *) apr_table_copy(apr_pool_t *p,
                                          const apr_table_t *t);

/**
 * Create a new table whose contents are deep copied from the given
 * table. A deep copy operation copies all fields, and makes copies
 * of dynamically allocated memory pointed to by the fields.
 * @param p The pool to allocate the new table out of
 * @param t The table to clone
 * @return A deep copy of the table passed in
 */
APR_DECLARE(apr_table_t *) apr_table_clone(apr_pool_t *p,
                                           const apr_table_t *t);

/**
 * Delete all of the elements from a table.
 * @param t The table to clear
 */
APR_DECLARE(void) apr_table_clear(apr_table_t *t);

/**
 * Get the value associated with a given key from the table.  After this call,
 * the data is still in the table.
 * @param t The table to search for the key
 * @param key The key to search for (case does not matter)
 * @return The value associated with the key, or NULL if the key does not exist. 
 */
APR_DECLARE(const char *) apr_table_get(const apr_table_t *t, const char *key);

/**
 * Get values associated with a given key from the table.      If more than one
 * value exists, return a comma separated list of values.  After this call, the
 * data is still in the table.
 * @param p The pool to allocate the combined value from, if necessary
 * @param t The table to search for the key
 * @param key The key to search for (case does not matter)
 * @return The value associated with the key, or NULL if the key does not exist.
 */
APR_DECLARE(const char *) apr_table_getm(apr_pool_t *p, const apr_table_t *t,
                                         const char *key);

/**
 * Add a key/value pair to a table.  If another element already exists with the
 * same key, this will overwrite the old data.
 * @param t The table to add the data to.
 * @param key The key to use (case does not matter)
 * @param val The value to add
 * @remark When adding data, this function makes a copy of both the key and the
 *         value.
 */
APR_DECLARE(void) apr_table_set(apr_table_t *t, const char *key,
                                const char *val);

/**
 * Add a key/value pair to a table.  If another element already exists with the
 * same key, this will overwrite the old data.
 * @param t The table to add the data to.
 * @param key The key to use (case does not matter)
 * @param val The value to add
 * @warning When adding data, this function does not make a copy of the key or 
 *          the value, so care should be taken to ensure that the values will 
 *          not change after they have been added..
 */
APR_DECLARE(void) apr_table_setn(apr_table_t *t, const char *key,
                                 const char *val);

/**
 * Remove data from the table.
 * @param t The table to remove data from
 * @param key The key of the data being removed (case does not matter)
 */
APR_DECLARE(void) apr_table_unset(apr_table_t *t, const char *key);

/**
 * Add data to a table by merging the value with data that has already been 
 * stored. The merging is done by concatenating the two values, separated
 * by the string ", ".
 * @param t The table to search for the data
 * @param key The key to merge data for (case does not matter)
 * @param val The data to add
 * @remark If the key is not found, then this function acts like apr_table_add()
 */
APR_DECLARE(void) apr_table_merge(apr_table_t *t, const char *key,
                                  const char *val);

/**
 * Add data to a table by merging the value with data that has already been 
 * stored. The merging is done by concatenating the two values, separated
 * by the string ", ".
 * @param t The table to search for the data
 * @param key The key to merge data for (case does not matter)
 * @param val The data to add
 * @remark If the key is not found, then this function acts like apr_table_addn()
 */
APR_DECLARE(void) apr_table_mergen(apr_table_t *t, const char *key,
                                   const char *val);

/**
 * Add data to a table, regardless of whether there is another element with the
 * same key.
 * @param t The table to add to
 * @param key The key to use
 * @param val The value to add.
 * @remark When adding data, this function makes a copy of both the key and the
 *         value.
 */
APR_DECLARE(void) apr_table_add(apr_table_t *t, const char *key,
                                const char *val);

/**
 * Add data to a table, regardless of whether there is another element with the
 * same key.
 * @param t The table to add to
 * @param key The key to use
 * @param val The value to add.
 * @remark When adding data, this function does not make a copy of the key or the
 *         value, so care should be taken to ensure that the values will not 
 *         change after they have been added.
 */
APR_DECLARE(void) apr_table_addn(apr_table_t *t, const char *key,
                                 const char *val);

/**
 * Merge two tables into one new table.
 * @param p The pool to use for the new table
 * @param overlay The first table to put in the new table
 * @param base The table to add at the end of the new table
 * @return A new table containing all of the data from the two passed in
 */
APR_DECLARE(apr_table_t *) apr_table_overlay(apr_pool_t *p,
                                             const apr_table_t *overlay,
                                             const apr_table_t *base);

/**
 * Declaration prototype for the iterator callback function of apr_table_do()
 * and apr_table_vdo().
 * @param rec The data passed as the first argument to apr_table_[v]do()
 * @param key The key from this iteration of the table
 * @param value The value from this iteration of the table
 * @remark Iteration continues while this callback function returns non-zero.
 * To export the callback function for apr_table_[v]do() it must be declared 
 * in the _NONSTD convention.
 * @see apr_table_do @see apr_table_vdo
 */
typedef int (apr_table_do_callback_fn_t)(void *rec, const char *key, 
                                                    const char *value);

/** 
 * Iterate over a table running the provided function once for every
 * element in the table.  The varargs array must be a list of zero or
 * more (char *) keys followed by a NULL pointer.  If zero keys are
 * given, the @p comp function will be invoked for every element
 * in the table.  Otherwise, the function is invoked only for those
 * elements matching the keys specified.
 *
 * If an invocation of the @p comp function returns zero,
 * iteration will continue using the next specified key, if any.
 *
 * @param comp The function to run
 * @param rec The data to pass as the first argument to the function
 * @param t The table to iterate over
 * @param ... A varargs array of zero or more (char *) keys followed by NULL
 * @return FALSE if one of the comp() iterations returned zero; TRUE if all
 *            iterations returned non-zero
 * @see apr_table_do_callback_fn_t @see apr_table_vdo
 */
APR_DECLARE_NONSTD(int) apr_table_do(apr_table_do_callback_fn_t *comp,
                                     void *rec, const apr_table_t *t, ...)
#if defined(__GNUC__) && __GNUC__ >= 4
    __attribute__((sentinel))
#endif
    ;

/** 
 * Iterate over a table running the provided function once for every
 * element in the table.  The @p vp varargs parameter must be a
 * list of zero or more (char *) keys followed by a NULL pointer.  If
 * zero keys are given, the @p comp function will be invoked for
 * every element in the table.  Otherwise, the function is invoked
 * only for those elements matching the keys specified.
 *
 * If an invocation of the @p comp function returns zero,
 * iteration will continue using the next specified key, if any.
 *
 * @param comp The function to run
 * @param rec The data to pass as the first argument to the function
 * @param t The table to iterate over
 * @param vp List of zero or more (char *) keys followed by NULL
 * @return FALSE if one of the comp() iterations returned zero; TRUE if all
 *            iterations returned non-zero
 * @see apr_table_do_callback_fn_t @see apr_table_do
 */
APR_DECLARE(int) apr_table_vdo(apr_table_do_callback_fn_t *comp,
                               void *rec, const apr_table_t *t, va_list vp);

/** flag for overlap to use apr_table_setn */
#define APR_OVERLAP_TABLES_SET   (0)
/** flag for overlap to use apr_table_mergen */
#define APR_OVERLAP_TABLES_MERGE (1)
/** flag for overlap to use apr_table_addn */
#define APR_OVERLAP_TABLES_ADD   (2)
/**
 * For each element in table b, either use setn or mergen to add the data
 * to table a.  Which method is used is determined by the flags passed in.
 * @param a The table to add the data to.
 * @param b The table to iterate over, adding its data to table a
 * @param flags How to add the table to table a.  One of:
 *          APR_OVERLAP_TABLES_SET        Use apr_table_setn
 *          APR_OVERLAP_TABLES_MERGE      Use apr_table_mergen
 *          APR_OVERLAP_TABLES_ADD        Use apr_table_addn
 * @remark  When merging duplicates, the two values are concatenated,
 *          separated by the string ", ".
 * @remark  This function is highly optimized, and uses less memory and CPU cycles
 *          than a function that just loops through table b calling other functions.
 */
/**
 * Conceptually, apr_table_overlap does this:
 *
 * <pre>
 *  apr_array_header_t *barr = apr_table_elts(b);
 *  apr_table_entry_t *belt = (apr_table_entry_t *)barr->elts;
 *  int i;
 *
 *  for (i = 0; i < barr->nelts; ++i) {
 *      if (flags & APR_OVERLAP_TABLES_MERGE) {
 *          apr_table_mergen(a, belt[i].key, belt[i].val);
 *      }
 *      else if (flags & APR_OVERLAP_TABLES_ADD) {
 *          apr_table_addn(a, belt[i].key, belt[i].val);
 *      }
 *      else {
 *          apr_table_setn(a, belt[i].key, belt[i].val);
 *      }
 *  }
 * </pre>
 *
 *  Except that it is more efficient (less space and cpu-time) especially
 *  when b has many elements.
 *
 *  Notice the assumptions on the keys and values in b -- they must be
 *  in an ancestor of a's pool.  In practice b and a are usually from
 *  the same pool.
 */

APR_DECLARE(void) apr_table_overlap(apr_table_t *a, const apr_table_t *b,
                                     unsigned flags);

/**
 * Eliminate redundant entries in a table by either overwriting
 * or merging duplicates.
 *
 * @param t Table.
 * @param flags APR_OVERLAP_TABLES_MERGE to merge, or
 *              APR_OVERLAP_TABLES_SET to overwrite, or
 *              APR_OVERLAP_TABLES_ADD to add
 * @remark When merging duplicates, the two values are concatenated,
 *         separated by the string ", ".
 */
APR_DECLARE(void) apr_table_compress(apr_table_t *t, unsigned flags);

/** @} */

#ifdef __cplusplus
}
#endif

#endif	/* ! APR_TABLES_H */
apr-1/apr_strings.h000064400000035061151730340560010201 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* Portions of this file are covered by */
/* -*- mode: c; c-file-style: "k&r" -*-

  strnatcmp.c -- Perform 'natural order' comparisons of strings in C.
  Copyright (C) 2000 by Martin Pool <mbp@humbug.org.au>

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
*/

#ifndef APR_STRINGS_H
#define APR_STRINGS_H

/**
 * @file apr_strings.h
 * @brief APR Strings library
 */

#include "apr.h"
#include "apr_errno.h"
#include "apr_pools.h"
#define APR_WANT_IOVEC
#include "apr_want.h"

#if APR_HAVE_STDARG_H
#include <stdarg.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @defgroup apr_strings String routines
 * @ingroup APR 
 * @{
 */

/**
 * Do a natural order comparison of two strings.
 * @param a The first string to compare
 * @param b The second string to compare
 * @return Either <0, 0, or >0.  If the first string is less than the second
 *          this returns <0, if they are equivalent it returns 0, and if the
 *          first string is greater than second string it retuns >0.
 */
APR_DECLARE(int) apr_strnatcmp(char const *a, char const *b);

/**
 * Do a natural order comparison of two strings ignoring the case of the 
 * strings.
 * @param a The first string to compare
 * @param b The second string to compare
 * @return Either <0, 0, or >0.  If the first string is less than the second
 *         this returns <0, if they are equivalent it returns 0, and if the
 *         first string is greater than second string it retuns >0.
 */
APR_DECLARE(int) apr_strnatcasecmp(char const *a, char const *b);

/**
 * duplicate a string into memory allocated out of a pool
 * @param p The pool to allocate out of
 * @param s The string to duplicate
 * @return The new string or NULL if s == NULL
 */
APR_DECLARE(char *) apr_pstrdup(apr_pool_t *p, const char *s);

/**
 * Create a null-terminated string by making a copy of a sequence
 * of characters and appending a null byte
 * @param p The pool to allocate out of
 * @param s The block of characters to duplicate
 * @param n The number of characters to duplicate
 * @return The new string or NULL if s == NULL
 * @remark This is a faster alternative to apr_pstrndup(), for use
 *         when you know that the string being duplicated really
 *         has 'n' or more characters.  If the string might contain
 *         fewer characters, use apr_pstrndup().
 */
APR_DECLARE(char *) apr_pstrmemdup(apr_pool_t *p, const char *s, apr_size_t n)
#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
    __attribute__((alloc_size(3)))
#endif
    ;

/**
 * Duplicate at most n characters of a string into memory allocated 
 * out of a pool; the new string will be NUL-terminated
 * @param p The pool to allocate out of
 * @param s The string to duplicate
 * @param n The maximum number of characters to duplicate
 * @return The new string or NULL if s == NULL
 * @remark The amount of memory allocated from the pool is the length
 *         of the returned string including the NUL terminator
 */
APR_DECLARE(char *) apr_pstrndup(apr_pool_t *p, const char *s, apr_size_t n);

/**
 * Duplicate a block of memory.
 *
 * @param p The pool to allocate from
 * @param m The memory to duplicate
 * @param n The number of bytes to duplicate
 * @return The new block of memory or NULL if m == NULL
 */
APR_DECLARE(void *) apr_pmemdup(apr_pool_t *p, const void *m, apr_size_t n)
#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
    __attribute__((alloc_size(3)))
#endif
    ;

/**
 * Concatenate multiple strings, allocating memory out a pool
 * @param p The pool to allocate out of
 * @param ... The strings to concatenate.  The final string must be NULL
 * @return The new string
 */
APR_DECLARE_NONSTD(char *) apr_pstrcat(apr_pool_t *p, ...)
#if defined(__GNUC__) && __GNUC__ >= 4
    __attribute__((sentinel))
#endif
    ;

/**
 * Concatenate multiple strings specified in a writev-style vector
 * @param p The pool from which to allocate
 * @param vec The strings to concatenate
 * @param nvec The number of strings to concatenate
 * @param nbytes (output) strlen of new string (pass in NULL to omit)
 * @return The new string
 */
APR_DECLARE(char *) apr_pstrcatv(apr_pool_t *p, const struct iovec *vec,
                                 apr_size_t nvec, apr_size_t *nbytes);

/**
 * printf-style style printing routine.  The data is output to a string 
 * allocated from a pool
 * @param p The pool to allocate out of
 * @param fmt The format of the string
 * @param ap The arguments to use while printing the data
 * @return The new string
 */
APR_DECLARE(char *) apr_pvsprintf(apr_pool_t *p, const char *fmt, va_list ap);

/**
 * printf-style style printing routine.  The data is output to a string 
 * allocated from a pool
 * @param p The pool to allocate out of
 * @param fmt The format of the string
 * @param ... The arguments to use while printing the data
 * @return The new string
 */
APR_DECLARE_NONSTD(char *) apr_psprintf(apr_pool_t *p, const char *fmt, ...)
        __attribute__((format(printf,2,3)));

/**
 * Copy up to dst_size characters from src to dst; does not copy
 * past a NUL terminator in src, but always terminates dst with a NUL
 * regardless.
 * @param dst The destination string
 * @param src The source string
 * @param dst_size The space available in dst; dst always receives
 *                 NUL termination, so if src is longer than
 *                 dst_size, the actual number of characters copied is
 *                 dst_size - 1.
 * @return Pointer to the NUL terminator of the destination string, dst
 * @remark
 * <PRE>
 * Note the differences between this function and strncpy():
 *  1) strncpy() doesn't always NUL terminate; apr_cpystrn() does.
 *  2) strncpy() pads the destination string with NULs, which is often 
 *     unnecessary; apr_cpystrn() does not.
 *  3) strncpy() returns a pointer to the beginning of the dst string;
 *     apr_cpystrn() returns a pointer to the NUL terminator of dst, 
 *     to allow a check for truncation.
 * </PRE>
 */
APR_DECLARE(char *) apr_cpystrn(char *dst, const char *src,
                                apr_size_t dst_size);

/**
 * Remove all whitespace from a string
 * @param dest The destination string.  It is okay to modify the string
 *             in place.  Namely dest == src
 * @param src The string to rid the spaces from.
 * @return A pointer to the destination string's null terminator.
 */
APR_DECLARE(char *) apr_collapse_spaces(char *dest, const char *src);

/**
 * Convert the arguments to a program from one string to an array of 
 * strings terminated by a NULL pointer
 * @param arg_str The arguments to convert
 * @param argv_out Output location.  This is a pointer to an array of strings.
 * @param token_context Pool to use.
 */
APR_DECLARE(apr_status_t) apr_tokenize_to_argv(const char *arg_str,
                                               char ***argv_out,
                                               apr_pool_t *token_context);

/**
 * Split a string into separate null-terminated tokens.  The tokens are 
 * delimited in the string by one or more characters from the sep
 * argument.
 * @param str The string to separate; this should be specified on the
 *            first call to apr_strtok() for a given string, and NULL
 *            on subsequent calls.
 * @param sep The set of delimiters
 * @param last State saved by apr_strtok() between calls.
 * @return The next token from the string
 * @note the 'last' state points to the trailing NUL char of the final
 * token, otherwise it points to the character following the current
 * token (all successive or empty occurances of sep are skiped on the
 * subsequent call to apr_strtok).  Therefore it is possible to avoid
 * a strlen() determination, with the following logic;
 * toklen = last - retval; if (*last) --toklen;
 */
APR_DECLARE(char *) apr_strtok(char *str, const char *sep, char **last);

/**
 * @defgroup APR_Strings_Snprintf snprintf implementations
 * @warning
 * These are snprintf implementations based on apr_vformatter().
 *
 * Note that various standards and implementations disagree on the return
 * value of snprintf, and side-effects due to %n in the formatting string.
 * apr_snprintf (and apr_vsnprintf) behaves as follows:
 *
 * Process the format string until the entire string is exhausted, or
 * the buffer fills.  If the buffer fills then stop processing immediately
 * (so no further %n arguments are processed), and return the buffer
 * length.  In all cases the buffer is NUL terminated. It will return the
 * number of characters inserted into the buffer, not including the
 * terminating NUL. As a special case, if len is 0, apr_snprintf will
 * return the number of characters that would have been inserted if
 * the buffer had been infinite (in this case, *buffer can be NULL)
 *
 * In no event does apr_snprintf return a negative number.
 * @{
 */

/**
 * snprintf routine based on apr_vformatter.  This means it understands the
 * same extensions.
 * @param buf The buffer to write to
 * @param len The size of the buffer
 * @param format The format string
 * @param ... The arguments to use to fill out the format string.
 */
APR_DECLARE_NONSTD(int) apr_snprintf(char *buf, apr_size_t len,
                                     const char *format, ...)
        __attribute__((format(printf,3,4)));

/**
 * vsnprintf routine based on apr_vformatter.  This means it understands the
 * same extensions.
 * @param buf The buffer to write to
 * @param len The size of the buffer
 * @param format The format string
 * @param ap The arguments to use to fill out the format string.
 */
APR_DECLARE(int) apr_vsnprintf(char *buf, apr_size_t len, const char *format,
                               va_list ap);
/** @} */

/**
 * create a string representation of an int, allocated from a pool
 * @param p The pool from which to allocate
 * @param n The number to format
 * @return The string representation of the number
 */
APR_DECLARE(char *) apr_itoa(apr_pool_t *p, int n);

/**
 * create a string representation of a long, allocated from a pool
 * @param p The pool from which to allocate
 * @param n The number to format
 * @return The string representation of the number
 */
APR_DECLARE(char *) apr_ltoa(apr_pool_t *p, long n);

/**
 * create a string representation of an apr_off_t, allocated from a pool
 * @param p The pool from which to allocate
 * @param n The number to format
 * @return The string representation of the number
 */
APR_DECLARE(char *) apr_off_t_toa(apr_pool_t *p, apr_off_t n);

/**
 * Convert a numeric string into an apr_off_t numeric value.
 * @param offset The value of the parsed string.
 * @param buf The string to parse. It may contain optional whitespace,
 *   followed by an optional '+' (positive, default) or '-' (negative)
 *   character, followed by an optional '0x' prefix if base is 0 or 16,
 *   followed by numeric digits appropriate for base.
 * @param end A pointer to the end of the valid character in buf. If
 *   not NULL, it is set to the first invalid character in buf.
 * @param base A numeric base in the range between 2 and 36 inclusive,
 *   or 0.  If base is zero, buf will be treated as base ten unless its
 *   digits are prefixed with '0x', in which case it will be treated as
 *   base 16.
 * @bug *end breaks type safety; where *buf is const, *end needs to be
 * declared as const in APR 2.0
 */
APR_DECLARE(apr_status_t) apr_strtoff(apr_off_t *offset, const char *buf, 
                                      char **end, int base);

/**
 * parse a numeric string into a 64-bit numeric value
 * @param buf The string to parse. It may contain optional whitespace,
 *   followed by an optional '+' (positive, default) or '-' (negative)
 *   character, followed by an optional '0x' prefix if base is 0 or 16,
 *   followed by numeric digits appropriate for base.
 * @param end A pointer to the end of the valid character in buf. If
 *   not NULL, it is set to the first invalid character in buf.
 * @param base A numeric base in the range between 2 and 36 inclusive,
 *   or 0.  If base is zero, buf will be treated as base ten unless its
 *   digits are prefixed with '0x', in which case it will be treated as
 *   base 16.
 * @return The numeric value of the string.  On overflow, errno is set
 * to ERANGE.  On success, errno is set to 0.
 */
APR_DECLARE(apr_int64_t) apr_strtoi64(const char *buf, char **end, int base);

/**
 * parse a base-10 numeric string into a 64-bit numeric value.
 * Equivalent to apr_strtoi64(buf, (char**)NULL, 10).
 * @param buf The string to parse
 * @return The numeric value of the string.  On overflow, errno is set
 * to ERANGE.  On success, errno is set to 0.
 */
APR_DECLARE(apr_int64_t) apr_atoi64(const char *buf);

/**
 * Format a binary size (magnitiudes are 2^10 rather than 10^3) from an apr_off_t,
 * as bytes, K, M, T, etc, to a four character compacted human readable string.
 * @param size The size to format
 * @param buf The 5 byte text buffer (counting the trailing null)
 * @return The buf passed to apr_strfsize()
 * @remark All negative sizes report '  - ', apr_strfsize only formats positive values.
 */
APR_DECLARE(char *) apr_strfsize(apr_off_t size, char *buf);

/** @} */

#ifdef __cplusplus
}
#endif

#endif  /* !APR_STRINGS_H */
apr-1/apr_mmap.h000064400000012015151730340560007434 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_MMAP_H
#define APR_MMAP_H

/**
 * @file apr_mmap.h
 * @brief APR MMAP routines
 */

#include "apr.h"
#include "apr_pools.h"
#include "apr_errno.h"
#include "apr_ring.h"
#include "apr_file_io.h"        /* for apr_file_t */

#ifdef BEOS
#include <kernel/OS.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @defgroup apr_mmap MMAP (Memory Map) Routines
 * @ingroup APR 
 * @{
 */

/** MMap opened for reading */
#define APR_MMAP_READ    1
/** MMap opened for writing */
#define APR_MMAP_WRITE   2

/** @see apr_mmap_t */
typedef struct apr_mmap_t            apr_mmap_t;

/**
 * @remark
 * As far as I can tell the only really sane way to store an MMAP is as a
 * void * and a length.  BeOS requires this area_id, but that's just a little
 * something extra.  I am exposing this type, because it doesn't make much
 * sense to keep it private, and opening it up makes some stuff easier in
 * Apache.
 */
/** The MMAP structure */
struct apr_mmap_t {
    /** The pool the mmap structure was allocated out of. */
    apr_pool_t *cntxt;
#ifdef BEOS
    /** An area ID.  Only valid on BeOS */
    area_id area;
#endif
#ifdef WIN32
    /** The handle of the file mapping */
    HANDLE mhandle;
    /** The start of the real memory page area (mapped view) */
    void *mv;
    /** The physical start, size and offset */
    apr_off_t  pstart;
    apr_size_t psize;
    apr_off_t  poffset;
#endif
    /** The start of the memory mapped area */
    void *mm;
    /** The amount of data in the mmap */
    apr_size_t size;
    /** ring of apr_mmap_t's that reference the same
     * mmap'ed region; acts in place of a reference count */
    APR_RING_ENTRY(apr_mmap_t) link;
};

#if APR_HAS_MMAP || defined(DOXYGEN)

/** @def APR_MMAP_THRESHOLD 
 * Files have to be at least this big before they're mmap()d.  This is to deal
 * with systems where the expense of doing an mmap() and an munmap() outweighs
 * the benefit for small files.  It shouldn't be set lower than 1.
 */
#ifdef MMAP_THRESHOLD
#  define APR_MMAP_THRESHOLD              MMAP_THRESHOLD
#else
#  ifdef SUNOS4
#    define APR_MMAP_THRESHOLD            (8*1024)
#  else
#    define APR_MMAP_THRESHOLD            1
#  endif /* SUNOS4 */
#endif /* MMAP_THRESHOLD */

/** @def APR_MMAP_LIMIT
 * Maximum size of MMap region
 */
#ifdef MMAP_LIMIT
#  define APR_MMAP_LIMIT                  MMAP_LIMIT
#else
#  define APR_MMAP_LIMIT                  (4*1024*1024)
#endif /* MMAP_LIMIT */

/** Can this file be MMaped */
#define APR_MMAP_CANDIDATE(filelength) \
    ((filelength >= APR_MMAP_THRESHOLD) && (filelength < APR_MMAP_LIMIT))

/*   Function definitions */

/** 
 * Create a new mmap'ed file out of an existing APR file.
 * @param newmmap The newly created mmap'ed file.
 * @param file The file to turn into an mmap.
 * @param offset The offset into the file to start the data pointer at.
 * @param size The size of the file
 * @param flag bit-wise or of:
 * <PRE>
 *          APR_MMAP_READ       MMap opened for reading
 *          APR_MMAP_WRITE      MMap opened for writing
 * </PRE>
 * @param cntxt The pool to use when creating the mmap.
 */
APR_DECLARE(apr_status_t) apr_mmap_create(apr_mmap_t **newmmap, 
                                          apr_file_t *file, apr_off_t offset,
                                          apr_size_t size, apr_int32_t flag,
                                          apr_pool_t *cntxt);

/**
 * Duplicate the specified MMAP.
 * @param new_mmap The structure to duplicate into. 
 * @param old_mmap The mmap to duplicate.
 * @param p The pool to use for new_mmap.
 */         
APR_DECLARE(apr_status_t) apr_mmap_dup(apr_mmap_t **new_mmap,
                                       apr_mmap_t *old_mmap,
                                       apr_pool_t *p);

/**
 * Remove a mmap'ed.
 * @param mm The mmap'ed file.
 */
APR_DECLARE(apr_status_t) apr_mmap_delete(apr_mmap_t *mm);

/** 
 * Move the pointer into the mmap'ed file to the specified offset.
 * @param addr The pointer to the offset specified.
 * @param mm The mmap'ed file.
 * @param offset The offset to move to.
 */
APR_DECLARE(apr_status_t) apr_mmap_offset(void **addr, apr_mmap_t *mm, 
                                          apr_off_t offset);

#endif /* APR_HAS_MMAP */

/** @} */

#ifdef __cplusplus
}
#endif

#endif  /* ! APR_MMAP_H */
apr-1/apr_encode.h000064400000074545151730340570007760 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @file apr_encode.h
 * @brief APR-UTIL Encoding
 */
#ifndef APR_ENCODE_H
#define APR_ENCODE_H

#include "apr.h"
#include "apr_general.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @defgroup APR_Util_Encode Base64/Base64Url/Base32/Base32Hex/Base16 Encoding
 * @ingroup APR_Util
 * @{
 */

/**
 * RFC4648 and RFC7515 compliant BASE64, BASE64URL, BASE32, BASE32HEX
 * and BASE16 encode/decode functions.
 *
 * The following encodings are supported:
 *
 * - Base 64 Encoding
 *
 *   o Use flag APR_ENCODE_NONE
 *   o https://tools.ietf.org/html/rfc4648#section-4
 *
 * - Base 64 Encoding with URL and Filename Safe Alphabet
 *
 *   o Use flag APR_ENCODE_URL
 *   o https://tools.ietf.org/html/rfc4648#section-5
 *
 * - Base 64 URL Encoding without Padding
 *
 *   o Use flag APR_ENCODE_BASE64URL
 *   o https://tools.ietf.org/html/rfc7515#appendix-C
 *
 * - Base 32 Encoding
 *
 *   o Use flag APR_ENCODE_NONE
 *   o https://tools.ietf.org/html/rfc4648#section-6
 *
 * - Base 32 Encoding with Extended Hex Alphabet
 *
 *   o Use flag APR_ENCODE_BASE32HEX
 *   o https://tools.ietf.org/html/rfc4648#section-7
 *
 * - Base 16 Encoding
 *
 *   o Use flags APR_ENCODE_NONE/APR_ENCODE_COLON
 *   o https://tools.ietf.org/html/rfc4648#section-8
 *
 * If a non valid character of any kind including whitespace is passed to any
 * of the decoder functions, APR_BADCH will be returned. In this case decoding
 * will still take place, but the results can not be trusted.
 *
 * If APR_ENCODE_RELAXED is passed to the decoder functions, decoding will be
 * attempted up until the first non valid character. If this results in an
 * invalid state in the decoder, such as but not limited to an odd number of
 * base16 characters, APR_BADCH will still be returned.
 *
 * If APR_ENCODE_RELAXED is not passed to a decoder function, the decoding will
 * be done in constant time regardless of whether the result returns APR_SUCCESS
 * or APR_BADCH.
 *
 * If the dest parameter is NULL, the maximum theoretical buffer size is
 * returned in the len field, including space for a terminating zero character
 * if the destination is a string. This value can be used to allocate buffers
 * of a suitable safe size.
 *
 * If the dest parameter is provided, the encoding or decoding will take place,
 * and the actual number of characters written is returned in the len field,
 * ignoring any terminating zero.
 *
 * Plain strings are not assumed '\0' terminated unless APR_ENCODE_STRING is
 * provided.
 *
 */

/**
 * When passing a string to one of the encode functions, this value can be
 * passed to indicate a string-valued key, and have the length computed
 * automatically.
 */
#define APR_ENCODE_STRING      (-1)

/**
 * Generate RFC4648 base16/base32/base64.
 */
#define APR_ENCODE_NONE 0

/**
 * If relaxed, decode up until the first non base16/base32/base64 character.
 */
#define APR_ENCODE_RELAXED 1

/**
 * Omit the padding character (=) while encoding.
 */
#define APR_ENCODE_NOPADDING 2

/**
 * Generate RFC4648 Base 64 Encoding with URL and Filename Safe Alphabet
 */
#define APR_ENCODE_URL 4

/**
 * Generate RFC7515 BASE64URL
 */
#define APR_ENCODE_BASE64URL (APR_ENCODE_NOPADDING | APR_ENCODE_URL)

/**
 * Generate base32hex encoding instead of base32 encoding
 */
#define APR_ENCODE_BASE32HEX 8

/**
 * Generate base16 with colons between each token.
 */
#define APR_ENCODE_COLON 16

/**
 * Generate base16 with lower case characters.
 */
#define APR_ENCODE_LOWER 32

/**
 * Convert text data to base64.
 * @param dest The destination string, can be NULL to output in \c len the
 *  needed buffer length for encoding.
 * @param src The original string, can be NULL if \c dest is NULL and \c slen
 *  is positive or nul.
 * @param slen The length of the original string, or APR_ENCODE_STRING if
 *  the actual length should be computed based on NUL termination.
 * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 64 Encoding. If
 *  APR_ENCODE_NOPADDING, omit the = padding character.	If APR_ENCODE_URL,
 *  use RFC4648 Base 64 Encoding with URL and Filename Safe Alphabet.
 *  If APR_ENCODE_BASE64URL, use RFC7515 base64url Encoding.
 * @param len If not NULL, outputs the length of the buffer needed for encoding
 *  (including the trailing NUL) if \c dest is NULL, or the actual length of
 *  the encoding (excluding the trailing NUL) if \c dest is not NULL.
 * @return APR_SUCCESS, or APR_EINVAL if \c slen is not APR_ENCODE_STRING and
 *  negative, or APR_NOTFOUND if \c dest is not NULL and \c src is NULL, or
 *  APR_ENOSPC if \c dest is NULL and the source length (based on \c slen or
 *  APR_ENCODE_STRING) is too big to encode.
 */
APR_DECLARE(apr_status_t) apr_encode_base64(char *dest, const char *src,
        apr_ssize_t slen, int flags, apr_size_t * len);

/**
 * Convert binary data to base64.
 * @param dest The destination string, can be NULL to output in \c len the
 *  needed buffer length for encoding.
 * @param src The original buffer, can be NULL if \c dest is NULL.
 * @param slen The length of the original buffer.
 * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 64 Encoding. If
 *  APR_ENCODE_NOPADDING, omit the = padding character.	If APR_ENCODE_URL,
 *  use RFC4648 Base 64 Encoding with URL and Filename Safe Alphabet.
 *  If APR_ENCODE_BASE64URL, use RFC7515 base64url Encoding.
 * @param len If not NULL, outputs the length of the buffer needed for encoding
 *  (including the trailing NUL) if \c dest is NULL, or the actual length of
 *  the encoding (excluding the trailing NUL) if \c dest is not NULL.
 * @return APR_SUCCESS, or APR_EINVAL if \c slen is negative, or APR_NOTFOUND
 *  if \c dest is not NULL and \c src is NULL, or APR_ENOSPC if \c dest is NULL
 *  and the source length (based on \c slen or APR_ENCODE_STRING) is too big to
 *  encode.
 */
APR_DECLARE(apr_status_t) apr_encode_base64_binary(char *dest, const unsigned char *src,
        apr_ssize_t slen, int flags, apr_size_t * len);

/**
 * Convert text data to base64, and return the results from a pool.
 * @param p Pool to allocate from.
 * @param src The original string.
 * @param slen The length of the original string, or APR_ENCODE_STRING if
 *  the actual length should be computed based on NUL termination.
 * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 64 Encoding. If
 *  APR_ENCODE_NOPADDING, omit the = padding character.	If APR_ENCODE_URL,
 *  use RFC4648 Base 64 Encoding with URL and Filename Safe Alphabet.
 *  If APR_ENCODE_BASE64URL, use RFC7515 base64url Encoding.
 * @param len If not NULL, outputs the length of the encoding (excluding the
 *  trailing NUL).
 * @return A NUL terminated string allocated from the pool on success,
 *  or NULL if src is NULL or allocation failed or the encoding is not
 *  possible (see apr_encode_base64 errors).
 */
APR_DECLARE(const char *)apr_pencode_base64(apr_pool_t * p, const char *src,
        apr_ssize_t slen, int flags, apr_size_t * len)__attribute__((nonnull(1)));

/**
 * Convert binary data to base64, and return the results from a pool.
 * @param p Pool to allocate from.
 * @param src The original buffer.
 * @param slen The length of the original buffer.
 * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 64 Encoding. If
 *  APR_ENCODE_NOPADDING, omit the = padding character.	If APR_ENCODE_URL,
 *  use RFC4648 Base 64 Encoding with URL and Filename Safe Alphabet.
 *  If APR_ENCODE_BASE64URL, use RFC7515 base64url Encoding.
 * @param len If not NULL, outputs the length of the encoding (excluding the
 *  trailing NUL).
 * @return A NUL terminated string allocated from the pool on success,
 *  or NULL if src is NULL or allocation failed or the encoding is not
 *  possible (see apr_encode_base64_binary errors).
 */
APR_DECLARE(const char *)apr_pencode_base64_binary(apr_pool_t * p, const unsigned char *src,
        apr_ssize_t slen, int flags, apr_size_t * len)__attribute__((nonnull(1)));

/**
 * Convert base64 or base64url with or without padding to text data.
 * @param dest The destination string, can be NULL to output in \c len the
 *  needed buffer length for decoding.
 * @param src The base64 string, can be NULL if \c dest is NULL and \c slen
 *  is positive or nul.
 * @param slen The length of the base64 string, or APR_ENCODE_STRING if
 *  the actual length should be computed based on NUL termination.
 * @param flags If APR_ENCODE_NONE, attempt to decode the full base64 string,
 *  and return NULL if any bad character is detected. If APR_ENCODE_RELAXED,
 *  decode until the first non base64/base64url character.
 * @param len If not NULL, outputs the length of the buffer needed for decoding
 *  (including the trailing NUL) if \c dest is NULL, or the actual length of
 *  the decoding (excluding the trailing NUL) if \c dest is not NULL.
 * @return APR_SUCCESS, or APR_EINVAL if \c slen is not APR_ENCODE_STRING and
 *  negative, or APR_NOTFOUND if \c dest is not NULL and \c src is NULL, or
 *  APR_ENOSPC if \c dest is NULL and the source length (based on \c slen or
 *  APR_ENCODE_STRING) is too big to decode, or APR_EINCOMPLETE if the source
 *  length (based on \c slen or APR_ENCODE_STRING) is invalid for a base64
 *  encoding, or APR_BADCH if a non base64 character is present and
 *  APR_ENCODE_RELAXED is not specified.
 */
APR_DECLARE(apr_status_t) apr_decode_base64(char *dest, const char *src,
        apr_ssize_t slen, int flags, apr_size_t * len);

/**
 * Convert base64 or base64url with or without padding to binary data.
 * @param dest The destination string, can be NULL to output in \c len the
 *  needed buffer length for decoding.
 * @param src The base64 string, can be NULL if \c dest is NULL and \c slen
 *  is positive or nul.
 * @param slen The length of the base64 string, or APR_ENCODE_STRING if
 *  the actual length should be computed based on NUL termination.
 * @param flags If APR_ENCODE_NONE, attempt to decode the full base64 string,
 *  and return NULL if any bad character is detected. If APR_ENCODE_RELAXED,
 *  decode until the first non base64/base64url character.
 * @param len If not NULL, outputs the length of the buffer needed for decoding
 *  (including the trailing NUL) if \c dest is NULL, or the actual length of
 *  the decoding (excluding the trailing NUL) if \c dest is not NULL.
 * @return APR_SUCCESS, or APR_EINVAL if \c slen is not APR_ENCODE_STRING and
 *  negative, or APR_NOTFOUND if \c dest is not NULL and \c src is NULL, or
 *  APR_ENOSPC if \c dest is NULL and the source length (based on \c slen or
 *  APR_ENCODE_STRING) is too big to decode, or APR_EINCOMPLETE if the source
 *  length (based on \c slen or APR_ENCODE_STRING) is invalid for a base64
 *  encoding, or APR_BADCH if a non base64 character is present and
 *  APR_ENCODE_RELAXED is not specified.
 */
APR_DECLARE(apr_status_t) apr_decode_base64_binary(unsigned char *dest,
        const char *src, apr_ssize_t slen, int flags, apr_size_t * len);

/**
 * Convert base64 or base64url with or without padding to text data, and
 * return the results from a pool.
 * @param p Pool to allocate from.
 * @param src The base64 string to decode.
 * @param slen The length of the original string, or APR_ENCODE_STRING if
 *  the actual length should be computed based on NUL termination.
 * @param flags If APR_ENCODE_NONE, attempt to decode the full original buffer,
 *  and return NULL if any bad character is detected. If APR_ENCODE_RELAXED,
 *  decode until the first non base64/base64url character.
 * @param len If not NULL, outputs the length of the decoding (excluding the
 *  trailing NUL).
 * @return A NUL terminated string allocated from the pool on success,
 *  or NULL if src is NULL or allocation failed or the decoding is not
 *  possible (see apr_decode_base64_binary errors).
 */
APR_DECLARE(const char *)apr_pdecode_base64(apr_pool_t * p, const char *src,
        apr_ssize_t slen, int flags, apr_size_t * len)
        __attribute__((nonnull(1)));

/**
 * Convert base64 or base64url with or without padding to binary data, and
 * return the results from a pool.
 * @param p Pool to allocate from.
 * @param src The base64 string to decode.
 * @param slen The length of the original string, or APR_ENCODE_STRING if
 *  the actual length should be computed based on NUL termination.
 * @param flags If APR_ENCODE_NONE, attempt to decode the full original buffer,
 *  and return NULL if any bad character is detected. If APR_ENCODE_RELAXED,
 *  decode until the first non base64/base64url character.
 * @param len If not NULL, outputs the length of the decoding (excluding the
 *  trailing NUL).
 * @return A NUL terminated string allocated from the pool on success,
 *  or NULL if src is NULL or allocation failed or the decoding is not
 *  possible (see apr_decode_base64_binary errors).
 */
APR_DECLARE(const unsigned char *)apr_pdecode_base64_binary(apr_pool_t * p,
        const char *src, apr_ssize_t slen, int flags, apr_size_t * len)
        __attribute__((nonnull(1)));

/**
 * Convert text data to base32.
 * @param dest The destination string, can be NULL to output in \c len the
 *  needed buffer length for encoding.
 * @param src The original string, can be NULL if \c dest is NULL and \c slen
 *  is positive or nul.
 * @param slen The length of the original string, or APR_ENCODE_STRING if
 *  the actual length should be computed based on NUL termination.
 * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 32 Encoding. If
 *  APR_ENCODE_NOPADDING, omit the = padding character.	If APR_ENCODE_BASE32HEX,
 *  use RFC4648 base32hex Encoding.
 * @param len If not NULL, outputs the length of the buffer needed for encoding
 *  (including the trailing NUL) if \c dest is NULL, or the actual length of
 *  the encoding (excluding the trailing NUL) if \c dest is not NULL.
 * @return APR_SUCCESS, or APR_EINVAL if \c slen is not APR_ENCODE_STRING and
 *  negative, or APR_NOTFOUND if \c dest is not NULL and \c src is NULL, or
 *  APR_ENOSPC if \c dest is NULL and the source length (based on \c slen or
 *  APR_ENCODE_STRING) is too big to encode.
 */
APR_DECLARE(apr_status_t) apr_encode_base32(char *dest, const char *src,
        apr_ssize_t slen, int flags, apr_size_t * len);

/**
 * Convert binary data to base32.
 * @param dest The destination string, can be NULL to output in \c len the
 *  needed buffer length for encoding.
 * @param src The original buffer, can be NULL if \c dest is NULL.
 * @param slen The length of the original buffer.
 * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 32 Encoding. If
 *  APR_ENCODE_NOPADDING, omit the = padding character.	If APR_ENCODE_BASE32HEX,
 *  use RFC4648 base32hex Encoding.
 * @param len If not NULL, outputs the length of the buffer needed for encoding
 *  (including the trailing NUL) if \c dest is NULL, or the actual length of
 *  the encoding (excluding the trailing NUL) if \c dest is not NULL.
 * @return APR_SUCCESS, or APR_EINVAL if \c slen is negative, or APR_NOTFOUND
 *  if \c dest is not NULL and \c src is NULL, or APR_ENOSPC if \c dest is NULL
 *  and the source length (based on \c slen or APR_ENCODE_STRING) is too big to
 *  encode.
 */
APR_DECLARE(apr_status_t) apr_encode_base32_binary(char *dest, const unsigned char *src,
        apr_ssize_t slen, int flags, apr_size_t * len);

/**
 * Convert text data to base32, and return the results from a pool.
 * @param p Pool to allocate from.
 * @param src The original string.
 * @param slen The length of the original string, or APR_ENCODE_STRING if
 *  the actual length should be computed based on NUL termination.
 * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 32 Encoding. If
 *  APR_ENCODE_NOPADDING, omit the = padding character.	If APR_ENCODE_BASE32HEX,
 *  use RFC4648 base32hex Encoding.
 * @param len If not NULL, outputs the length of the encoding (excluding the
 *  trailing NUL).
 * @return A NUL terminated string allocated from the pool on success,
 *  or NULL if src is NULL or allocation failed or the encoding is not
 *  possible (see apr_encode_base32 errors).
 */
APR_DECLARE(const char *)apr_pencode_base32(apr_pool_t * p, const char *src,
        apr_ssize_t slen, int flags, apr_size_t * len)
        __attribute__((nonnull(1)));

/**
 * Convert binary data to base32, and return the results from a pool.
 * @param p Pool to allocate from.
 * @param src The original buffer.
 * @param slen The length of the original buffer.
 * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 32 Encoding. If
 *  APR_ENCODE_NOPADDING, omit the = padding character.	If APR_ENCODE_BASE32HEX,
 *  use RFC4648 base32hex Encoding.
 * @param len If not NULL, outputs the length of the encoding (excluding the
 *  trailing NUL).
 * @return A NUL terminated string allocated from the pool on success,
 *  or NULL if src is NULL or allocation failed or the encoding is not
 *  possible (see apr_encode_base32_binary errors).
 */
APR_DECLARE(const char *)apr_pencode_base32_binary(apr_pool_t * p, const unsigned char *src,
        apr_ssize_t slen, int flags, apr_size_t * len)
        __attribute__((nonnull(1)));

/**
 * Convert base32 or base32hex with or without padding to text data.
 * @param dest The destination string, can be NULL to output in \c len the
 *  needed buffer length for decoding.
 * @param src The base32 string, can be NULL if \c dest is NULL and \c slen
 *  is positive or nul.
 * @param slen The length of the base32 string, or APR_ENCODE_STRING if
 *  the actual length should be computed based on NUL termination.
 * @param flags If APR_ENCODE_NONE, parse RFC4648 Base 32 Encoding. If
 *  APR_ENCODE_BASE32HEX, use RFC4648 base32hex Encoding.
 * @param len If not NULL, outputs the length of the buffer needed for decoding
 *  (including the trailing NUL) if \c dest is NULL, or the actual length of
 *  the decoding (excluding the trailing NUL) if \c dest is not NULL.
 * @return APR_SUCCESS, or APR_EINVAL if \c slen is not APR_ENCODE_STRING and
 *  negative, or APR_NOTFOUND if \c dest is not NULL and \c src is NULL, or
 *  APR_ENOSPC if \c dest is NULL and the source length (based on \c slen or
 *  APR_ENCODE_STRING) is too big to decode, or APR_EINCOMPLETE if the source
 *  length (based on \c slen or APR_ENCODE_STRING) is invalid for a base32
 *  encoding, or APR_BADCH if a non base32 character is present and
 *  APR_ENCODE_RELAXED is not specified.
 */
APR_DECLARE(apr_status_t) apr_decode_base32(char *dest, const char *src,
        apr_ssize_t slen, int flags, apr_size_t * len);

/**
 * Convert base32 or base32hex with or without padding to binary data.
 * @param dest The destination string, can be NULL to output in \c len the
 *  needed buffer length for decoding.
 * @param src The base32 string, can be NULL if \c dest is NULL and \c slen
 *  is positive or nul.
 * @param slen The length of the base32 string, or APR_ENCODE_STRING if
 *  the actual length should be computed based on NUL termination.
 * @param flags If APR_ENCODE_NONE, parse RFC4648 Base 32 Encoding. If
 *  APR_ENCODE_BASE32HEX, use RFC4648 base32hex Encoding.
 * @param len If not NULL, outputs the length of the buffer needed for decoding
 *  (including the trailing NUL) if \c dest is NULL, or the actual length of
 *  the decoding (excluding the trailing NUL) if \c dest is not NULL.
 * @return APR_SUCCESS, or APR_EINVAL if \c slen is not APR_ENCODE_STRING and
 *  negative, or APR_NOTFOUND if \c dest is not NULL and \c src is NULL, or
 *  APR_ENOSPC if \c dest is NULL and the source length (based on \c slen or
 *  APR_ENCODE_STRING) is too big to decode, or APR_EINCOMPLETE if the source
 *  length (based on \c slen or APR_ENCODE_STRING) is invalid for a base32
 *  encoding, or APR_BADCH if a non base32 character is present and
 *  APR_ENCODE_RELAXED is not specified.
 */
APR_DECLARE(apr_status_t) apr_decode_base32_binary(unsigned char *dest,
        const char *src, apr_ssize_t slen, int flags, apr_size_t * len);

/**
 * Convert base32 or base32hex with or without padding to text data, and
 * return the results from a pool.
 * @param p Pool to allocate from.
 * @param src The base32 string to decode.
 * @param slen The length of the original string, or APR_ENCODE_STRING if
 *  the actual length should be computed based on NUL termination.
 * @param flags If APR_ENCODE_NONE, parse RFC4648 Base 32 Encoding. If
 *  APR_ENCODE_BASE32HEX, use RFC4648 base32hex Encoding.
 * @param len If not NULL, outputs the length of the encoding (excluding the
 *  trailing NUL).
 * @return A NUL terminated string allocated from the pool on success,
 *  or NULL if src is NULL or allocation failed or the decoding is not
 *  possible (see apr_decode_base32 errors).
 */
APR_DECLARE(const char *)apr_pdecode_base32(apr_pool_t * p, const char *src,
        apr_ssize_t slen, int flags, apr_size_t * len)
        __attribute__((nonnull(1)));

/**
 * Convert base32 or base32hex with or without padding to binary data, and
 * return the results from a pool.
 * @param p Pool to allocate from.
 * @param src The base32 string to decode.
 * @param slen The length of the original string, or APR_ENCODE_STRING if
 *  the actual length should be computed based on NUL termination.
 * @param flags If APR_ENCODE_NONE, parse RFC4648 Base 32 Encoding. If
 *  APR_ENCODE_BASE32HEX, use RFC4648 base32hex Encoding.
 * @param len If not NULL, outputs the length of the encoding (excluding the
 *  trailing NUL).
 * @return A NUL terminated string allocated from the pool on success,
 *  or NULL if src is NULL or allocation failed or the decoding is not
 *  possible (see apr_decode_base32_binary errors).
 */
APR_DECLARE(const unsigned char *)apr_pdecode_base32_binary(apr_pool_t * p,
        const char *src, apr_ssize_t slen, int flags, apr_size_t * len)
        __attribute__((nonnull(1)));

/**
 * Convert text data to base16 (hex).
 * @param dest The destination string, can be NULL to output in \c len the
 *  needed buffer length for encoding.
 * @param src The original string, can be NULL if \c dest is NULL and \c slen
 *  is positive or nul.
 * @param slen The length of the original string, or APR_ENCODE_STRING if
 *  the actual length should be computed based on NUL termination.
 * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 16 Encoding. If
 *  APR_ENCODE_COLON, separate each token with a colon.
 * @param len If not NULL, outputs the length of the buffer needed for encoding
 *  (including the trailing NUL) if \c dest is NULL, or the actual length of
 *  the encoding (excluding the trailing NUL) if \c dest is not NULL.
 * @return APR_SUCCESS, or APR_EINVAL if \c slen is not APR_ENCODE_STRING and
 *  negative, or APR_NOTFOUND if \c dest is not NULL and \c src is NULL, or
 *  APR_ENOSPC if \c dest is NULL and the source length (based on \c slen or
 *  APR_ENCODE_STRING) is too big to encode.
 */
APR_DECLARE(apr_status_t) apr_encode_base16(char *dest, const char *src,
        apr_ssize_t slen, int flags, apr_size_t * len);

/**
 * Convert binary data to base16 (hex).
 * @param dest The destination string, can be NULL to output in \c len the
 *  needed buffer length for encoding.
 * @param src The original buffer, can be NULL if \c dest is NULL.
 * @param slen The length of the original buffer.
 * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 16 Encoding. If
 *  APR_ENCODE_COLON, separate each token with a colon.
 * @param len If not NULL, outputs the length of the buffer needed for encoding
 *  (including the trailing NUL) if \c dest is NULL, or the actual length of
 *  the encoding (excluding the trailing NUL) if \c dest is not NULL.
 * @return APR_SUCCESS, or APR_EINVAL if \c slen is negative, or APR_NOTFOUND
 *  if \c dest is not NULL and \c src is NULL, or APR_ENOSPC if \c dest is NULL
 *  and the source length (based on \c slen or APR_ENCODE_STRING) is too big to
 *  encode.
 */
APR_DECLARE(apr_status_t) apr_encode_base16_binary(char *dest,
        const unsigned char *src, apr_ssize_t slen, int flags,
        apr_size_t * len);

/**
 * Convert text data to base16 (hex), and return the results from a
 * pool.
 * @param p Pool to allocate from.
 * @param src The original string.
 * @param slen The length of the original string, or APR_ENCODE_STRING if
 *  the actual length should be computed based on NUL termination.
 * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 16 Encoding. If
 *  APR_ENCODE_COLON, separate each token with a colon.
 * @param len If not NULL, outputs the length of the encoding (excluding the
 *  trailing NUL).
 * @return A NUL terminated string allocated from the pool on success,
 *  or NULL if src is NULL or allocation failed or the encoding is not
 *  possible (see apr_encode_base16 errors).
 */
APR_DECLARE(const char *)apr_pencode_base16(apr_pool_t * p, const char *src,
        apr_ssize_t slen, int flags, apr_size_t * len)
        __attribute__((nonnull(1)));

/**
 * Convert binary data to base16 (hex), and return the results from a
 * pool.
 * @param p Pool to allocate from.
 * @param src The original buffer.
 * @param slen The length of the original buffer.
 * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 16 Encoding. If
 *  APR_ENCODE_COLON, separate each token with a colon.
 * @param len If not NULL, outputs the length of the encoding (excluding the
 *  trailing NUL).
 * @return A NUL terminated string allocated from the pool on success,
 *  or NULL if src is NULL or allocation failed or the encoding is not
 *  possible (see apr_encode_base16_binary errors).
 */
APR_DECLARE(const char *)apr_pencode_base16_binary(apr_pool_t * p,
        const unsigned char *src, apr_ssize_t slen,
        int flags, apr_size_t * len)__attribute__((nonnull(1)));

/**
 * Convert base16 (hex) to text data.
 * @param dest The destination string, can be NULL to output in \c len the
 *  needed buffer length for decoding.
 * @param src The base16 string, can be NULL if \c dest is NULL and \c slen
 *  is positive or nul.
 * @param slen The length of the base16 string, or APR_ENCODE_STRING if
 *  the actual length should be computed based on NUL termination.
 * @param flags If APR_ENCODE_NONE, parse RFC4648 Base 16 Encoding. If
 *  APR_ENCODE_COLON, allow tokens to be separated with a colon.
 * @param len If not NULL, outputs the length of the buffer needed for decoding
 *  (including the trailing NUL) if \c dest is NULL, or the actual length of
 *  the decoding (excluding the trailing NUL) if \c dest is not NULL.
 * @return APR_SUCCESS, or APR_EINVAL if \c slen is not APR_ENCODE_STRING and
 *  negative, or APR_NOTFOUND if \c dest is not NULL and \c src is NULL, or
 *  APR_ENOSPC if \c dest is NULL and the source length (based on \c slen or
 *  APR_ENCODE_STRING) is too big to decode, or APR_EINCOMPLETE if the source
 *  length (based on \c slen or APR_ENCODE_STRING) is invalid for a base16
 *  encoding, or APR_BADCH if a non base16 character is present and
 *  APR_ENCODE_RELAXED is not specified.
 */
APR_DECLARE(apr_status_t) apr_decode_base16(char *dest, const char *src,
        apr_ssize_t slen, int flags, apr_size_t * len);

/**
 * Convert base16 (hex) to binary data.
 * @param dest The destination string, can be NULL to output in \c len the
 *  needed buffer length for decoding.
 * @param src The base16 string, can be NULL if \c dest is NULL and \c slen
 *  is positive or nul.
 * @param slen The length of the base16 string, or APR_ENCODE_STRING if
 *  the actual length should be computed based on NUL termination.
 * @param flags If APR_ENCODE_NONE, parse RFC4648 Base 16 Encoding. If
 *  APR_ENCODE_COLON, allow tokens to be separated with a colon.
 * @param len If not NULL, outputs the length of the buffer needed for decoding
 *  (including the trailing NUL) if \c dest is NULL, or the actual length of
 *  the decoding (excluding the trailing NUL) if \c dest is not NULL.
 * @return APR_SUCCESS, or APR_EINVAL if \c slen is not APR_ENCODE_STRING and
 *  negative, or APR_NOTFOUND if \c dest is not NULL and \c src is NULL, or
 *  APR_ENOSPC if \c dest is NULL and the source length (based on \c slen or
 *  APR_ENCODE_STRING) is too big to decode, or APR_EINCOMPLETE if the source
 *  length (based on \c slen or APR_ENCODE_STRING) is invalid for a base16
 *  encoding, or APR_BADCH if a non base16 character is present and
 *  APR_ENCODE_RELAXED is not specified.
 */
APR_DECLARE(apr_status_t) apr_decode_base16_binary(unsigned char *dest,
        const char *src, apr_ssize_t slen, int flags, apr_size_t * len);

/**
 * Convert base16 (hex) and return the results from a pool.
 * @param p Pool to allocate from.
 * @param src The base16 string to decode.
 * @param slen The length of the original string, or APR_ENCODE_STRING if
 *  the actual length should be computed based on NUL termination.
 * @param flags If APR_ENCODE_NONE, parse RFC4648 Base 16 Encoding. If
 *  APR_ENCODE_COLON, allow tokens to be separated with a colon.
 * @param len If not NULL, outputs the length of the encoding (excluding the
 *  trailing NUL).
 * @return A NUL terminated string allocated from the pool on success,
 *  or NULL if src is NULL or allocation failed or the decoding is not
 *  possible (see apr_decode_base16 errors).
 */
APR_DECLARE(const char *)apr_pdecode_base16(apr_pool_t * p, const char *src,
        apr_ssize_t slen, int flags, apr_size_t * len)
        __attribute__((nonnull(1)));

/**
 * Convert base16 (hex) to binary data, and return the results from a pool.
 * @param p Pool to allocate from.
 * @param src The base16 string to decode.
 * @param slen The length of the original string, or APR_ENCODE_STRING if
 *  the actual length should be computed based on NUL termination.
 * @param flags If APR_ENCODE_NONE, parse RFC4648 Base 16 Encoding. If
 *  APR_ENCODE_COLON, allow tokens to be separated with a colon.
 * @param len If not NULL, outputs the length of the encoding (excluding the
 *  trailing NUL).
 * @return A NUL terminated string allocated from the pool on success,
 *  or NULL if src is NULL or allocation failed or the decoding is not
 *  possible (see apr_decode_base16_binary errors).
 */
APR_DECLARE(const unsigned char *)apr_pdecode_base16_binary(apr_pool_t * p,
        const char *src, apr_ssize_t slen, int flags, apr_size_t * len)
        __attribute__((nonnull(1)));

/** @} */
#ifdef __cplusplus
}
#endif

#endif                          /* !APR_ENCODE_H */
apr-1/apr_fnmatch.h000064400000014125151730340570010127 0ustar00/*
 * Copyright (c) 1992, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)fnmatch.h	8.1 (Berkeley) 6/2/93
 */

/* This file has been modified by the Apache Software Foundation. */
#ifndef	_APR_FNMATCH_H_
#define	_APR_FNMATCH_H_

/**
 * @file apr_fnmatch.h
 * @brief APR FNMatch Functions
 */

#include "apr_errno.h"
#include "apr_tables.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @defgroup apr_fnmatch Filename Matching Functions
 * @ingroup APR 
 * @{
 */

#define APR_FNM_NOMATCH     1     /**< Match failed. */
 
#define APR_FNM_NOESCAPE    0x01  /**< Disable backslash escaping. */
#define APR_FNM_PATHNAME    0x02  /**< Slash must be matched by slash. */
#define APR_FNM_PERIOD      0x04  /**< Period must be matched by period. */
#define APR_FNM_CASE_BLIND  0x08  /**< Compare characters case-insensitively. */

/**
 * Try to match the string to the given pattern, return APR_SUCCESS if
 *    match, else return APR_FNM_NOMATCH.  Note that there is no such thing as
 *    an illegal pattern.
 *
 * With all flags unset, a pattern is interpreted as such:
 *
 * PATTERN: Backslash followed by any character, including another
 *          backslash.<br/>
 * MATCHES: That character exactly.
 * 
 * <p>
 * PATTERN: ?<br/>
 * MATCHES: Any single character.
 * </p>
 * 
 * <p>
 * PATTERN: *<br/>
 * MATCHES: Any sequence of zero or more characters. (Note that multiple
 *          *s in a row are equivalent to one.)
 * 
 * PATTERN: Any character other than \?*[ or a \ at the end of the pattern<br/>
 * MATCHES: That character exactly. (Case sensitive.)
 * 
 * PATTERN: [ followed by a class description followed by ]<br/>
 * MATCHES: A single character described by the class description.
 *          (Never matches, if the class description reaches until the
 *          end of the string without a ].) If the first character of
 *          the class description is ^ or !, the sense of the description
 *          is reversed.  The rest of the class description is a list of
 *          single characters or pairs of characters separated by -. Any
 *          of those characters can have a backslash in front of them,
 *          which is ignored; this lets you use the characters ] and -
 *          in the character class, as well as ^ and ! at the
 *          beginning.  The pattern matches a single character if it
 *          is one of the listed characters or falls into one of the
 *          listed ranges (inclusive, case sensitive).  Ranges with
 *          the first character larger than the second are legal but
 *          never match. Edge cases: [] never matches, and [^] and [!]
 *          always match without consuming a character.
 * 
 * Note that these patterns attempt to match the entire string, not
 * just find a substring matching the pattern.
 *
 * @param pattern The pattern to match to
 * @param strings The string we are trying to match
 * @param flags flags to use in the match.  Bitwise OR of:
 * <pre>
 *              APR_FNM_NOESCAPE       Disable backslash escaping
 *              APR_FNM_PATHNAME       Slash must be matched by slash
 *              APR_FNM_PERIOD         Period must be matched by period
 *              APR_FNM_CASE_BLIND     Compare characters case-insensitively.
 * </pre>
 */

APR_DECLARE(apr_status_t) apr_fnmatch(const char *pattern, 
                                      const char *strings, int flags);

/**
 * Determine if the given pattern is a regular expression.
 * @param pattern The pattern to search for glob characters.
 * @return non-zero if pattern has any glob characters in it
 */
APR_DECLARE(int) apr_fnmatch_test(const char *pattern);

/**
 * Find all files that match a specified pattern in a directory.
 * @param dir_pattern The pattern to use for finding files, appended
 * to the search directory.  The pattern is anything following the
 * final forward or backward slash in the parameter.  If no slash
 * is found, the current directory is searched.
 * @param result Array to use when storing the results
 * @param p The pool to use.
 * @return APR_SUCCESS if no processing errors occurred, APR error
 * code otherwise
 * @remark The returned array may be empty even if APR_SUCCESS was
 * returned.
 */
APR_DECLARE(apr_status_t) apr_match_glob(const char *dir_pattern, 
                                         apr_array_header_t **result,
                                         apr_pool_t *p);

/** @} */

#ifdef __cplusplus
}
#endif

#endif /* !_APR_FNMATCH_H_ */
apr-1/apr_strmatch.h000064400000005165151730340570010340 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_STRMATCH_H
#define APR_STRMATCH_H
/**
 * @file apr_strmatch.h
 * @brief APR-UTIL string matching routines
 */

#include "apu.h"
#include "apr_pools.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @defgroup APR_Util_StrMatch String matching routines
 * @ingroup APR_Util
 * @{
 */

/** @see apr_strmatch_pattern */
typedef struct apr_strmatch_pattern apr_strmatch_pattern;

/**
 * Precompiled search pattern
 */
struct apr_strmatch_pattern {
    /** Function called to compare */
    const char *(*compare)(const apr_strmatch_pattern *this_pattern,
                           const char *s, apr_size_t slen);
    const char *pattern;    /**< Current pattern */
    apr_size_t length;      /**< Current length */
    void *context;          /**< hook to add precomputed metadata */
};

#if defined(DOXYGEN)
/**
 * Search for a precompiled pattern within a string
 * @param pattern The pattern
 * @param s The string in which to search for the pattern
 * @param slen The length of s (excluding null terminator)
 * @return A pointer to the first instance of the pattern in s, or
 *         NULL if not found
 */
APU_DECLARE(const char *) apr_strmatch(const apr_strmatch_pattern *pattern,
                                       const char *s, apr_size_t slen);
#else
#define apr_strmatch(pattern, s, slen) (*((pattern)->compare))((pattern), (s), (slen))
#endif

/**
 * Precompile a pattern for matching using the Boyer-Moore-Horspool algorithm
 * @param p The pool from which to allocate the pattern
 * @param s The pattern string
 * @param case_sensitive Whether the matching should be case-sensitive
 * @return a pointer to the compiled pattern, or NULL if compilation fails
 */
APU_DECLARE(const apr_strmatch_pattern *) apr_strmatch_precompile(apr_pool_t *p, const char *s, int case_sensitive);

/** @} */
#ifdef __cplusplus
}
#endif

#endif	/* !APR_STRMATCH_H */
apr-1/apr_ring.h000064400000045432151730340570007453 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * This code draws heavily from the 4.4BSD <sys/queue.h> macros
 * and Dean Gaudet's "splim/ring.h".
 * <http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/sys/queue.h>
 * <http://www.arctic.org/~dean/splim/>
 *
 * We'd use Dean's code directly if we could guarantee the
 * availability of inline functions.
 */

#ifndef APR_RING_H
#define APR_RING_H

/**
 * @file apr_ring.h
 * @brief APR Rings
 */

/*
 * for offsetof()
 */
#include "apr_general.h"

/**
 * @defgroup apr_ring Ring Macro Implementations
 * @ingroup APR 
 * A ring is a kind of doubly-linked list that can be manipulated
 * without knowing where its head is.
 * @{
 */

/**
 * The Ring Element
 *
 * A ring element struct is linked to the other elements in the ring
 * through its ring entry field, e.g.
 * <pre>
 *      struct my_element_t {
 *          APR_RING_ENTRY(my_element_t) link;
 *          int foo;
 *          char *bar;
 *      };
 * </pre>
 *
 * An element struct may be put on more than one ring if it has more
 * than one APR_RING_ENTRY field. Each APR_RING_ENTRY has a corresponding
 * APR_RING_HEAD declaration.
 *
 * @warning For strict C standards compliance you should put the APR_RING_ENTRY
 * first in the element struct unless the head is always part of a larger
 * object with enough earlier fields to accommodate the offsetof() used
 * to compute the ring sentinel below. You can usually ignore this caveat.
 */
#define APR_RING_ENTRY(elem)						\
    struct {								\
	struct elem * volatile next;					\
	struct elem * volatile prev;					\
    }

/**
 * The Ring Head
 *
 * Each ring is managed via its head, which is a struct declared like this:
 * <pre>
 *      APR_RING_HEAD(my_ring_t, my_element_t);
 *      struct my_ring_t ring, *ringp;
 * </pre>
 *
 * This struct looks just like the element link struct so that we can
 * be sure that the typecasting games will work as expected.
 *
 * The first element in the ring is next after the head, and the last
 * element is just before the head.
 */
#define APR_RING_HEAD(head, elem)					\
    struct head {							\
	struct elem * volatile next;					\
	struct elem * volatile prev;					\
    }

/**
 * The Ring Sentinel
 *
 * This is the magic pointer value that occurs before the first and
 * after the last elements in the ring, computed from the address of
 * the ring's head.  The head itself isn't an element, but in order to
 * get rid of all the special cases when dealing with the ends of the
 * ring, we play typecasting games to make it look like one.
 *
 * Here is a diagram to illustrate the arrangements of the next and
 * prev pointers of each element in a single ring. Note that they point
 * to the start of each element, not to the APR_RING_ENTRY structure.
 *
 * <pre>
 *     +->+------+<-+  +->+------+<-+  +->+------+<-+
 *     |  |struct|  |  |  |struct|  |  |  |struct|  |
 *    /   | elem |   \/   | elem |   \/   | elem |  \
 * ...    |      |   /\   |      |   /\   |      |   ...
 *        +------+  |  |  +------+  |  |  +------+
 *   ...--|prev  |  |  +--|ring  |  |  +--|prev  |
 *        |  next|--+     | entry|--+     |  next|--...
 *        +------+        +------+        +------+
 *        | etc. |        | etc. |        | etc. |
 *        :      :        :      :        :      :
 * </pre>
 *
 * The APR_RING_HEAD is nothing but a bare APR_RING_ENTRY. The prev
 * and next pointers in the first and last elements don't actually
 * point to the head, they point to a phantom place called the
 * sentinel. Its value is such that last->next->next == first because
 * the offset from the sentinel to the head's next pointer is the same
 * as the offset from the start of an element to its next pointer.
 * This also works in the opposite direction.
 *
 * <pre>
 *        last                            first
 *     +->+------+<-+  +->sentinel<-+  +->+------+<-+
 *     |  |struct|  |  |            |  |  |struct|  |
 *    /   | elem |   \/              \/   | elem |  \
 * ...    |      |   /\              /\   |      |   ...
 *        +------+  |  |  +------+  |  |  +------+
 *   ...--|prev  |  |  +--|ring  |  |  +--|prev  |
 *        |  next|--+     |  head|--+     |  next|--...
 *        +------+        +------+        +------+
 *        | etc. |                        | etc. |
 *        :      :                        :      :
 * </pre>
 *
 * Note that the offset mentioned above is different for each kind of
 * ring that the element may be on, and each kind of ring has a unique
 * name for its APR_RING_ENTRY in each element, and has its own type
 * for its APR_RING_HEAD.
 *
 * Note also that if the offset is non-zero (which is required if an
 * element has more than one APR_RING_ENTRY), the unreality of the
 * sentinel may have bad implications on very perverse implementations
 * of C -- see the warning in APR_RING_ENTRY.
 *
 * @param hp   The head of the ring
 * @param elem The name of the element struct
 * @param link The name of the APR_RING_ENTRY in the element struct
 */
#define APR_RING_SENTINEL(hp, elem, link)				\
    (struct elem *)((char *)(&(hp)->next) - APR_OFFSETOF(struct elem, link))

/**
 * The first element of the ring
 * @param hp   The head of the ring
 */
#define APR_RING_FIRST(hp)	(hp)->next
/**
 * The last element of the ring
 * @param hp   The head of the ring
 */
#define APR_RING_LAST(hp)	(hp)->prev
/**
 * The next element in the ring
 * @param ep   The current element
 * @param link The name of the APR_RING_ENTRY in the element struct
 */
#define APR_RING_NEXT(ep, link)	(ep)->link.next
/**
 * The previous element in the ring
 * @param ep   The current element
 * @param link The name of the APR_RING_ENTRY in the element struct
 */
#define APR_RING_PREV(ep, link)	(ep)->link.prev


/**
 * Initialize a ring
 * @param hp   The head of the ring
 * @param elem The name of the element struct
 * @param link The name of the APR_RING_ENTRY in the element struct
 */
#define APR_RING_INIT(hp, elem, link) do {				\
	APR_RING_FIRST((hp)) = APR_RING_SENTINEL((hp), elem, link);	\
	APR_RING_LAST((hp))  = APR_RING_SENTINEL((hp), elem, link);	\
    } while (0)

/**
 * Determine if a ring is empty
 * @param hp   The head of the ring
 * @param elem The name of the element struct
 * @param link The name of the APR_RING_ENTRY in the element struct
 * @return true or false
 */
#define APR_RING_EMPTY(hp, elem, link)					\
    (APR_RING_FIRST((hp)) == APR_RING_SENTINEL((hp), elem, link))

/**
 * Initialize a singleton element
 * @param ep   The element
 * @param link The name of the APR_RING_ENTRY in the element struct
 */
#define APR_RING_ELEM_INIT(ep, link) do {				\
	APR_RING_NEXT((ep), link) = (ep);				\
	APR_RING_PREV((ep), link) = (ep);				\
    } while (0)


/**
 * Splice the sequence ep1..epN into the ring before element lep
 *   (..lep.. becomes ..ep1..epN..lep..)
 * @warning This doesn't work for splicing before the first element or on
 *   empty rings... see APR_RING_SPLICE_HEAD for one that does
 * @param lep  Element in the ring to splice before
 * @param ep1  First element in the sequence to splice in
 * @param epN  Last element in the sequence to splice in
 * @param link The name of the APR_RING_ENTRY in the element struct
 */
#define APR_RING_SPLICE_BEFORE(lep, ep1, epN, link) do {		\
	APR_RING_NEXT((epN), link) = (lep);				\
	APR_RING_PREV((ep1), link) = APR_RING_PREV((lep), link);	\
	APR_RING_NEXT(APR_RING_PREV((lep), link), link) = (ep1);	\
	APR_RING_PREV((lep), link) = (epN);				\
    } while (0)

/**
 * Splice the sequence ep1..epN into the ring after element lep
 *   (..lep.. becomes ..lep..ep1..epN..)
 * @warning This doesn't work for splicing after the last element or on
 *   empty rings... see APR_RING_SPLICE_TAIL for one that does
 * @param lep  Element in the ring to splice after
 * @param ep1  First element in the sequence to splice in
 * @param epN  Last element in the sequence to splice in
 * @param link The name of the APR_RING_ENTRY in the element struct
 */
#define APR_RING_SPLICE_AFTER(lep, ep1, epN, link) do {			\
	APR_RING_PREV((ep1), link) = (lep);				\
	APR_RING_NEXT((epN), link) = APR_RING_NEXT((lep), link);	\
	APR_RING_PREV(APR_RING_NEXT((lep), link), link) = (epN);	\
	APR_RING_NEXT((lep), link) = (ep1);				\
    } while (0)

/**
 * Insert the element nep into the ring before element lep
 *   (..lep.. becomes ..nep..lep..)
 * @warning This doesn't work for inserting before the first element or on
 *   empty rings... see APR_RING_INSERT_HEAD for one that does
 * @param lep  Element in the ring to insert before
 * @param nep  Element to insert
 * @param link The name of the APR_RING_ENTRY in the element struct
 */
#define APR_RING_INSERT_BEFORE(lep, nep, link)				\
	APR_RING_SPLICE_BEFORE((lep), (nep), (nep), link)

/**
 * Insert the element nep into the ring after element lep
 *   (..lep.. becomes ..lep..nep..)
 * @warning This doesn't work for inserting after the last element or on
 *   empty rings... see APR_RING_INSERT_TAIL for one that does
 * @param lep  Element in the ring to insert after
 * @param nep  Element to insert
 * @param link The name of the APR_RING_ENTRY in the element struct
 */
#define APR_RING_INSERT_AFTER(lep, nep, link)				\
	APR_RING_SPLICE_AFTER((lep), (nep), (nep), link)


/**
 * Splice the sequence ep1..epN into the ring before the first element
 *   (..hp.. becomes ..hp..ep1..epN..)
 * @param hp   Head of the ring
 * @param ep1  First element in the sequence to splice in
 * @param epN  Last element in the sequence to splice in
 * @param elem The name of the element struct
 * @param link The name of the APR_RING_ENTRY in the element struct
 */
#define APR_RING_SPLICE_HEAD(hp, ep1, epN, elem, link) do {		\
	APR_RING_PREV((ep1), link) = APR_RING_SENTINEL((hp), elem, link);\
	APR_RING_NEXT((epN), link) = APR_RING_FIRST((hp));		\
	APR_RING_PREV(APR_RING_FIRST((hp)), link) = (epN);		\
	APR_RING_FIRST((hp)) = (ep1);					\
    } while (0)

/**
 * Splice the sequence ep1..epN into the ring after the last element
 *   (..hp.. becomes ..ep1..epN..hp..)
 * @param hp   Head of the ring
 * @param ep1  First element in the sequence to splice in
 * @param epN  Last element in the sequence to splice in
 * @param elem The name of the element struct
 * @param link The name of the APR_RING_ENTRY in the element struct
 */
#define APR_RING_SPLICE_TAIL(hp, ep1, epN, elem, link) do {		\
	APR_RING_NEXT((epN), link) = APR_RING_SENTINEL((hp), elem, link);\
	APR_RING_PREV((ep1), link) = APR_RING_LAST((hp));		\
	APR_RING_NEXT(APR_RING_LAST((hp)), link) = (ep1);		\
	APR_RING_LAST((hp)) = (epN);					\
    } while (0)

/**
 * Insert the element nep into the ring before the first element
 *   (..hp.. becomes ..hp..nep..)
 * @param hp   Head of the ring
 * @param nep  Element to insert
 * @param elem The name of the element struct
 * @param link The name of the APR_RING_ENTRY in the element struct
 */
#define APR_RING_INSERT_HEAD(hp, nep, elem, link)			\
	APR_RING_SPLICE_HEAD((hp), (nep), (nep), elem, link)

/**
 * Insert the element nep into the ring after the last element
 *   (..hp.. becomes ..nep..hp..)
 * @param hp   Head of the ring
 * @param nep  Element to insert
 * @param elem The name of the element struct
 * @param link The name of the APR_RING_ENTRY in the element struct
 */
#define APR_RING_INSERT_TAIL(hp, nep, elem, link)			\
	APR_RING_SPLICE_TAIL((hp), (nep), (nep), elem, link)

/**
 * Concatenate ring h2 onto the end of ring h1, leaving h2 empty.
 * @param h1   Head of the ring to concatenate onto
 * @param h2   Head of the ring to concatenate
 * @param elem The name of the element struct
 * @param link The name of the APR_RING_ENTRY in the element struct
 */
#define APR_RING_CONCAT(h1, h2, elem, link) do {			\
	if (!APR_RING_EMPTY((h2), elem, link)) {			\
	    APR_RING_SPLICE_TAIL((h1), APR_RING_FIRST((h2)),		\
				 APR_RING_LAST((h2)), elem, link);	\
	    APR_RING_INIT((h2), elem, link);				\
	}								\
    } while (0)

/**
 * Prepend ring h2 onto the beginning of ring h1, leaving h2 empty.
 * @param h1   Head of the ring to prepend onto
 * @param h2   Head of the ring to prepend
 * @param elem The name of the element struct
 * @param link The name of the APR_RING_ENTRY in the element struct
 */
#define APR_RING_PREPEND(h1, h2, elem, link) do {			\
	if (!APR_RING_EMPTY((h2), elem, link)) {			\
	    APR_RING_SPLICE_HEAD((h1), APR_RING_FIRST((h2)),		\
				 APR_RING_LAST((h2)), elem, link);	\
	    APR_RING_INIT((h2), elem, link);				\
	}								\
    } while (0)

/**
 * Unsplice a sequence of elements from a ring
 * @warning The unspliced sequence is left with dangling pointers at either end
 * @param ep1  First element in the sequence to unsplice
 * @param epN  Last element in the sequence to unsplice
 * @param link The name of the APR_RING_ENTRY in the element struct
 */
#define APR_RING_UNSPLICE(ep1, epN, link) do {				\
	APR_RING_NEXT(APR_RING_PREV((ep1), link), link) =		\
		     APR_RING_NEXT((epN), link);			\
	APR_RING_PREV(APR_RING_NEXT((epN), link), link) =		\
		     APR_RING_PREV((ep1), link);			\
    } while (0)

/**
 * Remove a single element from a ring
 * @warning The unspliced element is left with dangling pointers at either end
 * @param ep   Element to remove
 * @param link The name of the APR_RING_ENTRY in the element struct
 */
#define APR_RING_REMOVE(ep, link)					\
    APR_RING_UNSPLICE((ep), (ep), link)

/**
 * Iterate over a ring
 * @param ep The current element
 * @param head The head of the ring
 * @param elem The name of the element struct
 * @param link The name of the APR_RING_ENTRY in the element struct
 */
#define APR_RING_FOREACH(ep, head, elem, link)                          \
    for (ep = APR_RING_FIRST(head);                                     \
         ep != APR_RING_SENTINEL(head, elem, link);                     \
         ep = APR_RING_NEXT(ep, link))

/**
 * Iterate over a ring safe against removal of the current element
 * @param ep1 The current element
 * @param ep2 Iteration cursor
 * @param head The head of the ring
 * @param elem The name of the element struct
 * @param link The name of the APR_RING_ENTRY in the element struct
 */
#define APR_RING_FOREACH_SAFE(ep1, ep2, head, elem, link)               \
    for (ep1 = APR_RING_FIRST(head), ep2 = APR_RING_NEXT(ep1, link);    \
         ep1 != APR_RING_SENTINEL(head, elem, link);                    \
         ep1 = ep2, ep2 = APR_RING_NEXT(ep1, link))

/* Debugging tools: */

#ifdef APR_RING_DEBUG
#include <stdio.h>
#include <assert.h>

#define APR_RING_CHECK_ONE(msg, ptr)					\
	fprintf(stderr, "*** %s %p\n", msg, ptr)

#define APR_RING_CHECK(hp, elem, link, msg)				\
	APR_RING_CHECK_ELEM(APR_RING_SENTINEL(hp, elem, link), elem, link, msg)

#define APR_RING_CHECK_ELEM(ep, elem, link, msg) do {			\
	struct elem *start = (ep);					\
	struct elem *here = start;					\
	fprintf(stderr, "*** ring check start -- %s\n", msg);		\
	do {								\
	    fprintf(stderr, "\telem %p\n", here);			\
	    fprintf(stderr, "\telem->next %p\n",			\
		    APR_RING_NEXT(here, link));				\
	    fprintf(stderr, "\telem->prev %p\n",			\
		    APR_RING_PREV(here, link));				\
	    fprintf(stderr, "\telem->next->prev %p\n",			\
		    APR_RING_PREV(APR_RING_NEXT(here, link), link));	\
	    fprintf(stderr, "\telem->prev->next %p\n",			\
		    APR_RING_NEXT(APR_RING_PREV(here, link), link));	\
	    if (APR_RING_PREV(APR_RING_NEXT(here, link), link) != here) { \
		fprintf(stderr, "\t*** elem->next->prev != elem\n");	\
		break;							\
	    }								\
	    if (APR_RING_NEXT(APR_RING_PREV(here, link), link) != here) { \
		fprintf(stderr, "\t*** elem->prev->next != elem\n");	\
		break;							\
	    }								\
	    here = APR_RING_NEXT(here, link);				\
	} while (here != start);					\
	fprintf(stderr, "*** ring check end\n");			\
    } while (0)

#define APR_RING_CHECK_CONSISTENCY(hp, elem, link)			\
	APR_RING_CHECK_ELEM_CONSISTENCY(APR_RING_SENTINEL(hp, elem, link),\
					elem, link)

#define APR_RING_CHECK_ELEM_CONSISTENCY(ep, elem, link) do {		\
	struct elem *start = (ep);					\
	struct elem *here = start;					\
	do {								\
	    assert(APR_RING_PREV(APR_RING_NEXT(here, link), link) == here); \
	    assert(APR_RING_NEXT(APR_RING_PREV(here, link), link) == here); \
	    here = APR_RING_NEXT(here, link);				\
	} while (here != start);					\
    } while (0)

#else
/**
 * Print a single pointer value to STDERR
 *   (This is a no-op unless APR_RING_DEBUG is defined.)
 * @param msg Descriptive message
 * @param ptr Pointer value to print
 */
#define APR_RING_CHECK_ONE(msg, ptr)
/**
 * Dump all ring pointers to STDERR, starting with the head and looping all
 * the way around the ring back to the head.  Aborts if an inconsistency
 * is found.
 *   (This is a no-op unless APR_RING_DEBUG is defined.)
 * @param hp   Head of the ring
 * @param elem The name of the element struct
 * @param link The name of the APR_RING_ENTRY in the element struct
 * @param msg  Descriptive message
 */
#define APR_RING_CHECK(hp, elem, link, msg)
/**
 * Loops around a ring and checks all the pointers for consistency.  Pops
 * an assertion if any inconsistency is found.  Same idea as APR_RING_CHECK()
 * except that it's silent if all is well.
 *   (This is a no-op unless APR_RING_DEBUG is defined.)
 * @param hp   Head of the ring
 * @param elem The name of the element struct
 * @param link The name of the APR_RING_ENTRY in the element struct
 */
#define APR_RING_CHECK_CONSISTENCY(hp, elem, link)
/**
 * Dump all ring pointers to STDERR, starting with the given element and
 * looping all the way around the ring back to that element.  Aborts if
 * an inconsistency is found.
 *   (This is a no-op unless APR_RING_DEBUG is defined.)
 * @param ep   The element
 * @param elem The name of the element struct
 * @param link The name of the APR_RING_ENTRY in the element struct
 * @param msg  Descriptive message
 */
#define APR_RING_CHECK_ELEM(ep, elem, link, msg)
/**
 * Loops around a ring, starting with the given element, and checks all
 * the pointers for consistency.  Pops an assertion if any inconsistency
 * is found.  Same idea as APR_RING_CHECK_ELEM() except that it's silent
 * if all is well.
 *   (This is a no-op unless APR_RING_DEBUG is defined.)
 * @param ep   The element
 * @param elem The name of the element struct
 * @param link The name of the APR_RING_ENTRY in the element struct
 */
#define APR_RING_CHECK_ELEM_CONSISTENCY(ep, elem, link)
#endif

/** @} */ 

#endif /* !APR_RING_H */
apr-1/apr_crypto.h000064400000047275151730340570010043 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_CRYPTO_H
#define APR_CRYPTO_H

#include "apu.h"
#include "apr_pools.h"
#include "apr_tables.h"
#include "apr_hash.h"
#include "apu_errno.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @file apr_crypto.h
 * @brief APR-UTIL Crypto library
 */
/**
 * @defgroup APR_Util_Crypto Crypto routines
 * @ingroup APR_Util
 * @{
 */

#if APU_HAVE_CRYPTO

#ifndef APU_CRYPTO_RECOMMENDED_DRIVER
#if APU_HAVE_COMMONCRYPTO
#define APU_CRYPTO_RECOMMENDED_DRIVER "commoncrypto"
#else
#if APU_HAVE_OPENSSL
#define APU_CRYPTO_RECOMMENDED_DRIVER "openssl"
#else
#if APU_HAVE_NSS
#define APU_CRYPTO_RECOMMENDED_DRIVER "nss"
#else
#if APU_HAVE_MSCNG
#define APU_CRYPTO_RECOMMENDED_DRIVER "mscng"
#else
#if APU_HAVE_MSCAPI
#define APU_CRYPTO_RECOMMENDED_DRIVER "mscapi"
#else
#endif
#endif
#endif
#endif
#endif
#endif

/**
 * Symmetric Key types understood by the library.
 *
 * NOTE: It is expected that this list will grow over time.
 *
 * Interoperability Matrix:
 *
 * The matrix is based on the testcrypto.c unit test, which attempts to
 * test whether a simple encrypt/decrypt will succeed, as well as testing
 * whether an encrypted string by one library can be decrypted by the
 * others.
 *
 * Some libraries will successfully encrypt and decrypt their own data,
 * but won't decrypt data from another library. It is hoped that over
 * time these anomalies will be found and fixed, but until then it is
 * recommended that ciphers are chosen that interoperate across platform.
 *
 * An X below means the test passes, it does not necessarily mean that
 * encryption performed is correct or secure. Applications should stick
 * to ciphers that pass the interoperablity tests on the right hand side
 * of the table.
 *
 * Aligned data is data whose length is a multiple of the block size for
 * the chosen cipher. Padded data is data that is not aligned by block
 * size and must be padded by the crypto library.
 *
 *                  OpenSSL    CommonCrypto   NSS       Interop
 *                 Align  Pad  Align  Pad  Align  Pad  Align  Pad
 * 3DES_192/CBC    X      X    X      X    X      X    X      X
 * 3DES_192/ECB    X      X    X      X
 * AES_256/CBC     X      X    X      X    X      X    X      X
 * AES_256/ECB     X      X    X      X    X           X
 * AES_192/CBC     X      X    X      X    X      X
 * AES_192/ECB     X      X    X      X    X
 * AES_128/CBC     X      X    X      X    X      X
 * AES_128/ECB     X      X    X      X    X
 *
 * Conclusion: for padded data, use 3DES_192/CBC or AES_256/CBC. For
 * aligned data, use 3DES_192/CBC, AES_256/CBC or AES_256/ECB.
 */

typedef enum
{
    APR_KEY_NONE, APR_KEY_3DES_192, /** 192 bit (3-Key) 3DES */
    APR_KEY_AES_128, /** 128 bit AES */
    APR_KEY_AES_192, /** 192 bit AES */
    APR_KEY_AES_256
/** 256 bit AES */
} apr_crypto_block_key_type_e;

typedef enum
{
    APR_MODE_NONE, /** An error condition */
    APR_MODE_ECB, /** Electronic Code Book */
    APR_MODE_CBC
/** Cipher Block Chaining */
} apr_crypto_block_key_mode_e;

/* These are opaque structs.  Instantiation is up to each backend */
typedef struct apr_crypto_driver_t apr_crypto_driver_t;
typedef struct apr_crypto_t apr_crypto_t;
typedef struct apr_crypto_config_t apr_crypto_config_t;
typedef struct apr_crypto_key_t apr_crypto_key_t;
typedef struct apr_crypto_block_t apr_crypto_block_t;

typedef struct apr_crypto_block_key_type_t {
    apr_crypto_block_key_type_e type;
    int keysize;
    int blocksize;
    int ivsize;
} apr_crypto_block_key_type_t;

typedef struct apr_crypto_block_key_mode_t {
    apr_crypto_block_key_mode_e mode;
} apr_crypto_block_key_mode_t;

typedef struct apr_crypto_passphrase_t {
    const char *pass;
    apr_size_t passLen;
    const unsigned char * salt;
    apr_size_t saltLen;
    int iterations;
} apr_crypto_passphrase_t;

typedef struct apr_crypto_secret_t {
    const unsigned char *secret;
    apr_size_t secretLen;
} apr_crypto_secret_t;

typedef enum {
    /** Key is derived from a passphrase */
    APR_CRYPTO_KTYPE_PASSPHRASE     = 1,
    /** Key is derived from a raw key */
    APR_CRYPTO_KTYPE_SECRET     = 2,
} apr_crypto_key_type;

typedef struct apr_crypto_key_rec_t {
    apr_crypto_key_type ktype;
    apr_crypto_block_key_type_e type;
    apr_crypto_block_key_mode_e mode;
    int pad;
    union {
        apr_crypto_passphrase_t passphrase;
        apr_crypto_secret_t secret;
    } k;
} apr_crypto_key_rec_t;

/**
 * @brief Perform once-only initialisation. Call once only.
 *
 * @param pool - pool to register any shutdown cleanups, etc
 * @return APR_NOTIMPL in case of no crypto support.
 */
APU_DECLARE(apr_status_t) apr_crypto_init(apr_pool_t *pool);

/**
 * @brief Zero out the buffer provided when the pool is cleaned up.
 *
 * @param pool - pool to register the cleanup
 * @param buffer - buffer to zero out
 * @param size - size of the buffer to zero out
 */
APU_DECLARE(apr_status_t) apr_crypto_clear(apr_pool_t *pool, void *buffer,
        apr_size_t size);

/**
 * @brief Always zero out the buffer provided, without being optimized out by
 * the compiler.
 *
 * @param buffer - buffer to zero out
 * @param size - size of the buffer to zero out
 */
APU_DECLARE(apr_status_t) apr_crypto_memzero(void *buffer, apr_size_t size);

/**
 * @brief Timing attacks safe buffers comparison, where the executing time does
 * not depend on the bytes compared but solely on the number of bytes.
 *
 * @param buf1 - first buffer to compare
 * @param buf2 - second buffer to compare
 * @param size - size of the buffers to compare
 * @return 1 if the buffers are equals, 0 otherwise.
 */
APU_DECLARE(int) apr_crypto_equals(const void *buf1, const void *buf2,
                                   apr_size_t size);

/**
 * @brief Get the driver struct for a name
 *
 * @param driver - pointer to driver struct.
 * @param name - driver name
 * @param params - array of initialisation parameters
 * @param result - result and error message on failure
 * @param pool - (process) pool to register cleanup
 * @return APR_SUCCESS for success
 * @return APR_ENOTIMPL for no driver (when DSO not enabled)
 * @return APR_EDSOOPEN if DSO driver file can't be opened
 * @return APR_ESYMNOTFOUND if the driver file doesn't contain a driver
 * @remarks NSS: the params can have "dir", "key3", "cert7" and "secmod"
 *  keys, each followed by an equal sign and a value. Such key/value pairs can
 *  be delimited by space or tab. If the value contains a space, surround the
 *  whole key value pair in quotes: "dir=My Directory".
 * @remarks OpenSSL: currently no params are supported.
 */
APU_DECLARE(apr_status_t) apr_crypto_get_driver(
        const apr_crypto_driver_t **driver,
        const char *name, const char *params, const apu_err_t **result,
        apr_pool_t *pool);

/**
 * @brief Return the name of the driver.
 *
 * @param driver - The driver in use.
 * @return The name of the driver.
 */
APU_DECLARE(const char *) apr_crypto_driver_name(
        const apr_crypto_driver_t *driver);

/**
 * @brief Get the result of the last operation on a context. If the result
 *        is NULL, the operation was successful.
 * @param result - the result structure
 * @param f - context pointer
 * @return APR_SUCCESS for success
 */
APU_DECLARE(apr_status_t) apr_crypto_error(const apu_err_t **result,
        const apr_crypto_t *f);

/**
 * @brief Create a context for supporting encryption. Keys, certificates,
 *        algorithms and other parameters will be set per context. More than
 *        one context can be created at one time. A cleanup will be automatically
 *        registered with the given pool to guarantee a graceful shutdown.
 * @param f - context pointer will be written here
 * @param driver - driver to use
 * @param params - array of key parameters
 * @param pool - process pool
 * @return APR_ENOENGINE when the engine specified does not exist. APR_EINITENGINE
 * if the engine cannot be initialised.
 * @remarks NSS: currently no params are supported.
 * @remarks OpenSSL: the params can have "engine" as a key, followed by an equal
 *  sign and a value.
 */
APU_DECLARE(apr_status_t) apr_crypto_make(apr_crypto_t **f,
        const apr_crypto_driver_t *driver, const char *params,
        apr_pool_t *pool);

/**
 * @brief Get a hash table of key types, keyed by the name of the type against
 * a pointer to apr_crypto_block_key_type_t, which in turn begins with an
 * integer.
 *
 * @param types - hashtable of key types keyed to constants.
 * @param f - encryption context
 * @return APR_SUCCESS for success
 */
APU_DECLARE(apr_status_t) apr_crypto_get_block_key_types(apr_hash_t **types,
        const apr_crypto_t *f);

/**
 * @brief Get a hash table of key modes, keyed by the name of the mode against
 * a pointer to apr_crypto_block_key_mode_t, which in turn begins with an
 * integer.
 *
 * @param modes - hashtable of key modes keyed to constants.
 * @param f - encryption context
 * @return APR_SUCCESS for success
 */
APU_DECLARE(apr_status_t) apr_crypto_get_block_key_modes(apr_hash_t **modes,
        const apr_crypto_t *f);

/**
 * @brief Create a key from the provided secret or passphrase. The key is cleaned
 *        up when the context is cleaned, and may be reused with multiple encryption
 *        or decryption operations.
 * @note If *key is NULL, a apr_crypto_key_t will be created from a pool. If
 *       *key is not NULL, *key must point at a previously created structure.
 * @param key The key returned, see note.
 * @param rec The key record, from which the key will be derived.
 * @param f The context to use.
 * @param p The pool to use.
 * @return Returns APR_ENOKEY if the pass phrase is missing or empty, or if a backend
 *         error occurred while generating the key. APR_ENOCIPHER if the type or mode
 *         is not supported by the particular backend. APR_EKEYTYPE if the key type is
 *         not known. APR_EPADDING if padding was requested but is not supported.
 *         APR_ENOTIMPL if not implemented.
 */
APU_DECLARE(apr_status_t) apr_crypto_key(apr_crypto_key_t **key,
        const apr_crypto_key_rec_t *rec, const apr_crypto_t *f, apr_pool_t *p);

/**
 * @brief Create a key from the given passphrase. By default, the PBKDF2
 *        algorithm is used to generate the key from the passphrase. It is expected
 *        that the same pass phrase will generate the same key, regardless of the
 *        backend crypto platform used. The key is cleaned up when the context
 *        is cleaned, and may be reused with multiple encryption or decryption
 *        operations.
 * @note If *key is NULL, a apr_crypto_key_t will be created from a pool. If
 *       *key is not NULL, *key must point at a previously created structure.
 * @param key The key returned, see note.
 * @param ivSize The size of the initialisation vector will be returned, based
 *               on whether an IV is relevant for this type of crypto.
 * @param pass The passphrase to use.
 * @param passLen The passphrase length in bytes
 * @param salt The salt to use.
 * @param saltLen The salt length in bytes
 * @param type 3DES_192, AES_128, AES_192, AES_256.
 * @param mode Electronic Code Book / Cipher Block Chaining.
 * @param doPad Pad if necessary.
 * @param iterations Number of iterations to use in algorithm
 * @param f The context to use.
 * @param p The pool to use.
 * @return Returns APR_ENOKEY if the pass phrase is missing or empty, or if a backend
 *         error occurred while generating the key. APR_ENOCIPHER if the type or mode
 *         is not supported by the particular backend. APR_EKEYTYPE if the key type is
 *         not known. APR_EPADDING if padding was requested but is not supported.
 *         APR_ENOTIMPL if not implemented.
 * @deprecated Replaced by apr_crypto_key().
 */
APU_DECLARE(apr_status_t) apr_crypto_passphrase(apr_crypto_key_t **key,
        apr_size_t *ivSize, const char *pass, apr_size_t passLen,
        const unsigned char * salt, apr_size_t saltLen,
        const apr_crypto_block_key_type_e type,
        const apr_crypto_block_key_mode_e mode, const int doPad,
        const int iterations, const apr_crypto_t *f, apr_pool_t *p);

/**
 * @brief Initialise a context for encrypting arbitrary data using the given key.
 * @note If *ctx is NULL, a apr_crypto_block_t will be created from a pool. If
 *       *ctx is not NULL, *ctx must point at a previously created structure.
 * @param ctx The block context returned, see note.
 * @param iv Optional initialisation vector. If the buffer pointed to is NULL,
 *           an IV will be created at random, in space allocated from the pool.
 *           If the buffer pointed to is not NULL, the IV in the buffer will be
 *           used.
 * @param key The key structure to use.
 * @param blockSize The block size of the cipher.
 * @param p The pool to use.
 * @return Returns APR_ENOIV if an initialisation vector is required but not specified.
 *         Returns APR_EINIT if the backend failed to initialise the context. Returns
 *         APR_ENOTIMPL if not implemented.
 */
APU_DECLARE(apr_status_t) apr_crypto_block_encrypt_init(
        apr_crypto_block_t **ctx, const unsigned char **iv,
        const apr_crypto_key_t *key, apr_size_t *blockSize, apr_pool_t *p);

/**
 * @brief Encrypt data provided by in, write it to out.
 * @note The number of bytes written will be written to outlen. If
 *       out is NULL, outlen will contain the maximum size of the
 *       buffer needed to hold the data, including any data
 *       generated by apr_crypto_block_encrypt_finish below. If *out points
 *       to NULL, a buffer sufficiently large will be created from
 *       the pool provided. If *out points to a not-NULL value, this
 *       value will be used as a buffer instead.
 * @param out Address of a buffer to which data will be written,
 *        see note.
 * @param outlen Length of the output will be written here.
 * @param in Address of the buffer to read.
 * @param inlen Length of the buffer to read.
 * @param ctx The block context to use.
 * @return APR_ECRYPT if an error occurred. Returns APR_ENOTIMPL if
 *         not implemented.
 */
APU_DECLARE(apr_status_t) apr_crypto_block_encrypt(unsigned char **out,
        apr_size_t *outlen, const unsigned char *in, apr_size_t inlen,
        apr_crypto_block_t *ctx);

/**
 * @brief Encrypt final data block, write it to out.
 * @note If necessary the final block will be written out after being
 *       padded. Typically the final block will be written to the
 *       same buffer used by apr_crypto_block_encrypt, offset by the
 *       number of bytes returned as actually written by the
 *       apr_crypto_block_encrypt() call. After this call, the context
 *       is cleaned and can be reused by apr_crypto_block_encrypt_init().
 * @param out Address of a buffer to which data will be written. This
 *            buffer must already exist, and is usually the same
 *            buffer used by apr_evp_crypt(). See note.
 * @param outlen Length of the output will be written here.
 * @param ctx The block context to use.
 * @return APR_ECRYPT if an error occurred.
 * @return APR_EPADDING if padding was enabled and the block was incorrectly
 *         formatted.
 * @return APR_ENOTIMPL if not implemented.
 */
APU_DECLARE(apr_status_t) apr_crypto_block_encrypt_finish(unsigned char *out,
        apr_size_t *outlen, apr_crypto_block_t *ctx);

/**
 * @brief Initialise a context for decrypting arbitrary data using the given key.
 * @note If *ctx is NULL, a apr_crypto_block_t will be created from a pool. If
 *       *ctx is not NULL, *ctx must point at a previously created structure.
 * @param ctx The block context returned, see note.
 * @param blockSize The block size of the cipher.
 * @param iv Optional initialisation vector.
 * @param key The key structure to use.
 * @param p The pool to use.
 * @return Returns APR_ENOIV if an initialisation vector is required but not specified.
 *         Returns APR_EINIT if the backend failed to initialise the context. Returns
 *         APR_ENOTIMPL if not implemented.
 */
APU_DECLARE(apr_status_t) apr_crypto_block_decrypt_init(
        apr_crypto_block_t **ctx, apr_size_t *blockSize,
        const unsigned char *iv, const apr_crypto_key_t *key, apr_pool_t *p);

/**
 * @brief Decrypt data provided by in, write it to out.
 * @note The number of bytes written will be written to outlen. If
 *       out is NULL, outlen will contain the maximum size of the
 *       buffer needed to hold the data, including any data
 *       generated by apr_crypto_block_decrypt_finish below. If *out points
 *       to NULL, a buffer sufficiently large will be created from
 *       the pool provided. If *out points to a not-NULL value, this
 *       value will be used as a buffer instead.
 * @param out Address of a buffer to which data will be written,
 *        see note.
 * @param outlen Length of the output will be written here.
 * @param in Address of the buffer to read.
 * @param inlen Length of the buffer to read.
 * @param ctx The block context to use.
 * @return APR_ECRYPT if an error occurred. Returns APR_ENOTIMPL if
 *         not implemented.
 */
APU_DECLARE(apr_status_t) apr_crypto_block_decrypt(unsigned char **out,
        apr_size_t *outlen, const unsigned char *in, apr_size_t inlen,
        apr_crypto_block_t *ctx);

/**
 * @brief Decrypt final data block, write it to out.
 * @note If necessary the final block will be written out after being
 *       padded. Typically the final block will be written to the
 *       same buffer used by apr_crypto_block_decrypt, offset by the
 *       number of bytes returned as actually written by the
 *       apr_crypto_block_decrypt() call. After this call, the context
 *       is cleaned and can be reused by apr_crypto_block_decrypt_init().
 * @param out Address of a buffer to which data will be written. This
 *            buffer must already exist, and is usually the same
 *            buffer used by apr_evp_crypt(). See note.
 * @param outlen Length of the output will be written here.
 * @param ctx The block context to use.
 * @return APR_ECRYPT if an error occurred.
 * @return APR_EPADDING if padding was enabled and the block was incorrectly
 *         formatted.
 * @return APR_ENOTIMPL if not implemented.
 */
APU_DECLARE(apr_status_t) apr_crypto_block_decrypt_finish(unsigned char *out,
        apr_size_t *outlen, apr_crypto_block_t *ctx);

/**
 * @brief Clean encryption / decryption context.
 * @note After cleanup, a context is free to be reused if necessary.
 * @param ctx The block context to use.
 * @return Returns APR_ENOTIMPL if not supported.
 */
APU_DECLARE(apr_status_t) apr_crypto_block_cleanup(apr_crypto_block_t *ctx);

/**
 * @brief Clean encryption / decryption context.
 * @note After cleanup, a context is free to be reused if necessary.
 * @param f The context to use.
 * @return Returns APR_ENOTIMPL if not supported.
 */
APU_DECLARE(apr_status_t) apr_crypto_cleanup(apr_crypto_t *f);

/**
 * @brief Shutdown the crypto library.
 * @note After shutdown, it is expected that the init function can be called again.
 * @param driver - driver to use
 * @return Returns APR_ENOTIMPL if not supported.
 */
APU_DECLARE(apr_status_t) apr_crypto_shutdown(
        const apr_crypto_driver_t *driver);

#endif /* APU_HAVE_CRYPTO */

/** @} */

#ifdef __cplusplus
}
#endif

#endif
apr-1/apr_pools.h000064400000075700151730340570007651 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef APR_POOLS_H
#define APR_POOLS_H

/**
 * @file apr_pools.h
 * @brief 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.
 *
 * Note that most operations on pools are not thread-safe: a single pool
 * should only be accessed by a single thread at any given time. The one
 * exception to this rule is creating a subpool of a given pool: one or more
 * threads can safely create subpools at the same time that another thread
 * accesses the parent pool.
 */

#include "apr.h"
#include "apr_errno.h"
#include "apr_general.h" /* for APR_STRINGIFY */
#define APR_WANT_MEMFUNC /**< for no good reason? */
#include "apr_want.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @defgroup apr_pools Memory Pool Functions
 * @ingroup APR 
 * @{
 */

/** The fundamental pool type */
typedef struct apr_pool_t apr_pool_t;


/**
 * Declaration helper macro to construct apr_foo_pool_get()s.
 *
 * This standardized macro is used by opaque (APR) data types to return
 * the apr_pool_t that is associated with the data type.
 *
 * APR_POOL_DECLARE_ACCESSOR() is used in a header file to declare the
 * accessor function. A typical usage and result would be:
 * <pre>
 *    APR_POOL_DECLARE_ACCESSOR(file);
 * becomes:
 *    APR_DECLARE(apr_pool_t *) apr_file_pool_get(const apr_file_t *thefile);
 * </pre>
 * @remark Doxygen unwraps this macro (via doxygen.conf) to provide 
 * actual help for each specific occurrence of apr_foo_pool_get.
 * @remark the linkage is specified for APR. It would be possible to expand
 *       the macros to support other linkages.
 */
#define APR_POOL_DECLARE_ACCESSOR(type) \
    APR_DECLARE(apr_pool_t *) apr_##type##_pool_get \
        (const apr_##type##_t *the##type)

/** 
 * Implementation helper macro to provide apr_foo_pool_get()s.
 *
 * In the implementation, the APR_POOL_IMPLEMENT_ACCESSOR() is used to
 * actually define the function. It assumes the field is named "pool".
 */
#define APR_POOL_IMPLEMENT_ACCESSOR(type) \
    APR_DECLARE(apr_pool_t *) apr_##type##_pool_get \
            (const apr_##type##_t *the##type) \
        { return the##type->pool; }


/**
 * Pool debug levels
 *
 * <pre>
 * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
 * ---------------------------------
 * |   |   |   |   |   |   |   | x |  General debug code enabled (useful in
 *                                    combination with --with-efence).
 *
 * |   |   |   |   |   |   | x |   |  Verbose output on stderr (report
 *                                    CREATE, CLEAR, DESTROY).
 *
 * |   |   |   | x |   |   |   |   |  Verbose output on stderr (report
 *                                    PALLOC, PCALLOC).
 *
 * |   |   |   |   |   | x |   |   |  Lifetime checking. On each use of a
 *                                    pool, check its lifetime.  If the pool
 *                                    is out of scope, abort().
 *                                    In combination with the verbose flag
 *                                    above, it will output LIFE in such an
 *                                    event prior to aborting.
 *
 * |   |   |   |   | x |   |   |   |  Pool owner checking.  On each use of a
 *                                    pool, check if the current thread is the
 *                                    pool's owner.  If not, abort().  In
 *                                    combination with the verbose flag above,
 *                                    it will output OWNER in such an event
 *                                    prior to aborting.  Use the debug
 *                                    function apr_pool_owner_set() to switch
 *                                    a pool's ownership.
 *
 * When no debug level was specified, assume general debug mode.
 * If level 0 was specified, debugging is switched off.
 * </pre>
 */
#if defined(APR_POOL_DEBUG)
/* If APR_POOL_DEBUG is blank, we get 1; if it is a number, we get -1. */
#if (APR_POOL_DEBUG - APR_POOL_DEBUG -1 == 1)
#undef APR_POOL_DEBUG
#define APR_POOL_DEBUG 1
#endif
#else
#define APR_POOL_DEBUG 0
#endif

/** the place in the code where the particular function was called */
#define APR_POOL__FILE_LINE__ __FILE__ ":" APR_STRINGIFY(__LINE__)



/** A function that is called when allocation fails. */
typedef int (*apr_abortfunc_t)(int retcode);

/*
 * APR memory structure manipulators (pools, tables, and arrays).
 */

/*
 * Initialization
 */

/**
 * Setup all of the internal structures required to use pools
 * @remark Programs do NOT need to call this directly.  APR will call this
 *      automatically from apr_initialize.
 * @internal
 */
APR_DECLARE(apr_status_t) apr_pool_initialize(void);

/**
 * Tear down all of the internal structures required to use pools
 * @remark Programs do NOT need to call this directly.  APR will call this
 *      automatically from apr_terminate.
 * @internal
 */
APR_DECLARE(void) apr_pool_terminate(void);


/*
 * Pool creation/destruction
 */

#include "apr_allocator.h"

/**
 * Create a new pool.
 * @param newpool The pool we have just created.
 * @param parent The parent pool.  If this is NULL, the new pool is a root
 *        pool.  If it is non-NULL, the new pool will inherit all
 *        of its parent pool's attributes, except the apr_pool_t will
 *        be a sub-pool.
 * @param abort_fn A function to use if the pool cannot allocate more memory.
 * @param allocator The allocator to use with the new pool.  If NULL the
 *        allocator of the parent pool will be used.
 * @remark This function is thread-safe, in the sense that multiple threads
 *         can safely create subpools of the same parent pool concurrently.
 *         Similarly, a subpool can be created by one thread at the same
 *         time that another thread accesses the parent pool.
 */
APR_DECLARE(apr_status_t) apr_pool_create_ex(apr_pool_t **newpool,
                                             apr_pool_t *parent,
                                             apr_abortfunc_t abort_fn,
                                             apr_allocator_t *allocator)
                          __attribute__((nonnull(1)));

/**
 * Create a new pool.
 * @deprecated @see apr_pool_create_unmanaged_ex.
 */
APR_DECLARE(apr_status_t) apr_pool_create_core_ex(apr_pool_t **newpool,
                                                  apr_abortfunc_t abort_fn,
                                                  apr_allocator_t *allocator);

/**
 * Create a new unmanaged pool.
 * @param newpool The pool we have just created.
 * @param abort_fn A function to use if the pool cannot allocate more memory.
 * @param allocator The allocator to use with the new pool.  If NULL a
 *        new allocator will be created with the new pool as owner.
 * @remark An unmanaged pool is a special pool without a parent; it will
 *         NOT be destroyed upon apr_terminate.  It must be explicitly
 *         destroyed by calling apr_pool_destroy, to prevent memory leaks.
 *         Use of this function is discouraged, think twice about whether
 *         you really really need it.
 * @warning Any child cleanups registered against the new pool, or
 *         against sub-pools thereof, will not be executed during an
 *         invocation of apr_proc_create(), so resources created in an
 *         "unmanaged" pool hierarchy will leak to child processes.
 */
APR_DECLARE(apr_status_t) apr_pool_create_unmanaged_ex(apr_pool_t **newpool,
                                                   apr_abortfunc_t abort_fn,
                                                   apr_allocator_t *allocator)
                          __attribute__((nonnull(1)));

/**
 * Debug version of apr_pool_create_ex.
 * @param newpool @see apr_pool_create.
 * @param parent @see apr_pool_create.
 * @param abort_fn @see apr_pool_create.
 * @param allocator @see apr_pool_create.
 * @param file_line Where the function is called from.
 *        This is usually APR_POOL__FILE_LINE__.
 * @remark Only available when APR_POOL_DEBUG is defined.
 *         Call this directly if you have your apr_pool_create_ex
 *         calls in a wrapper function and wish to override
 *         the file_line argument to reflect the caller of
 *         your wrapper function.  If you do not have
 *         apr_pool_create_ex in a wrapper, trust the macro
 *         and don't call apr_pool_create_ex_debug directly.
 */
APR_DECLARE(apr_status_t) apr_pool_create_ex_debug(apr_pool_t **newpool,
                                                   apr_pool_t *parent,
                                                   apr_abortfunc_t abort_fn,
                                                   apr_allocator_t *allocator,
                                                   const char *file_line)
                          __attribute__((nonnull(1)));

#if APR_POOL_DEBUG
#define apr_pool_create_ex(newpool, parent, abort_fn, allocator)  \
    apr_pool_create_ex_debug(newpool, parent, abort_fn, allocator, \
                             APR_POOL__FILE_LINE__)
#endif

/**
 * Debug version of apr_pool_create_core_ex.
 * @deprecated @see apr_pool_create_unmanaged_ex_debug.
 */
APR_DECLARE(apr_status_t) apr_pool_create_core_ex_debug(apr_pool_t **newpool,
                                                   apr_abortfunc_t abort_fn,
                                                   apr_allocator_t *allocator,
                                                   const char *file_line);

/**
 * Debug version of apr_pool_create_unmanaged_ex.
 * @param newpool @see apr_pool_create_unmanaged.
 * @param abort_fn @see apr_pool_create_unmanaged.
 * @param allocator @see apr_pool_create_unmanaged.
 * @param file_line Where the function is called from.
 *        This is usually APR_POOL__FILE_LINE__.
 * @remark Only available when APR_POOL_DEBUG is defined.
 *         Call this directly if you have your apr_pool_create_unmanaged_ex
 *         calls in a wrapper function and wish to override
 *         the file_line argument to reflect the caller of
 *         your wrapper function.  If you do not have
 *         apr_pool_create_core_ex in a wrapper, trust the macro
 *         and don't call apr_pool_create_core_ex_debug directly.
 */
APR_DECLARE(apr_status_t) apr_pool_create_unmanaged_ex_debug(apr_pool_t **newpool,
                                                   apr_abortfunc_t abort_fn,
                                                   apr_allocator_t *allocator,
                                                   const char *file_line)
                          __attribute__((nonnull(1)));

#if APR_POOL_DEBUG
#define apr_pool_create_core_ex(newpool, abort_fn, allocator)  \
    apr_pool_create_unmanaged_ex_debug(newpool, abort_fn, allocator, \
                                  APR_POOL__FILE_LINE__)

#define apr_pool_create_unmanaged_ex(newpool, abort_fn, allocator)  \
    apr_pool_create_unmanaged_ex_debug(newpool, abort_fn, allocator, \
                                  APR_POOL__FILE_LINE__)

#endif

/**
 * Create a new pool.
 * @param newpool The pool we have just created.
 * @param parent The parent pool.  If this is NULL, the new pool is a root
 *        pool.  If it is non-NULL, the new pool will inherit all
 *        of its parent pool's attributes, except the apr_pool_t will
 *        be a sub-pool.
 * @remark This function is thread-safe, in the sense that multiple threads
 *         can safely create subpools of the same parent pool concurrently.
 *         Similarly, a subpool can be created by one thread at the same
 *         time that another thread accesses the parent pool.
 */
#if defined(DOXYGEN)
APR_DECLARE(apr_status_t) apr_pool_create(apr_pool_t **newpool,
                                          apr_pool_t *parent);
#else
#if APR_POOL_DEBUG
#define apr_pool_create(newpool, parent) \
    apr_pool_create_ex_debug(newpool, parent, NULL, NULL, \
                             APR_POOL__FILE_LINE__)
#else
#define apr_pool_create(newpool, parent) \
    apr_pool_create_ex(newpool, parent, NULL, NULL)
#endif
#endif

/**
 * Create a new unmanaged pool.
 * @param newpool The pool we have just created.
 */
#if defined(DOXYGEN)
APR_DECLARE(apr_status_t) apr_pool_create_core(apr_pool_t **newpool);
APR_DECLARE(apr_status_t) apr_pool_create_unmanaged(apr_pool_t **newpool);
#else
#if APR_POOL_DEBUG
#define apr_pool_create_core(newpool) \
    apr_pool_create_unmanaged_ex_debug(newpool, NULL, NULL, \
                                  APR_POOL__FILE_LINE__)
#define apr_pool_create_unmanaged(newpool) \
    apr_pool_create_unmanaged_ex_debug(newpool, NULL, NULL, \
                                  APR_POOL__FILE_LINE__)
#else
#define apr_pool_create_core(newpool) \
    apr_pool_create_unmanaged_ex(newpool, NULL, NULL)
#define apr_pool_create_unmanaged(newpool) \
    apr_pool_create_unmanaged_ex(newpool, NULL, NULL)
#endif
#endif

/**
 * Find the pool's allocator
 * @param pool The pool to get the allocator from.
 */
APR_DECLARE(apr_allocator_t *) apr_pool_allocator_get(apr_pool_t *pool)
                               __attribute__((nonnull(1)));

/**
 * Clear all memory in the pool and run all the cleanups. This also destroys all
 * subpools.
 * @param p The pool to clear
 * @remark This does not actually free the memory, it just allows the pool
 *         to re-use this memory for the next allocation.
 * @see apr_pool_destroy()
 */
APR_DECLARE(void) apr_pool_clear(apr_pool_t *p) __attribute__((nonnull(1)));

/**
 * Debug version of apr_pool_clear.
 * @param p See: apr_pool_clear.
 * @param file_line Where the function is called from.
 *        This is usually APR_POOL__FILE_LINE__.
 * @remark Only available when APR_POOL_DEBUG is defined.
 *         Call this directly if you have your apr_pool_clear
 *         calls in a wrapper function and wish to override
 *         the file_line argument to reflect the caller of
 *         your wrapper function.  If you do not have
 *         apr_pool_clear in a wrapper, trust the macro
 *         and don't call apr_pool_destroy_clear directly.
 */
APR_DECLARE(void) apr_pool_clear_debug(apr_pool_t *p,
                                       const char *file_line)
                  __attribute__((nonnull(1)));

#if APR_POOL_DEBUG
#define apr_pool_clear(p) \
    apr_pool_clear_debug(p, APR_POOL__FILE_LINE__)
#endif

/**
 * Destroy the pool. This takes similar action as apr_pool_clear() and then
 * frees all the memory.
 * @param p The pool to destroy
 * @remark This will actually free the memory
 */
APR_DECLARE(void) apr_pool_destroy(apr_pool_t *p) __attribute__((nonnull(1)));

/**
 * Debug version of apr_pool_destroy.
 * @param p See: apr_pool_destroy.
 * @param file_line Where the function is called from.
 *        This is usually APR_POOL__FILE_LINE__.
 * @remark Only available when APR_POOL_DEBUG is defined.
 *         Call this directly if you have your apr_pool_destroy
 *         calls in a wrapper function and wish to override
 *         the file_line argument to reflect the caller of
 *         your wrapper function.  If you do not have
 *         apr_pool_destroy in a wrapper, trust the macro
 *         and don't call apr_pool_destroy_debug directly.
 */
APR_DECLARE(void) apr_pool_destroy_debug(apr_pool_t *p,
                                         const char *file_line)
                  __attribute__((nonnull(1)));

#if APR_POOL_DEBUG
#define apr_pool_destroy(p) \
    apr_pool_destroy_debug(p, APR_POOL__FILE_LINE__)
#endif


/*
 * Memory allocation
 */

/**
 * Allocate a block of memory from a pool
 * @param p The pool to allocate from
 * @param size The amount of memory to allocate
 * @return The allocated memory
 */
APR_DECLARE(void *) apr_palloc(apr_pool_t *p, apr_size_t size)
#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
                    __attribute__((alloc_size(2)))
#endif
                    __attribute__((nonnull(1)));

/**
 * Debug version of apr_palloc
 * @param p See: apr_palloc
 * @param size See: apr_palloc
 * @param file_line Where the function is called from.
 *        This is usually APR_POOL__FILE_LINE__.
 * @return See: apr_palloc
 */
APR_DECLARE(void *) apr_palloc_debug(apr_pool_t *p, apr_size_t size,
                                     const char *file_line)
#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
                    __attribute__((alloc_size(2)))
#endif
                    __attribute__((nonnull(1)));

#if APR_POOL_DEBUG
#define apr_palloc(p, size) \
    apr_palloc_debug(p, size, APR_POOL__FILE_LINE__)
#endif

/**
 * Allocate a block of memory from a pool and set all of the memory to 0
 * @param p The pool to allocate from
 * @param size The amount of memory to allocate
 * @return The allocated memory
 */
#if defined(DOXYGEN)
APR_DECLARE(void *) apr_pcalloc(apr_pool_t *p, apr_size_t size);
#elif !APR_POOL_DEBUG
#define apr_pcalloc(p, size) memset(apr_palloc(p, size), 0, size)
#endif

/**
 * Debug version of apr_pcalloc
 * @param p See: apr_pcalloc
 * @param size See: apr_pcalloc
 * @param file_line Where the function is called from.
 *        This is usually APR_POOL__FILE_LINE__.
 * @return See: apr_pcalloc
 */
APR_DECLARE(void *) apr_pcalloc_debug(apr_pool_t *p, apr_size_t size,
                                      const char *file_line)
                    __attribute__((nonnull(1)));

#if APR_POOL_DEBUG
#define apr_pcalloc(p, size) \
    apr_pcalloc_debug(p, size, APR_POOL__FILE_LINE__)
#endif


/*
 * Pool Properties
 */

/**
 * Set the function to be called when an allocation failure occurs.
 * @remark If the program wants APR to exit on a memory allocation error,
 *      then this function can be called to set the callback to use (for
 *      performing cleanup and then exiting). If this function is not called,
 *      then APR will return an error and expect the calling program to
 *      deal with the error accordingly.
 */
APR_DECLARE(void) apr_pool_abort_set(apr_abortfunc_t abortfunc,
                                     apr_pool_t *pool)
                  __attribute__((nonnull(2)));

/**
 * Get the abort function associated with the specified pool.
 * @param pool The pool for retrieving the abort function.
 * @return The abort function for the given pool.
 */
APR_DECLARE(apr_abortfunc_t) apr_pool_abort_get(apr_pool_t *pool)
                             __attribute__((nonnull(1)));

/**
 * Get the parent pool of the specified pool.
 * @param pool The pool for retrieving the parent pool.
 * @return The parent of the given pool.
 */
APR_DECLARE(apr_pool_t *) apr_pool_parent_get(apr_pool_t *pool)
                          __attribute__((nonnull(1)));

/**
 * Determine if pool a is an ancestor of pool b.
 * @param a The pool to search
 * @param b The pool to search for
 * @return True if a is an ancestor of b, NULL is considered an ancestor
 *         of all pools.
 * @remark if compiled with APR_POOL_DEBUG, this function will also
 * return true if A is a pool which has been guaranteed by the caller
 * (using apr_pool_join) to have a lifetime at least as long as some
 * ancestor of pool B.
 */
APR_DECLARE(int) apr_pool_is_ancestor(apr_pool_t *a, apr_pool_t *b);

/**
 * Tag a pool (give it a name)
 * @param pool The pool to tag
 * @param tag  The tag
 */
APR_DECLARE(void) apr_pool_tag(apr_pool_t *pool, const char *tag)
                  __attribute__((nonnull(1)));


/*
 * User data management
 */

/**
 * Set the data associated with the current pool
 * @param data The user data associated with the pool.
 * @param key The key to use for association
 * @param cleanup The cleanup program to use to cleanup the data (NULL if none)
 * @param pool The current pool
 * @warning The data to be attached to the pool should have a life span
 *          at least as long as the pool it is being attached to.
 *
 *      Users of APR must take EXTREME care when choosing a key to
 *      use for their data.  It is possible to accidentally overwrite
 *      data by choosing a key that another part of the program is using.
 *      Therefore it is advised that steps are taken to ensure that unique
 *      keys are used for all of the userdata objects in a particular pool
 *      (the same key in two different pools or a pool and one of its
 *      subpools is okay) at all times.  Careful namespace prefixing of
 *      key names is a typical way to help ensure this uniqueness.
 *
 */
APR_DECLARE(apr_status_t) apr_pool_userdata_set(const void *data,
                                                const char *key,
                                                apr_status_t (*cleanup)(void *),
                                                apr_pool_t *pool)
                          __attribute__((nonnull(2,4)));

/**
 * Set the data associated with the current pool
 * @param data The user data associated with the pool.
 * @param key The key to use for association
 * @param cleanup The cleanup program to use to cleanup the data (NULL if none)
 * @param pool The current pool
 * @note same as apr_pool_userdata_set(), except that this version doesn't
 *       make a copy of the key (this function is useful, for example, when
 *       the key is a string literal)
 * @warning This should NOT be used if the key could change addresses by
 *       any means between the apr_pool_userdata_setn() call and a
 *       subsequent apr_pool_userdata_get() on that key, such as if a
 *       static string is used as a userdata key in a DSO and the DSO could
 *       be unloaded and reloaded between the _setn() and the _get().  You
 *       MUST use apr_pool_userdata_set() in such cases.
 * @warning More generally, the key and the data to be attached to the
 *       pool should have a life span at least as long as the pool itself.
 *
 */
APR_DECLARE(apr_status_t) apr_pool_userdata_setn(
                                const void *data, const char *key,
                                apr_status_t (*cleanup)(void *),
                                apr_pool_t *pool)
                          __attribute__((nonnull(2,4)));

/**
 * Return the data associated with the current pool.
 * @param data The user data associated with the pool.
 * @param key The key for the data to retrieve
 * @param pool The current pool.
 */
APR_DECLARE(apr_status_t) apr_pool_userdata_get(void **data, const char *key,
                                                apr_pool_t *pool)
                          __attribute__((nonnull(1,2,3)));


/**
 * @defgroup PoolCleanup  Pool Cleanup Functions
 *
 * Cleanups are performed in the reverse order they were registered.  That is:
 * Last In, First Out.  A cleanup function can safely allocate memory from
 * the pool that is being cleaned up. It can also safely register additional
 * cleanups which will be run LIFO, directly after the current cleanup
 * terminates.  Cleanups have to take caution in calling functions that
 * create subpools. Subpools, created during cleanup will NOT automatically
 * be cleaned up.  In other words, cleanups are to clean up after themselves.
 *
 * @{
 */

/**
 * Register a function to be called when a pool is cleared or destroyed
 * @param p The pool to register the cleanup with
 * @param data The data to pass to the cleanup function.
 * @param plain_cleanup The function to call when the pool is cleared
 *                      or destroyed
 * @param child_cleanup The function to call when a child process is about
 *                      to exec - this function is called in the child, obviously!
 */
APR_DECLARE(void) apr_pool_cleanup_register(
                            apr_pool_t *p, const void *data,
                            apr_status_t (*plain_cleanup)(void *),
                            apr_status_t (*child_cleanup)(void *))
                  __attribute__((nonnull(3,4)));

/**
 * Register a function to be called when a pool is cleared or destroyed.
 *
 * Unlike apr_pool_cleanup_register which registers a cleanup
 * that is called AFTER all subpools are destroyed, this function registers
 * a function that will be called before any of the subpools are destroyed.
 *
 * @param p The pool to register the cleanup with
 * @param data The data to pass to the cleanup function.
 * @param plain_cleanup The function to call when the pool is cleared
 *                      or destroyed
 */
APR_DECLARE(void) apr_pool_pre_cleanup_register(
                            apr_pool_t *p, const void *data,
                            apr_status_t (*plain_cleanup)(void *))
                  __attribute__((nonnull(3)));

/**
 * Remove a previously registered cleanup function.
 * 
 * The cleanup most recently registered with @a p having the same values of
 * @a data and @a cleanup will be removed.
 *
 * @param p The pool to remove the cleanup from
 * @param data The data of the registered cleanup
 * @param cleanup The function to remove from cleanup
 * @remarks For some strange reason only the plain_cleanup is handled by this
 *          function
 */
APR_DECLARE(void) apr_pool_cleanup_kill(apr_pool_t *p, const void *data,
                                        apr_status_t (*cleanup)(void *))
                  __attribute__((nonnull(3)));

/**
 * Replace the child cleanup function of a previously registered cleanup.
 * 
 * The cleanup most recently registered with @a p having the same values of
 * @a data and @a plain_cleanup will have the registered child cleanup
 * function replaced with @a child_cleanup.
 *
 * @param p The pool of the registered cleanup
 * @param data The data of the registered cleanup
 * @param plain_cleanup The plain cleanup function of the registered cleanup
 * @param child_cleanup The function to register as the child cleanup
 */
APR_DECLARE(void) apr_pool_child_cleanup_set(
                        apr_pool_t *p, const void *data,
                        apr_status_t (*plain_cleanup)(void *),
                        apr_status_t (*child_cleanup)(void *))
                  __attribute__((nonnull(3,4)));

/**
 * Run the specified cleanup function immediately and unregister it.
 *
 * The cleanup most recently registered with @a p having the same values of
 * @a data and @a cleanup will be removed and @a cleanup will be called
 * with @a data as the argument.
 *
 * @param p The pool to remove the cleanup from
 * @param data The data to remove from cleanup
 * @param cleanup The function to remove from cleanup
 */
APR_DECLARE(apr_status_t) apr_pool_cleanup_run(apr_pool_t *p, void *data,
                                               apr_status_t (*cleanup)(void *))
                          __attribute__((nonnull(3)));

/**
 * An empty cleanup function.
 * 
 * Passed to apr_pool_cleanup_register() when no cleanup is required.
 *
 * @param data The data to cleanup, will not be used by this function.
 */
APR_DECLARE_NONSTD(apr_status_t) apr_pool_cleanup_null(void *data);

/**
 * Run all registered child cleanups, in preparation for an exec()
 * call in a forked child -- close files, etc., but *don't* flush I/O
 * buffers, *don't* wait for subprocesses, and *don't* free any
 * memory.
 */
APR_DECLARE(void) apr_pool_cleanup_for_exec(void);

/** @} */

/**
 * @defgroup PoolDebug Pool Debugging functions
 *
 * pools have nested lifetimes -- sub_pools are destroyed when the
 * parent pool is cleared.  We allow certain liberties with operations
 * on things such as tables (and on other structures in a more general
 * sense) where we allow the caller to insert values into a table which
 * were not allocated from the table's pool.  The table's data will
 * remain valid as long as all the pools from which its values are
 * allocated remain valid.
 *
 * For example, if B is a sub pool of A, and you build a table T in
 * pool B, then it's safe to insert data allocated in A or B into T
 * (because B lives at most as long as A does, and T is destroyed when
 * B is cleared/destroyed).  On the other hand, if S is a table in
 * pool A, it is safe to insert data allocated in A into S, but it
 * is *not safe* to insert data allocated from B into S... because
 * B can be cleared/destroyed before A is (which would leave dangling
 * pointers in T's data structures).
 *
 * In general we say that it is safe to insert data into a table T
 * if the data is allocated in any ancestor of T's pool.  This is the
 * basis on which the APR_POOL_DEBUG code works -- it tests these ancestor
 * relationships for all data inserted into tables.  APR_POOL_DEBUG also
 * provides tools (apr_pool_find, and apr_pool_is_ancestor) for other
 * folks to implement similar restrictions for their own data
 * structures.
 *
 * However, sometimes this ancestor requirement is inconvenient --
 * sometimes it's necessary to create a sub pool where the sub pool is
 * guaranteed to have the same lifetime as the parent pool.  This is a
 * guarantee implemented by the *caller*, not by the pool code.  That
 * is, the caller guarantees they won't destroy the sub pool
 * individually prior to destroying the parent pool.
 *
 * In this case the caller must call apr_pool_join() to indicate this
 * guarantee to the APR_POOL_DEBUG code.
 *
 * These functions are only implemented when #APR_POOL_DEBUG is set.
 *
 * @{
 */
#if APR_POOL_DEBUG || defined(DOXYGEN)
/**
 * Guarantee that a subpool has the same lifetime as the parent.
 * @param p The parent pool
 * @param sub The subpool
 */
APR_DECLARE(void) apr_pool_join(apr_pool_t *p, apr_pool_t *sub)
                  __attribute__((nonnull(2)));

/**
 * Find a pool from something allocated in it.
 * @param mem The thing allocated in the pool
 * @return The pool it is allocated in
 */
APR_DECLARE(apr_pool_t *) apr_pool_find(const void *mem);

/**
 * Report the number of bytes currently in the pool
 * @param p The pool to inspect
 * @param recurse Recurse/include the subpools' sizes
 * @return The number of bytes
 */
APR_DECLARE(apr_size_t) apr_pool_num_bytes(apr_pool_t *p, int recurse)
                        __attribute__((nonnull(1)));

/**
 * Lock a pool
 * @param pool The pool to lock
 * @param flag  The flag
 */
APR_DECLARE(void) apr_pool_lock(apr_pool_t *pool, int flag);

/** @} */

#else /* APR_POOL_DEBUG or DOXYGEN */

#ifdef apr_pool_join
#undef apr_pool_join
#endif
#define apr_pool_join(a,b)

#ifdef apr_pool_lock
#undef apr_pool_lock
#endif
#define apr_pool_lock(pool, lock)

#endif /* APR_POOL_DEBUG or DOXYGEN */

/** @} */

#ifdef __cplusplus
}
#endif

#endif /* !APR_POOLS_H */
apr-1/apu.h000064400000010336151730340570006432 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * apu.h is generated from apu.h.in by configure -- do not edit apu.h
 */
/* @file apu.h
 * @brief APR-Utility main file
 */
/**
 * @defgroup APR_Util APR Utility Functions
 * @{
 */


#ifndef APU_H
#define APU_H

/**
 * APU_DECLARE_EXPORT is defined when building the APR-UTIL dynamic library,
 * so that all public symbols are exported.
 *
 * APU_DECLARE_STATIC is defined when including the APR-UTIL public headers,
 * to provide static linkage when the dynamic library may be unavailable.
 *
 * APU_DECLARE_STATIC and APU_DECLARE_EXPORT are left undefined when
 * including the APR-UTIL public headers, to import and link the symbols from 
 * the dynamic APR-UTIL library and assure appropriate indirection and calling
 * conventions at compile time.
 */

#if defined(DOXYGEN) || !defined(WIN32)
/**
 * 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().
 *
 * @fn APU_DECLARE(rettype) apr_func(args);
 */
#define APU_DECLARE(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.
 *
 * @fn APU_DECLARE_NONSTD(rettype) apr_func(args, ...);
 */
#define APU_DECLARE_NONSTD(type)     type
/**
 * The public APR-UTIL variables are declared with APU_DECLARE_DATA.
 * This assures the appropriate indirection is invoked at compile time.
 *
 * @fn APU_DECLARE_DATA type apr_variable;
 * @note APU_DECLARE_DATA extern type apr_variable; syntax is required for
 * declarations within headers to properly import the variable.
 */
#define APU_DECLARE_DATA
#elif defined(APU_DECLARE_STATIC)
#define APU_DECLARE(type)            type __stdcall
#define APU_DECLARE_NONSTD(type)     type __cdecl
#define APU_DECLARE_DATA
#elif defined(APU_DECLARE_EXPORT)
#define APU_DECLARE(type)            __declspec(dllexport) type __stdcall
#define APU_DECLARE_NONSTD(type)     __declspec(dllexport) type __cdecl
#define APU_DECLARE_DATA             __declspec(dllexport)
#else
#define APU_DECLARE(type)            __declspec(dllimport) type __stdcall
#define APU_DECLARE_NONSTD(type)     __declspec(dllimport) type __cdecl
#define APU_DECLARE_DATA             __declspec(dllimport)
#endif

#if !defined(WIN32) || defined(APU_MODULE_DECLARE_STATIC)
/**
 * Declare a dso module's exported module structure as APU_MODULE_DECLARE_DATA.
 *
 * Unless APU_MODULE_DECLARE_STATIC is defined at compile time, symbols 
 * declared with APU_MODULE_DECLARE_DATA are always exported.
 * @code
 * module APU_MODULE_DECLARE_DATA mod_tag
 * @endcode
 */
#define APU_MODULE_DECLARE_DATA
#else
#define APU_MODULE_DECLARE_DATA           __declspec(dllexport)
#endif

/*
 * we always have SDBM (it's in our codebase)
 */
#define APU_HAVE_SDBM   1
#define APU_HAVE_GDBM   0
#define APU_HAVE_NDBM   0
#define APU_HAVE_DB     1

#if APU_HAVE_DB
#define APU_HAVE_DB_VERSION    5
#endif

#define APU_HAVE_PGSQL         1
#define APU_HAVE_MYSQL         1
#define APU_HAVE_SQLITE3       1
#define APU_HAVE_SQLITE2       0
#define APU_HAVE_ORACLE        0
#define APU_HAVE_ODBC          1

#define APU_HAVE_CRYPTO        1
#define APU_HAVE_OPENSSL       1
#define APU_HAVE_NSS           1
#define APU_HAVE_COMMONCRYPTO  0

#define APU_HAVE_APR_ICONV     0
#define APU_HAVE_ICONV         1
#define APR_HAS_XLATE          (APU_HAVE_APR_ICONV || APU_HAVE_ICONV)

#endif /* APU_H */
/** @} */
apr-1/apr_ldap_option.h000064400000020634151730340600011013 0ustar00/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @file apr_ldap_option.h
 * @brief  APR-UTIL LDAP ldap_*_option() functions
 */
#ifndef APR_LDAP_OPTION_H
#define APR_LDAP_OPTION_H

/**
 * @addtogroup APR_Util_LDAP
 * @{
 */

#include "apr_ldap.h"

#if APR_HAS_LDAP

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/*
 * The following defines handle the different TLS certificate
 * options available. If these options are missing, APR will try and
 * emulate support for this using the deprecated ldap_start_tls_s()
 * function.
 */
/**
 * Set SSL mode to one of APR_LDAP_NONE, APR_LDAP_SSL, APR_LDAP_STARTTLS
 * or APR_LDAP_STOPTLS.
 */
#define APR_LDAP_OPT_TLS 0x6fff
/**
 * Set zero or more CA certificates, client certificates or private
 * keys globally, or per connection (where supported).
 */
#define APR_LDAP_OPT_TLS_CERT 0x6ffe
/**
 * Set the LDAP library to no verify the server certificate.  This means
 * all servers are considered trusted.
 */
#define APR_LDAP_OPT_VERIFY_CERT 0x6ffd
/**
 * Set the LDAP library to indicate if referrals should be chased during
 * LDAP searches.
 */
#define APR_LDAP_OPT_REFERRALS 0x6ffc
/**
 * Set the LDAP library to indicate a maximum number of referral hops to
 * chase before giving up on the search.
 */
#define APR_LDAP_OPT_REFHOPLIMIT 0x6ffb

/**
 * Structures for the apr_set_option() cases
 */

/**
 * APR_LDAP_OPT_TLS_CERT
 *
 * This structure includes possible options to set certificates on
 * system initialisation. Different SDKs have different certificate
 * requirements, and to achieve this multiple certificates must be
 * specified at once passed as an (apr_array_header_t *).
 *
 * Netscape:
 * Needs the CA cert database (cert7.db), the client cert database (key3.db)
 * and the security module file (secmod.db) set at the system initialisation
 * time. Three types are supported: APR_LDAP_CERT7_DB, APR_LDAP_KEY3_DB and
 * APR_LDAP_SECMOD.
 *
 * To specify a client cert connection, a certificate nickname needs to be
 * provided with a type of APR_LDAP_CERT.
 * int ldapssl_enable_clientauth( LDAP *ld, char *keynickname,
 * char *keypasswd, char *certnickname );
 * keynickname is currently not used, and should be set to ""
 *
 * Novell:
 * Needs CA certificates and client certificates set at system initialisation
 * time. Three types are supported: APR_LDAP_CA*, APR_LDAP_CERT* and
 * APR_LDAP_KEY*.
 *
 * Certificates cannot be specified per connection.
 *
 * The functions used are:
 * ldapssl_add_trusted_cert(serverTrustedRoot, serverTrustedRootEncoding);
 * Clients certs and keys are set at system initialisation time with
 * int ldapssl_set_client_cert (
 *  void   *cert,
 *  int     type
 *  void   *password); 
 * type can be LDAPSSL_CERT_FILETYPE_B64 or LDAPSSL_CERT_FILETYPE_DER
 *  ldapssl_set_client_private_key(clientPrivateKey,
 *                                 clientPrivateKeyEncoding,
 *                                 clientPrivateKeyPassword);
 *
 * OpenSSL:
 * Needs one or more CA certificates to be set at system initialisation time
 * with a type of APR_LDAP_CA*.
 *
 * May have one or more client certificates set per connection with a type of
 * APR_LDAP_CERT*, and keys with APR_LDAP_KEY*.
 */
/** CA certificate type unknown */
#define APR_LDAP_CA_TYPE_UNKNOWN    0
/** binary DER encoded CA certificate */
#define APR_LDAP_CA_TYPE_DER        1
/** PEM encoded CA certificate */
#define APR_LDAP_CA_TYPE_BASE64     2
/** Netscape/Mozilla cert7.db CA certificate database */
#define APR_LDAP_CA_TYPE_CERT7_DB   3
/** Netscape/Mozilla secmod file */
#define APR_LDAP_CA_TYPE_SECMOD     4
/** Client certificate type unknown */
#define APR_LDAP_CERT_TYPE_UNKNOWN  5
/** binary DER encoded client certificate */
#define APR_LDAP_CERT_TYPE_DER      6
/** PEM encoded client certificate */
#define APR_LDAP_CERT_TYPE_BASE64   7
/** Netscape/Mozilla key3.db client certificate database */
#define APR_LDAP_CERT_TYPE_KEY3_DB  8
/** Netscape/Mozilla client certificate nickname */
#define APR_LDAP_CERT_TYPE_NICKNAME 9
/** Private key type unknown */
#define APR_LDAP_KEY_TYPE_UNKNOWN   10
/** binary DER encoded private key */
#define APR_LDAP_KEY_TYPE_DER       11
/** PEM encoded private key */
#define APR_LDAP_KEY_TYPE_BASE64    12
/** PKCS#12 encoded client certificate */
#define APR_LDAP_CERT_TYPE_PFX      13
/** PKCS#12 encoded private key */
#define APR_LDAP_KEY_TYPE_PFX       14
/** Openldap directory full of base64-encoded cert 
 * authorities with hashes in corresponding .0 directory
 */
#define APR_LDAP_CA_TYPE_CACERTDIR_BASE64 15


/**
 * Certificate structure.
 *
 * This structure is used to store certificate details. An array of
 * these structures is passed to apr_ldap_set_option() to set CA
 * and client certificates.
 * @param type Type of certificate APR_LDAP_*_TYPE_*
 * @param path Path, file or nickname of the certificate
 * @param password Optional password, can be NULL
 */
typedef struct apr_ldap_opt_tls_cert_t apr_ldap_opt_tls_cert_t;
struct apr_ldap_opt_tls_cert_t {
    int type;
    const char *path;
    const char *password;
};

/**
 * APR_LDAP_OPT_TLS
 *
 * This sets the SSL level on the LDAP handle.
 *
 * Netscape/Mozilla:
 * Supports SSL, but not STARTTLS
 * SSL is enabled by calling ldapssl_install_routines().
 *
 * Novell:
 * Supports SSL and STARTTLS.
 * SSL is enabled by calling ldapssl_install_routines(). Note that calling
 * other ldap functions before ldapssl_install_routines() may cause this
 * function to fail.
 * STARTTLS is enabled by calling ldapssl_start_tls_s() after calling
 * ldapssl_install_routines() (check this).
 *
 * OpenLDAP:
 * Supports SSL and supports STARTTLS, but none of this is documented:
 * http://www.openldap.org/lists/openldap-software/200409/msg00618.html
 * Documentation for both SSL support and STARTTLS has been deleted from
 * the OpenLDAP documentation and website.
 */

/** No encryption */
#define APR_LDAP_NONE 0
/** SSL encryption (ldaps://) */
#define APR_LDAP_SSL 1
/** TLS encryption (STARTTLS) */
#define APR_LDAP_STARTTLS 2
/** end TLS encryption (STOPTLS) */
#define APR_LDAP_STOPTLS 3

/**
 * APR LDAP get option function
 *
 * This function gets option values from a given LDAP session if
 * one was specified. It maps to the native ldap_get_option() function.
 * @param pool The pool to use
 * @param ldap The LDAP handle
 * @param option The LDAP_OPT_* option to return
 * @param outvalue The value returned (if any)
 * @param result_err The apr_ldap_err_t structure contained detailed results
 *        of the operation.
 */
APU_DECLARE_LDAP(int) apr_ldap_get_option(apr_pool_t *pool,
                                          LDAP *ldap,
                                          int option,
                                          void *outvalue,
                                          apr_ldap_err_t **result_err);

/**
 * APR LDAP set option function
 * 
 * This function sets option values to a given LDAP session if
 * one was specified. It maps to the native ldap_set_option() function.
 * 
 * Where an option is not supported by an LDAP toolkit, this function
 * will try and apply legacy functions to achieve the same effect,
 * depending on the platform.
 * @param pool The pool to use
 * @param ldap The LDAP handle
 * @param option The LDAP_OPT_* option to set
 * @param invalue The value to set
 * @param result_err The apr_ldap_err_t structure contained detailed results
 *        of the operation.
 */
APU_DECLARE_LDAP(int) apr_ldap_set_option(apr_pool_t *pool,
                                          LDAP *ldap,
                                          int option,
                                          const void *invalue,
                                          apr_ldap_err_t **result_err);

#ifdef __cplusplus
}
#endif

#endif /* APR_HAS_LDAP */

/** @} */

#endif /* APR_LDAP_OPTION_H */

php-zts/php/ext/apcu/apc_globals.h000064400000007064151730540170013121 0ustar00/*
  +----------------------------------------------------------------------+
  | APC                                                                  |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2011 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt.                                 |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Daniel Cowgill <dcowgill@communityconnect.com>              |
  |          George Schlossnagle <george@omniti.com>                     |
  |          Rasmus Lerdorf <rasmus@php.net>                             |
  |          Arun C. Murthy <arunc@yahoo-inc.com>                        |
  |          Gopal Vijayaraghavan <gopalv@yahoo-inc.com>                 |
  +----------------------------------------------------------------------+

   This software was contributed to PHP by Community Connect Inc. in 2002
   and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
   Future revisions and derivatives of this source code must acknowledge
   Community Connect Inc. as the original contributor of this module by
   leaving this note intact in the source code.

   All other licensing and usage conditions are those of the PHP Group.

 */

#ifndef APC_GLOBALS_H
#define APC_GLOBALS_H

#include "apc.h"

ZEND_BEGIN_MODULE_GLOBALS(apcu)
	/* configuration parameters */
	zend_bool enabled;      /* if true, apc is enabled (defaults to true) */
	zend_long shm_segments;      /* number of shared memory segments to use */
	zend_long shm_size;          /* size of each shared memory segment (in MB) */
	zend_long entries_hint;      /* hint at the number of entries expected */
	zend_long gc_ttl;            /* parameter to apc_cache_create */
	zend_long ttl;               /* parameter to apc_cache_create */
	zend_long smart;             /* smart value */

#if APC_MMAP
	char *mmap_file_mask;   /* mktemp-style file-mask to pass to mmap */
#endif

	/* module variables */
	zend_bool initialized;       /* true if module was initialized */
	zend_bool enable_cli;        /* Flag to override turning APC off for CLI */
	zend_bool slam_defense;      /* true for user cache slam defense */

	char *preload_path;          /* preload path */
	zend_bool coredump_unmap;    /* trap signals that coredump and unmap shared memory */
	zend_bool use_request_time;  /* use the SAPI request start time for TTL */
	time_t request_time;         /* cached request time */

	char *serializer_name;       /* the serializer config option */

	/* Nesting level of apcu_entry calls. */
	unsigned int entry_level;
ZEND_END_MODULE_GLOBALS(apcu)

/* (the following is defined in php_apc.c) */
ZEND_EXTERN_MODULE_GLOBALS(apcu)

#ifdef ZTS
# define APCG(v) TSRMG(apcu_globals_id, zend_apcu_globals *, v)
#else
# define APCG(v) (apcu_globals.v)
#endif

extern struct _apc_cache_t* apc_user_cache;

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim>600: noexpandtab sw=4 ts=4 sts=4 fdm=marker
 * vim<600: noexpandtab sw=4 ts=4 sts=4
 */
php-zts/php/ext/apcu/apc_cache.h000064400000032033151730540170012533 0ustar00/*
  +----------------------------------------------------------------------+
  | APC                                                                  |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2011 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt.                                 |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Daniel Cowgill <dcowgill@communityconnect.com>              |
  |          Rasmus Lerdorf <rasmus@php.net>                             |
  +----------------------------------------------------------------------+

   This software was contributed to PHP by Community Connect Inc. in 2002
   and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
   Future revisions and derivatives of this source code must acknowledge
   Community Connect Inc. as the original contributor of this module by
   leaving this note intact in the source code.

   All other licensing and usage conditions are those of the PHP Group.

 */

#ifndef APC_CACHE_H
#define APC_CACHE_H

#include "apc.h"
#include "apc_sma.h"
#include "apc_lock.h"
#include "apc_globals.h"
#include "TSRM.h"

typedef struct apc_cache_slam_key_t apc_cache_slam_key_t;
struct apc_cache_slam_key_t {
	zend_ulong hash;         /* hash of the key */
	size_t len;              /* length of the key */
	time_t mtime;            /* creation time of this key */
	pid_t owner_pid;         /* the pid that created this key */
#ifdef ZTS
	void ***owner_thread;    /* TSRMLS cache of thread that created this key */
#endif
};

/* {{{ struct definition: apc_cache_entry_t */
typedef struct apc_cache_entry_t apc_cache_entry_t;
struct apc_cache_entry_t {
	zend_string *key;        /* entry key */
	zval val;                /* the zval copied at store time */
	apc_cache_entry_t *next; /* next entry in linked list */
	zend_long ttl;           /* the ttl on this specific entry */
	zend_long ref_count;     /* the reference count of this entry */
	zend_long nhits;         /* number of hits to this entry */
	time_t ctime;            /* time entry was initialized */
	time_t mtime;            /* the mtime of this cached entry */
	time_t dtime;            /* time entry was removed from cache */
	time_t atime;            /* time entry was last accessed */
	zend_long mem_size;      /* memory used */
};
/* }}} */

/* {{{ struct definition: apc_cache_header_t
   Any values that must be shared among processes should go in here. */
typedef struct _apc_cache_header_t {
	apc_lock_t lock;                /* header lock */
	zend_long nhits;                /* hit count */
	zend_long nmisses;              /* miss count */
	zend_long ninserts;             /* insert count */
	zend_long nexpunges;            /* expunge count */
	zend_long nentries;             /* entry count */
	zend_long mem_size;             /* used */
	time_t stime;                   /* start time */
	unsigned short state;           /* cache state */
	apc_cache_slam_key_t lastkey;   /* last key inserted (not necessarily without error) */
	apc_cache_entry_t *gc;          /* gc list */
} apc_cache_header_t; /* }}} */

/* {{{ struct definition: apc_cache_t */
typedef struct _apc_cache_t {
	void* shmaddr;                /* process (local) address of shared cache */
	apc_cache_header_t* header;   /* cache header (stored in SHM) */
	apc_cache_entry_t** slots;    /* array of cache slots (stored in SHM) */
	apc_sma_t* sma;               /* shared memory allocator */
	apc_serializer_t* serializer; /* serializer */
	size_t nslots;                /* number of slots in cache */
	zend_long gc_ttl;            /* maximum time on GC list for a entry */
	zend_long ttl;               /* if slot is needed and entry's access time is older than this ttl, remove it */
	zend_long smart;             /* smart parameter for gc */
	zend_bool defend;             /* defense parameter for runtime */
} apc_cache_t; /* }}} */

/* {{{ typedef: apc_cache_updater_t */
typedef zend_bool (*apc_cache_updater_t)(apc_cache_t*, apc_cache_entry_t*, void* data); /* }}} */

/* {{{ typedef: apc_cache_atomic_updater_t */
typedef zend_bool (*apc_cache_atomic_updater_t)(apc_cache_t*, zend_long*, void* data); /* }}} */

/*
 * apc_cache_create creates the shared memory cache.
 *
 * This function should be called once per process per cache
 *
 * serializer for APCu is set by globals on MINIT and ensured with apc_cache_serializer
 * during execution. Using apc_cache_serializer avoids race conditions between MINIT/RINIT of
 * APCU and the third party serializer. API users can choose to leave this null to use default
 * PHP serializers, or search the list of serializers for the preferred serializer
 *
 * size_hint is a "hint" at the total number entries that will be expected.
 * It determines the physical size of the hash table. Passing 0 for
 * this argument will use a reasonable default value
 *
 * gc_ttl is the maximum time a cache entry may speed on the garbage
 * collection list. This is basically a work around for the inherent
 * unreliability of our reference counting mechanism (see apc_cache_release).
 *
 * ttl is the maximum time a cache entry can idle in a slot in case the slot
 * is needed.  This helps in cleaning up the cache and ensuring that entries
 * hit frequently stay cached and ones not hit very often eventually disappear.
 *
 * for an explanation of smart, see apc_cache_default_expunge
 *
 * defend enables/disables slam defense for this particular cache
 */
PHP_APCU_API apc_cache_t* apc_cache_create(
        apc_sma_t* sma, apc_serializer_t* serializer, zend_long size_hint,
        zend_long gc_ttl, zend_long ttl, zend_long smart, zend_bool defend);
/*
* apc_cache_preload preloads the data at path into the specified cache
*/
PHP_APCU_API zend_bool apc_cache_preload(apc_cache_t* cache, const char* path);

/*
 * apc_cache_detach detaches from the shared memory cache and cleans up
 * local allocations. Under apache, this function can be safely called by
 * the child processes when they exit.
 */
PHP_APCU_API void apc_cache_detach(apc_cache_t* cache);

/*
 * apc_cache_clear empties a cache. This can safely be called at any time.
 */
PHP_APCU_API void apc_cache_clear(apc_cache_t* cache);

/*
 * apc_cache_store creates key, entry and context in which to make an insertion of val into the specified cache
 */
PHP_APCU_API zend_bool apc_cache_store(
        apc_cache_t* cache, zend_string *key, const zval *val,
        const int32_t ttl, const zend_bool exclusive);
/*
 * apc_cache_update updates an entry in place. The updater function must not bailout.
 * The update is performed under write-lock and doesn't have to be atomic.
 */
PHP_APCU_API zend_bool apc_cache_update(
		apc_cache_t *cache, zend_string *key, apc_cache_updater_t updater, void *data,
		zend_bool insert_if_not_found, zend_long ttl);

/*
 * apc_cache_atomic_update_long updates an integer entry in place. The updater function must
 * perform the update atomically, as the update is performed under read-lock.
 */
PHP_APCU_API zend_bool apc_cache_atomic_update_long(
		apc_cache_t *cache, zend_string *key, apc_cache_atomic_updater_t updater, void *data,
		zend_bool insert_if_not_found, zend_long ttl);

/*
 * apc_cache_find searches for a cache entry by its hashed identifier,
 * and returns a pointer to the entry if found, NULL otherwise.
 *
 */
PHP_APCU_API apc_cache_entry_t* apc_cache_find(apc_cache_t* cache, zend_string *key, time_t t);

/*
 * apc_cache_fetch fetches an entry from the cache directly into dst
 *
 */
PHP_APCU_API zend_bool apc_cache_fetch(apc_cache_t* cache, zend_string *key, time_t t, zval *dst);

/*
 * apc_cache_exists searches for a cache entry by its hashed identifier,
 * and returns whether the entry exists.
 */
PHP_APCU_API zend_bool apc_cache_exists(apc_cache_t* cache, zend_string *key, time_t t);

/*
 * apc_cache_delete and apc_cache_delete finds an entry in the cache and deletes it.
 */
PHP_APCU_API zend_bool apc_cache_delete(apc_cache_t* cache, zend_string *key);

/* apc_cache_fetch_zval copies a cache entry value to be usable at runtime.
 */
PHP_APCU_API zend_bool apc_cache_entry_fetch_zval(
		apc_cache_t *cache, apc_cache_entry_t *entry, zval *dst);

/*
 * apc_cache_entry_release decrements the reference count associated with a cache
 * entry. Calling apc_cache_find automatically increments the reference count,
 * and this function must be called post-execution to return the count to its
 * original value. Failing to do so will prevent the entry from being
 * garbage-collected.
 *
 * entry is the cache entry whose ref count you want to decrement.
 */
PHP_APCU_API void apc_cache_entry_release(apc_cache_t *cache, apc_cache_entry_t *entry);

/*
 fetches information about the cache provided for userland status functions
*/
PHP_APCU_API zend_bool apc_cache_info(zval *info, apc_cache_t *cache, zend_bool limited);

/*
 fetches information about the key provided
*/
PHP_APCU_API void apc_cache_stat(apc_cache_t *cache, zend_string *key, zval *stat);

/*
* apc_cache_defense: guard against slamming a key
*  will return true if the following conditions are met:
*	the key provided has a matching hash and length to the last key inserted into cache
*   the last key has a different owner
* in ZTS mode, TSRM determines owner
* in non-ZTS mode, PID determines owner
* Note: this function sets the owner of key during execution
*/
PHP_APCU_API zend_bool apc_cache_defense(apc_cache_t *cache, zend_string *key, time_t t);

/*
* apc_cache_serializer
* sets the serializer for a cache, and by proxy contexts created for the cache
* Note: this avoids race conditions between third party serializers and APCu
*/
PHP_APCU_API void apc_cache_serializer(apc_cache_t* cache, const char* name);

/*
* The remaining functions allow a third party to reimplement expunge
*
* Look at the source of apc_cache_default_expunge for what is expected of this function
*
* The default behaviour of expunge is explained below, should no combination of those options
* be suitable, you will need to reimplement apc_cache_default_expunge and pass it to your
* call to apc_sma_api_impl, this will replace the default functionality.
* The functions below you can use during your own implementation of expunge to gain more
* control over how the expunge process works ...
*
* Note: beware of locking (copy it exactly), setting states is also important
*/

/* {{{ apc_cache_default_expunge
* Where smart is not set:
*  Where no ttl is set on cache:
*   1) Perform cleanup of stale entries
*   2) Expunge if available memory is less than sma->size/2
*  Where ttl is set on cache:
*   1) Perform cleanup of stale entries
*   2) If available memory if less than the size requested, run full expunge
*
* Where smart is set:
*  Where no ttl is set on cache:
*   1) Perform cleanup of stale entries
*   2) Expunge is available memory is less than size * smart
*  Where ttl is set on cache:
*   1) Perform cleanup of stale entries
*   2) If available memory if less than the size requested, run full expunge
*
* The TTL of an entry takes precedence over the TTL of a cache
*/
PHP_APCU_API void apc_cache_default_expunge(apc_cache_t* cache, size_t size);

/*
* apc_cache_entry: generate and create or fetch an entry
*
* @see https://github.com/krakjoe/apcu/issues/142
*/
PHP_APCU_API void apc_cache_entry(apc_cache_t *cache, zend_string *key, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zend_long ttl, zend_long now, zval *return_value);

/* apcu_entry() holds a write lock on the cache while executing user code.
 * That code may call other apcu_* functions, which also try to acquire a
 * read or write lock, which would deadlock. As such, don't try to acquire a
 * lock if the current thread is inside apcu_entry().
 *
 * Whether the current thread is inside apcu_entry() is tracked by APCG(entry_level).
 * This breaks the self-contained apc_cache_t abstraction, but is currently
 * necessary because the entry_level needs to be tracked per-thread, while
 * apc_cache_t is a per-process structure.
 */

static inline zend_bool apc_cache_wlock(apc_cache_t *cache) {
	if (!APCG(entry_level)) {
		return WLOCK(&cache->header->lock);
	}
	return 1;
}

static inline void apc_cache_wunlock(apc_cache_t *cache) {
	if (!APCG(entry_level)) {
		WUNLOCK(&cache->header->lock);
	}
}

static inline zend_bool apc_cache_rlock(apc_cache_t *cache) {
	if (!APCG(entry_level)) {
		return RLOCK(&cache->header->lock);
	}
	return 1;
}

static inline void apc_cache_runlock(apc_cache_t *cache) {
	if (!APCG(entry_level)) {
		RUNLOCK(&cache->header->lock);
	}
}

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim>600: noexpandtab sw=4 ts=4 sts=4 fdm=marker
 * vim<600: noexpandtab sw=4 ts=4 sts=4
 */
php-zts/php/ext/apcu/apc_lock.h000064400000010521151730540170012416 0ustar00/*
  +----------------------------------------------------------------------+
  | APCu                                                                 |
  +----------------------------------------------------------------------+
  | Copyright (c) 2013 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: Joe Watkins <joe.watkins@live.co.uk>                        |
  +----------------------------------------------------------------------+
 */

#ifndef APC_LOCK_H
#define APC_LOCK_H

/*
 APCu works most efficiently where there is access to native read/write locks
 If the current system has native rwlocks present they will be used, if they are
	not present, APCu will emulate their behavior with standard mutex.
 While APCu is emulating read/write locks, reads and writes are exclusive,
	additionally the write lock prefers readers, as is the default behaviour of
	the majority of Posix rwlock implementations
*/

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include "apc.h"

#ifndef PHP_WIN32
# ifndef __USE_UNIX98
#  define __USE_UNIX98
# endif
# include "pthread.h"
# ifndef APC_SPIN_LOCK
#   ifndef APC_FCNTL_LOCK
#       ifdef APC_NATIVE_RWLOCK
		typedef pthread_rwlock_t apc_lock_t;
#		define APC_LOCK_SHARED
#       else
		typedef pthread_mutex_t apc_lock_t;
#		define APC_LOCK_RECURSIVE
#       endif
#   else
		typedef int apc_lock_t;
#		define APC_LOCK_FILE
#   endif
# else
# define APC_LOCK_NICE 1
typedef struct {
	unsigned long state;
} apc_lock_t;
# endif
#else
/* XXX kernel lock mode only for now, compatible through all the wins, add more ifdefs for others */
# include "apc_windows_srwlock_kernel.h"
typedef apc_windows_cs_rwlock_t apc_lock_t;
# define APC_LOCK_SHARED
#endif

/* {{{ functions */
/*
  The following functions should be called once per process:
	apc_lock_init initializes attributes suitable for all locks
	apc_lock_cleanup destroys those attributes
  This saves us from having to create and destroy attributes for
  every lock we use at runtime */
PHP_APCU_API zend_bool apc_lock_init(void);
PHP_APCU_API void      apc_lock_cleanup(void);
/*
  The following functions should be self explanitory:
*/
PHP_APCU_API zend_bool apc_lock_create(apc_lock_t *lock);
PHP_APCU_API zend_bool apc_lock_rlock(apc_lock_t *lock);
PHP_APCU_API zend_bool apc_lock_wlock(apc_lock_t *lock);
PHP_APCU_API zend_bool apc_lock_runlock(apc_lock_t *lock);
PHP_APCU_API zend_bool apc_lock_wunlock(apc_lock_t *lock);
PHP_APCU_API void apc_lock_destroy(apc_lock_t *lock); /* }}} */

/* {{{ generic locking macros */
#define CREATE_LOCK(lock)     apc_lock_create(lock)
#define DESTROY_LOCK(lock)    apc_lock_destroy(lock)
#define WLOCK(lock)           apc_lock_wlock(lock)
#define WUNLOCK(lock)         { apc_lock_wunlock(lock); HANDLE_UNBLOCK_INTERRUPTIONS(); }
#define RLOCK(lock)           apc_lock_rlock(lock)
#define RUNLOCK(lock)         { apc_lock_runlock(lock); HANDLE_UNBLOCK_INTERRUPTIONS(); }
/* }}} */

/* atomic operations */
#ifdef PHP_WIN32
# ifdef _WIN64
#  define ATOMIC_INC(a) InterlockedIncrement64(&a)
#  define ATOMIC_DEC(a) InterlockedDecrement64(&a)
#  define ATOMIC_ADD(a, b) (InterlockedExchangeAdd64(&a, b) + b)
#  define ATOMIC_CAS(a, old, new) (InterlockedCompareExchange64(&a, new, old) == old)
# else
#  define ATOMIC_INC(a) InterlockedIncrement(&a)
#  define ATOMIC_DEC(a) InterlockedDecrement(&a)
#  define ATOMIC_ADD(a, b) (InterlockedExchangeAdd(&a, b) + b)
#  define ATOMIC_CAS(a, old, new) (InterlockedCompareExchange(&a, new, old) == old)
# endif
#else
# define ATOMIC_INC(a) __sync_add_and_fetch(&a, 1)
# define ATOMIC_DEC(a) __sync_sub_and_fetch(&a, 1)
# define ATOMIC_ADD(a, b) __sync_add_and_fetch(&a, b)
# define ATOMIC_CAS(a, old, new) __sync_bool_compare_and_swap(&a, old, new)
#endif

#endif
php-zts/php/ext/apcu/php_apc.h000064400000004353151730540170012263 0ustar00/*
  +----------------------------------------------------------------------+
  | APC                                                                  |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2011 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Daniel Cowgill <dcowgill@communityconnect.com>              |
  |          George Schlossnagle <george@omniti.com>                     |
  |          Rasmus Lerdorf <rasmus@php.net>                             |
  +----------------------------------------------------------------------+

   This software was contributed to PHP by Community Connect Inc. in 2002
   and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
   Future revisions and derivatives of this source code must acknowledge
   Community Connect Inc. as the original contributor of this module by
   leaving this note intact in the source code.

   All other licensing and usage conditions are those of the PHP Group.

 */

#ifndef PHP_APCU_H
#define PHP_APCU_H

#include "apc.h"
#include "apc_globals.h"

#define PHP_APCU_VERSION "5.1.23"
#define PHP_APCU_EXTNAME "apcu"

PHP_APCU_API zend_bool apc_is_enabled(void);

extern zend_module_entry apcu_module_entry;
#define apcu_module_ptr &apcu_module_entry

#define phpext_apcu_ptr apcu_module_ptr

#if defined(ZTS) && defined(COMPILE_DL_APCU)
ZEND_TSRMLS_CACHE_EXTERN();
#endif

#endif /* PHP_APC_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim>600: noexpandtab sw=4 ts=4 sts=4 fdm=marker
 * vim<600: noexpandtab sw=4 ts=4 sts=4
 */
php-zts/php/ext/apcu/apc_arginfo.h000064400000000161151730540170013112 0ustar00#if PHP_VERSION_ID < 80000
# include "php_apc_legacy_arginfo.h"
#else
# error Not supported on PHP >= 8.0
#endif
php-zts/php/ext/apcu/apc_api.h000064400000002355151730540200012237 0ustar00/*
  +----------------------------------------------------------------------+
  | APCu                                                                 |
  +----------------------------------------------------------------------+
  | Copyright (c) 2013 The PHP Group                                     |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: Joe Watkins <joe.watkins@live.co.uk>                         |
  +----------------------------------------------------------------------+
 */

#ifndef APC_API_H
#define APC_API_H

#include "apc.h"
#include "apc_lock.h"
#include "apc_sma.h"
#include "apc_cache.h"

#endif
php-zts/php/ext/apcu/php_apc_legacy_arginfo.h000064400000005645151730540200015313 0ustar00/* This is a generated file, edit the .stub.php file instead.
 * Stub hash: 5282d856fd334278d5799581ad251977a3c6b18e */

ZEND_BEGIN_ARG_INFO_EX(arginfo_apcu_clear_cache, 0, 0, 0)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_apcu_cache_info, 0, 0, 0)
	ZEND_ARG_INFO(0, limited)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_apcu_key_info, 0, 0, 1)
	ZEND_ARG_INFO(0, key)
ZEND_END_ARG_INFO()

#define arginfo_apcu_sma_info arginfo_apcu_cache_info

#define arginfo_apcu_enabled arginfo_apcu_clear_cache

ZEND_BEGIN_ARG_INFO_EX(arginfo_apcu_store, 0, 0, 1)
	ZEND_ARG_INFO(0, key)
	ZEND_ARG_INFO(0, value)
	ZEND_ARG_INFO(0, ttl)
ZEND_END_ARG_INFO()

#define arginfo_apcu_add arginfo_apcu_store

ZEND_BEGIN_ARG_INFO_EX(arginfo_apcu_inc, 0, 0, 1)
	ZEND_ARG_INFO(0, key)
	ZEND_ARG_INFO(0, step)
	ZEND_ARG_INFO(1, success)
	ZEND_ARG_INFO(0, ttl)
ZEND_END_ARG_INFO()

#define arginfo_apcu_dec arginfo_apcu_inc

ZEND_BEGIN_ARG_INFO_EX(arginfo_apcu_cas, 0, 0, 3)
	ZEND_ARG_INFO(0, key)
	ZEND_ARG_INFO(0, old)
	ZEND_ARG_INFO(0, new)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_apcu_fetch, 0, 0, 1)
	ZEND_ARG_INFO(0, key)
	ZEND_ARG_INFO(1, success)
ZEND_END_ARG_INFO()

#define arginfo_apcu_exists arginfo_apcu_key_info

#define arginfo_apcu_delete arginfo_apcu_key_info

ZEND_BEGIN_ARG_INFO_EX(arginfo_apcu_entry, 0, 0, 2)
	ZEND_ARG_INFO(0, key)
	ZEND_ARG_INFO(0, callback)
	ZEND_ARG_INFO(0, ttl)
ZEND_END_ARG_INFO()

#if defined(APC_DEBUG)
ZEND_BEGIN_ARG_INFO_EX(arginfo_apcu_inc_request_time, 0, 0, 0)
	ZEND_ARG_INFO(0, by)
ZEND_END_ARG_INFO()
#endif


PHP_APCU_API ZEND_FUNCTION(apcu_clear_cache);
PHP_APCU_API ZEND_FUNCTION(apcu_cache_info);
PHP_APCU_API ZEND_FUNCTION(apcu_key_info);
PHP_APCU_API ZEND_FUNCTION(apcu_sma_info);
PHP_APCU_API ZEND_FUNCTION(apcu_enabled);
PHP_APCU_API ZEND_FUNCTION(apcu_store);
PHP_APCU_API ZEND_FUNCTION(apcu_add);
PHP_APCU_API ZEND_FUNCTION(apcu_inc);
PHP_APCU_API ZEND_FUNCTION(apcu_dec);
PHP_APCU_API ZEND_FUNCTION(apcu_cas);
PHP_APCU_API ZEND_FUNCTION(apcu_fetch);
PHP_APCU_API ZEND_FUNCTION(apcu_exists);
PHP_APCU_API ZEND_FUNCTION(apcu_delete);
PHP_APCU_API ZEND_FUNCTION(apcu_entry);
#if defined(APC_DEBUG)
PHP_APCU_API ZEND_FUNCTION(apcu_inc_request_time);
#endif


static const zend_function_entry ext_functions[] = {
	ZEND_FE(apcu_clear_cache, arginfo_apcu_clear_cache)
	ZEND_FE(apcu_cache_info, arginfo_apcu_cache_info)
	ZEND_FE(apcu_key_info, arginfo_apcu_key_info)
	ZEND_FE(apcu_sma_info, arginfo_apcu_sma_info)
	ZEND_FE(apcu_enabled, arginfo_apcu_enabled)
	ZEND_FE(apcu_store, arginfo_apcu_store)
	ZEND_FE(apcu_add, arginfo_apcu_add)
	ZEND_FE(apcu_inc, arginfo_apcu_inc)
	ZEND_FE(apcu_dec, arginfo_apcu_dec)
	ZEND_FE(apcu_cas, arginfo_apcu_cas)
	ZEND_FE(apcu_fetch, arginfo_apcu_fetch)
	ZEND_FE(apcu_exists, arginfo_apcu_exists)
	ZEND_FE(apcu_delete, arginfo_apcu_delete)
	ZEND_FE(apcu_entry, arginfo_apcu_entry)
#if defined(APC_DEBUG)
	ZEND_FE(apcu_inc_request_time, arginfo_apcu_inc_request_time)
#endif
	ZEND_FE_END
};
php-zts/php/ext/apcu/apc_serializer.h000064400000005731151730540200013640 0ustar00/*
  +----------------------------------------------------------------------+
  | APC                                                                  |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2011 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt.                                 |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Gopal Vijayaraghavan <gopalv@php.net>                       |
  +----------------------------------------------------------------------+

 */

#ifndef APC_SERIALIZER_H
#define APC_SERIALIZER_H

/* this is a shipped .h file, do not include any other header in this file */
#define APC_SERIALIZER_NAME(module) module##_apc_serializer
#define APC_UNSERIALIZER_NAME(module) module##_apc_unserializer

#define APC_SERIALIZER_ARGS unsigned char **buf, size_t *buf_len, const zval *value, void *config
#define APC_UNSERIALIZER_ARGS zval *value, unsigned char *buf, size_t buf_len, void *config

typedef int (*apc_serialize_t)(APC_SERIALIZER_ARGS);
typedef int (*apc_unserialize_t)(APC_UNSERIALIZER_ARGS);

typedef int (*apc_register_serializer_t)(const char* name, apc_serialize_t serialize, apc_unserialize_t unserialize, void *config);

/*
 * ABI version for constant hooks. Increment this any time you make any changes
 * to any function in this file.
 */
#define APC_SERIALIZER_ABI "0"
#define APC_SERIALIZER_CONSTANT "\000apc_register_serializer-" APC_SERIALIZER_ABI

#if !defined(APC_UNUSED)
# if defined(__GNUC__)
#  define APC_UNUSED __attribute__((unused))
# else
# define APC_UNUSED
# endif
#endif

static APC_UNUSED int apc_register_serializer(
        const char* name, apc_serialize_t serialize, apc_unserialize_t unserialize, void *config)
{
	int retval = 0;

	zend_string *lookup = zend_string_init(
		APC_SERIALIZER_CONSTANT, sizeof(APC_SERIALIZER_CONSTANT)-1, 0);
	zval *magic = zend_get_constant(lookup);

	/* zend_get_constant will return 1 on success, otherwise apc_magic_constant wouldn't be touched at all */
	if (magic) {
		apc_register_serializer_t register_func = (apc_register_serializer_t)(Z_LVAL_P(magic));
		if(register_func) {
			retval = register_func(name, serialize, unserialize, NULL);
		}
	}

	zend_string_release(lookup);

	return retval;
}

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim>600: noexpandtab sw=4 ts=4 sts=4 fdm=marker
 * vim<600: noexpandtab sw=4 ts=4 sts=4
 */
php-zts/php/ext/apcu/apc_iterator.h000064400000007446151730540200013325 0ustar00/*
  +----------------------------------------------------------------------+
  | APC                                                                  |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2011 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Brian Shire <shire@.php.net>                                |
  +----------------------------------------------------------------------+

 */

#ifndef APC_ITERATOR_H
#define APC_ITERATOR_H

#include "apc.h"
#include "apc_stack.h"

#include "ext/pcre/php_pcre.h"
#include "zend_smart_str.h"

#define APC_DEFAULT_CHUNK_SIZE 100

#define APC_LIST_ACTIVE   0x1
#define APC_LIST_DELETED  0x2

#define APC_ITER_TYPE		(1 << 0)
#define APC_ITER_KEY        (1 << 1)
#define APC_ITER_VALUE      (1 << 2)
#define APC_ITER_NUM_HITS   (1 << 3)
#define APC_ITER_MTIME      (1 << 4)
#define APC_ITER_CTIME      (1 << 5)
#define APC_ITER_DTIME      (1 << 6)
#define APC_ITER_ATIME      (1 << 7)
#define APC_ITER_REFCOUNT   (1 << 8)
#define APC_ITER_MEM_SIZE   (1 << 9)
#define APC_ITER_TTL        (1 << 10)

#define APC_ITER_NONE       0
#define APC_ITER_ALL        (0xffffffffL)

/* {{{ apc_iterator_t */
typedef struct _apc_iterator_t {
	short int initialized;   /* sanity check in case __construct failed */
	zend_long format;             /* format bitmask of the return values ie: key, value, info */
	size_t (*fetch)(struct _apc_iterator_t *iterator);
							 /* fetch callback to fetch items from cache slots or lists */
	size_t slot_idx;           /* index to the slot array or linked list */
	size_t chunk_size;         /* number of entries to pull down per fetch */
	apc_stack_t *stack;      /* stack of entries pulled from cache */
	int stack_idx;           /* index into the current stack */
	pcre_cache_entry *pce;     /* regex filter on entry identifiers */
#if PHP_VERSION_ID >= 70300
	pcre2_match_data *re_match_data; /* match data for regex */
#endif
	zend_string *regex;
	HashTable *search_hash;  /* hash of keys to iterate over */
	zend_long key_idx;            /* incrementing index for numerical keys */
	short int totals_flag;   /* flag if totals have been calculated */
	zend_long hits;               /* hit total */
	size_t size;             /* size total */
	zend_long count;              /* count total */
	zend_object obj;
} apc_iterator_t;
/* }}} */

#define apc_iterator_fetch_from(o) ((apc_iterator_t*)((char*)o - XtOffsetOf(apc_iterator_t, obj)))
#define apc_iterator_fetch(z) apc_iterator_fetch_from(Z_OBJ_P(z))

/* {{{ apc_iterator_item */
typedef struct _apc_iterator_item_t {
	zend_string *key;
	zval value;
} apc_iterator_item_t;
/* }}} */

PHP_APCU_API void apc_iterator_obj_init(
	apc_iterator_t *iterator,
	zval *search,
	zend_long format,
	size_t chunk_size,
	zend_long list);
PHP_APCU_API zend_class_entry* apc_iterator_get_ce(void);
PHP_APCU_API int apc_iterator_init(int module_number);
PHP_APCU_API int apc_iterator_shutdown(int module_number);

extern int apc_iterator_delete(zval *key);
#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim>600: noexpandtab sw=4 ts=4 sts=4 fdm=marker
 * vim<600: noexpandtab sw=4 ts=4 sts=4
 */
php-zts/php/ext/apcu/apc_stack.h000064400000004353151730540210012574 0ustar00/*
  +----------------------------------------------------------------------+
  | APC                                                                  |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2011 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Daniel Cowgill <dcowgill@communityconnect.com>              |
  |          George Schlossnagle <george@omniti.com>                     |
  +----------------------------------------------------------------------+

   This software was contributed to PHP by Community Connect Inc. in 2002
   and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
   Future revisions and derivatives of this source code must acknowledge
   Community Connect Inc. as the original contributor of this module by
   leaving this note intact in the source code.

   All other licensing and usage conditions are those of the PHP Group.

 */

#ifndef APC_STACK_H
#define APC_STACK_H

/* Basic stack datatype */

#define T apc_stack_t*
typedef struct apc_stack_t apc_stack_t; /* opaque stack type */

extern T apc_stack_create(size_t size_hint);
extern void apc_stack_destroy(T stack);
extern void apc_stack_clear(T stack);
extern void apc_stack_push(T stack, void* item);
extern void* apc_stack_pop(T stack);
extern void* apc_stack_top(T stack);
extern void* apc_stack_get(T stack, size_t n);
extern int apc_stack_size(T stack);

#undef T
#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim>600: noexpandtab sw=4 ts=4 sts=4 fdm=marker
 * vim<600: noexpandtab sw=4 ts=4 sts=4
 */
php-zts/php/ext/apcu/apc.h000064400000013376151730540210011414 0ustar00/*
  +----------------------------------------------------------------------+
  | APC                                                                  |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2011 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Daniel Cowgill <dcowgill@communityconnect.com>              |
  |          George Schlossnagle <george@omniti.com>                     |
  |          Rasmus Lerdorf <rasmus@php.net>                             |
  |          Arun C. Murthy <arunc@yahoo-inc.com>                        |
  |          Gopal Vijayaraghavan <gopalv@yahoo-inc.com>                 |
  +----------------------------------------------------------------------+

   This software was contributed to PHP by Community Connect Inc. in 2002
   and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
   Future revisions and derivatives of this source code must acknowledge
   Community Connect Inc. as the original contributor of this module by
   leaving this note intact in the source code.

   All other licensing and usage conditions are those of the PHP Group.

 */

#ifndef APC_H
#define APC_H

/*
 * This module defines utilities and helper functions used elsewhere in APC.
 */
#ifdef PHP_WIN32
# define PHP_APCU_API __declspec(dllexport)
#elif defined(__GNUC__) && __GNUC__ >= 4
# define PHP_APCU_API __attribute__ ((visibility("default")))
#else
# define PHP_APCU_API
#endif

/* Commonly needed C library headers. */
#include <assert.h>
#include <errno.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

/* UNIX headers (needed for struct stat) */
#include <sys/types.h>
#include <sys/stat.h>
#ifndef PHP_WIN32
#include <unistd.h>
#endif

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include "php.h"
#include "main/php_streams.h"

/* console display functions */
PHP_APCU_API void apc_error(const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 1, 2);
PHP_APCU_API void apc_warning(const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 1, 2);
PHP_APCU_API void apc_notice(const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 1, 2);
PHP_APCU_API void apc_debug(const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 1, 2);

/* apc_flip_hash flips keys and values for faster searching */
PHP_APCU_API HashTable* apc_flip_hash(HashTable *hash);

#if defined(__GNUC__)
# define APC_UNUSED __attribute__((unused))
# define APC_USED __attribute__((used))
# define APC_ALLOC __attribute__((malloc))
# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__  > 2)
#  define APC_HOTSPOT __attribute__((hot))
# else
#  define APC_HOTSPOT
# endif
#else
# define APC_UNUSED
# define APC_USED
# define APC_ALLOC
# define APC_HOTSPOT
#endif

/*
* Serializer API
*/
#define APC_SERIALIZER_ABI "0"
#define APC_SERIALIZER_CONSTANT "\000apc_register_serializer-" APC_SERIALIZER_ABI

#define APC_SERIALIZER_NAME(module) module##_apc_serializer
#define APC_UNSERIALIZER_NAME(module) module##_apc_unserializer

#define APC_SERIALIZER_ARGS unsigned char **buf, size_t *buf_len, const zval *value, void *config
#define APC_UNSERIALIZER_ARGS zval *value, unsigned char *buf, size_t buf_len, void *config

typedef int (*apc_serialize_t)(APC_SERIALIZER_ARGS);
typedef int (*apc_unserialize_t)(APC_UNSERIALIZER_ARGS);

/* {{{ struct definition: apc_serializer_t */
typedef struct apc_serializer_t {
	const char*        name;
	apc_serialize_t    serialize;
	apc_unserialize_t  unserialize;
	void*              config;
} apc_serializer_t;
/* }}} */

/* {{{ _apc_register_serializer
 registers the serializer using the given name and parameters */
PHP_APCU_API int _apc_register_serializer(
        const char* name, apc_serialize_t serialize, apc_unserialize_t unserialize, void *config);
/* }}} */

/* {{{ apc_get_serializers
 fetches the list of serializers */
PHP_APCU_API apc_serializer_t* apc_get_serializers(void); /* }}} */

/* {{{ apc_find_serializer
 finds a previously registered serializer by name */
PHP_APCU_API apc_serializer_t* apc_find_serializer(const char* name); /* }}} */

/* {{{ default serializers */
PHP_APCU_API int APC_SERIALIZER_NAME(php) (APC_SERIALIZER_ARGS);
PHP_APCU_API int APC_UNSERIALIZER_NAME(php) (APC_UNSERIALIZER_ARGS); /* }}} */

#define php_apc_try                        \
{                                          \
	JMP_BUF *zb = EG(bailout);             \
	JMP_BUF ab;                            \
	zend_bool _bailout = 0;                \
	                                       \
	EG(bailout) = &ab;                     \
	if (SETJMP(ab) == SUCCESS) {

#define php_apc_finally                    \
	} else {                               \
		_bailout = 1;                      \
	}

#define php_apc_end_try()                  \
	EG(bailout) = zb;                      \
	if (_bailout) {                        \
		zend_bailout();                    \
	}                                      \
}

#define php_apc_try_finish() (EG(bailout) = zb)

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim>600: noexpandtab sw=4 ts=4 sts=4 fdm=marker
 * vim<600: noexpandtab sw=4 ts=4 sts=4
 */
php-zts/php/ext/apcu/apc_sma.h000064400000012753151730540210012252 0ustar00/*
  +----------------------------------------------------------------------+
  | APC                                                                  |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2011 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Daniel Cowgill <dcowgill@communityconnect.com>              |
  +----------------------------------------------------------------------+

   This software was contributed to PHP by Community Connect Inc. in 2002
   and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
   Future revisions and derivatives of this source code must acknowledge
   Community Connect Inc. as the original contributor of this module by
   leaving this note intact in the source code.

   All other licensing and usage conditions are those of the PHP Group.

 */

#ifndef APC_SMA_H
#define APC_SMA_H

/* {{{ SMA API
	APC SMA API provides support for shared memory allocators to external libraries ( and to APC )
	Skip to the bottom macros for error free usage of the SMA API
*/

#include "apc.h"

/* {{{ struct definition: apc_segment_t */
typedef struct _apc_segment_t {
	size_t size;            /* size of this segment */
	void* shmaddr;          /* address of shared memory */
#ifdef APC_MEMPROTECT
	void* roaddr;           /* read only (mprotect'd) address */
#endif
} apc_segment_t; /* }}} */

/* {{{ struct definition: apc_sma_link_t */
typedef struct apc_sma_link_t apc_sma_link_t;
struct apc_sma_link_t {
	zend_long size;              /* size of this free block */
	zend_long offset;            /* offset in segment of this block */
	apc_sma_link_t* next;   /* link to next free block */
};
/* }}} */

/* {{{ struct definition: apc_sma_info_t */
typedef struct apc_sma_info_t apc_sma_info_t;
struct apc_sma_info_t {
	int num_seg;            /* number of segments */
	size_t seg_size;        /* segment size */
	apc_sma_link_t** list;  /* one list per segment of links */
};
/* }}} */

typedef void (*apc_sma_expunge_f)(void *pointer, size_t size); /* }}} */

/* {{{ struct definition: apc_sma_t */
typedef struct _apc_sma_t {
	zend_bool initialized;         /* flag to indicate this sma has been initialized */

	/* callback */
	apc_sma_expunge_f expunge;     /* expunge */
	void** data;                   /* expunge data */

	/* info */
	int32_t  num;                  /* number of segments */
	size_t size;                   /* segment size */
	int32_t  last;                 /* last segment */

	/* segments */
	apc_segment_t *segs;           /* segments */
} apc_sma_t; /* }}} */

/*
* apc_sma_api_init will initialize a shared memory allocator with num segments of the given size
*
* should be called once per allocator per process
*/
PHP_APCU_API void apc_sma_init(
		apc_sma_t* sma, void** data, apc_sma_expunge_f expunge,
		int32_t num, size_t size, char *mask);

/*
 * apc_sma_detach will detach from shared memory and cleanup local allocations.
 */
PHP_APCU_API void apc_sma_detach(apc_sma_t* sma);

/*
* apc_smap_api_malloc will allocate a block from the sma of the given size
*/
PHP_APCU_API void* apc_sma_malloc(apc_sma_t* sma, size_t size);

/*
 * apc_sma_api_malloc_ex will allocate a block from the sma of the given size and
 * provide the size of the actual allocation.
 */
PHP_APCU_API void *apc_sma_malloc_ex(
		apc_sma_t *sma, size_t size, size_t *allocated);

/*
* apc_sma_api_free will free p (which should be a pointer to a block allocated from sma)
*/
PHP_APCU_API void apc_sma_free(apc_sma_t* sma, void* p);

/*
* apc_sma_api_protect will protect p (which should be a pointer to a block allocated from sma)
*/
PHP_APCU_API void* apc_sma_protect(apc_sma_t* sma, void* p);

/*
* apc_sma_api_protect will uprotect p (which should be a pointer to a block allocated from sma)
*/
PHP_APCU_API void* apc_sma_unprotect(apc_sma_t* sma, void *p);

/*
* apc_sma_api_info returns information about the allocator
*/
PHP_APCU_API apc_sma_info_t* apc_sma_info(apc_sma_t* sma, zend_bool limited);

/*
* apc_sma_api_info_free_info is for freeing apc_sma_info_t* returned by apc_sma_api_info
*/
PHP_APCU_API void apc_sma_free_info(apc_sma_t* sma, apc_sma_info_t* info);

/*
* apc_sma_api_get_avail_mem will return the amount of memory available left to sma
*/
PHP_APCU_API size_t apc_sma_get_avail_mem(apc_sma_t* sma);

/*
* apc_sma_api_get_avail_size will return true if at least size bytes are available to the sma
*/
PHP_APCU_API zend_bool apc_sma_get_avail_size(apc_sma_t* sma, size_t size);

/*
* apc_sma_api_check_integrity will check the integrity of sma
*/
PHP_APCU_API void apc_sma_check_integrity(apc_sma_t* sma); /* }}} */

/* {{{ ALIGNWORD: pad up x, aligned to the system's word boundary */
typedef union { void* p; int i; long l; double d; void (*f)(void); } apc_word_t;
#define ALIGNSIZE(x, size) ((size) * (1 + (((x)-1)/(size))))
#define ALIGNWORD(x) ALIGNSIZE(x, sizeof(apc_word_t))
/* }}} */

#endif

php-zts/php/ext/apcu/apc_mutex.h000064400000004366151730540210012635 0ustar00/*
  +----------------------------------------------------------------------+
  | APCu                                                                 |
  +----------------------------------------------------------------------+
  | Copyright (c) 2013 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: Joe Watkins <joe.watkins@live.co.uk>                        |
  +----------------------------------------------------------------------+
 */

#ifndef APC_MUTEX_H
#define APC_MUTEX_H

#include "apc.h"

#ifdef APC_HAS_PTHREAD_MUTEX

#include "pthread.h"

typedef pthread_mutex_t apc_mutex_t;

PHP_APCU_API zend_bool apc_mutex_init(void);
PHP_APCU_API void apc_mutex_cleanup(void);
PHP_APCU_API zend_bool apc_mutex_create(apc_mutex_t *lock);
PHP_APCU_API zend_bool apc_mutex_lock(apc_mutex_t *lock);
PHP_APCU_API zend_bool apc_mutex_unlock(apc_mutex_t *lock);
PHP_APCU_API void apc_mutex_destroy(apc_mutex_t *lock);

#define APC_MUTEX_INIT()          apc_mutex_init()
#define APC_MUTEX_CLEANUP()       apc_mutex_cleanup()

#define APC_CREATE_MUTEX(lock)    apc_mutex_create(lock)
#define APC_DESTROY_MUTEX(lock)   apc_mutex_destroy(lock)
#define APC_MUTEX_LOCK(lock)      apc_mutex_lock(lock)
#define APC_MUTEX_UNLOCK(lock)    apc_mutex_unlock(lock)

#else

#include "apc_lock.h"

typedef apc_lock_t apc_mutex_t;

// Fallback to normal locks

#define APC_MUTEX_INIT()
#define APC_MUTEX_CLEANUP()

#define APC_CREATE_MUTEX(lock)    CREATE_LOCK(lock)
#define APC_DESTROY_MUTEX(lock)   DESTROY_LOCK(lock)
#define APC_MUTEX_LOCK(lock)      WLOCK(lock)
#define APC_MUTEX_UNLOCK(lock)    WUNLOCK(lock)

#endif

#endif
php/sapi/cli/cli.h000064400000003551151730540220007761 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: Johannes Schlueter <johannes@php.net>                        |
  +----------------------------------------------------------------------+
*/

/* $Id$ */

#ifndef CLI_H
#define CLI_H

#ifdef PHP_WIN32
#   define PHP_CLI_API __declspec(dllexport)
#elif defined(__GNUC__) && __GNUC__ >= 4
#   define PHP_CLI_API __attribute__ ((visibility("default")))
#else
#   define PHP_CLI_API
#endif


extern PHP_CLI_API size_t sapi_cli_single_write(const char *str, size_t str_length);

typedef struct  {
	size_t (*cli_shell_write)(const char *str, size_t str_length);
	size_t (*cli_shell_ub_write)(const char *str, size_t str_length);
	int (*cli_shell_run)(void);
} cli_shell_callbacks_t;

extern PHP_CLI_API cli_shell_callbacks_t *php_cli_get_shell_callbacks();

#endif /* CLI_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/ext/pdo/php_pdo.h000064400000005743151730540220010527 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 5                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2010 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: Wez Furlong <wez@php.net>                                    |
  +----------------------------------------------------------------------+
*/

/* $Id: php_pdo.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_PDO_H
#define PHP_PDO_H

#include "zend.h"

#if PHP_MAJOR_VERSION > 5 || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1)
#define can_handle_soft_dependency_on_SPL 1
#endif

extern zend_module_entry pdo_module_entry;
#define phpext_pdo_ptr &pdo_module_entry

#ifdef PHP_WIN32
# if defined(PDO_EXPORTS) || (!defined(COMPILE_DL_PDO))
#  define PDO_API __declspec(dllexport)
# elif defined(COMPILE_DL_PDO)
#  define PDO_API __declspec(dllimport)
# else
#  define PDO_API /* nothing special */
# endif
#else
# define PDO_API /* nothing special */
#endif

#ifdef ZTS
# include "TSRM.h"
#endif

PHP_MINIT_FUNCTION(pdo);
PHP_MSHUTDOWN_FUNCTION(pdo);
PHP_MINFO_FUNCTION(pdo);

ZEND_BEGIN_MODULE_GLOBALS(pdo)
	long  global_value;
ZEND_END_MODULE_GLOBALS(pdo)

#ifdef ZTS
# define PDOG(v) TSRMG(pdo_globals_id, zend_pdo_globals *, v)
#else
# define PDOG(v) (pdo_globals.v)
#endif

#define REGISTER_PDO_CLASS_CONST_LONG(const_name, value) \
	zend_declare_class_constant_long(php_pdo_get_dbh_ce(), const_name, sizeof(const_name)-1, (long)value TSRMLS_CC);

#define REGISTER_PDO_CONST_LONG(const_name, value) { \
	zend_class_entry **pce;	\
	if (zend_hash_find(CG(class_table), "pdo", sizeof("pdo"), (void **) &pce) != FAILURE)	\
		zend_declare_class_constant_long(*pce, const_name, sizeof(const_name)-1, (long)value TSRMLS_CC);	\
}	\

#define REGISTER_PDO_CLASS_CONST_STRING(const_name, value) \
	zend_declare_class_constant_stringl(php_pdo_get_dbh_ce(), const_name, sizeof(const_name)-1, value, sizeof(value)-1 TSRMLS_CC);

#define PDO_CONSTRUCT_CHECK	\
	if (!dbh->driver) {	\
		pdo_raise_impl_error(dbh, NULL, "00000", "PDO constructor was not called" TSRMLS_CC);	\
		return;	\
	}	\


#endif	/* PHP_PDO_H */


/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/ext/pdo/php_pdo_error.h000064400000003665151730540220011741 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: Wez Furlong <wez@php.net>                                    |
  +----------------------------------------------------------------------+
*/

/* $Id$ */

#ifndef PHP_PDO_ERROR_H
#define PHP_PDO_ERROR_H

#include "php_pdo_driver.h"

PDO_API void pdo_handle_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt);

#define PDO_DBH_CLEAR_ERR()             do { \
	strlcpy(dbh->error_code, PDO_ERR_NONE, sizeof(PDO_ERR_NONE)); \
	if (dbh->query_stmt) { \
		dbh->query_stmt = NULL; \
		zval_ptr_dtor(&dbh->query_stmt_zval); \
	} \
} while (0)
#define PDO_STMT_CLEAR_ERR()    strcpy(stmt->error_code, PDO_ERR_NONE)
#define PDO_HANDLE_DBH_ERR()    if (strcmp(dbh->error_code, PDO_ERR_NONE)) { pdo_handle_error(dbh, NULL); }
#define PDO_HANDLE_STMT_ERR()   if (strcmp(stmt->error_code, PDO_ERR_NONE)) { pdo_handle_error(stmt->dbh, stmt); }

#endif /* PHP_PDO_ERROR_H */
/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/ext/pdo/php_pdo_driver.h000064400000056760151730540220012107 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 5                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2010 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: Wez Furlong <wez@php.net>                                    |
  +----------------------------------------------------------------------+
*/

/* $Id: php_pdo_driver.h 301252 2010-07-13 23:59:54Z kalle $ */

#ifndef PHP_PDO_DRIVER_H
#define PHP_PDO_DRIVER_H

#include "php_pdo.h"

/* forward declarations */
typedef struct _pdo_dbh_t 	pdo_dbh_t;
typedef struct _pdo_stmt_t	pdo_stmt_t;
struct pdo_bound_param_data;

#ifdef PHP_WIN32
typedef __int64 pdo_int64_t;
typedef unsigned __int64 pdo_uint64_t;
#else
typedef long long int pdo_int64_t;
typedef unsigned long long int pdo_uint64_t;
#endif
PDO_API char *php_pdo_int64_to_str(pdo_int64_t i64 TSRMLS_DC);

#ifndef TRUE
# define TRUE 1
#endif
#ifndef FALSE
# define FALSE 0
#endif

#define PDO_DRIVER_API	20060511

enum pdo_param_type {
	PDO_PARAM_NULL,

	/* int as in long (the php native int type).
	 * If you mark a column as an int, PDO expects get_col to return
	 * a pointer to a long */
	PDO_PARAM_INT,

	/* get_col ptr should point to start of the string buffer */
	PDO_PARAM_STR,

	/* get_col: when len is 0 ptr should point to a php_stream *,
	 * otherwise it should behave like a string. Indicate a NULL field
	 * value by setting the ptr to NULL */
	PDO_PARAM_LOB,

	/* get_col: will expect the ptr to point to a new PDOStatement object handle,
	 * but this isn't wired up yet */
	PDO_PARAM_STMT, /* hierarchical result set */

	/* get_col ptr should point to a zend_bool */
	PDO_PARAM_BOOL
};

/* magic flag to denote a parameter as being input/output */
#define	PDO_PARAM_INPUT_OUTPUT 	0x80000000	

#define PDO_PARAM_FLAGS			0xFFFF0000

#define PDO_PARAM_TYPE(x)		((x) & ~PDO_PARAM_FLAGS)

enum pdo_fetch_type {
	PDO_FETCH_USE_DEFAULT,
	PDO_FETCH_LAZY,
	PDO_FETCH_ASSOC,
	PDO_FETCH_NUM,
	PDO_FETCH_BOTH,
	PDO_FETCH_OBJ,
	PDO_FETCH_BOUND, /* return true/false only; rely on bound columns */
	PDO_FETCH_COLUMN,	/* fetch a numbered column only */
	PDO_FETCH_CLASS,	/* create an instance of named class, call ctor and set properties */
	PDO_FETCH_INTO,		/* fetch row into an existing object */
	PDO_FETCH_FUNC,		/* fetch into function and return its result */
	PDO_FETCH_NAMED,    /* like PDO_FETCH_ASSOC, but can handle duplicate names */
	PDO_FETCH_KEY_PAIR,	/* fetch into an array where the 1st column is a key and all subsequent columns are values */
	PDO_FETCH__MAX /* must be last */
};

#define PDO_FETCH_FLAGS     0xFFFF0000  /* fetchAll() modes or'd to PDO_FETCH_XYZ */
#define PDO_FETCH_GROUP     0x00010000  /* fetch into groups */
#define PDO_FETCH_UNIQUE    0x00030000  /* fetch into groups assuming first col is unique */
#define PDO_FETCH_CLASSTYPE 0x00040000  /* fetch class gets its class name from 1st column */
#define PDO_FETCH_SERIALIZE 0x00080000  /* fetch class instances by calling serialize */
#define PDO_FETCH_PROPS_LATE 0x00100000  /* fetch props after calling ctor */

/* fetch orientation for scrollable cursors */
enum pdo_fetch_orientation {
	PDO_FETCH_ORI_NEXT,		/* default: fetch the next available row */
	PDO_FETCH_ORI_PRIOR,	/* scroll back to prior row and fetch that */
	PDO_FETCH_ORI_FIRST,	/* scroll to the first row and fetch that */
	PDO_FETCH_ORI_LAST,		/* scroll to the last row and fetch that */
	PDO_FETCH_ORI_ABS,		/* scroll to an absolute numbered row and fetch that */
	PDO_FETCH_ORI_REL		/* scroll relative to the current row, and fetch that */
};

enum pdo_attribute_type {
	PDO_ATTR_AUTOCOMMIT,	/* use to turn on or off auto-commit mode */
	PDO_ATTR_PREFETCH,		/* configure the prefetch size for drivers that support it. Size is in KB */
	PDO_ATTR_TIMEOUT,		/* connection timeout in seconds */
	PDO_ATTR_ERRMODE,		/* control how errors are handled */
	PDO_ATTR_SERVER_VERSION,	/* database server version */
	PDO_ATTR_CLIENT_VERSION,	/* client library version */
	PDO_ATTR_SERVER_INFO,		/* server information */
	PDO_ATTR_CONNECTION_STATUS,	/* connection status */
	PDO_ATTR_CASE,				/* control case folding for portability */
	PDO_ATTR_CURSOR_NAME,		/* name a cursor for use in "WHERE CURRENT OF <name>" */
	PDO_ATTR_CURSOR,			/* cursor type */
	PDO_ATTR_ORACLE_NULLS,		/* convert empty strings to NULL */
	PDO_ATTR_PERSISTENT,		/* pconnect style connection */
	PDO_ATTR_STATEMENT_CLASS,	/* array(classname, array(ctor_args)) to specify the class of the constructed statement */
	PDO_ATTR_FETCH_TABLE_NAMES, /* include table names in the column names, where available */
	PDO_ATTR_FETCH_CATALOG_NAMES, /* include the catalog/db name names in the column names, where available */
	PDO_ATTR_DRIVER_NAME,		  /* name of the driver (as used in the constructor) */
	PDO_ATTR_STRINGIFY_FETCHES,	/* converts integer/float types to strings during fetch */
	PDO_ATTR_MAX_COLUMN_LEN,	/* make database calculate maximum length of data found in a column */
	PDO_ATTR_DEFAULT_FETCH_MODE, /* Set the default fetch mode */
	PDO_ATTR_EMULATE_PREPARES,  /* use query emulation rather than native */

	/* this defines the start of the range for driver specific options.
	 * Drivers should define their own attribute constants beginning with this
	 * value. */
	PDO_ATTR_DRIVER_SPECIFIC = 1000
};

enum pdo_cursor_type {
	PDO_CURSOR_FWDONLY,		/* forward only cursor (default) */
	PDO_CURSOR_SCROLL		/* scrollable cursor */
};

/* SQL-92 SQLSTATE error codes.

The character string value returned for an SQLSTATE consists of a two-character
class value followed by a three-character subclass value. A class value of 01
indicates a warning and is accompanied by a return code of
SQL_SUCCESS_WITH_INFO.

Class values other than '01', except for the class 'IM',
indicate an error and are accompanied by a return code of SQL_ERROR. The class
'IM' is specific to warnings and errors that derive from the implementation of
ODBC itself.

The subclass value '000' in any class indicates that there is no
subclass for that SQLSTATE. The assignment of class and subclass values is
defined by SQL-92.
*/

typedef char pdo_error_type[6]; /* SQLSTATE */


#define PDO_ERR_NONE				"00000"

enum pdo_error_mode {
	PDO_ERRMODE_SILENT,		/* just set error codes */
	PDO_ERRMODE_WARNING,	/* raise E_WARNING */
	PDO_ERRMODE_EXCEPTION	/* throw exceptions */
};

enum pdo_case_conversion {
	PDO_CASE_NATURAL,
	PDO_CASE_UPPER,
	PDO_CASE_LOWER
};

/* oracle interop settings */
enum pdo_null_handling {
	PDO_NULL_NATURAL = 0,
	PDO_NULL_EMPTY_STRING = 1,
	PDO_NULL_TO_STRING = 2
};

/* {{{ utils for reading attributes set as driver_options */
static inline long pdo_attr_lval(zval *options, enum pdo_attribute_type option_name, long defval TSRMLS_DC)
{
	zval **v;

	if (options && SUCCESS == zend_hash_index_find(Z_ARRVAL_P(options), option_name, (void**)&v)) {
		convert_to_long_ex(v);
		return Z_LVAL_PP(v);
	}
	return defval;
}
static inline char *pdo_attr_strval(zval *options, enum pdo_attribute_type option_name, char *defval TSRMLS_DC)
{
	zval **v;

	if (options && SUCCESS == zend_hash_index_find(Z_ARRVAL_P(options), option_name, (void**)&v)) {
		convert_to_string_ex(v);
		return estrndup(Z_STRVAL_PP(v), Z_STRLEN_PP(v));
	}
	return defval ? estrdup(defval) : NULL;
}
/* }}} */

/* This structure is registered with PDO when a PDO driver extension is
 * initialized */
typedef struct {
	const char		*driver_name;
	unsigned long	driver_name_len;
	unsigned long	api_version; /* needs to be compatible with PDO */

#define PDO_DRIVER_HEADER(name)	\
	#name, sizeof(#name)-1, \
	PDO_DRIVER_API
	
	/* create driver specific portion of the database handle and stash it into
	 * the dbh.  dbh contains the data source string and flags for this
	 * instance.  You MUST respect dbh->is_persistent and pass that flag to
	 * pemalloc() for all allocations that are stored in the dbh or your instance
	 * data in the db, otherwise you will crash PHP when persistent connections
	 * are used.
	 */
	int (*db_handle_factory)(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC);

} pdo_driver_t;

/* {{{ methods for a database handle */

/* close or otherwise disconnect the database */
typedef int (*pdo_dbh_close_func)(pdo_dbh_t *dbh TSRMLS_DC);

/* prepare a statement and stash driver specific portion into stmt */
typedef int (*pdo_dbh_prepare_func)(pdo_dbh_t *dbh, const char *sql, long sql_len, pdo_stmt_t *stmt, zval *driver_options TSRMLS_DC);

/* execute a statement (that does not return a result set) */
typedef long (*pdo_dbh_do_func)(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC);

/* quote a string */
typedef int (*pdo_dbh_quote_func)(pdo_dbh_t *dbh, const char *unquoted, int unquotedlen, char **quoted, int *quotedlen, enum pdo_param_type paramtype TSRMLS_DC);

/* transaction related */
typedef int (*pdo_dbh_txn_func)(pdo_dbh_t *dbh TSRMLS_DC);

/* setting of attributes */
typedef int (*pdo_dbh_set_attr_func)(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC);

/* return last insert id.  NULL indicates error condition, otherwise, the return value
 * MUST be an emalloc'd NULL terminated string. */
typedef char *(*pdo_dbh_last_id_func)(pdo_dbh_t *dbh, const char *name, unsigned int *len TSRMLS_DC);

/* fetch error information.  if stmt is not null, fetch information pertaining
 * to the statement, otherwise fetch global error information.  The driver
 * should add the following information to the array "info" in this order:
 * - native error code
 * - string representation of the error code ... any other optional driver
 *   specific data ...  */
typedef	int (*pdo_dbh_fetch_error_func)(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info TSRMLS_DC);

/* fetching of attributes */
typedef int (*pdo_dbh_get_attr_func)(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC);

/* checking/pinging persistent connections; return SUCCESS if the connection
 * is still alive and ready to be used, FAILURE otherwise.
 * You may set this handler to NULL, which is equivalent to returning SUCCESS. */
typedef int (*pdo_dbh_check_liveness_func)(pdo_dbh_t *dbh TSRMLS_DC);

/* called at request end for each persistent dbh; this gives the driver
 * the opportunity to safely release resources that only have per-request
 * scope */
typedef void (*pdo_dbh_request_shutdown)(pdo_dbh_t *dbh TSRMLS_DC);

/* for adding methods to the dbh or stmt objects 
pointer to a list of driver specific functions. The convention is
to prefix the function names using the PDO driver name; this will
reduce the chance of collisions with future functionality in the
PDO class or in user code (they can extend the PDO object).
*/
enum {
	PDO_DBH_DRIVER_METHOD_KIND_DBH = 0,
	PDO_DBH_DRIVER_METHOD_KIND_STMT,
	PDO_DBH_DRIVER_METHOD_KIND__MAX
};

typedef zend_function_entry *(*pdo_dbh_get_driver_methods_func)(pdo_dbh_t *dbh, int kind TSRMLS_DC);

struct pdo_dbh_methods {
	pdo_dbh_close_func		closer;
	pdo_dbh_prepare_func	preparer;
	pdo_dbh_do_func			doer;
	pdo_dbh_quote_func		quoter;
	pdo_dbh_txn_func		begin;
	pdo_dbh_txn_func		commit;
	pdo_dbh_txn_func		rollback;
	pdo_dbh_set_attr_func	set_attribute;
	pdo_dbh_last_id_func		last_id;
	pdo_dbh_fetch_error_func	fetch_err;
	pdo_dbh_get_attr_func   	get_attribute;
	pdo_dbh_check_liveness_func	check_liveness;
	pdo_dbh_get_driver_methods_func get_driver_methods;
	pdo_dbh_request_shutdown	persistent_shutdown;
};

/* }}} */

/* {{{ methods for a statement handle */

/* free the statement handle */
typedef int (*pdo_stmt_dtor_func)(pdo_stmt_t *stmt TSRMLS_DC);

/* start the query */
typedef int (*pdo_stmt_execute_func)(pdo_stmt_t *stmt TSRMLS_DC);

/* causes the next row in the set to be fetched; indicates if there are no
 * more rows.  The ori and offset params modify which row should be returned,
 * if the stmt represents a scrollable cursor */
typedef int (*pdo_stmt_fetch_func)(pdo_stmt_t *stmt, 
	enum pdo_fetch_orientation ori, long offset TSRMLS_DC);

/* queries information about the type of a column, by index (0 based).
 * Driver should populate stmt->columns[colno] with appropriate info */
typedef int (*pdo_stmt_describe_col_func)(pdo_stmt_t *stmt, int colno TSRMLS_DC);

/* retrieves pointer and size of the value for a column.
 * Note that PDO expects the driver to manage the lifetime of this data;
 * it will copy the value into a zval on behalf of the script.
 * If the driver sets caller_frees, ptr should point to emalloc'd memory
 * and PDO will free it as soon as it is done using it.
 */
typedef int (*pdo_stmt_get_col_data_func)(pdo_stmt_t *stmt, int colno, char **ptr, unsigned long *len, int *caller_frees TSRMLS_DC);

/* hook for bound params */
enum pdo_param_event {
	PDO_PARAM_EVT_ALLOC,
	PDO_PARAM_EVT_FREE,
	PDO_PARAM_EVT_EXEC_PRE,
	PDO_PARAM_EVT_EXEC_POST,
	PDO_PARAM_EVT_FETCH_PRE,
	PDO_PARAM_EVT_FETCH_POST,
	PDO_PARAM_EVT_NORMALIZE
};

typedef int (*pdo_stmt_param_hook_func)(pdo_stmt_t *stmt, struct pdo_bound_param_data *param, enum pdo_param_event event_type TSRMLS_DC);

/* setting of attributes */
typedef int (*pdo_stmt_set_attr_func)(pdo_stmt_t *stmt, long attr, zval *val TSRMLS_DC);

/* fetching of attributes */
typedef int (*pdo_stmt_get_attr_func)(pdo_stmt_t *stmt, long attr, zval *val TSRMLS_DC);

/* retrieves meta data for a numbered column.
 * Returns SUCCESS/FAILURE.
 * On SUCCESS, fill in return_value with an array with the following fields.
 * If a particular field is not supported, then the driver simply does not add it to
 * the array, so that scripts can use isset() to check for it.
 *
 * ### this is just a rough first cut, and subject to change ###
 *
 * these are added by PDO itself, based on data from the describe handler:
 *   name => the column name
 *   len => the length/size of the column
 *   precision => precision of the column
 *   pdo_type => an integer, one of the PDO_PARAM_XXX values
 *
 *   scale => the floating point scale
 *   table => the table for that column
 *   type => a string representation of the type, mapped to the PHP equivalent type name
 *   native_type => a string representation of the type, native style, if different from
 *                  the mapped name.
 *   flags => an array of flags including zero or more of the following:
 *            primary_key, not_null, unique_key, multiple_key, unsigned, auto_increment, blob
 *
 * Any driver specific data should be returned using a prefixed key or value.
 * Eg: custom data for the mysql driver would use either
 *   'mysql:foobar' => 'some data' // to add a new key to the array
 * or
 *   'flags' => array('not_null', 'mysql:some_flag'); // to add data to an existing key
 */
typedef int (*pdo_stmt_get_column_meta_func)(pdo_stmt_t *stmt, long colno, zval *return_value TSRMLS_DC);

/* advances the statement to the next rowset of the batch.
 * If it returns 1, PDO will tear down its idea of columns
 * and meta data.  If it returns 0, PDO will indicate an error
 * to the caller. */
typedef int (*pdo_stmt_next_rowset_func)(pdo_stmt_t *stmt TSRMLS_DC);

/* closes the active cursor on a statement, leaving the prepared
 * statement ready for re-execution.  Useful to explicitly state
 * that you are done with a given rowset, without having to explicitly
 * fetch all the rows. */
typedef int (*pdo_stmt_cursor_closer_func)(pdo_stmt_t *stmt TSRMLS_DC);

struct pdo_stmt_methods {
	pdo_stmt_dtor_func			dtor;
	pdo_stmt_execute_func		executer;
	pdo_stmt_fetch_func			fetcher;
	pdo_stmt_describe_col_func	describer;
	pdo_stmt_get_col_data_func	get_col;
	pdo_stmt_param_hook_func	param_hook;
	pdo_stmt_set_attr_func		set_attribute;
	pdo_stmt_get_attr_func		get_attribute;
	pdo_stmt_get_column_meta_func get_column_meta;
	pdo_stmt_next_rowset_func		next_rowset;
	pdo_stmt_cursor_closer_func 	cursor_closer;
};

/* }}} */

enum pdo_placeholder_support {
	PDO_PLACEHOLDER_NONE=0,
	PDO_PLACEHOLDER_NAMED=1,
	PDO_PLACEHOLDER_POSITIONAL=2
};

/* represents a connection to a database */
struct _pdo_dbh_t {
	/* these items must appear in this order at the beginning of the
       struct so that this can be cast as a zend_object.  we need this
       to allow the extending class to escape all the custom handlers
	   that PDO declares.
    */
	zend_class_entry *ce; 
	HashTable *properties;
	unsigned int in_get:1;
	unsigned int in_set:1;

	/* driver specific methods */
	struct pdo_dbh_methods *methods;
	/* driver specific data */
	void *driver_data;

	/* credentials */
	char *username, *password;
	
	/* if true, then data stored and pointed at by this handle must all be
	 * persistently allocated */
	unsigned is_persistent:1;

	/* if true, driver should act as though a COMMIT were executed between
	 * each executed statement; otherwise, COMMIT must be carried out manually
	 * */
	unsigned auto_commit:1;

	/* if true, the handle has been closed and will not function anymore */
	unsigned is_closed:1;

	/* if true, the driver requires that memory be allocated explicitly for
	 * the columns that are returned */
	unsigned alloc_own_columns:1;

	/* if true, commit or rollBack is allowed to be called */
	unsigned in_txn:1;

	/* max length a single character can become after correct quoting */
	unsigned max_escaped_char_length:3;

	/* oracle compat; see enum pdo_null_handling */
	unsigned oracle_nulls:2;

	/* when set, convert int/floats to strings */
	unsigned stringify:1;

	/* the sum of the number of bits here and the bit fields preceeding should
	 * equal 32 */
	unsigned _reserved_flags:21;

	/* data source string used to open this handle */
	const char *data_source;
	unsigned long data_source_len;

	/* the global error code. */
	pdo_error_type error_code;

	enum pdo_error_mode error_mode;

	enum pdo_case_conversion native_case, desired_case;

	/* persistent hash key associated with this handle */
	const char *persistent_id;
	int persistent_id_len;
	unsigned int refcount;

	/* driver specific "class" methods for the dbh and stmt */
	HashTable *cls_methods[PDO_DBH_DRIVER_METHOD_KIND__MAX];

	pdo_driver_t *driver;
	
	zend_class_entry *def_stmt_ce;

	zval *def_stmt_ctor_args;

	/* when calling PDO::query(), we need to keep the error
	 * context from the statement around until we next clear it.
	 * This will allow us to report the correct error message
	 * when PDO::query() fails */
	pdo_stmt_t *query_stmt;
	zval query_stmt_zval;

	/* defaults for fetches */
	enum pdo_fetch_type default_fetch_type;
};

/* describes a column */
struct pdo_column_data {
	char *name;
	int namelen;
	unsigned long maxlen;
	enum pdo_param_type param_type;
	unsigned long precision;

	/* don't touch this unless your name is dbdo */
	void *dbdo_data;
};

/* describes a bound parameter */
struct pdo_bound_param_data {
	long paramno; /* if -1, then it has a name, and we don't know the index *yet* */
	char *name;
	int namelen;

	long max_value_len;	/* as a hint for pre-allocation */
	
	zval *parameter;				/* the variable itself */
	enum pdo_param_type param_type; /* desired or suggested type */

	zval *driver_params;			/* optional parameter(s) for the driver */
	void *driver_data;

	pdo_stmt_t *stmt;	/* for convenience in dtor */
	int is_param;		/* parameter or column ? */
};

/* represents a prepared statement */
struct _pdo_stmt_t {
	/* these items must appear in this order at the beginning of the
       struct so that this can be cast as a zend_object.  we need this
       to allow the extending class to escape all the custom handlers
	   that PDO declares.
    */
	zend_class_entry *ce; 
	HashTable *properties;
	unsigned int in_get:1;
	unsigned int in_set:1;

	/* driver specifics */
	struct pdo_stmt_methods *methods;
	void *driver_data;

	/* if true, we've already successfully executed this statement at least
	 * once */
	unsigned executed:1;
	/* if true, the statement supports placeholders and can implement
	 * bindParam() for its prepared statements, if false, PDO should
	 * emulate prepare and bind on its behalf */
	unsigned supports_placeholders:2;

	unsigned _reserved:29;

	/* the number of columns in the result set; not valid until after
	 * the statement has been executed at least once.  In some cases, might
	 * not be valid until fetch (at the driver level) has been called at least once.
	 * */
	int column_count;
	struct pdo_column_data *columns;
	
	/* we want to keep the dbh alive while we live, so we own a reference */
	zval database_object_handle;
	pdo_dbh_t *dbh;

	/* keep track of bound input parameters.  Some drivers support
	 * input/output parameters, but you can't rely on that working */
	HashTable *bound_params;
	/* When rewriting from named to positional, this maps positions to names */
	HashTable *bound_param_map;
	/* keep track of PHP variables bound to named (or positional) columns
	 * in the result set */
	HashTable *bound_columns;

	/* not always meaningful */
	long row_count;

	/* used to hold the statement's current query */
	char *query_string;
	int query_stringlen;

	/* the copy of the query with expanded binds ONLY for emulated-prepare drivers */
	char *active_query_string;
	int active_query_stringlen;

	/* the cursor specific error code. */
	pdo_error_type error_code;

	/* for lazy fetches, we always return the same lazy object handle.
	 * Let's keep it here. */
	zval lazy_object_ref;
	unsigned long refcount;

	/* defaults for fetches */
	enum pdo_fetch_type default_fetch_type;
	union {
		int column;
		struct {
			zend_class_entry *ce;	
			zval *ctor_args;            /* freed */
			zval *retval_ptr; 
			zend_fcall_info fci;
			zend_fcall_info_cache fcc;
		} cls;
		struct {
			zval *function;
			zval *fetch_args;           /* freed */
			zval *object;
			zend_fcall_info fci;
			zend_fcall_info_cache fcc;
			zval **values;              /* freed */
		} func;
		zval *into;
	} fetch;

	/* used by the query parser for driver specific
	 * parameter naming (see pgsql driver for example) */
	const char *named_rewrite_template;
};

/* call this in MINIT to register your PDO driver */
PDO_API int php_pdo_register_driver(pdo_driver_t *driver);
/* call this in MSHUTDOWN to unregister your PDO driver */
PDO_API void php_pdo_unregister_driver(pdo_driver_t *driver);

/* For the convenience of drivers, this function will parse a data source
 * string, of the form "name=value; name2=value2" and populate variables
 * according to the data you pass in and array of pdo_data_src_parser structures */
struct pdo_data_src_parser {
	const char *optname;
	char *optval;
	int freeme;
};

PDO_API int php_pdo_parse_data_source(const char *data_source,
		unsigned long data_source_len, struct pdo_data_src_parser *parsed,
		int nparams);

PDO_API zend_class_entry *php_pdo_get_dbh_ce(void);
PDO_API zend_class_entry *php_pdo_get_exception(void);

PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len, 
	char **outquery, int *outquery_len TSRMLS_DC);

PDO_API void pdo_raise_impl_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt,
	const char *sqlstate, const char *supp TSRMLS_DC);

PDO_API void php_pdo_dbh_addref(pdo_dbh_t *dbh TSRMLS_DC);
PDO_API void php_pdo_dbh_delref(pdo_dbh_t *dbh TSRMLS_DC);

PDO_API void php_pdo_stmt_addref(pdo_stmt_t *stmt TSRMLS_DC);
PDO_API void php_pdo_stmt_delref(pdo_stmt_t *stmt TSRMLS_DC);


#endif /* PHP_PDO_DRIVER_H */
/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/ext/sockets/php_sockets.h000064400000006655151730540220012314 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 7                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2018 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Chris Vandomelen <chrisv@b0rked.dhs.org>                    |
   |          Sterling Hughes  <sterling@php.net>                         |
   |                                                                      |
   | WinSock: Daniel Beulshausen <daniel@php4win.de>                      |
   +----------------------------------------------------------------------+
 */

#ifndef PHP_SOCKETS_H
#define PHP_SOCKETS_H

/* $Id$ */

#if HAVE_CONFIG_H
# include "config.h"
#endif

#if HAVE_SOCKETS

#include <php.h>
#ifdef PHP_WIN32
# include "windows_common.h"
#endif

#define PHP_SOCKETS_VERSION PHP_VERSION

extern zend_module_entry sockets_module_entry;
#define phpext_sockets_ptr &sockets_module_entry

#ifdef PHP_WIN32
#include <Winsock2.h>
#else
#if HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#endif

#ifndef PHP_WIN32
typedef int PHP_SOCKET;
# define PHP_SOCKETS_API PHPAPI
#else
# define PHP_SOCKETS_API __declspec(dllexport)
typedef SOCKET PHP_SOCKET;
#endif

typedef struct {
	PHP_SOCKET	bsd_socket;
	int			type;
	int			error;
	int			blocking;
	zval		zstream;
} php_socket;

#ifdef PHP_WIN32
struct	sockaddr_un {
	short	sun_family;
	char	sun_path[108];
};
#endif

PHP_SOCKETS_API int php_sockets_le_socket(void);
PHP_SOCKETS_API php_socket *php_create_socket(void);
PHP_SOCKETS_API void php_destroy_socket(zend_resource *rsrc);
PHP_SOCKETS_API void php_destroy_sockaddr(zend_resource *rsrc);

#define php_sockets_le_socket_name "Socket"
#define php_sockets_le_addrinfo_name "AddressInfo"

#define PHP_SOCKET_ERROR(socket, msg, errn) \
		do { \
			int _err = (errn); /* save value to avoid repeated calls to WSAGetLastError() on Windows */ \
			(socket)->error = _err; \
			SOCKETS_G(last_error) = _err; \
			if (_err != EAGAIN && _err != EWOULDBLOCK && _err != EINPROGRESS) { \
				php_error_docref(NULL, E_WARNING, "%s [%d]: %s", msg, _err, sockets_strerror(_err)); \
			} \
		} while (0)

ZEND_BEGIN_MODULE_GLOBALS(sockets)
	int last_error;
	char *strerror_buf;
ZEND_END_MODULE_GLOBALS(sockets)

ZEND_EXTERN_MODULE_GLOBALS(sockets)
#define SOCKETS_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(sockets, v)

enum sockopt_return {
	SOCKOPT_ERROR,
	SOCKOPT_CONTINUE,
	SOCKOPT_SUCCESS
};

char *sockets_strerror(int error);
php_socket *socket_import_file_descriptor(PHP_SOCKET sock);

#else
#define phpext_sockets_ptr NULL
#endif

#if defined(_AIX) && !defined(HAVE_SA_SS_FAMILY)
# define ss_family __ss_family
#endif

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 */
php/ext/libxml/php_libxml.h000064400000014001151730540220011724 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Shane Caraveo <shane@php.net>                               |
   |          Wez Furlong <wez@thebrainroom.com>                          |
   +----------------------------------------------------------------------+
*/

/* $Id: php_libxml.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_LIBXML_H
#define PHP_LIBXML_H

#if HAVE_LIBXML
extern zend_module_entry libxml_module_entry;
#define libxml_module_ptr &libxml_module_entry

#ifdef PHP_WIN32
#define PHP_LIBXML_API __declspec(dllexport)
#else
#define PHP_LIBXML_API
#endif

#include "ext/standard/php_smart_str.h"
#include <libxml/tree.h>

#define LIBXML_SAVE_NOEMPTYTAG 1<<2

ZEND_BEGIN_MODULE_GLOBALS(libxml)
	zval *stream_context;
	smart_str error_buffer;
	zend_llist *error_list;
	zend_bool entity_loader_disabled;
ZEND_END_MODULE_GLOBALS(libxml)

typedef struct _libxml_doc_props {
	int formatoutput;
	int validateonparse;
	int resolveexternals;
	int preservewhitespace;
	int substituteentities;
	int stricterror;
	int recover;
	HashTable *classmap;
} libxml_doc_props;

typedef struct _php_libxml_ref_obj {
	void *ptr;
	int   refcount;
	libxml_doc_props *doc_props;
} php_libxml_ref_obj;

typedef struct _php_libxml_node_ptr {
	xmlNodePtr node;
	int	refcount;
	void *_private;
} php_libxml_node_ptr;

typedef struct _php_libxml_node_object {
	zend_object  std;
	php_libxml_node_ptr *node;
	php_libxml_ref_obj *document;
	HashTable *properties;
} php_libxml_node_object;

typedef void * (*php_libxml_export_node) (zval *object TSRMLS_DC);

PHP_LIBXML_API int php_libxml_increment_node_ptr(php_libxml_node_object *object, xmlNodePtr node, void *private_data TSRMLS_DC);
PHP_LIBXML_API int php_libxml_decrement_node_ptr(php_libxml_node_object *object TSRMLS_DC);
PHP_LIBXML_API int php_libxml_increment_doc_ref(php_libxml_node_object *object, xmlDocPtr docp TSRMLS_DC);
PHP_LIBXML_API int php_libxml_decrement_doc_ref(php_libxml_node_object *object TSRMLS_DC);
PHP_LIBXML_API xmlNodePtr php_libxml_import_node(zval *object TSRMLS_DC);
PHP_LIBXML_API int php_libxml_register_export(zend_class_entry *ce, php_libxml_export_node export_function);
/* When an explicit freeing of node and children is required */
void php_libxml_node_free_resource(xmlNodePtr node TSRMLS_DC);
/* When object dtor is called as node may still be referenced */
void php_libxml_node_decrement_resource(php_libxml_node_object *object TSRMLS_DC);
PHP_LIBXML_API void php_libxml_error_handler(void *ctx, const char *msg, ...);
void php_libxml_ctx_warning(void *ctx, const char *msg, ...);
void php_libxml_ctx_error(void *ctx, const char *msg, ...);
PHP_LIBXML_API int php_libxml_xmlCheckUTF8(const unsigned char *s);
PHP_LIBXML_API zval *php_libxml_switch_context(zval *context TSRMLS_DC);
PHP_LIBXML_API void php_libxml_issue_error(int level, const char *msg TSRMLS_DC);
PHP_LIBXML_API zend_bool php_libxml_disable_entity_loader(zend_bool disable TSRMLS_DC);

/* Init/shutdown functions*/
PHP_LIBXML_API void php_libxml_initialize(void);
PHP_LIBXML_API void php_libxml_shutdown(void);

#ifdef ZTS
#define LIBXML(v) TSRMG(libxml_globals_id, zend_libxml_globals *, v)
#else
#define LIBXML(v) (libxml_globals.v)
#endif

/* Other extension may override the global state options, these global options
 * are copied initially to ctxt->options. Set the options to a known good value.
 * See libxml2 globals.c and parserInternals.c.
 * The unique_name argument allows multiple sanitizes and restores within the
 * same function, even nested is necessary. */
#define PHP_LIBXML_SANITIZE_GLOBALS(unique_name) \
	int xml_old_loadsubset_##unique_name = xmlLoadExtDtdDefaultValue; \
	xmlLoadExtDtdDefaultValue = 0; \
	int xml_old_validate_##unique_name = xmlDoValidityCheckingDefaultValue; \
	xmlDoValidityCheckingDefaultValue = 0; \
	int xml_old_pedantic_##unique_name = xmlPedanticParserDefault(0); \
	int xml_old_substitute_##unique_name = xmlSubstituteEntitiesDefault(0); \
	int xml_old_linenrs_##unique_name = xmlLineNumbersDefault(0); \
	int xml_old_blanks_##unique_name = xmlKeepBlanksDefault(1);

#define PHP_LIBXML_RESTORE_GLOBALS(unique_name) \
	xmlLoadExtDtdDefaultValue = xml_old_loadsubset_##unique_name; \
	xmlDoValidityCheckingDefaultValue = xml_old_validate_##unique_name; \
	(void) xmlPedanticParserDefault(xml_old_pedantic_##unique_name); \
	(void) xmlSubstituteEntitiesDefault(xml_old_substitute_##unique_name); \
	(void) xmlLineNumbersDefault(xml_old_linenrs_##unique_name); \
	(void) xmlKeepBlanksDefault(xml_old_blanks_##unique_name);

/* Alternative for above, working directly on the context and not setting globals.
 * Generally faster because no locking is involved, and this has the advantage that it sets the options to a known good value. */
static void php_libxml_sanitize_parse_ctxt_options(xmlParserCtxtPtr ctxt)
{
	ctxt->loadsubset = 0;
	ctxt->validate = 0;
	ctxt->pedantic = 0;
	ctxt->replaceEntities = 0;
	ctxt->linenumbers = 0;
	ctxt->keepBlanks = 1;
	ctxt->options = 0;
}

#else /* HAVE_LIBXML */
#define libxml_module_ptr NULL
#endif

#define phpext_libxml_ptr libxml_module_ptr

#endif /* PHP_LIBXML_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 */
php/ext/xml/expat_compat.h000064400000014023151730540220011567 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Sterling Hughes <sterling@php.net>                          |
   +----------------------------------------------------------------------+
*/

/* $Id: expat_compat.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_EXPAT_COMPAT_H
#define PHP_EXPAT_COMPAT_H

#ifdef PHP_WIN32
#include "config.w32.h"
#else
#include <php_config.h>
#endif

#if !defined(HAVE_LIBEXPAT) && defined(HAVE_LIBXML)
#define LIBXML_EXPAT_COMPAT 1

#include "php.h"
#include "php_compat.h"

#include <libxml/parser.h>
#include <libxml/parserInternals.h>
#include <libxml/tree.h>
#include <libxml/hash.h>

typedef xmlChar XML_Char;

typedef void (*XML_StartElementHandler)(void *, const XML_Char *, const XML_Char **);
typedef void (*XML_EndElementHandler)(void *, const XML_Char *);
typedef void (*XML_CharacterDataHandler)(void *, const XML_Char *, int);
typedef void (*XML_ProcessingInstructionHandler)(void *, const XML_Char *, const XML_Char *);
typedef void (*XML_CommentHandler)(void *, const XML_Char *);
typedef void (*XML_DefaultHandler)(void *, const XML_Char *, int);
typedef void (*XML_UnparsedEntityDeclHandler)(void *, const XML_Char *, const XML_Char *, const XML_Char *, const XML_Char *, const XML_Char *);
typedef void (*XML_NotationDeclHandler)(void *, const XML_Char *, const XML_Char *, const XML_Char *, const XML_Char *);
typedef int  (*XML_ExternalEntityRefHandler)(void *, const XML_Char *, const XML_Char *, const XML_Char *, const XML_Char *);
typedef void (*XML_StartNamespaceDeclHandler)(void *, const XML_Char *, const XML_Char *);
typedef void (*XML_EndNamespaceDeclHandler)(void *, const XML_Char *);

typedef struct _XML_Memory_Handling_Suite {
  void *(*malloc_fcn)(size_t size);
  void *(*realloc_fcn)(void *ptr, size_t size);
  void (*free_fcn)(void *ptr);
} XML_Memory_Handling_Suite;

typedef struct _XML_Parser {
	int use_namespace;

	xmlChar *_ns_seperator;

	void *user;
	xmlParserCtxtPtr parser;

	XML_StartElementHandler          h_start_element;
	XML_EndElementHandler            h_end_element;
	XML_CharacterDataHandler         h_cdata;
	XML_ProcessingInstructionHandler h_pi;
	XML_CommentHandler               h_comment;
	XML_DefaultHandler               h_default;
	XML_UnparsedEntityDeclHandler    h_unparsed_entity_decl;
	XML_NotationDeclHandler          h_notation_decl;
	XML_ExternalEntityRefHandler     h_external_entity_ref;
	XML_StartNamespaceDeclHandler    h_start_ns;
	XML_EndNamespaceDeclHandler      h_end_ns;
} *XML_Parser;

enum XML_Error {
	XML_ERROR_NONE,
	XML_ERROR_NO_MEMORY,
	XML_ERROR_SYNTAX,
	XML_ERROR_NO_ELEMENTS,
	XML_ERROR_INVALID_TOKEN,
	XML_ERROR_UNCLOSED_TOKEN,
	XML_ERROR_PARTIAL_CHAR,
	XML_ERROR_TAG_MISMATCH,
	XML_ERROR_DUPLICATE_ATTRIBUTE,
	XML_ERROR_JUNK_AFTER_DOC_ELEMENT,
	XML_ERROR_PARAM_ENTITY_REF,
	XML_ERROR_UNDEFINED_ENTITY,
	XML_ERROR_RECURSIVE_ENTITY_REF,
	XML_ERROR_ASYNC_ENTITY,
	XML_ERROR_BAD_CHAR_REF,
	XML_ERROR_BINARY_ENTITY_REF,
	XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF,
	XML_ERROR_MISPLACED_XML_PI,
	XML_ERROR_UNKNOWN_ENCODING,
	XML_ERROR_INCORRECT_ENCODING,
	XML_ERROR_UNCLOSED_CDATA_SECTION,
	XML_ERROR_EXTERNAL_ENTITY_HANDLING,
	XML_ERROR_NOT_STANDALONE,
	XML_ERROR_UNEXPECTED_STATE,
	XML_ERROR_ENTITY_DECLARED_IN_PE,
	XML_ERROR_FEATURE_REQUIRES_XML_DTD,
	XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING
};

enum XML_Content_Type {
	XML_CTYPE_EMPTY = 1,
	XML_CTYPE_ANY,
	XML_CTYPE_MIXED,
	XML_CTYPE_NAME,
	XML_CTYPE_CHOICE,
	XML_CTYPE_SEQ
};

PHPAPI XML_Parser XML_ParserCreate(const XML_Char *);
PHPAPI XML_Parser XML_ParserCreateNS(const XML_Char *, const XML_Char);
PHPAPI XML_Parser XML_ParserCreate_MM(const XML_Char *, const XML_Memory_Handling_Suite *, const XML_Char *);
PHPAPI void XML_SetUserData(XML_Parser, void *);
PHPAPI void *XML_GetUserData(XML_Parser);
PHPAPI void XML_SetElementHandler(XML_Parser, XML_StartElementHandler, XML_EndElementHandler);
PHPAPI void XML_SetCharacterDataHandler(XML_Parser, XML_CharacterDataHandler);
PHPAPI void XML_SetProcessingInstructionHandler(XML_Parser, XML_ProcessingInstructionHandler);
PHPAPI void XML_SetDefaultHandler(XML_Parser, XML_DefaultHandler);
PHPAPI void XML_SetUnparsedEntityDeclHandler(XML_Parser, XML_UnparsedEntityDeclHandler);
PHPAPI void XML_SetNotationDeclHandler(XML_Parser, XML_NotationDeclHandler);
PHPAPI void XML_SetExternalEntityRefHandler(XML_Parser, XML_ExternalEntityRefHandler);
PHPAPI void XML_SetStartNamespaceDeclHandler(XML_Parser, XML_StartNamespaceDeclHandler);
PHPAPI void XML_SetEndNamespaceDeclHandler(XML_Parser, XML_EndNamespaceDeclHandler);
PHPAPI int  XML_Parse(XML_Parser, const XML_Char *, int data_len, int is_final);
PHPAPI int  XML_GetErrorCode(XML_Parser);
PHPAPI const XML_Char *XML_ErrorString(int);
PHPAPI int  XML_GetCurrentLineNumber(XML_Parser);
PHPAPI int  XML_GetCurrentColumnNumber(XML_Parser);
PHPAPI int  XML_GetCurrentByteIndex(XML_Parser);
PHPAPI int  XML_GetCurrentByteCount(XML_Parser);
PHPAPI const XML_Char *XML_ExpatVersion(void);
PHPAPI void XML_ParserFree(XML_Parser);

#elif defined(HAVE_LIBEXPAT)
#include "php.h"
#include <expat.h>
#endif /* HAVE_LIBEXPAT */

#endif /* PHP_EXPAT_COMPAT_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 */
php/ext/xml/php_xml.h000064400000011160151730540230010552 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Stig S�ther Bakken <ssb@php.net>                            |
   |          Thies C. Arntzen <thies@thieso.net>                         |
   |          Sterling Hughes <sterling@php.net>                          |
   +----------------------------------------------------------------------+
*/

/* $Id: php_xml.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_XML_H
#define PHP_XML_H

#ifdef HAVE_XML
extern zend_module_entry xml_module_entry;
#define xml_module_ptr &xml_module_entry
#else
#define xml_module_ptr NULL
#endif

#ifdef HAVE_XML 

#include "ext/xml/expat_compat.h"

#ifdef PHP_WIN32
#define PHP_XML_API __declspec(dllexport)
#else
#define PHP_XML_API
#endif


#ifdef XML_UNICODE
#error "UTF-16 Unicode support not implemented!"
#endif

ZEND_BEGIN_MODULE_GLOBALS(xml)
	XML_Char *default_encoding;
ZEND_END_MODULE_GLOBALS(xml)

typedef struct {
	int index;
	int case_folding;
	XML_Parser parser;
	XML_Char *target_encoding;

	zval *startElementHandler;
	zval *endElementHandler;
	zval *characterDataHandler;
	zval *processingInstructionHandler;
	zval *defaultHandler;
	zval *unparsedEntityDeclHandler;
	zval *notationDeclHandler;
	zval *externalEntityRefHandler;
	zval *unknownEncodingHandler;	
	zval *startNamespaceDeclHandler;
	zval *endNamespaceDeclHandler;

	zend_function *startElementPtr;
	zend_function *endElementPtr;
	zend_function *characterDataPtr;
	zend_function *processingInstructionPtr;
	zend_function *defaultPtr;
	zend_function *unparsedEntityDeclPtr;
	zend_function *notationDeclPtr;
	zend_function *externalEntityRefPtr;
	zend_function *unknownEncodingPtr;
	zend_function *startNamespaceDeclPtr;
	zend_function *endNamespaceDeclPtr;

	zval *object;

	zval *data;
	zval *info;
	int level;
	int toffset;
	int curtag;
	zval **ctag;
	char **ltags;
	int lastwasopen;
	int skipwhite;
	int isparsing;
	
	XML_Char *baseURI;
} xml_parser;


typedef struct {
	XML_Char *name;
	char (*decoding_function)(unsigned short);
	unsigned short (*encoding_function)(unsigned char);
} xml_encoding;


enum php_xml_option {
    PHP_XML_OPTION_CASE_FOLDING = 1,
    PHP_XML_OPTION_TARGET_ENCODING,
    PHP_XML_OPTION_SKIP_TAGSTART,
    PHP_XML_OPTION_SKIP_WHITE
};

/* for xml_parse_into_struct */
	
#define XML_MAXLEVEL 255 /* XXX this should be dynamic */
	
PHP_FUNCTION(xml_parser_create);
PHP_FUNCTION(xml_parser_create_ns);
PHP_FUNCTION(xml_set_object);
PHP_FUNCTION(xml_set_element_handler);
PHP_FUNCTION(xml_set_character_data_handler);
PHP_FUNCTION(xml_set_processing_instruction_handler);
PHP_FUNCTION(xml_set_default_handler);
PHP_FUNCTION(xml_set_unparsed_entity_decl_handler);
PHP_FUNCTION(xml_set_notation_decl_handler);
PHP_FUNCTION(xml_set_external_entity_ref_handler);
PHP_FUNCTION(xml_set_start_namespace_decl_handler);
PHP_FUNCTION(xml_set_end_namespace_decl_handler);
PHP_FUNCTION(xml_parse);
PHP_FUNCTION(xml_get_error_code);
PHP_FUNCTION(xml_error_string);
PHP_FUNCTION(xml_get_current_line_number);
PHP_FUNCTION(xml_get_current_column_number);
PHP_FUNCTION(xml_get_current_byte_index);
PHP_FUNCTION(xml_parser_free);
PHP_FUNCTION(xml_parser_set_option);
PHP_FUNCTION(xml_parser_get_option);
PHP_FUNCTION(utf8_encode);
PHP_FUNCTION(utf8_decode);
PHP_FUNCTION(xml_parse_into_struct);

PHPAPI char *_xml_zval_strdup(zval *val);
PHPAPI char *xml_utf8_decode(const XML_Char *, int, int *, const XML_Char *);
PHPAPI char *xml_utf8_encode(const char *s, int len, int *newlen, const XML_Char *encoding);

#endif /* HAVE_LIBEXPAT */

#define phpext_xml_ptr xml_module_ptr

#ifdef ZTS
#define XML(v) TSRMG(xml_globals_id, zend_xml_globals *, v)
#else
#define XML(v) (xml_globals.v)
#endif

#endif /* PHP_XML_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 */
php/ext/curl/php_curl.h000064400000011705151730540230011071 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Sterling Hughes <sterling@php.net>                           |
   |         Wez Furlong <wez@thebrainroom.com>                           |
   +----------------------------------------------------------------------+
*/

/* $Id: php_curl.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef _PHP_CURL_H
#define _PHP_CURL_H

#include "php.h"
#include "ext/standard/php_smart_str.h"

#ifdef COMPILE_DL_CURL
#undef HAVE_CURL
#define HAVE_CURL 1
#endif

#if HAVE_CURL

#define PHP_CURL_DEBUG 0

#include <curl/curl.h>
#include <curl/multi.h>

extern zend_module_entry curl_module_entry;
#define curl_module_ptr &curl_module_entry

#define CURLOPT_RETURNTRANSFER 19913
#define CURLOPT_BINARYTRANSFER 19914
#define PHP_CURL_STDOUT 0
#define PHP_CURL_FILE   1
#define PHP_CURL_USER   2
#define PHP_CURL_DIRECT 3
#define PHP_CURL_RETURN 4
#define PHP_CURL_ASCII  5
#define PHP_CURL_BINARY 6
#define PHP_CURL_IGNORE 7

#define SAVE_CURL_ERROR(__handle, __err) (__handle)->err.no = (int) __err;

extern int  le_curl;
#define le_curl_name "cURL handle"
extern int  le_curl_multi_handle;
#define le_curl_multi_handle_name "cURL Multi Handle"

PHP_MINIT_FUNCTION(curl);
PHP_MSHUTDOWN_FUNCTION(curl);
PHP_MINFO_FUNCTION(curl);
PHP_FUNCTION(curl_version);
PHP_FUNCTION(curl_init);
PHP_FUNCTION(curl_copy_handle);
PHP_FUNCTION(curl_setopt);
PHP_FUNCTION(curl_setopt_array);
PHP_FUNCTION(curl_exec);
PHP_FUNCTION(curl_getinfo);
PHP_FUNCTION(curl_error);
PHP_FUNCTION(curl_errno);
PHP_FUNCTION(curl_close);
PHP_FUNCTION(curl_multi_init);
PHP_FUNCTION(curl_multi_add_handle);
PHP_FUNCTION(curl_multi_remove_handle);
PHP_FUNCTION(curl_multi_select);
PHP_FUNCTION(curl_multi_exec);
PHP_FUNCTION(curl_multi_getcontent);
PHP_FUNCTION(curl_multi_info_read);
PHP_FUNCTION(curl_multi_close);
void _php_curl_multi_close(zend_rsrc_list_entry * TSRMLS_DC);

typedef struct {
	zval            *func_name;
	zend_fcall_info_cache fci_cache;
	FILE            *fp;
	smart_str       buf;
	int             method;
	int             type;
	zval		*stream;
} php_curl_write;

typedef struct {
	zval            *func_name;
	zend_fcall_info_cache fci_cache;
	FILE            *fp;
	long            fd;
	int             method;
	zval		*stream;
} php_curl_read;

typedef struct {
	php_curl_write *write;
	php_curl_write *write_header;
	php_curl_read  *read;
	zval           *passwd;
	zval           *std_err;
} php_curl_handlers;

struct _php_curl_error  {
	char str[CURL_ERROR_SIZE + 1];
	int  no;
};

struct _php_curl_send_headers {
	char *str;
	size_t str_len;
};

struct _php_curl_free {
#if LIBCURL_VERSION_NUM < 0x071100
	zend_llist str;
#endif
	zend_llist post;
	zend_llist slist;
};

typedef struct {
	struct _php_curl_error   err;
	struct _php_curl_free    to_free;
	struct _php_curl_send_headers header;
	void ***thread_ctx;
	CURL                    *cp;
	php_curl_handlers       *handlers;
	long                     id;
	unsigned int             uses;
	zend_bool                in_callback;
	zval                     *clone;
} php_curl;

typedef struct {
	int    still_running;
	CURLM *multi;
	zend_llist easyh;
} php_curlm;

void _php_curl_cleanup_handle(php_curl *);
void _php_curl_multi_cleanup_list(void *data);

/* streams support */

extern php_stream_ops php_curl_stream_ops;
#define PHP_STREAM_IS_CURL	&php_curl_stream_ops

php_stream *php_curl_stream_opener(php_stream_wrapper *wrapper, char *filename, char *mode,
		int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC);

extern php_stream_wrapper php_curl_wrapper;

struct php_curl_buffer {
	off_t readpos, writepos;
	php_stream *buf;
};

typedef struct {
	CURL	*curl;
	CURLM	*multi;
	char *url;
	struct php_curl_buffer readbuffer; /* holds downloaded data */
	struct php_curl_buffer writebuffer; /* holds data to upload */

	fd_set readfds, writefds, excfds;
	int maxfd;
	
	char errstr[CURL_ERROR_SIZE + 1];
	CURLMcode mcode;
	int pending;
	zval *headers;
} php_curl_stream;


#else
#define curl_module_ptr NULL
#endif /* HAVE_CURL */
#define phpext_curl_ptr curl_module_ptr
#endif  /* _PHP_CURL_H */
php/ext/filter/php_filter.h000064400000007037151730540230011734 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 5                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2010 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Rasmus Lerdorf <rasmus@php.net>                             |
  |          Derick Rethans <derick@php.net>                             |
  +----------------------------------------------------------------------+
*/

/* $Id: php_filter.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_FILTER_H
#define PHP_FILTER_H

#include "SAPI.h"
#include "zend_API.h"
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "ext/standard/php_string.h"
#include "php_variables.h"

extern zend_module_entry filter_module_entry;
#define phpext_filter_ptr &filter_module_entry

#ifdef PHP_WIN32
#define PHP_FILTER_API __declspec(dllexport)
#else
#define PHP_FILTER_API
#endif

#ifdef ZTS
#include "TSRM.h"
#endif

PHP_MINIT_FUNCTION(filter);
PHP_MSHUTDOWN_FUNCTION(filter);
PHP_RINIT_FUNCTION(filter);
PHP_RSHUTDOWN_FUNCTION(filter);
PHP_MINFO_FUNCTION(filter);

PHP_FUNCTION(filter_input);
PHP_FUNCTION(filter_var);
PHP_FUNCTION(filter_input_array);
PHP_FUNCTION(filter_var_array);
PHP_FUNCTION(filter_list);
PHP_FUNCTION(filter_has_var);
PHP_FUNCTION(filter_id);

ZEND_BEGIN_MODULE_GLOBALS(filter)
	zval *post_array;
	zval *get_array;
	zval *cookie_array;
	zval *env_array;
	zval *server_array;
	zval *session_array;
	long  default_filter;
	long  default_filter_flags;
ZEND_END_MODULE_GLOBALS(filter)

#ifdef ZTS
#define IF_G(v) TSRMG(filter_globals_id, zend_filter_globals *, v)
#else
#define IF_G(v) (filter_globals.v)
#endif


#define PHP_INPUT_FILTER_PARAM_DECL zval *value, long flags, zval *option_array, char *charset TSRMLS_DC
void php_filter_int(PHP_INPUT_FILTER_PARAM_DECL);
void php_filter_boolean(PHP_INPUT_FILTER_PARAM_DECL);
void php_filter_float(PHP_INPUT_FILTER_PARAM_DECL);
void php_filter_validate_regexp(PHP_INPUT_FILTER_PARAM_DECL);
void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL);
void php_filter_validate_email(PHP_INPUT_FILTER_PARAM_DECL);
void php_filter_validate_ip(PHP_INPUT_FILTER_PARAM_DECL);

void php_filter_string(PHP_INPUT_FILTER_PARAM_DECL);
void php_filter_encoded(PHP_INPUT_FILTER_PARAM_DECL);
void php_filter_special_chars(PHP_INPUT_FILTER_PARAM_DECL);
void php_filter_unsafe_raw(PHP_INPUT_FILTER_PARAM_DECL);
void php_filter_email(PHP_INPUT_FILTER_PARAM_DECL);
void php_filter_url(PHP_INPUT_FILTER_PARAM_DECL);
void php_filter_number_int(PHP_INPUT_FILTER_PARAM_DECL);
void php_filter_number_float(PHP_INPUT_FILTER_PARAM_DECL);
void php_filter_magic_quotes(PHP_INPUT_FILTER_PARAM_DECL);

void php_filter_callback(PHP_INPUT_FILTER_PARAM_DECL);

#endif	/* FILTER_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/ext/simplexml/php_simplexml_exports.h000064400000004310151730540230014761 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: Sterling Hughes <sterling@php.net>                           |
  |         Marcus Boerger <helly@php.net>                               |
  |         Rob Richards <rrichards@php.net>                             |
  +----------------------------------------------------------------------+
*/

/* $Id$ */

#ifndef PHP_SIMPLEXML_EXPORTS_H
#define PHP_SIMPLEXML_EXPORTS_H

#include "php_simplexml.h"

#define SKIP_TEXT(__p) \
	if ((__p)->type == XML_TEXT_NODE) { \
		goto next_iter; \
	}

#define GET_NODE(__s, __n) { \
	if ((__s)->node && (__s)->node->node) { \
		__n = (__s)->node->node; \
	} else { \
		__n = NULL; \
		php_error_docref(NULL, E_WARNING, "Node no longer exists"); \
	} \
}

PHP_SXE_API zend_object *sxe_object_new(zend_class_entry *ce);

static inline php_sxe_object *php_sxe_fetch_object(zend_object *obj) /* {{{ */ {
	return (php_sxe_object *)((char*)(obj) - XtOffsetOf(php_sxe_object, zo));
}
/* }}} */

#define Z_SXEOBJ_P(zv) php_sxe_fetch_object(Z_OBJ_P((zv)))

typedef struct {
	zend_object_iterator  intern;
	php_sxe_object        *sxe;
} php_sxe_iterator;

#endif /* PHP_SIMPLEXML_EXPORTS_H */

/**
 * Local Variables:
 * c-basic-offset: 4
 * tab-width: 4
 * indent-tabs-mode: t
 * End:
 * vim600: fdm=marker
 * vim: noet sw=4 ts=4
 */
php/ext/simplexml/php_simplexml.h000064400000005504151730540230013203 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: Sterling Hughes <sterling@php.net>                           |
  +----------------------------------------------------------------------+
*/

/* $Id$ */

#ifndef PHP_SIMPLEXML_H
#define PHP_SIMPLEXML_H

extern zend_module_entry simplexml_module_entry;
#define phpext_simplexml_ptr &simplexml_module_entry

#include "php_version.h"
#define PHP_SIMPLEXML_VERSION PHP_VERSION

#ifdef ZTS
#include "TSRM.h"
#endif

#include "ext/libxml/php_libxml.h"
#include <libxml/parser.h>
#include <libxml/parserInternals.h>
#include <libxml/tree.h>
#include <libxml/uri.h>
#include <libxml/xmlerror.h>
#include <libxml/xinclude.h>
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>
#include <libxml/xpointer.h>
#include <libxml/xmlschemas.h>

PHP_MINIT_FUNCTION(simplexml);
PHP_MSHUTDOWN_FUNCTION(simplexml);
PHP_MINFO_FUNCTION(simplexml);

typedef enum {
	SXE_ITER_NONE     = 0,
	SXE_ITER_ELEMENT  = 1,
	SXE_ITER_CHILD    = 2,
	SXE_ITER_ATTRLIST = 3
} SXE_ITER;

typedef struct {
	php_libxml_node_ptr *node;
	php_libxml_ref_obj *document;
	HashTable *properties;
	xmlXPathContextPtr xpath;
	struct {
		xmlChar               *name;
		xmlChar               *nsprefix;
		int                   isprefix;
		SXE_ITER              type;
		zval                  data;
	} iter;
	zval tmp;
	zend_function *fptr_count;
	zend_object zo;
} php_sxe_object;

#ifdef ZTS
#define SIMPLEXML_G(v) TSRMG(simplexml_globals_id, zend_simplexml_globals *, v)
#else
#define SIMPLEXML_G(v) (simplexml_globals.v)
#endif

#ifdef PHP_WIN32
#	ifdef PHP_SIMPLEXML_EXPORTS
#		define PHP_SXE_API __declspec(dllexport)
#	else
#		define PHP_SXE_API __declspec(dllimport)
#	endif
#else
#	define PHP_SXE_API ZEND_API
#endif

PHP_SXE_API zend_class_entry *sxe_get_element_class_entry();

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 * vim600: fdm=marker
 * vim: noet sw=4 ts=4
 */
php/ext/mbstring/mbstring.h000064400000017626151730540240011773 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Tsukada Takuya <tsukada@fminn.nagano.nagano.jp>              |
   +----------------------------------------------------------------------+
 */

/* $Id: mbstring.h 293036 2010-01-03 09:23:27Z sebastian $ */

/*
 * PHP 4 Multibyte String module "mbstring" (currently only for Japanese)
 *
 * History:
 *   2000.5.19  Release php-4.0RC2_jstring-1.0
 *   2001.4.1   Release php4_jstring-1.0.91
 *   2001.4.30  Release php4-jstring-1.1 (contribute to The PHP Group)
 *   2001.5.1   Renamed from jstring to mbstring (hirokawa@php.net)
 */

/*
 * PHP3 Internationalization support program.
 *
 * Copyright (c) 1999,2000 by the PHP3 internationalization team.
 * All rights reserved.
 *
 * See README_PHP3-i18n-ja for more detail.
 *
 * Authors:
 *    Hironori Sato <satoh@jpnnet.com>
 *    Shigeru Kanemoto <sgk@happysize.co.jp>
 *    Tsukada Takuya <tsukada@fminn.nagano.nagano.jp>
 */


#ifndef _MBSTRING_H
#define _MBSTRING_H

#ifdef COMPILE_DL_MBSTRING
#undef HAVE_MBSTRING
#define HAVE_MBSTRING 1
#endif

#ifdef PHP_WIN32
# undef MBSTRING_API
# ifdef MBSTRING_EXPORTS
#  define MBSTRING_API __declspec(dllexport)
# elif defined(COMPILE_DL_MBSTRING)
#  define MBSTRING_API __declspec(dllimport)
# else
#  define MBSTRING_API /* nothing special */
# endif
#else
# undef MBSTRING_API
# define MBSTRING_API /* nothing special */
#endif


#if HAVE_MBSTRING

#include "libmbfl/mbfl/mbfilter.h"
#include "SAPI.h"

#define PHP_MBSTRING_API 20021024

#if HAVE_MBREGEX
#include "php_mbregex.h"
#endif

extern zend_module_entry mbstring_module_entry;
#define mbstring_module_ptr &mbstring_module_entry

PHP_MINIT_FUNCTION(mbstring);
PHP_MSHUTDOWN_FUNCTION(mbstring);
PHP_RINIT_FUNCTION(mbstring);
PHP_RSHUTDOWN_FUNCTION(mbstring);
PHP_MINFO_FUNCTION(mbstring);

/* functions in php_unicode.c */
PHP_FUNCTION(mb_convert_case);
PHP_FUNCTION(mb_strtoupper);
PHP_FUNCTION(mb_strtolower);

/* php function registration */
PHP_FUNCTION(mb_language);
PHP_FUNCTION(mb_internal_encoding);
PHP_FUNCTION(mb_http_input);
PHP_FUNCTION(mb_http_output);
PHP_FUNCTION(mb_detect_order);
PHP_FUNCTION(mb_substitute_character);
PHP_FUNCTION(mb_preferred_mime_name);
PHP_FUNCTION(mb_parse_str);
PHP_FUNCTION(mb_output_handler);
PHP_FUNCTION(mb_strlen);
PHP_FUNCTION(mb_strpos);
PHP_FUNCTION(mb_strrpos);
PHP_FUNCTION(mb_stripos);
PHP_FUNCTION(mb_strripos);
PHP_FUNCTION(mb_strstr);
PHP_FUNCTION(mb_strrchr);
PHP_FUNCTION(mb_stristr);
PHP_FUNCTION(mb_strrichr);
PHP_FUNCTION(mb_substr_count);
PHP_FUNCTION(mb_substr);
PHP_FUNCTION(mb_strcut);
PHP_FUNCTION(mb_strwidth);
PHP_FUNCTION(mb_strimwidth);
PHP_FUNCTION(mb_convert_encoding);
PHP_FUNCTION(mb_detect_encoding);
PHP_FUNCTION(mb_list_encodings);
PHP_FUNCTION(mb_convert_kana);
PHP_FUNCTION(mb_encode_mimeheader);
PHP_FUNCTION(mb_decode_mimeheader);
PHP_FUNCTION(mb_convert_variables);
PHP_FUNCTION(mb_encode_numericentity);
PHP_FUNCTION(mb_decode_numericentity);
PHP_FUNCTION(mb_send_mail);
PHP_FUNCTION(mb_get_info);
PHP_FUNCTION(mb_check_encoding);

MBSTRING_API int php_mb_encoding_translation(TSRMLS_D);

MBSTRING_API char *php_mb_safe_strrchr_ex(const char *s, unsigned int c,
                                    size_t nbytes, const mbfl_encoding *enc);
MBSTRING_API char *php_mb_safe_strrchr(const char *s, unsigned int c,
                                 size_t nbytes TSRMLS_DC);
MBSTRING_API char *php_mb_strrchr(const char *s, char c TSRMLS_DC);

MBSTRING_API char * php_mb_convert_encoding(char *input, size_t length,
                                      char *_to_encoding,
                                      char *_from_encodings,
                                      size_t *output_len TSRMLS_DC);

MBSTRING_API int php_mb_check_encoding_list(const char *encoding_list TSRMLS_DC);

MBSTRING_API size_t php_mb_mbchar_bytes_ex(const char *s, const mbfl_encoding *enc);
MBSTRING_API size_t php_mb_mbchar_bytes(const char *s TSRMLS_DC);

MBSTRING_API size_t php_mb_gpc_mbchar_bytes(const char *s TSRMLS_DC);

MBSTRING_API int php_mb_encoding_detector_ex(const char *arg_string, int arg_length, 
											 char *arg_list TSRMLS_DC);

MBSTRING_API int php_mb_encoding_converter_ex(char **str, int *len, const char *encoding_to, 
											  const char *encoding_from TSRMLS_DC);
MBSTRING_API int php_mb_gpc_encoding_converter(char **str, int *len, int num, const char *encoding_to, const char *encoding_from TSRMLS_DC);

MBSTRING_API int php_mb_gpc_encoding_detector(char **arg_string, int *arg_length, int num, char *arg_list TSRMLS_DC);

MBSTRING_API int php_mb_stripos(int mode, char *old_haystack, int old_haystack_len, char *old_needle, int old_needle_len, long offset, char *from_encoding TSRMLS_DC);

/* internal use only */
int _php_mb_ini_mbstring_internal_encoding_set(const char *new_value, uint new_value_length TSRMLS_DC);

ZEND_BEGIN_MODULE_GLOBALS(mbstring)
	enum mbfl_no_language language;
	enum mbfl_no_encoding internal_encoding;
	enum mbfl_no_encoding current_internal_encoding;
#ifdef ZEND_MULTIBYTE
	enum mbfl_no_encoding *script_encoding_list;
	int script_encoding_list_size;
#endif /* ZEND_MULTIBYTE */
	enum mbfl_no_encoding http_output_encoding;
	enum mbfl_no_encoding current_http_output_encoding;
	enum mbfl_no_encoding http_input_identify;
	enum mbfl_no_encoding http_input_identify_get;
	enum mbfl_no_encoding http_input_identify_post;
	enum mbfl_no_encoding http_input_identify_cookie;
	enum mbfl_no_encoding http_input_identify_string;
	enum mbfl_no_encoding *http_input_list;
	int http_input_list_size;
	enum mbfl_no_encoding *detect_order_list;
	int detect_order_list_size;
	enum mbfl_no_encoding *current_detect_order_list;
	int current_detect_order_list_size;
	enum mbfl_no_encoding *default_detect_order_list;
	int default_detect_order_list_size;
	int filter_illegal_mode;
	int filter_illegal_substchar;
	int current_filter_illegal_mode;
	int current_filter_illegal_substchar;
	long func_overload;
	zend_bool encoding_translation;
	long strict_detection;
	long illegalchars;
	mbfl_buffer_converter *outconv;
#if HAVE_MBREGEX && defined(PHP_MBREGEX_GLOBALS)
	PHP_MBREGEX_GLOBALS	
#endif
ZEND_END_MODULE_GLOBALS(mbstring)

#define MB_OVERLOAD_MAIL 1
#define MB_OVERLOAD_STRING 2
#define MB_OVERLOAD_REGEX 4

struct mb_overload_def {
	int type;
	char *orig_func;
	char *ovld_func;
	char *save_func;
};

#ifdef ZTS
#define MBSTRG(v) TSRMG(mbstring_globals_id, zend_mbstring_globals *, v)
#else
#define MBSTRG(v) (mbstring_globals.v)
#endif

#ifdef ZEND_MULTIBYTE
MBSTRING_API int php_mb_set_zend_encoding(TSRMLS_D);
char* php_mb_encoding_detector(const char *string, int length, char *list
		TSRMLS_DC);
int php_mb_encoding_converter(char **to, int *to_length, const char *from,
		int from_length, const char *encoding_to, const char *encoding_from
		TSRMLS_DC);
int php_mb_oddlen(const char *string, int length, const char *encoding TSRMLS_DC);
#endif /* ZEND_MULTIBYTE */

#else	/* HAVE_MBSTRING */

#define mbstring_module_ptr NULL

#endif	/* HAVE_MBSTRING */

#define phpext_mbstring_ptr mbstring_module_ptr

#endif		/* _MBSTRING_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 */
php/ext/mbstring/libmbfl/config.h000064400000000030151730540240012777 0ustar00#include "php_config.h"
php/ext/mbstring/libmbfl/mbfl/mbfilter.h000064400000023265151730540240014275 0ustar00/* charset=UTF-8
 * vim: encoding=utf-8:
 * */

/*
 * "streamable kanji code filter and converter"
 *
 * Copyright (c) 1998,1999,2000,2001 HappySize, Inc. All rights reserved.
 *
 * This software is released under the GNU Lesser General Public License.
 * (Version 2.1, February 1999)
 * Please read the following detail of the licence (in japanese).
 *
 * ◆使用許諾条件◆
 *
 * このソフトウェアは株式会社ハッピーサイズによって開発されました。株式会社ハッ
 * ピーサイズは、著作権法および万国著作権条約の定めにより、このソフトウェアに関
 * するすべての権利を留保する権利を持ち、ここに行使します。株式会社ハッピーサイ
 * ズは以下に明記した条件に従って、このソフトウェアを使用する排他的ではない権利
 * をお客様に許諾します。何人たりとも、以下の条件に反してこのソフトウェアを使用
 * することはできません。
 *
 * このソフトウェアを「GNU Lesser General Public License (Version 2.1, February
 * 1999)」に示された条件で使用することを、全ての方に許諾します。「GNU Lesser
 * General Public License」を満たさない使用には、株式会社ハッピーサイズから書面
 * による許諾を得る必要があります。
 *
 * 「GNU Lesser General Public License」の全文は以下のウェブページから取得でき
 * ます。「GNU Lesser General Public License」とは、これまでLibrary General
 * Public Licenseと呼ばれていたものです。
 *     http://www.gnu.org/ --- GNUウェブサイト
 *     http://www.gnu.org/copyleft/lesser.html --- ライセンス文面
 * このライセンスの内容がわからない方、守れない方には使用を許諾しません。
 *
 * しかしながら、当社とGNUプロジェクトとの特定の関係を示唆または主張するもので
 * はありません。
 *
 * ◆保証内容◆
 *
 * このソフトウェアは、期待された動作・機能・性能を持つことを目標として設計され
 * 開発されていますが、これを保証するものではありません。このソフトウェアは「こ
 * のまま」の状態で提供されており、たとえばこのソフトウェアの有用性ないし特定の
 * 目的に合致することといった、何らかの保証内容が、明示されたり暗黙に示されてい
 * る場合であっても、その保証は無効です。このソフトウェアを使用した結果ないし使
 * 用しなかった結果によって、直接あるいは間接に受けた身体的な傷害、財産上の損害
 * 、データの損失あるいはその他の全ての損害については、その損害の可能性が使用者
 * 、当社あるいは第三者によって警告されていた場合であっても、当社はその損害の賠
 * 償および補填を行いません。この規定は他の全ての、書面上または書面に無い保証・
 * 契約・規定に優先します。
 *
 * ◆著作権者の連絡先および使用条件についての問い合わせ先◆
 *
 * 〒102-0073
 * 東京都千代田区九段北1-13-5日本地所第一ビル4F
 * 株式会社ハッピーサイズ
 * Phone: 03-3512-3655, Fax: 03-3512-3656
 * Email: sales@happysize.co.jp
 * Web: http://happysize.com/
 *
 * ◆著者◆
 *
 * 金本 茂 <sgk@happysize.co.jp>
 *
 * ◆履歴◆
 *
 * 1998/11/10 sgk implementation in C++
 * 1999/4/25  sgk Cで書きなおし。
 * 1999/4/26  sgk 入力フィルタを実装。漢字コードを推定しながらフィルタを追加。
 * 1999/6/??      Unicodeサポート。
 * 1999/6/22  sgk ライセンスをLGPLに変更。
 *
 */

/* 
 * Unicode support
 *
 * Portions copyright (c) 1999,2000,2001 by the PHP3 internationalization team.
 * All rights reserved.
 *
 */

/*
 *
 * streamable kanji code filter and converter
 *    mbfl : Multi Byte FiLter Liblary
 *
 */

#ifndef MBFL_MBFILTER_H
#define MBFL_MBFILTER_H

#include "mbfl_defs.h"
#include "mbfl_consts.h"
#include "mbfl_allocators.h"
#include "mbfl_encoding.h"
#include "mbfl_language.h"
#include "mbfl_string.h"
#include "mbfl_convert.h"
#include "mbfl_ident.h"

/*
 * convert filter
 */
#define MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE 0
#define MBFL_OUTPUTFILTER_ILLEGAL_MODE_CHAR 1
#define MBFL_OUTPUTFILTER_ILLEGAL_MODE_LONG 2
#define MBFL_OUTPUTFILTER_ILLEGAL_MODE_ENTITY 3

/*
 * convenience macros
 */
#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
#endif

/*
 * buffering converter
 */
typedef struct _mbfl_buffer_converter mbfl_buffer_converter;

struct _mbfl_buffer_converter {
	mbfl_convert_filter *filter1;
	mbfl_convert_filter *filter2;
	mbfl_memory_device device;
	const mbfl_encoding *from;
	const mbfl_encoding *to;
};

MBFLAPI extern mbfl_buffer_converter * mbfl_buffer_converter_new(enum mbfl_no_encoding from, enum mbfl_no_encoding to, int buf_initsz);
MBFLAPI extern void mbfl_buffer_converter_delete(mbfl_buffer_converter *convd);
MBFLAPI extern void mbfl_buffer_converter_reset(mbfl_buffer_converter *convd);
MBFLAPI extern int mbfl_buffer_converter_illegal_mode(mbfl_buffer_converter *convd, int mode);
MBFLAPI extern int mbfl_buffer_converter_illegal_substchar(mbfl_buffer_converter *convd, int substchar);
MBFLAPI extern int mbfl_buffer_converter_strncat(mbfl_buffer_converter *convd, const unsigned char *p, int n);
MBFLAPI extern int mbfl_buffer_converter_feed(mbfl_buffer_converter *convd, mbfl_string *string);
MBFLAPI extern int mbfl_buffer_converter_flush(mbfl_buffer_converter *convd);
MBFLAPI extern mbfl_string * mbfl_buffer_converter_getbuffer(mbfl_buffer_converter *convd, mbfl_string *result);
MBFLAPI extern mbfl_string * mbfl_buffer_converter_result(mbfl_buffer_converter *convd, mbfl_string *result);
MBFLAPI extern mbfl_string * mbfl_buffer_converter_feed_result(mbfl_buffer_converter *convd, mbfl_string *string, mbfl_string *result);
MBFLAPI extern int mbfl_buffer_illegalchars(mbfl_buffer_converter *convd);

/*
 * encoding detector
 */
typedef struct _mbfl_encoding_detector mbfl_encoding_detector;

struct _mbfl_encoding_detector {
	mbfl_identify_filter **filter_list;
	int filter_list_size;
	int strict;
};

MBFLAPI extern mbfl_encoding_detector * mbfl_encoding_detector_new(enum mbfl_no_encoding *elist, int elistsz, int strict);
MBFLAPI extern void mbfl_encoding_detector_delete(mbfl_encoding_detector *identd);
MBFLAPI extern int mbfl_encoding_detector_feed(mbfl_encoding_detector *identd, mbfl_string *string);
MBFLAPI extern enum mbfl_no_encoding mbfl_encoding_detector_judge(mbfl_encoding_detector *identd);


/*
 * encoding converter
 */
MBFLAPI extern mbfl_string *
mbfl_convert_encoding(mbfl_string *string, mbfl_string *result, enum mbfl_no_encoding toenc);


/*
 * identify encoding
 */
MBFLAPI extern const mbfl_encoding *
mbfl_identify_encoding(mbfl_string *string, enum mbfl_no_encoding *elist, int elistsz, int strict);

MBFLAPI extern const char *
mbfl_identify_encoding_name(mbfl_string *string, enum mbfl_no_encoding *elist, int elistsz, int strict);

MBFLAPI extern enum mbfl_no_encoding
mbfl_identify_encoding_no(mbfl_string *string, enum mbfl_no_encoding *elist, int elistsz, int strict);

/*
 * strlen
 */
MBFLAPI extern int
mbfl_strlen(mbfl_string *string);

/*
 * oddlen
 */
MBFLAPI extern int
mbfl_oddlen(mbfl_string *string);

/*
 * strpos
 */
MBFLAPI extern int
mbfl_strpos(mbfl_string *haystack, mbfl_string *needle, int offset, int reverse);


/*
 * substr_count
 */
MBFLAPI extern int
mbfl_substr_count(mbfl_string *haystack, mbfl_string *needle);

/*
 * substr
 */
MBFLAPI extern mbfl_string *
mbfl_substr(mbfl_string *string, mbfl_string *result, int from, int length);

/*
 * strcut
 */
MBFLAPI extern mbfl_string *
mbfl_strcut(mbfl_string *string, mbfl_string *result, int from, int length);

/*
 *  strwidth
 */
MBFLAPI extern int
mbfl_strwidth(mbfl_string *string);

/*
 *  strimwidth
 */
MBFLAPI extern mbfl_string *
mbfl_strimwidth(mbfl_string *string, mbfl_string *marker, mbfl_string *result, int from, int width);

/*
 * MIME header encode
 */
struct mime_header_encoder_data;	/* forward declaration */

MBFLAPI extern struct mime_header_encoder_data *
mime_header_encoder_new(
    enum mbfl_no_encoding incode,
    enum mbfl_no_encoding outcode,
    enum mbfl_no_encoding encoding);

MBFLAPI extern void
mime_header_encoder_delete(struct mime_header_encoder_data *pe);

MBFLAPI extern int
mime_header_encoder_feed(int c, struct mime_header_encoder_data *pe);

MBFLAPI extern mbfl_string *
mime_header_encoder_result(struct mime_header_encoder_data *pe, mbfl_string *result);

MBFLAPI extern mbfl_string *
mbfl_mime_header_encode(
    mbfl_string *string, mbfl_string *result,
    enum mbfl_no_encoding outcode,
    enum mbfl_no_encoding encoding,
    const char *linefeed,
    int indent);

/*
 * MIME header decode
 */
struct mime_header_decoder_data;	/* forward declaration */

MBFLAPI extern struct mime_header_decoder_data *
mime_header_decoder_new(enum mbfl_no_encoding outcode);

MBFLAPI extern void
mime_header_decoder_delete(struct mime_header_decoder_data *pd);

MBFLAPI extern int
mime_header_decoder_feed(int c, struct mime_header_decoder_data *pd);

MBFLAPI extern mbfl_string *
mime_header_decoder_result(struct mime_header_decoder_data *pd, mbfl_string *result);

MBFLAPI extern mbfl_string *
mbfl_mime_header_decode(
    mbfl_string *string,
    mbfl_string *result,
    enum mbfl_no_encoding outcode);

/*
 * convert HTML numeric entity
 */
MBFLAPI extern mbfl_string *
mbfl_html_numeric_entity(mbfl_string *string, mbfl_string *result, int *convmap, int mapsize, int type);

/*
 * convert of harfwidth and fullwidth for japanese
 */
MBFLAPI extern mbfl_string *
mbfl_ja_jp_hantozen(mbfl_string *string, mbfl_string *result, int mode);

#endif	/* MBFL_MBFILTER_H */
php/ext/mbstring/libmbfl/mbfl/mbfilter_pass.h000064400000002533151730540240015316 0ustar00/*
 * "streamable kanji code filter and converter"
 * Copyright (c) 1998-2002 HappySize, Inc. All rights reserved.
 *
 * LICENSE NOTICES
 *
 * This file is part of "streamable kanji code filter and converter",
 * which is distributed under the terms of GNU Lesser General Public 
 * License (version 2) as published by the Free Software Foundation.
 *
 * 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.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with "streamable kanji code filter and converter";
 * if not, write to the Free Software Foundation, Inc., 59 Temple Place,
 * Suite 330, Boston, MA  02111-1307  USA
 *
 * The author of this file:
 *
 */
/*
 * The source code included in this files was separated from mbfilter.c
 * by moriyoshi koizumi <moriyoshi@php.net> on 4 dec 2002.
 * 
 */

#ifndef MBFL_MBFILTER_PASS_H
#define MBFL_MBFILTER_PASS_H

#include "mbfl_defs.h"
#include "mbfilter.h"

MBFLAPI extern const mbfl_encoding mbfl_encoding_pass; 
MBFLAPI extern const struct mbfl_convert_vtbl vtbl_pass;

MBFLAPI extern int mbfl_filt_conv_pass(int c, mbfl_convert_filter *filter);

#endif /* MBFL_MBFILTER_PASS_H */
php/ext/mbstring/libmbfl/mbfl/eaw_table.h000064400000001324151730540240014404 0ustar00static const struct {
	int begin;
	int end;
} mbfl_eaw_table[] = {
	{ 0x1100, 0x1159 },
	{ 0x115f, 0x115f },
	{ 0x2329, 0x232a },
	{ 0x2e80, 0x2e99 },
	{ 0x2e9b, 0x2ef3 },
	{ 0x2f00, 0x2fd5 },
	{ 0x2ff0, 0x2ffb },
	{ 0x3000, 0x303e },
	{ 0x3041, 0x3096 },
	{ 0x3099, 0x30ff },
	{ 0x3105, 0x312c },
	{ 0x3131, 0x318e },
	{ 0x3190, 0x31b7 },
	{ 0x31f0, 0x321e },
	{ 0x3220, 0x3243 },
	{ 0x3250, 0x327d },
	{ 0x327f, 0x32fe },
	{ 0x3300, 0x4db5 },
	{ 0x4e00, 0x9fa5 },
	{ 0xa000, 0xa48c },
	{ 0xa490, 0xa4c6 },
	{ 0xac00, 0xd7a3 },
	{ 0xf900, 0xfa2d },
	{ 0xfa30, 0xfa6a },
	{ 0xfe30, 0xfe52 },
	{ 0xfe54, 0xfe66 },
	{ 0xfe68, 0xfe6b },
	{ 0xff01, 0xff60 },
	{ 0xffe0, 0xffe6 },
	{ 0x20000, 0x2fffd },
	{ 0x30000, 0x3fffd }
};
php/ext/mbstring/libmbfl/mbfl/mbfl_defs.h000064400000002605151730540250014406 0ustar00/*
 * "streamable kanji code filter and converter"
 * Copyright (c) 1998-2002 HappySize, Inc. All rights reserved.
 *
 * LICENSE NOTICES
 *
 * This file is part of "streamable kanji code filter and converter",
 * which is distributed under the terms of GNU Lesser General Public 
 * License (version 2) as published by the Free Software Foundation.
 *
 * 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.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with "streamable kanji code filter and converter";
 * if not, write to the Free Software Foundation, Inc., 59 Temple Place,
 * Suite 330, Boston, MA  02111-1307  USA
 *
 * The author of this file:
 *
 */
/*
 * The source code included in this files was separated from mbfilter.h
 * by Moriyoshi Koizumi <moriyoshi@php.net> on 20 Dec 2002. The file
 * mbfilter.h is included in this package .
 *
 */

#ifndef MBFL_DEFS_H
#define MBFL_DEFS_H

#ifndef NULL
#ifdef __cplusplus
#define NULL (0L)
#else
#define NULL (void *)(0L)
#endif
#endif 

#ifdef WIN32
#ifdef MBFL_DLL_EXPORT
#define MBFLAPI __declspec(dllexport)
#else
#define MBFLAPI __declspec(dllimport)
#endif
#else
#define MBFLAPI
#endif

#endif /* MBFL_DEFS_H */
php/ext/mbstring/libmbfl/mbfl/mbfl_language.h000064400000005422151730540250015250 0ustar00/*
 * "streamable kanji code filter and converter"
 * Copyright (c) 1998-2002 HappySize, Inc. All rights reserved.
 *
 * LICENSE NOTICES
 *
 * This file is part of "streamable kanji code filter and converter",
 * which is distributed under the terms of GNU Lesser General Public 
 * License (version 2) as published by the Free Software Foundation.
 *
 * 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.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with "streamable kanji code filter and converter";
 * if not, write to the Free Software Foundation, Inc., 59 Temple Place,
 * Suite 330, Boston, MA  02111-1307  USA
 *
 * The author of this file:
 *
 */
/*
 * The source code included in this files was separated from mbfilter.h
 * by Moriyoshi Koizumi <moriyoshi@php.net> on 20 Dec 2002. The file
 * mbfilter.h is included in this package .
 *
 */

#ifndef MBFL_LANGUAGE_H
#define MBFL_LANGUAGE_H

#include "mbfl_defs.h"
#include "mbfl_encoding.h"

enum mbfl_no_language {
	mbfl_no_language_invalid = -1,
	mbfl_no_language_neutral,
	mbfl_no_language_uni,
	mbfl_no_language_min,
	mbfl_no_language_catalan,		/* ca */
	mbfl_no_language_danish,		/* da */
	mbfl_no_language_german,		/* de */
	mbfl_no_language_english,		/* en */
	mbfl_no_language_estonian,		/* et */
	mbfl_no_language_greek,			/* el */
	mbfl_no_language_spanish,		/* es */
	mbfl_no_language_french,		/* fr */
	mbfl_no_language_italian,		/* it */
	mbfl_no_language_japanese,		/* ja */
	mbfl_no_language_korean,		/* ko */
	mbfl_no_language_dutch,			/* nl */
	mbfl_no_language_polish,		/* pl */
	mbfl_no_language_portuguese,	        /* pt */
	mbfl_no_language_swedish,		/* sv */
	mbfl_no_language_simplified_chinese,		/* zh-cn */
	mbfl_no_language_traditional_chinese,		/* zh-tw */
	mbfl_no_language_russian,		/* ru */
	mbfl_no_language_armenian,		/* hy */
	mbfl_no_language_turkish,		/* tr */
	mbfl_no_language_max
};

typedef enum mbfl_no_language mbfl_language_id;

/*
 * language
 */
typedef struct _mbfl_language {
	enum mbfl_no_language no_language;
	const char *name;
	const char *short_name;
	const char *(*aliases)[];
	enum mbfl_no_encoding mail_charset;
	enum mbfl_no_encoding mail_header_encoding;
	enum mbfl_no_encoding mail_body_encoding;
} mbfl_language;

MBFLAPI extern const mbfl_language * mbfl_name2language(const char *name);
MBFLAPI extern const mbfl_language * mbfl_no2language(enum mbfl_no_language no_language);
MBFLAPI extern enum mbfl_no_language mbfl_name2no_language(const char *name);
MBFLAPI extern const char * mbfl_no_language2name(enum mbfl_no_language no_language);


#endif /* MBFL_LANGUAGE_H */
php/ext/mbstring/libmbfl/mbfl/mbfl_string.h000064400000003251151730540250014771 0ustar00/*
 * "streamable kanji code filter and converter"
 * Copyright (c) 1998-2002 HappySize, Inc. All rights reserved.
 *
 * LICENSE NOTICES
 *
 * This file is part of "streamable kanji code filter and converter",
 * which is distributed under the terms of GNU Lesser General Public 
 * License (version 2) as published by the Free Software Foundation.
 *
 * 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.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with "streamable kanji code filter and converter";
 * if not, write to the Free Software Foundation, Inc., 59 Temple Place,
 * Suite 330, Boston, MA  02111-1307  USA
 *
 * The author of this file:
 *
 */
/*
 * The source code included in this files was separated from mbfilter.h
 * by Moriyoshi Koizumi <moriyoshi@php.net> on 20 Dec 2002. The file
 * mbfilter.h is included in this package .
 *
 */

#ifndef MBFL_STRING_H
#define MBFL_STRING_H

#include "mbfl_defs.h"
#include "mbfl_encoding.h"
#include "mbfl_language.h"

/*
 * string object
 */
typedef struct _mbfl_string {
	enum mbfl_no_language no_language;
	enum mbfl_no_encoding no_encoding;
	unsigned char *val;
	unsigned int len;
} mbfl_string;

MBFLAPI extern void mbfl_string_init(mbfl_string *string);
MBFLAPI extern void mbfl_string_init_set(mbfl_string *string, mbfl_language_id no_language, mbfl_encoding_id no_encoding);
MBFLAPI extern void mbfl_string_clear(mbfl_string *string);

#ifndef NULL
#define NULL 0
#endif

#endif /* MBFL_STRING_H */
php/ext/mbstring/libmbfl/mbfl/mbfl_memory_device.h000064400000005267151730540250016323 0ustar00/*
 * "streamable kanji code filter and converter"
 * Copyright (c) 1998-2002 HappySize, Inc. All rights reserved.
 *
 * LICENSE NOTICES
 *
 * This file is part of "streamable kanji code filter and converter",
 * which is distributed under the terms of GNU Lesser General Public 
 * License (version 2) as published by the Free Software Foundation.
 *
 * 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.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with "streamable kanji code filter and converter";
 * if not, write to the Free Software Foundation, Inc., 59 Temple Place,
 * Suite 330, Boston, MA  02111-1307  USA
 *
 * The author of this file:
 *
 */
/*
 * The source code included in this files was separated from mbfilter.h
 * by Moriyoshi Koizumi <moriyoshi@php.net> on 20 Dec 2002. The file
 * mbfilter.h is included in this package .
 *
 */

#ifndef MBFL_MEMORY_DEVICE_H
#define MBFL_MEMORY_DEVICE_H

#include "mbfl_defs.h"
#include "mbfl_string.h"

#define MBFL_MEMORY_DEVICE_ALLOC_SIZE	64

typedef struct _mbfl_memory_device {
	unsigned char *buffer;
	int length;
	int pos;
	int allocsz;
} mbfl_memory_device;

typedef struct _mbfl_wchar_device {
	unsigned int *buffer;
	int length;
	int pos;
	int allocsz;
} mbfl_wchar_device;

MBFLAPI extern void mbfl_memory_device_init(mbfl_memory_device *device, int initsz, int allocsz);
MBFLAPI extern void mbfl_memory_device_realloc(mbfl_memory_device *device, int initsz, int allocsz);
MBFLAPI extern void mbfl_memory_device_clear(mbfl_memory_device *device);
MBFLAPI extern void mbfl_memory_device_reset(mbfl_memory_device *device);
MBFLAPI extern mbfl_string * mbfl_memory_device_result(mbfl_memory_device *device, mbfl_string *result);
MBFLAPI extern void mbfl_memory_device_unput(mbfl_memory_device *device);
MBFLAPI extern int mbfl_memory_device_output(int c, void *data);
MBFLAPI extern int mbfl_memory_device_output2(int c, void *data);
MBFLAPI extern int mbfl_memory_device_output4(int c, void *data);
MBFLAPI extern int mbfl_memory_device_strcat(mbfl_memory_device *device, const char *psrc);
MBFLAPI extern int mbfl_memory_device_strncat(mbfl_memory_device *device, const char *psrc, int len);
MBFLAPI extern int mbfl_memory_device_devcat(mbfl_memory_device *dest, mbfl_memory_device *src);

MBFLAPI extern void mbfl_wchar_device_init(mbfl_wchar_device *device);
MBFLAPI extern int mbfl_wchar_device_output(int c, void *data);
MBFLAPI extern void mbfl_wchar_device_clear(mbfl_wchar_device *device);



#endif /* MBFL_MEMORY_DEVICE_H */

php/ext/mbstring/libmbfl/mbfl/mbfl_consts.h000064400000007241151730540250014777 0ustar00/*
 * "streamable kanji code filter and converter"
 * Copyright (c) 1998-2002 HappySize, Inc. All rights reserved.
 *
 * LICENSE NOTICES
 *
 * This file is part of "streamable kanji code filter and converter",
 * which is distributed under the terms of GNU Lesser General Public 
 * License (version 2) as published by the Free Software Foundation.
 *
 * 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.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with "streamable kanji code filter and converter";
 * if not, write to the Free Software Foundation, Inc., 59 Temple Place,
 * Suite 330, Boston, MA  02111-1307  USA
 *
 * The author of this file:
 *
 */
/*
 * The source code included in this files was separated from mbfilter.h
 * by Moriyoshi Koizumi <moriyoshi@php.net> on 20 Dec 2002. The file
 * mbfilter.h is included in this package .
 *
 */

#ifndef MBFL_CONSTS_H
#define MBFL_CONSTS_H

#define MBFL_ENCTYPE_SBCS		0x00000001
#define MBFL_ENCTYPE_MBCS		0x00000002
#define MBFL_ENCTYPE_WCS2BE		0x00000010
#define MBFL_ENCTYPE_WCS2LE		0x00000020
#define MBFL_ENCTYPE_MWC2BE		0x00000040
#define MBFL_ENCTYPE_MWC2LE		0x00000080
#define MBFL_ENCTYPE_WCS4BE		0x00000100
#define MBFL_ENCTYPE_WCS4LE		0x00000200
#define MBFL_ENCTYPE_MWC4BE		0x00000400
#define MBFL_ENCTYPE_MWC4LE		0x00000800
#define MBFL_ENCTYPE_SHFTCODE	0x00001000 
#define MBFL_ENCTYPE_HTML_ENT       0x00002000

/* wchar plane, special charactor */
#define MBFL_WCSPLANE_MASK			0xffff
#define MBFL_WCSPLANE_UCS2MAX		0x00010000
#define MBFL_WCSPLANE_SUPMIN		0x00010000
#define MBFL_WCSPLANE_SUPMAX		0x00200000
#define MBFL_WCSPLANE_JIS0208		0x70e10000		/* JIS HEX : 2121h - 7E7Eh */
#define MBFL_WCSPLANE_JIS0212		0x70e20000		/* JIS HEX : 2121h - 7E7Eh */
#define MBFL_WCSPLANE_WINCP932		0x70e30000		/* JIS HEX : 2121h - 9898h */
#define MBFL_WCSPLANE_8859_1		0x70e40000		/*  00h - FFh */
#define MBFL_WCSPLANE_8859_2		0x70e50000		/*  00h - FFh */
#define MBFL_WCSPLANE_8859_3		0x70e60000		/*  00h - FFh */
#define MBFL_WCSPLANE_8859_4		0x70e70000		/*  00h - FFh */
#define MBFL_WCSPLANE_8859_5		0x70e80000		/*  00h - FFh */
#define MBFL_WCSPLANE_8859_6		0x70e90000		/*  00h - FFh */
#define MBFL_WCSPLANE_8859_7		0x70ea0000		/*  00h - FFh */
#define MBFL_WCSPLANE_8859_8		0x70eb0000		/*  00h - FFh */
#define MBFL_WCSPLANE_8859_9		0x70ec0000		/*  00h - FFh */
#define MBFL_WCSPLANE_8859_10		0x70ed0000		/*  00h - FFh */
#define MBFL_WCSPLANE_8859_13		0x70ee0000		/*  00h - FFh */
#define MBFL_WCSPLANE_8859_14		0x70ef0000		/*  00h - FFh */
#define MBFL_WCSPLANE_8859_15		0x70f00000		/*  00h - FFh */
#define MBFL_WCSPLANE_KSC5601		0x70f10000		/*  2121h - 7E7Eh */
#define MBFL_WCSPLANE_GB2312		0x70f20000		/*  2121h - 7E7Eh */
#define MBFL_WCSPLANE_WINCP936		0x70f30000		/*  2121h - 9898h */
#define MBFL_WCSPLANE_BIG5		0x70f40000		/*  2121h - 9898h */
#define MBFL_WCSPLANE_CNS11643		0x70f50000		/*  2121h - 9898h */
#define MBFL_WCSPLANE_UHC		0x70f60000		/*  8141h - fefeh */
#define MBFL_WCSPLANE_CP1251		0x70f70000	
#define MBFL_WCSPLANE_CP866			0x70f80000	
#define MBFL_WCSPLANE_KOI8R 		0x70f90000	
#define MBFL_WCSPLANE_8859_16		0x70fa0000		/*  00h - FFh */
#define MBFL_WCSPLANE_ARMSCII8 		0x70fb0000
#define MBFL_WCSGROUP_MASK                0xffffff
#define MBFL_WCSGROUP_UCS4MAX		0x70000000
#define MBFL_WCSGROUP_WCHARMAX		0x78000000
#define MBFL_WCSGROUP_THROUGH		0x78000000		/* 000000h - FFFFFFh */

#define MBFL_QPRINT_STS_MIME_HEADER 0x1000000
#define MBFL_BASE64_STS_MIME_HEADER 0x1000000

#endif /* MBFL_CONSTS_H */
php/ext/mbstring/libmbfl/mbfl/mbfl_encoding.h000064400000007374151730540260015264 0ustar00/*
 * "streamable kanji code filter and converter"
 * Copyright (c) 1998-2002 HappySize, Inc. All rights reserved.
 *
 * LICENSE NOTICES
 *
 * This file is part of "streamable kanji code filter and converter",
 * which is distributed under the terms of GNU Lesser General Public 
 * License (version 2) as published by the Free Software Foundation.
 *
 * 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.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with "streamable kanji code filter and converter";
 * if not, write to the Free Software Foundation, Inc., 59 Temple Place,
 * Suite 330, Boston, MA  02111-1307  USA
 *
 * The author of this file:
 *
 */
/*
 * The source code included in this files was separated from mbfilter.h
 * by Moriyoshi Koizumi <moriyoshi@php.net> on 20 Dec 2002. The file
 * mbfilter.h is included in this package .
 *
 */

#ifndef MBFL_ENCODING_H
#define MBFL_ENCODING_H

#include "mbfl_defs.h"

enum mbfl_no_encoding {
	mbfl_no_encoding_invalid = -1,
	mbfl_no_encoding_pass,
	mbfl_no_encoding_auto,
	mbfl_no_encoding_wchar,
	mbfl_no_encoding_byte2be,
	mbfl_no_encoding_byte2le,
	mbfl_no_encoding_byte4be,
	mbfl_no_encoding_byte4le,
	mbfl_no_encoding_base64,
	mbfl_no_encoding_uuencode,
	mbfl_no_encoding_html_ent,
	mbfl_no_encoding_qprint,
	mbfl_no_encoding_7bit,
	mbfl_no_encoding_8bit,
	mbfl_no_encoding_charset_min,
	mbfl_no_encoding_ucs4,
	mbfl_no_encoding_ucs4be,
	mbfl_no_encoding_ucs4le,
	mbfl_no_encoding_ucs2,
	mbfl_no_encoding_ucs2be,
	mbfl_no_encoding_ucs2le,
	mbfl_no_encoding_utf32,
	mbfl_no_encoding_utf32be,
	mbfl_no_encoding_utf32le,
	mbfl_no_encoding_utf16,
	mbfl_no_encoding_utf16be,
	mbfl_no_encoding_utf16le,
	mbfl_no_encoding_utf8,
	mbfl_no_encoding_utf7,
	mbfl_no_encoding_utf7imap,
	mbfl_no_encoding_ascii,
	mbfl_no_encoding_euc_jp,
	mbfl_no_encoding_sjis,
	mbfl_no_encoding_eucjp_win,
	mbfl_no_encoding_sjis_win,
	mbfl_no_encoding_sjis_mac,
	mbfl_no_encoding_cp51932,
	mbfl_no_encoding_jis,
	mbfl_no_encoding_2022jp,
	mbfl_no_encoding_2022jpms,
	mbfl_no_encoding_cp1252,
	mbfl_no_encoding_8859_1,
	mbfl_no_encoding_8859_2,
	mbfl_no_encoding_8859_3,
	mbfl_no_encoding_8859_4,
	mbfl_no_encoding_8859_5,
	mbfl_no_encoding_8859_6,
	mbfl_no_encoding_8859_7,
	mbfl_no_encoding_8859_8,
	mbfl_no_encoding_8859_9,
	mbfl_no_encoding_8859_10,
	mbfl_no_encoding_8859_13,
	mbfl_no_encoding_8859_14,
	mbfl_no_encoding_8859_15,
	mbfl_no_encoding_euc_cn,
	mbfl_no_encoding_cp936,
	mbfl_no_encoding_euc_tw,
	mbfl_no_encoding_big5,
	mbfl_no_encoding_euc_kr,
	mbfl_no_encoding_2022kr,
	mbfl_no_encoding_uhc,
	mbfl_no_encoding_hz,
	mbfl_no_encoding_cp1251,
	mbfl_no_encoding_cp866,
	mbfl_no_encoding_koi8r,
	mbfl_no_encoding_8859_16,
	mbfl_no_encoding_armscii8,
	mbfl_no_encoding_charset_max
};

typedef enum mbfl_no_encoding mbfl_encoding_id;

/*
 * encoding
 */
typedef struct _mbfl_encoding {
	enum mbfl_no_encoding no_encoding;
	const char *name;
	const char *mime_name;
	const char *(*aliases)[];
	const unsigned char *mblen_table;
	unsigned int flag;
} mbfl_encoding;

MBFLAPI extern const mbfl_encoding * mbfl_name2encoding(const char *name);
MBFLAPI extern const mbfl_encoding * mbfl_no2encoding(enum mbfl_no_encoding no_encoding);
MBFLAPI extern enum mbfl_no_encoding mbfl_name2no_encoding(const char *name);
MBFLAPI extern const mbfl_encoding ** mbfl_get_supported_encodings();
MBFLAPI extern const char * mbfl_no_encoding2name(enum mbfl_no_encoding no_encoding);
MBFLAPI extern const char * mbfl_no2preferred_mime_name(enum mbfl_no_encoding no_encoding);
MBFLAPI extern int mbfl_is_support_encoding(const char *name);


#endif /* MBFL_ENCODING_H */
php/ext/mbstring/libmbfl/mbfl/mbfilter_8bit.h000064400000002411151730540260015213 0ustar00/*
 * "streamable kanji code filter and converter"
 * Copyright (c) 1998-2002 HappySize, Inc. All rights reserved.
 *
 * LICENSE NOTICES
 *
 * This file is part of "streamable kanji code filter and converter",
 * which is distributed under the terms of GNU Lesser General Public 
 * License (version 2) as published by the Free Software Foundation.
 *
 * 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.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with "streamable kanji code filter and converter";
 * if not, write to the Free Software Foundation, Inc., 59 Temple Place,
 * Suite 330, Boston, MA  02111-1307  USA
 *
 * The author of this file:
 *
 */
/*
 * The source code included in this files was separated from mbfilter.c
 * by Moriyoshi Koizumi <moriyoshi@php.net> on 20 Dec 2002. The file
 * mbfilter.c is included in this package .
 *
 */

#ifndef MBFL_MBFILTER_8BIT_H
#define MBFL_MBFILTER_8BIT_H

#include "mbfl_defs.h"
#include "mbfilter.h"

MBFLAPI extern const mbfl_encoding mbfl_encoding_8bit;

#endif /* MBFL_MBFILTER_8BIT_H */
php/ext/mbstring/libmbfl/mbfl/mbfl_convert.h000064400000006677151730540260015163 0ustar00/*
 * "streamable kanji code filter and converter"
 * Copyright (c) 1998-2002 HappySize, Inc. All rights reserved.
 *
 * LICENSE NOTICES
 *
 * This file is part of "streamable kanji code filter and converter",
 * which is distributed under the terms of GNU Lesser General Public 
 * License (version 2) as published by the Free Software Foundation.
 *
 * 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.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with "streamable kanji code filter and converter";
 * if not, write to the Free Software Foundation, Inc., 59 Temple Place,
 * Suite 330, Boston, MA  02111-1307  USA
 *
 * The author of this file:
 *
 */
/*
 * The source code included in this files was separated from mbfilter.h
 * by Moriyoshi Koizumi <moriyoshi@php.net> on 20 Dec 2002. The file
 * mbfilter.h is included in this package .
 *
 */

#ifndef MBFL_CONVERT_H
#define MBFL_CONVERT_H

#include "mbfl_defs.h"
#include "mbfl_encoding.h"
#include "mbfl_memory_device.h"

typedef struct _mbfl_convert_filter mbfl_convert_filter;

struct _mbfl_convert_filter {
	void (*filter_ctor)(mbfl_convert_filter *filter);
	void (*filter_dtor)(mbfl_convert_filter *filter);
	int (*filter_function)(int c, mbfl_convert_filter *filter);
	int (*filter_flush)(mbfl_convert_filter *filter);
	int (*output_function)(int c, void *data);
	int (*flush_function)(void *data);
	void *data;
	int status;
	int cache;
	const mbfl_encoding *from;
	const mbfl_encoding *to;
	int illegal_mode;
	int illegal_substchar;
	int num_illegalchar;
	void *opaque;
};

struct mbfl_convert_vtbl {
	enum mbfl_no_encoding from;
	enum mbfl_no_encoding to;
	void (*filter_ctor)(mbfl_convert_filter *filter);
	void (*filter_dtor)(mbfl_convert_filter *filter);
	int (*filter_function)(int c, mbfl_convert_filter *filter);
	int (*filter_flush)(mbfl_convert_filter *filter);
};

MBFLAPI extern const struct mbfl_convert_vtbl *mbfl_convert_filter_list[];

MBFLAPI extern mbfl_convert_filter *mbfl_convert_filter_new(
    enum mbfl_no_encoding from,
    enum mbfl_no_encoding to,
    int (*output_function)(int, void *),
    int (*flush_function)(void *),
    void *data );
MBFLAPI extern void mbfl_convert_filter_delete(mbfl_convert_filter *filter);
MBFLAPI extern int mbfl_convert_filter_feed(int c, mbfl_convert_filter *filter);
MBFLAPI extern int mbfl_convert_filter_flush(mbfl_convert_filter *filter);
MBFLAPI extern void mbfl_convert_filter_reset(mbfl_convert_filter *filter, enum mbfl_no_encoding from, enum mbfl_no_encoding to);
MBFLAPI extern void mbfl_convert_filter_copy(mbfl_convert_filter *src, mbfl_convert_filter *dist);
MBFLAPI extern int mbfl_filt_conv_illegal_output(int c, mbfl_convert_filter *filter);
MBFLAPI extern const struct mbfl_convert_vtbl * mbfl_convert_filter_get_vtbl(enum mbfl_no_encoding from, enum mbfl_no_encoding to);

MBFLAPI extern void mbfl_filt_conv_common_ctor(mbfl_convert_filter *filter);
MBFLAPI extern int mbfl_filt_conv_common_flush(mbfl_convert_filter *filter);
MBFLAPI extern void mbfl_filt_conv_common_dtor(mbfl_convert_filter *filter);

MBFLAPI extern int mbfl_convert_filter_devcat(mbfl_convert_filter *filter, mbfl_memory_device *src);
MBFLAPI extern int mbfl_convert_filter_strcat(mbfl_convert_filter *filter, const unsigned char *p);

#endif /* MBFL_CONVERT_H */
php/ext/mbstring/libmbfl/mbfl/mbfilter_wchar.h000064400000002415151730540260015455 0ustar00/*
 * "streamable kanji code filter and converter"
 * Copyright (c) 1998-2002 HappySize, Inc. All rights reserved.
 *
 * LICENSE NOTICES
 *
 * This file is part of "streamable kanji code filter and converter",
 * which is distributed under the terms of GNU Lesser General Public 
 * License (version 2) as published by the Free Software Foundation.
 *
 * 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.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with "streamable kanji code filter and converter";
 * if not, write to the Free Software Foundation, Inc., 59 Temple Place,
 * Suite 330, Boston, MA  02111-1307  USA
 *
 * The author of this file:
 *
 */
/*
 * The source code included in this files was separated from mbfilter.c
 * by Moriyoshi Koizumi <moriyoshi@php.net> on 20 Dec 2002. The file
 * mbfilter.c is included in this package .
 *
 */

#ifndef MBFL_MBFILTER_WCHAR_H
#define MBFL_MBFILTER_WCHAR_H

#include "mbfl_defs.h"
#include "mbfilter.h"

MBFLAPI extern const mbfl_encoding mbfl_encoding_wchar;

#endif /* MBFL_MBFILTER_WCHAR_H */
php/ext/mbstring/libmbfl/mbfl/mbfl_allocators.h000064400000003543151730540260015633 0ustar00/*
 * "streamable kanji code filter and converter"
 * Copyright (c) 1998-2002 HappySize, Inc. All rights reserved.
 *
 * LICENSE NOTICES
 *
 * This file is part of "streamable kanji code filter and converter",
 * which is distributed under the terms of GNU Lesser General Public 
 * License (version 2) as published by the Free Software Foundation.
 *
 * 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.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with "streamable kanji code filter and converter";
 * if not, write to the Free Software Foundation, Inc., 59 Temple Place,
 * Suite 330, Boston, MA  02111-1307  USA
 *
 * The author of this file:
 *
 */
/*
 * The source code included in this files was separated from mbfilter.h
 * by Moriyoshi Koizumi <moriyoshi@php.net> on 20 Dec 2002. The file
 * mbfilter.h is included in this package .
 *
 */

#ifndef MBFL_ALLOCATORS_H
#define MBFL_ALLOCATORS_H

#include "mbfl_defs.h"

typedef struct _mbfl_allocators {
	void *(*malloc)(unsigned int);
	void *(*realloc)(void *, unsigned int);
	void *(*calloc)(unsigned int, unsigned int);
	void (*free)(void *);
	void *(*pmalloc)(unsigned int); 
	void *(*prealloc)(void *, unsigned int);
	void (*pfree)(void *);
} mbfl_allocators;

MBFLAPI extern mbfl_allocators *__mbfl_allocators; 

#define mbfl_malloc (__mbfl_allocators->malloc)
#define mbfl_realloc (__mbfl_allocators->realloc)
#define mbfl_calloc (__mbfl_allocators->calloc)
#define mbfl_free (__mbfl_allocators->free)
#define mbfl_pmalloc (__mbfl_allocators->pmalloc)
#define mbfl_prealloc (__mbfl_allocators->preallloc)
#define mbfl_pfree (__mbfl_allocators->pfree)

#endif /* MBFL_ALLOCATORS_H */
php/ext/mbstring/libmbfl/mbfl/mbfl_ident.h000064400000005150151730540270014570 0ustar00/*
 * "streamable kanji code filter and converter"
 * Copyright (c) 1998-2002 HappySize, Inc. All rights reserved.
 *
 * LICENSE NOTICES
 *
 * This file is part of "streamable kanji code filter and converter",
 * which is distributed under the terms of GNU Lesser General Public 
 * License (version 2) as published by the Free Software Foundation.
 *
 * 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.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with "streamable kanji code filter and converter";
 * if not, write to the Free Software Foundation, Inc., 59 Temple Place,
 * Suite 330, Boston, MA  02111-1307  USA
 *
 * The author of this file:
 *
 */
/*
 * The source code included in this files was separated from mbfilter.h
 * by Moriyoshi Koizumi <moriyoshi@php.net> on 20 Dec 2002. The file
 * mbfilter.h is included in this package .
 *
 */

#ifndef MBFL_IDENT_H
#define MBFL_IDENT_H

#include "mbfl_defs.h"
#include "mbfl_encoding.h"

/*
 * identify filter
 */
typedef struct _mbfl_identify_filter mbfl_identify_filter;

struct _mbfl_identify_filter {
	void (*filter_ctor)(mbfl_identify_filter *filter);
	void (*filter_dtor)(mbfl_identify_filter *filter);
	int (*filter_function)(int c, mbfl_identify_filter *filter);
	int status;
	int flag;
	int score;
	const mbfl_encoding *encoding;
};

struct mbfl_identify_vtbl {
	enum mbfl_no_encoding encoding;
	void (*filter_ctor)(mbfl_identify_filter *filter);
	void (*filter_dtor)(mbfl_identify_filter *filter);
	int (*filter_function)(int c, mbfl_identify_filter *filter);
};

MBFLAPI extern const struct mbfl_identify_vtbl * mbfl_identify_filter_get_vtbl(enum mbfl_no_encoding encoding);
MBFLAPI extern mbfl_identify_filter * mbfl_identify_filter_new(enum mbfl_no_encoding encoding);
MBFLAPI extern void mbfl_identify_filter_delete(mbfl_identify_filter *filter);
MBFLAPI extern int mbfl_identify_filter_init(mbfl_identify_filter *filter, enum mbfl_no_encoding encoding);
MBFLAPI void mbfl_identify_filter_cleanup(mbfl_identify_filter *filter);

MBFLAPI extern void mbfl_filt_ident_common_ctor(mbfl_identify_filter *filter);
MBFLAPI extern void mbfl_filt_ident_common_dtor(mbfl_identify_filter *filter);
MBFLAPI extern void mbfl_filt_ident_false_ctor(mbfl_identify_filter *filter);

MBFLAPI extern int mbfl_filt_ident_false(int c, mbfl_identify_filter *filter);
MBFLAPI extern int mbfl_filt_ident_true(int c, mbfl_identify_filter *filter);

#endif /* MBFL_IDENT_H */
php/ext/mbstring/libmbfl/mbfl/mbfl_filter_output.h000064400000002442151730540270016373 0ustar00/*
 * "streamable kanji code filter and converter"
 * Copyright (c) 1998-2002 HappySize, Inc. All rights reserved.
 *
 * LICENSE NOTICES
 *
 * This file is part of "streamable kanji code filter and converter",
 * which is distributed under the terms of GNU Lesser General Public 
 * License (version 2) as published by the Free Software Foundation.
 *
 * 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.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with "streamable kanji code filter and converter";
 * if not, write to the Free Software Foundation, Inc., 59 Temple Place,
 * Suite 330, Boston, MA  02111-1307  USA
 *
 * The author of this file:
 *
 */
/*
 * The source code included in this files was separated from mbfilter.h
 * by Moriyoshi Koizumi <moriyoshi@php.net> on 20 Dec 2002. The file
 * mbfilter.h is included in this package .
 *
 */

#ifndef MBFL_FILTER_OUTPUT_H
#define MBFL_FILTER_OUTPUT_H

MBFLAPI extern int mbfl_filter_output_pipe(int c, void* data);
MBFLAPI extern int mbfl_filter_output_null(int c, void* data);

#endif /* MBFL_FILTER_OUTPUT_H */
php/ext/mbstring/php_onig_compat.h000064400000000400151730540270013275 0ustar00#ifndef _PHP_ONIG_COMPAT_H
#define _PHP_ONIG_COMPAT_H

#define re_pattern_buffer           php_mb_re_pattern_buffer
#define regex_t                     php_mb_regex_t
#define re_registers                php_mb_re_registers

#endif /* _PHP_ONIG_COMPAT_H */
php/ext/mbstring/oniguruma/oniguruma.h000064400000115305151730540270014156 0ustar00#ifndef ONIGURUMA_H
#define ONIGURUMA_H
/**********************************************************************
  oniguruma.h - Oniguruma (regular expression library)
**********************************************************************/
/*-
 * Copyright (c) 2002-2009  K.Kosako  <sndgk393 AT ybb DOT ne DOT jp>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include "php_onig_compat.h"

#ifdef __cplusplus
extern "C" {
#endif

#define ONIGURUMA
#define ONIGURUMA_VERSION_MAJOR   4
#define ONIGURUMA_VERSION_MINOR   4
#define ONIGURUMA_VERSION_TEENY   4

#ifdef __cplusplus
# ifndef  HAVE_PROTOTYPES
#  define HAVE_PROTOTYPES 1
# endif
# ifndef  HAVE_STDARG_PROTOTYPES
#  define HAVE_STDARG_PROTOTYPES 1
# endif
#endif

/* escape Mac OS X/Xcode 2.4/gcc 4.0.1 problem */
#if defined(__APPLE__) && defined(__GNUC__) && __GNUC__ >= 4
# ifndef  HAVE_STDARG_PROTOTYPES
#  define HAVE_STDARG_PROTOTYPES 1
# endif
#endif

#ifndef P_
#if defined(__STDC__) || defined(_WIN32)
# define P_(args) args
#else
# define P_(args) ()
#endif
#endif

#ifndef PV_
#ifdef HAVE_STDARG_PROTOTYPES
# define PV_(args) args
#else
# define PV_(args) ()
#endif
#endif

#ifndef ONIG_EXTERN
#if defined(_WIN32) && !defined(__GNUC__)
#if defined(EXPORT) || defined(RUBY_EXPORT)
#define ONIG_EXTERN   extern __declspec(dllexport)
#else
#define ONIG_EXTERN   extern __declspec(dllimport)
#endif
#endif
#endif

#ifndef ONIG_EXTERN
#define ONIG_EXTERN   extern
#endif

/* PART: character encoding */

#ifndef ONIG_ESCAPE_UCHAR_COLLISION
#define UChar OnigUChar
#endif

typedef unsigned char  OnigUChar;
typedef unsigned long  OnigCodePoint;
typedef unsigned int   OnigDistance;

#define ONIG_INFINITE_DISTANCE  ~((OnigDistance )0)

/* ambiguous match flag */
typedef unsigned int OnigAmbigType;

ONIG_EXTERN OnigAmbigType OnigDefaultAmbigFlag;

#define ONIGENC_AMBIGUOUS_MATCH_NONE                   0
#define ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE            (1<<0)
#define ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE         (1<<1)
/* #define ONIGENC_AMBIGUOUS_MATCH_ACCENT             (1<<2) */
/* #define ONIGENC_AMBIGUOUS_MATCH_HIRAGANA_KATAKANA  (1<<3) */
/* #define ONIGENC_AMBIGUOUS_MATCH_KATAKANA_WIDTH     (1<<4) */

#define ONIGENC_AMBIGUOUS_MATCH_LIMIT                 (1<<1)
#define ONIGENC_AMBIGUOUS_MATCH_COMPOUND              (1<<30)

#define ONIGENC_AMBIGUOUS_MATCH_FULL \
  ( ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE | \
    ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE | \
    ONIGENC_AMBIGUOUS_MATCH_COMPOUND )
#define ONIGENC_AMBIGUOUS_MATCH_DEFAULT  OnigDefaultAmbigFlag


#define ONIGENC_MAX_COMP_AMBIG_CODE_LEN       3
#define ONIGENC_MAX_COMP_AMBIG_CODE_ITEM_NUM  4

/* code range */
#define ONIGENC_CODE_RANGE_NUM(range)     ((int )range[0])
#define ONIGENC_CODE_RANGE_FROM(range,i)  range[((i)*2) + 1]
#define ONIGENC_CODE_RANGE_TO(range,i)    range[((i)*2) + 2]

typedef struct {
  int len;
  OnigCodePoint code[ONIGENC_MAX_COMP_AMBIG_CODE_LEN];
} OnigCompAmbigCodeItem;

typedef struct {
  int n;
  OnigCodePoint code;
  OnigCompAmbigCodeItem items[ONIGENC_MAX_COMP_AMBIG_CODE_ITEM_NUM];
} OnigCompAmbigCodes;

typedef struct {
  OnigCodePoint from;
  OnigCodePoint to;
} OnigPairAmbigCodes;

typedef struct {
  OnigCodePoint esc;
  OnigCodePoint anychar;
  OnigCodePoint anytime;
  OnigCodePoint zero_or_one_time;
  OnigCodePoint one_or_more_time;
  OnigCodePoint anychar_anytime;
} OnigMetaCharTableType;


#if defined(RUBY_PLATFORM) && defined(M17N_H)

#define ONIG_RUBY_M17N
typedef m17n_encoding*        OnigEncoding;

#else

typedef struct {
  int    (*mbc_enc_len)(const OnigUChar* p);
  const char*   name;
  int           max_enc_len;
  int           min_enc_len;
  OnigAmbigType support_ambig_flag;
  OnigMetaCharTableType meta_char_table;
  int    (*is_mbc_newline)(const OnigUChar* p, const OnigUChar* end);
  OnigCodePoint (*mbc_to_code)(const OnigUChar* p, const OnigUChar* end);
  int    (*code_to_mbclen)(OnigCodePoint code);
  int    (*code_to_mbc)(OnigCodePoint code, OnigUChar *buf);
  int    (*mbc_to_normalize)(OnigAmbigType flag, const OnigUChar** pp, const OnigUChar* end, OnigUChar* to);
  int    (*is_mbc_ambiguous)(OnigAmbigType flag, const OnigUChar** pp, const OnigUChar* end);
  int    (*get_all_pair_ambig_codes)(OnigAmbigType flag, const OnigPairAmbigCodes** acs);
  int    (*get_all_comp_ambig_codes)(OnigAmbigType flag, const OnigCompAmbigCodes** acs);
  int    (*is_code_ctype)(OnigCodePoint code, unsigned int ctype);
  int    (*get_ctype_code_range)(int ctype, const OnigCodePoint* sb_range[], const OnigCodePoint* mb_range[]);
  OnigUChar* (*left_adjust_char_head)(const OnigUChar* start, const OnigUChar* p);
  int    (*is_allowed_reverse_match)(const OnigUChar* p, const OnigUChar* end);
} OnigEncodingType;

typedef OnigEncodingType* OnigEncoding;

ONIG_EXTERN OnigEncodingType OnigEncodingASCII;
ONIG_EXTERN OnigEncodingType OnigEncodingISO_8859_1;
ONIG_EXTERN OnigEncodingType OnigEncodingISO_8859_2;
ONIG_EXTERN OnigEncodingType OnigEncodingISO_8859_3;
ONIG_EXTERN OnigEncodingType OnigEncodingISO_8859_4;
ONIG_EXTERN OnigEncodingType OnigEncodingISO_8859_5;
ONIG_EXTERN OnigEncodingType OnigEncodingISO_8859_6;
ONIG_EXTERN OnigEncodingType OnigEncodingISO_8859_7;
ONIG_EXTERN OnigEncodingType OnigEncodingISO_8859_8;
ONIG_EXTERN OnigEncodingType OnigEncodingISO_8859_9;
ONIG_EXTERN OnigEncodingType OnigEncodingISO_8859_10;
ONIG_EXTERN OnigEncodingType OnigEncodingISO_8859_11;
ONIG_EXTERN OnigEncodingType OnigEncodingISO_8859_13;
ONIG_EXTERN OnigEncodingType OnigEncodingISO_8859_14;
ONIG_EXTERN OnigEncodingType OnigEncodingISO_8859_15;
ONIG_EXTERN OnigEncodingType OnigEncodingISO_8859_16;
ONIG_EXTERN OnigEncodingType OnigEncodingUTF8;
ONIG_EXTERN OnigEncodingType OnigEncodingUTF16_BE;
ONIG_EXTERN OnigEncodingType OnigEncodingUTF16_LE;
ONIG_EXTERN OnigEncodingType OnigEncodingUTF32_BE;
ONIG_EXTERN OnigEncodingType OnigEncodingUTF32_LE;
ONIG_EXTERN OnigEncodingType OnigEncodingEUC_JP;
ONIG_EXTERN OnigEncodingType OnigEncodingEUC_TW;
ONIG_EXTERN OnigEncodingType OnigEncodingEUC_KR;
ONIG_EXTERN OnigEncodingType OnigEncodingEUC_CN;
ONIG_EXTERN OnigEncodingType OnigEncodingSJIS;
ONIG_EXTERN OnigEncodingType OnigEncodingKOI8;
ONIG_EXTERN OnigEncodingType OnigEncodingKOI8_R;
ONIG_EXTERN OnigEncodingType OnigEncodingBIG5;
ONIG_EXTERN OnigEncodingType OnigEncodingGB18030;

#define ONIG_ENCODING_ASCII        (&OnigEncodingASCII)
#define ONIG_ENCODING_ISO_8859_1   (&OnigEncodingISO_8859_1)
#define ONIG_ENCODING_ISO_8859_2   (&OnigEncodingISO_8859_2)
#define ONIG_ENCODING_ISO_8859_3   (&OnigEncodingISO_8859_3)
#define ONIG_ENCODING_ISO_8859_4   (&OnigEncodingISO_8859_4)
#define ONIG_ENCODING_ISO_8859_5   (&OnigEncodingISO_8859_5)
#define ONIG_ENCODING_ISO_8859_6   (&OnigEncodingISO_8859_6)
#define ONIG_ENCODING_ISO_8859_7   (&OnigEncodingISO_8859_7)
#define ONIG_ENCODING_ISO_8859_8   (&OnigEncodingISO_8859_8)
#define ONIG_ENCODING_ISO_8859_9   (&OnigEncodingISO_8859_9)
#define ONIG_ENCODING_ISO_8859_10  (&OnigEncodingISO_8859_10)
#define ONIG_ENCODING_ISO_8859_11  (&OnigEncodingISO_8859_11)
#define ONIG_ENCODING_ISO_8859_13  (&OnigEncodingISO_8859_13)
#define ONIG_ENCODING_ISO_8859_14  (&OnigEncodingISO_8859_14)
#define ONIG_ENCODING_ISO_8859_15  (&OnigEncodingISO_8859_15)
#define ONIG_ENCODING_ISO_8859_16  (&OnigEncodingISO_8859_16)
#define ONIG_ENCODING_UTF8         (&OnigEncodingUTF8)
#define ONIG_ENCODING_UTF16_BE     (&OnigEncodingUTF16_BE)
#define ONIG_ENCODING_UTF16_LE     (&OnigEncodingUTF16_LE)
#define ONIG_ENCODING_UTF32_BE     (&OnigEncodingUTF32_BE)
#define ONIG_ENCODING_UTF32_LE     (&OnigEncodingUTF32_LE)
#define ONIG_ENCODING_EUC_JP       (&OnigEncodingEUC_JP)
#define ONIG_ENCODING_EUC_TW       (&OnigEncodingEUC_TW)
#define ONIG_ENCODING_EUC_KR       (&OnigEncodingEUC_KR)
#define ONIG_ENCODING_EUC_CN       (&OnigEncodingEUC_CN)
#define ONIG_ENCODING_SJIS         (&OnigEncodingSJIS)
#define ONIG_ENCODING_KOI8         (&OnigEncodingKOI8)
#define ONIG_ENCODING_KOI8_R       (&OnigEncodingKOI8_R)
#define ONIG_ENCODING_BIG5         (&OnigEncodingBIG5)
#define ONIG_ENCODING_GB18030      (&OnigEncodingGB18030)

#endif /* else RUBY && M17N */

#define ONIG_ENCODING_UNDEF    ((OnigEncoding )0)


/* work size */
#define ONIGENC_CODE_TO_MBC_MAXLEN      7
#define ONIGENC_MBC_NORMALIZE_MAXLEN    ONIGENC_CODE_TO_MBC_MAXLEN

/* character types */
#define ONIGENC_CTYPE_NEWLINE  (1<< 0)
#define ONIGENC_CTYPE_ALPHA    (1<< 1)
#define ONIGENC_CTYPE_BLANK    (1<< 2)
#define ONIGENC_CTYPE_CNTRL    (1<< 3)
#define ONIGENC_CTYPE_DIGIT    (1<< 4)
#define ONIGENC_CTYPE_GRAPH    (1<< 5)
#define ONIGENC_CTYPE_LOWER    (1<< 6)
#define ONIGENC_CTYPE_PRINT    (1<< 7)
#define ONIGENC_CTYPE_PUNCT    (1<< 8)
#define ONIGENC_CTYPE_SPACE    (1<< 9)
#define ONIGENC_CTYPE_UPPER    (1<<10)
#define ONIGENC_CTYPE_XDIGIT   (1<<11)
#define ONIGENC_CTYPE_WORD     (1<<12)
#define ONIGENC_CTYPE_ASCII    (1<<13)
#define ONIGENC_CTYPE_ALNUM    (ONIGENC_CTYPE_ALPHA | ONIGENC_CTYPE_DIGIT)

#define enc_len(enc,p)                ONIGENC_MBC_ENC_LEN(enc, p)

#define ONIGENC_IS_UNDEF(enc)          ((enc) == ONIG_ENCODING_UNDEF)
#define ONIGENC_IS_SINGLEBYTE(enc)     (ONIGENC_MBC_MAXLEN(enc) == 1)
#define ONIGENC_IS_MBC_HEAD(enc,p)     (ONIGENC_MBC_ENC_LEN(enc,p) != 1)
#define ONIGENC_IS_MBC_ASCII(p)           (*(p)   < 128)
#define ONIGENC_IS_CODE_ASCII(code)       ((code) < 128)
#define ONIGENC_IS_CODE_SB_WORD(enc,code) \
  (ONIGENC_IS_CODE_ASCII(code) && ONIGENC_IS_CODE_WORD(enc,code))
#define ONIGENC_IS_MBC_WORD(enc,s,end) \
   ONIGENC_IS_CODE_WORD(enc,ONIGENC_MBC_TO_CODE(enc,s,end))


#ifdef ONIG_RUBY_M17N

#include <ctype.h> /* for isblank(), isgraph() */

#define ONIGENC_MBC_TO_NORMALIZE(enc,flag,pp,end,buf) \
        onigenc_mbc_to_normalize(enc,flag,pp,end,buf)
#define ONIGENC_IS_MBC_AMBIGUOUS(enc,flag,pp,end) \
        onigenc_is_mbc_ambiguous(enc,flag,pp,end)

#define ONIGENC_SUPPORT_AMBIG_FLAG(enc)     ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE
#define ONIGENC_IS_ALLOWED_REVERSE_MATCH(enc,s,end) \
        onigenc_is_allowed_reverse_match(enc, s, end)
#define ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc,start,s) \
        onigenc_get_left_adjust_char_head(enc, start, s)
#define ONIGENC_GET_ALL_PAIR_AMBIG_CODES(enc, ambig_flag, acs)    0
#define ONIGENC_GET_ALL_COMP_AMBIG_CODES(enc, ambig_flag, acs)    0
#define ONIGENC_GET_CTYPE_CODE_RANGE(enc,ctype,sbr,mbr) \
        ONIG_NO_SUPPORT_CONFIG
#define ONIGENC_MBC_ENC_LEN(enc,p)            m17n_mbclen(enc,(int )(*p))
#define ONIGENC_MBC_MAXLEN(enc)               m17n_mbmaxlen(enc)
#define ONIGENC_MBC_MAXLEN_DIST(enc) \
    (ONIGENC_MBC_MAXLEN(enc) > 0 ? ONIGENC_MBC_MAXLEN(enc) \
                                 : ONIG_INFINITE_DISTANCE)
#define ONIGENC_MBC_MINLEN(enc)            1
#define ONIGENC_MBC_TO_CODE(enc,p,e)       m17n_codepoint((enc),(p),(e))
#define ONIGENC_CODE_TO_MBCLEN(enc,code)   m17n_codelen((enc),(code))
#define ONIGENC_CODE_TO_MBC(enc,code,buf)  onigenc_code_to_mbc(enc, code, buf)

#if 0     /* !! not supported !! */
#define ONIGENC_IS_MBC_NEWLINE(enc,p,end)
#define ONIGENC_STEP_BACK(enc,start,s,n)
#endif

#define ONIGENC_IS_CODE_CTYPE(enc,code,ctype) \
        onigenc_is_code_ctype(enc,code,ctype)

#ifdef isblank
# define ONIGENC_IS_CODE_BLANK(enc,code) isblank((int )code)
#else
# define ONIGENC_IS_CODE_BLANK(enc,code) ((code) == ' ' || (code) == '\t')
#endif
#ifdef isgraph
# define ONIGENC_IS_CODE_GRAPH(enc,code) isgraph((int )code)
#else
# define ONIGENC_IS_CODE_GRAPH(enc,code) \
  (isprint((int )code) && !isspace((int )code))
#endif

#define ONIGENC_IS_CODE_PRINT(enc,code)     m17n_isprint(enc,code)
#define ONIGENC_IS_CODE_ALNUM(enc,code)     m17n_isalnum(enc,code)
#define ONIGENC_IS_CODE_ALPHA(enc,code)     m17n_isalpha(enc,code)
#define ONIGENC_IS_CODE_LOWER(enc,code)     m17n_islower(enc,code)
#define ONIGENC_IS_CODE_UPPER(enc,code)     m17n_isupper(enc,code)
#define ONIGENC_IS_CODE_CNTRL(enc,code)     m17n_iscntrl(enc,code)
#define ONIGENC_IS_CODE_PUNCT(enc,code)     m17n_ispunct(enc,code)
#define ONIGENC_IS_CODE_SPACE(enc,code)     m17n_isspace(enc,code)
#define ONIGENC_IS_CODE_DIGIT(enc,code)     m17n_isdigit(enc,code)
#define ONIGENC_IS_CODE_XDIGIT(enc,code)    m17n_isxdigit(enc,code)
#define ONIGENC_IS_CODE_WORD(enc,code)      m17n_iswchar(enc,code)

ONIG_EXTERN
int onigenc_is_code_ctype P_((OnigEncoding enc, OnigCodePoint code, int ctype));
ONIG_EXTERN
int onigenc_code_to_mbc P_((OnigEncoding enc, OnigCodePoint code, OnigUChar *buf));
ONIG_EXTERN
int onigenc_mbc_to_normalize P_((OnigEncoding enc, OnigAmbigType flag, const OnigUChar** pp, const OnigUChar* end, OnigUChar* buf));
ONIG_EXTERN
int onigenc_is_mbc_ambiguous P_((OnigEncoding enc, OnigAmbigType flag, const OnigUChar** pp, const OnigUChar* end));
ONIG_EXTERN
int onigenc_is_allowed_reverse_match P_((OnigEncoding enc, const OnigUChar* s, const OnigUChar* end));

#else  /* ONIG_RUBY_M17N */

#define ONIGENC_NAME(enc)                      ((enc)->name)

#define ONIGENC_MBC_TO_NORMALIZE(enc,flag,pp,end,buf) \
  (enc)->mbc_to_normalize(flag,(const OnigUChar** )pp,end,buf)
#define ONIGENC_IS_MBC_AMBIGUOUS(enc,flag,pp,end) \
  (enc)->is_mbc_ambiguous(flag,(const OnigUChar** )pp,end)
#define ONIGENC_SUPPORT_AMBIG_FLAG(enc)        ((enc)->support_ambig_flag)
#define ONIGENC_IS_ALLOWED_REVERSE_MATCH(enc,s,end) \
        (enc)->is_allowed_reverse_match(s,end)
#define ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc,start,s) \
        (enc)->left_adjust_char_head(start, s)
#define ONIGENC_GET_ALL_PAIR_AMBIG_CODES(enc,ambig_flag,acs) \
        (enc)->get_all_pair_ambig_codes(ambig_flag,acs)
#define ONIGENC_GET_ALL_COMP_AMBIG_CODES(enc,ambig_flag,acs) \
        (enc)->get_all_comp_ambig_codes(ambig_flag,acs)
#define ONIGENC_STEP_BACK(enc,start,s,n) \
        onigenc_step_back((enc),(start),(s),(n))

#define ONIGENC_MBC_ENC_LEN(enc,p)             (enc)->mbc_enc_len(p)
#define ONIGENC_MBC_MAXLEN(enc)               ((enc)->max_enc_len)
#define ONIGENC_MBC_MAXLEN_DIST(enc)           ONIGENC_MBC_MAXLEN(enc)
#define ONIGENC_MBC_MINLEN(enc)               ((enc)->min_enc_len)
#define ONIGENC_IS_MBC_NEWLINE(enc,p,end)      (enc)->is_mbc_newline((p),(end))
#define ONIGENC_MBC_TO_CODE(enc,p,end)         (enc)->mbc_to_code((p),(end))
#define ONIGENC_CODE_TO_MBCLEN(enc,code)       (enc)->code_to_mbclen(code)
#define ONIGENC_CODE_TO_MBC(enc,code,buf)      (enc)->code_to_mbc(code,buf)

#define ONIGENC_IS_CODE_CTYPE(enc,code,ctype)  (enc)->is_code_ctype(code,ctype)

#define ONIGENC_IS_CODE_NEWLINE(enc,code) \
        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_NEWLINE)
#define ONIGENC_IS_CODE_GRAPH(enc,code) \
        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_GRAPH)
#define ONIGENC_IS_CODE_PRINT(enc,code) \
        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_PRINT)
#define ONIGENC_IS_CODE_ALNUM(enc,code) \
        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_ALNUM)
#define ONIGENC_IS_CODE_ALPHA(enc,code) \
        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_ALPHA)
#define ONIGENC_IS_CODE_LOWER(enc,code) \
        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_LOWER)
#define ONIGENC_IS_CODE_UPPER(enc,code) \
        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_UPPER)
#define ONIGENC_IS_CODE_CNTRL(enc,code) \
        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_CNTRL)
#define ONIGENC_IS_CODE_PUNCT(enc,code) \
        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_PUNCT)
#define ONIGENC_IS_CODE_SPACE(enc,code) \
        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_SPACE)
#define ONIGENC_IS_CODE_BLANK(enc,code) \
        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_BLANK)
#define ONIGENC_IS_CODE_DIGIT(enc,code) \
        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_DIGIT)
#define ONIGENC_IS_CODE_XDIGIT(enc,code) \
        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_XDIGIT)
#define ONIGENC_IS_CODE_WORD(enc,code) \
        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_WORD)

#define ONIGENC_GET_CTYPE_CODE_RANGE(enc,ctype,sbr,mbr) \
        (enc)->get_ctype_code_range(ctype,sbr,mbr)

ONIG_EXTERN
OnigUChar* onigenc_step_back P_((OnigEncoding enc, const OnigUChar* start, const OnigUChar* s, int n));

#endif /* is not ONIG_RUBY_M17N */


/* encoding API */
ONIG_EXTERN
int onigenc_init P_(());
ONIG_EXTERN
int onigenc_set_default_encoding P_((OnigEncoding enc));
ONIG_EXTERN
OnigEncoding onigenc_get_default_encoding P_(());
ONIG_EXTERN
void  onigenc_set_default_caseconv_table P_((const OnigUChar* table));
ONIG_EXTERN
OnigUChar* onigenc_get_right_adjust_char_head_with_prev P_((OnigEncoding enc, const OnigUChar* start, const OnigUChar* s, const OnigUChar** prev));
ONIG_EXTERN
OnigUChar* onigenc_get_prev_char_head P_((OnigEncoding enc, const OnigUChar* start, const OnigUChar* s));
ONIG_EXTERN
OnigUChar* onigenc_get_left_adjust_char_head P_((OnigEncoding enc, const OnigUChar* start, const OnigUChar* s));
ONIG_EXTERN
OnigUChar* onigenc_get_right_adjust_char_head P_((OnigEncoding enc, const OnigUChar* start, const OnigUChar* s));
ONIG_EXTERN
int onigenc_strlen P_((OnigEncoding enc, const OnigUChar* p, const OnigUChar* end));
ONIG_EXTERN
int onigenc_strlen_null P_((OnigEncoding enc, const OnigUChar* p));
ONIG_EXTERN
int onigenc_str_bytelen_null P_((OnigEncoding enc, const OnigUChar* p));



/* PART: regular expression */

/* config parameters */
#define ONIG_NREGION                          10
#define ONIG_MAX_BACKREF_NUM                1000
#define ONIG_MAX_REPEAT_NUM               100000
#define ONIG_MAX_MULTI_BYTE_RANGES_NUM     10000
/* constants */
#define ONIG_MAX_ERROR_MESSAGE_LEN            90

typedef unsigned int        OnigOptionType;

#define ONIG_OPTION_DEFAULT            ONIG_OPTION_NONE

/* options */
#define ONIG_OPTION_NONE                 0U
#define ONIG_OPTION_IGNORECASE           1U
#define ONIG_OPTION_EXTEND               (ONIG_OPTION_IGNORECASE         << 1)
#define ONIG_OPTION_MULTILINE            (ONIG_OPTION_EXTEND             << 1)
#define ONIG_OPTION_SINGLELINE           (ONIG_OPTION_MULTILINE          << 1)
#define ONIG_OPTION_FIND_LONGEST         (ONIG_OPTION_SINGLELINE         << 1)
#define ONIG_OPTION_FIND_NOT_EMPTY       (ONIG_OPTION_FIND_LONGEST       << 1)
#define ONIG_OPTION_NEGATE_SINGLELINE    (ONIG_OPTION_FIND_NOT_EMPTY     << 1)
#define ONIG_OPTION_DONT_CAPTURE_GROUP   (ONIG_OPTION_NEGATE_SINGLELINE  << 1)
#define ONIG_OPTION_CAPTURE_GROUP        (ONIG_OPTION_DONT_CAPTURE_GROUP << 1)
/* options (search time) */
#define ONIG_OPTION_NOTBOL               (ONIG_OPTION_CAPTURE_GROUP << 1)
#define ONIG_OPTION_NOTEOL               (ONIG_OPTION_NOTBOL << 1)
#define ONIG_OPTION_POSIX_REGION         (ONIG_OPTION_NOTEOL << 1)
#define ONIG_OPTION_MAXBIT               ONIG_OPTION_POSIX_REGION  /* limit */

#define ONIG_OPTION_ON(options,regopt)      ((options) |= (regopt))
#define ONIG_OPTION_OFF(options,regopt)     ((options) &= ~(regopt))
#define ONIG_IS_OPTION_ON(options,option)   ((options) & (option))

/* syntax */
typedef struct {
  unsigned int  op;
  unsigned int  op2;
  unsigned int  behavior;
  OnigOptionType options;    /* default option */
} OnigSyntaxType;

ONIG_EXTERN OnigSyntaxType OnigSyntaxASIS;
ONIG_EXTERN OnigSyntaxType OnigSyntaxPosixBasic;
ONIG_EXTERN OnigSyntaxType OnigSyntaxPosixExtended;
ONIG_EXTERN OnigSyntaxType OnigSyntaxEmacs;
ONIG_EXTERN OnigSyntaxType OnigSyntaxGrep;
ONIG_EXTERN OnigSyntaxType OnigSyntaxGnuRegex;
ONIG_EXTERN OnigSyntaxType OnigSyntaxJava;
ONIG_EXTERN OnigSyntaxType OnigSyntaxPerl;
ONIG_EXTERN OnigSyntaxType OnigSyntaxPerl_NG;
ONIG_EXTERN OnigSyntaxType OnigSyntaxRuby;

/* predefined syntaxes (see regsyntax.c) */
#define ONIG_SYNTAX_ASIS               (&OnigSyntaxASIS)
#define ONIG_SYNTAX_POSIX_BASIC        (&OnigSyntaxPosixBasic)
#define ONIG_SYNTAX_POSIX_EXTENDED     (&OnigSyntaxPosixExtended)
#define ONIG_SYNTAX_EMACS              (&OnigSyntaxEmacs)
#define ONIG_SYNTAX_GREP               (&OnigSyntaxGrep)
#define ONIG_SYNTAX_GNU_REGEX          (&OnigSyntaxGnuRegex)
#define ONIG_SYNTAX_JAVA               (&OnigSyntaxJava)
#define ONIG_SYNTAX_PERL               (&OnigSyntaxPerl)
#define ONIG_SYNTAX_PERL_NG            (&OnigSyntaxPerl_NG)
#define ONIG_SYNTAX_RUBY               (&OnigSyntaxRuby)

/* default syntax */
ONIG_EXTERN OnigSyntaxType*   OnigDefaultSyntax;
#define ONIG_SYNTAX_DEFAULT   OnigDefaultSyntax

/* syntax (operators) */
#define ONIG_SYN_OP_VARIABLE_META_CHARACTERS    (1U<<0)
#define ONIG_SYN_OP_DOT_ANYCHAR                 (1U<<1)   /* . */
#define ONIG_SYN_OP_ASTERISK_ZERO_INF           (1U<<2)   /* * */
#define ONIG_SYN_OP_ESC_ASTERISK_ZERO_INF       (1U<<3)
#define ONIG_SYN_OP_PLUS_ONE_INF                (1U<<4)   /* + */
#define ONIG_SYN_OP_ESC_PLUS_ONE_INF            (1U<<5)
#define ONIG_SYN_OP_QMARK_ZERO_ONE              (1U<<6)   /* ? */
#define ONIG_SYN_OP_ESC_QMARK_ZERO_ONE          (1U<<7)
#define ONIG_SYN_OP_BRACE_INTERVAL              (1U<<8)   /* {lower,upper} */
#define ONIG_SYN_OP_ESC_BRACE_INTERVAL          (1U<<9)   /* \{lower,upper\} */
#define ONIG_SYN_OP_VBAR_ALT                    (1U<<10)   /* | */
#define ONIG_SYN_OP_ESC_VBAR_ALT                (1U<<11)  /* \| */
#define ONIG_SYN_OP_LPAREN_SUBEXP               (1U<<12)  /* (...)   */
#define ONIG_SYN_OP_ESC_LPAREN_SUBEXP           (1U<<13)  /* \(...\) */
#define ONIG_SYN_OP_ESC_AZ_BUF_ANCHOR           (1U<<14)  /* \A, \Z, \z */
#define ONIG_SYN_OP_ESC_CAPITAL_G_BEGIN_ANCHOR  (1U<<15)  /* \G     */
#define ONIG_SYN_OP_DECIMAL_BACKREF             (1U<<16)  /* \num   */
#define ONIG_SYN_OP_BRACKET_CC                  (1U<<17)  /* [...]  */
#define ONIG_SYN_OP_ESC_W_WORD                  (1U<<18)  /* \w, \W */
#define ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END     (1U<<19)  /* \<. \> */
#define ONIG_SYN_OP_ESC_B_WORD_BOUND            (1U<<20)  /* \b, \B */
#define ONIG_SYN_OP_ESC_S_WHITE_SPACE           (1U<<21)  /* \s, \S */
#define ONIG_SYN_OP_ESC_D_DIGIT                 (1U<<22)  /* \d, \D */
#define ONIG_SYN_OP_LINE_ANCHOR                 (1U<<23)  /* ^, $   */
#define ONIG_SYN_OP_POSIX_BRACKET               (1U<<24)  /* [:xxxx:] */
#define ONIG_SYN_OP_QMARK_NON_GREEDY            (1U<<25)  /* ??,*?,+?,{n,m}? */
#define ONIG_SYN_OP_ESC_CONTROL_CHARS           (1U<<26)  /* \n,\r,\t,\a ... */
#define ONIG_SYN_OP_ESC_C_CONTROL               (1U<<27)  /* \cx  */
#define ONIG_SYN_OP_ESC_OCTAL3                  (1U<<28)  /* \OOO */
#define ONIG_SYN_OP_ESC_X_HEX2                  (1U<<29)  /* \xHH */
#define ONIG_SYN_OP_ESC_X_BRACE_HEX8            (1U<<30)  /* \x{7HHHHHHH} */

#define ONIG_SYN_OP2_ESC_CAPITAL_Q_QUOTE        (1U<<0)  /* \Q...\E */
#define ONIG_SYN_OP2_QMARK_GROUP_EFFECT         (1U<<1)  /* (?...) */
#define ONIG_SYN_OP2_OPTION_PERL                (1U<<2)  /* (?imsx),(?-imsx) */
#define ONIG_SYN_OP2_OPTION_RUBY                (1U<<3)  /* (?imx), (?-imx)  */
#define ONIG_SYN_OP2_PLUS_POSSESSIVE_REPEAT     (1U<<4)  /* ?+,*+,++ */
#define ONIG_SYN_OP2_PLUS_POSSESSIVE_INTERVAL   (1U<<5)  /* {n,m}+   */
#define ONIG_SYN_OP2_CCLASS_SET_OP              (1U<<6)  /* [...&&..[..]..] */
#define ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP       (1U<<7)  /* (?<name>...) */
#define ONIG_SYN_OP2_ESC_K_NAMED_BACKREF        (1U<<8)  /* \k<name> */
#define ONIG_SYN_OP2_ESC_G_SUBEXP_CALL          (1U<<9)  /* \g<name>, \g<n> */
#define ONIG_SYN_OP2_ATMARK_CAPTURE_HISTORY     (1U<<10) /* (?@..),(?@<x>..) */
#define ONIG_SYN_OP2_ESC_CAPITAL_C_BAR_CONTROL  (1U<<11) /* \C-x */
#define ONIG_SYN_OP2_ESC_CAPITAL_M_BAR_META     (1U<<12) /* \M-x */
#define ONIG_SYN_OP2_ESC_V_VTAB                 (1U<<13) /* \v as VTAB */
#define ONIG_SYN_OP2_ESC_U_HEX4                 (1U<<14) /* \uHHHH */
#define ONIG_SYN_OP2_ESC_GNU_BUF_ANCHOR         (1U<<15) /* \`, \' */
#define ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY  (1U<<16) /* \p{...}, \P{...} */
#define ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT (1U<<17) /* \p{^..}, \P{^..} */
#define ONIG_SYN_OP2_CHAR_PROPERTY_PREFIX_IS    (1U<<18) /* \p{IsXDigit} */
#define ONIG_SYN_OP2_ESC_H_XDIGIT               (1U<<19) /* \h, \H */
#define ONIG_SYN_OP2_INEFFECTIVE_ESCAPE         (1U<<20) /* \ */

/* syntax (behavior) */
#define ONIG_SYN_CONTEXT_INDEP_ANCHORS           (1U<<31) /* not implemented */
#define ONIG_SYN_CONTEXT_INDEP_REPEAT_OPS        (1U<<0)  /* ?, *, +, {n,m} */
#define ONIG_SYN_CONTEXT_INVALID_REPEAT_OPS      (1U<<1)  /* error or ignore */
#define ONIG_SYN_ALLOW_UNMATCHED_CLOSE_SUBEXP    (1U<<2)  /* ...)... */
#define ONIG_SYN_ALLOW_INVALID_INTERVAL          (1U<<3)  /* {??? */
#define ONIG_SYN_ALLOW_INTERVAL_LOW_ABBREV       (1U<<4)  /* {,n} => {0,n} */
#define ONIG_SYN_STRICT_CHECK_BACKREF            (1U<<5)  /* /(\1)/,/\1()/ ..*/
#define ONIG_SYN_DIFFERENT_LEN_ALT_LOOK_BEHIND   (1U<<6)  /* (?<=a|bc) */
#define ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP        (1U<<7)  /* see doc/RE */
#define ONIG_SYN_ALLOW_MULTIPLEX_DEFINITION_NAME (1U<<8)  /* (?<x>)(?<x>) */
#define ONIG_SYN_FIXED_INTERVAL_IS_GREEDY_ONLY   (1U<<9)  /* a{n}?=(?:a{n})? */

/* syntax (behavior) in char class [...] */
#define ONIG_SYN_NOT_NEWLINE_IN_NEGATIVE_CC      (1U<<20) /* [^...] */
#define ONIG_SYN_BACKSLASH_ESCAPE_IN_CC          (1U<<21) /* [..\w..] etc.. */
#define ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC         (1U<<22)
#define ONIG_SYN_ALLOW_DOUBLE_RANGE_OP_IN_CC     (1U<<23) /* [0-9-a]=[0-9\-a] */
/* syntax (behavior) warning */
#define ONIG_SYN_WARN_CC_OP_NOT_ESCAPED          (1U<<24) /* [,-,] */
#define ONIG_SYN_WARN_REDUNDANT_NESTED_REPEAT    (1U<<25) /* (?:a*)+ */

/* meta character specifiers (onig_set_meta_char()) */
#define ONIG_META_CHAR_ESCAPE               0
#define ONIG_META_CHAR_ANYCHAR              1
#define ONIG_META_CHAR_ANYTIME              2
#define ONIG_META_CHAR_ZERO_OR_ONE_TIME     3
#define ONIG_META_CHAR_ONE_OR_MORE_TIME     4
#define ONIG_META_CHAR_ANYCHAR_ANYTIME      5

#define ONIG_INEFFECTIVE_META_CHAR          0

/* error codes */
#define ONIG_IS_PATTERN_ERROR(ecode)   ((ecode) <= -100 && (ecode) > -1000)
/* normal return */
#define ONIG_NORMAL                                            0
#define ONIG_MISMATCH                                         -1
#define ONIG_NO_SUPPORT_CONFIG                                -2

/* internal error */
#define ONIGERR_MEMORY                                         -5
#define ONIGERR_TYPE_BUG                                       -6
#define ONIGERR_PARSER_BUG                                    -11
#define ONIGERR_STACK_BUG                                     -12
#define ONIGERR_UNDEFINED_BYTECODE                            -13
#define ONIGERR_UNEXPECTED_BYTECODE                           -14
#define ONIGERR_MATCH_STACK_LIMIT_OVER                        -15
#define ONIGERR_DEFAULT_ENCODING_IS_NOT_SETTED                -21
#define ONIGERR_SPECIFIED_ENCODING_CANT_CONVERT_TO_WIDE_CHAR  -22
/* general error */
#define ONIGERR_INVALID_ARGUMENT                              -30 
/* syntax error */
#define ONIGERR_END_PATTERN_AT_LEFT_BRACE                    -100
#define ONIGERR_END_PATTERN_AT_LEFT_BRACKET                  -101
#define ONIGERR_EMPTY_CHAR_CLASS                             -102
#define ONIGERR_PREMATURE_END_OF_CHAR_CLASS                  -103
#define ONIGERR_END_PATTERN_AT_ESCAPE                        -104
#define ONIGERR_END_PATTERN_AT_META                          -105
#define ONIGERR_END_PATTERN_AT_CONTROL                       -106
#define ONIGERR_META_CODE_SYNTAX                             -108
#define ONIGERR_CONTROL_CODE_SYNTAX                          -109
#define ONIGERR_CHAR_CLASS_VALUE_AT_END_OF_RANGE             -110
#define ONIGERR_CHAR_CLASS_VALUE_AT_START_OF_RANGE           -111
#define ONIGERR_UNMATCHED_RANGE_SPECIFIER_IN_CHAR_CLASS      -112
#define ONIGERR_TARGET_OF_REPEAT_OPERATOR_NOT_SPECIFIED      -113
#define ONIGERR_TARGET_OF_REPEAT_OPERATOR_INVALID            -114
#define ONIGERR_NESTED_REPEAT_OPERATOR                       -115
#define ONIGERR_UNMATCHED_CLOSE_PARENTHESIS                  -116
#define ONIGERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS       -117
#define ONIGERR_END_PATTERN_IN_GROUP                         -118
#define ONIGERR_UNDEFINED_GROUP_OPTION                       -119
#define ONIGERR_INVALID_POSIX_BRACKET_TYPE                   -121
#define ONIGERR_INVALID_LOOK_BEHIND_PATTERN                  -122
#define ONIGERR_INVALID_REPEAT_RANGE_PATTERN                 -123
/* values error (syntax error) */
#define ONIGERR_TOO_BIG_NUMBER                               -200
#define ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE              -201
#define ONIGERR_UPPER_SMALLER_THAN_LOWER_IN_REPEAT_RANGE     -202
#define ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS                    -203
#define ONIGERR_MISMATCH_CODE_LENGTH_IN_CLASS_RANGE          -204
#define ONIGERR_TOO_MANY_MULTI_BYTE_RANGES                   -205
#define ONIGERR_TOO_SHORT_MULTI_BYTE_STRING                  -206
#define ONIGERR_TOO_BIG_BACKREF_NUMBER                       -207
#define ONIGERR_INVALID_BACKREF                              -208
#define ONIGERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED         -209
#define ONIGERR_TOO_LONG_WIDE_CHAR_VALUE                     -212
#define ONIGERR_EMPTY_GROUP_NAME                             -214
#define ONIGERR_INVALID_GROUP_NAME                           -215
#define ONIGERR_INVALID_CHAR_IN_GROUP_NAME                   -216
#define ONIGERR_UNDEFINED_NAME_REFERENCE                     -217
#define ONIGERR_UNDEFINED_GROUP_REFERENCE                    -218
#define ONIGERR_MULTIPLEX_DEFINED_NAME                       -219
#define ONIGERR_MULTIPLEX_DEFINITION_NAME_CALL               -220
#define ONIGERR_NEVER_ENDING_RECURSION                       -221
#define ONIGERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY        -222
#define ONIGERR_INVALID_CHAR_PROPERTY_NAME                   -223
#define ONIGERR_INVALID_WIDE_CHAR_VALUE                      -400
#define ONIGERR_TOO_BIG_WIDE_CHAR_VALUE                      -401
#define ONIGERR_NOT_SUPPORTED_ENCODING_COMBINATION           -402
#define ONIGERR_INVALID_COMBINATION_OF_OPTIONS               -403

/* errors related to thread */
#define ONIGERR_OVER_THREAD_PASS_LIMIT_COUNT                -1001


/* must be smaller than BIT_STATUS_BITS_NUM (unsigned int * 8) */
#define ONIG_MAX_CAPTURE_HISTORY_GROUP   31
#define ONIG_IS_CAPTURE_HISTORY_GROUP(r, i) \
  ((i) <= ONIG_MAX_CAPTURE_HISTORY_GROUP && (r)->list && (r)->list[i])

typedef struct OnigCaptureTreeNodeStruct {
  int group;   /* group number */
  int beg;
  int end;
  int allocated;
  int num_childs;
  struct OnigCaptureTreeNodeStruct** childs;
} OnigCaptureTreeNode;

/* match result region type */
struct re_registers {
  int  allocated;
  int  num_regs;
  int* beg;
  int* end;
  /* extended */
  OnigCaptureTreeNode* history_root;  /* capture history tree root */
};

/* capture tree traverse */
#define ONIG_TRAVERSE_CALLBACK_AT_FIRST   1
#define ONIG_TRAVERSE_CALLBACK_AT_LAST    2
#define ONIG_TRAVERSE_CALLBACK_AT_BOTH \
  ( ONIG_TRAVERSE_CALLBACK_AT_FIRST | ONIG_TRAVERSE_CALLBACK_AT_LAST )


#define ONIG_REGION_NOTPOS            -1

typedef struct re_registers   OnigRegion;

typedef struct {
  OnigUChar* par;
  OnigUChar* par_end;
} OnigErrorInfo;

typedef struct {
  int lower;
  int upper;
} OnigRepeatRange;

typedef void (*OnigWarnFunc) P_((const char* s));
extern void onig_null_warn P_((const char* s));
#define ONIG_NULL_WARN       onig_null_warn

#define ONIG_CHAR_TABLE_SIZE   256

/* regex_t state */
#define ONIG_STATE_NORMAL              0
#define ONIG_STATE_SEARCHING           1
#define ONIG_STATE_COMPILING          -1
#define ONIG_STATE_MODIFY             -2

#define ONIG_STATE(reg) \
  ((reg)->state > 0 ? ONIG_STATE_SEARCHING : (reg)->state)

typedef struct re_pattern_buffer {
  /* common members of BBuf(bytes-buffer) */
  unsigned char* p;         /* compiled pattern */
  unsigned int used;        /* used space for p */
  unsigned int alloc;       /* allocated space for p */

  int state;                     /* normal, searching, compiling */
  int num_mem;                   /* used memory(...) num counted from 1 */
  int num_repeat;                /* OP_REPEAT/OP_REPEAT_NG id-counter */
  int num_null_check;            /* OP_NULL_CHECK_START/END id counter */
  int num_comb_exp_check;        /* combination explosion check */
  int num_call;                  /* number of subexp call */
  unsigned int capture_history;  /* (?@...) flag (1-31) */
  unsigned int bt_mem_start;     /* need backtrack flag */
  unsigned int bt_mem_end;       /* need backtrack flag */
  int stack_pop_level;
  int repeat_range_alloc;
  OnigRepeatRange* repeat_range;

  OnigEncoding  enc;
  OnigOptionType    options;
  OnigSyntaxType*   syntax;
  OnigAmbigType     ambig_flag;
  void*             name_table;

  /* optimization info (string search, char-map and anchors) */
  int            optimize;          /* optimize flag */
  int            threshold_len;     /* search str-length for apply optimize */
  int            anchor;            /* BEGIN_BUF, BEGIN_POS, (SEMI_)END_BUF */
  OnigDistance   anchor_dmin;       /* (SEMI_)END_BUF anchor distance */
  OnigDistance   anchor_dmax;       /* (SEMI_)END_BUF anchor distance */
  int            sub_anchor;        /* start-anchor for exact or map */
  unsigned char *exact;
  unsigned char *exact_end;
  unsigned char  map[ONIG_CHAR_TABLE_SIZE]; /* used as BM skip or char-map */
  int           *int_map;                   /* BM skip for exact_len > 255 */
  int           *int_map_backward;          /* BM skip for backward search */
  OnigDistance   dmin;                      /* min-distance of exact or map */
  OnigDistance   dmax;                      /* max-distance of exact or map */

  /* regex_t link chain */
  struct re_pattern_buffer* chain;  /* escape compile-conflict */
} OnigRegexType;

typedef OnigRegexType*  OnigRegex;

#ifndef ONIG_ESCAPE_REGEX_T_COLLISION
  typedef OnigRegexType  regex_t;
#endif


typedef struct {
  int             num_of_elements;
  OnigEncoding    pattern_enc;
  OnigEncoding    target_enc;
  OnigSyntaxType* syntax;
  OnigOptionType  option;
  OnigAmbigType   ambig_flag;
} OnigCompileInfo;

/* Oniguruma Native API */
ONIG_EXTERN
int onig_init P_((void));
ONIG_EXTERN
int onig_error_code_to_str PV_((OnigUChar* s, int err_code, ...));
ONIG_EXTERN
void onig_set_warn_func P_((OnigWarnFunc f));
ONIG_EXTERN
void onig_set_verb_warn_func P_((OnigWarnFunc f));
ONIG_EXTERN
int onig_new P_((OnigRegex*, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigOptionType option, OnigEncoding enc, OnigSyntaxType* syntax, OnigErrorInfo* einfo));
ONIG_EXTERN
int onig_new_deluxe P_((OnigRegex* reg, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigCompileInfo* ci, OnigErrorInfo* einfo));
ONIG_EXTERN
void onig_free P_((OnigRegex));
ONIG_EXTERN
int onig_recompile P_((OnigRegex, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigOptionType option, OnigEncoding enc, OnigSyntaxType* syntax, OnigErrorInfo* einfo));
ONIG_EXTERN
int onig_recompile_deluxe P_((OnigRegex reg, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigCompileInfo* ci, OnigErrorInfo* einfo));
ONIG_EXTERN
int onig_search P_((OnigRegex, const OnigUChar* str, const OnigUChar* end, const OnigUChar* start, const OnigUChar* range, OnigRegion* region, OnigOptionType option));
ONIG_EXTERN
int onig_match P_((OnigRegex, const OnigUChar* str, const OnigUChar* end, const OnigUChar* at, OnigRegion* region, OnigOptionType option));
ONIG_EXTERN
OnigRegion* onig_region_new P_((void));
ONIG_EXTERN
void onig_region_init P_((OnigRegion* region));
ONIG_EXTERN
void onig_region_free P_((OnigRegion* region, int free_self));
ONIG_EXTERN
void onig_region_copy P_((OnigRegion* to, OnigRegion* from));
ONIG_EXTERN
void onig_region_clear P_((OnigRegion* region));
ONIG_EXTERN
int onig_region_resize P_((OnigRegion* region, int n));
ONIG_EXTERN
int onig_region_set P_((OnigRegion* region, int at, int beg, int end));
ONIG_EXTERN
int onig_name_to_group_numbers P_((OnigRegex reg, const OnigUChar* name, const OnigUChar* name_end, int** nums));
ONIG_EXTERN
int onig_name_to_backref_number P_((OnigRegex reg, const OnigUChar* name, const OnigUChar* name_end, OnigRegion *region));
ONIG_EXTERN
int onig_foreach_name P_((OnigRegex reg, int (*func)(const OnigUChar*, const OnigUChar*,int,int*,OnigRegex,void*), void* arg));
ONIG_EXTERN
int onig_number_of_names P_((OnigRegex reg));
ONIG_EXTERN
int onig_number_of_captures P_((OnigRegex reg));
ONIG_EXTERN
int onig_number_of_capture_histories P_((OnigRegex reg));
ONIG_EXTERN
OnigCaptureTreeNode* onig_get_capture_tree P_((OnigRegion* region));
ONIG_EXTERN
int onig_capture_tree_traverse P_((OnigRegion* region, int at, int(*callback_func)(int,int,int,int,int,void*), void* arg));
ONIG_EXTERN
int onig_noname_group_capture_is_active P_((OnigRegex reg));
ONIG_EXTERN
OnigEncoding onig_get_encoding P_((OnigRegex reg));
ONIG_EXTERN
OnigOptionType onig_get_options P_((OnigRegex reg));
ONIG_EXTERN
OnigAmbigType onig_get_ambig_flag P_((OnigRegex reg));
ONIG_EXTERN
OnigSyntaxType* onig_get_syntax P_((OnigRegex reg));
ONIG_EXTERN
int onig_set_default_syntax P_((OnigSyntaxType* syntax));
ONIG_EXTERN
void onig_copy_syntax P_((OnigSyntaxType* to, OnigSyntaxType* from));
ONIG_EXTERN
unsigned int onig_get_syntax_op P_((OnigSyntaxType* syntax));
ONIG_EXTERN
unsigned int onig_get_syntax_op2 P_((OnigSyntaxType* syntax));
ONIG_EXTERN
unsigned int onig_get_syntax_behavior P_((OnigSyntaxType* syntax));
ONIG_EXTERN
OnigOptionType onig_get_syntax_options P_((OnigSyntaxType* syntax));
ONIG_EXTERN
void onig_set_syntax_op P_((OnigSyntaxType* syntax, unsigned int op));
ONIG_EXTERN
void onig_set_syntax_op2 P_((OnigSyntaxType* syntax, unsigned int op2));
ONIG_EXTERN
void onig_set_syntax_behavior P_((OnigSyntaxType* syntax, unsigned int behavior));
ONIG_EXTERN
void onig_set_syntax_options P_((OnigSyntaxType* syntax, OnigOptionType options));
ONIG_EXTERN
int onig_set_meta_char P_((OnigEncoding enc, unsigned int what, OnigCodePoint code));
ONIG_EXTERN
void onig_copy_encoding P_((OnigEncoding to, OnigEncoding from));
ONIG_EXTERN
OnigAmbigType onig_get_default_ambig_flag P_(());
ONIG_EXTERN
int onig_set_default_ambig_flag P_((OnigAmbigType ambig_flag));
ONIG_EXTERN
unsigned int onig_get_match_stack_limit_size P_((void));
ONIG_EXTERN
int onig_set_match_stack_limit_size P_((unsigned int size));
ONIG_EXTERN
int onig_end P_((void));
ONIG_EXTERN
const char* onig_version P_((void));
ONIG_EXTERN
const char* onig_copyright P_((void));

#ifdef __cplusplus
}
#endif

#endif /* ONIGURUMA_H */
php/ext/mbstring/php_mbregex.h000064400000010541151730540270012436 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Moriyoshi Koizumi <moriyoshi@php.net>                        |
   +----------------------------------------------------------------------+
 */

/* $Id: php_mbregex.h 293036 2010-01-03 09:23:27Z sebastian $ */
 
#ifndef _PHP_MBREGEX_H
#define _PHP_MBREGEX_H

#if HAVE_MBREGEX

#include "php.h"
#include "zend.h"
#include "oniguruma/oniguruma.h"

/* {{{ PHP_MBREGEX_GLOBALS */
#define PHP_MBREGEX_GLOBALS \
	OnigEncoding default_mbctype; \
	OnigEncoding current_mbctype; \
	HashTable ht_rc; \
	zval *search_str; \
	zval *search_str_val; \
	unsigned int search_pos; \
	php_mb_regex_t *search_re; \
	OnigRegion *search_regs; \
	OnigOptionType regex_default_options; \
	OnigSyntaxType *regex_default_syntax;
/* }}} */

/* {{{ PHP_MBREGEX_FUNCTION_ENTRIES */
#define PHP_MBREGEX_FUNCTION_ENTRIES \
	PHP_FE(mb_regex_encoding,	NULL) \
	PHP_FE(mb_regex_set_options,	NULL) \
	PHP_FE(mb_ereg,			third_arg_force_ref) \
	PHP_FE(mb_eregi,			third_arg_force_ref) \
	PHP_FE(mb_ereg_replace,			NULL) \
	PHP_FE(mb_eregi_replace,			NULL) \
	PHP_FE(mb_split,					NULL) \
	PHP_FE(mb_ereg_match,			NULL) \
	PHP_FE(mb_ereg_search,			NULL) \
	PHP_FE(mb_ereg_search_pos,		NULL) \
	PHP_FE(mb_ereg_search_regs,		NULL) \
	PHP_FE(mb_ereg_search_init,		NULL) \
	PHP_FE(mb_ereg_search_getregs,	NULL) \
	PHP_FE(mb_ereg_search_getpos,	NULL) \
	PHP_FE(mb_ereg_search_setpos,	NULL) \
	PHP_FALIAS(mbregex_encoding,	mb_regex_encoding,	NULL) \
	PHP_FALIAS(mbereg,	mb_ereg,	NULL) \
	PHP_FALIAS(mberegi,	mb_eregi,	NULL) \
	PHP_FALIAS(mbereg_replace,	mb_ereg_replace,	NULL) \
	PHP_FALIAS(mberegi_replace,	mb_eregi_replace,	NULL) \
	PHP_FALIAS(mbsplit,	mb_split,	NULL) \
	PHP_FALIAS(mbereg_match,	mb_ereg_match,	NULL) \
	PHP_FALIAS(mbereg_search,	mb_ereg_search,	NULL) \
	PHP_FALIAS(mbereg_search_pos,	mb_ereg_search_pos,	NULL) \
	PHP_FALIAS(mbereg_search_regs,	mb_ereg_search_regs,	NULL) \
	PHP_FALIAS(mbereg_search_init,	mb_ereg_search_init,	NULL) \
	PHP_FALIAS(mbereg_search_getregs,	mb_ereg_search_getregs,	NULL) \
	PHP_FALIAS(mbereg_search_getpos,	mb_ereg_search_getpos,	NULL) \
	PHP_FALIAS(mbereg_search_setpos,	mb_ereg_search_setpos,	NULL)
/* }}} */

typedef struct _zend_mbstring_globals * zend_mbstring_globals_ptr;

#define PHP_MBREGEX_MAXCACHE 50

PHP_MINIT_FUNCTION(mb_regex);
PHP_MSHUTDOWN_FUNCTION(mb_regex);
PHP_RINIT_FUNCTION(mb_regex);
PHP_RSHUTDOWN_FUNCTION(mb_regex);
void _php_mb_regex_globals_ctor(zend_mbstring_globals_ptr pglobals TSRMLS_DC);
void php_mb_regex_set_options(OnigOptionType options, OnigSyntaxType *syntax, OnigOptionType *prev_options, OnigSyntaxType **prev_syntax TSRMLS_DC);
void _php_mb_regex_globals_dtor(zend_mbstring_globals_ptr pglobals TSRMLS_DC);
OnigEncoding php_mb_regex_name2mbctype(const char *pname);
const char *php_mb_regex_mbctype2name(OnigEncoding mbctype);

PHP_FUNCTION(mb_regex_encoding);
PHP_FUNCTION(mb_ereg);
PHP_FUNCTION(mb_eregi);
PHP_FUNCTION(mb_ereg_replace);
PHP_FUNCTION(mb_eregi_replace);
PHP_FUNCTION(mb_split);
PHP_FUNCTION(mb_ereg_match);
PHP_FUNCTION(mb_ereg_search);
PHP_FUNCTION(mb_ereg_search_pos);
PHP_FUNCTION(mb_ereg_search_regs);
PHP_FUNCTION(mb_ereg_search_init);
PHP_FUNCTION(mb_ereg_search_getregs);
PHP_FUNCTION(mb_ereg_search_getpos);
PHP_FUNCTION(mb_ereg_search_setpos);
PHP_FUNCTION(mb_regex_set_options);

#endif /* HAVE_MBREGEX */

#endif /* _PHP_MBREGEX_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */

php/ext/json/php_json.h000064400000003714151730540270011106 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 5                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2010 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: Omar Kilani <omar@php.net>                                   |
  +----------------------------------------------------------------------+
*/

/* $Id: php_json.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_JSON_H
#define PHP_JSON_H

#define PHP_JSON_VERSION "1.2.1"

#include "ext/standard/php_smart_str.h"

extern zend_module_entry json_module_entry;
#define phpext_json_ptr &json_module_entry

#ifdef PHP_WIN32
#define PHP_JSON_API __declspec(dllexport)
#else
#define PHP_JSON_API
#endif

#ifdef ZTS
#include "TSRM.h"
#endif

#ifdef ZTS
#define JSON_G(v) TSRMG(json_globals_id, zend_json_globals *, v)
#else
#define JSON_G(v) (json_globals.v)
#endif

PHP_JSON_API void php_json_encode(smart_str *buf, zval *val TSRMLS_DC);
PHP_JSON_API void php_json_decode(zval *return_value, char *buf, int buf_len, zend_bool assoc TSRMLS_DC);

#endif  /* PHP_JSON_H */


/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/ext/json/php_json_scanner.h000064400000004557151730540270012625 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: Jakub Zelenka <bukka@php.net>                                |
  +----------------------------------------------------------------------+
*/

#ifndef PHP_JSON_SCANNER_H
#define	PHP_JSON_SCANNER_H

#include "php.h"
#include "php_json.h"

typedef unsigned char php_json_ctype;

typedef struct _php_json_scanner {
	php_json_ctype *cursor;         /* cursor position */
	php_json_ctype *token;          /* token position */
	php_json_ctype *limit;          /* the last read character + 1 position */
	php_json_ctype *marker;         /* marker position for backtracking */
	php_json_ctype *ctxmarker;      /* marker position for context backtracking */
	php_json_ctype *str_start;      /* start position of the string */
	php_json_ctype *pstr;           /* string pointer for escapes conversion */
	zval value;                     /* value */
	int str_esc;                    /* number of extra characters for escaping */
	int state;                      /* condition state */
	int options;                    /* options */
	php_json_error_code errcode;    /* error type if there is an error */
	int utf8_invalid;               /* whether utf8 is invalid */
	int utf8_invalid_count;         /* number of extra character for invalid utf8 */
} php_json_scanner;


void php_json_scanner_init(php_json_scanner *scanner, char *str, size_t str_len, int options);
int php_json_scan(php_json_scanner *s);

#endif	/* PHP_JSON_SCANNER_H */
php/ext/json/php_json_parser.h000064400000006252151730540270012462 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: Jakub Zelenka <bukka@php.net>                                |
  +----------------------------------------------------------------------+
*/

#ifndef PHP_JSON_PARSER_H
#define	PHP_JSON_PARSER_H

#include "php.h"
#include "php_json_scanner.h"

typedef struct _php_json_parser php_json_parser;

typedef int (*php_json_parser_func_array_create_t)(
		php_json_parser *parser, zval *array);
typedef int (*php_json_parser_func_array_append_t)(
		php_json_parser *parser, zval *array, zval *zvalue);
typedef int (*php_json_parser_func_array_start_t)(
		php_json_parser *parser);
typedef int (*php_json_parser_func_array_end_t)(
		php_json_parser *parser, zval *object);
typedef int (*php_json_parser_func_object_create_t)(
		php_json_parser *parser, zval *object);
typedef int (*php_json_parser_func_object_update_t)(
		php_json_parser *parser, zval *object, zend_string *key, zval *zvalue);
typedef int (*php_json_parser_func_object_start_t)(
		php_json_parser *parser);
typedef int (*php_json_parser_func_object_end_t)(
		php_json_parser *parser, zval *object);

typedef struct _php_json_parser_methods {
	php_json_parser_func_array_create_t array_create;
	php_json_parser_func_array_append_t array_append;
	php_json_parser_func_array_start_t array_start;
	php_json_parser_func_array_end_t array_end;
	php_json_parser_func_object_create_t object_create;
	php_json_parser_func_object_update_t object_update;
	php_json_parser_func_object_start_t object_start;
	php_json_parser_func_object_end_t object_end;
} php_json_parser_methods;

struct _php_json_parser {
	php_json_scanner scanner;
	zval *return_value;
	int depth;
	int max_depth;
	php_json_parser_methods methods;
};

PHP_JSON_API void php_json_parser_init_ex(
		php_json_parser *parser,
		zval *return_value,
		char *str,
		size_t str_len,
		int options,
		int max_depth,
		const php_json_parser_methods *methods);

PHP_JSON_API void php_json_parser_init(
		php_json_parser *parser,
		zval *return_value,
		char *str,
		size_t str_len,
		int options,
		int max_depth);

PHP_JSON_API php_json_error_code php_json_parser_error_code(const php_json_parser *parser);

PHP_JSON_API int php_json_parse(php_json_parser *parser);

int php_json_yyparse(php_json_parser *parser);

#endif	/* PHP_JSON_PARSER_H */
php/ext/iconv/php_iconv_aliased_libiconv.h000064400000000001151730540270014751 0ustar00
php/ext/iconv/php_have_ibm_iconv.h000064400000000001151730540300013226 0ustar00
php/ext/iconv/php_have_iconv.h000064400000000025151730540300012405 0ustar00#define HAVE_ICONV 1
php/ext/iconv/php_iconv.h000064400000007143151730540300011412 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Rui Hirokawa <rui_hirokawa@ybb.ne.jp>                       |
   |          Stig Bakken <ssb@php.net>                                   |
   +----------------------------------------------------------------------+
 */

/* $Revision: 295968 $ */

#ifndef PHP_ICONV_H
#define PHP_ICONV_H

#ifdef PHP_WIN32
# ifdef PHP_ICONV_EXPORTS
#  define PHP_ICONV_API __declspec(dllexport)
# else
#  define PHP_ICONV_API __declspec(dllimport)
# endif 
#else
# define PHP_ICONV_API
#endif

#ifdef PHP_ATOM_INC
#include "ext/iconv/php_have_iconv.h"
#include "ext/iconv/php_have_libiconv.h"
#include "ext/iconv/php_iconv_aliased_libiconv.h"
#include "ext/iconv/php_have_glibc_iconv.h"
#include "ext/iconv/php_have_bsd_iconv.h"
#include "ext/iconv/php_iconv_supports_errno.h"
#include "ext/iconv/php_php_iconv_impl.h"
#include "ext/iconv/php_php_iconv_h_path.h"
#endif

#ifdef HAVE_ICONV
extern zend_module_entry iconv_module_entry;
#define iconv_module_ptr &iconv_module_entry

PHP_MINIT_FUNCTION(miconv);
PHP_MSHUTDOWN_FUNCTION(miconv);
PHP_MINFO_FUNCTION(miconv);

PHP_NAMED_FUNCTION(php_if_iconv);
PHP_FUNCTION(ob_iconv_handler);
PHP_FUNCTION(iconv_get_encoding);
PHP_FUNCTION(iconv_set_encoding);
PHP_FUNCTION(iconv_strlen);
PHP_FUNCTION(iconv_substr);
PHP_FUNCTION(iconv_strpos);
PHP_FUNCTION(iconv_strrpos);
PHP_FUNCTION(iconv_mime_encode);
PHP_FUNCTION(iconv_mime_decode);
PHP_FUNCTION(iconv_mime_decode_headers);

ZEND_BEGIN_MODULE_GLOBALS(iconv)
	char *input_encoding;
	char *internal_encoding;
	char *output_encoding;
ZEND_END_MODULE_GLOBALS(iconv)

#ifdef ZTS
# define ICONVG(v) TSRMG(iconv_globals_id, zend_iconv_globals *, v)
#else
# define ICONVG(v) (iconv_globals.v)
#endif

#define ICONV_INPUT_ENCODING "ISO-8859-1" 
#define ICONV_OUTPUT_ENCODING "ISO-8859-1"
#define ICONV_INTERNAL_ENCODING "ISO-8859-1" 

#ifndef ICONV_CSNMAXLEN
#define ICONV_CSNMAXLEN 64
#endif

/* {{{ typedef enum php_iconv_err_t */
typedef enum _php_iconv_err_t {
	PHP_ICONV_ERR_SUCCESS           = SUCCESS,
	PHP_ICONV_ERR_CONVERTER         = 1,
	PHP_ICONV_ERR_WRONG_CHARSET     = 2,
	PHP_ICONV_ERR_TOO_BIG           = 3,
	PHP_ICONV_ERR_ILLEGAL_SEQ       = 4,
	PHP_ICONV_ERR_ILLEGAL_CHAR      = 5,
	PHP_ICONV_ERR_UNKNOWN           = 6,
	PHP_ICONV_ERR_MALFORMED         = 7,
	PHP_ICONV_ERR_ALLOC             = 8
} php_iconv_err_t;
/* }}} */

PHP_ICONV_API php_iconv_err_t php_iconv_string(const char * in_p, size_t in_len, char **out, size_t *out_len, const char *out_charset, const char *in_charset);

#else

#define iconv_module_ptr NULL

#endif /* HAVE_ICONV */

#define phpext_iconv_ptr iconv_module_ptr

#endif	/* PHP_ICONV_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 */
php/ext/iconv/php_php_iconv_impl.h000064400000000037151730540300013275 0ustar00#define PHP_ICONV_IMPL "glibc"
php/ext/iconv/php_have_libiconv.h000064400000000001151730540310013067 0ustar00
php/ext/iconv/php_php_iconv_h_path.h000064400000000060151730540310013574 0ustar00#define PHP_ICONV_H_PATH </usr/include/iconv.h>
php/ext/iconv/php_iconv_supports_errno.h000064400000000037151730540310014572 0ustar00#define ICONV_SUPPORTS_ERRNO 1
php/ext/iconv/php_iconv_broken_ignore.h000064400000000036151730540310014310 0ustar00#define ICONV_BROKEN_IGNORE 1
php/ext/iconv/php_have_glibc_iconv.h000064400000000033151730540310013545 0ustar00#define HAVE_GLIBC_ICONV 1
php/ext/iconv/php_have_bsd_iconv.h000064400000000001151730540310013230 0ustar00
php/ext/spl/spl_exceptions.h000064400000004335151730540320012146 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Marcus Boerger <helly@php.net>                              |
   +----------------------------------------------------------------------+
 */

/* $Id: spl_exceptions.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef SPL_EXCEPTIONS_H
#define SPL_EXCEPTIONS_H

#include "php.h"
#include "php_spl.h"

extern PHPAPI zend_class_entry *spl_ce_LogicException;
extern PHPAPI zend_class_entry *spl_ce_BadFunctionCallException;
extern PHPAPI zend_class_entry *spl_ce_BadMethodCallException;
extern PHPAPI zend_class_entry *spl_ce_DomainException;
extern PHPAPI zend_class_entry *spl_ce_InvalidArgumentException;
extern PHPAPI zend_class_entry *spl_ce_LengthException;
extern PHPAPI zend_class_entry *spl_ce_OutOfRangeException;

extern PHPAPI zend_class_entry *spl_ce_RuntimeException;
extern PHPAPI zend_class_entry *spl_ce_OutOfBoundsException;
extern PHPAPI zend_class_entry *spl_ce_OverflowException;
extern PHPAPI zend_class_entry *spl_ce_RangeException;
extern PHPAPI zend_class_entry *spl_ce_UnderflowException;
extern PHPAPI zend_class_entry *spl_ce_UnexpectedValueException;

PHP_MINIT_FUNCTION(spl_exceptions);

#endif /* SPL_EXCEPTIONS_H */

/*
 * Local Variables:
 * c-basic-offset: 4
 * tab-width: 4
 * End:
 * vim600: fdm=marker
 * vim: noet sw=4 ts=4
 */
php/ext/spl/spl_engine.h000064400000005112151730540320011224 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Marcus Boerger <helly@php.net>                              |
   +----------------------------------------------------------------------+
 */

/* $Id: spl_engine.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef SPL_ENGINE_H
#define SPL_ENGINE_H

#include "php.h"
#include "php_spl.h"
#include "zend_interfaces.h"

/* {{{ zend_class_entry */
static inline zend_class_entry *spl_get_class_entry(zval *obj TSRMLS_DC)
{
	if (obj && Z_TYPE_P(obj) == IS_OBJECT && Z_OBJ_HT_P(obj)->get_class_entry) {
		return Z_OBJ_HT_P(obj)->get_class_entry(obj TSRMLS_CC);
	} else {
		return NULL;
	}
}
/* }}} */

PHPAPI void spl_instantiate(zend_class_entry *pce, zval **object, int alloc TSRMLS_DC);

/* {{{ spl_instantiate_arg_ex1 */
static inline int spl_instantiate_arg_ex1(zend_class_entry *pce, zval **retval, int alloc, zval *arg1 TSRMLS_DC)
{
	spl_instantiate(pce, retval, alloc TSRMLS_CC);
	
	zend_call_method(retval, pce, &pce->constructor, pce->constructor->common.function_name, strlen(pce->constructor->common.function_name), NULL, 1, arg1, NULL TSRMLS_CC);
	return 0;
}
/* }}} */

/* {{{ spl_instantiate_arg_ex2 */
static inline int spl_instantiate_arg_ex2(zend_class_entry *pce, zval **retval, int alloc, zval *arg1, zval *arg2 TSRMLS_DC)
{
	spl_instantiate(pce, retval, alloc TSRMLS_CC);
	
	zend_call_method(retval, pce, &pce->constructor, pce->constructor->common.function_name, strlen(pce->constructor->common.function_name), NULL, 2, arg1, arg2 TSRMLS_CC);
	return 0;
}
/* }}} */

#endif /* SPL_ENGINE_H */

/*
 * Local Variables:
 * c-basic-offset: 4
 * tab-width: 4
 * End:
 * vim600: fdm=marker
 * vim: noet sw=4 ts=4
 */
php/ext/spl/spl_array.h000064400000003444151730540320011103 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Marcus Boerger <helly@php.net>                              |
   +----------------------------------------------------------------------+
 */

/* $Id: spl_array.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef SPL_ARRAY_H
#define SPL_ARRAY_H

#include "php.h"
#include "php_spl.h"
#include "spl_iterators.h"

extern PHPAPI zend_class_entry *spl_ce_ArrayObject;
extern PHPAPI zend_class_entry *spl_ce_ArrayIterator;
extern PHPAPI zend_class_entry *spl_ce_RecursiveArrayIterator;

PHP_MINIT_FUNCTION(spl_array);

extern void spl_array_iterator_append(zval *object, zval *append_value TSRMLS_DC);
extern void spl_array_iterator_key(zval *object, zval *return_value TSRMLS_DC);

#endif /* SPL_ARRAY_H */

/*
 * Local Variables:
 * c-basic-offset: 4
 * tab-width: 4
 * End:
 * vim600: fdm=marker
 * vim: noet sw=4 ts=4
 */
php/ext/spl/spl_functions.h000064400000011506151730540330011774 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Marcus Boerger <helly@php.net>                              |
   +----------------------------------------------------------------------+
 */

/* $Id: spl_functions.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_FUNCTIONS_H
#define PHP_FUNCTIONS_H

#include "php.h"

typedef zend_object_value (*create_object_func_t)(zend_class_entry *class_type TSRMLS_DC);

#define REGISTER_SPL_STD_CLASS(class_name, obj_ctor) \
	spl_register_std_class(&spl_ce_ ## class_name, # class_name, obj_ctor, NULL TSRMLS_CC);

#define REGISTER_SPL_STD_CLASS_EX(class_name, obj_ctor, funcs) \
	spl_register_std_class(&spl_ce_ ## class_name, # class_name, obj_ctor, funcs TSRMLS_CC);

#define REGISTER_SPL_SUB_CLASS_EX(class_name, parent_class_name, obj_ctor, funcs) \
	spl_register_sub_class(&spl_ce_ ## class_name, spl_ce_ ## parent_class_name, # class_name, obj_ctor, funcs TSRMLS_CC);

#define REGISTER_SPL_INTERFACE(class_name) \
	spl_register_interface(&spl_ce_ ## class_name, # class_name, spl_funcs_ ## class_name TSRMLS_CC);

#define REGISTER_SPL_PARENT_CE(class_name, parent_class) \
	spl_register_parent_ce(spl_ce_ ## class_name, spl_ce_ ## parent_class TSRMLS_CC);

#define REGISTER_SPL_IMPLEMENTS(class_name, interface_name) \
	zend_class_implements(spl_ce_ ## class_name TSRMLS_CC, 1, spl_ce_ ## interface_name);

#define REGISTER_SPL_ITERATOR(class_name) \
	zend_class_implements(spl_ce_ ## class_name TSRMLS_CC, 1, zend_ce_iterator);

#define REGISTER_SPL_FUNCTIONS(class_name, function_list) \
	spl_register_functions(spl_ce_ ## class_name, function_list TSRMLS_CC);

#define REGISTER_SPL_PROPERTY(class_name, prop_name, prop_flags) \
	spl_register_property(spl_ce_ ## class_name, prop_name, sizeof(prop_name)-1, prop_flags TSRMLS_CC);

#define REGISTER_SPL_CLASS_CONST_LONG(class_name, const_name, value) \
	zend_declare_class_constant_long(spl_ce_ ## class_name, const_name, sizeof(const_name)-1, (long)value TSRMLS_CC);

void spl_destroy_class(zend_class_entry ** ppce);

void spl_register_std_class(zend_class_entry ** ppce, char * class_name, create_object_func_t ctor, zend_function_entry * function_list TSRMLS_DC);
void spl_register_sub_class(zend_class_entry ** ppce, zend_class_entry * parent_ce, char * class_name, create_object_func_t ctor, zend_function_entry * function_list TSRMLS_DC);

void spl_register_interface(zend_class_entry ** ppce, char * class_name, zend_function_entry *functions TSRMLS_DC);

void spl_register_parent_ce(zend_class_entry * class_entry, zend_class_entry * parent_class TSRMLS_DC);
void spl_register_functions(zend_class_entry * class_entry, zend_function_entry * function_list TSRMLS_DC);
void spl_register_property( zend_class_entry * class_entry, char *prop_name, int prop_name_len, int prop_flags TSRMLS_DC);

/* sub: whether to allow subclasses/interfaces
   allow = 0: allow all classes and interfaces
   allow > 0: allow all that match and mask ce_flags
   allow < 0: disallow all that match and mask ce_flags
 */
void spl_add_class_name(zval * list, zend_class_entry * pce, int allow, int ce_flags TSRMLS_DC);
void spl_add_interfaces(zval * list, zend_class_entry * pce, int allow, int ce_flags TSRMLS_DC);
int spl_add_classes(zend_class_entry ** ppce, zval *list, int sub, int allow, int ce_flags TSRMLS_DC);

#define SPL_ME(class_name, function_name, arg_info, flags) \
	PHP_ME( spl_ ## class_name, function_name, arg_info, flags)
	
#define SPL_ABSTRACT_ME(class_name, function_name, arg_info) \
	ZEND_ABSTRACT_ME( spl_ ## class_name, function_name, arg_info)

#define SPL_METHOD(class_name, function_name) \
	PHP_METHOD(spl_ ## class_name, function_name)

#define SPL_MA(class_name, function_name, alias_class, alias_function, arg_info, flags) \
	PHP_MALIAS(spl_ ## alias_class, function_name, alias_function, arg_info, flags)
#endif /* PHP_FUNCTIONS_H */

/*
 * Local Variables:
 * c-basic-offset: 4
 * tab-width: 4
 * End:
 * vim600: fdm=marker
 * vim: noet sw=4 ts=4
 */
php/ext/spl/spl_directory.h000064400000011203151730540330011762 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Marcus Boerger <helly@php.net>                              |
   +----------------------------------------------------------------------+
 */

/* $Id: spl_directory.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef SPL_DIRECTORY_H
#define SPL_DIRECTORY_H

#include "php.h"
#include "php_spl.h"

extern PHPAPI zend_class_entry *spl_ce_SplFileInfo;
extern PHPAPI zend_class_entry *spl_ce_DirectoryIterator;
extern PHPAPI zend_class_entry *spl_ce_RecursiveDirectoryIterator;
extern PHPAPI zend_class_entry *spl_ce_SplFileObject;
extern PHPAPI zend_class_entry *spl_ce_SplTempFileObject;

PHP_MINIT_FUNCTION(spl_directory);

typedef enum {
	SPL_FS_INFO, /* must be 0 */
	SPL_FS_DIR,
	SPL_FS_FILE
} SPL_FS_OBJ_TYPE;

typedef struct _spl_filesystem_object  spl_filesystem_object;

typedef void (*spl_foreign_dtor_t)(spl_filesystem_object *object TSRMLS_DC);
typedef void (*spl_foreign_clone_t)(spl_filesystem_object *src, spl_filesystem_object *dst TSRMLS_DC);

typedef struct _spl_other_handler {
	spl_foreign_dtor_t     dtor;
	spl_foreign_clone_t    clone;
} spl_other_handler;

struct _spl_filesystem_object {
	zend_object        std;
	void               *oth;
	spl_other_handler  *oth_handler;
	char               *path;
	int                path_len;
	char               *file_name;
	int                file_name_len;
	SPL_FS_OBJ_TYPE    type;
	long               flags;
	zend_class_entry   *file_class;
	zend_class_entry   *info_class;
	union {
		struct {
			php_stream         *dirp;
			php_stream_dirent  entry;
			char               *sub_path;
			int                sub_path_len;
			int                index;
			int                is_recursive;
		} dir;
		struct {
			php_stream         *stream;
			php_stream_context *context;
			zval               *zcontext;
			char               *open_mode;
			int                open_mode_len;
			zval               *current_zval;
			char               *current_line;
			size_t             current_line_len;
			size_t             max_line_len;
			long               current_line_num;
			zval               zresource;
			zend_function      *func_getCurr;
			char               delimiter;
			char               enclosure;
		} file;
	} u;
};

#define SPL_FILE_OBJECT_DROP_NEW_LINE      0x00000001 /* drop new lines */
#define SPL_FILE_OBJECT_READ_AHEAD         0x00000002 /* read on rewind/next */
#define SPL_FILE_OBJECT_SKIP_EMPTY         0x00000006 /* skip empty lines */
#define SPL_FILE_OBJECT_READ_CSV           0x00000008 /* read via fgetcsv */

#define SPL_FILE_DIR_CURRENT_AS_FILEINFO   0x00000000 /* make RecursiveDirectoryTree::current() return SplFileInfo */
#define SPL_FILE_DIR_CURRENT_AS_SELF       0x00000010 /* make RecursiveDirectoryTree::current() return getSelf() */
#define SPL_FILE_DIR_CURRENT_AS_PATHNAME   0x00000020 /* make RecursiveDirectoryTree::current() return getPathname() */
#define SPL_FILE_DIR_CURRENT_MODE_MASK     0x000000F0 /* mask RecursiveDirectoryTree::current() */
#define SPL_FILE_DIR_CURRENT(intern,mode)  ((intern->flags&SPL_FILE_DIR_CURRENT_MODE_MASK)==mode)

#define SPL_FILE_DIR_KEY_AS_PATHNAME       0x00000000 /* make RecursiveDirectoryTree::key() return getPathname() */
#define SPL_FILE_DIR_KEY_AS_FILENAME       0x00000100 /* make RecursiveDirectoryTree::key() return getFilename() */
#define SPL_FILE_DIR_FOLLOW_SYMLINKS       0x00000200 /* make RecursiveDirectoryTree::hasChildren() follow symlinks */
#define SPL_FILE_DIR_KEY_MODE_MASK         0x00000F00 /* mask RecursiveDirectoryTree::key() */
#define SPL_FILE_DIR_KEY(intern,mode)      ((intern->flags&SPL_FILE_DIR_KEY_MODE_MASK)==mode)

#endif /* SPL_DIRECTORY_H */

/*
 * Local Variables:
 * c-basic-offset: 4
 * tab-width: 4
 * End:
 * vim600: fdm=marker
 * vim: noet sw=4 ts=4
 */
php/ext/spl/spl_iterators.h000064400000012311151730540330011773 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Marcus Boerger <helly@php.net>                              |
   +----------------------------------------------------------------------+
 */

/* $Id: spl_iterators.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef SPL_ITERATORS_H
#define SPL_ITERATORS_H

#include "php.h"
#include "php_spl.h"
#if HAVE_PCRE || HAVE_BUNDLED_PCRE
#include "ext/pcre/php_pcre.h"
#endif

#define spl_ce_Traversable   zend_ce_traversable
#define spl_ce_Iterator      zend_ce_iterator
#define spl_ce_Aggregate     zend_ce_aggregate
#define spl_ce_ArrayAccess   zend_ce_arrayaccess
#define spl_ce_Serializable  zend_ce_serializable

extern PHPAPI zend_class_entry *spl_ce_RecursiveIterator;
extern PHPAPI zend_class_entry *spl_ce_RecursiveIteratorIterator;
extern PHPAPI zend_class_entry *spl_ce_FilterIterator;
extern PHPAPI zend_class_entry *spl_ce_RecursiveFilterIterator;
extern PHPAPI zend_class_entry *spl_ce_ParentIterator;
extern PHPAPI zend_class_entry *spl_ce_SeekableIterator;
extern PHPAPI zend_class_entry *spl_ce_LimitIterator;
extern PHPAPI zend_class_entry *spl_ce_CachingIterator;
extern PHPAPI zend_class_entry *spl_ce_RecursiveCachingIterator;
extern PHPAPI zend_class_entry *spl_ce_OuterIterator;
extern PHPAPI zend_class_entry *spl_ce_IteratorIterator;
extern PHPAPI zend_class_entry *spl_ce_NoRewindIterator;
extern PHPAPI zend_class_entry *spl_ce_InfiniteIterator;
extern PHPAPI zend_class_entry *spl_ce_EmptyIterator;
extern PHPAPI zend_class_entry *spl_ce_AppendIterator;
extern PHPAPI zend_class_entry *spl_ce_RegexIterator;
extern PHPAPI zend_class_entry *spl_ce_RecursiveRegexIterator;
extern PHPAPI zend_class_entry *spl_ce_Countable;

PHP_MINIT_FUNCTION(spl_iterators);

PHP_FUNCTION(iterator_to_array);
PHP_FUNCTION(iterator_count);
PHP_FUNCTION(iterator_apply);

typedef enum {
	DIT_Default = 0,
	DIT_FilterIterator = DIT_Default,
	DIT_RecursiveFilterIterator = DIT_Default,
	DIT_ParentIterator = DIT_Default,
	DIT_LimitIterator,
	DIT_CachingIterator,
	DIT_RecursiveCachingIterator,
	DIT_IteratorIterator,
	DIT_NoRewindIterator,
	DIT_InfiniteIterator,
	DIT_AppendIterator,
#if HAVE_PCRE || HAVE_BUNDLED_PCRE
	DIT_RegexIterator,
	DIT_RecursiveRegexIterator,
#endif
	DIT_Unknown = ~0
} dual_it_type;

enum {
	/* public */
	CIT_CALL_TOSTRING        = 0x00000001,
	CIT_TOSTRING_USE_KEY     = 0x00000002,
	CIT_TOSTRING_USE_CURRENT = 0x00000004,
	CIT_TOSTRING_USE_INNER   = 0x00000008,
	CIT_CATCH_GET_CHILD      = 0x00000010,
	CIT_FULL_CACHE           = 0x00000100,
	CIT_PUBLIC               = 0x0000FFFF,
	/* private */
	CIT_VALID                = 0x00010000,
	CIT_HAS_CHILDREN         = 0x00020000
};

enum {
	/* public */
	REGIT_USE_KEY            = 0x00000001,
	REGIT_INVERTED           = 0x00000002
};

typedef enum {
	REGIT_MODE_MATCH,
	REGIT_MODE_GET_MATCH,
	REGIT_MODE_ALL_MATCHES,
	REGIT_MODE_SPLIT,
	REGIT_MODE_REPLACE,
	REGIT_MODE_MAX
} regex_mode;

typedef struct _spl_dual_it_object {
	zend_object              std;
	struct {
		zval                 *zobject;
		zend_class_entry     *ce;
		zend_object          *object;
		zend_object_iterator *iterator;
	} inner;
	struct {
		zval                 *data;
		char                 *str_key;
		uint                 str_key_len;
		ulong                int_key;
		int                  key_type; /* HASH_KEY_IS_STRING or HASH_KEY_IS_LONG */
		int                  pos;
	} current;
	dual_it_type             dit_type;
	union {
		struct {
			long             offset;
			long             count;
		} limit;
		struct {
			long             flags; /* CIT_* */
			zval             *zstr;
			zval             *zchildren;
			zval             *zcache;
		} caching;
		struct {
			zval                 *zarrayit;
			zend_object_iterator *iterator;
		} append;
#if HAVE_PCRE || HAVE_BUNDLED_PCRE
		struct {
			int              use_flags;
			long             flags;
			regex_mode       mode;
			long             preg_flags;
			pcre_cache_entry *pce;
			char             *regex;
		} regex;
#endif
	} u;
} spl_dual_it_object;

typedef int (*spl_iterator_apply_func_t)(zend_object_iterator *iter, void *puser TSRMLS_DC);

PHPAPI int spl_iterator_apply(zval *obj, spl_iterator_apply_func_t apply_func, void *puser TSRMLS_DC);

#endif /* SPL_ITERATORS_H */

/*
 * Local Variables:
 * c-basic-offset: 4
 * tab-width: 4
 * End:
 * vim600: fdm=marker
 * vim: noet sw=4 ts=4
 */
php/ext/spl/php_spl.h000064400000004623151730540340010556 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Marcus Boerger <helly@php.net>                              |
   +----------------------------------------------------------------------+
 */

#ifndef PHP_SPL_H
#define PHP_SPL_H

#include "php.h"
#include <stdarg.h>

#if 0
#define SPL_DEBUG(x)	x
#else
#define SPL_DEBUG(x)
#endif

extern zend_module_entry spl_module_entry;
#define phpext_spl_ptr &spl_module_entry

#ifdef PHP_WIN32
# ifdef SPL_EXPORTS
#  define SPL_API __declspec(dllexport)
# elif defined(COMPILE_DL_SPL)
#  define SPL_API __declspec(dllimport)
# else
#  define SPL_API /* nothing */
# endif
#else
# define SPL_API
#endif

#if defined(PHP_WIN32) && !defined(COMPILE_DL_SPL)
#undef phpext_spl
#define phpext_spl NULL
#endif

PHP_MINIT_FUNCTION(spl);
PHP_MSHUTDOWN_FUNCTION(spl);
PHP_RINIT_FUNCTION(spl);
PHP_RSHUTDOWN_FUNCTION(spl);
PHP_MINFO_FUNCTION(spl);


ZEND_BEGIN_MODULE_GLOBALS(spl)
	char *       autoload_extensions;
	HashTable *  autoload_functions;
	int          autoload_running;
	int          autoload_extensions_len;
ZEND_END_MODULE_GLOBALS(spl)

#ifdef ZTS
# define SPL_G(v) TSRMG(spl_globals_id, zend_spl_globals *, v)
extern int spl_globals_id;
#else
# define SPL_G(v) (spl_globals.v)
extern zend_spl_globals spl_globals;
#endif

PHP_FUNCTION(spl_classes);
PHP_FUNCTION(class_parents);
PHP_FUNCTION(class_implements);

#endif /* PHP_SPL_H */

/*
 * Local Variables:
 * c-basic-offset: 4
 * tab-width: 4
 * End:
 * vim600: fdm=marker
 * vim: noet sw=4 ts=4
 */
php/ext/spl/spl_dllist.h000064400000003052151730540340011255 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 7                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2018 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Etienne Kneuss <colder@php.net>                             |
   +----------------------------------------------------------------------+
 */

/* $Id$ */

#ifndef SPL_DLLIST_H
#define SPL_DLLIST_H

#include "php.h"
#include "php_spl.h"

extern PHPAPI zend_class_entry *spl_ce_SplDoublyLinkedList;
extern PHPAPI zend_class_entry *spl_ce_SplQueue;
extern PHPAPI zend_class_entry *spl_ce_SplStack;

PHP_MINIT_FUNCTION(spl_dllist);

#endif /* SPL_DLLIST_H */

/*
 * Local Variables:
 * c-basic-offset: 4
 * tab-width: 4
 * End:
 * vim600: fdm=marker
 * vim: noet sw=4 ts=4
 */
php/ext/spl/spl_observer.h000064400000003153151730540340011613 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Marcus Boerger <helly@php.net>                              |
   +----------------------------------------------------------------------+
 */

/* $Id: spl_observer.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef SPL_OBSERVER_H
#define SPL_OBSERVER_H

#include "php.h"
#include "php_spl.h"

extern PHPAPI zend_class_entry *spl_ce_SplObserver;
extern PHPAPI zend_class_entry *spl_ce_SplSubject;
extern PHPAPI zend_class_entry *spl_ce_SplObjectStorage;

PHP_MINIT_FUNCTION(spl_observer);

#endif /* SPL_OBSERVER_H */

/*
 * Local Variables:
 * c-basic-offset: 4
 * tab-width: 4
 * End:
 * vim600: fdm=marker
 * vim: noet sw=4 ts=4
 */
php/ext/spl/spl_fixedarray.h000064400000002771151730540340012127 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: Antony Dovgal <tony@daylessday.org>                          |
  |         Etienne Kneuss <colder@php.net>                              |
  +----------------------------------------------------------------------+
*/

/* $Id$ */

#ifndef SPL_FIXEDARRAY_H
#define SPL_FIXEDARRAY_H

extern PHPAPI zend_class_entry *spl_ce_SplFixedArray;

PHP_MINIT_FUNCTION(spl_fixedarray);

#endif	/* SPL_FIXEDARRAY_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/ext/spl/spl_heap.h000064400000003124151730540350010700 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 7                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2018 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Etienne Kneuss <colder@php.net>                             |
   +----------------------------------------------------------------------+
 */

/* $Id$ */

#ifndef SPL_HEAP_H
#define SPL_HEAP_H

#include "php.h"
#include "php_spl.h"

extern PHPAPI zend_class_entry *spl_ce_SplHeap;
extern PHPAPI zend_class_entry *spl_ce_SplMinHeap;
extern PHPAPI zend_class_entry *spl_ce_SplMaxHeap;

extern PHPAPI zend_class_entry *spl_ce_SplPriorityQueue;

PHP_MINIT_FUNCTION(spl_heap);

#endif /* SPL_HEAP_H */

/*
 * Local Variables:
 * c-basic-offset: 4
 * tab-width: 4
 * End:
 * vim600: fdm=marker
 * vim: noet sw=4 ts=4
 */
php/ext/pcre/pcrelib/ucp.h000064400000012137151730540350011453 0ustar00/*************************************************
*          Unicode Property Table handler        *
*************************************************/

#ifndef _UCP_H
#define _UCP_H

/* This file contains definitions of the property values that are returned by
the UCD access macros. New values that are added for new releases of Unicode
should always be at the end of each enum, for backwards compatibility.

IMPORTANT: Note also that the specific numeric values of the enums have to be
the same as the values that are generated by the maint/MultiStage2.py script,
where the equivalent property descriptive names are listed in vectors.

ALSO: The specific values of the first two enums are assumed for the table
called catposstab in pcre_compile.c. */

/* These are the general character categories. */

enum {
  ucp_C,     /* Other */
  ucp_L,     /* Letter */
  ucp_M,     /* Mark */
  ucp_N,     /* Number */
  ucp_P,     /* Punctuation */
  ucp_S,     /* Symbol */
  ucp_Z      /* Separator */
};

/* These are the particular character categories. */

enum {
  ucp_Cc,    /* Control */
  ucp_Cf,    /* Format */
  ucp_Cn,    /* Unassigned */
  ucp_Co,    /* Private use */
  ucp_Cs,    /* Surrogate */
  ucp_Ll,    /* Lower case letter */
  ucp_Lm,    /* Modifier letter */
  ucp_Lo,    /* Other letter */
  ucp_Lt,    /* Title case letter */
  ucp_Lu,    /* Upper case letter */
  ucp_Mc,    /* Spacing mark */
  ucp_Me,    /* Enclosing mark */
  ucp_Mn,    /* Non-spacing mark */
  ucp_Nd,    /* Decimal number */
  ucp_Nl,    /* Letter number */
  ucp_No,    /* Other number */
  ucp_Pc,    /* Connector punctuation */
  ucp_Pd,    /* Dash punctuation */
  ucp_Pe,    /* Close punctuation */
  ucp_Pf,    /* Final punctuation */
  ucp_Pi,    /* Initial punctuation */
  ucp_Po,    /* Other punctuation */
  ucp_Ps,    /* Open punctuation */
  ucp_Sc,    /* Currency symbol */
  ucp_Sk,    /* Modifier symbol */
  ucp_Sm,    /* Mathematical symbol */
  ucp_So,    /* Other symbol */
  ucp_Zl,    /* Line separator */
  ucp_Zp,    /* Paragraph separator */
  ucp_Zs     /* Space separator */
};

/* These are grapheme break properties. Note that the code for processing them
assumes that the values are less than 16. If more values are added that take
the number to 16 or more, the code will have to be rewritten. */

enum {
  ucp_gbCR,                /*  0 */
  ucp_gbLF,                /*  1 */
  ucp_gbControl,           /*  2 */
  ucp_gbExtend,            /*  3 */
  ucp_gbPrepend,           /*  4 */
  ucp_gbSpacingMark,       /*  5 */
  ucp_gbL,                 /*  6 Hangul syllable type L */
  ucp_gbV,                 /*  7 Hangul syllable type V */
  ucp_gbT,                 /*  8 Hangul syllable type T */
  ucp_gbLV,                /*  9 Hangul syllable type LV */
  ucp_gbLVT,               /* 10 Hangul syllable type LVT */
  ucp_gbRegionalIndicator, /* 11 */
  ucp_gbOther              /* 12 */
};

/* These are the script identifications. */

enum {
  ucp_Arabic,
  ucp_Armenian,
  ucp_Bengali,
  ucp_Bopomofo,
  ucp_Braille,
  ucp_Buginese,
  ucp_Buhid,
  ucp_Canadian_Aboriginal,
  ucp_Cherokee,
  ucp_Common,
  ucp_Coptic,
  ucp_Cypriot,
  ucp_Cyrillic,
  ucp_Deseret,
  ucp_Devanagari,
  ucp_Ethiopic,
  ucp_Georgian,
  ucp_Glagolitic,
  ucp_Gothic,
  ucp_Greek,
  ucp_Gujarati,
  ucp_Gurmukhi,
  ucp_Han,
  ucp_Hangul,
  ucp_Hanunoo,
  ucp_Hebrew,
  ucp_Hiragana,
  ucp_Inherited,
  ucp_Kannada,
  ucp_Katakana,
  ucp_Kharoshthi,
  ucp_Khmer,
  ucp_Lao,
  ucp_Latin,
  ucp_Limbu,
  ucp_Linear_B,
  ucp_Malayalam,
  ucp_Mongolian,
  ucp_Myanmar,
  ucp_New_Tai_Lue,
  ucp_Ogham,
  ucp_Old_Italic,
  ucp_Old_Persian,
  ucp_Oriya,
  ucp_Osmanya,
  ucp_Runic,
  ucp_Shavian,
  ucp_Sinhala,
  ucp_Syloti_Nagri,
  ucp_Syriac,
  ucp_Tagalog,
  ucp_Tagbanwa,
  ucp_Tai_Le,
  ucp_Tamil,
  ucp_Telugu,
  ucp_Thaana,
  ucp_Thai,
  ucp_Tibetan,
  ucp_Tifinagh,
  ucp_Ugaritic,
  ucp_Yi,
  /* New for Unicode 5.0: */
  ucp_Balinese,
  ucp_Cuneiform,
  ucp_Nko,
  ucp_Phags_Pa,
  ucp_Phoenician,
  /* New for Unicode 5.1: */
  ucp_Carian,
  ucp_Cham,
  ucp_Kayah_Li,
  ucp_Lepcha,
  ucp_Lycian,
  ucp_Lydian,
  ucp_Ol_Chiki,
  ucp_Rejang,
  ucp_Saurashtra,
  ucp_Sundanese,
  ucp_Vai,
  /* New for Unicode 5.2: */
  ucp_Avestan,
  ucp_Bamum,
  ucp_Egyptian_Hieroglyphs,
  ucp_Imperial_Aramaic,
  ucp_Inscriptional_Pahlavi,
  ucp_Inscriptional_Parthian,
  ucp_Javanese,
  ucp_Kaithi,
  ucp_Lisu,
  ucp_Meetei_Mayek,
  ucp_Old_South_Arabian,
  ucp_Old_Turkic,
  ucp_Samaritan,
  ucp_Tai_Tham,
  ucp_Tai_Viet,
  /* New for Unicode 6.0.0: */
  ucp_Batak,
  ucp_Brahmi,
  ucp_Mandaic,
  /* New for Unicode 6.1.0: */
  ucp_Chakma,
  ucp_Meroitic_Cursive,
  ucp_Meroitic_Hieroglyphs,
  ucp_Miao,
  ucp_Sharada,
  ucp_Sora_Sompeng,
  ucp_Takri,
  /* New for Unicode 7.0.0: */
  ucp_Bassa_Vah,
  ucp_Caucasian_Albanian,
  ucp_Duployan,
  ucp_Elbasan,
  ucp_Grantha,
  ucp_Khojki,
  ucp_Khudawadi,
  ucp_Linear_A,
  ucp_Mahajani,
  ucp_Manichaean,
  ucp_Mende_Kikakui,
  ucp_Modi,
  ucp_Mro,
  ucp_Nabataean,
  ucp_Old_North_Arabian,
  ucp_Old_Permic,
  ucp_Pahawh_Hmong,
  ucp_Palmyrene,
  ucp_Psalter_Pahlavi,
  ucp_Pau_Cin_Hau,
  ucp_Siddham,
  ucp_Tirhuta,
  ucp_Warang_Citi
};

#endif

/* End of ucp.h */
php/ext/pcre/pcrelib/pcre_internal.h000064400000336767151730540360013534 0ustar00/*************************************************
*      Perl-Compatible Regular Expressions       *
*************************************************/


/* 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
           Copyright (c) 1997-2016 University of Cambridge

-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice,
      this list of conditions and the following disclaimer.

    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.

    * Neither the name of the University of Cambridge nor the names of its
      contributors may be used to endorse or promote products derived from
      this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-----------------------------------------------------------------------------
*/

/* This header contains definitions that are shared between the different
modules, but which are not relevant to the exported API. This includes some
functions whose names all begin with "_pcre_", "_pcre16_" or "_pcre32_"
depending on the PRIV macro. */

#ifndef PCRE_INTERNAL_H
#define PCRE_INTERNAL_H

/* Define PCRE_DEBUG to get debugging output on stdout. */

#if 0
#define PCRE_DEBUG
#endif

/* PCRE is compiled as an 8 bit library if it is not requested otherwise. */

#if !defined COMPILE_PCRE16 && !defined COMPILE_PCRE32
#define COMPILE_PCRE8
#endif

/* If SUPPORT_UCP is defined, SUPPORT_UTF must also be defined. The
"configure" script ensures this, but not everybody uses "configure". */

#if defined SUPPORT_UCP && !(defined SUPPORT_UTF)
#define SUPPORT_UTF 1
#endif

/* We define SUPPORT_UTF if SUPPORT_UTF8 is enabled for compatibility
reasons with existing code. */

#if defined SUPPORT_UTF8 && !(defined SUPPORT_UTF)
#define SUPPORT_UTF 1
#endif

/* Fixme: SUPPORT_UTF8 should be eventually disappear from the code.
Until then we define it if SUPPORT_UTF is defined. */

#if defined SUPPORT_UTF && !(defined SUPPORT_UTF8)
#define SUPPORT_UTF8 1
#endif

/* We do not support both EBCDIC and UTF-8/16/32 at the same time. The "configure"
script prevents both being selected, but not everybody uses "configure". */

#if defined EBCDIC && defined SUPPORT_UTF
#error The use of both EBCDIC and SUPPORT_UTF is not supported.
#endif

/* Use a macro for debugging printing, 'cause that eliminates the use of #ifdef
inline, and there are *still* stupid compilers about that don't like indented
pre-processor statements, or at least there were when I first wrote this. After
all, it had only been about 10 years then...

It turns out that the Mac Debugging.h header also defines the macro DPRINTF, so
be absolutely sure we get our version. */

#undef DPRINTF
#ifdef PCRE_DEBUG
#define DPRINTF(p) printf p
#else
#define DPRINTF(p) /* Nothing */
#endif


/* Standard C headers plus the external interface definition. The only time
setjmp and stdarg are used is when NO_RECURSE is set. */

#include <ctype.h>
#include <limits.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* Valgrind (memcheck) support */

#ifdef SUPPORT_VALGRIND
#include <valgrind/memcheck.h>
#endif

/* When compiling a DLL for Windows, the exported symbols have to be declared
using some MS magic. I found some useful information on this web page:
http://msdn2.microsoft.com/en-us/library/y4h7bcy6(VS.80).aspx. According to the
information there, using __declspec(dllexport) without "extern" we have a
definition; with "extern" we have a declaration. The settings here override the
setting in pcre.h (which is included below); it defines only PCRE_EXP_DECL,
which is all that is needed for applications (they just import the symbols). We
use:

  PCRE_EXP_DECL       for declarations
  PCRE_EXP_DEFN       for definitions of exported functions
  PCRE_EXP_DATA_DEFN  for definitions of exported variables

The reason for the two DEFN macros is that in non-Windows environments, one
does not want to have "extern" before variable definitions because it leads to
compiler warnings. So we distinguish between functions and variables. In
Windows, the two should always be the same.

The reason for wrapping this in #ifndef PCRE_EXP_DECL is so that pcretest,
which is an application, but needs to import this file in order to "peek" at
internals, can #include pcre.h first to get an application's-eye view.

In principle, people compiling for non-Windows, non-Unix-like (i.e. uncommon,
special-purpose environments) might want to stick other stuff in front of
exported symbols. That's why, in the non-Windows case, we set PCRE_EXP_DEFN and
PCRE_EXP_DATA_DEFN only if they are not already set. */

#ifndef PCRE_EXP_DECL
#  ifdef _WIN32
#    ifndef PCRE_STATIC
#      define PCRE_EXP_DECL       extern __declspec(dllexport)
#      define PCRE_EXP_DEFN       __declspec(dllexport)
#      define PCRE_EXP_DATA_DEFN  __declspec(dllexport)
#    else
#      define PCRE_EXP_DECL       extern
#      define PCRE_EXP_DEFN
#      define PCRE_EXP_DATA_DEFN
#    endif
#  else
#    ifdef __cplusplus
#      define PCRE_EXP_DECL       extern "C"
#    else
#      define PCRE_EXP_DECL       extern
#    endif
#    ifndef PCRE_EXP_DEFN
#      define PCRE_EXP_DEFN       PCRE_EXP_DECL
#    endif
#    ifndef PCRE_EXP_DATA_DEFN
#      define PCRE_EXP_DATA_DEFN
#    endif
#  endif
#endif

/* When compiling with the MSVC compiler, it is sometimes necessary to include
a "calling convention" before exported function names. (This is secondhand
information; I know nothing about MSVC myself). For example, something like

  void __cdecl function(....)

might be needed. In order so make this easy, all the exported functions have
PCRE_CALL_CONVENTION just before their names. It is rarely needed; if not
set, we ensure here that it has no effect. */

#ifndef PCRE_CALL_CONVENTION
#define PCRE_CALL_CONVENTION
#endif

/* We need to have types that specify unsigned 8, 16 and 32-bit integers. We
cannot determine these outside the compilation (e.g. by running a program as
part of "configure") because PCRE is often cross-compiled for use on other
systems. Instead we make use of the maximum sizes that are available at
preprocessor time in standard C environments. */

typedef unsigned char pcre_uint8;

#if USHRT_MAX == 65535
typedef unsigned short pcre_uint16;
typedef short pcre_int16;
#define PCRE_UINT16_MAX USHRT_MAX
#define PCRE_INT16_MAX SHRT_MAX
#elif UINT_MAX == 65535
typedef unsigned int pcre_uint16;
typedef int pcre_int16;
#define PCRE_UINT16_MAX UINT_MAX
#define PCRE_INT16_MAX INT_MAX
#else
#error Cannot determine a type for 16-bit integers
#endif

#if UINT_MAX == 4294967295U
typedef unsigned int pcre_uint32;
typedef int pcre_int32;
#define PCRE_UINT32_MAX UINT_MAX
#define PCRE_INT32_MAX INT_MAX
#elif ULONG_MAX == 4294967295UL
typedef unsigned long int pcre_uint32;
typedef long int pcre_int32;
#define PCRE_UINT32_MAX ULONG_MAX
#define PCRE_INT32_MAX LONG_MAX
#else
#error Cannot determine a type for 32-bit integers
#endif

/* When checking for integer overflow in pcre_compile(), we need to handle
large integers. If a 64-bit integer type is available, we can use that.
Otherwise we have to cast to double, which of course requires floating point
arithmetic. Handle this by defining a macro for the appropriate type. If
stdint.h is available, include it; it may define INT64_MAX. Systems that do not
have stdint.h (e.g. Solaris) may have inttypes.h. The macro int64_t may be set
by "configure". */

#if defined HAVE_STDINT_H
#include <stdint.h>
#elif defined HAVE_INTTYPES_H
#include <inttypes.h>
#endif

#if defined INT64_MAX || defined int64_t
#define INT64_OR_DOUBLE int64_t
#else
#define INT64_OR_DOUBLE double
#endif

/* All character handling must be done as unsigned characters. Otherwise there
are problems with top-bit-set characters and functions such as isspace().
However, we leave the interface to the outside world as char * or short *,
because that should make things easier for callers. This character type is
called pcre_uchar.

The IN_UCHARS macro multiply its argument with the byte size of the current
pcre_uchar type. Useful for memcpy and such operations, whose require the
byte size of their input/output buffers.

The MAX_255 macro checks whether its pcre_uchar input is less than 256.

The TABLE_GET macro is designed for accessing elements of tables whose contain
exactly 256 items. When the character is able to contain more than 256
items, some check is needed before accessing these tables.
*/

#if defined COMPILE_PCRE8

typedef unsigned char pcre_uchar;
#define IN_UCHARS(x) (x)
#define MAX_255(c) 1
#define TABLE_GET(c, table, default) ((table)[c])

#elif defined COMPILE_PCRE16

#if USHRT_MAX != 65535
/* This is a warning message. Change PCRE_UCHAR16 to a 16 bit data type in
pcre.h(.in) and disable (comment out) this message. */
#error Warning: PCRE_UCHAR16 is not a 16 bit data type.
#endif

typedef pcre_uint16 pcre_uchar;
#define UCHAR_SHIFT (1)
#define IN_UCHARS(x) ((x) * 2)
#define MAX_255(c) ((c) <= 255u)
#define TABLE_GET(c, table, default) (MAX_255(c)? ((table)[c]):(default))

#elif defined COMPILE_PCRE32

typedef pcre_uint32 pcre_uchar;
#define UCHAR_SHIFT (2)
#define IN_UCHARS(x) ((x) * 4)
#define MAX_255(c) ((c) <= 255u)
#define TABLE_GET(c, table, default) (MAX_255(c)? ((table)[c]):(default))

#else
#error Unsupported compiling mode
#endif /* COMPILE_PCRE[8|16|32] */

/* This is an unsigned int value that no character can ever have. UTF-8
characters only go up to 0x7fffffff (though Unicode doesn't go beyond
0x0010ffff). */

#define NOTACHAR 0xffffffff

/* PCRE is able to support several different kinds of newline (CR, LF, CRLF,
"any" and "anycrlf" at present). The following macros are used to package up
testing for newlines. NLBLOCK, PSSTART, and PSEND are defined in the various
modules to indicate in which datablock the parameters exist, and what the
start/end of string field names are. */

#define NLTYPE_FIXED    0     /* Newline is a fixed length string */
#define NLTYPE_ANY      1     /* Newline is any Unicode line ending */
#define NLTYPE_ANYCRLF  2     /* Newline is CR, LF, or CRLF */

/* This macro checks for a newline at the given position */

#define IS_NEWLINE(p) \
  ((NLBLOCK->nltype != NLTYPE_FIXED)? \
    ((p) < NLBLOCK->PSEND && \
     PRIV(is_newline)((p), NLBLOCK->nltype, NLBLOCK->PSEND, \
       &(NLBLOCK->nllen), utf)) \
    : \
    ((p) <= NLBLOCK->PSEND - NLBLOCK->nllen && \
     UCHAR21TEST(p) == NLBLOCK->nl[0] && \
     (NLBLOCK->nllen == 1 || UCHAR21TEST(p+1) == NLBLOCK->nl[1])       \
    ) \
  )

/* This macro checks for a newline immediately preceding the given position */

#define WAS_NEWLINE(p) \
  ((NLBLOCK->nltype != NLTYPE_FIXED)? \
    ((p) > NLBLOCK->PSSTART && \
     PRIV(was_newline)((p), NLBLOCK->nltype, NLBLOCK->PSSTART, \
       &(NLBLOCK->nllen), utf)) \
    : \
    ((p) >= NLBLOCK->PSSTART + NLBLOCK->nllen && \
     UCHAR21TEST(p - NLBLOCK->nllen) == NLBLOCK->nl[0] &&              \
     (NLBLOCK->nllen == 1 || UCHAR21TEST(p - NLBLOCK->nllen + 1) == NLBLOCK->nl[1]) \
    ) \
  )

/* When PCRE is compiled as a C++ library, the subject pointer can be replaced
with a custom type. This makes it possible, for example, to allow pcre_exec()
to process subject strings that are discontinuous by using a smart pointer
class. It must always be possible to inspect all of the subject string in
pcre_exec() because of the way it backtracks. Two macros are required in the
normal case, for sign-unspecified and unsigned char pointers. The former is
used for the external interface and appears in pcre.h, which is why its name
must begin with PCRE_. */

#ifdef CUSTOM_SUBJECT_PTR
#define PCRE_PUCHAR CUSTOM_SUBJECT_PTR
#else
#define PCRE_PUCHAR const pcre_uchar *
#endif

/* Include the public PCRE header and the definitions of UCP character property
values. */

#include "pcre.h"
#include "ucp.h"

#ifdef COMPILE_PCRE32
/* Assert that the public PCRE_UCHAR32 is a 32-bit type */
typedef int __assert_pcre_uchar32_size[sizeof(PCRE_UCHAR32) == 4 ? 1 : -1];
#endif

/* When compiling for use with the Virtual Pascal compiler, these functions
need to have their names changed. PCRE must be compiled with the -DVPCOMPAT
option on the command line. */

#ifdef VPCOMPAT
#define strlen(s)        _strlen(s)
#define strncmp(s1,s2,m) _strncmp(s1,s2,m)
#define memcmp(s,c,n)    _memcmp(s,c,n)
#define memcpy(d,s,n)    _memcpy(d,s,n)
#define memmove(d,s,n)   _memmove(d,s,n)
#define memset(s,c,n)    _memset(s,c,n)
#else  /* VPCOMPAT */

/* To cope with SunOS4 and other systems that lack memmove() but have bcopy(),
define a macro for memmove() if HAVE_MEMMOVE is false, provided that HAVE_BCOPY
is set. Otherwise, include an emulating function for those systems that have
neither (there some non-Unix environments where this is the case). */

#ifndef HAVE_MEMMOVE
#undef  memmove        /* some systems may have a macro */
#ifdef HAVE_BCOPY
#define memmove(a, b, c) bcopy(b, a, c)
#else  /* HAVE_BCOPY */
static void *
pcre_memmove(void *d, const void *s, size_t n)
{
size_t i;
unsigned char *dest = (unsigned char *)d;
const unsigned char *src = (const unsigned char *)s;
if (dest > src)
  {
  dest += n;
  src += n;
  for (i = 0; i < n; ++i) *(--dest) = *(--src);
  return (void *)dest;
  }
else
  {
  for (i = 0; i < n; ++i) *dest++ = *src++;
  return (void *)(dest - n);
  }
}
#define memmove(a, b, c) pcre_memmove(a, b, c)
#endif   /* not HAVE_BCOPY */
#endif   /* not HAVE_MEMMOVE */
#endif   /* not VPCOMPAT */


/* PCRE keeps offsets in its compiled code as 2-byte quantities (always stored
in big-endian order) by default. These are used, for example, to link from the
start of a subpattern to its alternatives and its end. The use of 2 bytes per
offset limits the size of the compiled regex to around 64K, which is big enough
for almost everybody. However, I received a request for an even bigger limit.
For this reason, and also to make the code easier to maintain, the storing and
loading of offsets from the byte string is now handled by the macros that are
defined here.

The macros are controlled by the value of LINK_SIZE. This defaults to 2 in
the config.h file, but can be overridden by using -D on the command line. This
is automated on Unix systems via the "configure" command. */

#if defined COMPILE_PCRE8

#if LINK_SIZE == 2

#define PUT(a,n,d)   \
  (a[n] = (d) >> 8), \
  (a[(n)+1] = (d) & 255)

#define GET(a,n) \
  (((a)[n] << 8) | (a)[(n)+1])

#define MAX_PATTERN_SIZE (1 << 16)


#elif LINK_SIZE == 3

#define PUT(a,n,d)       \
  (a[n] = (d) >> 16),    \
  (a[(n)+1] = (d) >> 8), \
  (a[(n)+2] = (d) & 255)

#define GET(a,n) \
  (((a)[n] << 16) | ((a)[(n)+1] << 8) | (a)[(n)+2])

#define MAX_PATTERN_SIZE (1 << 24)


#elif LINK_SIZE == 4

#define PUT(a,n,d)        \
  (a[n] = (d) >> 24),     \
  (a[(n)+1] = (d) >> 16), \
  (a[(n)+2] = (d) >> 8),  \
  (a[(n)+3] = (d) & 255)

#define GET(a,n) \
  (((a)[n] << 24) | ((a)[(n)+1] << 16) | ((a)[(n)+2] << 8) | (a)[(n)+3])

/* Keep it positive */
#define MAX_PATTERN_SIZE (1 << 30)

#else
#error LINK_SIZE must be either 2, 3, or 4
#endif

#elif defined COMPILE_PCRE16

#if LINK_SIZE == 2

/* Redefine LINK_SIZE as a multiple of sizeof(pcre_uchar) */
#undef LINK_SIZE
#define LINK_SIZE 1

#define PUT(a,n,d)   \
  (a[n] = (d))

#define GET(a,n) \
  (a[n])

#define MAX_PATTERN_SIZE (1 << 16)

#elif LINK_SIZE == 3 || LINK_SIZE == 4

/* Redefine LINK_SIZE as a multiple of sizeof(pcre_uchar) */
#undef LINK_SIZE
#define LINK_SIZE 2

#define PUT(a,n,d)   \
  (a[n] = (d) >> 16), \
  (a[(n)+1] = (d) & 65535)

#define GET(a,n) \
  (((a)[n] << 16) | (a)[(n)+1])

/* Keep it positive */
#define MAX_PATTERN_SIZE (1 << 30)

#else
#error LINK_SIZE must be either 2, 3, or 4
#endif

#elif defined COMPILE_PCRE32

/* Only supported LINK_SIZE is 4 */
/* Redefine LINK_SIZE as a multiple of sizeof(pcre_uchar) */
#undef LINK_SIZE
#define LINK_SIZE 1

#define PUT(a,n,d)   \
  (a[n] = (d))

#define GET(a,n) \
  (a[n])

/* Keep it positive */
#define MAX_PATTERN_SIZE (1 << 30)

#else
#error Unsupported compiling mode
#endif /* COMPILE_PCRE[8|16|32] */

/* Convenience macro defined in terms of the others */

#define PUTINC(a,n,d)   PUT(a,n,d), a += LINK_SIZE


/* PCRE uses some other 2-byte quantities that do not change when the size of
offsets changes. There are used for repeat counts and for other things such as
capturing parenthesis numbers in back references. */

#if defined COMPILE_PCRE8

#define IMM2_SIZE 2

#define PUT2(a,n,d)   \
  a[n] = (d) >> 8; \
  a[(n)+1] = (d) & 255

/* For reasons that I do not understand, the expression in this GET2 macro is
treated by gcc as a signed expression, even when a is declared as unsigned. It
seems that any kind of arithmetic results in a signed value. */

#define GET2(a,n) \
  (unsigned int)(((a)[n] << 8) | (a)[(n)+1])

#elif defined COMPILE_PCRE16

#define IMM2_SIZE 1

#define PUT2(a,n,d)   \
   a[n] = d

#define GET2(a,n) \
   a[n]

#elif defined COMPILE_PCRE32

#define IMM2_SIZE 1

#define PUT2(a,n,d)   \
   a[n] = d

#define GET2(a,n) \
   a[n]

#else
#error Unsupported compiling mode
#endif /* COMPILE_PCRE[8|16|32] */

#define PUT2INC(a,n,d)  PUT2(a,n,d), a += IMM2_SIZE

/* The maximum length of a MARK name is currently one data unit; it may be
changed in future to be a fixed number of bytes or to depend on LINK_SIZE. */

#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
#define MAX_MARK ((1u << 16) - 1)
#else
#define MAX_MARK ((1u << 8) - 1)
#endif

/* There is a proposed future special "UTF-21" mode, in which only the lowest
21 bits of a 32-bit character are interpreted as UTF, with the remaining 11
high-order bits available to the application for other uses. In preparation for
the future implementation of this mode, there are macros that load a data item
and, if in this special mode, mask it to 21 bits. These macros all have names
starting with UCHAR21. In all other modes, including the normal 32-bit
library, the macros all have the same simple definitions. When the new mode is
implemented, it is expected that these definitions will be varied appropriately
using #ifdef when compiling the library that supports the special mode. */

#define UCHAR21(eptr)        (*(eptr))
#define UCHAR21TEST(eptr)    (*(eptr))
#define UCHAR21INC(eptr)     (*(eptr)++)
#define UCHAR21INCTEST(eptr) (*(eptr)++)

/* When UTF encoding is being used, a character is no longer just a single
byte in 8-bit mode or a single short in 16-bit mode. The macros for character
handling generate simple sequences when used in the basic mode, and more
complicated ones for UTF characters. GETCHARLENTEST and other macros are not
used when UTF is not supported. To make sure they can never even appear when
UTF support is omitted, we don't even define them. */

#ifndef SUPPORT_UTF

/* #define MAX_VALUE_FOR_SINGLE_CHAR */
/* #define HAS_EXTRALEN(c) */
/* #define GET_EXTRALEN(c) */
/* #define NOT_FIRSTCHAR(c) */
#define GETCHAR(c, eptr) c = *eptr;
#define GETCHARTEST(c, eptr) c = *eptr;
#define GETCHARINC(c, eptr) c = *eptr++;
#define GETCHARINCTEST(c, eptr) c = *eptr++;
#define GETCHARLEN(c, eptr, len) c = *eptr;
/* #define GETCHARLENTEST(c, eptr, len) */
/* #define BACKCHAR(eptr) */
/* #define FORWARDCHAR(eptr) */
/* #define ACROSSCHAR(condition, eptr, action) */

#else   /* SUPPORT_UTF */

/* Tests whether the code point needs extra characters to decode. */

#define HASUTF8EXTRALEN(c) ((c) >= 0xc0)

/* Base macro to pick up the remaining bytes of a UTF-8 character, not
advancing the pointer. */

#define GETUTF8(c, eptr) \
    { \
    if ((c & 0x20) == 0) \
      c = ((c & 0x1f) << 6) | (eptr[1] & 0x3f); \
    else if ((c & 0x10) == 0) \
      c = ((c & 0x0f) << 12) | ((eptr[1] & 0x3f) << 6) | (eptr[2] & 0x3f); \
    else if ((c & 0x08) == 0) \
      c = ((c & 0x07) << 18) | ((eptr[1] & 0x3f) << 12) | \
      ((eptr[2] & 0x3f) << 6) | (eptr[3] & 0x3f); \
    else if ((c & 0x04) == 0) \
      c = ((c & 0x03) << 24) | ((eptr[1] & 0x3f) << 18) | \
          ((eptr[2] & 0x3f) << 12) | ((eptr[3] & 0x3f) << 6) | \
          (eptr[4] & 0x3f); \
    else \
      c = ((c & 0x01) << 30) | ((eptr[1] & 0x3f) << 24) | \
          ((eptr[2] & 0x3f) << 18) | ((eptr[3] & 0x3f) << 12) | \
          ((eptr[4] & 0x3f) << 6) | (eptr[5] & 0x3f); \
    }

/* Base macro to pick up the remaining bytes of a UTF-8 character, advancing
the pointer. */

#define GETUTF8INC(c, eptr) \
    { \
    if ((c & 0x20) == 0) \
      c = ((c & 0x1f) << 6) | (*eptr++ & 0x3f); \
    else if ((c & 0x10) == 0) \
      { \
      c = ((c & 0x0f) << 12) | ((*eptr & 0x3f) << 6) | (eptr[1] & 0x3f); \
      eptr += 2; \
      } \
    else if ((c & 0x08) == 0) \
      { \
      c = ((c & 0x07) << 18) | ((*eptr & 0x3f) << 12) | \
          ((eptr[1] & 0x3f) << 6) | (eptr[2] & 0x3f); \
      eptr += 3; \
      } \
    else if ((c & 0x04) == 0) \
      { \
      c = ((c & 0x03) << 24) | ((*eptr & 0x3f) << 18) | \
          ((eptr[1] & 0x3f) << 12) | ((eptr[2] & 0x3f) << 6) | \
          (eptr[3] & 0x3f); \
      eptr += 4; \
      } \
    else \
      { \
      c = ((c & 0x01) << 30) | ((*eptr & 0x3f) << 24) | \
          ((eptr[1] & 0x3f) << 18) | ((eptr[2] & 0x3f) << 12) | \
          ((eptr[3] & 0x3f) << 6) | (eptr[4] & 0x3f); \
      eptr += 5; \
      } \
    }

#if defined COMPILE_PCRE8

/* These macros were originally written in the form of loops that used data
from the tables whose names start with PRIV(utf8_table). They were rewritten by
a user so as not to use loops, because in some environments this gives a
significant performance advantage, and it seems never to do any harm. */

/* Tells the biggest code point which can be encoded as a single character. */

#define MAX_VALUE_FOR_SINGLE_CHAR 127

/* Tests whether the code point needs extra characters to decode. */

#define HAS_EXTRALEN(c) ((c) >= 0xc0)

/* Returns with the additional number of characters if IS_MULTICHAR(c) is TRUE.
Otherwise it has an undefined behaviour. */

#define GET_EXTRALEN(c) (PRIV(utf8_table4)[(c) & 0x3f])

/* Returns TRUE, if the given character is not the first character
of a UTF sequence. */

#define NOT_FIRSTCHAR(c) (((c) & 0xc0) == 0x80)

/* Get the next UTF-8 character, not advancing the pointer. This is called when
we know we are in UTF-8 mode. */

#define GETCHAR(c, eptr) \
  c = *eptr; \
  if (c >= 0xc0) GETUTF8(c, eptr);

/* Get the next UTF-8 character, testing for UTF-8 mode, and not advancing the
pointer. */

#define GETCHARTEST(c, eptr) \
  c = *eptr; \
  if (utf && c >= 0xc0) GETUTF8(c, eptr);

/* Get the next UTF-8 character, advancing the pointer. This is called when we
know we are in UTF-8 mode. */

#define GETCHARINC(c, eptr) \
  c = *eptr++; \
  if (c >= 0xc0) GETUTF8INC(c, eptr);

/* Get the next character, testing for UTF-8 mode, and advancing the pointer.
This is called when we don't know if we are in UTF-8 mode. */

#define GETCHARINCTEST(c, eptr) \
  c = *eptr++; \
  if (utf && c >= 0xc0) GETUTF8INC(c, eptr);

/* Base macro to pick up the remaining bytes of a UTF-8 character, not
advancing the pointer, incrementing the length. */

#define GETUTF8LEN(c, eptr, len) \
    { \
    if ((c & 0x20) == 0) \
      { \
      c = ((c & 0x1f) << 6) | (eptr[1] & 0x3f); \
      len++; \
      } \
    else if ((c & 0x10)  == 0) \
      { \
      c = ((c & 0x0f) << 12) | ((eptr[1] & 0x3f) << 6) | (eptr[2] & 0x3f); \
      len += 2; \
      } \
    else if ((c & 0x08)  == 0) \
      {\
      c = ((c & 0x07) << 18) | ((eptr[1] & 0x3f) << 12) | \
          ((eptr[2] & 0x3f) << 6) | (eptr[3] & 0x3f); \
      len += 3; \
      } \
    else if ((c & 0x04)  == 0) \
      { \
      c = ((c & 0x03) << 24) | ((eptr[1] & 0x3f) << 18) | \
          ((eptr[2] & 0x3f) << 12) | ((eptr[3] & 0x3f) << 6) | \
          (eptr[4] & 0x3f); \
      len += 4; \
      } \
    else \
      {\
      c = ((c & 0x01) << 30) | ((eptr[1] & 0x3f) << 24) | \
          ((eptr[2] & 0x3f) << 18) | ((eptr[3] & 0x3f) << 12) | \
          ((eptr[4] & 0x3f) << 6) | (eptr[5] & 0x3f); \
      len += 5; \
      } \
    }

/* Get the next UTF-8 character, not advancing the pointer, incrementing length
if there are extra bytes. This is called when we know we are in UTF-8 mode. */

#define GETCHARLEN(c, eptr, len) \
  c = *eptr; \
  if (c >= 0xc0) GETUTF8LEN(c, eptr, len);

/* Get the next UTF-8 character, testing for UTF-8 mode, not advancing the
pointer, incrementing length if there are extra bytes. This is called when we
do not know if we are in UTF-8 mode. */

#define GETCHARLENTEST(c, eptr, len) \
  c = *eptr; \
  if (utf && c >= 0xc0) GETUTF8LEN(c, eptr, len);

/* If the pointer is not at the start of a character, move it back until
it is. This is called only in UTF-8 mode - we don't put a test within the macro
because almost all calls are already within a block of UTF-8 only code. */

#define BACKCHAR(eptr) while((*eptr & 0xc0) == 0x80) eptr--

/* Same as above, just in the other direction. */
#define FORWARDCHAR(eptr) while((*eptr & 0xc0) == 0x80) eptr++

/* Same as above, but it allows a fully customizable form. */
#define ACROSSCHAR(condition, eptr, action) \
  while((condition) && ((eptr) & 0xc0) == 0x80) action

#elif defined COMPILE_PCRE16

/* Tells the biggest code point which can be encoded as a single character. */

#define MAX_VALUE_FOR_SINGLE_CHAR 65535

/* Tests whether the code point needs extra characters to decode. */

#define HAS_EXTRALEN(c) (((c) & 0xfc00) == 0xd800)

/* Returns with the additional number of characters if IS_MULTICHAR(c) is TRUE.
Otherwise it has an undefined behaviour. */

#define GET_EXTRALEN(c) 1

/* Returns TRUE, if the given character is not the first character
of a UTF sequence. */

#define NOT_FIRSTCHAR(c) (((c) & 0xfc00) == 0xdc00)

/* Base macro to pick up the low surrogate of a UTF-16 character, not
advancing the pointer. */

#define GETUTF16(c, eptr) \
   { c = (((c & 0x3ff) << 10) | (eptr[1] & 0x3ff)) + 0x10000; }

/* Get the next UTF-16 character, not advancing the pointer. This is called when
we know we are in UTF-16 mode. */

#define GETCHAR(c, eptr) \
  c = *eptr; \
  if ((c & 0xfc00) == 0xd800) GETUTF16(c, eptr);

/* Get the next UTF-16 character, testing for UTF-16 mode, and not advancing the
pointer. */

#define GETCHARTEST(c, eptr) \
  c = *eptr; \
  if (utf && (c & 0xfc00) == 0xd800) GETUTF16(c, eptr);

/* Base macro to pick up the low surrogate of a UTF-16 character, advancing
the pointer. */

#define GETUTF16INC(c, eptr) \
   { c = (((c & 0x3ff) << 10) | (*eptr++ & 0x3ff)) + 0x10000; }

/* Get the next UTF-16 character, advancing the pointer. This is called when we
know we are in UTF-16 mode. */

#define GETCHARINC(c, eptr) \
  c = *eptr++; \
  if ((c & 0xfc00) == 0xd800) GETUTF16INC(c, eptr);

/* Get the next character, testing for UTF-16 mode, and advancing the pointer.
This is called when we don't know if we are in UTF-16 mode. */

#define GETCHARINCTEST(c, eptr) \
  c = *eptr++; \
  if (utf && (c & 0xfc00) == 0xd800) GETUTF16INC(c, eptr);

/* Base macro to pick up the low surrogate of a UTF-16 character, not
advancing the pointer, incrementing the length. */

#define GETUTF16LEN(c, eptr, len) \
   { c = (((c & 0x3ff) << 10) | (eptr[1] & 0x3ff)) + 0x10000; len++; }

/* Get the next UTF-16 character, not advancing the pointer, incrementing
length if there is a low surrogate. This is called when we know we are in
UTF-16 mode. */

#define GETCHARLEN(c, eptr, len) \
  c = *eptr; \
  if ((c & 0xfc00) == 0xd800) GETUTF16LEN(c, eptr, len);

/* Get the next UTF-816character, testing for UTF-16 mode, not advancing the
pointer, incrementing length if there is a low surrogate. This is called when
we do not know if we are in UTF-16 mode. */

#define GETCHARLENTEST(c, eptr, len) \
  c = *eptr; \
  if (utf && (c & 0xfc00) == 0xd800) GETUTF16LEN(c, eptr, len);

/* If the pointer is not at the start of a character, move it back until
it is. This is called only in UTF-16 mode - we don't put a test within the
macro because almost all calls are already within a block of UTF-16 only
code. */

#define BACKCHAR(eptr) if ((*eptr & 0xfc00) == 0xdc00) eptr--

/* Same as above, just in the other direction. */
#define FORWARDCHAR(eptr) if ((*eptr & 0xfc00) == 0xdc00) eptr++

/* Same as above, but it allows a fully customizable form. */
#define ACROSSCHAR(condition, eptr, action) \
  if ((condition) && ((eptr) & 0xfc00) == 0xdc00) action

#elif defined COMPILE_PCRE32

/* These are trivial for the 32-bit library, since all UTF-32 characters fit
into one pcre_uchar unit. */
#define MAX_VALUE_FOR_SINGLE_CHAR (0x10ffffu)
#define HAS_EXTRALEN(c) (0)
#define GET_EXTRALEN(c) (0)
#define NOT_FIRSTCHAR(c) (0)

/* Get the next UTF-32 character, not advancing the pointer. This is called when
we know we are in UTF-32 mode. */

#define GETCHAR(c, eptr) \
  c = *(eptr);

/* Get the next UTF-32 character, testing for UTF-32 mode, and not advancing the
pointer. */

#define GETCHARTEST(c, eptr) \
  c = *(eptr);

/* Get the next UTF-32 character, advancing the pointer. This is called when we
know we are in UTF-32 mode. */

#define GETCHARINC(c, eptr) \
  c = *((eptr)++);

/* Get the next character, testing for UTF-32 mode, and advancing the pointer.
This is called when we don't know if we are in UTF-32 mode. */

#define GETCHARINCTEST(c, eptr) \
  c = *((eptr)++);

/* Get the next UTF-32 character, not advancing the pointer, not incrementing
length (since all UTF-32 is of length 1). This is called when we know we are in
UTF-32 mode. */

#define GETCHARLEN(c, eptr, len) \
  GETCHAR(c, eptr)

/* Get the next UTF-32character, testing for UTF-32 mode, not advancing the
pointer, not incrementing the length (since all UTF-32 is of length 1).
This is called when we do not know if we are in UTF-32 mode. */

#define GETCHARLENTEST(c, eptr, len) \
  GETCHARTEST(c, eptr)

/* If the pointer is not at the start of a character, move it back until
it is. This is called only in UTF-32 mode - we don't put a test within the
macro because almost all calls are already within a block of UTF-32 only
code.
These are all no-ops since all UTF-32 characters fit into one pcre_uchar. */

#define BACKCHAR(eptr) do { } while (0)

/* Same as above, just in the other direction. */
#define FORWARDCHAR(eptr) do { } while (0)

/* Same as above, but it allows a fully customizable form. */
#define ACROSSCHAR(condition, eptr, action) do { } while (0)

#else
#error Unsupported compiling mode
#endif /* COMPILE_PCRE[8|16|32] */

#endif  /* SUPPORT_UTF */

/* Tests for Unicode horizontal and vertical whitespace characters must check a
number of different values. Using a switch statement for this generates the
fastest code (no loop, no memory access), and there are several places in the
interpreter code where this happens. In order to ensure that all the case lists
remain in step, we use macros so that there is only one place where the lists
are defined.

These values are also required as lists in pcre_compile.c when processing \h,
\H, \v and \V in a character class. The lists are defined in pcre_tables.c, but
macros that define the values are here so that all the definitions are
together. The lists must be in ascending character order, terminated by
NOTACHAR (which is 0xffffffff).

Any changes should ensure that the various macros are kept in step with each
other. NOTE: The values also appear in pcre_jit_compile.c. */

/* ------ ASCII/Unicode environments ------ */

#ifndef EBCDIC

#define HSPACE_LIST \
  CHAR_HT, CHAR_SPACE, CHAR_NBSP, \
  0x1680, 0x180e, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, \
  0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202f, 0x205f, 0x3000, \
  NOTACHAR

#define HSPACE_MULTIBYTE_CASES \
  case 0x1680:  /* OGHAM SPACE MARK */ \
  case 0x180e:  /* MONGOLIAN VOWEL SEPARATOR */ \
  case 0x2000:  /* EN QUAD */ \
  case 0x2001:  /* EM QUAD */ \
  case 0x2002:  /* EN SPACE */ \
  case 0x2003:  /* EM SPACE */ \
  case 0x2004:  /* THREE-PER-EM SPACE */ \
  case 0x2005:  /* FOUR-PER-EM SPACE */ \
  case 0x2006:  /* SIX-PER-EM SPACE */ \
  case 0x2007:  /* FIGURE SPACE */ \
  case 0x2008:  /* PUNCTUATION SPACE */ \
  case 0x2009:  /* THIN SPACE */ \
  case 0x200A:  /* HAIR SPACE */ \
  case 0x202f:  /* NARROW NO-BREAK SPACE */ \
  case 0x205f:  /* MEDIUM MATHEMATICAL SPACE */ \
  case 0x3000   /* IDEOGRAPHIC SPACE */

#define HSPACE_BYTE_CASES \
  case CHAR_HT: \
  case CHAR_SPACE: \
  case CHAR_NBSP

#define HSPACE_CASES \
  HSPACE_BYTE_CASES: \
  HSPACE_MULTIBYTE_CASES

#define VSPACE_LIST \
  CHAR_LF, CHAR_VT, CHAR_FF, CHAR_CR, CHAR_NEL, 0x2028, 0x2029, NOTACHAR

#define VSPACE_MULTIBYTE_CASES \
  case 0x2028:    /* LINE SEPARATOR */ \
  case 0x2029     /* PARAGRAPH SEPARATOR */

#define VSPACE_BYTE_CASES \
  case CHAR_LF: \
  case CHAR_VT: \
  case CHAR_FF: \
  case CHAR_CR: \
  case CHAR_NEL

#define VSPACE_CASES \
  VSPACE_BYTE_CASES: \
  VSPACE_MULTIBYTE_CASES

/* ------ EBCDIC environments ------ */

#else
#define HSPACE_LIST CHAR_HT, CHAR_SPACE, CHAR_NBSP, NOTACHAR

#define HSPACE_BYTE_CASES \
  case CHAR_HT: \
  case CHAR_SPACE: \
  case CHAR_NBSP

#define HSPACE_CASES HSPACE_BYTE_CASES

#ifdef EBCDIC_NL25
#define VSPACE_LIST \
  CHAR_VT, CHAR_FF, CHAR_CR, CHAR_NEL, CHAR_LF, NOTACHAR
#else
#define VSPACE_LIST \
  CHAR_VT, CHAR_FF, CHAR_CR, CHAR_LF, CHAR_NEL, NOTACHAR
#endif

#define VSPACE_BYTE_CASES \
  case CHAR_LF: \
  case CHAR_VT: \
  case CHAR_FF: \
  case CHAR_CR: \
  case CHAR_NEL

#define VSPACE_CASES VSPACE_BYTE_CASES
#endif  /* EBCDIC */

/* ------ End of whitespace macros ------ */



/* Private flags containing information about the compiled regex. They used to
live at the top end of the options word, but that got almost full, so they were
moved to a 16-bit flags word - which got almost full, so now they are in a
32-bit flags word. From release 8.00, PCRE_NOPARTIAL is unused, as the
restrictions on partial matching have been lifted. It remains for backwards
compatibility. */

#define PCRE_MODE8         0x00000001  /* compiled in 8 bit mode */
#define PCRE_MODE16        0x00000002  /* compiled in 16 bit mode */
#define PCRE_MODE32        0x00000004  /* compiled in 32 bit mode */
#define PCRE_FIRSTSET      0x00000010  /* first_char is set */
#define PCRE_FCH_CASELESS  0x00000020  /* caseless first char */
#define PCRE_REQCHSET      0x00000040  /* req_byte is set */
#define PCRE_RCH_CASELESS  0x00000080  /* caseless requested char */
#define PCRE_STARTLINE     0x00000100  /* start after \n for multiline */
#define PCRE_NOPARTIAL     0x00000200  /* can't use partial with this regex */
#define PCRE_JCHANGED      0x00000400  /* j option used in regex */
#define PCRE_HASCRORLF     0x00000800  /* explicit \r or \n in pattern */
#define PCRE_HASTHEN       0x00001000  /* pattern contains (*THEN) */
#define PCRE_MLSET         0x00002000  /* match limit set by regex */
#define PCRE_RLSET         0x00004000  /* recursion limit set by regex */
#define PCRE_MATCH_EMPTY   0x00008000  /* pattern can match empty string */

#if defined COMPILE_PCRE8
#define PCRE_MODE          PCRE_MODE8
#elif defined COMPILE_PCRE16
#define PCRE_MODE          PCRE_MODE16
#elif defined COMPILE_PCRE32
#define PCRE_MODE          PCRE_MODE32
#endif
#define PCRE_MODE_MASK     (PCRE_MODE8 | PCRE_MODE16 | PCRE_MODE32)

/* Flags for the "extra" block produced by pcre_study(). */

#define PCRE_STUDY_MAPPED  0x0001  /* a map of starting chars exists */
#define PCRE_STUDY_MINLEN  0x0002  /* a minimum length field exists */

/* Masks for identifying the public options that are permitted at compile
time, run time, or study time, respectively. */

#define PCRE_NEWLINE_BITS (PCRE_NEWLINE_CR|PCRE_NEWLINE_LF|PCRE_NEWLINE_ANY| \
                           PCRE_NEWLINE_ANYCRLF)

#define PUBLIC_COMPILE_OPTIONS \
  (PCRE_CASELESS|PCRE_EXTENDED|PCRE_ANCHORED|PCRE_MULTILINE| \
   PCRE_DOTALL|PCRE_DOLLAR_ENDONLY|PCRE_EXTRA|PCRE_UNGREEDY|PCRE_UTF8| \
   PCRE_NO_AUTO_CAPTURE|PCRE_NO_AUTO_POSSESS| \
   PCRE_NO_UTF8_CHECK|PCRE_AUTO_CALLOUT|PCRE_FIRSTLINE| \
   PCRE_DUPNAMES|PCRE_NEWLINE_BITS|PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE| \
   PCRE_JAVASCRIPT_COMPAT|PCRE_UCP|PCRE_NO_START_OPTIMIZE|PCRE_NEVER_UTF)

#define PUBLIC_EXEC_OPTIONS \
  (PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|PCRE_NOTEMPTY_ATSTART| \
   PCRE_NO_UTF8_CHECK|PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT|PCRE_NEWLINE_BITS| \
   PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE|PCRE_NO_START_OPTIMIZE)

#define PUBLIC_DFA_EXEC_OPTIONS \
  (PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|PCRE_NOTEMPTY_ATSTART| \
   PCRE_NO_UTF8_CHECK|PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT|PCRE_DFA_SHORTEST| \
   PCRE_DFA_RESTART|PCRE_NEWLINE_BITS|PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE| \
   PCRE_NO_START_OPTIMIZE)

#define PUBLIC_STUDY_OPTIONS \
   (PCRE_STUDY_JIT_COMPILE|PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE| \
    PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE|PCRE_STUDY_EXTRA_NEEDED)

#define PUBLIC_JIT_EXEC_OPTIONS \
   (PCRE_NO_UTF8_CHECK|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|\
    PCRE_NOTEMPTY_ATSTART|PCRE_PARTIAL_SOFT|PCRE_PARTIAL_HARD)

/* Magic number to provide a small check against being handed junk. */

#define MAGIC_NUMBER  0x50435245UL   /* 'PCRE' */

/* This variable is used to detect a loaded regular expression
in different endianness. */

#define REVERSED_MAGIC_NUMBER  0x45524350UL   /* 'ERCP' */

/* The maximum remaining length of subject we are prepared to search for a
req_byte match. */

#define REQ_BYTE_MAX 1000

/* Miscellaneous definitions. The #ifndef is to pacify compiler warnings in
environments where these macros are defined elsewhere. Unfortunately, there
is no way to do the same for the typedef. */

typedef int BOOL;

#ifndef FALSE
#define FALSE   0
#define TRUE    1
#endif

/* If PCRE is to support UTF-8 on EBCDIC platforms, we cannot use normal
character constants like '*' because the compiler would emit their EBCDIC code,
which is different from their ASCII/UTF-8 code. Instead we define macros for
the characters so that they always use the ASCII/UTF-8 code when UTF-8 support
is enabled. When UTF-8 support is not enabled, the definitions use character
literals. Both character and string versions of each character are needed, and
there are some longer strings as well.

This means that, on EBCDIC platforms, the PCRE library can handle either
EBCDIC, or UTF-8, but not both. To support both in the same compiled library
would need different lookups depending on whether PCRE_UTF8 was set or not.
This would make it impossible to use characters in switch/case statements,
which would reduce performance. For a theoretical use (which nobody has asked
for) in a minority area (EBCDIC platforms), this is not sensible. Any
application that did need both could compile two versions of the library, using
macros to give the functions distinct names. */

#ifndef SUPPORT_UTF

/* UTF-8 support is not enabled; use the platform-dependent character literals
so that PCRE works in both ASCII and EBCDIC environments, but only in non-UTF
mode. Newline characters are problematic in EBCDIC. Though it has CR and LF
characters, a common practice has been to use its NL (0x15) character as the
line terminator in C-like processing environments. However, sometimes the LF
(0x25) character is used instead, according to this Unicode document:

http://unicode.org/standard/reports/tr13/tr13-5.html

PCRE defaults EBCDIC NL to 0x15, but has a build-time option to select 0x25
instead. Whichever is *not* chosen is defined as NEL.

In both ASCII and EBCDIC environments, CHAR_NL and CHAR_LF are synonyms for the
same code point. */

#ifdef EBCDIC

#ifndef EBCDIC_NL25
#define CHAR_NL                     '\x15'
#define CHAR_NEL                    '\x25'
#define STR_NL                      "\x15"
#define STR_NEL                     "\x25"
#else
#define CHAR_NL                     '\x25'
#define CHAR_NEL                    '\x15'
#define STR_NL                      "\x25"
#define STR_NEL                     "\x15"
#endif

#define CHAR_LF                     CHAR_NL
#define STR_LF                      STR_NL

#define CHAR_ESC                    '\047'
#define CHAR_DEL                    '\007'
#define CHAR_NBSP                   '\x41'
#define STR_ESC                     "\047"
#define STR_DEL                     "\007"

#else  /* Not EBCDIC */

/* In ASCII/Unicode, linefeed is '\n' and we equate this to NL for
compatibility. NEL is the Unicode newline character; make sure it is
a positive value. */

#define CHAR_LF                     '\n'
#define CHAR_NL                     CHAR_LF
#define CHAR_NEL                    ((unsigned char)'\x85')
#define CHAR_ESC                    '\033'
#define CHAR_DEL                    '\177'
#define CHAR_NBSP                   ((unsigned char)'\xa0')

#define STR_LF                      "\n"
#define STR_NL                      STR_LF
#define STR_NEL                     "\x85"
#define STR_ESC                     "\033"
#define STR_DEL                     "\177"

#endif  /* EBCDIC */

/* The remaining definitions work in both environments. */

#define CHAR_NULL                   '\0'
#define CHAR_HT                     '\t'
#define CHAR_VT                     '\v'
#define CHAR_FF                     '\f'
#define CHAR_CR                     '\r'
#define CHAR_BS                     '\b'
#define CHAR_BEL                    '\a'

#define CHAR_SPACE                  ' '
#define CHAR_EXCLAMATION_MARK       '!'
#define CHAR_QUOTATION_MARK         '"'
#define CHAR_NUMBER_SIGN            '#'
#define CHAR_DOLLAR_SIGN            '$'
#define CHAR_PERCENT_SIGN           '%'
#define CHAR_AMPERSAND              '&'
#define CHAR_APOSTROPHE             '\''
#define CHAR_LEFT_PARENTHESIS       '('
#define CHAR_RIGHT_PARENTHESIS      ')'
#define CHAR_ASTERISK               '*'
#define CHAR_PLUS                   '+'
#define CHAR_COMMA                  ','
#define CHAR_MINUS                  '-'
#define CHAR_DOT                    '.'
#define CHAR_SLASH                  '/'
#define CHAR_0                      '0'
#define CHAR_1                      '1'
#define CHAR_2                      '2'
#define CHAR_3                      '3'
#define CHAR_4                      '4'
#define CHAR_5                      '5'
#define CHAR_6                      '6'
#define CHAR_7                      '7'
#define CHAR_8                      '8'
#define CHAR_9                      '9'
#define CHAR_COLON                  ':'
#define CHAR_SEMICOLON              ';'
#define CHAR_LESS_THAN_SIGN         '<'
#define CHAR_EQUALS_SIGN            '='
#define CHAR_GREATER_THAN_SIGN      '>'
#define CHAR_QUESTION_MARK          '?'
#define CHAR_COMMERCIAL_AT          '@'
#define CHAR_A                      'A'
#define CHAR_B                      'B'
#define CHAR_C                      'C'
#define CHAR_D                      'D'
#define CHAR_E                      'E'
#define CHAR_F                      'F'
#define CHAR_G                      'G'
#define CHAR_H                      'H'
#define CHAR_I                      'I'
#define CHAR_J                      'J'
#define CHAR_K                      'K'
#define CHAR_L                      'L'
#define CHAR_M                      'M'
#define CHAR_N                      'N'
#define CHAR_O                      'O'
#define CHAR_P                      'P'
#define CHAR_Q                      'Q'
#define CHAR_R                      'R'
#define CHAR_S                      'S'
#define CHAR_T                      'T'
#define CHAR_U                      'U'
#define CHAR_V                      'V'
#define CHAR_W                      'W'
#define CHAR_X                      'X'
#define CHAR_Y                      'Y'
#define CHAR_Z                      'Z'
#define CHAR_LEFT_SQUARE_BRACKET    '['
#define CHAR_BACKSLASH              '\\'
#define CHAR_RIGHT_SQUARE_BRACKET   ']'
#define CHAR_CIRCUMFLEX_ACCENT      '^'
#define CHAR_UNDERSCORE             '_'
#define CHAR_GRAVE_ACCENT           '`'
#define CHAR_a                      'a'
#define CHAR_b                      'b'
#define CHAR_c                      'c'
#define CHAR_d                      'd'
#define CHAR_e                      'e'
#define CHAR_f                      'f'
#define CHAR_g                      'g'
#define CHAR_h                      'h'
#define CHAR_i                      'i'
#define CHAR_j                      'j'
#define CHAR_k                      'k'
#define CHAR_l                      'l'
#define CHAR_m                      'm'
#define CHAR_n                      'n'
#define CHAR_o                      'o'
#define CHAR_p                      'p'
#define CHAR_q                      'q'
#define CHAR_r                      'r'
#define CHAR_s                      's'
#define CHAR_t                      't'
#define CHAR_u                      'u'
#define CHAR_v                      'v'
#define CHAR_w                      'w'
#define CHAR_x                      'x'
#define CHAR_y                      'y'
#define CHAR_z                      'z'
#define CHAR_LEFT_CURLY_BRACKET     '{'
#define CHAR_VERTICAL_LINE          '|'
#define CHAR_RIGHT_CURLY_BRACKET    '}'
#define CHAR_TILDE                  '~'

#define STR_HT                      "\t"
#define STR_VT                      "\v"
#define STR_FF                      "\f"
#define STR_CR                      "\r"
#define STR_BS                      "\b"
#define STR_BEL                     "\a"

#define STR_SPACE                   " "
#define STR_EXCLAMATION_MARK        "!"
#define STR_QUOTATION_MARK          "\""
#define STR_NUMBER_SIGN             "#"
#define STR_DOLLAR_SIGN             "$"
#define STR_PERCENT_SIGN            "%"
#define STR_AMPERSAND               "&"
#define STR_APOSTROPHE              "'"
#define STR_LEFT_PARENTHESIS        "("
#define STR_RIGHT_PARENTHESIS       ")"
#define STR_ASTERISK                "*"
#define STR_PLUS                    "+"
#define STR_COMMA                   ","
#define STR_MINUS                   "-"
#define STR_DOT                     "."
#define STR_SLASH                   "/"
#define STR_0                       "0"
#define STR_1                       "1"
#define STR_2                       "2"
#define STR_3                       "3"
#define STR_4                       "4"
#define STR_5                       "5"
#define STR_6                       "6"
#define STR_7                       "7"
#define STR_8                       "8"
#define STR_9                       "9"
#define STR_COLON                   ":"
#define STR_SEMICOLON               ";"
#define STR_LESS_THAN_SIGN          "<"
#define STR_EQUALS_SIGN             "="
#define STR_GREATER_THAN_SIGN       ">"
#define STR_QUESTION_MARK           "?"
#define STR_COMMERCIAL_AT           "@"
#define STR_A                       "A"
#define STR_B                       "B"
#define STR_C                       "C"
#define STR_D                       "D"
#define STR_E                       "E"
#define STR_F                       "F"
#define STR_G                       "G"
#define STR_H                       "H"
#define STR_I                       "I"
#define STR_J                       "J"
#define STR_K                       "K"
#define STR_L                       "L"
#define STR_M                       "M"
#define STR_N                       "N"
#define STR_O                       "O"
#define STR_P                       "P"
#define STR_Q                       "Q"
#define STR_R                       "R"
#define STR_S                       "S"
#define STR_T                       "T"
#define STR_U                       "U"
#define STR_V                       "V"
#define STR_W                       "W"
#define STR_X                       "X"
#define STR_Y                       "Y"
#define STR_Z                       "Z"
#define STR_LEFT_SQUARE_BRACKET     "["
#define STR_BACKSLASH               "\\"
#define STR_RIGHT_SQUARE_BRACKET    "]"
#define STR_CIRCUMFLEX_ACCENT       "^"
#define STR_UNDERSCORE              "_"
#define STR_GRAVE_ACCENT            "`"
#define STR_a                       "a"
#define STR_b                       "b"
#define STR_c                       "c"
#define STR_d                       "d"
#define STR_e                       "e"
#define STR_f                       "f"
#define STR_g                       "g"
#define STR_h                       "h"
#define STR_i                       "i"
#define STR_j                       "j"
#define STR_k                       "k"
#define STR_l                       "l"
#define STR_m                       "m"
#define STR_n                       "n"
#define STR_o                       "o"
#define STR_p                       "p"
#define STR_q                       "q"
#define STR_r                       "r"
#define STR_s                       "s"
#define STR_t                       "t"
#define STR_u                       "u"
#define STR_v                       "v"
#define STR_w                       "w"
#define STR_x                       "x"
#define STR_y                       "y"
#define STR_z                       "z"
#define STR_LEFT_CURLY_BRACKET      "{"
#define STR_VERTICAL_LINE           "|"
#define STR_RIGHT_CURLY_BRACKET     "}"
#define STR_TILDE                   "~"

#define STRING_ACCEPT0              "ACCEPT\0"
#define STRING_COMMIT0              "COMMIT\0"
#define STRING_F0                   "F\0"
#define STRING_FAIL0                "FAIL\0"
#define STRING_MARK0                "MARK\0"
#define STRING_PRUNE0               "PRUNE\0"
#define STRING_SKIP0                "SKIP\0"
#define STRING_THEN                 "THEN"

#define STRING_alpha0               "alpha\0"
#define STRING_lower0               "lower\0"
#define STRING_upper0               "upper\0"
#define STRING_alnum0               "alnum\0"
#define STRING_ascii0               "ascii\0"
#define STRING_blank0               "blank\0"
#define STRING_cntrl0               "cntrl\0"
#define STRING_digit0               "digit\0"
#define STRING_graph0               "graph\0"
#define STRING_print0               "print\0"
#define STRING_punct0               "punct\0"
#define STRING_space0               "space\0"
#define STRING_word0                "word\0"
#define STRING_xdigit               "xdigit"

#define STRING_DEFINE               "DEFINE"
#define STRING_WEIRD_STARTWORD      "[:<:]]"
#define STRING_WEIRD_ENDWORD        "[:>:]]"

#define STRING_CR_RIGHTPAR              "CR)"
#define STRING_LF_RIGHTPAR              "LF)"
#define STRING_CRLF_RIGHTPAR            "CRLF)"
#define STRING_ANY_RIGHTPAR             "ANY)"
#define STRING_ANYCRLF_RIGHTPAR         "ANYCRLF)"
#define STRING_BSR_ANYCRLF_RIGHTPAR     "BSR_ANYCRLF)"
#define STRING_BSR_UNICODE_RIGHTPAR     "BSR_UNICODE)"
#define STRING_UTF8_RIGHTPAR            "UTF8)"
#define STRING_UTF16_RIGHTPAR           "UTF16)"
#define STRING_UTF32_RIGHTPAR           "UTF32)"
#define STRING_UTF_RIGHTPAR             "UTF)"
#define STRING_UCP_RIGHTPAR             "UCP)"
#define STRING_NO_AUTO_POSSESS_RIGHTPAR "NO_AUTO_POSSESS)"
#define STRING_NO_START_OPT_RIGHTPAR    "NO_START_OPT)"
#define STRING_LIMIT_MATCH_EQ           "LIMIT_MATCH="
#define STRING_LIMIT_RECURSION_EQ       "LIMIT_RECURSION="

#else  /* SUPPORT_UTF */

/* UTF-8 support is enabled; always use UTF-8 (=ASCII) character codes. This
works in both modes non-EBCDIC platforms, and on EBCDIC platforms in UTF-8 mode
only. */

#define CHAR_HT                     '\011'
#define CHAR_VT                     '\013'
#define CHAR_FF                     '\014'
#define CHAR_CR                     '\015'
#define CHAR_LF                     '\012'
#define CHAR_NL                     CHAR_LF
#define CHAR_NEL                    ((unsigned char)'\x85')
#define CHAR_BS                     '\010'
#define CHAR_BEL                    '\007'
#define CHAR_ESC                    '\033'
#define CHAR_DEL                    '\177'

#define CHAR_NULL                   '\0'
#define CHAR_SPACE                  '\040'
#define CHAR_EXCLAMATION_MARK       '\041'
#define CHAR_QUOTATION_MARK         '\042'
#define CHAR_NUMBER_SIGN            '\043'
#define CHAR_DOLLAR_SIGN            '\044'
#define CHAR_PERCENT_SIGN           '\045'
#define CHAR_AMPERSAND              '\046'
#define CHAR_APOSTROPHE             '\047'
#define CHAR_LEFT_PARENTHESIS       '\050'
#define CHAR_RIGHT_PARENTHESIS      '\051'
#define CHAR_ASTERISK               '\052'
#define CHAR_PLUS                   '\053'
#define CHAR_COMMA                  '\054'
#define CHAR_MINUS                  '\055'
#define CHAR_DOT                    '\056'
#define CHAR_SLASH                  '\057'
#define CHAR_0                      '\060'
#define CHAR_1                      '\061'
#define CHAR_2                      '\062'
#define CHAR_3                      '\063'
#define CHAR_4                      '\064'
#define CHAR_5                      '\065'
#define CHAR_6                      '\066'
#define CHAR_7                      '\067'
#define CHAR_8                      '\070'
#define CHAR_9                      '\071'
#define CHAR_COLON                  '\072'
#define CHAR_SEMICOLON              '\073'
#define CHAR_LESS_THAN_SIGN         '\074'
#define CHAR_EQUALS_SIGN            '\075'
#define CHAR_GREATER_THAN_SIGN      '\076'
#define CHAR_QUESTION_MARK          '\077'
#define CHAR_COMMERCIAL_AT          '\100'
#define CHAR_A                      '\101'
#define CHAR_B                      '\102'
#define CHAR_C                      '\103'
#define CHAR_D                      '\104'
#define CHAR_E                      '\105'
#define CHAR_F                      '\106'
#define CHAR_G                      '\107'
#define CHAR_H                      '\110'
#define CHAR_I                      '\111'
#define CHAR_J                      '\112'
#define CHAR_K                      '\113'
#define CHAR_L                      '\114'
#define CHAR_M                      '\115'
#define CHAR_N                      '\116'
#define CHAR_O                      '\117'
#define CHAR_P                      '\120'
#define CHAR_Q                      '\121'
#define CHAR_R                      '\122'
#define CHAR_S                      '\123'
#define CHAR_T                      '\124'
#define CHAR_U                      '\125'
#define CHAR_V                      '\126'
#define CHAR_W                      '\127'
#define CHAR_X                      '\130'
#define CHAR_Y                      '\131'
#define CHAR_Z                      '\132'
#define CHAR_LEFT_SQUARE_BRACKET    '\133'
#define CHAR_BACKSLASH              '\134'
#define CHAR_RIGHT_SQUARE_BRACKET   '\135'
#define CHAR_CIRCUMFLEX_ACCENT      '\136'
#define CHAR_UNDERSCORE             '\137'
#define CHAR_GRAVE_ACCENT           '\140'
#define CHAR_a                      '\141'
#define CHAR_b                      '\142'
#define CHAR_c                      '\143'
#define CHAR_d                      '\144'
#define CHAR_e                      '\145'
#define CHAR_f                      '\146'
#define CHAR_g                      '\147'
#define CHAR_h                      '\150'
#define CHAR_i                      '\151'
#define CHAR_j                      '\152'
#define CHAR_k                      '\153'
#define CHAR_l                      '\154'
#define CHAR_m                      '\155'
#define CHAR_n                      '\156'
#define CHAR_o                      '\157'
#define CHAR_p                      '\160'
#define CHAR_q                      '\161'
#define CHAR_r                      '\162'
#define CHAR_s                      '\163'
#define CHAR_t                      '\164'
#define CHAR_u                      '\165'
#define CHAR_v                      '\166'
#define CHAR_w                      '\167'
#define CHAR_x                      '\170'
#define CHAR_y                      '\171'
#define CHAR_z                      '\172'
#define CHAR_LEFT_CURLY_BRACKET     '\173'
#define CHAR_VERTICAL_LINE          '\174'
#define CHAR_RIGHT_CURLY_BRACKET    '\175'
#define CHAR_TILDE                  '\176'
#define CHAR_NBSP                   ((unsigned char)'\xa0')

#define STR_HT                      "\011"
#define STR_VT                      "\013"
#define STR_FF                      "\014"
#define STR_CR                      "\015"
#define STR_NL                      "\012"
#define STR_BS                      "\010"
#define STR_BEL                     "\007"
#define STR_ESC                     "\033"
#define STR_DEL                     "\177"

#define STR_SPACE                   "\040"
#define STR_EXCLAMATION_MARK        "\041"
#define STR_QUOTATION_MARK          "\042"
#define STR_NUMBER_SIGN             "\043"
#define STR_DOLLAR_SIGN             "\044"
#define STR_PERCENT_SIGN            "\045"
#define STR_AMPERSAND               "\046"
#define STR_APOSTROPHE              "\047"
#define STR_LEFT_PARENTHESIS        "\050"
#define STR_RIGHT_PARENTHESIS       "\051"
#define STR_ASTERISK                "\052"
#define STR_PLUS                    "\053"
#define STR_COMMA                   "\054"
#define STR_MINUS                   "\055"
#define STR_DOT                     "\056"
#define STR_SLASH                   "\057"
#define STR_0                       "\060"
#define STR_1                       "\061"
#define STR_2                       "\062"
#define STR_3                       "\063"
#define STR_4                       "\064"
#define STR_5                       "\065"
#define STR_6                       "\066"
#define STR_7                       "\067"
#define STR_8                       "\070"
#define STR_9                       "\071"
#define STR_COLON                   "\072"
#define STR_SEMICOLON               "\073"
#define STR_LESS_THAN_SIGN          "\074"
#define STR_EQUALS_SIGN             "\075"
#define STR_GREATER_THAN_SIGN       "\076"
#define STR_QUESTION_MARK           "\077"
#define STR_COMMERCIAL_AT           "\100"
#define STR_A                       "\101"
#define STR_B                       "\102"
#define STR_C                       "\103"
#define STR_D                       "\104"
#define STR_E                       "\105"
#define STR_F                       "\106"
#define STR_G                       "\107"
#define STR_H                       "\110"
#define STR_I                       "\111"
#define STR_J                       "\112"
#define STR_K                       "\113"
#define STR_L                       "\114"
#define STR_M                       "\115"
#define STR_N                       "\116"
#define STR_O                       "\117"
#define STR_P                       "\120"
#define STR_Q                       "\121"
#define STR_R                       "\122"
#define STR_S                       "\123"
#define STR_T                       "\124"
#define STR_U                       "\125"
#define STR_V                       "\126"
#define STR_W                       "\127"
#define STR_X                       "\130"
#define STR_Y                       "\131"
#define STR_Z                       "\132"
#define STR_LEFT_SQUARE_BRACKET     "\133"
#define STR_BACKSLASH               "\134"
#define STR_RIGHT_SQUARE_BRACKET    "\135"
#define STR_CIRCUMFLEX_ACCENT       "\136"
#define STR_UNDERSCORE              "\137"
#define STR_GRAVE_ACCENT            "\140"
#define STR_a                       "\141"
#define STR_b                       "\142"
#define STR_c                       "\143"
#define STR_d                       "\144"
#define STR_e                       "\145"
#define STR_f                       "\146"
#define STR_g                       "\147"
#define STR_h                       "\150"
#define STR_i                       "\151"
#define STR_j                       "\152"
#define STR_k                       "\153"
#define STR_l                       "\154"
#define STR_m                       "\155"
#define STR_n                       "\156"
#define STR_o                       "\157"
#define STR_p                       "\160"
#define STR_q                       "\161"
#define STR_r                       "\162"
#define STR_s                       "\163"
#define STR_t                       "\164"
#define STR_u                       "\165"
#define STR_v                       "\166"
#define STR_w                       "\167"
#define STR_x                       "\170"
#define STR_y                       "\171"
#define STR_z                       "\172"
#define STR_LEFT_CURLY_BRACKET      "\173"
#define STR_VERTICAL_LINE           "\174"
#define STR_RIGHT_CURLY_BRACKET     "\175"
#define STR_TILDE                   "\176"

#define STRING_ACCEPT0              STR_A STR_C STR_C STR_E STR_P STR_T "\0"
#define STRING_COMMIT0              STR_C STR_O STR_M STR_M STR_I STR_T "\0"
#define STRING_F0                   STR_F "\0"
#define STRING_FAIL0                STR_F STR_A STR_I STR_L "\0"
#define STRING_MARK0                STR_M STR_A STR_R STR_K "\0"
#define STRING_PRUNE0               STR_P STR_R STR_U STR_N STR_E "\0"
#define STRING_SKIP0                STR_S STR_K STR_I STR_P "\0"
#define STRING_THEN                 STR_T STR_H STR_E STR_N

#define STRING_alpha0               STR_a STR_l STR_p STR_h STR_a "\0"
#define STRING_lower0               STR_l STR_o STR_w STR_e STR_r "\0"
#define STRING_upper0               STR_u STR_p STR_p STR_e STR_r "\0"
#define STRING_alnum0               STR_a STR_l STR_n STR_u STR_m "\0"
#define STRING_ascii0               STR_a STR_s STR_c STR_i STR_i "\0"
#define STRING_blank0               STR_b STR_l STR_a STR_n STR_k "\0"
#define STRING_cntrl0               STR_c STR_n STR_t STR_r STR_l "\0"
#define STRING_digit0               STR_d STR_i STR_g STR_i STR_t "\0"
#define STRING_graph0               STR_g STR_r STR_a STR_p STR_h "\0"
#define STRING_print0               STR_p STR_r STR_i STR_n STR_t "\0"
#define STRING_punct0               STR_p STR_u STR_n STR_c STR_t "\0"
#define STRING_space0               STR_s STR_p STR_a STR_c STR_e "\0"
#define STRING_word0                STR_w STR_o STR_r STR_d       "\0"
#define STRING_xdigit               STR_x STR_d STR_i STR_g STR_i STR_t

#define STRING_DEFINE               STR_D STR_E STR_F STR_I STR_N STR_E
#define STRING_WEIRD_STARTWORD      STR_LEFT_SQUARE_BRACKET STR_COLON STR_LESS_THAN_SIGN STR_COLON STR_RIGHT_SQUARE_BRACKET STR_RIGHT_SQUARE_BRACKET
#define STRING_WEIRD_ENDWORD        STR_LEFT_SQUARE_BRACKET STR_COLON STR_GREATER_THAN_SIGN STR_COLON STR_RIGHT_SQUARE_BRACKET STR_RIGHT_SQUARE_BRACKET

#define STRING_CR_RIGHTPAR              STR_C STR_R STR_RIGHT_PARENTHESIS
#define STRING_LF_RIGHTPAR              STR_L STR_F STR_RIGHT_PARENTHESIS
#define STRING_CRLF_RIGHTPAR            STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS
#define STRING_ANY_RIGHTPAR             STR_A STR_N STR_Y STR_RIGHT_PARENTHESIS
#define STRING_ANYCRLF_RIGHTPAR         STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS
#define STRING_BSR_ANYCRLF_RIGHTPAR     STR_B STR_S STR_R STR_UNDERSCORE STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS
#define STRING_BSR_UNICODE_RIGHTPAR     STR_B STR_S STR_R STR_UNDERSCORE STR_U STR_N STR_I STR_C STR_O STR_D STR_E STR_RIGHT_PARENTHESIS
#define STRING_UTF8_RIGHTPAR            STR_U STR_T STR_F STR_8 STR_RIGHT_PARENTHESIS
#define STRING_UTF16_RIGHTPAR           STR_U STR_T STR_F STR_1 STR_6 STR_RIGHT_PARENTHESIS
#define STRING_UTF32_RIGHTPAR           STR_U STR_T STR_F STR_3 STR_2 STR_RIGHT_PARENTHESIS
#define STRING_UTF_RIGHTPAR             STR_U STR_T STR_F STR_RIGHT_PARENTHESIS
#define STRING_UCP_RIGHTPAR             STR_U STR_C STR_P STR_RIGHT_PARENTHESIS
#define STRING_NO_AUTO_POSSESS_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_A STR_U STR_T STR_O STR_UNDERSCORE STR_P STR_O STR_S STR_S STR_E STR_S STR_S STR_RIGHT_PARENTHESIS
#define STRING_NO_START_OPT_RIGHTPAR    STR_N STR_O STR_UNDERSCORE STR_S STR_T STR_A STR_R STR_T STR_UNDERSCORE STR_O STR_P STR_T STR_RIGHT_PARENTHESIS
#define STRING_LIMIT_MATCH_EQ           STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_M STR_A STR_T STR_C STR_H STR_EQUALS_SIGN
#define STRING_LIMIT_RECURSION_EQ       STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_R STR_E STR_C STR_U STR_R STR_S STR_I STR_O STR_N STR_EQUALS_SIGN

#endif  /* SUPPORT_UTF */

/* Escape items that are just an encoding of a particular data value. */

#ifndef ESC_a
#define ESC_a CHAR_BEL
#endif

#ifndef ESC_e
#define ESC_e CHAR_ESC
#endif

#ifndef ESC_f
#define ESC_f CHAR_FF
#endif

#ifndef ESC_n
#define ESC_n CHAR_LF
#endif

#ifndef ESC_r
#define ESC_r CHAR_CR
#endif

/* We can't officially use ESC_t because it is a POSIX reserved identifier
(presumably because of all the others like size_t). */

#ifndef ESC_tee
#define ESC_tee CHAR_HT
#endif

/* Codes for different types of Unicode property */

#define PT_ANY        0    /* Any property - matches all chars */
#define PT_LAMP       1    /* L& - the union of Lu, Ll, Lt */
#define PT_GC         2    /* Specified general characteristic (e.g. L) */
#define PT_PC         3    /* Specified particular characteristic (e.g. Lu) */
#define PT_SC         4    /* Script (e.g. Han) */
#define PT_ALNUM      5    /* Alphanumeric - the union of L and N */
#define PT_SPACE      6    /* Perl space - Z plus 9,10,12,13 */
#define PT_PXSPACE    7    /* POSIX space - Z plus 9,10,11,12,13 */
#define PT_WORD       8    /* Word - L plus N plus underscore */
#define PT_CLIST      9    /* Pseudo-property: match character list */
#define PT_UCNC      10    /* Universal Character nameable character */
#define PT_TABSIZE   11    /* Size of square table for autopossessify tests */

/* The following special properties are used only in XCLASS items, when POSIX
classes are specified and PCRE_UCP is set - in other words, for Unicode
handling of these classes. They are not available via the \p or \P escapes like
those in the above list, and so they do not take part in the autopossessifying
table. */

#define PT_PXGRAPH   11    /* [:graph:] - characters that mark the paper */
#define PT_PXPRINT   12    /* [:print:] - [:graph:] plus non-control spaces */
#define PT_PXPUNCT   13    /* [:punct:] - punctuation characters */

/* Flag bits and data types for the extended class (OP_XCLASS) for classes that
contain characters with values greater than 255. */

#define XCL_NOT       0x01    /* Flag: this is a negative class */
#define XCL_MAP       0x02    /* Flag: a 32-byte map is present */
#define XCL_HASPROP   0x04    /* Flag: property checks are present. */

#define XCL_END       0    /* Marks end of individual items */
#define XCL_SINGLE    1    /* Single item (one multibyte char) follows */
#define XCL_RANGE     2    /* A range (two multibyte chars) follows */
#define XCL_PROP      3    /* Unicode property (2-byte property code follows) */
#define XCL_NOTPROP   4    /* Unicode inverted property (ditto) */

/* These are escaped items that aren't just an encoding of a particular data
value such as \n. They must have non-zero values, as check_escape() returns 0
for a data character.  Also, they must appear in the same order as in the
opcode definitions below, up to ESC_z. There's a dummy for OP_ALLANY because it
corresponds to "." in DOTALL mode rather than an escape sequence. It is also
used for [^] in JavaScript compatibility mode, and for \C in non-utf mode. In
non-DOTALL mode, "." behaves like \N.

The special values ESC_DU, ESC_du, etc. are used instead of ESC_D, ESC_d, etc.
when PCRE_UCP is set and replacement of \d etc by \p sequences is required.
They must be contiguous, and remain in order so that the replacements can be
looked up from a table.

Negative numbers are used to encode a backreference (\1, \2, \3, etc.) in
check_escape(). There are two tests in the code for an escape
greater than ESC_b and less than ESC_Z to detect the types that may be
repeated. These are the types that consume characters. If any new escapes are
put in between that don't consume a character, that code will have to change.
*/

enum { ESC_A = 1, ESC_G, ESC_K, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s,
       ESC_W, ESC_w, ESC_N, ESC_dum, ESC_C, ESC_P, ESC_p, ESC_R, ESC_H,
       ESC_h, ESC_V, ESC_v, ESC_X, ESC_Z, ESC_z,
       ESC_E, ESC_Q, ESC_g, ESC_k,
       ESC_DU, ESC_du, ESC_SU, ESC_su, ESC_WU, ESC_wu };


/********************** Opcode definitions ******************/

/****** NOTE NOTE NOTE ******

Starting from 1 (i.e. after OP_END), the values up to OP_EOD must correspond in
order to the list of escapes immediately above. Furthermore, values up to
OP_DOLLM must not be changed without adjusting the table called autoposstab in
pcre_compile.c

Whenever this list is updated, the two macro definitions that follow must be
updated to match. The possessification table called "opcode_possessify" in
pcre_compile.c must also be updated, and also the tables called "coptable"
and "poptable" in pcre_dfa_exec.c.

****** NOTE NOTE NOTE ******/


/* The values between FIRST_AUTOTAB_OP and LAST_AUTOTAB_RIGHT_OP, inclusive,
are used in a table for deciding whether a repeated character type can be
auto-possessified. */

#define FIRST_AUTOTAB_OP       OP_NOT_DIGIT
#define LAST_AUTOTAB_LEFT_OP   OP_EXTUNI
#define LAST_AUTOTAB_RIGHT_OP  OP_DOLLM

enum {
  OP_END,            /* 0 End of pattern */

  /* Values corresponding to backslashed metacharacters */

  OP_SOD,            /* 1 Start of data: \A */
  OP_SOM,            /* 2 Start of match (subject + offset): \G */
  OP_SET_SOM,        /* 3 Set start of match (\K) */
  OP_NOT_WORD_BOUNDARY,  /*  4 \B */
  OP_WORD_BOUNDARY,      /*  5 \b */
  OP_NOT_DIGIT,          /*  6 \D */
  OP_DIGIT,              /*  7 \d */
  OP_NOT_WHITESPACE,     /*  8 \S */
  OP_WHITESPACE,         /*  9 \s */
  OP_NOT_WORDCHAR,       /* 10 \W */
  OP_WORDCHAR,           /* 11 \w */

  OP_ANY,            /* 12 Match any character except newline (\N) */
  OP_ALLANY,         /* 13 Match any character */
  OP_ANYBYTE,        /* 14 Match any byte (\C); different to OP_ANY for UTF-8 */
  OP_NOTPROP,        /* 15 \P (not Unicode property) */
  OP_PROP,           /* 16 \p (Unicode property) */
  OP_ANYNL,          /* 17 \R (any newline sequence) */
  OP_NOT_HSPACE,     /* 18 \H (not horizontal whitespace) */
  OP_HSPACE,         /* 19 \h (horizontal whitespace) */
  OP_NOT_VSPACE,     /* 20 \V (not vertical whitespace) */
  OP_VSPACE,         /* 21 \v (vertical whitespace) */
  OP_EXTUNI,         /* 22 \X (extended Unicode sequence */
  OP_EODN,           /* 23 End of data or \n at end of data (\Z) */
  OP_EOD,            /* 24 End of data (\z) */

  /* Line end assertions */

  OP_DOLL,           /* 25 End of line - not multiline */
  OP_DOLLM,          /* 26 End of line - multiline */
  OP_CIRC,           /* 27 Start of line - not multiline */
  OP_CIRCM,          /* 28 Start of line - multiline */

  /* Single characters; caseful must precede the caseless ones */

  OP_CHAR,           /* 29 Match one character, casefully */
  OP_CHARI,          /* 30 Match one character, caselessly */
  OP_NOT,            /* 31 Match one character, not the given one, casefully */
  OP_NOTI,           /* 32 Match one character, not the given one, caselessly */

  /* The following sets of 13 opcodes must always be kept in step because
  the offset from the first one is used to generate the others. */

  /* Repeated characters; caseful must precede the caseless ones */

  OP_STAR,           /* 33 The maximizing and minimizing versions of */
  OP_MINSTAR,        /* 34 these six opcodes must come in pairs, with */
  OP_PLUS,           /* 35 the minimizing one second. */
  OP_MINPLUS,        /* 36 */
  OP_QUERY,          /* 37 */
  OP_MINQUERY,       /* 38 */

  OP_UPTO,           /* 39 From 0 to n matches of one character, caseful*/
  OP_MINUPTO,        /* 40 */
  OP_EXACT,          /* 41 Exactly n matches */

  OP_POSSTAR,        /* 42 Possessified star, caseful */
  OP_POSPLUS,        /* 43 Possessified plus, caseful */
  OP_POSQUERY,       /* 44 Posesssified query, caseful */
  OP_POSUPTO,        /* 45 Possessified upto, caseful */

  /* Repeated characters; caseless must follow the caseful ones */

  OP_STARI,          /* 46 */
  OP_MINSTARI,       /* 47 */
  OP_PLUSI,          /* 48 */
  OP_MINPLUSI,       /* 49 */
  OP_QUERYI,         /* 50 */
  OP_MINQUERYI,      /* 51 */

  OP_UPTOI,          /* 52 From 0 to n matches of one character, caseless */
  OP_MINUPTOI,       /* 53 */
  OP_EXACTI,         /* 54 */

  OP_POSSTARI,       /* 55 Possessified star, caseless */
  OP_POSPLUSI,       /* 56 Possessified plus, caseless */
  OP_POSQUERYI,      /* 57 Posesssified query, caseless */
  OP_POSUPTOI,       /* 58 Possessified upto, caseless */

  /* The negated ones must follow the non-negated ones, and match them */
  /* Negated repeated character, caseful; must precede the caseless ones */

  OP_NOTSTAR,        /* 59 The maximizing and minimizing versions of */
  OP_NOTMINSTAR,     /* 60 these six opcodes must come in pairs, with */
  OP_NOTPLUS,        /* 61 the minimizing one second. They must be in */
  OP_NOTMINPLUS,     /* 62 exactly the same order as those above. */
  OP_NOTQUERY,       /* 63 */
  OP_NOTMINQUERY,    /* 64 */

  OP_NOTUPTO,        /* 65 From 0 to n matches, caseful */
  OP_NOTMINUPTO,     /* 66 */
  OP_NOTEXACT,       /* 67 Exactly n matches */

  OP_NOTPOSSTAR,     /* 68 Possessified versions, caseful */
  OP_NOTPOSPLUS,     /* 69 */
  OP_NOTPOSQUERY,    /* 70 */
  OP_NOTPOSUPTO,     /* 71 */

  /* Negated repeated character, caseless; must follow the caseful ones */

  OP_NOTSTARI,       /* 72 */
  OP_NOTMINSTARI,    /* 73 */
  OP_NOTPLUSI,       /* 74 */
  OP_NOTMINPLUSI,    /* 75 */
  OP_NOTQUERYI,      /* 76 */
  OP_NOTMINQUERYI,   /* 77 */

  OP_NOTUPTOI,       /* 78 From 0 to n matches, caseless */
  OP_NOTMINUPTOI,    /* 79 */
  OP_NOTEXACTI,      /* 80 Exactly n matches */

  OP_NOTPOSSTARI,    /* 81 Possessified versions, caseless */
  OP_NOTPOSPLUSI,    /* 82 */
  OP_NOTPOSQUERYI,   /* 83 */
  OP_NOTPOSUPTOI,    /* 84 */

  /* Character types */

  OP_TYPESTAR,       /* 85 The maximizing and minimizing versions of */
  OP_TYPEMINSTAR,    /* 86 these six opcodes must come in pairs, with */
  OP_TYPEPLUS,       /* 87 the minimizing one second. These codes must */
  OP_TYPEMINPLUS,    /* 88 be in exactly the same order as those above. */
  OP_TYPEQUERY,      /* 89 */
  OP_TYPEMINQUERY,   /* 90 */

  OP_TYPEUPTO,       /* 91 From 0 to n matches */
  OP_TYPEMINUPTO,    /* 92 */
  OP_TYPEEXACT,      /* 93 Exactly n matches */

  OP_TYPEPOSSTAR,    /* 94 Possessified versions */
  OP_TYPEPOSPLUS,    /* 95 */
  OP_TYPEPOSQUERY,   /* 96 */
  OP_TYPEPOSUPTO,    /* 97 */

  /* These are used for character classes and back references; only the
  first six are the same as the sets above. */

  OP_CRSTAR,         /* 98 The maximizing and minimizing versions of */
  OP_CRMINSTAR,      /* 99 all these opcodes must come in pairs, with */
  OP_CRPLUS,         /* 100 the minimizing one second. These codes must */
  OP_CRMINPLUS,      /* 101 be in exactly the same order as those above. */
  OP_CRQUERY,        /* 102 */
  OP_CRMINQUERY,     /* 103 */

  OP_CRRANGE,        /* 104 These are different to the three sets above. */
  OP_CRMINRANGE,     /* 105 */

  OP_CRPOSSTAR,      /* 106 Possessified versions */
  OP_CRPOSPLUS,      /* 107 */
  OP_CRPOSQUERY,     /* 108 */
  OP_CRPOSRANGE,     /* 109 */

  /* End of quantifier opcodes */

  OP_CLASS,          /* 110 Match a character class, chars < 256 only */
  OP_NCLASS,         /* 111 Same, but the bitmap was created from a negative
                              class - the difference is relevant only when a
                              character > 255 is encountered. */
  OP_XCLASS,         /* 112 Extended class for handling > 255 chars within the
                              class. This does both positive and negative. */
  OP_REF,            /* 113 Match a back reference, casefully */
  OP_REFI,           /* 114 Match a back reference, caselessly */
  OP_DNREF,          /* 115 Match a duplicate name backref, casefully */
  OP_DNREFI,         /* 116 Match a duplicate name backref, caselessly */
  OP_RECURSE,        /* 117 Match a numbered subpattern (possibly recursive) */
  OP_CALLOUT,        /* 118 Call out to external function if provided */

  OP_ALT,            /* 119 Start of alternation */
  OP_KET,            /* 120 End of group that doesn't have an unbounded repeat */
  OP_KETRMAX,        /* 121 These two must remain together and in this */
  OP_KETRMIN,        /* 122 order. They are for groups the repeat for ever. */
  OP_KETRPOS,        /* 123 Possessive unlimited repeat. */

  /* The assertions must come before BRA, CBRA, ONCE, and COND, and the four
  asserts must remain in order. */

  OP_REVERSE,        /* 124 Move pointer back - used in lookbehind assertions */
  OP_ASSERT,         /* 125 Positive lookahead */
  OP_ASSERT_NOT,     /* 126 Negative lookahead */
  OP_ASSERTBACK,     /* 127 Positive lookbehind */
  OP_ASSERTBACK_NOT, /* 128 Negative lookbehind */

  /* ONCE, ONCE_NC, BRA, BRAPOS, CBRA, CBRAPOS, and COND must come immediately
  after the assertions, with ONCE first, as there's a test for >= ONCE for a
  subpattern that isn't an assertion. The POS versions must immediately follow
  the non-POS versions in each case. */

  OP_ONCE,           /* 129 Atomic group, contains captures */
  OP_ONCE_NC,        /* 130 Atomic group containing no captures */
  OP_BRA,            /* 131 Start of non-capturing bracket */
  OP_BRAPOS,         /* 132 Ditto, with unlimited, possessive repeat */
  OP_CBRA,           /* 133 Start of capturing bracket */
  OP_CBRAPOS,        /* 134 Ditto, with unlimited, possessive repeat */
  OP_COND,           /* 135 Conditional group */

  /* These five must follow the previous five, in the same order. There's a
  check for >= SBRA to distinguish the two sets. */

  OP_SBRA,           /* 136 Start of non-capturing bracket, check empty  */
  OP_SBRAPOS,        /* 137 Ditto, with unlimited, possessive repeat */
  OP_SCBRA,          /* 138 Start of capturing bracket, check empty */
  OP_SCBRAPOS,       /* 139 Ditto, with unlimited, possessive repeat */
  OP_SCOND,          /* 140 Conditional group, check empty */

  /* The next two pairs must (respectively) be kept together. */

  OP_CREF,           /* 141 Used to hold a capture number as condition */
  OP_DNCREF,         /* 142 Used to point to duplicate names as a condition */
  OP_RREF,           /* 143 Used to hold a recursion number as condition */
  OP_DNRREF,         /* 144 Used to point to duplicate names as a condition */
  OP_DEF,            /* 145 The DEFINE condition */

  OP_BRAZERO,        /* 146 These two must remain together and in this */
  OP_BRAMINZERO,     /* 147 order. */
  OP_BRAPOSZERO,     /* 148 */

  /* These are backtracking control verbs */

  OP_MARK,           /* 149 always has an argument */
  OP_PRUNE,          /* 150 */
  OP_PRUNE_ARG,      /* 151 same, but with argument */
  OP_SKIP,           /* 152 */
  OP_SKIP_ARG,       /* 153 same, but with argument */
  OP_THEN,           /* 154 */
  OP_THEN_ARG,       /* 155 same, but with argument */
  OP_COMMIT,         /* 156 */

  /* These are forced failure and success verbs */

  OP_FAIL,           /* 157 */
  OP_ACCEPT,         /* 158 */
  OP_ASSERT_ACCEPT,  /* 159 Used inside assertions */
  OP_CLOSE,          /* 160 Used before OP_ACCEPT to close open captures */

  /* This is used to skip a subpattern with a {0} quantifier */

  OP_SKIPZERO,       /* 161 */

  /* This is not an opcode, but is used to check that tables indexed by opcode
  are the correct length, in order to catch updating errors - there have been
  some in the past. */

  OP_TABLE_LENGTH
};

/* *** NOTE NOTE NOTE *** Whenever the list above is updated, the two macro
definitions that follow must also be updated to match. There are also tables
called "opcode_possessify" in pcre_compile.c and "coptable" and "poptable" in
pcre_dfa_exec.c that must be updated. */


/* This macro defines textual names for all the opcodes. These are used only
for debugging, and some of them are only partial names. The macro is referenced
only in pcre_printint.c, which fills out the full names in many cases (and in
some cases doesn't actually use these names at all). */

#define OP_NAME_LIST \
  "End", "\\A", "\\G", "\\K", "\\B", "\\b", "\\D", "\\d",         \
  "\\S", "\\s", "\\W", "\\w", "Any", "AllAny", "Anybyte",         \
  "notprop", "prop", "\\R", "\\H", "\\h", "\\V", "\\v",           \
  "extuni",  "\\Z", "\\z",                                        \
  "$", "$", "^", "^", "char", "chari", "not", "noti",             \
  "*", "*?", "+", "+?", "?", "??",                                \
  "{", "{", "{",                                                  \
  "*+","++", "?+", "{",                                           \
  "*", "*?", "+", "+?", "?", "??",                                \
  "{", "{", "{",                                                  \
  "*+","++", "?+", "{",                                           \
  "*", "*?", "+", "+?", "?", "??",                                \
  "{", "{", "{",                                                  \
  "*+","++", "?+", "{",                                           \
  "*", "*?", "+", "+?", "?", "??",                                \
  "{", "{", "{",                                                  \
  "*+","++", "?+", "{",                                           \
  "*", "*?", "+", "+?", "?", "??", "{", "{", "{",                 \
  "*+","++", "?+", "{",                                           \
  "*", "*?", "+", "+?", "?", "??", "{", "{",                      \
  "*+","++", "?+", "{",                                           \
  "class", "nclass", "xclass", "Ref", "Refi", "DnRef", "DnRefi",  \
  "Recurse", "Callout",                                           \
  "Alt", "Ket", "KetRmax", "KetRmin", "KetRpos",                  \
  "Reverse", "Assert", "Assert not", "AssertB", "AssertB not",    \
  "Once", "Once_NC",                                              \
  "Bra", "BraPos", "CBra", "CBraPos",                             \
  "Cond",                                                         \
  "SBra", "SBraPos", "SCBra", "SCBraPos",                         \
  "SCond",                                                        \
  "Cond ref", "Cond dnref", "Cond rec", "Cond dnrec", "Cond def", \
  "Brazero", "Braminzero", "Braposzero",                          \
  "*MARK", "*PRUNE", "*PRUNE", "*SKIP", "*SKIP",                  \
  "*THEN", "*THEN", "*COMMIT", "*FAIL",                           \
  "*ACCEPT", "*ASSERT_ACCEPT",                                    \
  "Close", "Skip zero"


/* This macro defines the length of fixed length operations in the compiled
regex. The lengths are used when searching for specific things, and also in the
debugging printing of a compiled regex. We use a macro so that it can be
defined close to the definitions of the opcodes themselves.

As things have been extended, some of these are no longer fixed lenths, but are
minima instead. For example, the length of a single-character repeat may vary
in UTF-8 mode. The code that uses this table must know about such things. */

#define OP_LENGTHS \
  1,                             /* End                                    */ \
  1, 1, 1, 1, 1,                 /* \A, \G, \K, \B, \b                     */ \
  1, 1, 1, 1, 1, 1,              /* \D, \d, \S, \s, \W, \w                 */ \
  1, 1, 1,                       /* Any, AllAny, Anybyte                   */ \
  3, 3,                          /* \P, \p                                 */ \
  1, 1, 1, 1, 1,                 /* \R, \H, \h, \V, \v                     */ \
  1,                             /* \X                                     */ \
  1, 1, 1, 1, 1, 1,              /* \Z, \z, $, $M ^, ^M                    */ \
  2,                             /* Char  - the minimum length             */ \
  2,                             /* Chari  - the minimum length            */ \
  2,                             /* not                                    */ \
  2,                             /* noti                                   */ \
  /* Positive single-char repeats                             ** These are */ \
  2, 2, 2, 2, 2, 2,              /* *, *?, +, +?, ?, ??       ** minima in */ \
  2+IMM2_SIZE, 2+IMM2_SIZE,      /* upto, minupto             ** mode      */ \
  2+IMM2_SIZE,                   /* exact                                  */ \
  2, 2, 2, 2+IMM2_SIZE,          /* *+, ++, ?+, upto+                      */ \
  2, 2, 2, 2, 2, 2,              /* *I, *?I, +I, +?I, ?I, ??I ** UTF-8     */ \
  2+IMM2_SIZE, 2+IMM2_SIZE,      /* upto I, minupto I                      */ \
  2+IMM2_SIZE,                   /* exact I                                */ \
  2, 2, 2, 2+IMM2_SIZE,          /* *+I, ++I, ?+I, upto+I                  */ \
  /* Negative single-char repeats - only for chars < 256                   */ \
  2, 2, 2, 2, 2, 2,              /* NOT *, *?, +, +?, ?, ??                */ \
  2+IMM2_SIZE, 2+IMM2_SIZE,      /* NOT upto, minupto                      */ \
  2+IMM2_SIZE,                   /* NOT exact                              */ \
  2, 2, 2, 2+IMM2_SIZE,          /* Possessive NOT *, +, ?, upto           */ \
  2, 2, 2, 2, 2, 2,              /* NOT *I, *?I, +I, +?I, ?I, ??I          */ \
  2+IMM2_SIZE, 2+IMM2_SIZE,      /* NOT upto I, minupto I                  */ \
  2+IMM2_SIZE,                   /* NOT exact I                            */ \
  2, 2, 2, 2+IMM2_SIZE,          /* Possessive NOT *I, +I, ?I, upto I      */ \
  /* Positive type repeats                                                 */ \
  2, 2, 2, 2, 2, 2,              /* Type *, *?, +, +?, ?, ??               */ \
  2+IMM2_SIZE, 2+IMM2_SIZE,      /* Type upto, minupto                     */ \
  2+IMM2_SIZE,                   /* Type exact                             */ \
  2, 2, 2, 2+IMM2_SIZE,          /* Possessive *+, ++, ?+, upto+           */ \
  /* Character class & ref repeats                                         */ \
  1, 1, 1, 1, 1, 1,              /* *, *?, +, +?, ?, ??                    */ \
  1+2*IMM2_SIZE, 1+2*IMM2_SIZE,  /* CRRANGE, CRMINRANGE                    */ \
  1, 1, 1, 1+2*IMM2_SIZE,        /* Possessive *+, ++, ?+, CRPOSRANGE      */ \
  1+(32/sizeof(pcre_uchar)),     /* CLASS                                  */ \
  1+(32/sizeof(pcre_uchar)),     /* NCLASS                                 */ \
  0,                             /* XCLASS - variable length               */ \
  1+IMM2_SIZE,                   /* REF                                    */ \
  1+IMM2_SIZE,                   /* REFI                                   */ \
  1+2*IMM2_SIZE,                 /* DNREF                                  */ \
  1+2*IMM2_SIZE,                 /* DNREFI                                 */ \
  1+LINK_SIZE,                   /* RECURSE                                */ \
  2+2*LINK_SIZE,                 /* CALLOUT                                */ \
  1+LINK_SIZE,                   /* Alt                                    */ \
  1+LINK_SIZE,                   /* Ket                                    */ \
  1+LINK_SIZE,                   /* KetRmax                                */ \
  1+LINK_SIZE,                   /* KetRmin                                */ \
  1+LINK_SIZE,                   /* KetRpos                                */ \
  1+LINK_SIZE,                   /* Reverse                                */ \
  1+LINK_SIZE,                   /* Assert                                 */ \
  1+LINK_SIZE,                   /* Assert not                             */ \
  1+LINK_SIZE,                   /* Assert behind                          */ \
  1+LINK_SIZE,                   /* Assert behind not                      */ \
  1+LINK_SIZE,                   /* ONCE                                   */ \
  1+LINK_SIZE,                   /* ONCE_NC                                */ \
  1+LINK_SIZE,                   /* BRA                                    */ \
  1+LINK_SIZE,                   /* BRAPOS                                 */ \
  1+LINK_SIZE+IMM2_SIZE,         /* CBRA                                   */ \
  1+LINK_SIZE+IMM2_SIZE,         /* CBRAPOS                                */ \
  1+LINK_SIZE,                   /* COND                                   */ \
  1+LINK_SIZE,                   /* SBRA                                   */ \
  1+LINK_SIZE,                   /* SBRAPOS                                */ \
  1+LINK_SIZE+IMM2_SIZE,         /* SCBRA                                  */ \
  1+LINK_SIZE+IMM2_SIZE,         /* SCBRAPOS                               */ \
  1+LINK_SIZE,                   /* SCOND                                  */ \
  1+IMM2_SIZE, 1+2*IMM2_SIZE,    /* CREF, DNCREF                           */ \
  1+IMM2_SIZE, 1+2*IMM2_SIZE,    /* RREF, DNRREF                           */ \
  1,                             /* DEF                                    */ \
  1, 1, 1,                       /* BRAZERO, BRAMINZERO, BRAPOSZERO        */ \
  3, 1, 3,                       /* MARK, PRUNE, PRUNE_ARG                 */ \
  1, 3,                          /* SKIP, SKIP_ARG                         */ \
  1, 3,                          /* THEN, THEN_ARG                         */ \
  1, 1, 1, 1,                    /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT    */ \
  1+IMM2_SIZE, 1                 /* CLOSE, SKIPZERO                        */

/* A magic value for OP_RREF to indicate the "any recursion" condition. */

#define RREF_ANY  0xffff

/* Compile time error code numbers. They are given names so that they can more
easily be tracked. When a new number is added, the table called eint in
pcreposix.c must be updated. */

enum { ERR0,  ERR1,  ERR2,  ERR3,  ERR4,  ERR5,  ERR6,  ERR7,  ERR8,  ERR9,
       ERR10, ERR11, ERR12, ERR13, ERR14, ERR15, ERR16, ERR17, ERR18, ERR19,
       ERR20, ERR21, ERR22, ERR23, ERR24, ERR25, ERR26, ERR27, ERR28, ERR29,
       ERR30, ERR31, ERR32, ERR33, ERR34, ERR35, ERR36, ERR37, ERR38, ERR39,
       ERR40, ERR41, ERR42, ERR43, ERR44, ERR45, ERR46, ERR47, ERR48, ERR49,
       ERR50, ERR51, ERR52, ERR53, ERR54, ERR55, ERR56, ERR57, ERR58, ERR59,
       ERR60, ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68, ERR69,
       ERR70, ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, ERR77, ERR78, ERR79,
       ERR80, ERR81, ERR82, ERR83, ERR84, ERR85, ERR86, ERR87, ERRCOUNT };

/* JIT compiling modes. The function list is indexed by them. */

enum { JIT_COMPILE, JIT_PARTIAL_SOFT_COMPILE, JIT_PARTIAL_HARD_COMPILE,
       JIT_NUMBER_OF_COMPILE_MODES };

/* The real format of the start of the pcre block; the index of names and the
code vector run on as long as necessary after the end. We store an explicit
offset to the name table so that if a regex is compiled on one host, saved, and
then run on another where the size of pointers is different, all might still
be well.

The size of the structure must be a multiple of 8 bytes. For the case of
compiled-on-4 and run-on-8, we include an extra pointer that is always NULL so
that there are an even number of pointers which therefore are a multiple of 8
bytes.

It is necessary to fork the struct for the 32 bit library, since it needs to
use pcre_uint32 for first_char and req_char. We can't put an ifdef inside the
typedef because pcretest needs access to the struct of the 8-, 16- and 32-bit
variants.

*** WARNING ***
When new fields are added to these structures, remember to adjust the code in
pcre_byte_order.c that is concerned with swapping the byte order of the fields
when a compiled regex is reloaded on a host with different endianness.
*** WARNING ***
There is also similar byte-flipping code in pcretest.c, which is used for
testing the byte-flipping features. It must also be kept in step.
*** WARNING ***
*/

typedef struct real_pcre8_or_16 {
  pcre_uint32 magic_number;
  pcre_uint32 size;               /* Total that was malloced */
  pcre_uint32 options;            /* Public options */
  pcre_uint32 flags;              /* Private flags */
  pcre_uint32 limit_match;        /* Limit set from regex */
  pcre_uint32 limit_recursion;    /* Limit set from regex */
  pcre_uint16 first_char;         /* Starting character */
  pcre_uint16 req_char;           /* This character must be seen */
  pcre_uint16 max_lookbehind;     /* Longest lookbehind (characters) */
  pcre_uint16 top_bracket;        /* Highest numbered group */
  pcre_uint16 top_backref;        /* Highest numbered back reference */
  pcre_uint16 name_table_offset;  /* Offset to name table that follows */
  pcre_uint16 name_entry_size;    /* Size of any name items */
  pcre_uint16 name_count;         /* Number of name items */
  pcre_uint16 ref_count;          /* Reference count */
  pcre_uint16 dummy1;             /* To ensure size is a multiple of 8 */
  pcre_uint16 dummy2;             /* To ensure size is a multiple of 8 */
  pcre_uint16 dummy3;             /* To ensure size is a multiple of 8 */
  const pcre_uint8 *tables;       /* Pointer to tables or NULL for std */
  void             *nullpad;      /* NULL padding */
} real_pcre8_or_16;

typedef struct real_pcre8_or_16 real_pcre;
typedef struct real_pcre8_or_16 real_pcre16;

typedef struct real_pcre32 {
  pcre_uint32 magic_number;
  pcre_uint32 size;               /* Total that was malloced */
  pcre_uint32 options;            /* Public options */
  pcre_uint32 flags;              /* Private flags */
  pcre_uint32 limit_match;        /* Limit set from regex */
  pcre_uint32 limit_recursion;    /* Limit set from regex */
  pcre_uint32 first_char;         /* Starting character */
  pcre_uint32 req_char;           /* This character must be seen */
  pcre_uint16 max_lookbehind;     /* Longest lookbehind (characters) */
  pcre_uint16 top_bracket;        /* Highest numbered group */
  pcre_uint16 top_backref;        /* Highest numbered back reference */
  pcre_uint16 name_table_offset;  /* Offset to name table that follows */
  pcre_uint16 name_entry_size;    /* Size of any name items */
  pcre_uint16 name_count;         /* Number of name items */
  pcre_uint16 ref_count;          /* Reference count */
  pcre_uint16 dummy;              /* To ensure size is a multiple of 8 */
  const pcre_uint8 *tables;       /* Pointer to tables or NULL for std */
  void             *nullpad;      /* NULL padding */
} real_pcre32;

#if defined COMPILE_PCRE8
#define REAL_PCRE real_pcre
#elif defined COMPILE_PCRE16
#define REAL_PCRE real_pcre16
#elif defined COMPILE_PCRE32
#define REAL_PCRE real_pcre32
#endif

/* Assert that the size of REAL_PCRE is divisible by 8 */
typedef int __assert_real_pcre_size_divisible_8[(sizeof(REAL_PCRE) % 8) == 0 ? 1 : -1];

/* Needed in pcretest to access some fields in the real_pcre* structures
 * directly. They're unified for 8/16/32 bits since the structs only differ
 * after these fields; if that ever changes, need to fork those defines into
 * 8/16 and 32 bit versions. */
#define REAL_PCRE_MAGIC(re)     (((REAL_PCRE*)re)->magic_number)
#define REAL_PCRE_SIZE(re)      (((REAL_PCRE*)re)->size)
#define REAL_PCRE_OPTIONS(re)   (((REAL_PCRE*)re)->options)
#define REAL_PCRE_FLAGS(re)     (((REAL_PCRE*)re)->flags)

/* The format of the block used to store data from pcre_study(). The same
remark (see NOTE above) about extending this structure applies. */

typedef struct pcre_study_data {
  pcre_uint32 size;               /* Total that was malloced */
  pcre_uint32 flags;              /* Private flags */
  pcre_uint8 start_bits[32];      /* Starting char bits */
  pcre_uint32 minlength;          /* Minimum subject length */
} pcre_study_data;

/* Structure for building a chain of open capturing subpatterns during
compiling, so that instructions to close them can be compiled when (*ACCEPT) is
encountered. This is also used to identify subpatterns that contain recursive
back references to themselves, so that they can be made atomic. */

typedef struct open_capitem {
  struct open_capitem *next;    /* Chain link */
  pcre_uint16 number;           /* Capture number */
  pcre_uint16 flag;             /* Set TRUE if recursive back ref */
} open_capitem;

/* Structure for building a list of named groups during the first pass of
compiling. */

typedef struct named_group {
  const pcre_uchar  *name;          /* Points to the name in the pattern */
  int                length;        /* Length of the name */
  pcre_uint32        number;        /* Group number */
} named_group;

/* Structure for passing "static" information around between the functions
doing the compiling, so that they are thread-safe. */

typedef struct compile_data {
  const pcre_uint8 *lcc;            /* Points to lower casing table */
  const pcre_uint8 *fcc;            /* Points to case-flipping table */
  const pcre_uint8 *cbits;          /* Points to character type table */
  const pcre_uint8 *ctypes;         /* Points to table of type maps */
  const pcre_uchar *start_workspace;/* The start of working space */
  const pcre_uchar *start_code;     /* The start of the compiled code */
  const pcre_uchar *start_pattern;  /* The start of the pattern */
  const pcre_uchar *end_pattern;    /* The end of the pattern */
  pcre_uchar *hwm;                  /* High watermark of workspace */
  open_capitem *open_caps;          /* Chain of open capture items */
  named_group *named_groups;        /* Points to vector in pre-compile */
  pcre_uchar *name_table;           /* The name/number table */
  int  names_found;                 /* Number of entries so far */
  int  name_entry_size;             /* Size of each entry */
  int  named_group_list_size;       /* Number of entries in the list */
  int  workspace_size;              /* Size of workspace */
  unsigned int bracount;            /* Count of capturing parens as we compile */
  int  final_bracount;              /* Saved value after first pass */
  int  max_lookbehind;              /* Maximum lookbehind (characters) */
  int  top_backref;                 /* Maximum back reference */
  unsigned int backref_map;         /* Bitmap of low back refs */
  unsigned int namedrefcount;       /* Number of backreferences by name */
  int  parens_depth;                /* Depth of nested parentheses */
  int  assert_depth;                /* Depth of nested assertions */
  pcre_uint32 external_options;     /* External (initial) options */
  pcre_uint32 external_flags;       /* External flag bits to be set */
  int  req_varyopt;                 /* "After variable item" flag for reqbyte */
  BOOL had_accept;                  /* (*ACCEPT) encountered */
  BOOL had_pruneorskip;             /* (*PRUNE) or (*SKIP) encountered */
  BOOL check_lookbehind;            /* Lookbehinds need later checking */
  BOOL dupnames;                    /* Duplicate names exist */
  BOOL dupgroups;                   /* Duplicate groups exist: (?| found */
  BOOL iscondassert;                /* Next assert is a condition */
  int  nltype;                      /* Newline type */
  int  nllen;                       /* Newline string length */
  pcre_uchar nl[4];                 /* Newline string when fixed length */
} compile_data;

/* Structure for maintaining a chain of pointers to the currently incomplete
branches, for testing for left recursion while compiling. */

typedef struct branch_chain {
  struct branch_chain *outer;
  pcre_uchar *current_branch;
} branch_chain;

/* Structure for mutual recursion detection. */

typedef struct recurse_check {
  struct recurse_check *prev;
  const pcre_uchar *group;
} recurse_check;

/* Structure for items in a linked list that represents an explicit recursive
call within the pattern; used by pcre_exec(). */

typedef struct recursion_info {
  struct recursion_info *prevrec; /* Previous recursion record (or NULL) */
  unsigned int group_num;         /* Number of group that was called */
  int *offset_save;               /* Pointer to start of saved offsets */
  int saved_max;                  /* Number of saved offsets */
  int saved_capture_last;         /* Last capture number */
  PCRE_PUCHAR subject_position;   /* Position at start of recursion */
} recursion_info;

/* A similar structure for pcre_dfa_exec(). */

typedef struct dfa_recursion_info {
  struct dfa_recursion_info *prevrec;
  int group_num;
  PCRE_PUCHAR subject_position;
} dfa_recursion_info;

/* Structure for building a chain of data for holding the values of the subject
pointer at the start of each subpattern, so as to detect when an empty string
has been matched by a subpattern - to break infinite loops; used by
pcre_exec(). */

typedef struct eptrblock {
  struct eptrblock *epb_prev;
  PCRE_PUCHAR epb_saved_eptr;
} eptrblock;


/* Structure for passing "static" information around between the functions
doing traditional NFA matching, so that they are thread-safe. */

typedef struct match_data {
  unsigned long int match_call_count;      /* As it says */
  unsigned long int match_limit;           /* As it says */
  unsigned long int match_limit_recursion; /* As it says */
  int   *offset_vector;           /* Offset vector */
  int    offset_end;              /* One past the end */
  int    offset_max;              /* The maximum usable for return data */
  int    nltype;                  /* Newline type */
  int    nllen;                   /* Newline string length */
  int    name_count;              /* Number of names in name table */
  int    name_entry_size;         /* Size of entry in names table */
  unsigned int skip_arg_count;    /* For counting SKIP_ARGs */
  unsigned int ignore_skip_arg;   /* For re-run when SKIP arg name not found */
  pcre_uchar *name_table;         /* Table of names */
  pcre_uchar nl[4];               /* Newline string when fixed */
  const  pcre_uint8 *lcc;         /* Points to lower casing table */
  const  pcre_uint8 *fcc;         /* Points to case-flipping table */
  const  pcre_uint8 *ctypes;      /* Points to table of type maps */
  BOOL   notbol;                  /* NOTBOL flag */
  BOOL   noteol;                  /* NOTEOL flag */
  BOOL   utf;                     /* UTF-8 / UTF-16 flag */
  BOOL   jscript_compat;          /* JAVASCRIPT_COMPAT flag */
  BOOL   use_ucp;                 /* PCRE_UCP flag */
  BOOL   endonly;                 /* Dollar not before final \n */
  BOOL   notempty;                /* Empty string match not wanted */
  BOOL   notempty_atstart;        /* Empty string match at start not wanted */
  BOOL   hitend;                  /* Hit the end of the subject at some point */
  BOOL   bsr_anycrlf;             /* \R is just any CRLF, not full Unicode */
  BOOL   hasthen;                 /* Pattern contains (*THEN) */
  const  pcre_uchar *start_code;  /* For use when recursing */
  PCRE_PUCHAR start_subject;      /* Start of the subject string */
  PCRE_PUCHAR end_subject;        /* End of the subject string */
  PCRE_PUCHAR start_match_ptr;    /* Start of matched string */
  PCRE_PUCHAR end_match_ptr;      /* Subject position at end match */
  PCRE_PUCHAR start_used_ptr;     /* Earliest consulted character */
  int    partial;                 /* PARTIAL options */
  int    end_offset_top;          /* Highwater mark at end of match */
  pcre_int32 capture_last;        /* Most recent capture number + overflow flag */
  int    start_offset;            /* The start offset value */
  int    match_function_type;     /* Set for certain special calls of MATCH() */
  eptrblock *eptrchain;           /* Chain of eptrblocks for tail recursions */
  int    eptrn;                   /* Next free eptrblock */
  recursion_info *recursive;      /* Linked list of recursion data */
  void  *callout_data;            /* To pass back to callouts */
  const  pcre_uchar *mark;        /* Mark pointer to pass back on success */
  const  pcre_uchar *nomatch_mark;/* Mark pointer to pass back on failure */
  const  pcre_uchar *once_target; /* Where to back up to for atomic groups */
#ifdef NO_RECURSE
  void  *match_frames_base;       /* For remembering malloc'd frames */
#endif
} match_data;

/* A similar structure is used for the same purpose by the DFA matching
functions. */

typedef struct dfa_match_data {
  const pcre_uchar *start_code;     /* Start of the compiled pattern */
  const pcre_uchar *start_subject ; /* Start of the subject string */
  const pcre_uchar *end_subject;    /* End of subject string */
  const pcre_uchar *start_used_ptr; /* Earliest consulted character */
  const pcre_uint8 *tables;         /* Character tables */
  int   start_offset;               /* The start offset value */
  int   moptions;                   /* Match options */
  int   poptions;                   /* Pattern options */
  int   nltype;                     /* Newline type */
  int   nllen;                      /* Newline string length */
  pcre_uchar nl[4];                 /* Newline string when fixed */
  void *callout_data;               /* To pass back to callouts */
  dfa_recursion_info *recursive;    /* Linked list of recursion data */
} dfa_match_data;

/* Bit definitions for entries in the pcre_ctypes table. */

#define ctype_space   0x01
#define ctype_letter  0x02
#define ctype_digit   0x04
#define ctype_xdigit  0x08
#define ctype_word    0x10   /* alphanumeric or '_' */
#define ctype_meta    0x80   /* regexp meta char or zero (end pattern) */

/* Offsets for the bitmap tables in pcre_cbits. Each table contains a set
of bits for a class map. Some classes are built by combining these tables. */

#define cbit_space     0      /* [:space:] or \s */
#define cbit_xdigit   32      /* [:xdigit:] */
#define cbit_digit    64      /* [:digit:] or \d */
#define cbit_upper    96      /* [:upper:] */
#define cbit_lower   128      /* [:lower:] */
#define cbit_word    160      /* [:word:] or \w */
#define cbit_graph   192      /* [:graph:] */
#define cbit_print   224      /* [:print:] */
#define cbit_punct   256      /* [:punct:] */
#define cbit_cntrl   288      /* [:cntrl:] */
#define cbit_length  320      /* Length of the cbits table */

/* Offsets of the various tables from the base tables pointer, and
total length. */

#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)

/* Internal function and data prefixes. */

#if defined COMPILE_PCRE8
#ifndef PUBL
#define PUBL(name) pcre_##name
#endif
#ifndef PRIV
#define PRIV(name) _pcre_##name
#endif
#elif defined COMPILE_PCRE16
#ifndef PUBL
#define PUBL(name) pcre16_##name
#endif
#ifndef PRIV
#define PRIV(name) _pcre16_##name
#endif
#elif defined COMPILE_PCRE32
#ifndef PUBL
#define PUBL(name) pcre32_##name
#endif
#ifndef PRIV
#define PRIV(name) _pcre32_##name
#endif
#else
#error Unsupported compiling mode
#endif /* COMPILE_PCRE[8|16|32] */

/* Layout of the UCP type table that translates property names into types and
codes. Each entry used to point directly to a name, but to reduce the number of
relocations in shared libraries, it now has an offset into a single string
instead. */

typedef struct {
  pcre_uint16 name_offset;
  pcre_uint16 type;
  pcre_uint16 value;
} ucp_type_table;


/* Internal shared data tables. These are tables that are used by more than one
of the exported public functions. They have to be "external" in the C sense,
but are not part of the PCRE public API. The data for these tables is in the
pcre_tables.c module. */

#ifdef COMPILE_PCRE8
extern const int            PRIV(utf8_table1)[];
extern const int            PRIV(utf8_table1_size);
extern const int            PRIV(utf8_table2)[];
extern const int            PRIV(utf8_table3)[];
extern const pcre_uint8     PRIV(utf8_table4)[];
#endif /* COMPILE_PCRE8 */

extern const char           PRIV(utt_names)[];
extern const ucp_type_table PRIV(utt)[];
extern const int            PRIV(utt_size);

extern const pcre_uint8     PRIV(OP_lengths)[];
extern const pcre_uint8     PRIV(default_tables)[];

extern const pcre_uint32    PRIV(hspace_list)[];
extern const pcre_uint32    PRIV(vspace_list)[];


/* Internal shared functions. These are functions that are used by more than
one of the exported public functions. They have to be "external" in the C
sense, but are not part of the PCRE public API. */

/* String comparison functions. */
#if defined COMPILE_PCRE8

#define STRCMP_UC_UC(str1, str2) \
  strcmp((char *)(str1), (char *)(str2))
#define STRCMP_UC_C8(str1, str2) \
  strcmp((char *)(str1), (str2))
#define STRNCMP_UC_UC(str1, str2, num) \
  strncmp((char *)(str1), (char *)(str2), (num))
#define STRNCMP_UC_C8(str1, str2, num) \
  strncmp((char *)(str1), (str2), (num))
#define STRLEN_UC(str) strlen((const char *)str)

#elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32

extern int               PRIV(strcmp_uc_uc)(const pcre_uchar *,
                           const pcre_uchar *);
extern int               PRIV(strcmp_uc_c8)(const pcre_uchar *,
                           const char *);
extern int               PRIV(strncmp_uc_uc)(const pcre_uchar *,
                           const pcre_uchar *, unsigned int num);
extern int               PRIV(strncmp_uc_c8)(const pcre_uchar *,
                           const char *, unsigned int num);
extern unsigned int      PRIV(strlen_uc)(const pcre_uchar *str);

#define STRCMP_UC_UC(str1, str2) \
  PRIV(strcmp_uc_uc)((str1), (str2))
#define STRCMP_UC_C8(str1, str2) \
  PRIV(strcmp_uc_c8)((str1), (str2))
#define STRNCMP_UC_UC(str1, str2, num) \
  PRIV(strncmp_uc_uc)((str1), (str2), (num))
#define STRNCMP_UC_C8(str1, str2, num) \
  PRIV(strncmp_uc_c8)((str1), (str2), (num))
#define STRLEN_UC(str) PRIV(strlen_uc)(str)

#endif /* COMPILE_PCRE[8|16|32] */

#if defined COMPILE_PCRE8 || defined COMPILE_PCRE16

#define STRCMP_UC_UC_TEST(str1, str2) STRCMP_UC_UC(str1, str2)
#define STRCMP_UC_C8_TEST(str1, str2) STRCMP_UC_C8(str1, str2)

#elif defined COMPILE_PCRE32

extern int               PRIV(strcmp_uc_uc_utf)(const pcre_uchar *,
                           const pcre_uchar *);
extern int               PRIV(strcmp_uc_c8_utf)(const pcre_uchar *,
                           const char *);

#define STRCMP_UC_UC_TEST(str1, str2) \
  (utf ? PRIV(strcmp_uc_uc_utf)((str1), (str2)) : PRIV(strcmp_uc_uc)((str1), (str2)))
#define STRCMP_UC_C8_TEST(str1, str2) \
  (utf ? PRIV(strcmp_uc_c8_utf)((str1), (str2)) : PRIV(strcmp_uc_c8)((str1), (str2)))

#endif /* COMPILE_PCRE[8|16|32] */

extern const pcre_uchar *PRIV(find_bracket)(const pcre_uchar *, BOOL, int);
extern BOOL              PRIV(is_newline)(PCRE_PUCHAR, int, PCRE_PUCHAR,
                           int *, BOOL);
extern unsigned int      PRIV(ord2utf)(pcre_uint32, pcre_uchar *);
extern int               PRIV(valid_utf)(PCRE_PUCHAR, int, int *);
extern BOOL              PRIV(was_newline)(PCRE_PUCHAR, int, PCRE_PUCHAR,
                           int *, BOOL);
extern BOOL              PRIV(xclass)(pcre_uint32, const pcre_uchar *, BOOL);

#ifdef SUPPORT_JIT
extern void              PRIV(jit_compile)(const REAL_PCRE *,
                           PUBL(extra) *, int);
extern int               PRIV(jit_exec)(const PUBL(extra) *,
                           const pcre_uchar *, int, int, int, int *, int);
extern void              PRIV(jit_free)(void *);
extern int               PRIV(jit_get_size)(void *);
extern const char*       PRIV(jit_get_target)(void);
#endif

/* Unicode character database (UCD) */

typedef struct {
  pcre_uint8 script;     /* ucp_Arabic, etc. */
  pcre_uint8 chartype;   /* ucp_Cc, etc. (general categories) */
  pcre_uint8 gbprop;     /* ucp_gbControl, etc. (grapheme break property) */
  pcre_uint8 caseset;    /* offset to multichar other cases or zero */
  pcre_int32 other_case; /* offset to other case, or zero if none */
} ucd_record;

extern const pcre_uint32 PRIV(ucd_caseless_sets)[];
extern const ucd_record  PRIV(ucd_records)[];
extern const pcre_uint8  PRIV(ucd_stage1)[];
extern const pcre_uint16 PRIV(ucd_stage2)[];
extern const pcre_uint32 PRIV(ucp_gentype)[];
extern const pcre_uint32 PRIV(ucp_gbtable)[];
#ifdef COMPILE_PCRE32
extern const ucd_record  PRIV(dummy_ucd_record)[];
#endif
#ifdef SUPPORT_JIT
extern const int         PRIV(ucp_typerange)[];
#endif

#ifdef SUPPORT_UCP
/* UCD access macros */

#define UCD_BLOCK_SIZE 128
#define REAL_GET_UCD(ch) (PRIV(ucd_records) + \
        PRIV(ucd_stage2)[PRIV(ucd_stage1)[(int)(ch) / UCD_BLOCK_SIZE] * \
        UCD_BLOCK_SIZE + (int)(ch) % UCD_BLOCK_SIZE])

#ifdef COMPILE_PCRE32
#define GET_UCD(ch) ((ch > 0x10ffff)? PRIV(dummy_ucd_record) : REAL_GET_UCD(ch))
#else
#define GET_UCD(ch) REAL_GET_UCD(ch)
#endif

#define UCD_CHARTYPE(ch)    GET_UCD(ch)->chartype
#define UCD_SCRIPT(ch)      GET_UCD(ch)->script
#define UCD_CATEGORY(ch)    PRIV(ucp_gentype)[UCD_CHARTYPE(ch)]
#define UCD_GRAPHBREAK(ch)  GET_UCD(ch)->gbprop
#define UCD_CASESET(ch)     GET_UCD(ch)->caseset
#define UCD_OTHERCASE(ch)   ((pcre_uint32)((int)ch + (int)(GET_UCD(ch)->other_case)))

#endif /* SUPPORT_UCP */

#endif

/* End of pcre_internal.h */
php/ext/pcre/pcrelib/pcreposix.h000064400000012514151730540360012700 0ustar00/*************************************************
*       Perl-Compatible Regular Expressions      *
*************************************************/

#ifndef _PCREPOSIX_H
#define _PCREPOSIX_H

/* This is the header for the POSIX wrapper interface to the PCRE Perl-
Compatible Regular Expression library. It defines the things POSIX says should
be there. I hope.

            Copyright (c) 1997-2012 University of Cambridge

-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice,
      this list of conditions and the following disclaimer.

    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.

    * Neither the name of the University of Cambridge nor the names of its
      contributors may be used to endorse or promote products derived from
      this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-----------------------------------------------------------------------------
*/

/* Have to include stdlib.h in order to ensure that size_t is defined. */

#include <stdlib.h>

/* Allow for C++ users */

#ifdef __cplusplus
extern "C" {
#endif

/* Options, mostly defined by POSIX, but with some extras. */

#define REG_ICASE     0x0001   /* Maps to PCRE_CASELESS */
#define REG_NEWLINE   0x0002   /* Maps to PCRE_MULTILINE */
#define REG_NOTBOL    0x0004   /* Maps to PCRE_NOTBOL */
#define REG_NOTEOL    0x0008   /* Maps to PCRE_NOTEOL */
#define REG_DOTALL    0x0010   /* NOT defined by POSIX; maps to PCRE_DOTALL */
#define REG_NOSUB     0x0020   /* Maps to PCRE_NO_AUTO_CAPTURE */
#define REG_UTF8      0x0040   /* NOT defined by POSIX; maps to PCRE_UTF8 */
#define REG_STARTEND  0x0080   /* BSD feature: pass subject string by so,eo */
#define REG_NOTEMPTY  0x0100   /* NOT defined by POSIX; maps to PCRE_NOTEMPTY */
#define REG_UNGREEDY  0x0200   /* NOT defined by POSIX; maps to PCRE_UNGREEDY */
#define REG_UCP       0x0400   /* NOT defined by POSIX; maps to PCRE_UCP */

/* This is not used by PCRE, but by defining it we make it easier
to slot PCRE into existing programs that make POSIX calls. */

#define REG_EXTENDED  0

/* Error values. Not all these are relevant or used by the wrapper. */

enum {
  REG_ASSERT = 1,  /* internal error ? */
  REG_BADBR,       /* invalid repeat counts in {} */
  REG_BADPAT,      /* pattern error */
  REG_BADRPT,      /* ? * + invalid */
  REG_EBRACE,      /* unbalanced {} */
  REG_EBRACK,      /* unbalanced [] */
  REG_ECOLLATE,    /* collation error - not relevant */
  REG_ECTYPE,      /* bad class */
  REG_EESCAPE,     /* bad escape sequence */
  REG_EMPTY,       /* empty expression */
  REG_EPAREN,      /* unbalanced () */
  REG_ERANGE,      /* bad range inside [] */
  REG_ESIZE,       /* expression too big */
  REG_ESPACE,      /* failed to get memory */
  REG_ESUBREG,     /* bad back reference */
  REG_INVARG,      /* bad argument */
  REG_NOMATCH      /* match failed */
};


/* The structure representing a compiled regular expression. */

typedef struct {
  void *re_pcre;
  size_t re_nsub;
  size_t re_erroffset;
} regex_t;

/* The structure in which a captured offset is returned. */

typedef int regoff_t;

typedef struct {
  regoff_t rm_so;
  regoff_t rm_eo;
} regmatch_t;

/* When an application links to a PCRE DLL in Windows, the symbols that are
imported have to be identified as such. When building PCRE, the appropriate
export settings are needed, and are set in pcreposix.c before including this
file. */

#if defined(_WIN32) && !defined(PCRE_STATIC) && !defined(PCREPOSIX_EXP_DECL)
#  define PCREPOSIX_EXP_DECL  extern __declspec(dllimport)
#  define PCREPOSIX_EXP_DEFN  __declspec(dllimport)
#endif

/* By default, we use the standard "extern" declarations. */

#ifndef PCREPOSIX_EXP_DECL
#  ifdef __cplusplus
#    define PCREPOSIX_EXP_DECL  extern "C"
#    define PCREPOSIX_EXP_DEFN  extern "C"
#  else
#    define PCREPOSIX_EXP_DECL  extern
#    define PCREPOSIX_EXP_DEFN  extern
#  endif
#endif

/* The functions */

PCREPOSIX_EXP_DECL int regcomp(regex_t *, const char *, int);
PCREPOSIX_EXP_DECL int regexec(const regex_t *, const char *, size_t,
                     regmatch_t *, int);
PCREPOSIX_EXP_DECL size_t regerror(int, const regex_t *, char *, size_t);
PCREPOSIX_EXP_DECL void regfree(regex_t *);

#ifdef __cplusplus
}   /* extern "C" */
#endif

#endif /* End of pcreposix.h */
php/ext/pcre/pcrelib/config.h000064400000036615151730540360012141 0ustar00
#include <php_compat.h>

#ifdef PHP_WIN32
# include <config.w32.h>
#else
# include <php_config.h>
#endif

#undef PACKAGE_NAME
#undef PACKAGE_VERSION
#undef PACKAGE_TARNAME
#undef PACKAGE_STRING

#define SUPPORT_UCP
#define SUPPORT_UTF8

#if defined(__GNUC__) && __GNUC__ >= 4
# ifdef __cplusplus
#  define PCRE_EXP_DECL		extern "C" __attribute__ ((visibility("default")))
# else
#  define PCRE_EXP_DECL		extern __attribute__ ((visibility("default")))
# endif
# define PCRE_EXP_DEFN		__attribute__ ((visibility("default")))
# define PCRE_EXP_DATA_DEFN	__attribute__ ((visibility("default")))
#endif


/* Exclude these below definitions when building within PHP */
#ifndef ZEND_API

/* config.h.  Generated from config.h.in by configure.  */
/* config.h.in.  Generated from configure.ac by autoheader.  */


/* PCRE is written in Standard C, but there are a few non-standard things it
can cope with, allowing it to run on SunOS4 and other "close to standard"
systems.

In environments that support the facilities, config.h.in is converted by
"configure", or config-cmake.h.in is converted by CMake, into config.h. If you
are going to build PCRE "by hand" without using "configure" or CMake, you
should copy the distributed config.h.generic to config.h, and then edit the
macro definitions to be the way you need them. You must then add
-DHAVE_CONFIG_H to all of your compile commands, so that config.h is included
at the start of every source.

Alternatively, you can avoid editing by using -D on the compiler command line
to set the macro values. In this case, you do not have to set -DHAVE_CONFIG_H.

PCRE uses memmove() if HAVE_MEMMOVE is set to 1; otherwise it uses bcopy() if
HAVE_BCOPY is set to 1. If your system has neither bcopy() nor memmove(), set
them both to 0; an emulation function will be used. */

/* By default, the \R escape sequence matches any Unicode line ending
   character or sequence of characters. If BSR_ANYCRLF is defined (to any
   value), this is changed so that backslash-R matches only CR, LF, or CRLF.
   The build-time default can be overridden by the user of PCRE at runtime. */
#undef BSR_ANYCRLF

/* If you are compiling for a system that uses EBCDIC instead of ASCII
   character codes, define this macro to any value. You must also edit the
   NEWLINE macro below to set a suitable EBCDIC newline, commonly 21 (0x15).
   On systems that can use "configure" or CMake to set EBCDIC, NEWLINE is
   automatically adjusted. When EBCDIC is set, PCRE assumes that all input
   strings are in EBCDIC. If you do not define this macro, PCRE will assume
   input strings are ASCII or UTF-8/16/32 Unicode. It is not possible to build
   a version of PCRE that supports both EBCDIC and UTF-8/16/32. */
#undef EBCDIC

/* In an EBCDIC environment, define this macro to any value to arrange for the
   NL character to be 0x25 instead of the default 0x15. NL plays the role that
   LF does in an ASCII/Unicode environment. The value must also be set in the
   NEWLINE macro below. On systems that can use "configure" or CMake to set
   EBCDIC_NL25, the adjustment of NEWLINE is automatic. */
#undef EBCDIC_NL25

/* Define to 1 if you have the `bcopy' function. */
#ifndef HAVE_BCOPY
#define HAVE_BCOPY 1
#endif

/* Define to 1 if you have the <bits/type_traits.h> header file. */
/* #undef HAVE_BITS_TYPE_TRAITS_H */

/* Define to 1 if you have the <bzlib.h> header file. */
#ifndef HAVE_BZLIB_H
#define HAVE_BZLIB_H 1
#endif

/* Define to 1 if you have the <dirent.h> header file. */
#ifndef HAVE_DIRENT_H
#define HAVE_DIRENT_H 1
#endif

/* Define to 1 if you have the <dlfcn.h> header file. */
#ifndef HAVE_DLFCN_H
#define HAVE_DLFCN_H 1
#endif

/* Define to 1 if you have the <editline/readline.h> header file. */
/*#undef HAVE_EDITLINE_READLINE_H*/

/* Define to 1 if you have the <edit/readline/readline.h> header file. */
/* #undef HAVE_EDIT_READLINE_READLINE_H */

/* Define to 1 if you have the <inttypes.h> header file. */
#ifndef HAVE_INTTYPES_H
#define HAVE_INTTYPES_H 1
#endif

/* Define to 1 if you have the <limits.h> header file. */
#ifndef HAVE_LIMITS_H
#define HAVE_LIMITS_H 1
#endif

/* Define to 1 if the system has the type `long long'. */
#ifndef HAVE_LONG_LONG
#define HAVE_LONG_LONG 1
#endif

/* Define to 1 if you have the `memmove' function. */
#ifndef HAVE_MEMMOVE
#define HAVE_MEMMOVE 1
#endif

/* Define to 1 if you have the <memory.h> header file. */
#ifndef HAVE_MEMORY_H
#define HAVE_MEMORY_H 1
#endif

/* Define if you have POSIX threads libraries and header files. */
#undef HAVE_PTHREAD

/* Have PTHREAD_PRIO_INHERIT. */
#undef HAVE_PTHREAD_PRIO_INHERIT
/* Define to 1 if you have the <readline/history.h> header file. */
#ifndef HAVE_READLINE_HISTORY_H
#define HAVE_READLINE_HISTORY_H 1
#endif

/* Define to 1 if you have the <readline/readline.h> header file. */
#ifndef HAVE_READLINE_READLINE_H
#define HAVE_READLINE_READLINE_H 1
#endif

/* Define to 1 if you have the <stdint.h> header file. */
#ifndef HAVE_STDINT_H
#define HAVE_STDINT_H 1
#endif

/* Define to 1 if you have the <stdlib.h> header file. */
#ifndef HAVE_STDLIB_H
#define HAVE_STDLIB_H 1
#endif

/* Define to 1 if you have the `strerror' function. */
#ifndef HAVE_STRERROR
#define HAVE_STRERROR 1
#endif

/* Define to 1 if you have the <string> header file. */
#ifndef HAVE_STRING
#define HAVE_STRING 1
#endif

/* Define to 1 if you have the <strings.h> header file. */
#ifndef HAVE_STRINGS_H
#define HAVE_STRINGS_H 1
#endif

/* Define to 1 if you have the <string.h> header file. */
#ifndef HAVE_STRING_H
#define HAVE_STRING_H 1
#endif

/* Define to 1 if you have `strtoimax'. */
/* #undef HAVE_STRTOIMAX */

/* Define to 1 if you have `strtoll'. */
/* #undef HAVE_STRTOLL */

/* Define to 1 if you have `strtoq'. */
#ifndef HAVE_STRTOQ
#define HAVE_STRTOQ 1
#endif

/* Define to 1 if you have the <sys/stat.h> header file. */
#ifndef HAVE_SYS_STAT_H
#define HAVE_SYS_STAT_H 1
#endif

/* Define to 1 if you have the <sys/types.h> header file. */
#ifndef HAVE_SYS_TYPES_H
#define HAVE_SYS_TYPES_H 1
#endif

/* Define to 1 if you have the <type_traits.h> header file. */
/* #undef HAVE_TYPE_TRAITS_H */

/* Define to 1 if you have the <unistd.h> header file. */
#ifndef HAVE_UNISTD_H
#define HAVE_UNISTD_H 1
#endif

/* Define to 1 if the system has the type `unsigned long long'. */
#ifndef HAVE_UNSIGNED_LONG_LONG
#define HAVE_UNSIGNED_LONG_LONG 1
#endif

/* Define to 1 or 0, depending whether the compiler supports simple visibility
   declarations. */
/* #undef HAVE_VISIBILITY */

/* Define to 1 if you have the <windows.h> header file. */
/* #undef HAVE_WINDOWS_H */

/* Define to 1 if you have the <zlib.h> header file. */
#ifndef HAVE_ZLIB_H
#define HAVE_ZLIB_H 1
#endif

/* Define to 1 if you have `_strtoi64'. */
/* #undef HAVE__STRTOI64 */

/* Exclude these above definitions when building within PHP */
#endif

/* The value of LINK_SIZE determines the number of bytes used to store links
   as offsets within the compiled regex. The default is 2, which allows for
   compiled patterns up to 64K long. This covers the vast majority of cases.
   However, PCRE can also be compiled to use 3 or 4 bytes instead. This allows
   for longer patterns in extreme cases. On systems that support it,
   "configure" can be used to override this default. */
#ifndef LINK_SIZE
#define LINK_SIZE 2
#endif

/* Define to the sub-directory where libtool stores uninstalled libraries. */
/* This is ignored unless you are using libtool. */
#ifndef LT_OBJDIR
#define LT_OBJDIR ".libs/"
#endif

/* The value of MATCH_LIMIT determines the default number of times the
   internal match() function can be called during a single execution of
   pcre_exec(). There is a runtime interface for setting a different limit.
   The limit exists in order to catch runaway regular expressions that take
   for ever to determine that they do not match. The default is set very large
   so that it does not accidentally catch legitimate cases. On systems that
   support it, "configure" can be used to override this default default. */
#ifndef MATCH_LIMIT
#define MATCH_LIMIT 10000000
#endif

/* The above limit applies to all calls of match(), whether or not they
   increase the recursion depth. In some environments it is desirable to limit
   the depth of recursive calls of match() more strictly, in order to restrict
   the maximum amount of stack (or heap, if NO_RECURSE is defined) that is
   used. The value of MATCH_LIMIT_RECURSION applies only to recursive calls of
   match(). To have any useful effect, it must be less than the value of
   MATCH_LIMIT. The default is to use the same value as MATCH_LIMIT. There is
   a runtime method for setting a different limit. On systems that support it,
   "configure" can be used to override the default. */
#ifndef MATCH_LIMIT_RECURSION
#define MATCH_LIMIT_RECURSION MATCH_LIMIT
#endif

/* This limit is parameterized just in case anybody ever wants to change it.
   Care must be taken if it is increased, because it guards against integer
   overflow caused by enormously large patterns. */
#ifndef MAX_NAME_COUNT
#define MAX_NAME_COUNT 10000
#endif

/* This limit is parameterized just in case anybody ever wants to change it.
   Care must be taken if it is increased, because it guards against integer
   overflow caused by enormously large patterns. */
#ifndef MAX_NAME_SIZE
#define MAX_NAME_SIZE 32
#endif

/* The value of NEWLINE determines the default newline character sequence.
   PCRE client programs can override this by selecting other values at run
   time. In ASCII environments, the value can be 10 (LF), 13 (CR), or 3338
   (CRLF); in EBCDIC environments the value can be 21 or 37 (LF), 13 (CR), or
   3349 or 3365 (CRLF) because there are two alternative codepoints (0x15 and
   0x25) that are used as the NL line terminator that is equivalent to ASCII
   LF. In both ASCII and EBCDIC environments the value can also be -1 (ANY),
   or -2 (ANYCRLF). */
#ifndef NEWLINE
#define NEWLINE 10
#endif

/* Define to 1 if your C compiler doesn't accept -c and -o together. */
/* #undef NO_MINUS_C_MINUS_O */

/* PCRE uses recursive function calls to handle backtracking while matching.
   This can sometimes be a problem on systems that have stacks of limited
   size. Define NO_RECURSE to any value to get a version that doesn't use
   recursion in the match() function; instead it creates its own stack by
   steam using pcre_recurse_malloc() to obtain memory from the heap. For more
   detail, see the comments and other stuff just above the match() function.
   */
/* #undef NO_RECURSE */

#define PARENS_NEST_LIMIT 250

/* Name of package */
#define PACKAGE "pcre"

/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT ""

/* Define to the full name of this package. */
#define PACKAGE_NAME "PCRE"

/* Define to the full name and version of this package. */
#define PACKAGE_STRING "PCRE 8.41"

/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "pcre"

/* Define to the home page for this package. */
#define PACKAGE_URL ""

/* Define to the version of this package. */
#define PACKAGE_VERSION "8.41"

/* to make a symbol visible */
/* #undef PCRECPP_EXP_DECL */

/* to make a symbol visible */
/* #undef PCRECPP_EXP_DEFN */

/* The value of PARENS_NEST_LIMIT specifies the maximum depth of nested
   parentheses (of any kind) in a pattern. This limits the amount of system
   stack that is used while compiling a pattern. */
#ifndef PARENS_NEST_LIMIT
#define PARENS_NEST_LIMIT 250
#endif

/* The value of PCREGREP_BUFSIZE determines the size of buffer used by
   pcregrep to hold parts of the file it is searching. This is also the
   minimum value. The actual amount of memory used by pcregrep is three times
   this number, because it allows for the buffering of "before" and "after"
   lines. */
/* #undef PCREGREP_BUFSIZE */

/* to make a symbol visible */
/* #undef PCREPOSIX_EXP_DECL */

/* to make a symbol visible */
/* #undef PCREPOSIX_EXP_DEFN */

/* to make a symbol visible */
/* #undef PCRE_EXP_DATA_DEFN */

/* to make a symbol visible */
/* #undef PCRE_EXP_DECL */


/* If you are compiling for a system other than a Unix-like system or
   Win32, and it needs some magic to be inserted before the definition
   of a function that is exported by the library, define this macro to
   contain the relevant magic. If you do not define this macro, a suitable
    __declspec value is used for Windows systems; in other environments
   "extern" is used for a C compiler and "extern C" for a C++ compiler.
   This macro apears at the start of every exported function that is part
   of the external API. It does not appear on functions that are "external"
   in the C sense, but which are internal to the library. */
/* #undef PCRE_EXP_DEFN */

/* Define to any value if linking statically (TODO: make nice with Libtool) */
/* #undef PCRE_STATIC */

/* When calling PCRE via the POSIX interface, additional working storage is
   required for holding the pointers to capturing substrings because PCRE
   requires three integers per substring, whereas the POSIX interface provides
   only two. If the number of expected substrings is small, the wrapper
   function uses space on the stack, because this is faster than using
   malloc() for each call. The threshold above which the stack is no longer
   used is defined by POSIX_MALLOC_THRESHOLD. */
#ifndef POSIX_MALLOC_THRESHOLD
#define POSIX_MALLOC_THRESHOLD 10
#endif

/* Define to necessary symbol if this constant uses a non-standard name on
   your system. */
/* #undef PTHREAD_CREATE_JOINABLE */

/* Define to 1 if you have the ANSI C header files. */
#ifndef STDC_HEADERS
#define STDC_HEADERS 1
#endif

/* Define to allow pcretest and pcregrep to be linked with gcov, so that they
   are able to generate code coverage reports. */
#undef SUPPORT_GCOV

/* Define to any value to enable support for Just-In-Time compiling. */
#if HAVE_PCRE_JIT_SUPPORT
#define SUPPORT_JIT
#endif

/* Define to any value to allow pcregrep to be linked with libbz2, so that it
   is able to handle .bz2 files. */
/* #undef SUPPORT_LIBBZ2 */

/* Define to any value to allow pcretest to be linked with libedit. */
#undef SUPPORT_LIBEDIT

/* Define to any value to allow pcretest to be linked with libreadline. */
/* #undef SUPPORT_LIBREADLINE */

/* Define to any value to allow pcregrep to be linked with libz, so that it is
   able to handle .gz files. */
/* #undef SUPPORT_LIBZ */

/* Define to any value to enable the 16 bit PCRE library. */
/* #undef SUPPORT_PCRE16 */

/* Define to any value to enable the 32 bit PCRE library. */
/* #undef SUPPORT_PCRE32 */

/* Define to any value to enable the 8 bit PCRE library. */
/* #undef SUPPORT_PCRE8 */

/* Define to any value to enable JIT support in pcregrep. */
/* #undef SUPPORT_PCREGREP_JIT */

/* Define to enable support for Unicode properties */
/* #undef SUPPORT_UCP */

/* Define to any value to enable support for the UTF-8/16/32 Unicode encoding.
   This will work even in an EBCDIC environment, but it is incompatible with
   the EBCDIC macro. That is, PCRE can support *either* EBCDIC code *or*
   ASCII/UTF-8/16/32, but not both at once. */
/* #undef SUPPORT_UTF8 */

/* Valgrind support to find invalid memory reads. */
#if HAVE_PCRE_VALGRIND_SUPPORT
#define SUPPORT_VALGRIND 1
#endif

/* Version number of package */
#ifndef VERSION
#define VERSION "8.41"
#endif

/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */

/* Define to the type of a signed integer type of width exactly 64 bits if
   such a type exists and the standard includes do not define it. */
/* #undef int64_t */

/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */
php/ext/pcre/pcrelib/pcre.h000064400000075732151730540360011630 0ustar00/*************************************************
*       Perl-Compatible Regular Expressions      *
*************************************************/

/* This is the public header file for the PCRE library, to be #included by
applications that call the PCRE functions.

           Copyright (c) 1997-2014 University of Cambridge

-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice,
      this list of conditions and the following disclaimer.

    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.

    * Neither the name of the University of Cambridge nor the names of its
      contributors may be used to endorse or promote products derived from
      this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-----------------------------------------------------------------------------
*/

#ifndef _PCRE_H
#define _PCRE_H

/* The current PCRE version information. */

#define PCRE_MAJOR          8
#define PCRE_MINOR          41
#define PCRE_PRERELEASE     
#define PCRE_DATE           2017-07-05

/* When an application links to a PCRE DLL in Windows, the symbols that are
imported have to be identified as such. When building PCRE, the appropriate
export setting is defined in pcre_internal.h, which includes this file. So we
don't change existing definitions of PCRE_EXP_DECL and PCRECPP_EXP_DECL. */

#if defined(_WIN32) && !defined(PCRE_STATIC)
#  ifndef PCRE_EXP_DECL
#    define PCRE_EXP_DECL  extern __declspec(dllimport)
#  endif
#  ifdef __cplusplus
#    ifndef PCRECPP_EXP_DECL
#      define PCRECPP_EXP_DECL  extern __declspec(dllimport)
#    endif
#    ifndef PCRECPP_EXP_DEFN
#      define PCRECPP_EXP_DEFN  __declspec(dllimport)
#    endif
#  endif
#endif

/* By default, we use the standard "extern" declarations. */

#ifndef PCRE_EXP_DECL
#  ifdef __cplusplus
#    define PCRE_EXP_DECL  extern "C"
#  else
#    define PCRE_EXP_DECL  extern
#  endif
#endif

#ifdef __cplusplus
#  ifndef PCRECPP_EXP_DECL
#    define PCRECPP_EXP_DECL  extern
#  endif
#  ifndef PCRECPP_EXP_DEFN
#    define PCRECPP_EXP_DEFN
#  endif
#endif

/* Have to include stdlib.h in order to ensure that size_t is defined;
it is needed here for malloc. */

#include <stdlib.h>

/* Allow for C++ users */

#ifdef __cplusplus
extern "C" {
#endif

/* Public options. Some are compile-time only, some are run-time only, and some
are both. Most of the compile-time options are saved with the compiled regex so
that they can be inspected during studying (and therefore JIT compiling). Note
that pcre_study() has its own set of options. Originally, all the options
defined here used distinct bits. However, almost all the bits in a 32-bit word
are now used, so in order to conserve them, option bits that were previously
only recognized at matching time (i.e. by pcre_exec() or pcre_dfa_exec()) may
also be used for compile-time options that affect only compiling and are not
relevant for studying or JIT compiling.

Some options for pcre_compile() change its behaviour but do not affect the
behaviour of the execution functions. Other options are passed through to the
execution functions and affect their behaviour, with or without affecting the
behaviour of pcre_compile().

Options that can be passed to pcre_compile() are tagged Cx below, with these
variants:

C1   Affects compile only
C2   Does not affect compile; affects exec, dfa_exec
C3   Affects compile, exec, dfa_exec
C4   Affects compile, exec, dfa_exec, study
C5   Affects compile, exec, study

Options that can be set for pcre_exec() and/or pcre_dfa_exec() are flagged with
E and D, respectively. They take precedence over C3, C4, and C5 settings passed
from pcre_compile(). Those that are compatible with JIT execution are flagged
with J. */

#define PCRE_CASELESS           0x00000001  /* C1       */
#define PCRE_MULTILINE          0x00000002  /* C1       */
#define PCRE_DOTALL             0x00000004  /* C1       */
#define PCRE_EXTENDED           0x00000008  /* C1       */
#define PCRE_ANCHORED           0x00000010  /* C4 E D   */
#define PCRE_DOLLAR_ENDONLY     0x00000020  /* C2       */
#define PCRE_EXTRA              0x00000040  /* C1       */
#define PCRE_NOTBOL             0x00000080  /*    E D J */
#define PCRE_NOTEOL             0x00000100  /*    E D J */
#define PCRE_UNGREEDY           0x00000200  /* C1       */
#define PCRE_NOTEMPTY           0x00000400  /*    E D J */
#define PCRE_UTF8               0x00000800  /* C4        )          */
#define PCRE_UTF16              0x00000800  /* C4        ) Synonyms */
#define PCRE_UTF32              0x00000800  /* C4        )          */
#define PCRE_NO_AUTO_CAPTURE    0x00001000  /* C1       */
#define PCRE_NO_UTF8_CHECK      0x00002000  /* C1 E D J  )          */
#define PCRE_NO_UTF16_CHECK     0x00002000  /* C1 E D J  ) Synonyms */
#define PCRE_NO_UTF32_CHECK     0x00002000  /* C1 E D J  )          */
#define PCRE_AUTO_CALLOUT       0x00004000  /* C1       */
#define PCRE_PARTIAL_SOFT       0x00008000  /*    E D J  ) Synonyms */
#define PCRE_PARTIAL            0x00008000  /*    E D J  )          */

/* This pair use the same bit. */
#define PCRE_NEVER_UTF          0x00010000  /* C1        ) Overlaid */
#define PCRE_DFA_SHORTEST       0x00010000  /*      D    ) Overlaid */

/* This pair use the same bit. */
#define PCRE_NO_AUTO_POSSESS    0x00020000  /* C1        ) Overlaid */
#define PCRE_DFA_RESTART        0x00020000  /*      D    ) Overlaid */

#define PCRE_FIRSTLINE          0x00040000  /* C3       */
#define PCRE_DUPNAMES           0x00080000  /* C1       */
#define PCRE_NEWLINE_CR         0x00100000  /* C3 E D   */
#define PCRE_NEWLINE_LF         0x00200000  /* C3 E D   */
#define PCRE_NEWLINE_CRLF       0x00300000  /* C3 E D   */
#define PCRE_NEWLINE_ANY        0x00400000  /* C3 E D   */
#define PCRE_NEWLINE_ANYCRLF    0x00500000  /* C3 E D   */
#define PCRE_BSR_ANYCRLF        0x00800000  /* C3 E D   */
#define PCRE_BSR_UNICODE        0x01000000  /* C3 E D   */
#define PCRE_JAVASCRIPT_COMPAT  0x02000000  /* C5       */
#define PCRE_NO_START_OPTIMIZE  0x04000000  /* C2 E D    ) Synonyms */
#define PCRE_NO_START_OPTIMISE  0x04000000  /* C2 E D    )          */
#define PCRE_PARTIAL_HARD       0x08000000  /*    E D J */
#define PCRE_NOTEMPTY_ATSTART   0x10000000  /*    E D J */
#define PCRE_UCP                0x20000000  /* C3       */

/* Exec-time and get/set-time error codes */

#define PCRE_ERROR_NOMATCH          (-1)
#define PCRE_ERROR_NULL             (-2)
#define PCRE_ERROR_BADOPTION        (-3)
#define PCRE_ERROR_BADMAGIC         (-4)
#define PCRE_ERROR_UNKNOWN_OPCODE   (-5)
#define PCRE_ERROR_UNKNOWN_NODE     (-5)  /* For backward compatibility */
#define PCRE_ERROR_NOMEMORY         (-6)
#define PCRE_ERROR_NOSUBSTRING      (-7)
#define PCRE_ERROR_MATCHLIMIT       (-8)
#define PCRE_ERROR_CALLOUT          (-9)  /* Never used by PCRE itself */
#define PCRE_ERROR_BADUTF8         (-10)  /* Same for 8/16/32 */
#define PCRE_ERROR_BADUTF16        (-10)  /* Same for 8/16/32 */
#define PCRE_ERROR_BADUTF32        (-10)  /* Same for 8/16/32 */
#define PCRE_ERROR_BADUTF8_OFFSET  (-11)  /* Same for 8/16 */
#define PCRE_ERROR_BADUTF16_OFFSET (-11)  /* Same for 8/16 */
#define PCRE_ERROR_PARTIAL         (-12)
#define PCRE_ERROR_BADPARTIAL      (-13)
#define PCRE_ERROR_INTERNAL        (-14)
#define PCRE_ERROR_BADCOUNT        (-15)
#define PCRE_ERROR_DFA_UITEM       (-16)
#define PCRE_ERROR_DFA_UCOND       (-17)
#define PCRE_ERROR_DFA_UMLIMIT     (-18)
#define PCRE_ERROR_DFA_WSSIZE      (-19)
#define PCRE_ERROR_DFA_RECURSE     (-20)
#define PCRE_ERROR_RECURSIONLIMIT  (-21)
#define PCRE_ERROR_NULLWSLIMIT     (-22)  /* No longer actually used */
#define PCRE_ERROR_BADNEWLINE      (-23)
#define PCRE_ERROR_BADOFFSET       (-24)
#define PCRE_ERROR_SHORTUTF8       (-25)
#define PCRE_ERROR_SHORTUTF16      (-25)  /* Same for 8/16 */
#define PCRE_ERROR_RECURSELOOP     (-26)
#define PCRE_ERROR_JIT_STACKLIMIT  (-27)
#define PCRE_ERROR_BADMODE         (-28)
#define PCRE_ERROR_BADENDIANNESS   (-29)
#define PCRE_ERROR_DFA_BADRESTART  (-30)
#define PCRE_ERROR_JIT_BADOPTION   (-31)
#define PCRE_ERROR_BADLENGTH       (-32)
#define PCRE_ERROR_UNSET           (-33)

/* Specific error codes for UTF-8 validity checks */

#define PCRE_UTF8_ERR0               0
#define PCRE_UTF8_ERR1               1
#define PCRE_UTF8_ERR2               2
#define PCRE_UTF8_ERR3               3
#define PCRE_UTF8_ERR4               4
#define PCRE_UTF8_ERR5               5
#define PCRE_UTF8_ERR6               6
#define PCRE_UTF8_ERR7               7
#define PCRE_UTF8_ERR8               8
#define PCRE_UTF8_ERR9               9
#define PCRE_UTF8_ERR10             10
#define PCRE_UTF8_ERR11             11
#define PCRE_UTF8_ERR12             12
#define PCRE_UTF8_ERR13             13
#define PCRE_UTF8_ERR14             14
#define PCRE_UTF8_ERR15             15
#define PCRE_UTF8_ERR16             16
#define PCRE_UTF8_ERR17             17
#define PCRE_UTF8_ERR18             18
#define PCRE_UTF8_ERR19             19
#define PCRE_UTF8_ERR20             20
#define PCRE_UTF8_ERR21             21
#define PCRE_UTF8_ERR22             22  /* Unused (was non-character) */

/* Specific error codes for UTF-16 validity checks */

#define PCRE_UTF16_ERR0              0
#define PCRE_UTF16_ERR1              1
#define PCRE_UTF16_ERR2              2
#define PCRE_UTF16_ERR3              3
#define PCRE_UTF16_ERR4              4  /* Unused (was non-character) */

/* Specific error codes for UTF-32 validity checks */

#define PCRE_UTF32_ERR0              0
#define PCRE_UTF32_ERR1              1
#define PCRE_UTF32_ERR2              2  /* Unused (was non-character) */
#define PCRE_UTF32_ERR3              3

/* Request types for pcre_fullinfo() */

#define PCRE_INFO_OPTIONS            0
#define PCRE_INFO_SIZE               1
#define PCRE_INFO_CAPTURECOUNT       2
#define PCRE_INFO_BACKREFMAX         3
#define PCRE_INFO_FIRSTBYTE          4
#define PCRE_INFO_FIRSTCHAR          4  /* For backwards compatibility */
#define PCRE_INFO_FIRSTTABLE         5
#define PCRE_INFO_LASTLITERAL        6
#define PCRE_INFO_NAMEENTRYSIZE      7
#define PCRE_INFO_NAMECOUNT          8
#define PCRE_INFO_NAMETABLE          9
#define PCRE_INFO_STUDYSIZE         10
#define PCRE_INFO_DEFAULT_TABLES    11
#define PCRE_INFO_OKPARTIAL         12
#define PCRE_INFO_JCHANGED          13
#define PCRE_INFO_HASCRORLF         14
#define PCRE_INFO_MINLENGTH         15
#define PCRE_INFO_JIT               16
#define PCRE_INFO_JITSIZE           17
#define PCRE_INFO_MAXLOOKBEHIND     18
#define PCRE_INFO_FIRSTCHARACTER    19
#define PCRE_INFO_FIRSTCHARACTERFLAGS 20
#define PCRE_INFO_REQUIREDCHAR      21
#define PCRE_INFO_REQUIREDCHARFLAGS 22
#define PCRE_INFO_MATCHLIMIT        23
#define PCRE_INFO_RECURSIONLIMIT    24
#define PCRE_INFO_MATCH_EMPTY       25

/* Request types for pcre_config(). Do not re-arrange, in order to remain
compatible. */

#define PCRE_CONFIG_UTF8                    0
#define PCRE_CONFIG_NEWLINE                 1
#define PCRE_CONFIG_LINK_SIZE               2
#define PCRE_CONFIG_POSIX_MALLOC_THRESHOLD  3
#define PCRE_CONFIG_MATCH_LIMIT             4
#define PCRE_CONFIG_STACKRECURSE            5
#define PCRE_CONFIG_UNICODE_PROPERTIES      6
#define PCRE_CONFIG_MATCH_LIMIT_RECURSION   7
#define PCRE_CONFIG_BSR                     8
#define PCRE_CONFIG_JIT                     9
#define PCRE_CONFIG_UTF16                  10
#define PCRE_CONFIG_JITTARGET              11
#define PCRE_CONFIG_UTF32                  12
#define PCRE_CONFIG_PARENS_LIMIT           13

/* Request types for pcre_study(). Do not re-arrange, in order to remain
compatible. */

#define PCRE_STUDY_JIT_COMPILE                0x0001
#define PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE   0x0002
#define PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE   0x0004
#define PCRE_STUDY_EXTRA_NEEDED               0x0008

/* Bit flags for the pcre[16|32]_extra structure. Do not re-arrange or redefine
these bits, just add new ones on the end, in order to remain compatible. */

#define PCRE_EXTRA_STUDY_DATA             0x0001
#define PCRE_EXTRA_MATCH_LIMIT            0x0002
#define PCRE_EXTRA_CALLOUT_DATA           0x0004
#define PCRE_EXTRA_TABLES                 0x0008
#define PCRE_EXTRA_MATCH_LIMIT_RECURSION  0x0010
#define PCRE_EXTRA_MARK                   0x0020
#define PCRE_EXTRA_EXECUTABLE_JIT         0x0040

/* Types */

struct real_pcre;                 /* declaration; the definition is private  */
typedef struct real_pcre pcre;

struct real_pcre16;               /* declaration; the definition is private  */
typedef struct real_pcre16 pcre16;

struct real_pcre32;               /* declaration; the definition is private  */
typedef struct real_pcre32 pcre32;

struct real_pcre_jit_stack;       /* declaration; the definition is private  */
typedef struct real_pcre_jit_stack pcre_jit_stack;

struct real_pcre16_jit_stack;     /* declaration; the definition is private  */
typedef struct real_pcre16_jit_stack pcre16_jit_stack;

struct real_pcre32_jit_stack;     /* declaration; the definition is private  */
typedef struct real_pcre32_jit_stack pcre32_jit_stack;

/* If PCRE is compiled with 16 bit character support, PCRE_UCHAR16 must contain
a 16 bit wide signed data type. Otherwise it can be a dummy data type since
pcre16 functions are not implemented. There is a check for this in pcre_internal.h. */
#ifndef PCRE_UCHAR16
#define PCRE_UCHAR16 unsigned short
#endif

#ifndef PCRE_SPTR16
#define PCRE_SPTR16 const PCRE_UCHAR16 *
#endif

/* If PCRE is compiled with 32 bit character support, PCRE_UCHAR32 must contain
a 32 bit wide signed data type. Otherwise it can be a dummy data type since
pcre32 functions are not implemented. There is a check for this in pcre_internal.h. */
#ifndef PCRE_UCHAR32
#define PCRE_UCHAR32 unsigned int
#endif

#ifndef PCRE_SPTR32
#define PCRE_SPTR32 const PCRE_UCHAR32 *
#endif

/* When PCRE is compiled as a C++ library, the subject pointer type can be
replaced with a custom type. For conventional use, the public interface is a
const char *. */

#ifndef PCRE_SPTR
#define PCRE_SPTR const char *
#endif

/* The structure for passing additional data to pcre_exec(). This is defined in
such as way as to be extensible. Always add new fields at the end, in order to
remain compatible. */

typedef struct pcre_extra {
  unsigned long int flags;        /* Bits for which fields are set */
  void *study_data;               /* Opaque data from pcre_study() */
  unsigned long int match_limit;  /* Maximum number of calls to match() */
  void *callout_data;             /* Data passed back in callouts */
  const unsigned char *tables;    /* Pointer to character tables */
  unsigned long int match_limit_recursion; /* Max recursive calls to match() */
  unsigned char **mark;           /* For passing back a mark pointer */
  void *executable_jit;           /* Contains a pointer to a compiled jit code */
} pcre_extra;

/* Same structure as above, but with 16 bit char pointers. */

typedef struct pcre16_extra {
  unsigned long int flags;        /* Bits for which fields are set */
  void *study_data;               /* Opaque data from pcre_study() */
  unsigned long int match_limit;  /* Maximum number of calls to match() */
  void *callout_data;             /* Data passed back in callouts */
  const unsigned char *tables;    /* Pointer to character tables */
  unsigned long int match_limit_recursion; /* Max recursive calls to match() */
  PCRE_UCHAR16 **mark;            /* For passing back a mark pointer */
  void *executable_jit;           /* Contains a pointer to a compiled jit code */
} pcre16_extra;

/* Same structure as above, but with 32 bit char pointers. */

typedef struct pcre32_extra {
  unsigned long int flags;        /* Bits for which fields are set */
  void *study_data;               /* Opaque data from pcre_study() */
  unsigned long int match_limit;  /* Maximum number of calls to match() */
  void *callout_data;             /* Data passed back in callouts */
  const unsigned char *tables;    /* Pointer to character tables */
  unsigned long int match_limit_recursion; /* Max recursive calls to match() */
  PCRE_UCHAR32 **mark;            /* For passing back a mark pointer */
  void *executable_jit;           /* Contains a pointer to a compiled jit code */
} pcre32_extra;

/* The structure for passing out data via the pcre_callout_function. We use a
structure so that new fields can be added on the end in future versions,
without changing the API of the function, thereby allowing old clients to work
without modification. */

typedef struct pcre_callout_block {
  int          version;           /* Identifies version of block */
  /* ------------------------ Version 0 ------------------------------- */
  int          callout_number;    /* Number compiled into pattern */
  int         *offset_vector;     /* The offset vector */
  PCRE_SPTR    subject;           /* The subject being matched */
  int          subject_length;    /* The length of the subject */
  int          start_match;       /* Offset to start of this match attempt */
  int          current_position;  /* Where we currently are in the subject */
  int          capture_top;       /* Max current capture */
  int          capture_last;      /* Most recently closed capture */
  void        *callout_data;      /* Data passed in with the call */
  /* ------------------- Added for Version 1 -------------------------- */
  int          pattern_position;  /* Offset to next item in the pattern */
  int          next_item_length;  /* Length of next item in the pattern */
  /* ------------------- Added for Version 2 -------------------------- */
  const unsigned char *mark;      /* Pointer to current mark or NULL    */
  /* ------------------------------------------------------------------ */
} pcre_callout_block;

/* Same structure as above, but with 16 bit char pointers. */

typedef struct pcre16_callout_block {
  int          version;           /* Identifies version of block */
  /* ------------------------ Version 0 ------------------------------- */
  int          callout_number;    /* Number compiled into pattern */
  int         *offset_vector;     /* The offset vector */
  PCRE_SPTR16  subject;           /* The subject being matched */
  int          subject_length;    /* The length of the subject */
  int          start_match;       /* Offset to start of this match attempt */
  int          current_position;  /* Where we currently are in the subject */
  int          capture_top;       /* Max current capture */
  int          capture_last;      /* Most recently closed capture */
  void        *callout_data;      /* Data passed in with the call */
  /* ------------------- Added for Version 1 -------------------------- */
  int          pattern_position;  /* Offset to next item in the pattern */
  int          next_item_length;  /* Length of next item in the pattern */
  /* ------------------- Added for Version 2 -------------------------- */
  const PCRE_UCHAR16 *mark;       /* Pointer to current mark or NULL    */
  /* ------------------------------------------------------------------ */
} pcre16_callout_block;

/* Same structure as above, but with 32 bit char pointers. */

typedef struct pcre32_callout_block {
  int          version;           /* Identifies version of block */
  /* ------------------------ Version 0 ------------------------------- */
  int          callout_number;    /* Number compiled into pattern */
  int         *offset_vector;     /* The offset vector */
  PCRE_SPTR32  subject;           /* The subject being matched */
  int          subject_length;    /* The length of the subject */
  int          start_match;       /* Offset to start of this match attempt */
  int          current_position;  /* Where we currently are in the subject */
  int          capture_top;       /* Max current capture */
  int          capture_last;      /* Most recently closed capture */
  void        *callout_data;      /* Data passed in with the call */
  /* ------------------- Added for Version 1 -------------------------- */
  int          pattern_position;  /* Offset to next item in the pattern */
  int          next_item_length;  /* Length of next item in the pattern */
  /* ------------------- Added for Version 2 -------------------------- */
  const PCRE_UCHAR32 *mark;       /* Pointer to current mark or NULL    */
  /* ------------------------------------------------------------------ */
} pcre32_callout_block;

/* Indirection for store get and free functions. These can be set to
alternative malloc/free functions if required. Special ones are used in the
non-recursive case for "frames". There is also an optional callout function
that is triggered by the (?) regex item. For Virtual Pascal, these definitions
have to take another form. */

#ifndef VPCOMPAT
PCRE_EXP_DECL void *(*pcre_malloc)(size_t);
PCRE_EXP_DECL void  (*pcre_free)(void *);
PCRE_EXP_DECL void *(*pcre_stack_malloc)(size_t);
PCRE_EXP_DECL void  (*pcre_stack_free)(void *);
PCRE_EXP_DECL int   (*pcre_callout)(pcre_callout_block *);
PCRE_EXP_DECL int   (*pcre_stack_guard)(void);

PCRE_EXP_DECL void *(*pcre16_malloc)(size_t);
PCRE_EXP_DECL void  (*pcre16_free)(void *);
PCRE_EXP_DECL void *(*pcre16_stack_malloc)(size_t);
PCRE_EXP_DECL void  (*pcre16_stack_free)(void *);
PCRE_EXP_DECL int   (*pcre16_callout)(pcre16_callout_block *);
PCRE_EXP_DECL int   (*pcre16_stack_guard)(void);

PCRE_EXP_DECL void *(*pcre32_malloc)(size_t);
PCRE_EXP_DECL void  (*pcre32_free)(void *);
PCRE_EXP_DECL void *(*pcre32_stack_malloc)(size_t);
PCRE_EXP_DECL void  (*pcre32_stack_free)(void *);
PCRE_EXP_DECL int   (*pcre32_callout)(pcre32_callout_block *);
PCRE_EXP_DECL int   (*pcre32_stack_guard)(void);
#else   /* VPCOMPAT */
PCRE_EXP_DECL void *pcre_malloc(size_t);
PCRE_EXP_DECL void  pcre_free(void *);
PCRE_EXP_DECL void *pcre_stack_malloc(size_t);
PCRE_EXP_DECL void  pcre_stack_free(void *);
PCRE_EXP_DECL int   pcre_callout(pcre_callout_block *);
PCRE_EXP_DECL int   pcre_stack_guard(void);

PCRE_EXP_DECL void *pcre16_malloc(size_t);
PCRE_EXP_DECL void  pcre16_free(void *);
PCRE_EXP_DECL void *pcre16_stack_malloc(size_t);
PCRE_EXP_DECL void  pcre16_stack_free(void *);
PCRE_EXP_DECL int   pcre16_callout(pcre16_callout_block *);
PCRE_EXP_DECL int   pcre16_stack_guard(void);

PCRE_EXP_DECL void *pcre32_malloc(size_t);
PCRE_EXP_DECL void  pcre32_free(void *);
PCRE_EXP_DECL void *pcre32_stack_malloc(size_t);
PCRE_EXP_DECL void  pcre32_stack_free(void *);
PCRE_EXP_DECL int   pcre32_callout(pcre32_callout_block *);
PCRE_EXP_DECL int   pcre32_stack_guard(void);
#endif  /* VPCOMPAT */

/* User defined callback which provides a stack just before the match starts. */

typedef pcre_jit_stack *(*pcre_jit_callback)(void *);
typedef pcre16_jit_stack *(*pcre16_jit_callback)(void *);
typedef pcre32_jit_stack *(*pcre32_jit_callback)(void *);

/* Exported PCRE functions */

PCRE_EXP_DECL pcre *pcre_compile(const char *, int, const char **, int *,
                  const unsigned char *);
PCRE_EXP_DECL pcre16 *pcre16_compile(PCRE_SPTR16, int, const char **, int *,
                  const unsigned char *);
PCRE_EXP_DECL pcre32 *pcre32_compile(PCRE_SPTR32, int, const char **, int *,
                  const unsigned char *);
PCRE_EXP_DECL pcre *pcre_compile2(const char *, int, int *, const char **,
                  int *, const unsigned char *);
PCRE_EXP_DECL pcre16 *pcre16_compile2(PCRE_SPTR16, int, int *, const char **,
                  int *, const unsigned char *);
PCRE_EXP_DECL pcre32 *pcre32_compile2(PCRE_SPTR32, int, int *, const char **,
                  int *, const unsigned char *);
PCRE_EXP_DECL int  pcre_config(int, void *);
PCRE_EXP_DECL int  pcre16_config(int, void *);
PCRE_EXP_DECL int  pcre32_config(int, void *);
PCRE_EXP_DECL int  pcre_copy_named_substring(const pcre *, const char *,
                  int *, int, const char *, char *, int);
PCRE_EXP_DECL int  pcre16_copy_named_substring(const pcre16 *, PCRE_SPTR16,
                  int *, int, PCRE_SPTR16, PCRE_UCHAR16 *, int);
PCRE_EXP_DECL int  pcre32_copy_named_substring(const pcre32 *, PCRE_SPTR32,
                  int *, int, PCRE_SPTR32, PCRE_UCHAR32 *, int);
PCRE_EXP_DECL int  pcre_copy_substring(const char *, int *, int, int,
                  char *, int);
PCRE_EXP_DECL int  pcre16_copy_substring(PCRE_SPTR16, int *, int, int,
                  PCRE_UCHAR16 *, int);
PCRE_EXP_DECL int  pcre32_copy_substring(PCRE_SPTR32, int *, int, int,
                  PCRE_UCHAR32 *, int);
PCRE_EXP_DECL int  pcre_dfa_exec(const pcre *, const pcre_extra *,
                  const char *, int, int, int, int *, int , int *, int);
PCRE_EXP_DECL int  pcre16_dfa_exec(const pcre16 *, const pcre16_extra *,
                  PCRE_SPTR16, int, int, int, int *, int , int *, int);
PCRE_EXP_DECL int  pcre32_dfa_exec(const pcre32 *, const pcre32_extra *,
                  PCRE_SPTR32, int, int, int, int *, int , int *, int);
PCRE_EXP_DECL int  pcre_exec(const pcre *, const pcre_extra *, PCRE_SPTR,
                   int, int, int, int *, int);
PCRE_EXP_DECL int  pcre16_exec(const pcre16 *, const pcre16_extra *,
                   PCRE_SPTR16, int, int, int, int *, int);
PCRE_EXP_DECL int  pcre32_exec(const pcre32 *, const pcre32_extra *,
                   PCRE_SPTR32, int, int, int, int *, int);
PCRE_EXP_DECL int  pcre_jit_exec(const pcre *, const pcre_extra *,
                   PCRE_SPTR, int, int, int, int *, int,
                   pcre_jit_stack *);
PCRE_EXP_DECL int  pcre16_jit_exec(const pcre16 *, const pcre16_extra *,
                   PCRE_SPTR16, int, int, int, int *, int,
                   pcre16_jit_stack *);
PCRE_EXP_DECL int  pcre32_jit_exec(const pcre32 *, const pcre32_extra *,
                   PCRE_SPTR32, int, int, int, int *, int,
                   pcre32_jit_stack *);
PCRE_EXP_DECL void pcre_free_substring(const char *);
PCRE_EXP_DECL void pcre16_free_substring(PCRE_SPTR16);
PCRE_EXP_DECL void pcre32_free_substring(PCRE_SPTR32);
PCRE_EXP_DECL void pcre_free_substring_list(const char **);
PCRE_EXP_DECL void pcre16_free_substring_list(PCRE_SPTR16 *);
PCRE_EXP_DECL void pcre32_free_substring_list(PCRE_SPTR32 *);
PCRE_EXP_DECL int  pcre_fullinfo(const pcre *, const pcre_extra *, int,
                  void *);
PCRE_EXP_DECL int  pcre16_fullinfo(const pcre16 *, const pcre16_extra *, int,
                  void *);
PCRE_EXP_DECL int  pcre32_fullinfo(const pcre32 *, const pcre32_extra *, int,
                  void *);
PCRE_EXP_DECL int  pcre_get_named_substring(const pcre *, const char *,
                  int *, int, const char *, const char **);
PCRE_EXP_DECL int  pcre16_get_named_substring(const pcre16 *, PCRE_SPTR16,
                  int *, int, PCRE_SPTR16, PCRE_SPTR16 *);
PCRE_EXP_DECL int  pcre32_get_named_substring(const pcre32 *, PCRE_SPTR32,
                  int *, int, PCRE_SPTR32, PCRE_SPTR32 *);
PCRE_EXP_DECL int  pcre_get_stringnumber(const pcre *, const char *);
PCRE_EXP_DECL int  pcre16_get_stringnumber(const pcre16 *, PCRE_SPTR16);
PCRE_EXP_DECL int  pcre32_get_stringnumber(const pcre32 *, PCRE_SPTR32);
PCRE_EXP_DECL int  pcre_get_stringtable_entries(const pcre *, const char *,
                  char **, char **);
PCRE_EXP_DECL int  pcre16_get_stringtable_entries(const pcre16 *, PCRE_SPTR16,
                  PCRE_UCHAR16 **, PCRE_UCHAR16 **);
PCRE_EXP_DECL int  pcre32_get_stringtable_entries(const pcre32 *, PCRE_SPTR32,
                  PCRE_UCHAR32 **, PCRE_UCHAR32 **);
PCRE_EXP_DECL int  pcre_get_substring(const char *, int *, int, int,
                  const char **);
PCRE_EXP_DECL int  pcre16_get_substring(PCRE_SPTR16, int *, int, int,
                  PCRE_SPTR16 *);
PCRE_EXP_DECL int  pcre32_get_substring(PCRE_SPTR32, int *, int, int,
                  PCRE_SPTR32 *);
PCRE_EXP_DECL int  pcre_get_substring_list(const char *, int *, int,
                  const char ***);
PCRE_EXP_DECL int  pcre16_get_substring_list(PCRE_SPTR16, int *, int,
                  PCRE_SPTR16 **);
PCRE_EXP_DECL int  pcre32_get_substring_list(PCRE_SPTR32, int *, int,
                  PCRE_SPTR32 **);
PCRE_EXP_DECL const unsigned char *pcre_maketables(void);
PCRE_EXP_DECL const unsigned char *pcre16_maketables(void);
PCRE_EXP_DECL const unsigned char *pcre32_maketables(void);
PCRE_EXP_DECL int  pcre_refcount(pcre *, int);
PCRE_EXP_DECL int  pcre16_refcount(pcre16 *, int);
PCRE_EXP_DECL int  pcre32_refcount(pcre32 *, int);
PCRE_EXP_DECL pcre_extra *pcre_study(const pcre *, int, const char **);
PCRE_EXP_DECL pcre16_extra *pcre16_study(const pcre16 *, int, const char **);
PCRE_EXP_DECL pcre32_extra *pcre32_study(const pcre32 *, int, const char **);
PCRE_EXP_DECL void pcre_free_study(pcre_extra *);
PCRE_EXP_DECL void pcre16_free_study(pcre16_extra *);
PCRE_EXP_DECL void pcre32_free_study(pcre32_extra *);
PCRE_EXP_DECL const char *pcre_version(void);
PCRE_EXP_DECL const char *pcre16_version(void);
PCRE_EXP_DECL const char *pcre32_version(void);

/* Utility functions for byte order swaps. */
PCRE_EXP_DECL int  pcre_pattern_to_host_byte_order(pcre *, pcre_extra *,
                  const unsigned char *);
PCRE_EXP_DECL int  pcre16_pattern_to_host_byte_order(pcre16 *, pcre16_extra *,
                  const unsigned char *);
PCRE_EXP_DECL int  pcre32_pattern_to_host_byte_order(pcre32 *, pcre32_extra *,
                  const unsigned char *);
PCRE_EXP_DECL int  pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *,
                  PCRE_SPTR16, int, int *, int);
PCRE_EXP_DECL int  pcre32_utf32_to_host_byte_order(PCRE_UCHAR32 *,
                  PCRE_SPTR32, int, int *, int);

/* JIT compiler related functions. */

PCRE_EXP_DECL pcre_jit_stack *pcre_jit_stack_alloc(int, int);
PCRE_EXP_DECL pcre16_jit_stack *pcre16_jit_stack_alloc(int, int);
PCRE_EXP_DECL pcre32_jit_stack *pcre32_jit_stack_alloc(int, int);
PCRE_EXP_DECL void pcre_jit_stack_free(pcre_jit_stack *);
PCRE_EXP_DECL void pcre16_jit_stack_free(pcre16_jit_stack *);
PCRE_EXP_DECL void pcre32_jit_stack_free(pcre32_jit_stack *);
PCRE_EXP_DECL void pcre_assign_jit_stack(pcre_extra *,
                  pcre_jit_callback, void *);
PCRE_EXP_DECL void pcre16_assign_jit_stack(pcre16_extra *,
                  pcre16_jit_callback, void *);
PCRE_EXP_DECL void pcre32_assign_jit_stack(pcre32_extra *,
                  pcre32_jit_callback, void *);
PCRE_EXP_DECL void pcre_jit_free_unused_memory(void);
PCRE_EXP_DECL void pcre16_jit_free_unused_memory(void);
PCRE_EXP_DECL void pcre32_jit_free_unused_memory(void);

#ifdef __cplusplus
}  /* extern "C" */
#endif

#endif /* End of pcre.h */
php/ext/pcre/php_pcre.h000064400000006632151730540360011050 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Andrei Zmievski <andrei@php.net>                             |
   +----------------------------------------------------------------------+
 */
 
/* $Id: php_pcre.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_PCRE_H
#define PHP_PCRE_H

#if HAVE_PCRE || HAVE_BUNDLED_PCRE

#if HAVE_BUNDLED_PCRE
#include "pcrelib/pcre.h"
#else
#include "pcre.h"
#endif

#if HAVE_LOCALE_H
#include <locale.h>
#endif

PHP_FUNCTION(preg_match);
PHP_FUNCTION(preg_match_all);
PHP_FUNCTION(preg_replace);
PHP_FUNCTION(preg_replace_callback);
PHP_FUNCTION(preg_split);
PHP_FUNCTION(preg_quote);
PHP_FUNCTION(preg_grep);

PHPAPI char *php_pcre_replace(char *regex, int regex_len, char *subject, int subject_len, zval *replace_val, int is_callable_replace, int *result_len, int limit, int *replace_count TSRMLS_DC);
PHPAPI pcre* pcre_get_compiled_regex(char *regex, pcre_extra **extra, int *options TSRMLS_DC);
PHPAPI pcre* pcre_get_compiled_regex_ex(char *regex, pcre_extra **extra, int *preg_options, int *coptions TSRMLS_DC);

extern zend_module_entry pcre_module_entry;
#define pcre_module_ptr &pcre_module_entry

typedef struct {
	pcre *re;
	pcre_extra *extra;
	int preg_options;
#if HAVE_SETLOCALE
	char *locale;
	unsigned const char *tables;
#endif
	int compile_options;
	int refcount;
} pcre_cache_entry;

PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_len TSRMLS_DC);

PHPAPI void  php_pcre_match_impl(  pcre_cache_entry *pce, char *subject, int subject_len, zval *return_value,
	zval *subpats, int global, int use_flags, long flags, long start_offset TSRMLS_DC);

PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int subject_len, zval *return_value, 
	int is_callable_replace, int *result_len, int limit, int *replace_count TSRMLS_DC);

PHPAPI void  php_pcre_split_impl(  pcre_cache_entry *pce, char *subject, int subject_len, zval *return_value,
	long limit_val, long flags TSRMLS_DC);

PHPAPI void  php_pcre_grep_impl(   pcre_cache_entry *pce, zval *input, zval *return_value,
	long flags TSRMLS_DC);

ZEND_BEGIN_MODULE_GLOBALS(pcre)
	HashTable pcre_cache;
	long backtrack_limit;
	long recursion_limit;
	int  error_code;
ZEND_END_MODULE_GLOBALS(pcre)

#ifdef ZTS
# define PCRE_G(v) TSRMG(pcre_globals_id, zend_pcre_globals *, v)
#else
# define PCRE_G(v)	(pcre_globals.v)
#endif

#else

#define pcre_module_ptr NULL

#endif /* HAVE_PCRE || HAVE_BUNDLED_PCRE */

#define phpext_pcre_ptr pcre_module_ptr

#endif /* PHP_PCRE_H */
php/ext/session/php_session.h000064400000017336151730540360012337 0ustar00/* 
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Sascha Schumann <sascha@schumann.cx>                         |
   +----------------------------------------------------------------------+
 */

/* $Id: php_session.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_SESSION_H
#define PHP_SESSION_H

#include "ext/standard/php_var.h"

#define PHP_SESSION_API 20020330

#define PS_OPEN_ARGS void **mod_data, const char *save_path, const char *session_name TSRMLS_DC
#define PS_CLOSE_ARGS void **mod_data TSRMLS_DC
#define PS_READ_ARGS void **mod_data, const char *key, char **val, int *vallen TSRMLS_DC
#define PS_WRITE_ARGS void **mod_data, const char *key, const char *val, const int vallen TSRMLS_DC
#define PS_DESTROY_ARGS void **mod_data, const char *key TSRMLS_DC
#define PS_GC_ARGS void **mod_data, int maxlifetime, int *nrdels TSRMLS_DC
#define PS_CREATE_SID_ARGS void **mod_data, int *newlen TSRMLS_DC

/* default create id function */
PHPAPI char *php_session_create_id(PS_CREATE_SID_ARGS);

typedef struct ps_module_struct {
	const char *s_name;
	int (*s_open)(PS_OPEN_ARGS);
	int (*s_close)(PS_CLOSE_ARGS);
	int (*s_read)(PS_READ_ARGS);
	int (*s_write)(PS_WRITE_ARGS);
	int (*s_destroy)(PS_DESTROY_ARGS);
	int (*s_gc)(PS_GC_ARGS);
	char *(*s_create_sid)(PS_CREATE_SID_ARGS);
} ps_module;

#define PS_GET_MOD_DATA() *mod_data
#define PS_SET_MOD_DATA(a) *mod_data = (a)

#define PS_OPEN_FUNC(x) 	int ps_open_##x(PS_OPEN_ARGS)
#define PS_CLOSE_FUNC(x) 	int ps_close_##x(PS_CLOSE_ARGS)
#define PS_READ_FUNC(x) 	int ps_read_##x(PS_READ_ARGS)
#define PS_WRITE_FUNC(x) 	int ps_write_##x(PS_WRITE_ARGS)
#define PS_DESTROY_FUNC(x) 	int ps_delete_##x(PS_DESTROY_ARGS)
#define PS_GC_FUNC(x) 		int ps_gc_##x(PS_GC_ARGS)
#define PS_CREATE_SID_FUNC(x)	char *ps_create_sid_##x(PS_CREATE_SID_ARGS)

#define PS_FUNCS(x) \
	PS_OPEN_FUNC(x); \
	PS_CLOSE_FUNC(x); \
	PS_READ_FUNC(x); \
	PS_WRITE_FUNC(x); \
	PS_DESTROY_FUNC(x); \
	PS_GC_FUNC(x);	\
	PS_CREATE_SID_FUNC(x)

#define PS_MOD(x) \
	#x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \
	 ps_delete_##x, ps_gc_##x, php_session_create_id

/* SID enabled module handler definitions */
#define PS_FUNCS_SID(x) \
	PS_OPEN_FUNC(x); \
	PS_CLOSE_FUNC(x); \
	PS_READ_FUNC(x); \
	PS_WRITE_FUNC(x); \
	PS_DESTROY_FUNC(x); \
	PS_GC_FUNC(x); \
	PS_CREATE_SID_FUNC(x)

#define PS_MOD_SID(x) \
	#x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \
	 ps_delete_##x, ps_gc_##x, ps_create_sid_##x

typedef enum {
	php_session_disabled,
	php_session_none,
	php_session_active
} php_session_status;

typedef struct _php_ps_globals {
	char *save_path;
	char *session_name;
	char *id;
	char *extern_referer_chk;
	char *entropy_file;
	char *cache_limiter;
	long entropy_length;
	long cookie_lifetime;
	char *cookie_path;
	char *cookie_domain;
	zend_bool  cookie_secure;
	zend_bool  cookie_httponly;
	ps_module *mod;
	void *mod_data;
	php_session_status session_status;
	long gc_probability;
	long gc_divisor;
	long gc_maxlifetime;
	int module_number;
	long cache_expire;
	zend_bool bug_compat; /* Whether to behave like PHP 4.2 and earlier */
	zend_bool bug_compat_warn; /* Whether to warn about it */
	const struct ps_serializer_struct *serializer;
	zval *http_session_vars;
	zend_bool auto_start;
	zend_bool use_cookies;
	zend_bool use_only_cookies;
	zend_bool use_trans_sid;	/* contains the INI value of whether to use trans-sid */
	zend_bool apply_trans_sid;	/* whether or not to enable trans-sid for the current request */

	long hash_func;
	long hash_bits_per_character;
	int send_cookie;
	int define_sid;
	zend_bool invalid_session_id;	/* allows the driver to report about an invalid session id and request id regeneration */
} php_ps_globals;

typedef php_ps_globals zend_ps_globals;

extern zend_module_entry session_module_entry;
#define phpext_session_ptr &session_module_entry

#ifdef ZTS
#define PS(v) TSRMG(ps_globals_id, php_ps_globals *, v)
#else
#define PS(v) (ps_globals.v)
#endif

#define PS_SERIALIZER_ENCODE_ARGS char **newstr, int *newlen TSRMLS_DC
#define PS_SERIALIZER_DECODE_ARGS const char *val, int vallen TSRMLS_DC

typedef struct ps_serializer_struct {
	const char *name;
	int (*encode)(PS_SERIALIZER_ENCODE_ARGS);
	int (*decode)(PS_SERIALIZER_DECODE_ARGS);
} ps_serializer;

#define PS_SERIALIZER_ENCODE_NAME(x) ps_srlzr_encode_##x
#define PS_SERIALIZER_DECODE_NAME(x) ps_srlzr_decode_##x

#define PS_SERIALIZER_ENCODE_FUNC(x) \
	int PS_SERIALIZER_ENCODE_NAME(x)(PS_SERIALIZER_ENCODE_ARGS)
#define PS_SERIALIZER_DECODE_FUNC(x) \
	int PS_SERIALIZER_DECODE_NAME(x)(PS_SERIALIZER_DECODE_ARGS)

#define PS_SERIALIZER_FUNCS(x) \
	PS_SERIALIZER_ENCODE_FUNC(x); \
	PS_SERIALIZER_DECODE_FUNC(x)

#define PS_SERIALIZER_ENTRY(x) \
	{ #x, PS_SERIALIZER_ENCODE_NAME(x), PS_SERIALIZER_DECODE_NAME(x) }

PHPAPI void session_adapt_url(const char *, size_t, char **, size_t * TSRMLS_DC);

PHPAPI void php_add_session_var(char *name, size_t namelen TSRMLS_DC);
PHPAPI void php_set_session_var(char *name, size_t namelen, zval *state_val, php_unserialize_data_t *var_hash TSRMLS_DC);
PHPAPI int php_get_session_var(char *name, size_t namelen, zval ***state_var TSRMLS_DC);

PHPAPI int php_session_register_module(ps_module *);

PHPAPI int php_session_register_serializer(const char *name,
	        int (*encode)(PS_SERIALIZER_ENCODE_ARGS),
	        int (*decode)(PS_SERIALIZER_DECODE_ARGS));

PHPAPI void php_session_set_id(char *id TSRMLS_DC);
PHPAPI void php_session_start(TSRMLS_D);

PHPAPI ps_module *_php_find_ps_module(char *name TSRMLS_DC);
PHPAPI const ps_serializer *_php_find_ps_serializer(char *name TSRMLS_DC);

#define PS_ADD_VARL(name,namelen) do {										\
	php_add_session_var(name, namelen TSRMLS_CC);							\
} while (0)

#define PS_ADD_VAR(name) PS_ADD_VARL(name, strlen(name))

#define PS_DEL_VARL(name,namelen) do {										\
	if (PS(http_session_vars)) {											\
		zend_hash_del(Z_ARRVAL_P(PS(http_session_vars)), name, namelen+1);	\
	}																		\
} while (0)


#define PS_ENCODE_VARS 											\
	char *key;													\
	uint key_length;											\
	ulong num_key;												\
	zval **struc;

#define PS_ENCODE_LOOP(code) do {									\
		HashTable *_ht = Z_ARRVAL_P(PS(http_session_vars));			\
		int key_type;												\
																	\
		for (zend_hash_internal_pointer_reset(_ht);					\
				(key_type = zend_hash_get_current_key_ex(_ht, &key, &key_length, &num_key, 0, NULL)) != HASH_KEY_NON_EXISTANT; \
					zend_hash_move_forward(_ht)) {					\
			if (key_type == HASH_KEY_IS_LONG) {						\
				php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Skipping numeric key %ld", num_key);	\
				continue;											\
			}														\
			key_length--;											\
			if (php_get_session_var(key, key_length, &struc TSRMLS_CC) == SUCCESS) {	\
				code;		 										\
			} 														\
		}															\
	} while(0)

PHPAPI ZEND_EXTERN_MODULE_GLOBALS(ps)

void php_session_auto_start(void *data);
void php_session_shutdown(void *data);

#endif
php/ext/session/mod_files.h000064400000002502151730540360011733 0ustar00/* 
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Sascha Schumann <sascha@schumann.cx>                         |
   +----------------------------------------------------------------------+
 */

/* $Id: mod_files.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef MOD_FILES_H
#define MOD_FILES_H

extern ps_module ps_mod_files;
#define ps_files_ptr &ps_mod_files

PS_FUNCS(files);

#endif
php/ext/session/mod_user.h000064400000002744151730540370011620 0ustar00/* 
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Sascha Schumann <sascha@schumann.cx>                         |
   +----------------------------------------------------------------------+
 */

/* $Id: mod_user.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef MOD_USER_H
#define MOD_USER_H

typedef union {
	zval *names[6];
	struct {
		zval *ps_open;
		zval *ps_close;
		zval *ps_read;
		zval *ps_write;
		zval *ps_destroy;
		zval *ps_gc;
	} name;
} ps_user;

extern ps_module ps_mod_user;
#define ps_user_ptr &ps_mod_user

PS_FUNCS(user);

#endif
php/ext/apcu/apc_globals.h000064400000007064151730540370011516 0ustar00/*
  +----------------------------------------------------------------------+
  | APC                                                                  |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2011 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt.                                 |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Daniel Cowgill <dcowgill@communityconnect.com>              |
  |          George Schlossnagle <george@omniti.com>                     |
  |          Rasmus Lerdorf <rasmus@php.net>                             |
  |          Arun C. Murthy <arunc@yahoo-inc.com>                        |
  |          Gopal Vijayaraghavan <gopalv@yahoo-inc.com>                 |
  +----------------------------------------------------------------------+

   This software was contributed to PHP by Community Connect Inc. in 2002
   and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
   Future revisions and derivatives of this source code must acknowledge
   Community Connect Inc. as the original contributor of this module by
   leaving this note intact in the source code.

   All other licensing and usage conditions are those of the PHP Group.

 */

#ifndef APC_GLOBALS_H
#define APC_GLOBALS_H

#include "apc.h"

ZEND_BEGIN_MODULE_GLOBALS(apcu)
	/* configuration parameters */
	zend_bool enabled;      /* if true, apc is enabled (defaults to true) */
	zend_long shm_segments;      /* number of shared memory segments to use */
	zend_long shm_size;          /* size of each shared memory segment (in MB) */
	zend_long entries_hint;      /* hint at the number of entries expected */
	zend_long gc_ttl;            /* parameter to apc_cache_create */
	zend_long ttl;               /* parameter to apc_cache_create */
	zend_long smart;             /* smart value */

#if APC_MMAP
	char *mmap_file_mask;   /* mktemp-style file-mask to pass to mmap */
#endif

	/* module variables */
	zend_bool initialized;       /* true if module was initialized */
	zend_bool enable_cli;        /* Flag to override turning APC off for CLI */
	zend_bool slam_defense;      /* true for user cache slam defense */

	char *preload_path;          /* preload path */
	zend_bool coredump_unmap;    /* trap signals that coredump and unmap shared memory */
	zend_bool use_request_time;  /* use the SAPI request start time for TTL */
	time_t request_time;         /* cached request time */

	char *serializer_name;       /* the serializer config option */

	/* Nesting level of apcu_entry calls. */
	unsigned int entry_level;
ZEND_END_MODULE_GLOBALS(apcu)

/* (the following is defined in php_apc.c) */
ZEND_EXTERN_MODULE_GLOBALS(apcu)

#ifdef ZTS
# define APCG(v) TSRMG(apcu_globals_id, zend_apcu_globals *, v)
#else
# define APCG(v) (apcu_globals.v)
#endif

extern struct _apc_cache_t* apc_user_cache;

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim>600: noexpandtab sw=4 ts=4 sts=4 fdm=marker
 * vim<600: noexpandtab sw=4 ts=4 sts=4
 */
php/ext/apcu/apc_cache.h000064400000032033151730540370011130 0ustar00/*
  +----------------------------------------------------------------------+
  | APC                                                                  |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2011 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt.                                 |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Daniel Cowgill <dcowgill@communityconnect.com>              |
  |          Rasmus Lerdorf <rasmus@php.net>                             |
  +----------------------------------------------------------------------+

   This software was contributed to PHP by Community Connect Inc. in 2002
   and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
   Future revisions and derivatives of this source code must acknowledge
   Community Connect Inc. as the original contributor of this module by
   leaving this note intact in the source code.

   All other licensing and usage conditions are those of the PHP Group.

 */

#ifndef APC_CACHE_H
#define APC_CACHE_H

#include "apc.h"
#include "apc_sma.h"
#include "apc_lock.h"
#include "apc_globals.h"
#include "TSRM.h"

typedef struct apc_cache_slam_key_t apc_cache_slam_key_t;
struct apc_cache_slam_key_t {
	zend_ulong hash;         /* hash of the key */
	size_t len;              /* length of the key */
	time_t mtime;            /* creation time of this key */
	pid_t owner_pid;         /* the pid that created this key */
#ifdef ZTS
	void ***owner_thread;    /* TSRMLS cache of thread that created this key */
#endif
};

/* {{{ struct definition: apc_cache_entry_t */
typedef struct apc_cache_entry_t apc_cache_entry_t;
struct apc_cache_entry_t {
	zend_string *key;        /* entry key */
	zval val;                /* the zval copied at store time */
	apc_cache_entry_t *next; /* next entry in linked list */
	zend_long ttl;           /* the ttl on this specific entry */
	zend_long ref_count;     /* the reference count of this entry */
	zend_long nhits;         /* number of hits to this entry */
	time_t ctime;            /* time entry was initialized */
	time_t mtime;            /* the mtime of this cached entry */
	time_t dtime;            /* time entry was removed from cache */
	time_t atime;            /* time entry was last accessed */
	zend_long mem_size;      /* memory used */
};
/* }}} */

/* {{{ struct definition: apc_cache_header_t
   Any values that must be shared among processes should go in here. */
typedef struct _apc_cache_header_t {
	apc_lock_t lock;                /* header lock */
	zend_long nhits;                /* hit count */
	zend_long nmisses;              /* miss count */
	zend_long ninserts;             /* insert count */
	zend_long nexpunges;            /* expunge count */
	zend_long nentries;             /* entry count */
	zend_long mem_size;             /* used */
	time_t stime;                   /* start time */
	unsigned short state;           /* cache state */
	apc_cache_slam_key_t lastkey;   /* last key inserted (not necessarily without error) */
	apc_cache_entry_t *gc;          /* gc list */
} apc_cache_header_t; /* }}} */

/* {{{ struct definition: apc_cache_t */
typedef struct _apc_cache_t {
	void* shmaddr;                /* process (local) address of shared cache */
	apc_cache_header_t* header;   /* cache header (stored in SHM) */
	apc_cache_entry_t** slots;    /* array of cache slots (stored in SHM) */
	apc_sma_t* sma;               /* shared memory allocator */
	apc_serializer_t* serializer; /* serializer */
	size_t nslots;                /* number of slots in cache */
	zend_long gc_ttl;            /* maximum time on GC list for a entry */
	zend_long ttl;               /* if slot is needed and entry's access time is older than this ttl, remove it */
	zend_long smart;             /* smart parameter for gc */
	zend_bool defend;             /* defense parameter for runtime */
} apc_cache_t; /* }}} */

/* {{{ typedef: apc_cache_updater_t */
typedef zend_bool (*apc_cache_updater_t)(apc_cache_t*, apc_cache_entry_t*, void* data); /* }}} */

/* {{{ typedef: apc_cache_atomic_updater_t */
typedef zend_bool (*apc_cache_atomic_updater_t)(apc_cache_t*, zend_long*, void* data); /* }}} */

/*
 * apc_cache_create creates the shared memory cache.
 *
 * This function should be called once per process per cache
 *
 * serializer for APCu is set by globals on MINIT and ensured with apc_cache_serializer
 * during execution. Using apc_cache_serializer avoids race conditions between MINIT/RINIT of
 * APCU and the third party serializer. API users can choose to leave this null to use default
 * PHP serializers, or search the list of serializers for the preferred serializer
 *
 * size_hint is a "hint" at the total number entries that will be expected.
 * It determines the physical size of the hash table. Passing 0 for
 * this argument will use a reasonable default value
 *
 * gc_ttl is the maximum time a cache entry may speed on the garbage
 * collection list. This is basically a work around for the inherent
 * unreliability of our reference counting mechanism (see apc_cache_release).
 *
 * ttl is the maximum time a cache entry can idle in a slot in case the slot
 * is needed.  This helps in cleaning up the cache and ensuring that entries
 * hit frequently stay cached and ones not hit very often eventually disappear.
 *
 * for an explanation of smart, see apc_cache_default_expunge
 *
 * defend enables/disables slam defense for this particular cache
 */
PHP_APCU_API apc_cache_t* apc_cache_create(
        apc_sma_t* sma, apc_serializer_t* serializer, zend_long size_hint,
        zend_long gc_ttl, zend_long ttl, zend_long smart, zend_bool defend);
/*
* apc_cache_preload preloads the data at path into the specified cache
*/
PHP_APCU_API zend_bool apc_cache_preload(apc_cache_t* cache, const char* path);

/*
 * apc_cache_detach detaches from the shared memory cache and cleans up
 * local allocations. Under apache, this function can be safely called by
 * the child processes when they exit.
 */
PHP_APCU_API void apc_cache_detach(apc_cache_t* cache);

/*
 * apc_cache_clear empties a cache. This can safely be called at any time.
 */
PHP_APCU_API void apc_cache_clear(apc_cache_t* cache);

/*
 * apc_cache_store creates key, entry and context in which to make an insertion of val into the specified cache
 */
PHP_APCU_API zend_bool apc_cache_store(
        apc_cache_t* cache, zend_string *key, const zval *val,
        const int32_t ttl, const zend_bool exclusive);
/*
 * apc_cache_update updates an entry in place. The updater function must not bailout.
 * The update is performed under write-lock and doesn't have to be atomic.
 */
PHP_APCU_API zend_bool apc_cache_update(
		apc_cache_t *cache, zend_string *key, apc_cache_updater_t updater, void *data,
		zend_bool insert_if_not_found, zend_long ttl);

/*
 * apc_cache_atomic_update_long updates an integer entry in place. The updater function must
 * perform the update atomically, as the update is performed under read-lock.
 */
PHP_APCU_API zend_bool apc_cache_atomic_update_long(
		apc_cache_t *cache, zend_string *key, apc_cache_atomic_updater_t updater, void *data,
		zend_bool insert_if_not_found, zend_long ttl);

/*
 * apc_cache_find searches for a cache entry by its hashed identifier,
 * and returns a pointer to the entry if found, NULL otherwise.
 *
 */
PHP_APCU_API apc_cache_entry_t* apc_cache_find(apc_cache_t* cache, zend_string *key, time_t t);

/*
 * apc_cache_fetch fetches an entry from the cache directly into dst
 *
 */
PHP_APCU_API zend_bool apc_cache_fetch(apc_cache_t* cache, zend_string *key, time_t t, zval *dst);

/*
 * apc_cache_exists searches for a cache entry by its hashed identifier,
 * and returns whether the entry exists.
 */
PHP_APCU_API zend_bool apc_cache_exists(apc_cache_t* cache, zend_string *key, time_t t);

/*
 * apc_cache_delete and apc_cache_delete finds an entry in the cache and deletes it.
 */
PHP_APCU_API zend_bool apc_cache_delete(apc_cache_t* cache, zend_string *key);

/* apc_cache_fetch_zval copies a cache entry value to be usable at runtime.
 */
PHP_APCU_API zend_bool apc_cache_entry_fetch_zval(
		apc_cache_t *cache, apc_cache_entry_t *entry, zval *dst);

/*
 * apc_cache_entry_release decrements the reference count associated with a cache
 * entry. Calling apc_cache_find automatically increments the reference count,
 * and this function must be called post-execution to return the count to its
 * original value. Failing to do so will prevent the entry from being
 * garbage-collected.
 *
 * entry is the cache entry whose ref count you want to decrement.
 */
PHP_APCU_API void apc_cache_entry_release(apc_cache_t *cache, apc_cache_entry_t *entry);

/*
 fetches information about the cache provided for userland status functions
*/
PHP_APCU_API zend_bool apc_cache_info(zval *info, apc_cache_t *cache, zend_bool limited);

/*
 fetches information about the key provided
*/
PHP_APCU_API void apc_cache_stat(apc_cache_t *cache, zend_string *key, zval *stat);

/*
* apc_cache_defense: guard against slamming a key
*  will return true if the following conditions are met:
*	the key provided has a matching hash and length to the last key inserted into cache
*   the last key has a different owner
* in ZTS mode, TSRM determines owner
* in non-ZTS mode, PID determines owner
* Note: this function sets the owner of key during execution
*/
PHP_APCU_API zend_bool apc_cache_defense(apc_cache_t *cache, zend_string *key, time_t t);

/*
* apc_cache_serializer
* sets the serializer for a cache, and by proxy contexts created for the cache
* Note: this avoids race conditions between third party serializers and APCu
*/
PHP_APCU_API void apc_cache_serializer(apc_cache_t* cache, const char* name);

/*
* The remaining functions allow a third party to reimplement expunge
*
* Look at the source of apc_cache_default_expunge for what is expected of this function
*
* The default behaviour of expunge is explained below, should no combination of those options
* be suitable, you will need to reimplement apc_cache_default_expunge and pass it to your
* call to apc_sma_api_impl, this will replace the default functionality.
* The functions below you can use during your own implementation of expunge to gain more
* control over how the expunge process works ...
*
* Note: beware of locking (copy it exactly), setting states is also important
*/

/* {{{ apc_cache_default_expunge
* Where smart is not set:
*  Where no ttl is set on cache:
*   1) Perform cleanup of stale entries
*   2) Expunge if available memory is less than sma->size/2
*  Where ttl is set on cache:
*   1) Perform cleanup of stale entries
*   2) If available memory if less than the size requested, run full expunge
*
* Where smart is set:
*  Where no ttl is set on cache:
*   1) Perform cleanup of stale entries
*   2) Expunge is available memory is less than size * smart
*  Where ttl is set on cache:
*   1) Perform cleanup of stale entries
*   2) If available memory if less than the size requested, run full expunge
*
* The TTL of an entry takes precedence over the TTL of a cache
*/
PHP_APCU_API void apc_cache_default_expunge(apc_cache_t* cache, size_t size);

/*
* apc_cache_entry: generate and create or fetch an entry
*
* @see https://github.com/krakjoe/apcu/issues/142
*/
PHP_APCU_API void apc_cache_entry(apc_cache_t *cache, zend_string *key, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zend_long ttl, zend_long now, zval *return_value);

/* apcu_entry() holds a write lock on the cache while executing user code.
 * That code may call other apcu_* functions, which also try to acquire a
 * read or write lock, which would deadlock. As such, don't try to acquire a
 * lock if the current thread is inside apcu_entry().
 *
 * Whether the current thread is inside apcu_entry() is tracked by APCG(entry_level).
 * This breaks the self-contained apc_cache_t abstraction, but is currently
 * necessary because the entry_level needs to be tracked per-thread, while
 * apc_cache_t is a per-process structure.
 */

static inline zend_bool apc_cache_wlock(apc_cache_t *cache) {
	if (!APCG(entry_level)) {
		return WLOCK(&cache->header->lock);
	}
	return 1;
}

static inline void apc_cache_wunlock(apc_cache_t *cache) {
	if (!APCG(entry_level)) {
		WUNLOCK(&cache->header->lock);
	}
}

static inline zend_bool apc_cache_rlock(apc_cache_t *cache) {
	if (!APCG(entry_level)) {
		return RLOCK(&cache->header->lock);
	}
	return 1;
}

static inline void apc_cache_runlock(apc_cache_t *cache) {
	if (!APCG(entry_level)) {
		RUNLOCK(&cache->header->lock);
	}
}

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim>600: noexpandtab sw=4 ts=4 sts=4 fdm=marker
 * vim<600: noexpandtab sw=4 ts=4 sts=4
 */
php/ext/apcu/apc_lock.h000064400000010521151730540400011005 0ustar00/*
  +----------------------------------------------------------------------+
  | APCu                                                                 |
  +----------------------------------------------------------------------+
  | Copyright (c) 2013 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: Joe Watkins <joe.watkins@live.co.uk>                        |
  +----------------------------------------------------------------------+
 */

#ifndef APC_LOCK_H
#define APC_LOCK_H

/*
 APCu works most efficiently where there is access to native read/write locks
 If the current system has native rwlocks present they will be used, if they are
	not present, APCu will emulate their behavior with standard mutex.
 While APCu is emulating read/write locks, reads and writes are exclusive,
	additionally the write lock prefers readers, as is the default behaviour of
	the majority of Posix rwlock implementations
*/

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include "apc.h"

#ifndef PHP_WIN32
# ifndef __USE_UNIX98
#  define __USE_UNIX98
# endif
# include "pthread.h"
# ifndef APC_SPIN_LOCK
#   ifndef APC_FCNTL_LOCK
#       ifdef APC_NATIVE_RWLOCK
		typedef pthread_rwlock_t apc_lock_t;
#		define APC_LOCK_SHARED
#       else
		typedef pthread_mutex_t apc_lock_t;
#		define APC_LOCK_RECURSIVE
#       endif
#   else
		typedef int apc_lock_t;
#		define APC_LOCK_FILE
#   endif
# else
# define APC_LOCK_NICE 1
typedef struct {
	unsigned long state;
} apc_lock_t;
# endif
#else
/* XXX kernel lock mode only for now, compatible through all the wins, add more ifdefs for others */
# include "apc_windows_srwlock_kernel.h"
typedef apc_windows_cs_rwlock_t apc_lock_t;
# define APC_LOCK_SHARED
#endif

/* {{{ functions */
/*
  The following functions should be called once per process:
	apc_lock_init initializes attributes suitable for all locks
	apc_lock_cleanup destroys those attributes
  This saves us from having to create and destroy attributes for
  every lock we use at runtime */
PHP_APCU_API zend_bool apc_lock_init(void);
PHP_APCU_API void      apc_lock_cleanup(void);
/*
  The following functions should be self explanitory:
*/
PHP_APCU_API zend_bool apc_lock_create(apc_lock_t *lock);
PHP_APCU_API zend_bool apc_lock_rlock(apc_lock_t *lock);
PHP_APCU_API zend_bool apc_lock_wlock(apc_lock_t *lock);
PHP_APCU_API zend_bool apc_lock_runlock(apc_lock_t *lock);
PHP_APCU_API zend_bool apc_lock_wunlock(apc_lock_t *lock);
PHP_APCU_API void apc_lock_destroy(apc_lock_t *lock); /* }}} */

/* {{{ generic locking macros */
#define CREATE_LOCK(lock)     apc_lock_create(lock)
#define DESTROY_LOCK(lock)    apc_lock_destroy(lock)
#define WLOCK(lock)           apc_lock_wlock(lock)
#define WUNLOCK(lock)         { apc_lock_wunlock(lock); HANDLE_UNBLOCK_INTERRUPTIONS(); }
#define RLOCK(lock)           apc_lock_rlock(lock)
#define RUNLOCK(lock)         { apc_lock_runlock(lock); HANDLE_UNBLOCK_INTERRUPTIONS(); }
/* }}} */

/* atomic operations */
#ifdef PHP_WIN32
# ifdef _WIN64
#  define ATOMIC_INC(a) InterlockedIncrement64(&a)
#  define ATOMIC_DEC(a) InterlockedDecrement64(&a)
#  define ATOMIC_ADD(a, b) (InterlockedExchangeAdd64(&a, b) + b)
#  define ATOMIC_CAS(a, old, new) (InterlockedCompareExchange64(&a, new, old) == old)
# else
#  define ATOMIC_INC(a) InterlockedIncrement(&a)
#  define ATOMIC_DEC(a) InterlockedDecrement(&a)
#  define ATOMIC_ADD(a, b) (InterlockedExchangeAdd(&a, b) + b)
#  define ATOMIC_CAS(a, old, new) (InterlockedCompareExchange(&a, new, old) == old)
# endif
#else
# define ATOMIC_INC(a) __sync_add_and_fetch(&a, 1)
# define ATOMIC_DEC(a) __sync_sub_and_fetch(&a, 1)
# define ATOMIC_ADD(a, b) __sync_add_and_fetch(&a, b)
# define ATOMIC_CAS(a, old, new) __sync_bool_compare_and_swap(&a, old, new)
#endif

#endif
php/ext/apcu/php_apc.h000064400000004353151730540400010652 0ustar00/*
  +----------------------------------------------------------------------+
  | APC                                                                  |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2011 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Daniel Cowgill <dcowgill@communityconnect.com>              |
  |          George Schlossnagle <george@omniti.com>                     |
  |          Rasmus Lerdorf <rasmus@php.net>                             |
  +----------------------------------------------------------------------+

   This software was contributed to PHP by Community Connect Inc. in 2002
   and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
   Future revisions and derivatives of this source code must acknowledge
   Community Connect Inc. as the original contributor of this module by
   leaving this note intact in the source code.

   All other licensing and usage conditions are those of the PHP Group.

 */

#ifndef PHP_APCU_H
#define PHP_APCU_H

#include "apc.h"
#include "apc_globals.h"

#define PHP_APCU_VERSION "5.1.23"
#define PHP_APCU_EXTNAME "apcu"

PHP_APCU_API zend_bool apc_is_enabled(void);

extern zend_module_entry apcu_module_entry;
#define apcu_module_ptr &apcu_module_entry

#define phpext_apcu_ptr apcu_module_ptr

#if defined(ZTS) && defined(COMPILE_DL_APCU)
ZEND_TSRMLS_CACHE_EXTERN();
#endif

#endif /* PHP_APC_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim>600: noexpandtab sw=4 ts=4 sts=4 fdm=marker
 * vim<600: noexpandtab sw=4 ts=4 sts=4
 */
php/ext/apcu/apc_arginfo.h000064400000000161151730540400011501 0ustar00#if PHP_VERSION_ID < 80000
# include "php_apc_legacy_arginfo.h"
#else
# error Not supported on PHP >= 8.0
#endif
php/ext/apcu/apc_api.h000064400000002355151730540400010634 0ustar00/*
  +----------------------------------------------------------------------+
  | APCu                                                                 |
  +----------------------------------------------------------------------+
  | Copyright (c) 2013 The PHP Group                                     |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: Joe Watkins <joe.watkins@live.co.uk>                         |
  +----------------------------------------------------------------------+
 */

#ifndef APC_API_H
#define APC_API_H

#include "apc.h"
#include "apc_lock.h"
#include "apc_sma.h"
#include "apc_cache.h"

#endif
php/ext/apcu/php_apc_legacy_arginfo.h000064400000005645151730540410013711 0ustar00/* This is a generated file, edit the .stub.php file instead.
 * Stub hash: 5282d856fd334278d5799581ad251977a3c6b18e */

ZEND_BEGIN_ARG_INFO_EX(arginfo_apcu_clear_cache, 0, 0, 0)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_apcu_cache_info, 0, 0, 0)
	ZEND_ARG_INFO(0, limited)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_apcu_key_info, 0, 0, 1)
	ZEND_ARG_INFO(0, key)
ZEND_END_ARG_INFO()

#define arginfo_apcu_sma_info arginfo_apcu_cache_info

#define arginfo_apcu_enabled arginfo_apcu_clear_cache

ZEND_BEGIN_ARG_INFO_EX(arginfo_apcu_store, 0, 0, 1)
	ZEND_ARG_INFO(0, key)
	ZEND_ARG_INFO(0, value)
	ZEND_ARG_INFO(0, ttl)
ZEND_END_ARG_INFO()

#define arginfo_apcu_add arginfo_apcu_store

ZEND_BEGIN_ARG_INFO_EX(arginfo_apcu_inc, 0, 0, 1)
	ZEND_ARG_INFO(0, key)
	ZEND_ARG_INFO(0, step)
	ZEND_ARG_INFO(1, success)
	ZEND_ARG_INFO(0, ttl)
ZEND_END_ARG_INFO()

#define arginfo_apcu_dec arginfo_apcu_inc

ZEND_BEGIN_ARG_INFO_EX(arginfo_apcu_cas, 0, 0, 3)
	ZEND_ARG_INFO(0, key)
	ZEND_ARG_INFO(0, old)
	ZEND_ARG_INFO(0, new)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_apcu_fetch, 0, 0, 1)
	ZEND_ARG_INFO(0, key)
	ZEND_ARG_INFO(1, success)
ZEND_END_ARG_INFO()

#define arginfo_apcu_exists arginfo_apcu_key_info

#define arginfo_apcu_delete arginfo_apcu_key_info

ZEND_BEGIN_ARG_INFO_EX(arginfo_apcu_entry, 0, 0, 2)
	ZEND_ARG_INFO(0, key)
	ZEND_ARG_INFO(0, callback)
	ZEND_ARG_INFO(0, ttl)
ZEND_END_ARG_INFO()

#if defined(APC_DEBUG)
ZEND_BEGIN_ARG_INFO_EX(arginfo_apcu_inc_request_time, 0, 0, 0)
	ZEND_ARG_INFO(0, by)
ZEND_END_ARG_INFO()
#endif


PHP_APCU_API ZEND_FUNCTION(apcu_clear_cache);
PHP_APCU_API ZEND_FUNCTION(apcu_cache_info);
PHP_APCU_API ZEND_FUNCTION(apcu_key_info);
PHP_APCU_API ZEND_FUNCTION(apcu_sma_info);
PHP_APCU_API ZEND_FUNCTION(apcu_enabled);
PHP_APCU_API ZEND_FUNCTION(apcu_store);
PHP_APCU_API ZEND_FUNCTION(apcu_add);
PHP_APCU_API ZEND_FUNCTION(apcu_inc);
PHP_APCU_API ZEND_FUNCTION(apcu_dec);
PHP_APCU_API ZEND_FUNCTION(apcu_cas);
PHP_APCU_API ZEND_FUNCTION(apcu_fetch);
PHP_APCU_API ZEND_FUNCTION(apcu_exists);
PHP_APCU_API ZEND_FUNCTION(apcu_delete);
PHP_APCU_API ZEND_FUNCTION(apcu_entry);
#if defined(APC_DEBUG)
PHP_APCU_API ZEND_FUNCTION(apcu_inc_request_time);
#endif


static const zend_function_entry ext_functions[] = {
	ZEND_FE(apcu_clear_cache, arginfo_apcu_clear_cache)
	ZEND_FE(apcu_cache_info, arginfo_apcu_cache_info)
	ZEND_FE(apcu_key_info, arginfo_apcu_key_info)
	ZEND_FE(apcu_sma_info, arginfo_apcu_sma_info)
	ZEND_FE(apcu_enabled, arginfo_apcu_enabled)
	ZEND_FE(apcu_store, arginfo_apcu_store)
	ZEND_FE(apcu_add, arginfo_apcu_add)
	ZEND_FE(apcu_inc, arginfo_apcu_inc)
	ZEND_FE(apcu_dec, arginfo_apcu_dec)
	ZEND_FE(apcu_cas, arginfo_apcu_cas)
	ZEND_FE(apcu_fetch, arginfo_apcu_fetch)
	ZEND_FE(apcu_exists, arginfo_apcu_exists)
	ZEND_FE(apcu_delete, arginfo_apcu_delete)
	ZEND_FE(apcu_entry, arginfo_apcu_entry)
#if defined(APC_DEBUG)
	ZEND_FE(apcu_inc_request_time, arginfo_apcu_inc_request_time)
#endif
	ZEND_FE_END
};
php/ext/apcu/apc_serializer.h000064400000005731151730540410012236 0ustar00/*
  +----------------------------------------------------------------------+
  | APC                                                                  |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2011 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt.                                 |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Gopal Vijayaraghavan <gopalv@php.net>                       |
  +----------------------------------------------------------------------+

 */

#ifndef APC_SERIALIZER_H
#define APC_SERIALIZER_H

/* this is a shipped .h file, do not include any other header in this file */
#define APC_SERIALIZER_NAME(module) module##_apc_serializer
#define APC_UNSERIALIZER_NAME(module) module##_apc_unserializer

#define APC_SERIALIZER_ARGS unsigned char **buf, size_t *buf_len, const zval *value, void *config
#define APC_UNSERIALIZER_ARGS zval *value, unsigned char *buf, size_t buf_len, void *config

typedef int (*apc_serialize_t)(APC_SERIALIZER_ARGS);
typedef int (*apc_unserialize_t)(APC_UNSERIALIZER_ARGS);

typedef int (*apc_register_serializer_t)(const char* name, apc_serialize_t serialize, apc_unserialize_t unserialize, void *config);

/*
 * ABI version for constant hooks. Increment this any time you make any changes
 * to any function in this file.
 */
#define APC_SERIALIZER_ABI "0"
#define APC_SERIALIZER_CONSTANT "\000apc_register_serializer-" APC_SERIALIZER_ABI

#if !defined(APC_UNUSED)
# if defined(__GNUC__)
#  define APC_UNUSED __attribute__((unused))
# else
# define APC_UNUSED
# endif
#endif

static APC_UNUSED int apc_register_serializer(
        const char* name, apc_serialize_t serialize, apc_unserialize_t unserialize, void *config)
{
	int retval = 0;

	zend_string *lookup = zend_string_init(
		APC_SERIALIZER_CONSTANT, sizeof(APC_SERIALIZER_CONSTANT)-1, 0);
	zval *magic = zend_get_constant(lookup);

	/* zend_get_constant will return 1 on success, otherwise apc_magic_constant wouldn't be touched at all */
	if (magic) {
		apc_register_serializer_t register_func = (apc_register_serializer_t)(Z_LVAL_P(magic));
		if(register_func) {
			retval = register_func(name, serialize, unserialize, NULL);
		}
	}

	zend_string_release(lookup);

	return retval;
}

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim>600: noexpandtab sw=4 ts=4 sts=4 fdm=marker
 * vim<600: noexpandtab sw=4 ts=4 sts=4
 */
php/ext/apcu/apc_iterator.h000064400000007446151730540410011723 0ustar00/*
  +----------------------------------------------------------------------+
  | APC                                                                  |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2011 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Brian Shire <shire@.php.net>                                |
  +----------------------------------------------------------------------+

 */

#ifndef APC_ITERATOR_H
#define APC_ITERATOR_H

#include "apc.h"
#include "apc_stack.h"

#include "ext/pcre/php_pcre.h"
#include "zend_smart_str.h"

#define APC_DEFAULT_CHUNK_SIZE 100

#define APC_LIST_ACTIVE   0x1
#define APC_LIST_DELETED  0x2

#define APC_ITER_TYPE		(1 << 0)
#define APC_ITER_KEY        (1 << 1)
#define APC_ITER_VALUE      (1 << 2)
#define APC_ITER_NUM_HITS   (1 << 3)
#define APC_ITER_MTIME      (1 << 4)
#define APC_ITER_CTIME      (1 << 5)
#define APC_ITER_DTIME      (1 << 6)
#define APC_ITER_ATIME      (1 << 7)
#define APC_ITER_REFCOUNT   (1 << 8)
#define APC_ITER_MEM_SIZE   (1 << 9)
#define APC_ITER_TTL        (1 << 10)

#define APC_ITER_NONE       0
#define APC_ITER_ALL        (0xffffffffL)

/* {{{ apc_iterator_t */
typedef struct _apc_iterator_t {
	short int initialized;   /* sanity check in case __construct failed */
	zend_long format;             /* format bitmask of the return values ie: key, value, info */
	size_t (*fetch)(struct _apc_iterator_t *iterator);
							 /* fetch callback to fetch items from cache slots or lists */
	size_t slot_idx;           /* index to the slot array or linked list */
	size_t chunk_size;         /* number of entries to pull down per fetch */
	apc_stack_t *stack;      /* stack of entries pulled from cache */
	int stack_idx;           /* index into the current stack */
	pcre_cache_entry *pce;     /* regex filter on entry identifiers */
#if PHP_VERSION_ID >= 70300
	pcre2_match_data *re_match_data; /* match data for regex */
#endif
	zend_string *regex;
	HashTable *search_hash;  /* hash of keys to iterate over */
	zend_long key_idx;            /* incrementing index for numerical keys */
	short int totals_flag;   /* flag if totals have been calculated */
	zend_long hits;               /* hit total */
	size_t size;             /* size total */
	zend_long count;              /* count total */
	zend_object obj;
} apc_iterator_t;
/* }}} */

#define apc_iterator_fetch_from(o) ((apc_iterator_t*)((char*)o - XtOffsetOf(apc_iterator_t, obj)))
#define apc_iterator_fetch(z) apc_iterator_fetch_from(Z_OBJ_P(z))

/* {{{ apc_iterator_item */
typedef struct _apc_iterator_item_t {
	zend_string *key;
	zval value;
} apc_iterator_item_t;
/* }}} */

PHP_APCU_API void apc_iterator_obj_init(
	apc_iterator_t *iterator,
	zval *search,
	zend_long format,
	size_t chunk_size,
	zend_long list);
PHP_APCU_API zend_class_entry* apc_iterator_get_ce(void);
PHP_APCU_API int apc_iterator_init(int module_number);
PHP_APCU_API int apc_iterator_shutdown(int module_number);

extern int apc_iterator_delete(zval *key);
#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim>600: noexpandtab sw=4 ts=4 sts=4 fdm=marker
 * vim<600: noexpandtab sw=4 ts=4 sts=4
 */
php/ext/apcu/apc_stack.h000064400000004353151730540410011171 0ustar00/*
  +----------------------------------------------------------------------+
  | APC                                                                  |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2011 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Daniel Cowgill <dcowgill@communityconnect.com>              |
  |          George Schlossnagle <george@omniti.com>                     |
  +----------------------------------------------------------------------+

   This software was contributed to PHP by Community Connect Inc. in 2002
   and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
   Future revisions and derivatives of this source code must acknowledge
   Community Connect Inc. as the original contributor of this module by
   leaving this note intact in the source code.

   All other licensing and usage conditions are those of the PHP Group.

 */

#ifndef APC_STACK_H
#define APC_STACK_H

/* Basic stack datatype */

#define T apc_stack_t*
typedef struct apc_stack_t apc_stack_t; /* opaque stack type */

extern T apc_stack_create(size_t size_hint);
extern void apc_stack_destroy(T stack);
extern void apc_stack_clear(T stack);
extern void apc_stack_push(T stack, void* item);
extern void* apc_stack_pop(T stack);
extern void* apc_stack_top(T stack);
extern void* apc_stack_get(T stack, size_t n);
extern int apc_stack_size(T stack);

#undef T
#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim>600: noexpandtab sw=4 ts=4 sts=4 fdm=marker
 * vim<600: noexpandtab sw=4 ts=4 sts=4
 */
php/ext/apcu/apc.h000064400000013376151730540420010012 0ustar00/*
  +----------------------------------------------------------------------+
  | APC                                                                  |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2011 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Daniel Cowgill <dcowgill@communityconnect.com>              |
  |          George Schlossnagle <george@omniti.com>                     |
  |          Rasmus Lerdorf <rasmus@php.net>                             |
  |          Arun C. Murthy <arunc@yahoo-inc.com>                        |
  |          Gopal Vijayaraghavan <gopalv@yahoo-inc.com>                 |
  +----------------------------------------------------------------------+

   This software was contributed to PHP by Community Connect Inc. in 2002
   and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
   Future revisions and derivatives of this source code must acknowledge
   Community Connect Inc. as the original contributor of this module by
   leaving this note intact in the source code.

   All other licensing and usage conditions are those of the PHP Group.

 */

#ifndef APC_H
#define APC_H

/*
 * This module defines utilities and helper functions used elsewhere in APC.
 */
#ifdef PHP_WIN32
# define PHP_APCU_API __declspec(dllexport)
#elif defined(__GNUC__) && __GNUC__ >= 4
# define PHP_APCU_API __attribute__ ((visibility("default")))
#else
# define PHP_APCU_API
#endif

/* Commonly needed C library headers. */
#include <assert.h>
#include <errno.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

/* UNIX headers (needed for struct stat) */
#include <sys/types.h>
#include <sys/stat.h>
#ifndef PHP_WIN32
#include <unistd.h>
#endif

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include "php.h"
#include "main/php_streams.h"

/* console display functions */
PHP_APCU_API void apc_error(const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 1, 2);
PHP_APCU_API void apc_warning(const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 1, 2);
PHP_APCU_API void apc_notice(const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 1, 2);
PHP_APCU_API void apc_debug(const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 1, 2);

/* apc_flip_hash flips keys and values for faster searching */
PHP_APCU_API HashTable* apc_flip_hash(HashTable *hash);

#if defined(__GNUC__)
# define APC_UNUSED __attribute__((unused))
# define APC_USED __attribute__((used))
# define APC_ALLOC __attribute__((malloc))
# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__  > 2)
#  define APC_HOTSPOT __attribute__((hot))
# else
#  define APC_HOTSPOT
# endif
#else
# define APC_UNUSED
# define APC_USED
# define APC_ALLOC
# define APC_HOTSPOT
#endif

/*
* Serializer API
*/
#define APC_SERIALIZER_ABI "0"
#define APC_SERIALIZER_CONSTANT "\000apc_register_serializer-" APC_SERIALIZER_ABI

#define APC_SERIALIZER_NAME(module) module##_apc_serializer
#define APC_UNSERIALIZER_NAME(module) module##_apc_unserializer

#define APC_SERIALIZER_ARGS unsigned char **buf, size_t *buf_len, const zval *value, void *config
#define APC_UNSERIALIZER_ARGS zval *value, unsigned char *buf, size_t buf_len, void *config

typedef int (*apc_serialize_t)(APC_SERIALIZER_ARGS);
typedef int (*apc_unserialize_t)(APC_UNSERIALIZER_ARGS);

/* {{{ struct definition: apc_serializer_t */
typedef struct apc_serializer_t {
	const char*        name;
	apc_serialize_t    serialize;
	apc_unserialize_t  unserialize;
	void*              config;
} apc_serializer_t;
/* }}} */

/* {{{ _apc_register_serializer
 registers the serializer using the given name and parameters */
PHP_APCU_API int _apc_register_serializer(
        const char* name, apc_serialize_t serialize, apc_unserialize_t unserialize, void *config);
/* }}} */

/* {{{ apc_get_serializers
 fetches the list of serializers */
PHP_APCU_API apc_serializer_t* apc_get_serializers(void); /* }}} */

/* {{{ apc_find_serializer
 finds a previously registered serializer by name */
PHP_APCU_API apc_serializer_t* apc_find_serializer(const char* name); /* }}} */

/* {{{ default serializers */
PHP_APCU_API int APC_SERIALIZER_NAME(php) (APC_SERIALIZER_ARGS);
PHP_APCU_API int APC_UNSERIALIZER_NAME(php) (APC_UNSERIALIZER_ARGS); /* }}} */

#define php_apc_try                        \
{                                          \
	JMP_BUF *zb = EG(bailout);             \
	JMP_BUF ab;                            \
	zend_bool _bailout = 0;                \
	                                       \
	EG(bailout) = &ab;                     \
	if (SETJMP(ab) == SUCCESS) {

#define php_apc_finally                    \
	} else {                               \
		_bailout = 1;                      \
	}

#define php_apc_end_try()                  \
	EG(bailout) = zb;                      \
	if (_bailout) {                        \
		zend_bailout();                    \
	}                                      \
}

#define php_apc_try_finish() (EG(bailout) = zb)

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim>600: noexpandtab sw=4 ts=4 sts=4 fdm=marker
 * vim<600: noexpandtab sw=4 ts=4 sts=4
 */
php/ext/apcu/apc_sma.h000064400000012753151730540420010650 0ustar00/*
  +----------------------------------------------------------------------+
  | APC                                                                  |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2011 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Daniel Cowgill <dcowgill@communityconnect.com>              |
  +----------------------------------------------------------------------+

   This software was contributed to PHP by Community Connect Inc. in 2002
   and revised in 2005 by Yahoo! Inc. to add support for PHP 5.1.
   Future revisions and derivatives of this source code must acknowledge
   Community Connect Inc. as the original contributor of this module by
   leaving this note intact in the source code.

   All other licensing and usage conditions are those of the PHP Group.

 */

#ifndef APC_SMA_H
#define APC_SMA_H

/* {{{ SMA API
	APC SMA API provides support for shared memory allocators to external libraries ( and to APC )
	Skip to the bottom macros for error free usage of the SMA API
*/

#include "apc.h"

/* {{{ struct definition: apc_segment_t */
typedef struct _apc_segment_t {
	size_t size;            /* size of this segment */
	void* shmaddr;          /* address of shared memory */
#ifdef APC_MEMPROTECT
	void* roaddr;           /* read only (mprotect'd) address */
#endif
} apc_segment_t; /* }}} */

/* {{{ struct definition: apc_sma_link_t */
typedef struct apc_sma_link_t apc_sma_link_t;
struct apc_sma_link_t {
	zend_long size;              /* size of this free block */
	zend_long offset;            /* offset in segment of this block */
	apc_sma_link_t* next;   /* link to next free block */
};
/* }}} */

/* {{{ struct definition: apc_sma_info_t */
typedef struct apc_sma_info_t apc_sma_info_t;
struct apc_sma_info_t {
	int num_seg;            /* number of segments */
	size_t seg_size;        /* segment size */
	apc_sma_link_t** list;  /* one list per segment of links */
};
/* }}} */

typedef void (*apc_sma_expunge_f)(void *pointer, size_t size); /* }}} */

/* {{{ struct definition: apc_sma_t */
typedef struct _apc_sma_t {
	zend_bool initialized;         /* flag to indicate this sma has been initialized */

	/* callback */
	apc_sma_expunge_f expunge;     /* expunge */
	void** data;                   /* expunge data */

	/* info */
	int32_t  num;                  /* number of segments */
	size_t size;                   /* segment size */
	int32_t  last;                 /* last segment */

	/* segments */
	apc_segment_t *segs;           /* segments */
} apc_sma_t; /* }}} */

/*
* apc_sma_api_init will initialize a shared memory allocator with num segments of the given size
*
* should be called once per allocator per process
*/
PHP_APCU_API void apc_sma_init(
		apc_sma_t* sma, void** data, apc_sma_expunge_f expunge,
		int32_t num, size_t size, char *mask);

/*
 * apc_sma_detach will detach from shared memory and cleanup local allocations.
 */
PHP_APCU_API void apc_sma_detach(apc_sma_t* sma);

/*
* apc_smap_api_malloc will allocate a block from the sma of the given size
*/
PHP_APCU_API void* apc_sma_malloc(apc_sma_t* sma, size_t size);

/*
 * apc_sma_api_malloc_ex will allocate a block from the sma of the given size and
 * provide the size of the actual allocation.
 */
PHP_APCU_API void *apc_sma_malloc_ex(
		apc_sma_t *sma, size_t size, size_t *allocated);

/*
* apc_sma_api_free will free p (which should be a pointer to a block allocated from sma)
*/
PHP_APCU_API void apc_sma_free(apc_sma_t* sma, void* p);

/*
* apc_sma_api_protect will protect p (which should be a pointer to a block allocated from sma)
*/
PHP_APCU_API void* apc_sma_protect(apc_sma_t* sma, void* p);

/*
* apc_sma_api_protect will uprotect p (which should be a pointer to a block allocated from sma)
*/
PHP_APCU_API void* apc_sma_unprotect(apc_sma_t* sma, void *p);

/*
* apc_sma_api_info returns information about the allocator
*/
PHP_APCU_API apc_sma_info_t* apc_sma_info(apc_sma_t* sma, zend_bool limited);

/*
* apc_sma_api_info_free_info is for freeing apc_sma_info_t* returned by apc_sma_api_info
*/
PHP_APCU_API void apc_sma_free_info(apc_sma_t* sma, apc_sma_info_t* info);

/*
* apc_sma_api_get_avail_mem will return the amount of memory available left to sma
*/
PHP_APCU_API size_t apc_sma_get_avail_mem(apc_sma_t* sma);

/*
* apc_sma_api_get_avail_size will return true if at least size bytes are available to the sma
*/
PHP_APCU_API zend_bool apc_sma_get_avail_size(apc_sma_t* sma, size_t size);

/*
* apc_sma_api_check_integrity will check the integrity of sma
*/
PHP_APCU_API void apc_sma_check_integrity(apc_sma_t* sma); /* }}} */

/* {{{ ALIGNWORD: pad up x, aligned to the system's word boundary */
typedef union { void* p; int i; long l; double d; void (*f)(void); } apc_word_t;
#define ALIGNSIZE(x, size) ((size) * (1 + (((x)-1)/(size))))
#define ALIGNWORD(x) ALIGNSIZE(x, sizeof(apc_word_t))
/* }}} */

#endif

php/ext/apcu/apc_mutex.h000064400000004366151730540420011233 0ustar00/*
  +----------------------------------------------------------------------+
  | APCu                                                                 |
  +----------------------------------------------------------------------+
  | Copyright (c) 2013 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: Joe Watkins <joe.watkins@live.co.uk>                        |
  +----------------------------------------------------------------------+
 */

#ifndef APC_MUTEX_H
#define APC_MUTEX_H

#include "apc.h"

#ifdef APC_HAS_PTHREAD_MUTEX

#include "pthread.h"

typedef pthread_mutex_t apc_mutex_t;

PHP_APCU_API zend_bool apc_mutex_init(void);
PHP_APCU_API void apc_mutex_cleanup(void);
PHP_APCU_API zend_bool apc_mutex_create(apc_mutex_t *lock);
PHP_APCU_API zend_bool apc_mutex_lock(apc_mutex_t *lock);
PHP_APCU_API zend_bool apc_mutex_unlock(apc_mutex_t *lock);
PHP_APCU_API void apc_mutex_destroy(apc_mutex_t *lock);

#define APC_MUTEX_INIT()          apc_mutex_init()
#define APC_MUTEX_CLEANUP()       apc_mutex_cleanup()

#define APC_CREATE_MUTEX(lock)    apc_mutex_create(lock)
#define APC_DESTROY_MUTEX(lock)   apc_mutex_destroy(lock)
#define APC_MUTEX_LOCK(lock)      apc_mutex_lock(lock)
#define APC_MUTEX_UNLOCK(lock)    apc_mutex_unlock(lock)

#else

#include "apc_lock.h"

typedef apc_lock_t apc_mutex_t;

// Fallback to normal locks

#define APC_MUTEX_INIT()
#define APC_MUTEX_CLEANUP()

#define APC_CREATE_MUTEX(lock)    CREATE_LOCK(lock)
#define APC_DESTROY_MUTEX(lock)   DESTROY_LOCK(lock)
#define APC_MUTEX_LOCK(lock)      WLOCK(lock)
#define APC_MUTEX_UNLOCK(lock)    WUNLOCK(lock)

#endif

#endif
php/ext/mysqlnd/mysqlnd_result.h000064400000004025151730540430013063 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Andrey Hristov <andrey@php.net>                             |
  |          Ulf Wendel <uw@php.net>                                     |
  +----------------------------------------------------------------------+
*/

#ifndef MYSQLND_RESULT_H
#define MYSQLND_RESULT_H

PHPAPI MYSQLND_RES * mysqlnd_result_init(const unsigned int field_count, const zend_bool persistent);
PHPAPI MYSQLND_RES_UNBUFFERED * mysqlnd_result_unbuffered_init(const unsigned int field_count, const zend_bool ps, const zend_bool persistent);
PHPAPI MYSQLND_RES_BUFFERED_ZVAL * mysqlnd_result_buffered_zval_init(const unsigned int field_count, const zend_bool ps, const zend_bool persistent);
PHPAPI MYSQLND_RES_BUFFERED_C * mysqlnd_result_buffered_c_init(const unsigned int field_count, const zend_bool ps, const zend_bool persistent);

enum_func_status mysqlnd_query_read_result_set_header(MYSQLND_CONN_DATA * conn, MYSQLND_STMT * stmt);

#endif /* MYSQLND_RESULT_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/ext/mysqlnd/mysqlnd_ps.h000064400000004600151730540430012166 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Andrey Hristov <andrey@php.net>                             |
  |          Ulf Wendel <uw@php.net>                                     |
  +----------------------------------------------------------------------+
*/

#ifndef MYSQLND_PS_H
#define MYSQLND_PS_H

/* PS stuff */
typedef void (*ps_field_fetch_func)(zval * zv, const MYSQLND_FIELD * const field, const unsigned int pack_len, const zend_uchar ** row);

struct st_mysqlnd_perm_bind {
	ps_field_fetch_func func;
	/* should be signed int */
	int					pack_len;
	unsigned int		php_type;
	zend_bool			is_possibly_blob;
	zend_bool			can_ret_as_str_in_uni;
};

extern struct st_mysqlnd_perm_bind mysqlnd_ps_fetch_functions[MYSQL_TYPE_LAST + 1];

enum_func_status mysqlnd_stmt_fetch_row_buffered(MYSQLND_RES * result, void * param, const unsigned int flags, zend_bool * fetched_anything);
enum_func_status mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES * result, void * param, const unsigned int flags, zend_bool * fetched_anything);

void _mysqlnd_init_ps_subsystem();/* This one is private, mysqlnd_library_init() will call it */
void _mysqlnd_init_ps_fetch_subsystem();

void ps_fetch_from_1_to_8_bytes(zval * zv, const MYSQLND_FIELD * const field, const unsigned int pack_len, const zend_uchar ** row, unsigned int byte_count);

#endif /* MYSQLND_PS_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/ext/mysqlnd/mysqlnd_auth.h000064400000010730151730540440012507 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Andrey Hristov <andrey@php.net>                             |
  |          Ulf Wendel <uw@php.net>                                     |
  +----------------------------------------------------------------------+
*/

#ifndef MYSQLND_AUTH_H
#define MYSQLND_AUTH_H
enum_func_status
mysqlnd_auth_handshake(MYSQLND_CONN_DATA * conn,
						const char * const user,
						const char * const passwd,
						const size_t passwd_len,
						const char * const db,
						const size_t db_len,
						const MYSQLND_SESSION_OPTIONS * const session_options,
						zend_ulong mysql_flags,
						unsigned int server_charset_no,
						zend_bool use_full_blown_auth_packet,
						const char * const auth_protocol,
						const zend_uchar * const auth_plugin_data,
						const size_t auth_plugin_data_len,
						char ** switch_to_auth_protocol,
						size_t * switch_to_auth_protocol_len,
						zend_uchar ** switch_to_auth_protocol_data,
						size_t * switch_to_auth_protocol_data_len
						);

enum_func_status
mysqlnd_auth_handshake(MYSQLND_CONN_DATA * conn,
						const char * const user,
						const char * const passwd,
						const size_t passwd_len,
						const char * const db,
						const size_t db_len,
						const MYSQLND_SESSION_OPTIONS * const session_options,
						zend_ulong mysql_flags,
						unsigned int server_charset_no,
						zend_bool use_full_blown_auth_packet,
						const char * const auth_protocol,
						const zend_uchar * const auth_plugin_data,
						const size_t auth_plugin_data_len,
						char ** switch_to_auth_protocol,
						size_t * switch_to_auth_protocol_len,
						zend_uchar ** switch_to_auth_protocol_data,
						size_t * switch_to_auth_protocol_data_len
						);

enum_func_status
mysqlnd_auth_change_user(MYSQLND_CONN_DATA * const conn,
								const char * const user,
								const size_t user_len,
								const char * const passwd,
								const size_t passwd_len,
								const char * const db,
								const size_t db_len,
								const zend_bool silent,
								zend_bool use_full_blown_auth_packet,
								const char * const auth_protocol,
								zend_uchar * auth_plugin_data,
								size_t auth_plugin_data_len,
								char ** switch_to_auth_protocol,
								size_t * switch_to_auth_protocol_len,
								zend_uchar ** switch_to_auth_protocol_data,
								size_t * switch_to_auth_protocol_data_len
								);


enum_func_status
mysqlnd_connect_run_authentication(
			MYSQLND_CONN_DATA * conn,
			const char * const user,
			const char * const passwd,
			const char * const db,
			size_t db_len,
			size_t passwd_len,
			MYSQLND_STRING authentication_plugin_data,
			const char * const authentication_protocol,
			const unsigned int charset_no,
			size_t server_capabilities,
			const MYSQLND_SESSION_OPTIONS * const session_options,
			zend_ulong mysql_flags
			);

enum_func_status
mysqlnd_run_authentication(
			MYSQLND_CONN_DATA * conn,
			const char * const user,
			const char * const passwd,
			const size_t passwd_len,
			const char * const db,
			const size_t db_len,
			const MYSQLND_STRING auth_plugin_data,
			const char * const auth_protocol,
			unsigned int charset_no,
			const MYSQLND_SESSION_OPTIONS * const session_options,
			zend_ulong mysql_flags,
			zend_bool silent,
			zend_bool is_change_user
			);

PHPAPI void php_mysqlnd_scramble(zend_uchar * const buffer, const zend_uchar * const scramble, const zend_uchar * const pass, const size_t pass_len);

#endif /* MYSQLND_AUTH_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/ext/mysqlnd/mysqlnd_structs.h000064400000172373151730540440013271 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Andrey Hristov <andrey@php.net>                             |
  |          Ulf Wendel <uw@php.net>                                     |
  +----------------------------------------------------------------------+
*/

#ifndef MYSQLND_STRUCTS_H
#define MYSQLND_STRUCTS_H

#include "zend_smart_str_public.h"

#define MYSQLND_TYPEDEFED_METHODS

#define MYSQLND_CLASS_METHOD_TABLE_NAME(class) mysqlnd_##class##_methods
#define MYSQLND_CLASS_METHODS_TYPE(class) struct st_##class##_methods
#define MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(class) MYSQLND_CLASS_METHODS_TYPE(class) MYSQLND_CLASS_METHOD_TABLE_NAME(class)

#define MYSQLND_CLASS_METHODS_START(class)	MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(class) = {
#define MYSQLND_CLASS_METHODS_END			}

#define MYSQLND_CLASS_METHODS_INSTANCE_NAME(class)		mysqlnd_##class##_methods_ptr
#define MYSQLND_CLASS_METHODS_INSTANCE_DECLARE(class)	extern const MYSQLND_CLASS_METHODS_TYPE(class) * MYSQLND_CLASS_METHODS_INSTANCE_NAME(class)
#define MYSQLND_CLASS_METHODS_INSTANCE_DEFINE(class)	const MYSQLND_CLASS_METHODS_TYPE(class) * MYSQLND_CLASS_METHODS_INSTANCE_NAME(class) = & MYSQLND_CLASS_METHOD_TABLE_NAME(class)

typedef struct st_mysqlnd_string
{
	char	*s;
	size_t	l;
} MYSQLND_STRING;

typedef struct st_mysqlnd_const_string
{
	const char *s;
	size_t	l;
} MYSQLND_CSTRING;


typedef struct st_mysqlnd_memory_pool MYSQLND_MEMORY_POOL;
typedef struct st_mysqlnd_memory_pool_chunk MYSQLND_MEMORY_POOL_CHUNK;
typedef struct st_mysqlnd_memory_pool_chunk_llist MYSQLND_MEMORY_POOL_CHUNK_LLIST;


#define MYSQLND_MEMORY_POOL_CHUNK_LIST_SIZE 100

struct st_mysqlnd_memory_pool
{
	zend_uchar *arena;
	unsigned int arena_size;
	unsigned int free_size;

	MYSQLND_MEMORY_POOL_CHUNK*	(*get_chunk)(MYSQLND_MEMORY_POOL * pool, unsigned int size);
	enum_func_status	(*resize_chunk)(MYSQLND_MEMORY_POOL * pool, MYSQLND_MEMORY_POOL_CHUNK * chunk, unsigned int size);
	void				(*free_chunk)(MYSQLND_MEMORY_POOL * pool, MYSQLND_MEMORY_POOL_CHUNK * chunk);
};

struct st_mysqlnd_memory_pool_chunk
{
	size_t				app;
	zend_uchar			*ptr;
	unsigned int		size;
	zend_bool			from_pool;
};


typedef struct st_mysqlnd_cmd_buffer
{
	zend_uchar		*buffer;
	size_t			length;
} MYSQLND_CMD_BUFFER;


typedef struct st_mysqlnd_field
{
	zend_string *sname;			/* Name of column */
	const char  *name;          /* Name of column in C string */
	const char  *org_name;		/* Original column name, if an alias */
	const char  *table;			/* Table of column if column was a field */
	const char  *org_table;		/* Org table name, if table was an alias */
	const char  *db;			/* Database for table */
	const char  *catalog;		/* Catalog for table */
	char  *def;                 /* Default value */
	zend_ulong length;		/* Width of column (create length) */
	zend_ulong max_length;	/* Max width for selected set */
	unsigned int name_length;
	unsigned int org_name_length;
	unsigned int table_length;
	unsigned int org_table_length;
	unsigned int db_length;
	unsigned int catalog_length;
	unsigned int def_length;
	unsigned int flags;			/* Diverse flags */
	unsigned int decimals;		/* Number of decimals in field */
	unsigned int charsetnr;		/* Character set */
	enum mysqlnd_field_types type;	/* Type of field. See mysql_com.h for types */
	char *root;
	size_t root_len;
} MYSQLND_FIELD;


typedef struct st_mysqlnd_upsert_status MYSQLND_UPSERT_STATUS;
typedef void (*func_mysqlnd_upsert_status__reset)(MYSQLND_UPSERT_STATUS * const upsert_status);
typedef void (*func_mysqlnd_upsert_status__set_affected_rows_to_error)(MYSQLND_UPSERT_STATUS * const upsert_status);

MYSQLND_CLASS_METHODS_TYPE(mysqlnd_upsert_status)
{
	func_mysqlnd_upsert_status__reset reset;
	func_mysqlnd_upsert_status__set_affected_rows_to_error set_affected_rows_to_error;
};

struct st_mysqlnd_upsert_status
{
	unsigned int	warning_count;
	unsigned int	server_status;
	uint64_t		affected_rows;
	uint64_t		last_insert_id;

	MYSQLND_CLASS_METHODS_TYPE(mysqlnd_upsert_status) *m;
};

#define SET_EMPTY_ERROR(info)							(info)->m->reset((info))
#define SET_CLIENT_ERROR(info, err_no, sqlstate, error)	(err_no)? (info)->m->set_client_error((info), (err_no), (sqlstate), (error)) : (info)->m->reset((info))
#define SET_OOM_ERROR(info) 							SET_CLIENT_ERROR((info), CR_OUT_OF_MEMORY, UNKNOWN_SQLSTATE, mysqlnd_out_of_memory)
#define COPY_CLIENT_ERROR(dest, source)					SET_CLIENT_ERROR((dest), (source).error_no, (source).sqlstate, (source).error)


typedef struct st_mysqlnd_error_info MYSQLND_ERROR_INFO;
typedef void (*func_mysqlnd_error_info__reset)(MYSQLND_ERROR_INFO * const info);
typedef void (*func_mysqlnd_error_info__set_client_error)(MYSQLND_ERROR_INFO * const info, const unsigned int err_no, const char * const sqlstate, const char * const error);


MYSQLND_CLASS_METHODS_TYPE(mysqlnd_error_info)
{
	func_mysqlnd_error_info__reset reset;
	func_mysqlnd_error_info__set_client_error set_client_error;
};

struct st_mysqlnd_error_info
{
	char error[MYSQLND_ERRMSG_SIZE+1];
	char sqlstate[MYSQLND_SQLSTATE_LENGTH + 1];
	unsigned int error_no;
	zend_llist * error_list;

	zend_bool persistent;
	MYSQLND_CLASS_METHODS_TYPE(mysqlnd_error_info) *m;
};


typedef struct st_mysqlnd_error_list_element
{
	char * error;
	char sqlstate[MYSQLND_SQLSTATE_LENGTH + 1];
	unsigned int error_no;
} MYSQLND_ERROR_LIST_ELEMENT;


typedef struct st_mysqlnd_infile_info
{
	php_stream	*fd;
	int			error_no;
	char		error_msg[MYSQLND_ERRMSG_SIZE + 1];
	const char	*filename;
} MYSQLND_INFILE_INFO;


/* character set information */
typedef struct st_mysqlnd_charset
{
	unsigned int	nr;
	const char		*name;
	const char		*collation;
	unsigned int	char_minlen;
	unsigned int	char_maxlen;
	const char		*comment;
	unsigned int 	(*mb_charlen)(unsigned int c);
	unsigned int 	(*mb_valid)(const char *start, const char *end);
} MYSQLND_CHARSET;


/* local infile handler */
typedef struct st_mysqlnd_infile
{
	int		(*local_infile_init)(void **ptr, const char * const filename);
	int		(*local_infile_read)(void *ptr, zend_uchar * buf, unsigned int buf_len);
	int		(*local_infile_error)(void *ptr, char * error_msg, unsigned int error_msg_len);
	void	(*local_infile_end)(void *ptr);
} MYSQLND_INFILE;

typedef struct st_mysqlnd_session_options
{
	ulong		flags;

	/* init commands - we need to send them to server directly after connect */
	unsigned int	num_commands;
	char			**init_commands;

	/* configuration file information */
	char 		*cfg_file;
	char		*cfg_section;

	char		*auth_protocol;
	/*
	  We need to keep these because otherwise st_mysqlnd_conn will be changed.
	  The ABI will be broken and the methods structure will be somewhere else
	  in the memory which can crash external code. Feel free to reuse these.
	*/
	HashTable	* connect_attr;
	char		* unused1;
	char		* unused2;
	char		* unused3;

	enum_mysqlnd_session_protocol_type protocol;

	char 		*charset_name;
	/* maximum allowed packet size for communication */
	ulong		max_allowed_packet;

#ifdef MYSQLND_STRING_TO_INT_CONVERSION
	zend_bool	int_and_float_native;
#endif
} MYSQLND_SESSION_OPTIONS;


typedef struct st_mysqlnd_vio_options
{
	/* timeouts */
	unsigned int timeout_connect;
	unsigned int timeout_read;
	unsigned int timeout_write;

	size_t		net_read_buffer_size;

	/* SSL information */
	char		*ssl_key;
	char		*ssl_cert;
	char		*ssl_ca;
	char		*ssl_capath;
	char		*ssl_cipher;
	char		*ssl_passphrase;
	enum mysqlnd_ssl_peer {
		MYSQLND_SSL_PEER_DEFAULT = 0,
		MYSQLND_SSL_PEER_VERIFY = 1,
		MYSQLND_SSL_PEER_DONT_VERIFY = 2,

#define MYSQLND_SSL_PEER_DEFAULT_ACTION  MYSQLND_SSL_PEER_VERIFY
	} ssl_verify_peer;
} MYSQLND_VIO_OPTIONS;



typedef struct st_mysqlnd_connection MYSQLND;
typedef struct st_mysqlnd_connection_data MYSQLND_CONN_DATA;
typedef struct st_mysqlnd_protocol_frame_codec		MYSQLND_PFC;
typedef struct st_mysqlnd_protocol_frame_codec_data	MYSQLND_PFC_DATA;
typedef struct st_mysqlnd_vio		MYSQLND_VIO;
typedef struct st_mysqlnd_vio_data	MYSQLND_VIO_DATA;
typedef struct st_mysqlnd_protocol_payload_decoder_factory	MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY;
typedef struct st_mysqlnd_res	MYSQLND_RES;
typedef char** 					MYSQLND_ROW_C;		/* return data as array of strings */
typedef struct st_mysqlnd_stmt_data	MYSQLND_STMT_DATA;
typedef struct st_mysqlnd_stmt	MYSQLND_STMT;
typedef unsigned int			MYSQLND_FIELD_OFFSET;

typedef struct st_mysqlnd_param_bind MYSQLND_PARAM_BIND;

typedef struct st_mysqlnd_result_bind MYSQLND_RESULT_BIND;

typedef struct st_mysqlnd_result_metadata MYSQLND_RES_METADATA;
typedef struct st_mysqlnd_buffered_result_parent MYSQLND_RES_BUFFERED;
typedef struct st_mysqlnd_buffered_result_zval MYSQLND_RES_BUFFERED_ZVAL;
typedef struct st_mysqlnd_buffered_result_c MYSQLND_RES_BUFFERED_C;
typedef struct st_mysqlnd_unbuffered_result MYSQLND_RES_UNBUFFERED;

typedef struct st_mysqlnd_debug MYSQLND_DEBUG;


typedef MYSQLND_RES* (*mysqlnd_stmt_use_or_store_func)(MYSQLND_STMT * const);
typedef enum_func_status  (*mysqlnd_fetch_row_func)(MYSQLND_RES *result,
													void * param,
													const unsigned int flags,
													zend_bool * fetched_anything
													);


typedef struct st_mysqlnd_stats MYSQLND_STATS;

typedef void (*mysqlnd_stat_trigger)(MYSQLND_STATS * stats, enum_mysqlnd_collected_stats stat, int64_t change);

struct st_mysqlnd_stats
{
	uint64_t				*values;
	mysqlnd_stat_trigger	*triggers;
	size_t					count;
	zend_bool				in_trigger;
#ifdef ZTS
	MUTEX_T	LOCK_access;
#endif
};


typedef enum_func_status	(*func_mysqlnd_vio__init)(MYSQLND_VIO * const vio, MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info);
typedef void				(*func_mysqlnd_vio__dtor)(MYSQLND_VIO * const vio, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info);

typedef enum_func_status	(*func_mysqlnd_vio__connect)(MYSQLND_VIO * const vio, const MYSQLND_CSTRING scheme, const zend_bool persistent, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info);

typedef void				(*func_mysqlnd_vio__close_stream)(MYSQLND_VIO * const vio, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info);
typedef php_stream *		(*func_mysqlnd_vio__open_stream)(MYSQLND_VIO * const vio, const MYSQLND_CSTRING scheme, const zend_bool persistent, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info);
typedef php_stream *		(*func_mysqlnd_vio__get_stream)(const MYSQLND_VIO * const vio);
typedef enum_func_status	(*func_mysqlnd_vio__set_stream)(MYSQLND_VIO * const vio, php_stream * vio_stream);
typedef zend_bool			(*func_mysqlnd_vio__has_valid_stream)(const MYSQLND_VIO * const vio);
typedef func_mysqlnd_vio__open_stream (*func_mysqlnd_vio__get_open_stream)(MYSQLND_VIO * const vio, const MYSQLND_CSTRING scheme, MYSQLND_ERROR_INFO * const error_info);

typedef enum_func_status	(*func_mysqlnd_vio__set_client_option)(MYSQLND_VIO * const vio, enum_mysqlnd_client_option option, const char * const value);
typedef void				(*func_mysqlnd_vio__post_connect_set_opt)(MYSQLND_VIO * const vio, const MYSQLND_CSTRING scheme, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info);

typedef enum_func_status	(*func_mysqlnd_vio__enable_ssl)(MYSQLND_VIO * const vio);
typedef enum_func_status	(*func_mysqlnd_vio__disable_ssl)(MYSQLND_VIO * const vio);
typedef enum_func_status	(*func_mysqlnd_vio__network_read)(MYSQLND_VIO * const vio, zend_uchar * const buffer, const size_t count, MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info);
typedef size_t				(*func_mysqlnd_vio__network_write)(MYSQLND_VIO * const vio, const zend_uchar * const buf, const size_t count, MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info);

typedef size_t				(*func_mysqlnd_vio__consume_uneaten_data)(MYSQLND_VIO * const vio, enum php_mysqlnd_server_command cmd);

typedef void				(*func_mysqlnd_vio__free_contents)(MYSQLND_VIO * vio);


MYSQLND_CLASS_METHODS_TYPE(mysqlnd_vio)
{
	func_mysqlnd_vio__init init;
	func_mysqlnd_vio__dtor dtor;
	func_mysqlnd_vio__connect connect;

	func_mysqlnd_vio__close_stream close_stream;
	func_mysqlnd_vio__open_stream open_pipe;
	func_mysqlnd_vio__open_stream open_tcp_or_unix;

	func_mysqlnd_vio__get_stream get_stream;
	func_mysqlnd_vio__set_stream set_stream;
	func_mysqlnd_vio__has_valid_stream has_valid_stream;
	func_mysqlnd_vio__get_open_stream get_open_stream;

	func_mysqlnd_vio__set_client_option set_client_option;
	func_mysqlnd_vio__post_connect_set_opt post_connect_set_opt;

	func_mysqlnd_vio__enable_ssl enable_ssl;
	func_mysqlnd_vio__disable_ssl disable_ssl;

	func_mysqlnd_vio__network_read network_read;
	func_mysqlnd_vio__network_write network_write;

	func_mysqlnd_vio__consume_uneaten_data consume_uneaten_data;

	func_mysqlnd_vio__free_contents free_contents;
};


MYSQLND_CLASS_METHODS_TYPE(mysqlnd_object_factory);

typedef MYSQLND * (*func_mysqlnd_object_factory__get_connection)(MYSQLND_CLASS_METHODS_TYPE(mysqlnd_object_factory) * factory, const zend_bool persistent);
typedef MYSQLND * (*func_mysqlnd_object_factory__clone_connection_object)(MYSQLND * conn);
typedef MYSQLND_STMT * (*func_mysqlnd_object_factory__get_prepared_statement)(MYSQLND_CONN_DATA * conn, const zend_bool persistent);
typedef MYSQLND_PFC * (*func_mysqlnd_object_factory__get_pfc)(const zend_bool persistent, MYSQLND_STATS * stats, MYSQLND_ERROR_INFO * error_info);
typedef MYSQLND_VIO * (*func_mysqlnd_object_factory__get_vio)(const zend_bool persistent, MYSQLND_STATS * stats, MYSQLND_ERROR_INFO * error_info);
typedef MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * (*func_mysqlnd_object_factory__get_protocol_payload_decoder_factory)(MYSQLND_CONN_DATA * conn, const zend_bool persistent);


MYSQLND_CLASS_METHODS_TYPE(mysqlnd_object_factory)
{
	func_mysqlnd_object_factory__get_connection get_connection;
	func_mysqlnd_object_factory__clone_connection_object clone_connection_object;
	func_mysqlnd_object_factory__get_prepared_statement get_prepared_statement;
	func_mysqlnd_object_factory__get_pfc get_protocol_frame_codec;
	func_mysqlnd_object_factory__get_vio get_vio;
	func_mysqlnd_object_factory__get_protocol_payload_decoder_factory get_protocol_payload_decoder_factory;
};


typedef enum_func_status	(*func_mysqlnd_conn_data__connect)(MYSQLND_CONN_DATA * conn, MYSQLND_CSTRING hostname, MYSQLND_CSTRING username, MYSQLND_CSTRING password, MYSQLND_CSTRING database, unsigned int port, MYSQLND_CSTRING socket_or_pipe, unsigned int mysql_flags);
typedef zend_ulong			(*func_mysqlnd_conn_data__escape_string)(MYSQLND_CONN_DATA * const conn, char *newstr, const char *escapestr, size_t escapestr_len);
typedef enum_func_status	(*func_mysqlnd_conn_data__set_charset)(MYSQLND_CONN_DATA * const conn, const char * const charset);
typedef enum_func_status	(*func_mysqlnd_conn_data__query)(MYSQLND_CONN_DATA * conn, const char * const query, const size_t query_len);
typedef enum_func_status	(*func_mysqlnd_conn_data__send_query)(MYSQLND_CONN_DATA * conn, const char * const query, const size_t query_len, enum_mysqlnd_send_query_type type, zval *read_cb, zval *err_cb);
typedef enum_func_status	(*func_mysqlnd_conn_data__reap_query)(MYSQLND_CONN_DATA * conn, enum_mysqlnd_reap_result_type type);
typedef MYSQLND_RES *		(*func_mysqlnd_conn_data__use_result)(MYSQLND_CONN_DATA * const conn, const unsigned int flags);
typedef MYSQLND_RES *		(*func_mysqlnd_conn_data__store_result)(MYSQLND_CONN_DATA * const conn, const unsigned int flags);
typedef enum_func_status	(*func_mysqlnd_conn_data__next_result)(MYSQLND_CONN_DATA * const conn);
typedef zend_bool			(*func_mysqlnd_conn_data__more_results)(const MYSQLND_CONN_DATA * const conn);

typedef MYSQLND_STMT *		(*func_mysqlnd_conn_data__stmt_init)(MYSQLND_CONN_DATA * const conn);

typedef enum_func_status	(*func_mysqlnd_conn_data__shutdown_server)(MYSQLND_CONN_DATA * const conn, uint8_t level);
typedef enum_func_status	(*func_mysqlnd_conn_data__refresh_server)(MYSQLND_CONN_DATA * const conn, uint8_t options);

typedef enum_func_status	(*func_mysqlnd_conn_data__ping)(MYSQLND_CONN_DATA * const conn);
typedef enum_func_status	(*func_mysqlnd_conn_data__kill_connection)(MYSQLND_CONN_DATA * conn, unsigned int pid);
typedef enum_func_status	(*func_mysqlnd_conn_data__select_db)(MYSQLND_CONN_DATA * const conn, const char * const db, const size_t db_len);
typedef enum_func_status	(*func_mysqlnd_conn_data__server_dump_debug_information)(MYSQLND_CONN_DATA * const conn);
typedef enum_func_status	(*func_mysqlnd_conn_data__change_user)(MYSQLND_CONN_DATA * const conn, const char * user, const char * passwd, const char * db, zend_bool silent, size_t passwd_len);

typedef unsigned int		(*func_mysqlnd_conn_data__get_error_no)(const MYSQLND_CONN_DATA * const conn);
typedef const char *		(*func_mysqlnd_conn_data__get_error_str)(const MYSQLND_CONN_DATA * const conn);
typedef const char *		(*func_mysqlnd_conn_data__get_sqlstate)(const MYSQLND_CONN_DATA * const conn);
typedef uint64_t			(*func_mysqlnd_conn_data__get_thread_id)(const MYSQLND_CONN_DATA * const conn);
typedef void				(*func_mysqlnd_conn_data__get_statistics)(const MYSQLND_CONN_DATA * const conn, zval *return_value ZEND_FILE_LINE_DC);

typedef zend_ulong			(*func_mysqlnd_conn_data__get_server_version)(const MYSQLND_CONN_DATA * const conn);
typedef const char *		(*func_mysqlnd_conn_data__get_server_information)(const MYSQLND_CONN_DATA * const conn);
typedef enum_func_status	(*func_mysqlnd_conn_data__get_server_statistics)(MYSQLND_CONN_DATA * conn, zend_string **message);
typedef const char *		(*func_mysqlnd_conn_data__get_host_information)(const MYSQLND_CONN_DATA * const conn);
typedef unsigned int		(*func_mysqlnd_conn_data__get_protocol_information)(const MYSQLND_CONN_DATA * const conn);
typedef const char *		(*func_mysqlnd_conn_data__get_last_message)(const MYSQLND_CONN_DATA * const conn);
typedef const char *		(*func_mysqlnd_conn_data__charset_name)(const MYSQLND_CONN_DATA * const conn);
typedef MYSQLND_RES *		(*func_mysqlnd_conn_data__list_method)(MYSQLND_CONN_DATA * conn, const char * const query, const char * const achtung_wild, const char * const par1);

typedef uint64_t			(*func_mysqlnd_conn_data__get_last_insert_id)(const MYSQLND_CONN_DATA * const conn);
typedef uint64_t			(*func_mysqlnd_conn_data__get_affected_rows)(const MYSQLND_CONN_DATA * const conn);
typedef unsigned int		(*func_mysqlnd_conn_data__get_warning_count)(const MYSQLND_CONN_DATA * const conn);

typedef unsigned int		(*func_mysqlnd_conn_data__get_field_count)(const MYSQLND_CONN_DATA * const conn);

typedef unsigned int		(*func_mysqlnd_conn_data__get_server_status)(const MYSQLND_CONN_DATA * const conn);
typedef enum_func_status	(*func_mysqlnd_conn_data__set_server_option)(MYSQLND_CONN_DATA * const conn, enum_mysqlnd_server_option option);
typedef enum_func_status	(*func_mysqlnd_conn_data__set_client_option)(MYSQLND_CONN_DATA * const conn, enum_mysqlnd_client_option option, const char * const value);
typedef void				(*func_mysqlnd_conn_data__free_contents)(MYSQLND_CONN_DATA * conn);/* private */
typedef void				(*func_mysqlnd_conn_data__free_options)(MYSQLND_CONN_DATA * conn);	/* private */
typedef void				(*func_mysqlnd_conn_data__dtor)(MYSQLND_CONN_DATA * conn);	/* private */

typedef enum_func_status	(*func_mysqlnd_conn_data__query_read_result_set_header)(MYSQLND_CONN_DATA * conn, MYSQLND_STMT * stmt);

typedef MYSQLND_CONN_DATA *	(*func_mysqlnd_conn_data__get_reference)(MYSQLND_CONN_DATA * const conn);
typedef enum_func_status	(*func_mysqlnd_conn_data__free_reference)(MYSQLND_CONN_DATA * const conn);

typedef enum_func_status	(*func_mysqlnd_conn_data__send_command_do_request)(MYSQLND_CONN_DATA * const conn, const enum php_mysqlnd_server_command command, const zend_uchar * const arg, const size_t arg_len, const zend_bool silent, const zend_bool ignore_upsert_status);
typedef enum_func_status	(*func_mysqlnd_conn_data__send_command_handle_response)(MYSQLND_CONN_DATA * const conn, const enum mysqlnd_packet_type ok_packet, const zend_bool silent, const enum php_mysqlnd_server_command command, const zend_bool ignore_upsert_status);

typedef enum_func_status	(*func_mysqlnd_conn_data__restart_psession)(MYSQLND_CONN_DATA * conn);
typedef enum_func_status	(*func_mysqlnd_conn_data__end_psession)(MYSQLND_CONN_DATA * conn);
typedef enum_func_status	(*func_mysqlnd_conn_data__send_close)(MYSQLND_CONN_DATA * conn);

typedef enum_func_status    (*func_mysqlnd_conn_data__ssl_set)(MYSQLND_CONN_DATA * const conn, const char * key, const char * const cert, const char * const ca, const char * const capath, const char * const cipher);

typedef MYSQLND_RES * 		(*func_mysqlnd_conn_data__result_init)(unsigned int field_count, zend_bool persistent);

typedef enum_func_status	(*func_mysqlnd_conn_data__set_autocommit)(MYSQLND_CONN_DATA * conn, unsigned int mode);
typedef enum_func_status	(*func_mysqlnd_conn_data__tx_commit)(MYSQLND_CONN_DATA * conn);
typedef enum_func_status	(*func_mysqlnd_conn_data__tx_rollback)(MYSQLND_CONN_DATA * conn);
typedef enum_func_status	(*func_mysqlnd_conn_data__tx_begin)(MYSQLND_CONN_DATA * conn, const unsigned int mode, const char * const name);
typedef enum_func_status	(*func_mysqlnd_conn_data__tx_commit_or_rollback)(MYSQLND_CONN_DATA * conn, const zend_bool commit, const unsigned int flags, const char * const name);
typedef void				(*func_mysqlnd_conn_data__tx_cor_options_to_string)(const MYSQLND_CONN_DATA * const conn, smart_str * tmp_str, const unsigned int mode);
typedef enum_func_status	(*func_mysqlnd_conn_data__tx_savepoint)(MYSQLND_CONN_DATA * conn, const char * const name);
typedef enum_func_status	(*func_mysqlnd_conn_data__tx_savepoint_release)(MYSQLND_CONN_DATA * conn, const char * const name);

typedef enum_func_status	(*func_mysqlnd_conn_data__local_tx_start)(MYSQLND_CONN_DATA * conn, const size_t this_func);
typedef enum_func_status	(*func_mysqlnd_conn_data__local_tx_end)(MYSQLND_CONN_DATA * conn, const size_t this_func, const enum_func_status status);
typedef enum_func_status	(*func_mysqlnd_conn_data__execute_init_commands)(MYSQLND_CONN_DATA * conn);
typedef unsigned int		(*func_mysqlnd_conn_data__get_updated_connect_flags)(MYSQLND_CONN_DATA * conn, unsigned int mysql_flags);
typedef enum_func_status	(*func_mysqlnd_conn_data__connect_handshake)(MYSQLND_CONN_DATA * conn, const MYSQLND_CSTRING * const scheme, const MYSQLND_CSTRING * const username, const MYSQLND_CSTRING * const password, const MYSQLND_CSTRING * const database, const unsigned int mysql_flags);
typedef struct st_mysqlnd_authentication_plugin * (*func_mysqlnd_conn_data__fetch_auth_plugin_by_name)(const char * const requested_protocol);

typedef enum_func_status	(*func_mysqlnd_conn_data__set_client_option_2d)(MYSQLND_CONN_DATA * const conn, const enum_mysqlnd_client_option option, const char * const key, const char * const value);


typedef size_t				(*func_mysqlnd_conn_data__negotiate_client_api_capabilities)(MYSQLND_CONN_DATA * const conn, const size_t flags);
typedef size_t				(*func_mysqlnd_conn_data__get_client_api_capabilities)(const MYSQLND_CONN_DATA * const conn);

typedef MYSQLND_STRING		(*func_mysqlnd_conn_data__get_scheme)(MYSQLND_CONN_DATA * conn, MYSQLND_CSTRING hostname, MYSQLND_CSTRING *socket_or_pipe, unsigned int port, zend_bool * unix_socket, zend_bool * named_pipe);



MYSQLND_CLASS_METHODS_TYPE(mysqlnd_conn_data)
{
	func_mysqlnd_conn_data__connect connect;
	func_mysqlnd_conn_data__escape_string escape_string;
	func_mysqlnd_conn_data__set_charset set_charset;
	func_mysqlnd_conn_data__query query;
	func_mysqlnd_conn_data__send_query send_query;
	func_mysqlnd_conn_data__reap_query reap_query;
	func_mysqlnd_conn_data__use_result use_result;
	func_mysqlnd_conn_data__store_result store_result;
	func_mysqlnd_conn_data__next_result next_result;
	func_mysqlnd_conn_data__more_results more_results;

	func_mysqlnd_conn_data__stmt_init stmt_init;

	func_mysqlnd_conn_data__shutdown_server shutdown_server;
	func_mysqlnd_conn_data__refresh_server refresh_server;

	func_mysqlnd_conn_data__ping ping;
	func_mysqlnd_conn_data__kill_connection kill_connection;
	func_mysqlnd_conn_data__select_db select_db;
	func_mysqlnd_conn_data__server_dump_debug_information server_dump_debug_information;
	func_mysqlnd_conn_data__change_user change_user;

	func_mysqlnd_conn_data__get_error_no get_error_no;
	func_mysqlnd_conn_data__get_error_str get_error_str;
	func_mysqlnd_conn_data__get_sqlstate get_sqlstate;
	func_mysqlnd_conn_data__get_thread_id get_thread_id;
	func_mysqlnd_conn_data__get_statistics get_statistics;

	func_mysqlnd_conn_data__get_server_version get_server_version;
	func_mysqlnd_conn_data__get_server_information get_server_information;
	func_mysqlnd_conn_data__get_server_statistics get_server_statistics;
	func_mysqlnd_conn_data__get_host_information get_host_information;
	func_mysqlnd_conn_data__get_protocol_information get_protocol_information;
	func_mysqlnd_conn_data__get_last_message get_last_message;
	func_mysqlnd_conn_data__charset_name charset_name;
	func_mysqlnd_conn_data__list_method list_method;

	func_mysqlnd_conn_data__get_last_insert_id get_last_insert_id;
	func_mysqlnd_conn_data__get_affected_rows get_affected_rows;
	func_mysqlnd_conn_data__get_warning_count get_warning_count;

	func_mysqlnd_conn_data__get_field_count get_field_count;

	func_mysqlnd_conn_data__get_server_status get_server_status;

	func_mysqlnd_conn_data__set_server_option set_server_option;
	func_mysqlnd_conn_data__set_client_option set_client_option;
	func_mysqlnd_conn_data__free_contents free_contents;
	func_mysqlnd_conn_data__free_options free_options;
	func_mysqlnd_conn_data__dtor dtor;

	func_mysqlnd_conn_data__query_read_result_set_header query_read_result_set_header;

	func_mysqlnd_conn_data__get_reference get_reference;
	func_mysqlnd_conn_data__free_reference free_reference;

	func_mysqlnd_conn_data__restart_psession restart_psession;
	func_mysqlnd_conn_data__end_psession end_psession;
	func_mysqlnd_conn_data__send_close send_close;

	func_mysqlnd_conn_data__ssl_set ssl_set;

	func_mysqlnd_conn_data__result_init result_init;
	func_mysqlnd_conn_data__set_autocommit set_autocommit;
	func_mysqlnd_conn_data__tx_commit tx_commit;
	func_mysqlnd_conn_data__tx_rollback tx_rollback;
	func_mysqlnd_conn_data__tx_begin tx_begin;
	func_mysqlnd_conn_data__tx_commit_or_rollback tx_commit_or_rollback;
	func_mysqlnd_conn_data__tx_cor_options_to_string tx_cor_options_to_string;
	func_mysqlnd_conn_data__tx_savepoint tx_savepoint;
	func_mysqlnd_conn_data__tx_savepoint_release tx_savepoint_release;

	func_mysqlnd_conn_data__local_tx_start local_tx_start;
	func_mysqlnd_conn_data__local_tx_end local_tx_end;

	func_mysqlnd_conn_data__execute_init_commands execute_init_commands;
	func_mysqlnd_conn_data__get_updated_connect_flags get_updated_connect_flags;
	func_mysqlnd_conn_data__connect_handshake connect_handshake;
	func_mysqlnd_conn_data__fetch_auth_plugin_by_name fetch_auth_plugin_by_name;

	func_mysqlnd_conn_data__set_client_option_2d set_client_option_2d;

	func_mysqlnd_conn_data__negotiate_client_api_capabilities negotiate_client_api_capabilities;
	func_mysqlnd_conn_data__get_client_api_capabilities get_client_api_capabilities;

	func_mysqlnd_conn_data__get_scheme get_scheme;
};


typedef enum_func_status	(*func_mysqlnd_data__connect)(MYSQLND * conn, const MYSQLND_CSTRING hostname, const MYSQLND_CSTRING username, const MYSQLND_CSTRING password, const MYSQLND_CSTRING database, unsigned int port, const MYSQLND_CSTRING socket_or_pipe, unsigned int mysql_flags);
typedef MYSQLND *			(*func_mysqlnd_conn__clone_object)(MYSQLND * const conn);
typedef void				(*func_mysqlnd_conn__dtor)(MYSQLND * conn);
typedef enum_func_status	(*func_mysqlnd_conn__close)(MYSQLND * conn, const enum_connection_close_type close_type);

MYSQLND_CLASS_METHODS_TYPE(mysqlnd_conn)
{
	func_mysqlnd_data__connect connect;
	func_mysqlnd_conn__clone_object clone_object;
	func_mysqlnd_conn__dtor dtor;
	func_mysqlnd_conn__close close;
};


	/* for decoding - binary or text protocol */
typedef enum_func_status	(*func_mysqlnd_res__row_decoder)(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval * fields,
									unsigned int field_count, const MYSQLND_FIELD * fields_metadata,
									zend_bool as_int_or_float, MYSQLND_STATS * stats);


typedef MYSQLND_RES *		(*func_mysqlnd_res__use_result)(MYSQLND_RES * const result, const zend_bool ps_protocol);
typedef MYSQLND_RES *		(*func_mysqlnd_res__store_result)(MYSQLND_RES * result, MYSQLND_CONN_DATA * const conn, const unsigned int flags);
typedef void 				(*func_mysqlnd_res__fetch_into)(MYSQLND_RES *result, const unsigned int flags, zval *return_value, enum_mysqlnd_extension ext ZEND_FILE_LINE_DC);
typedef MYSQLND_ROW_C 		(*func_mysqlnd_res__fetch_row_c)(MYSQLND_RES *result);
typedef void 				(*func_mysqlnd_res__fetch_all)(MYSQLND_RES *result, const unsigned int flags, zval *return_value ZEND_FILE_LINE_DC);
typedef void 				(*func_mysqlnd_res__fetch_field_data)(MYSQLND_RES *result, unsigned int offset, zval *return_value);
typedef uint64_t			(*func_mysqlnd_res__num_rows)(const MYSQLND_RES * const result);
typedef unsigned int		(*func_mysqlnd_res__num_fields)(const MYSQLND_RES * const result);
typedef enum_func_status	(*func_mysqlnd_res__skip_result)(MYSQLND_RES * const result);
typedef enum_func_status	(*func_mysqlnd_res__seek_data)(MYSQLND_RES * const result, const uint64_t row);
typedef MYSQLND_FIELD_OFFSET (*func_mysqlnd_res__seek_field)(MYSQLND_RES * const result, const MYSQLND_FIELD_OFFSET field_offset);
typedef MYSQLND_FIELD_OFFSET (*func_mysqlnd_res__field_tell)(const MYSQLND_RES * const result);
typedef const MYSQLND_FIELD *(*func_mysqlnd_res__fetch_field)(MYSQLND_RES * const result);
typedef const MYSQLND_FIELD *(*func_mysqlnd_res__fetch_field_direct)(MYSQLND_RES * const result, const MYSQLND_FIELD_OFFSET fieldnr);
typedef const MYSQLND_FIELD *(*func_mysqlnd_res__fetch_fields)(MYSQLND_RES * const result);

typedef enum_func_status	(*func_mysqlnd_res__read_result_metadata)(MYSQLND_RES * result, MYSQLND_CONN_DATA * conn);
typedef const size_t *		(*func_mysqlnd_res__fetch_lengths)(MYSQLND_RES * const result);
typedef enum_func_status	(*func_mysqlnd_res__store_result_fetch_data)(MYSQLND_CONN_DATA * const conn, MYSQLND_RES * result, MYSQLND_RES_METADATA * meta, MYSQLND_MEMORY_POOL_CHUNK *** row_buffers, zend_bool binary_protocol);

typedef void				(*func_mysqlnd_res__free_result_buffers)(MYSQLND_RES * result);	/* private */
typedef enum_func_status	(*func_mysqlnd_res__free_result)(MYSQLND_RES * result, const zend_bool implicit);
typedef void				(*func_mysqlnd_res__free_result_internal)(MYSQLND_RES *result);
typedef void				(*func_mysqlnd_res__free_result_contents)(MYSQLND_RES *result);
typedef void				(*func_mysqlnd_res__free_buffered_data)(MYSQLND_RES *result);
typedef void				(*func_mysqlnd_res__unbuffered_free_last_data)(MYSQLND_RES *result);


typedef MYSQLND_RES_METADATA * (*func_mysqlnd_res__result_meta_init)(unsigned int field_count, zend_bool persistent);

MYSQLND_CLASS_METHODS_TYPE(mysqlnd_res)
{
	mysqlnd_fetch_row_func	fetch_row;

	func_mysqlnd_res__use_result use_result;
	func_mysqlnd_res__store_result store_result;
	func_mysqlnd_res__fetch_into fetch_into;
	func_mysqlnd_res__fetch_row_c fetch_row_c;
	func_mysqlnd_res__fetch_all fetch_all;
	func_mysqlnd_res__fetch_field_data fetch_field_data;
	func_mysqlnd_res__num_rows num_rows;
	func_mysqlnd_res__num_fields num_fields;
	func_mysqlnd_res__skip_result skip_result;
	func_mysqlnd_res__seek_data seek_data;
	func_mysqlnd_res__seek_field seek_field;
	func_mysqlnd_res__field_tell field_tell;
	func_mysqlnd_res__fetch_field fetch_field;
	func_mysqlnd_res__fetch_field_direct fetch_field_direct;
	func_mysqlnd_res__fetch_fields fetch_fields;
	func_mysqlnd_res__read_result_metadata read_result_metadata;
	func_mysqlnd_res__fetch_lengths fetch_lengths;
	func_mysqlnd_res__store_result_fetch_data store_result_fetch_data;
	func_mysqlnd_res__free_result_buffers free_result_buffers;
	func_mysqlnd_res__free_result free_result;
	func_mysqlnd_res__free_result_internal free_result_internal;
	func_mysqlnd_res__free_result_contents free_result_contents;

	func_mysqlnd_res__result_meta_init result_meta_init;

	void * unused1;
	void * unused2;
	void * unused3;
	void * unused4;
	void * unused5;
};


typedef uint64_t		(*func_mysqlnd_result_unbuffered__num_rows)(const MYSQLND_RES_UNBUFFERED * const result);
typedef const size_t *	(*func_mysqlnd_result_unbuffered__fetch_lengths)(MYSQLND_RES_UNBUFFERED * const result);
typedef void			(*func_mysqlnd_result_unbuffered__free_last_data)(MYSQLND_RES_UNBUFFERED * result, MYSQLND_STATS * const global_stats);
typedef void			(*func_mysqlnd_result_unbuffered__free_result)(MYSQLND_RES_UNBUFFERED * const result, MYSQLND_STATS * const global_stats);

MYSQLND_CLASS_METHODS_TYPE(mysqlnd_result_unbuffered)
{
	mysqlnd_fetch_row_func							fetch_row;
	func_mysqlnd_res__row_decoder					row_decoder;
	func_mysqlnd_result_unbuffered__num_rows		num_rows;
	func_mysqlnd_result_unbuffered__fetch_lengths	fetch_lengths;
	func_mysqlnd_result_unbuffered__free_last_data	free_last_data;
	func_mysqlnd_result_unbuffered__free_result		free_result;
};

typedef uint64_t			(*func_mysqlnd_result_buffered__num_rows)(const MYSQLND_RES_BUFFERED * const result);
typedef enum_func_status	(*func_mysqlnd_result_buffered__initialize_result_set_rest)(MYSQLND_RES_BUFFERED * const result, MYSQLND_RES_METADATA * const meta,
																						MYSQLND_STATS * stats, zend_bool int_and_float_native);
typedef const size_t *		(*func_mysqlnd_result_buffered__fetch_lengths)(MYSQLND_RES_BUFFERED * const result);
typedef enum_func_status	(*func_mysqlnd_result_buffered__data_seek)(MYSQLND_RES_BUFFERED * const result, const uint64_t row);
typedef void				(*func_mysqlnd_result_buffered__free_result)(MYSQLND_RES_BUFFERED * const result);

MYSQLND_CLASS_METHODS_TYPE(mysqlnd_result_buffered)
{
	mysqlnd_fetch_row_func						fetch_row;
	func_mysqlnd_res__row_decoder				row_decoder;
	func_mysqlnd_result_buffered__num_rows		num_rows;
	func_mysqlnd_result_buffered__fetch_lengths	fetch_lengths;
	func_mysqlnd_result_buffered__data_seek		data_seek;
	func_mysqlnd_result_buffered__initialize_result_set_rest initialize_result_set_rest;
	func_mysqlnd_result_buffered__free_result	free_result;
};


typedef const MYSQLND_FIELD *	(*func_mysqlnd_res_meta__fetch_field)(MYSQLND_RES_METADATA * const meta);
typedef const MYSQLND_FIELD *	(*func_mysqlnd_res_meta__fetch_field_direct)(const MYSQLND_RES_METADATA * const meta, const MYSQLND_FIELD_OFFSET fieldnr);
typedef const MYSQLND_FIELD *	(*func_mysqlnd_res_meta__fetch_fields)(MYSQLND_RES_METADATA * const meta);
typedef MYSQLND_FIELD_OFFSET	(*func_mysqlnd_res_meta__field_tell)(const MYSQLND_RES_METADATA * const meta);
typedef MYSQLND_FIELD_OFFSET	(*func_mysqlnd_res_meta__field_seek)(MYSQLND_RES_METADATA * const meta, const MYSQLND_FIELD_OFFSET field_offset);
typedef enum_func_status		(*func_mysqlnd_res_meta__read_metadata)(MYSQLND_RES_METADATA * const meta, MYSQLND_CONN_DATA * conn);
typedef MYSQLND_RES_METADATA *	(*func_mysqlnd_res_meta__clone_metadata)(const MYSQLND_RES_METADATA * const meta, const zend_bool persistent);
typedef void					(*func_mysqlnd_res_meta__free_metadata)(MYSQLND_RES_METADATA * meta);

MYSQLND_CLASS_METHODS_TYPE(mysqlnd_res_meta)
{
	func_mysqlnd_res_meta__fetch_field fetch_field;
	func_mysqlnd_res_meta__fetch_field_direct fetch_field_direct;
	func_mysqlnd_res_meta__fetch_fields fetch_fields;
	func_mysqlnd_res_meta__field_tell field_tell;
	func_mysqlnd_res_meta__field_seek field_seek;
	func_mysqlnd_res_meta__read_metadata read_metadata;
	func_mysqlnd_res_meta__clone_metadata clone_metadata;
	func_mysqlnd_res_meta__free_metadata free_metadata;
};


typedef enum_func_status	(*func_mysqlnd_stmt__prepare)(MYSQLND_STMT * const stmt, const char * const query, const size_t query_len);
typedef enum_func_status	(*func_mysqlnd_stmt__send_execute)(MYSQLND_STMT * const s, const enum_mysqlnd_send_execute_type type, zval * read_cb, zval * err_cb);
typedef enum_func_status	(*func_mysqlnd_stmt__execute)(MYSQLND_STMT * const stmt);
typedef MYSQLND_RES *		(*func_mysqlnd_stmt__use_result)(MYSQLND_STMT * const stmt);
typedef MYSQLND_RES *		(*func_mysqlnd_stmt__store_result)(MYSQLND_STMT * const stmt);
typedef MYSQLND_RES *		(*func_mysqlnd_stmt__get_result)(MYSQLND_STMT * const stmt);
typedef zend_bool			(*func_mysqlnd_stmt__more_results)(const MYSQLND_STMT * const stmt);
typedef enum_func_status	(*func_mysqlnd_stmt__next_result)(MYSQLND_STMT * const stmt);
typedef enum_func_status	(*func_mysqlnd_stmt__free_result)(MYSQLND_STMT * const stmt);
typedef enum_func_status	(*func_mysqlnd_stmt__seek_data)(const MYSQLND_STMT * const stmt, uint64_t row);
typedef enum_func_status	(*func_mysqlnd_stmt__reset)(MYSQLND_STMT * const stmt);
typedef enum_func_status	(*func_mysqlnd_stmt__close_on_server)(MYSQLND_STMT * const stmt, zend_bool implicit); /* private */
typedef enum_func_status	(*func_mysqlnd_stmt__dtor)(MYSQLND_STMT * const stmt, zend_bool implicit); /* use this for mysqlnd_stmt_close */
typedef enum_func_status	(*func_mysqlnd_stmt__fetch)(MYSQLND_STMT * const stmt, zend_bool * const fetched_anything);
typedef enum_func_status	(*func_mysqlnd_stmt__bind_parameters)(MYSQLND_STMT * const stmt, MYSQLND_PARAM_BIND * const param_bind);
typedef enum_func_status	(*func_mysqlnd_stmt__bind_one_parameter)(MYSQLND_STMT * const stmt, unsigned int param_no, zval * const zv, zend_uchar	type);
typedef enum_func_status	(*func_mysqlnd_stmt__refresh_bind_param)(MYSQLND_STMT * const stmt);
typedef enum_func_status	(*func_mysqlnd_stmt__bind_result)(MYSQLND_STMT * const stmt, MYSQLND_RESULT_BIND * const result_bind);
typedef enum_func_status	(*func_mysqlnd_stmt__bind_one_result)(MYSQLND_STMT * const stmt, unsigned int param_no);
typedef enum_func_status	(*func_mysqlnd_stmt__send_long_data)(MYSQLND_STMT * const stmt, unsigned int param_num, const char * const data, zend_ulong length);
typedef MYSQLND_RES *		(*func_mysqlnd_stmt__get_parameter_metadata)(MYSQLND_STMT * const stmt);
typedef MYSQLND_RES *		(*func_mysqlnd_stmt__get_result_metadata)(MYSQLND_STMT * const stmt);
typedef uint64_t			(*func_mysqlnd_stmt__get_last_insert_id)(const MYSQLND_STMT * const stmt);
typedef uint64_t			(*func_mysqlnd_stmt__get_affected_rows)(const MYSQLND_STMT * const stmt);
typedef uint64_t			(*func_mysqlnd_stmt__get_num_rows)(const MYSQLND_STMT * const stmt);
typedef unsigned int		(*func_mysqlnd_stmt__get_param_count)(const MYSQLND_STMT * const stmt);
typedef unsigned int		(*func_mysqlnd_stmt__get_field_count)(const MYSQLND_STMT * const stmt);
typedef unsigned int		(*func_mysqlnd_stmt__get_warning_count)(const MYSQLND_STMT * const stmt);
typedef unsigned int		(*func_mysqlnd_stmt__get_error_no)(const MYSQLND_STMT * const stmt);
typedef const char *		(*func_mysqlnd_stmt__get_error_str)(const MYSQLND_STMT * const stmt);
typedef const char *		(*func_mysqlnd_stmt__get_sqlstate)(const MYSQLND_STMT * const stmt);
typedef enum_func_status	(*func_mysqlnd_stmt__get_attribute)(const MYSQLND_STMT * const stmt, enum mysqlnd_stmt_attr attr_type, void * const value);
typedef enum_func_status	(*func_mysqlnd_stmt__set_attribute)(MYSQLND_STMT * const stmt, enum mysqlnd_stmt_attr attr_type, const void * const value);
typedef MYSQLND_PARAM_BIND *(*func_mysqlnd_stmt__alloc_param_bind)(MYSQLND_STMT * const stmt);
typedef MYSQLND_RESULT_BIND*(*func_mysqlnd_stmt__alloc_result_bind)(MYSQLND_STMT * const stmt);
typedef	void 				(*func_mysqlnd_stmt__free_parameter_bind)(MYSQLND_STMT * const stmt, MYSQLND_PARAM_BIND *);
typedef	void 				(*func_mysqlnd_stmt__free_result_bind)(MYSQLND_STMT * const stmt, MYSQLND_RESULT_BIND *);
typedef unsigned int		(*func_mysqlnd_stmt__server_status)(const MYSQLND_STMT * const stmt);
typedef enum_func_status 	(*func_mysqlnd_stmt__generate_execute_request)(MYSQLND_STMT * const s, zend_uchar ** request, size_t *request_len, zend_bool * free_buffer);
typedef enum_func_status	(*func_mysqlnd_stmt__parse_execute_response)(MYSQLND_STMT * const s, enum_mysqlnd_parse_exec_response_type type);
typedef void 				(*func_mysqlnd_stmt__free_stmt_content)(MYSQLND_STMT * const s);
typedef enum_func_status	(*func_mysqlnd_stmt__flush)(MYSQLND_STMT * const stmt);
typedef void 				(*func_mysqlnd_stmt__free_stmt_result)(MYSQLND_STMT * const s);

MYSQLND_CLASS_METHODS_TYPE(mysqlnd_stmt)
{
	func_mysqlnd_stmt__prepare prepare;
	func_mysqlnd_stmt__send_execute send_execute;
	func_mysqlnd_stmt__execute execute;
	func_mysqlnd_stmt__use_result use_result;
	func_mysqlnd_stmt__store_result store_result;
	func_mysqlnd_stmt__get_result get_result;
	func_mysqlnd_stmt__more_results more_results;
	func_mysqlnd_stmt__next_result next_result;
	func_mysqlnd_stmt__free_result free_result;
	func_mysqlnd_stmt__seek_data seek_data;
	func_mysqlnd_stmt__reset reset;
	func_mysqlnd_stmt__close_on_server close_on_server;
	func_mysqlnd_stmt__dtor dtor;
	func_mysqlnd_stmt__fetch fetch;

	func_mysqlnd_stmt__bind_parameters bind_parameters;
	func_mysqlnd_stmt__bind_one_parameter bind_one_parameter;
	func_mysqlnd_stmt__refresh_bind_param refresh_bind_param;
	func_mysqlnd_stmt__bind_result bind_result;
	func_mysqlnd_stmt__bind_one_result bind_one_result;
	func_mysqlnd_stmt__send_long_data send_long_data;
	func_mysqlnd_stmt__get_parameter_metadata get_parameter_metadata;
	func_mysqlnd_stmt__get_result_metadata get_result_metadata;

	func_mysqlnd_stmt__get_last_insert_id get_last_insert_id;
	func_mysqlnd_stmt__get_affected_rows get_affected_rows;
	func_mysqlnd_stmt__get_num_rows get_num_rows;

	func_mysqlnd_stmt__get_param_count get_param_count;
	func_mysqlnd_stmt__get_field_count get_field_count;
	func_mysqlnd_stmt__get_warning_count get_warning_count;

	func_mysqlnd_stmt__get_error_no get_error_no;
	func_mysqlnd_stmt__get_error_str get_error_str;
	func_mysqlnd_stmt__get_sqlstate get_sqlstate;

	func_mysqlnd_stmt__get_attribute get_attribute;
	func_mysqlnd_stmt__set_attribute set_attribute;

	func_mysqlnd_stmt__alloc_param_bind alloc_parameter_bind;
	func_mysqlnd_stmt__alloc_result_bind alloc_result_bind;

	func_mysqlnd_stmt__free_parameter_bind free_parameter_bind;
	func_mysqlnd_stmt__free_result_bind free_result_bind;

	func_mysqlnd_stmt__server_status get_server_status;

	func_mysqlnd_stmt__generate_execute_request generate_execute_request;
	func_mysqlnd_stmt__parse_execute_response parse_execute_response;

	func_mysqlnd_stmt__free_stmt_content free_stmt_content;

	func_mysqlnd_stmt__flush flush;

	func_mysqlnd_stmt__free_stmt_result free_stmt_result;
};


struct st_mysqlnd_vio_data
{
	php_stream			*stream;
	zend_bool			ssl;
	MYSQLND_VIO_OPTIONS	options;
#ifdef MYSQLND_DO_WIRE_CHECK_BEFORE_COMMAND
	zend_uchar			last_command;
#else
	zend_uchar			unused_pad1;
#endif

	zend_bool			persistent;

	MYSQLND_CLASS_METHODS_TYPE(mysqlnd_vio) m;
};


struct st_mysqlnd_vio
{
	struct st_mysqlnd_vio_data * data;

	zend_bool persistent;
};



struct st_mysqlnd_protocol_command
{
	enum_func_status (*run)(void *cmd);
	void (*free_command)(void * cmd);
};

typedef struct st_mysqlnd_protocol_command * (*func_mysqlnd__command_factory)(enum php_mysqlnd_server_command command, ...);



typedef struct st_mysqlnd_connection_state MYSQLND_CONNECTION_STATE;
typedef enum mysqlnd_connection_state (*func_mysqlnd_connection_state__get)(const MYSQLND_CONNECTION_STATE * const state_struct);
typedef void (*func_mysqlnd_connection_state__set)(MYSQLND_CONNECTION_STATE * const state_struct, const enum mysqlnd_connection_state state);


MYSQLND_CLASS_METHODS_TYPE(mysqlnd_connection_state)
{
	func_mysqlnd_connection_state__get get;
	func_mysqlnd_connection_state__set set;
};

struct st_mysqlnd_connection_state
{
	enum mysqlnd_connection_state state;

	MYSQLND_CLASS_METHODS_TYPE(mysqlnd_connection_state) *m;
};

struct st_mysqlnd_connection_data
{
/* Operation related */
	MYSQLND_PFC		* protocol_frame_codec;
	MYSQLND_VIO		* vio;
	MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * payload_decoder_factory;

/* Information related */
	MYSQLND_STRING	hostname;
	MYSQLND_STRING	unix_socket;
	MYSQLND_STRING	username;
	MYSQLND_STRING	password;
	MYSQLND_STRING	scheme;
	uint64_t		thread_id;
	char			*server_version;
	char			*host_info;
	MYSQLND_STRING	authentication_plugin_data;
	const MYSQLND_CHARSET *charset;
	const MYSQLND_CHARSET *greet_charset;
	MYSQLND_STRING	connect_or_select_db;
	MYSQLND_INFILE	infile;
	unsigned int	protocol_version;
	unsigned int	port;
	zend_ulong		server_capabilities;

	/* For UPSERT queries */
	MYSQLND_UPSERT_STATUS * upsert_status;
	MYSQLND_UPSERT_STATUS upsert_status_impl;
	MYSQLND_STRING last_message;

	/* If error packet, we use these */
	MYSQLND_ERROR_INFO	* error_info;
	MYSQLND_ERROR_INFO	error_info_impl;

	MYSQLND_CONNECTION_STATE	state;
	enum_mysqlnd_query_type		last_query_type;
	/* Temporary storage between query and (use|store)_result() call */
	MYSQLND_RES						*current_result;

	/*
	  How many result sets reference this connection.
	  It won't be freed until this number reaches 0.
	  The last one, please close the door! :-)
	  The result set objects can determine by inspecting
	  'quit_sent' whether the connection is still valid.
	*/
	unsigned int	refcount;

	/* Temporal storage for mysql_query */
	unsigned int	field_count;

	/* options */
	MYSQLND_SESSION_OPTIONS	* options;
	MYSQLND_SESSION_OPTIONS	options_impl;

	/* stats */
	MYSQLND_STATS	* stats;

	size_t			client_api_capabilities;

	zval			async_read_cb;
	zval			async_err_cb;
	zend_bool		in_async_read_cb;
	zend_bool		in_async_err_cb;

	MYSQLND_CLASS_METHODS_TYPE(mysqlnd_object_factory) object_factory;
	func_mysqlnd__command_factory command_factory;

	MYSQLND_CLASS_METHODS_TYPE(mysqlnd_conn_data) * m;

	/* persistent connection */
	zend_bool		persistent;
};


struct st_mysqlnd_connection
{
	MYSQLND_CONN_DATA * data;
	zend_bool persistent;
	MYSQLND_CLASS_METHODS_TYPE(mysqlnd_conn) * m;
};



struct st_mysqlnd_packet_greet;
struct st_mysqlnd_packet_greet;
struct st_mysqlnd_packet_auth;
struct st_mysqlnd_packet_ok;
struct st_mysqlnd_packet_command;
struct st_mysqlnd_packet_eof;
struct st_mysqlnd_packet_rset_header;
struct st_mysqlnd_packet_res_field;
struct st_mysqlnd_packet_row;
struct st_mysqlnd_packet_stats;
struct st_mysqlnd_packet_prepare_response;
struct st_mysqlnd_packet_chg_user_resp;
struct st_mysqlnd_packet_auth_pam;
struct st_mysqlnd_packet_sha256_pk_request;
struct st_mysqlnd_packet_sha256_pk_request_response;

typedef struct st_mysqlnd_packet_greet *		(*func_mysqlnd_protocol_payload_decoder_factory__get_greet_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent);
typedef struct st_mysqlnd_packet_auth *			(*func_mysqlnd_protocol_payload_decoder_factory__get_auth_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent);
typedef struct st_mysqlnd_packet_auth_response *(*func_mysqlnd_protocol_payload_decoder_factory__get_auth_response_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent);
typedef struct st_mysqlnd_packet_change_auth_response *	(*func_mysqlnd_protocol_payload_decoder_factory__get_change_auth_response_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent);
typedef struct st_mysqlnd_packet_ok *			(*func_mysqlnd_protocol_payload_decoder_factory__get_ok_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent);
typedef struct st_mysqlnd_packet_command *		(*func_mysqlnd_protocol_payload_decoder_factory__get_command_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent);
typedef struct st_mysqlnd_packet_eof *			(*func_mysqlnd_protocol_payload_decoder_factory__get_eof_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent);
typedef struct st_mysqlnd_packet_rset_header *	(*func_mysqlnd_protocol_payload_decoder_factory__get_rset_header_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent);
typedef struct st_mysqlnd_packet_res_field *	(*func_mysqlnd_protocol_payload_decoder_factory__get_result_field_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent);
typedef struct st_mysqlnd_packet_row *			(*func_mysqlnd_protocol_payload_decoder_factory__get_row_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent);
typedef struct st_mysqlnd_packet_stats *		(*func_mysqlnd_protocol_payload_decoder_factory__get_stats_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent);
typedef struct st_mysqlnd_packet_prepare_response *(*func_mysqlnd_protocol_payload_decoder_factory__get_prepare_response_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent);
typedef struct st_mysqlnd_packet_chg_user_resp*(*func_mysqlnd_protocol_payload_decoder_factory__get_change_user_response_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent);
typedef struct st_mysqlnd_packet_sha256_pk_request *(*func_mysqlnd_protocol_payload_decoder_factory__get_sha256_pk_request_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent);
typedef struct st_mysqlnd_packet_sha256_pk_request_response *(*func_mysqlnd_protocol_payload_decoder_factory__get_sha256_pk_request_response_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent);

typedef enum_func_status (*func_mysqlnd_protocol_payload_decoder_factory__send_command)(
			MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * payload_decoder_factory,
			const enum php_mysqlnd_server_command command,
			const zend_uchar * const arg, const size_t arg_len,
			const zend_bool silent,

			MYSQLND_CONNECTION_STATE * connection_state,
			MYSQLND_ERROR_INFO	* error_info,
			MYSQLND_UPSERT_STATUS * upsert_status,
			MYSQLND_STATS * stats,
			func_mysqlnd_conn_data__send_close send_close,
			void * send_close_ctx);

typedef enum_func_status (*func_mysqlnd_protocol_payload_decoder_factory__send_command_handle_OK)(
			MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const payload_decoder_factory,
			MYSQLND_ERROR_INFO * const error_info,
			MYSQLND_UPSERT_STATUS * const upsert_status,
			const zend_bool ignore_upsert_status,  /* actually used only by LOAD DATA. COM_QUERY and COM_EXECUTE handle the responses themselves */
			MYSQLND_STRING * const last_message,
			const zend_bool last_message_persistent);

typedef enum_func_status (*func_mysqlnd_protocol_payload_decoder_factory__send_command_handle_EOF)(
			MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const payload_decoder_factory,
			MYSQLND_ERROR_INFO * const error_info,
			MYSQLND_UPSERT_STATUS * const upsert_status);

typedef enum_func_status (*func_mysqlnd_protocol_payload_decoder_factory__send_command_handle_response)(
			MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * payload_decoder_factory,
			const enum mysqlnd_packet_type ok_packet,
			const zend_bool silent,
			const enum php_mysqlnd_server_command command,
			const zend_bool ignore_upsert_status, /* actually used only by LOAD DATA. COM_QUERY and COM_EXECUTE handle the responses themselves */

			MYSQLND_ERROR_INFO	* error_info,
			MYSQLND_UPSERT_STATUS * upsert_status,
			MYSQLND_STRING * last_message,
			zend_bool last_message_persistent);


MYSQLND_CLASS_METHODS_TYPE(mysqlnd_protocol_payload_decoder_factory)
{
	func_mysqlnd_protocol_payload_decoder_factory__get_greet_packet get_greet_packet;
	func_mysqlnd_protocol_payload_decoder_factory__get_auth_packet get_auth_packet;
	func_mysqlnd_protocol_payload_decoder_factory__get_auth_response_packet get_auth_response_packet;
	func_mysqlnd_protocol_payload_decoder_factory__get_change_auth_response_packet get_change_auth_response_packet;
	func_mysqlnd_protocol_payload_decoder_factory__get_ok_packet get_ok_packet;
	func_mysqlnd_protocol_payload_decoder_factory__get_command_packet get_command_packet;
	func_mysqlnd_protocol_payload_decoder_factory__get_eof_packet get_eof_packet;
	func_mysqlnd_protocol_payload_decoder_factory__get_rset_header_packet get_rset_header_packet;
	func_mysqlnd_protocol_payload_decoder_factory__get_result_field_packet get_result_field_packet;
	func_mysqlnd_protocol_payload_decoder_factory__get_row_packet get_row_packet;
	func_mysqlnd_protocol_payload_decoder_factory__get_stats_packet get_stats_packet;
	func_mysqlnd_protocol_payload_decoder_factory__get_prepare_response_packet get_prepare_response_packet;
	func_mysqlnd_protocol_payload_decoder_factory__get_change_user_response_packet get_change_user_response_packet;
	func_mysqlnd_protocol_payload_decoder_factory__get_sha256_pk_request_packet get_sha256_pk_request_packet;
	func_mysqlnd_protocol_payload_decoder_factory__get_sha256_pk_request_response_packet get_sha256_pk_request_response_packet;

	func_mysqlnd_protocol_payload_decoder_factory__send_command send_command;
	func_mysqlnd_protocol_payload_decoder_factory__send_command_handle_response send_command_handle_response;
	func_mysqlnd_protocol_payload_decoder_factory__send_command_handle_OK send_command_handle_OK;
	func_mysqlnd_protocol_payload_decoder_factory__send_command_handle_EOF send_command_handle_EOF;
};

struct st_mysqlnd_protocol_payload_decoder_factory
{
	MYSQLND_CONN_DATA * conn;
	zend_bool persistent;
	MYSQLND_CLASS_METHODS_TYPE(mysqlnd_protocol_payload_decoder_factory) m;
};


typedef struct st_mysqlnd_read_buffer {
	zend_uchar 	* data;
	size_t 		offset;
	size_t 		size;
	size_t		len;
	zend_bool	(*is_empty)(const struct st_mysqlnd_read_buffer *);
	void		(*read)(struct st_mysqlnd_read_buffer *, size_t count, zend_uchar * dest);
	size_t		(*bytes_left)(const struct st_mysqlnd_read_buffer *);
	void		(*free_buffer)(struct st_mysqlnd_read_buffer **);
} MYSQLND_READ_BUFFER;



typedef enum_func_status	(*func_mysqlnd_pfc__init)(MYSQLND_PFC * const pfc, MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info);
typedef void				(*func_mysqlnd_pfc__dtor)(MYSQLND_PFC * const pfc, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info);
typedef enum_func_status	(*func_mysqlnd_pfc__reset)(MYSQLND_PFC * const pfc, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info);
typedef enum_func_status	(*func_mysqlnd_pfc__set_client_option)(MYSQLND_PFC * const pfc, enum_mysqlnd_client_option option, const char * const value);
typedef enum_func_status	(*func_mysqlnd_pfc__decode)(zend_uchar * uncompressed_data, const size_t uncompressed_data_len, const zend_uchar * const compressed_data, const size_t compressed_data_len);
typedef enum_func_status	(*func_mysqlnd_pfc__encode)(zend_uchar * compress_buffer, size_t * compress_buffer_len, const zend_uchar * const uncompressed_data, const size_t uncompressed_data_len);
typedef size_t				(*func_mysqlnd_pfc__send)(MYSQLND_PFC * const pfc, MYSQLND_VIO * const vio, zend_uchar * const buffer, const size_t count, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info);
typedef enum_func_status	(*func_mysqlnd_pfc__receive)(MYSQLND_PFC * const pfc, MYSQLND_VIO * const vio, zend_uchar * const buffer, const size_t count, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info);
typedef enum_func_status	(*func_mysqlnd_pfc__read_compressed_packet_from_stream_and_fill_read_buffer)(MYSQLND_PFC * pfc, MYSQLND_VIO * const vio, size_t net_payload_size, MYSQLND_STATS * conn_stats, MYSQLND_ERROR_INFO * error_info);
typedef void				(*func_mysqlnd_pfc__free_contents)(MYSQLND_PFC * pfc);

MYSQLND_CLASS_METHODS_TYPE(mysqlnd_protocol_packet_frame_codec)
{
	func_mysqlnd_pfc__init init;
	func_mysqlnd_pfc__dtor dtor;
	func_mysqlnd_pfc__reset reset;
	func_mysqlnd_pfc__set_client_option set_client_option;

	func_mysqlnd_pfc__decode decode;
	func_mysqlnd_pfc__encode encode;

	func_mysqlnd_pfc__send send;
	func_mysqlnd_pfc__receive receive;

	func_mysqlnd_pfc__read_compressed_packet_from_stream_and_fill_read_buffer read_compressed_packet_from_stream_and_fill_read_buffer;

	func_mysqlnd_pfc__free_contents free_contents;
};


struct st_mysqlnd_protocol_frame_codec_data
{
	php_stream		*stream;
	zend_bool		compressed;
	zend_bool		ssl;
	uint64_t		flags;
	char *			sha256_server_public_key;

#ifdef MYSQLND_COMPRESSION_ENABLED
	MYSQLND_READ_BUFFER	* uncompressed_data;
#else
	void * 				unused_pad1;
#endif

	/* sequence for simple checking of correct packets */
	zend_uchar		packet_no;
	zend_uchar		compressed_envelope_packet_no;

	zend_bool		persistent;

	MYSQLND_CLASS_METHODS_TYPE(mysqlnd_protocol_packet_frame_codec) m;
};


struct st_mysqlnd_protocol_frame_codec
{
	MYSQLND_CMD_BUFFER	cmd_buffer;

	struct st_mysqlnd_protocol_frame_codec_data * data;

	zend_bool 		persistent;
};



struct mysqlnd_field_hash_key
{
	zend_bool		is_numeric;
	zend_ulong	key;
};


struct st_mysqlnd_result_metadata
{
	MYSQLND_FIELD					*fields;
	struct mysqlnd_field_hash_key	*zend_hash_keys;

	MYSQLND_CLASS_METHODS_TYPE(mysqlnd_res_meta) * m;

	unsigned int					current_field;
	unsigned int					field_count;

	zend_bool						persistent;
};


#define def_mysqlnd_buffered_result_parent 			\
	MYSQLND_MEMORY_POOL_CHUNK **row_buffers;		\
	uint64_t			row_count;					\
	uint64_t			initialized_rows;			\
													\
	/*  Column lengths of current row - both buffered and unbuffered. For buffered results it duplicates the data found in **data */ \
	size_t				*lengths;					\
													\
	MYSQLND_MEMORY_POOL	*result_set_memory_pool;	\
													\
	unsigned int		references;					\
													\
	MYSQLND_ERROR_INFO	error_info;					\
													\
	unsigned int		field_count;				\
	zend_bool			ps;							\
	zend_bool			persistent;					\
	MYSQLND_CLASS_METHODS_TYPE(mysqlnd_result_buffered) m;	\
	enum mysqlnd_buffered_type type;				\
	void				* unused1;					\
	void				* unused2;					\
	void				* unused3


struct st_mysqlnd_buffered_result_parent
{
	def_mysqlnd_buffered_result_parent;
};


struct st_mysqlnd_buffered_result_zval
{
	def_mysqlnd_buffered_result_parent;

	zval	*data;
	zval	*data_cursor;
};


struct st_mysqlnd_buffered_result_c
{
	def_mysqlnd_buffered_result_parent;

	zend_uchar	*initialized; /* every row is a single bit */
	uint64_t	current_row;
};


struct st_mysqlnd_unbuffered_result
{
	MYSQLND_CLASS_METHODS_TYPE(mysqlnd_result_unbuffered) m;
	uint64_t			row_count;

	/* For unbuffered (both normal and PS) */
	zval				*last_row_data;
	MYSQLND_MEMORY_POOL_CHUNK *last_row_buffer;

	/*
	  Column lengths of current row - both buffered and unbuffered.
	  For buffered results it duplicates the data found in **data
	*/
	size_t				*lengths;

	MYSQLND_MEMORY_POOL	*result_set_memory_pool;

	struct st_mysqlnd_packet_row * row_packet;

	unsigned int		field_count;

	zend_bool			eof_reached;

	zend_bool			ps;
	zend_bool			persistent;

};


struct st_mysqlnd_res
{
	MYSQLND_CONN_DATA		*conn;
	enum_mysqlnd_res_type	type;
	unsigned int			field_count;

	/* For metadata functions */
	MYSQLND_RES_METADATA	*meta;

	/* To be used with store_result() - both normal and PS */
	MYSQLND_RES_BUFFERED	*stored_data;
	MYSQLND_RES_UNBUFFERED	*unbuf;

	zend_bool				persistent;
	MYSQLND_CLASS_METHODS_TYPE(mysqlnd_res) m;
};


struct st_mysqlnd_param_bind
{
	zval		zv;
	zend_uchar	type;
	enum_param_bind_flags	flags;
};

struct st_mysqlnd_result_bind
{
	zval		zv;
	zend_bool	bound;
};


struct st_mysqlnd_stmt_data
{
	MYSQLND_CONN_DATA			*conn;
	zend_ulong					stmt_id;
	zend_ulong					flags;/* cursor is set here */
	enum_mysqlnd_stmt_state		state;
	MYSQLND_RES					*result;
	unsigned int				field_count;
	unsigned int				param_count;
	unsigned char				send_types_to_server;
	MYSQLND_PARAM_BIND			*param_bind;
	MYSQLND_RESULT_BIND			*result_bind;
	zend_bool					result_zvals_separated_once;
	zend_bool					persistent;

	MYSQLND_UPSERT_STATUS * 	upsert_status;
	MYSQLND_UPSERT_STATUS 		upsert_status_impl;

	MYSQLND_ERROR_INFO *		error_info;
	MYSQLND_ERROR_INFO			error_info_impl;

	zend_bool					update_max_length;
	zend_ulong					prefetch_rows;

	zend_bool					cursor_exists;
	mysqlnd_stmt_use_or_store_func default_rset_handler;

	zval						execute_read_cb;
	zval						execute_err_cb;
	zend_bool					in_execute_read_cb;
	zend_bool					in_execute_err_cb;

	MYSQLND_CMD_BUFFER			execute_cmd_buffer;
	unsigned int				execute_count;/* count how many times the stmt was executed */
};


struct st_mysqlnd_stmt
{
	MYSQLND_STMT_DATA * data;
	MYSQLND_CLASS_METHODS_TYPE(mysqlnd_stmt) * m;
	zend_bool persistent;
};


struct st_mysqlnd_plugin_header
{
	unsigned int	plugin_api_version;
	const char *	plugin_name;
	zend_ulong	plugin_version;
	const char *	plugin_string_version;
	const char *	plugin_license;
	const char *	plugin_author;
	struct
	{
		MYSQLND_STATS *			values;
		const MYSQLND_STRING *	names;
	} plugin_stats;

	struct
	{
		enum_func_status (*plugin_shutdown)(void * plugin);
	} m;
};


struct st_mysqlnd_plugin_core
{
	struct st_mysqlnd_plugin_header plugin_header;
};


struct st_mysqlnd_typeii_plugin_example
{
	struct st_mysqlnd_plugin_header plugin_header;
	void * methods;
	unsigned int counter;
};

struct st_mysqlnd_authentication_plugin;

typedef zend_uchar * (*func_auth_plugin__get_auth_data)(struct st_mysqlnd_authentication_plugin * self,
														size_t * auth_data_len,
														MYSQLND_CONN_DATA * conn, const char * const user, const char * const passwd,
														const size_t passwd_len, zend_uchar * auth_plugin_data, size_t auth_plugin_data_len,
														const MYSQLND_SESSION_OPTIONS * const session_options,
														const MYSQLND_PFC_DATA * const pfc_data, zend_ulong mysql_flags
														);

struct st_mysqlnd_authentication_plugin
{
	struct st_mysqlnd_plugin_header plugin_header;
	struct {
		func_auth_plugin__get_auth_data get_auth_data;
	} methods;
};

#endif /* MYSQLND_STRUCTS_H */
php/ext/mysqlnd/mysqlnd_statistics.h000064400000012206151730540440013740 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Andrey Hristov <andrey@php.net>                             |
  |          Ulf Wendel <uw@php.net>                                     |
  +----------------------------------------------------------------------+
*/

#ifndef MYSQLND_STATISTICS_H
#define MYSQLND_STATISTICS_H

#ifdef ZTS
#define MYSQLND_STATS_LOCK(stats) tsrm_mutex_lock((stats)->LOCK_access)
#define MYSQLND_STATS_UNLOCK(stats) tsrm_mutex_unlock((stats)->LOCK_access)
#else
#define MYSQLND_STATS_LOCK(stats)
#define MYSQLND_STATS_UNLOCK(stats)
#endif

#ifndef MYSQLND_CORE_STATISTICS_TRIGGERS_DISABLED
#define MYSQLND_STAT_CALL_TRIGGER(s_array, statistic, val) \
			if ((s_array)->triggers[(statistic)] && (s_array)->in_trigger == FALSE) { \
				(s_array)->in_trigger = TRUE; \
				MYSQLND_STATS_UNLOCK((s_array)); \
																						\
				(s_array)->triggers[(statistic)]((s_array), (statistic), (val)); \
																						\
				MYSQLND_STATS_LOCK((s_array)); \
				(s_array)->in_trigger = FALSE; \
			}
#else
#define MYSQLND_STAT_CALL_TRIGGER(s_array, statistic, val)
#endif /* MYSQLND_CORE_STATISTICS_TRIGGERS_DISABLED */

#define MYSQLND_UPDATE_VALUE_AND_CALL_TRIGGER(stats, statistic, value) \
	{ \
			MYSQLND_STATS_LOCK(stats); \
			(stats)->values[(statistic)] += (value); \
			MYSQLND_STAT_CALL_TRIGGER((stats), (statistic), (value)); \
			MYSQLND_STATS_UNLOCK(_p_s); \
	}

#define MYSQLND_DEC_STATISTIC(enabler, stats, statistic) \
 { \
	enum_mysqlnd_collected_stats _s = (statistic);\
	MYSQLND_STATS * _p_s = (MYSQLND_STATS *) (stats); \
	if ((enabler) && _p_s && _s != _p_s->count) { \
		MYSQLND_UPDATE_VALUE_AND_CALL_TRIGGER(_p_s, _s, -1); \
	}\
 }

#define MYSQLND_INC_STATISTIC(enabler, stats, statistic) \
 { \
	enum_mysqlnd_collected_stats _s = (statistic);\
	MYSQLND_STATS * _p_s = (MYSQLND_STATS *) (stats); \
	if ((enabler) && _p_s && _s != _p_s->count) { \
		MYSQLND_UPDATE_VALUE_AND_CALL_TRIGGER(_p_s, _s, 1); \
	}\
 }

#define MYSQLND_INC_STATISTIC_W_VALUE(enabler, stats, statistic, value) \
 { \
	enum_mysqlnd_collected_stats _s = (statistic);\
	MYSQLND_STATS * _p_s = (MYSQLND_STATS *) (stats); \
	if ((enabler) && _p_s && _s != _p_s->count) { \
		uint64_t v = (uint64_t) (value); \
		MYSQLND_UPDATE_VALUE_AND_CALL_TRIGGER(_p_s, _s, v); \
	}\
 }

#define MYSQLND_INC_STATISTIC_W_VALUE2(enabler, stats, statistic1, value1, statistic2, value2) \
 { \
	MYSQLND_STATS * _p_s = (MYSQLND_STATS *) (stats); \
	if ((enabler) && _p_s) { \
		uint64_t v1 = (uint64_t) (value1); \
		uint64_t v2 = (uint64_t) (value2); \
		enum_mysqlnd_collected_stats _s1 = (statistic1);\
		enum_mysqlnd_collected_stats _s2 = (statistic2);\
		if (_s1 != _p_s->count) MYSQLND_UPDATE_VALUE_AND_CALL_TRIGGER(_p_s, _s1, v1); \
		if (_s2 != _p_s->count) MYSQLND_UPDATE_VALUE_AND_CALL_TRIGGER(_p_s, _s2, v2); \
	}\
 }

#define MYSQLND_INC_STATISTIC_W_VALUE3(enabler, stats, statistic1, value1, statistic2, value2, statistic3, value3) \
 { \
	MYSQLND_STATS * _p_s = (MYSQLND_STATS *) (stats); \
	if ((enabler) && _p_s) { \
		uint64_t v1 = (uint64_t) (value1); \
		uint64_t v2 = (uint64_t) (value2); \
		uint64_t v3 = (uint64_t) (value3); \
		enum_mysqlnd_collected_stats _s1 = (statistic1);\
		enum_mysqlnd_collected_stats _s2 = (statistic2);\
		enum_mysqlnd_collected_stats _s3 = (statistic3);\
		if (_s1 != _p_s->count) MYSQLND_UPDATE_VALUE_AND_CALL_TRIGGER(_p_s, _s1, v1); \
		if (_s2 != _p_s->count) MYSQLND_UPDATE_VALUE_AND_CALL_TRIGGER(_p_s, _s2, v2); \
		if (_s3 != _p_s->count) MYSQLND_UPDATE_VALUE_AND_CALL_TRIGGER(_p_s, _s3, v3); \
	}\
 }



PHPAPI void mysqlnd_stats_init(MYSQLND_STATS ** stats, const size_t statistic_count, const zend_bool persistent);
PHPAPI void mysqlnd_stats_end(MYSQLND_STATS * stats, const zend_bool persistent);

PHPAPI void mysqlnd_fill_stats_hash(const MYSQLND_STATS * const stats, const MYSQLND_STRING * names, zval *return_value ZEND_FILE_LINE_DC);

PHPAPI mysqlnd_stat_trigger mysqlnd_stats_set_trigger(MYSQLND_STATS * const stats, enum_mysqlnd_collected_stats stat, mysqlnd_stat_trigger trigger);
PHPAPI mysqlnd_stat_trigger mysqlnd_stats_reset_triggers(MYSQLND_STATS * const stats);

#endif	/* MYSQLND_STATISTICS_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/ext/mysqlnd/mysqlnd_block_alloc.h000064400000003060151730540450014011 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Andrey Hristov <andrey@php.net>                             |
  |          Ulf Wendel <uw@php.net>                                     |
  +----------------------------------------------------------------------+
*/

#ifndef MYSQLND_BLOCK_ALLOC_H
#define MYSQLND_BLOCK_ALLOC_H

PHPAPI MYSQLND_MEMORY_POOL *	mysqlnd_mempool_create(size_t arena_size);
PHPAPI void 					mysqlnd_mempool_destroy(MYSQLND_MEMORY_POOL * pool);

#endif	/* MYSQLND_BLOCK_ALLOC_H */


/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/ext/mysqlnd/config-win.h000064400000006357151730540450012052 0ustar00/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB
This file is public domain and comes with NO WARRANTY of any kind */

/* Defines for Win32 to make it compatible for MySQL */

#ifndef _MYSQLND_CONFIG_WIN_H
#define _MYSQLND_CONFIG_WIN_H

#include <sys/locking.h>
#include <windows.h>
#include <math.h>			/* Because of rint() */
#include <fcntl.h>
#include <io.h>
#include <malloc.h>

#include <win32/php_stdint.h>

#ifndef HAVE_INT8_T
#define HAVE_INT8_T
#endif
#ifndef HAVE_UINT8_T
#define HAVE_UINT8_T
#endif
#ifndef HAVE_INT16_T
#define HAVE_INT16_T
#endif
#ifndef HAVE_UINT16_T
#define HAVE_UINT16_T
#endif
#ifndef HAVE_INT32_T
#define HAVE_INT32_T
#endif
#ifndef HAVE_UINT32_T
#define HAVE_UINT32_T
#endif
#ifndef HAVE_INT64_T
#define HAVE_INT64_T
#endif
#ifndef HAVE_UINT64_T
#define HAVE_UINT64_T
#endif


#ifndef _WIN64
#ifndef _WIN32
#define _WIN32				/* Compatible with old source */
#endif
#ifndef __WIN32__
#define __WIN32__
#endif
#endif /* _WIN64 */
#ifndef __WIN__
#define __WIN__				/* To make it easier in VC++ */
#endif

/* Type information */

#define SIZEOF_CHAR		1
#define SIZEOF_LONG		4
#define SIZEOF_LONG_LONG	8


#ifndef _WIN64
/* Optimized store functions for Intel x86 */

#define sint2korr(A)	(*((int16_t *) (A)))
#define sint3korr(A)	((int32_t) ((((zend_uchar) (A)[2]) & 128) ? \
										(((uint32_t) 255L << 24) | \
										(((uint32_t) (zend_uchar) (A)[2]) << 16) |\
										(((uint32_t) (zend_uchar) (A)[1]) << 8) | \
										((uint32_t) (zend_uchar) (A)[0])) : \
										(((uint32_t) (zend_uchar) (A)[2]) << 16) |\
										(((uint32_t) (zend_uchar) (A)[1]) << 8) | \
										((uint32_t) (zend_uchar) (A)[0])))
#define sint4korr(A)	(*((int32_t *) (A)))
#define uint2korr(A)	(*((uint16_t *) (A)))
#define uint3korr(A)	(int32_t) (*((uint32_t *) (A)) & 0xFFFFFF)
#define uint4korr(A)	(*((uint32_t *) (A)))
#define uint5korr(A)	((uint64_t)(((uint32_t) ((zend_uchar) (A)[0])) +\
									(((uint32_t) ((zend_uchar) (A)[1])) << 8) +\
									(((uint32_t) ((zend_uchar) (A)[2])) << 16) +\
									(((uint32_t) ((zend_uchar) (A)[3])) << 24)) +\
									(((uint64_t) ((zend_uchar) (A)[4])) << 32))
#define uint8korr(A)	(*((uint64_t *) (A)))
#define sint8korr(A)	(*((int64_t *) (A)))
#define int2store(T,A)	*((uint16_t*) (T))= (uint16_t) (A)
#define int3store(T,A)		{	*(T)=  (zend_uchar) ((A));\
								*(T+1)=(zend_uchar) (((uint32_t) (A) >> 8));\
								*(T+2)=(zend_uchar) (((A) >> 16)); }
#define int4store(T,A)	*((int32_t *) (T))= (int32_t) (A)
#define int5store(T,A)	{	*(T)= (zend_uchar)((A));\
							*((T)+1)=(zend_uchar) (((A) >> 8));\
							*((T)+2)=(zend_uchar) (((A) >> 16));\
							*((T)+3)=(zend_uchar) (((A) >> 24)); \
							*((T)+4)=(zend_uchar) (((A) >> 32)); }
#define int8store(T,A)	*((uint64_t *) (T))= (uint64_t) (A)

#define float8get(V,M)	{	*((int32_t *) &V) = *((int32_t*) M); \
							*(((int32_t *) &V)+1) = *(((int32_t*) M)+1); }
#define float8store(T,V) {	*((int32_t *) T) = *((int32_t*) &V); \
							*(((int32_t *) T)+1) = *(((int32_t*) &V)+1); }
#define float4get(V,M) { *((int32_t *) &(V)) = *((int32_t*) (M)); }

#endif /* _WIN64 */

#endif /* _MYSQLND_CONFIG_WIN_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/ext/mysqlnd/mysqlnd_connection.h000064400000006563151730540450013717 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Andrey Hristov <andrey@php.net>                             |
  |          Ulf Wendel <uw@php.net>                                     |
  +----------------------------------------------------------------------+
*/

#ifndef MYSQLND_CONNECTION_H
#define MYSQLND_CONNECTION_H

PHPAPI extern const char * const mysqlnd_out_of_sync;
PHPAPI extern const char * const mysqlnd_server_gone;
PHPAPI extern const char * const mysqlnd_out_of_memory;


void mysqlnd_upsert_status_init(MYSQLND_UPSERT_STATUS * const upsert_status);

#define UPSERT_STATUS_RESET(status)							(status)->m->reset((status))

#define UPSERT_STATUS_GET_SERVER_STATUS(status)				(status)->server_status
#define UPSERT_STATUS_SET_SERVER_STATUS(status, server_st)	(status)->server_status = (server_st)

#define UPSERT_STATUS_GET_WARNINGS(status)					(status)->warning_count
#define UPSERT_STATUS_SET_WARNINGS(status, warnings)		(status)->warning_count = (warnings)

#define UPSERT_STATUS_GET_AFFECTED_ROWS(status)				(status)->affected_rows
#define UPSERT_STATUS_SET_AFFECTED_ROWS(status, rows)		(status)->affected_rows = (rows)
#define UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(status)	(status)->m->set_affected_rows_to_error((status))

#define UPSERT_STATUS_GET_LAST_INSERT_ID(status)			(status)->last_insert_id
#define UPSERT_STATUS_SET_LAST_INSERT_ID(status, id)		(status)->last_insert_id = (id)


/* Error handling */
#define SET_NEW_MESSAGE(buf, buf_len, message, len, persistent) \
	{\
		if ((buf)) { \
			mnd_pefree((buf), (persistent)); \
		} \
		if ((message)) { \
			(buf) = mnd_pestrndup((message), (len), (persistent)); \
		} else { \
			(buf) = NULL; \
		} \
		(buf_len) = (len); \
	}

#define SET_EMPTY_MESSAGE(buf, buf_len, persistent) \
	{\
		if ((buf)) { \
			mnd_pefree((buf), (persistent)); \
			(buf) = NULL; \
		} \
		(buf_len) = 0; \
	}


PHPAPI enum_func_status mysqlnd_error_info_init(MYSQLND_ERROR_INFO * const info, const zend_bool persistent);
PHPAPI void	mysqlnd_error_info_free_contents(MYSQLND_ERROR_INFO * const info);

#define GET_CONNECTION_STATE(state_struct)		(state_struct)->m->get((state_struct))
#define SET_CONNECTION_STATE(state_struct, s)	(state_struct)->m->set((state_struct), (s))

PHPAPI void mysqlnd_connection_state_init(struct st_mysqlnd_connection_state * const state);

#endif /* MYSQLND_CONNECTION_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/ext/mysqlnd/php_mysqlnd.h000064400000002751151730540460012343 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Andrey Hristov <andrey@php.net>                             |
  |          Ulf Wendel <uw@php.net>                                     |
  +----------------------------------------------------------------------+
*/

#ifndef PHP_MYSQLND_H
#define PHP_MYSQLND_H

#define phpext_mysqlnd_ptr &mysqlnd_module_entry
extern zend_module_entry mysqlnd_module_entry;

#endif	/* PHP_MYSQLND_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/ext/mysqlnd/mysqlnd_ext_plugin.h000064400000020421151730540460013724 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Andrey Hristov <andrey@php.net>                             |
  |          Johannes Schl�ter <johannes@php.net>                        |
  |          Ulf Wendel <uw@php.net>                                     |
  +----------------------------------------------------------------------+
*/

#ifndef MYSQLND_EXT_PLUGIN_H
#define MYSQLND_EXT_PLUGIN_H

struct st_mysqlnd_plugin__plugin_area_getters
{
	void ** (*get_connection_area)(const MYSQLND * conn, const unsigned int plugin_id);
	void ** (*get_connection_data_area)(const MYSQLND_CONN_DATA * conn, const unsigned int plugin_id);
	void ** (*get_result_area)(const MYSQLND_RES * result, const unsigned int plugin_id);
	void ** (*get_unbuffered_area)(const MYSQLND_RES_UNBUFFERED * result, const unsigned int plugin_id);
	void ** (*get_result_buffered_area)(const MYSQLND_RES_BUFFERED_ZVAL * result, const unsigned int plugin_id);
	void ** (*get_result_buffered_aread_c)(const MYSQLND_RES_BUFFERED_C * result, const unsigned int plugin_id);
	void ** (*get_stmt_area)(const MYSQLND_STMT * stmt, const unsigned int plugin_id);
	void ** (*get_protocol_decoder_area)(const MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * factory, const unsigned int plugin_id);
	void ** (*get_pfc_area)(const MYSQLND_PFC * pfc, const unsigned int plugin_id);
	void ** (*get_vio_area)(const MYSQLND_VIO * vio, const unsigned int plugin_id);
};

PHPAPI extern struct st_mysqlnd_plugin__plugin_area_getters mysqlnd_plugin_area_getters;

#define mysqlnd_plugin_get_plugin_connection_data(c, p_id)				mysqlnd_plugin_area_getters.get_connection_area((c), (p_id))
#define mysqlnd_plugin_get_plugin_connection_data_data(c, p_id)			mysqlnd_plugin_area_getters.get_connection_data_area((c), (p_id))
#define mysqlnd_plugin_get_plugin_result_data(res, p_id)				mysqlnd_plugin_area_getters.get_result_area((res), (p_id))
#define mysqlnd_plugin_get_plugin_result_unbuffered_data(res, p_id)		mysqlnd_plugin_area_getters.get_unbuffered_area((res), (p_id))
#define mysqlnd_plugin_get_plugin_result_buffered_data_zval(res, p_id)	mysqlnd_plugin_area_getters.get_result_buffered_area((res), (p_id))
#define mysqlnd_plugin_get_plugin_result_buffered_data_c(res, p_id)		mysqlnd_plugin_area_getters.get_result_buffered_aread_c((res), (p_id))
#define mysqlnd_plugin_get_plugin_stmt_data(stmt, p_id)					mysqlnd_plugin_area_getters.get_stmt_area((stmt), (p_id))
#define mysqlnd_plugin_get_plugin_protocol_data(proto, p_id)			mysqlnd_plugin_area_getters.get_protocol_decoder_area((proto), (p_id))
#define mysqlnd_plugin_get_plugin_pfc_data(pfc, p_id)					mysqlnd_plugin_area_getters.get_pfc_area((pfc), (p_id))
#define mysqlnd_plugin_get_plugin_vio_data(vio, p_id)					mysqlnd_plugin_area_getters.get_pfc_area((vio), (p_id))


struct st_mysqlnd_plugin_methods_xetters
{
	struct st_mnd_object_factory_xetters
	{
		MYSQLND_CLASS_METHODS_TYPE(mysqlnd_object_factory) * (*get)();
		void (*set)(MYSQLND_CLASS_METHODS_TYPE(mysqlnd_object_factory) *methods);
	} object_factory;

	struct st_mnd_connection_xetters
	{
		MYSQLND_CLASS_METHODS_TYPE(mysqlnd_conn) * (*get)();
		void (*set)(MYSQLND_CLASS_METHODS_TYPE(mysqlnd_conn) *methods);
	} connection;

	struct st_mnd_connection_data_xetters
	{
		MYSQLND_CLASS_METHODS_TYPE(mysqlnd_conn_data) * (*get)();
		void (*set)(MYSQLND_CLASS_METHODS_TYPE(mysqlnd_conn_data) *methods);
	} connection_data;

	struct st_mnd_result_xetters
	{
		MYSQLND_CLASS_METHODS_TYPE(mysqlnd_res) * (*get)();
		void (*set)(MYSQLND_CLASS_METHODS_TYPE(mysqlnd_res) *methods);
	} result;

	struct st_mnd_unbuffered_result_xetters
	{
		MYSQLND_CLASS_METHODS_TYPE(mysqlnd_result_unbuffered) * (*get)();
		void (*set)(MYSQLND_CLASS_METHODS_TYPE(mysqlnd_result_unbuffered) *methods);
	} unbuffered_result;

	struct st_mnd_buffered_result_xetters
	{
		MYSQLND_CLASS_METHODS_TYPE(mysqlnd_result_buffered)* (*get)();
		void (*set)(MYSQLND_CLASS_METHODS_TYPE(mysqlnd_result_buffered) *methods);
	} buffered_result;

	struct st_mnd_stmt_xetters
	{
		MYSQLND_CLASS_METHODS_TYPE(mysqlnd_stmt) * (*get)();
		void (*set)(MYSQLND_CLASS_METHODS_TYPE(mysqlnd_stmt) * methods);
	} statement;

	struct st_mnd_protocol_xetters
	{
		MYSQLND_CLASS_METHODS_TYPE(mysqlnd_protocol_payload_decoder_factory)* (*get)();
		void (*set)(MYSQLND_CLASS_METHODS_TYPE(mysqlnd_protocol_payload_decoder_factory) *methods);
	} protocol;

	struct st_mnd_pfc_xetters
	{
		MYSQLND_CLASS_METHODS_TYPE(mysqlnd_protocol_packet_frame_codec) * (*get)();
		void (*set)(MYSQLND_CLASS_METHODS_TYPE(mysqlnd_protocol_packet_frame_codec) * methods);
	} pfc;

	struct st_mnd_vio_xetters
	{
		MYSQLND_CLASS_METHODS_TYPE(mysqlnd_vio) * (*get)();
		void (*set)(MYSQLND_CLASS_METHODS_TYPE(mysqlnd_vio) * methods);
	} vio;

	struct st_mnd_error_info_xetters
	{
		MYSQLND_CLASS_METHODS_TYPE(mysqlnd_error_info) * (*get)();
		void (*set)(MYSQLND_CLASS_METHODS_TYPE(mysqlnd_error_info) * methods);
	} error_info;

	struct st_mnd_command_factory_xetters
	{
		func_mysqlnd__command_factory (*get)();
		void (*set)(func_mysqlnd__command_factory factory);
	} command_factory;
};

PHPAPI extern struct st_mysqlnd_plugin_methods_xetters mysqlnd_plugin_methods_xetters;


#define mysqlnd_object_factory_get_methods()	mysqlnd_plugin_methods_xetters.object_factory.get()
#define mysqlnd_object_factory_set_methods(m)	mysqlnd_plugin_methods_xetters.object_factory.set((m))

#define mysqlnd_conn_get_methods()			mysqlnd_plugin_methods_xetters.connection.get()
#define mysqlnd_conn_set_methods(m)			mysqlnd_plugin_methods_xetters.connection.set((m))

#define mysqlnd_conn_data_get_methods()		mysqlnd_plugin_methods_xetters.connection_data.get()
#define mysqlnd_conn_data_set_methods(m)	mysqlnd_plugin_methods_xetters.connection_data.set((m))

#define mysqlnd_result_get_methods()		mysqlnd_plugin_methods_xetters.result.get()
#define mysqlnd_result_set_methods(m)		mysqlnd_plugin_methods_xetters.result.set((m))

#define mysqlnd_result_unbuffered_get_methods()		mysqlnd_plugin_methods_xetters.unbuffered_result.get()
#define mysqlnd_result_unbuffered_set_methods(m)	mysqlnd_plugin_methods_xetters.unbuffered_result.set((m))

#define mysqlnd_result_buffered_get_methods()		mysqlnd_plugin_methods_xetters.buffered_result.get()
#define mysqlnd_result_buffered_set_methods(m)		mysqlnd_plugin_methods_xetters.buffered_result.set((m))

#define mysqlnd_stmt_get_methods()		mysqlnd_plugin_methods_xetters.statement.get()
#define mysqlnd_stmt_set_methods(m)		mysqlnd_plugin_methods_xetters.statement.set((m))

#define mysqlnd_protocol_get_methods()	mysqlnd_plugin_methods_xetters.protocol.get()
#define mysqlnd_protocol_set_methods(m)	mysqlnd_plugin_methods_xetters.protocol.set((m))

#define mysqlnd_pfc_get_methods()		mysqlnd_plugin_methods_xetters.pfc.get()
#define mysqlnd_pfc_set_methods(m)		mysqlnd_plugin_methods_xetters.pfc.set((m))

#define mysqlnd_vio_get_methods()		mysqlnd_plugin_methods_xetters.vio.get()
#define mysqlnd_vio_set_methods(m)		mysqlnd_plugin_methods_xetters.vio.set((m))

#define mysqlnd_command_factory_get()		mysqlnd_plugin_methods_xetters.command_factory.get()
#define mysqlnd_command_factory_set(m)		mysqlnd_plugin_methods_xetters.command_factory.set((m))

#define mysqlnd_error_info_get_methods()	mysqlnd_plugin_methods_xetters.error_info.get()
#define mysqlnd_error_info_set_methods(m)	mysqlnd_plugin_methods_xetters.error_info.set((m))

#endif	/* MYSQLND_EXT_PLUGIN_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/ext/mysqlnd/mysqlnd.h000064400000045653151730540470011505 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Andrey Hristov <andrey@php.net>                             |
  |          Ulf Wendel <uw@php.net>                                     |
  |          Georg Richter <georg@php.net>                               |
  +----------------------------------------------------------------------+
*/

#ifndef MYSQLND_H
#define MYSQLND_H

#define PHP_MYSQLND_VERSION "mysqlnd 5.0.12-dev - 20150407 - $Id: 3591daad22de08524295e1bd073aceeff11e6579 $"
#define MYSQLND_VERSION_ID 50012

#define MYSQLND_PLUGIN_API_VERSION 2

#define MYSQLND_STRING_TO_INT_CONVERSION
/*
  This force mysqlnd to do a single (or more depending on amount of data)
  non-blocking read() calls before sending a command to the server. Useful
  for debugging, if previous function hasn't consumed all the output sent
  to it - like stmt_send_long_data() error because the data was larger that
  max_allowed_packet_size, and COM_STMT_SEND_LONG_DATA by protocol doesn't
  use response packets, thus letting the next command to fail miserably, if
  the connector implementor is not aware of this deficiency. Should be off
  on production systems, if of course measured performance degradation is not
  minimal.
*/
#if A0 && PHP_DEBUG
#define MYSQLND_DO_WIRE_CHECK_BEFORE_COMMAND 1
#endif

#if PHP_DEBUG
#define MYSQLND_DBG_ENABLED 1
#else
#define MYSQLND_DBG_ENABLED 0
#endif

#if defined(MYSQLND_COMPRESSION_WANTED) && defined(HAVE_ZLIB)
#define MYSQLND_COMPRESSION_ENABLED 1
#endif

#ifdef ZTS
#include "TSRM.h"
#endif

#include "mysqlnd_portability.h"
#include "mysqlnd_enum_n_def.h"
#include "mysqlnd_structs.h"

#define MYSQLND_STR_W_LEN(str)  str, (sizeof(str) - 1)

/* Library related */
PHPAPI void mysqlnd_library_init(void);
PHPAPI void mysqlnd_library_end(void);

PHPAPI unsigned int mysqlnd_plugin_register();
PHPAPI unsigned int mysqlnd_plugin_register_ex(struct st_mysqlnd_plugin_header * plugin);
PHPAPI unsigned int mysqlnd_plugin_count();
PHPAPI void * mysqlnd_plugin_find(const char * const name);

PHPAPI void mysqlnd_plugin_apply_with_argument(apply_func_arg_t apply_func, void * argument);

#define mysqlnd_restart_psession(conn)	((conn)->data)->m->restart_psession((conn)->data)
#define mysqlnd_end_psession(conn)		((conn)->data)->m->end_psession((conn)->data)
PHPAPI void mysqlnd_minfo_print_hash(zval *values);
#define mysqlnd_thread_safe()	TRUE

PHPAPI const MYSQLND_CHARSET * mysqlnd_find_charset_nr(unsigned int charsetno);
PHPAPI const MYSQLND_CHARSET * mysqlnd_find_charset_name(const char * const charsetname);


/* Connect */
#define mysqlnd_init(flags, persistent)		mysqlnd_connection_init((flags), (persistent), NULL /*use default factory*/)
#define mysqlnd_connect(conn, host, user, pass, pass_len, db, db_len, port, socket, mysql_flags, client_api_flags) \
			mysqlnd_connection_connect((conn), (host), (user), (pass), (pass_len), (db), (db_len), (port), (socket), (mysql_flags), (client_api_flags))

PHPAPI MYSQLND * mysqlnd_connection_init(const size_t client_flags, const zend_bool persistent, MYSQLND_CLASS_METHODS_TYPE(mysqlnd_object_factory) *object_factory);
PHPAPI MYSQLND * mysqlnd_connection_connect(MYSQLND * conn,
											const char * const host,
											const char * const user,
											const char * const passwd, unsigned int passwd_len,
											const char * const db, unsigned int db_len,
											unsigned int port,
											const char * const socket_or_pipe,
											unsigned int mysql_flags,
											unsigned int client_api_flags
										);

#define mysqlnd_change_user(conn, user, passwd, db, silent)					((conn)->data)->m->change_user((conn)->data, (user), (passwd), (db), (silent), strlen((passwd)))
#define mysqlnd_change_user_ex(conn, user, passwd, db, silent, passwd_len)	((conn)->data)->m->change_user((conn)->data, (user), (passwd), (db), (silent), (passwd_len))

PHPAPI void mysqlnd_debug(const char *mode);

/* Query */
#define mysqlnd_fetch_into(result, flags, ret_val, ext)	(result)->m.fetch_into((result), (flags), (ret_val), (ext) ZEND_FILE_LINE_CC)
#define mysqlnd_fetch_row_c(result)						(result)->m.fetch_row_c((result))
#define mysqlnd_fetch_all(result, flags, return_value)	(result)->m.fetch_all((result), (flags), (return_value) ZEND_FILE_LINE_CC)
#define mysqlnd_result_fetch_field_data(res,offset,ret)	(res)->m.fetch_field_data((res), (offset), (ret))
#define mysqlnd_get_connection_stats(conn, values)		((conn)->data)->m->get_statistics((conn)->data,  (values) ZEND_FILE_LINE_CC)
#define mysqlnd_get_client_stats(values)				_mysqlnd_get_client_stats(mysqlnd_global_stats, (values) ZEND_FILE_LINE_CC)

#define mysqlnd_close(conn,is_forced)					(conn)->m->close((conn), (is_forced))
#define mysqlnd_query(conn, query_str, query_len)		((conn)->data)->m->query((conn)->data, (query_str), (query_len))
#define mysqlnd_async_query(conn, query_str, query_len)	((conn)->data)->m->send_query((conn)->data, (query_str), (query_len), MYSQLND_SEND_QUERY_EXPLICIT, NULL, NULL)
#define mysqlnd_reap_async_query(conn)					((conn)->data)->m->reap_query((conn)->data, MYSQLND_REAP_RESULT_EXPLICIT)
#define mysqlnd_unbuffered_skip_result(result)			(result)->m.skip_result((result))

PHPAPI enum_func_status mysqlnd_poll(MYSQLND **r_array, MYSQLND **e_array, MYSQLND ***dont_poll, long sec, long usec, int * desc_num);

#define mysqlnd_use_result(conn)		((conn)->data)->m->use_result((conn)->data, 0)
#define mysqlnd_store_result(conn)		((conn)->data)->m->store_result((conn)->data, MYSQLND_STORE_NO_COPY)
#define mysqlnd_store_result_ofs(conn)	((conn)->data)->m->store_result((conn)->data, MYSQLND_STORE_COPY)
#define mysqlnd_next_result(conn)		((conn)->data)->m->next_result((conn)->data)
#define mysqlnd_more_results(conn)		((conn)->data)->m->more_results((conn)->data)
#define mysqlnd_free_result(r,e_or_i)	((MYSQLND_RES*)r)->m.free_result(((MYSQLND_RES*)(r)), (e_or_i))
#define mysqlnd_data_seek(result, row)	(result)->m.seek_data((result), (row))

/* Errors */
#define mysqlnd_errno(conn)				((conn)->data)->m->get_error_no((conn)->data)
#define mysqlnd_error(conn)				((conn)->data)->m->get_error_str((conn)->data)
#define mysqlnd_sqlstate(conn)			((conn)->data)->m->get_sqlstate((conn)->data)

/* Charset */
#define mysqlnd_character_set_name(conn) ((conn)->data)->m->charset_name((conn)->data)

/* Simple metadata */
#define mysqlnd_field_count(conn)		((conn)->data)->m->get_field_count((conn)->data)
#define mysqlnd_insert_id(conn)			((conn)->data)->m->get_last_insert_id((conn)->data)
#define mysqlnd_affected_rows(conn)		((conn)->data)->m->get_affected_rows((conn)->data)
#define mysqlnd_warning_count(conn)		((conn)->data)->m->get_warning_count((conn)->data)
#define mysqlnd_info(conn)				((conn)->data)->m->get_last_message((conn)->data)
#define mysqlnd_get_server_info(conn)	((conn)->data)->m->get_server_information((conn)->data)
#define mysqlnd_get_server_version(conn) ((conn)->data)->m->get_server_version((conn)->data)
#define mysqlnd_get_host_info(conn)		((conn)->data)->m->get_host_information((conn)->data)
#define mysqlnd_get_proto_info(conn)	((conn)->data)->m->get_protocol_information((conn)->data)
#define mysqlnd_thread_id(conn)			((conn)->data)->m->get_thread_id((conn)->data)
#define mysqlnd_get_server_status(conn)	((conn)->data)->m->get_server_status((conn)->data)

#define mysqlnd_num_rows(result)		(result)->m.num_rows((result))
#define mysqlnd_num_fields(result)		(result)->m.num_fields((result))

#define mysqlnd_fetch_lengths(result)	(result)->m.fetch_lengths((result))

#define mysqlnd_field_seek(result, ofs)			(result)->m.seek_field((result), (ofs))
#define mysqlnd_field_tell(result)				(result)->m.field_tell((result))
#define mysqlnd_fetch_field(result)				(result)->m.fetch_field((result))
#define mysqlnd_fetch_field_direct(result,fnr)	(result)->m.fetch_field_direct((result), (fnr))
#define mysqlnd_fetch_fields(result)			(result)->m.fetch_fields((result))

/* mysqlnd metadata */
PHPAPI const char *	mysqlnd_get_client_info();
PHPAPI unsigned int	mysqlnd_get_client_version();

#define mysqlnd_ssl_set(conn, key, cert, ca, capath, cipher) ((conn)->data)->m->ssl_set((conn)->data, (key), (cert), (ca), (capath), (cipher))

/* PS */
#define mysqlnd_stmt_insert_id(stmt)		(stmt)->m->get_last_insert_id((stmt))
#define mysqlnd_stmt_affected_rows(stmt)	(stmt)->m->get_affected_rows((stmt))
#define mysqlnd_stmt_num_rows(stmt)			(stmt)->m->get_num_rows((stmt))
#define mysqlnd_stmt_param_count(stmt)		(stmt)->m->get_param_count((stmt))
#define mysqlnd_stmt_field_count(stmt)		(stmt)->m->get_field_count((stmt))
#define mysqlnd_stmt_warning_count(stmt)	(stmt)->m->get_warning_count((stmt))
#define mysqlnd_stmt_server_status(stmt)	(stmt)->m->get_server_status((stmt))
#define mysqlnd_stmt_errno(stmt)			(stmt)->m->get_error_no((stmt))
#define mysqlnd_stmt_error(stmt)			(stmt)->m->get_error_str((stmt))
#define mysqlnd_stmt_sqlstate(stmt)			(stmt)->m->get_sqlstate((stmt))


PHPAPI void mysqlnd_efree_param_bind_dtor(MYSQLND_PARAM_BIND * param_bind);
PHPAPI void mysqlnd_efree_result_bind_dtor(MYSQLND_RESULT_BIND * result_bind);
PHPAPI void mysqlnd_free_param_bind_dtor(MYSQLND_PARAM_BIND * param_bind);
PHPAPI void mysqlnd_free_result_bind_dtor(MYSQLND_RESULT_BIND * result_bind);


PHPAPI const char * mysqlnd_field_type_name(const enum mysqlnd_field_types field_type);

/* LOAD DATA LOCAL */
PHPAPI void mysqlnd_local_infile_default(MYSQLND_CONN_DATA * conn);

/* Simple commands */
#define mysqlnd_autocommit(conn, mode)		((conn)->data)->m->set_autocommit((conn)->data, (mode))
#define mysqlnd_begin_transaction(conn,flags,name) ((conn)->data)->m->tx_begin((conn)->data, (flags), (name))
#define mysqlnd_commit(conn, flags, name)	((conn)->data)->m->tx_commit_or_rollback((conn)->data, TRUE, (flags), (name))
#define mysqlnd_rollback(conn, flags, name)	((conn)->data)->m->tx_commit_or_rollback((conn)->data, FALSE, (flags), (name))
#define mysqlnd_savepoint(conn, name)		((conn)->data)->m->tx_savepoint((conn)->data, (name))
#define mysqlnd_release_savepoint(conn, name) ((conn)->data)->m->tx_savepoint_release((conn)->data, (name))
#define mysqlnd_list_dbs(conn, wild)		((conn)->data)->m->list_method((conn)->data, wild? "SHOW DATABASES LIKE %s":"SHOW DATABASES", (wild), NULL)
#define mysqlnd_list_processes(conn)		((conn)->data)->m->list_method((conn)->data, "SHOW PROCESSLIST", NULL, NULL)
#define mysqlnd_list_tables(conn, wild)		((conn)->data)->m->list_method((conn)->data, wild? "SHOW TABLES LIKE %s":"SHOW TABLES", (wild), NULL)
#define mysqlnd_dump_debug_info(conn)		((conn)->data)->m->server_dump_debug_information((conn)->data)
#define mysqlnd_select_db(conn, db, db_len)	((conn)->data)->m->select_db((conn)->data, (db), (db_len))
#define mysqlnd_ping(conn)					((conn)->data)->m->ping((conn)->data)
#define mysqlnd_kill(conn, pid)				((conn)->data)->m->kill_connection((conn)->data, (pid))
#define mysqlnd_refresh(conn, options)		((conn)->data)->m->refresh_server((conn)->data, (options))
#define mysqlnd_shutdown(conn, level)		((conn)->data)->m->shutdown_server((conn)->data, (level))
#define mysqlnd_set_character_set(conn, cs)	((conn)->data)->m->set_charset((conn)->data, (cs))
#define mysqlnd_stat(conn, msg)				((conn)->data)->m->get_server_statistics(((conn)->data), (msg))
#define mysqlnd_options(conn, opt, value)	((conn)->data)->m->set_client_option((conn)->data, (opt), (value))
#define mysqlnd_options4(conn, opt, k, v)	((conn)->data)->m->set_client_option_2d((conn)->data, (opt), (k), (v))
#define mysqlnd_set_server_option(conn, op)	((conn)->data)->m->set_server_option((conn)->data, (op))

/* Escaping */
#define mysqlnd_real_escape_string(conn, newstr, escapestr, escapestr_len) \
		((conn)->data)->m->escape_string((conn)->data, (newstr), (escapestr), (escapestr_len))
#define mysqlnd_escape_string(newstr, escapestr, escapestr_len) \
		mysqlnd_old_escape_string((newstr), (escapestr), (escapestr_len))

PHPAPI zend_ulong mysqlnd_old_escape_string(char * newstr, const char * escapestr, size_t escapestr_len);


/* PS */
#define mysqlnd_stmt_init(conn)						((conn)->data)->m->stmt_init(((conn)->data))
#define mysqlnd_stmt_store_result(stmt)				(!mysqlnd_stmt_field_count((stmt)) ? PASS:((stmt)->m->store_result((stmt))? PASS:FAIL))
#define mysqlnd_stmt_get_result(stmt)				(stmt)->m->get_result((stmt))
#define mysqlnd_stmt_more_results(stmt)				(stmt)->m->more_results((stmt))
#define mysqlnd_stmt_next_result(stmt)				(stmt)->m->next_result((stmt))
#define mysqlnd_stmt_data_seek(stmt, row)			(stmt)->m->seek_data((stmt), (row))
#define mysqlnd_stmt_prepare(stmt, q, qlen)			(stmt)->m->prepare((stmt), (q), (qlen))
#define mysqlnd_stmt_execute(stmt) 					(stmt)->m->execute((stmt))
#define mysqlnd_stmt_send_long_data(stmt,p,d,l) 	(stmt)->m->send_long_data((stmt), (p), (d), (l))
#define mysqlnd_stmt_alloc_param_bind(stmt)			(stmt)->m->alloc_parameter_bind((stmt))
#define mysqlnd_stmt_free_param_bind(stmt,bind)		(stmt)->m->free_parameter_bind((stmt), (bind))
#define mysqlnd_stmt_bind_param(stmt,bind)			(stmt)->m->bind_parameters((stmt), (bind))
#define mysqlnd_stmt_bind_one_param(stmt,n,z,t)		(stmt)->m->bind_one_parameter((stmt), (n), (z), (t))
#define mysqlnd_stmt_refresh_bind_param(s)			(s)->m->refresh_bind_param((s))
#define mysqlnd_stmt_alloc_result_bind(stmt)		(stmt)->m->alloc_result_bind((stmt))
#define mysqlnd_stmt_free_result_bind(stmt,bind)	(stmt)->m->free_result_bind((stmt), (bind))
#define mysqlnd_stmt_bind_result(stmt,bind)			(stmt)->m->bind_result((stmt), (bind))
#define mysqlnd_stmt_bind_one_result(s,no)			(s)->m->bind_one_result((s), (no))
#define mysqlnd_stmt_param_metadata(stmt)			(stmt)->m->get_parameter_metadata((stmt))
#define mysqlnd_stmt_result_metadata(stmt)			(stmt)->m->get_result_metadata((stmt))

#define	mysqlnd_stmt_free_result(stmt)				(stmt)->m->free_result((stmt))
#define	mysqlnd_stmt_close(stmt, implicit)			(stmt)->m->dtor((stmt), (implicit))
#define	mysqlnd_stmt_reset(stmt)					(stmt)->m->reset((stmt))
#define	mysqlnd_stmt_flush(stmt)					(stmt)->m->flush((stmt))


#define mysqlnd_stmt_attr_get(stmt, attr, value)	(stmt)->m->get_attribute((stmt), (attr), (value))
#define mysqlnd_stmt_attr_set(stmt, attr, value)	(stmt)->m->set_attribute((stmt), (attr), (value))

#define mysqlnd_stmt_fetch(stmt, fetched)	(stmt)->m->fetch((stmt), (fetched))


/* Performance statistics */
PHPAPI extern MYSQLND_STATS * mysqlnd_global_stats;
PHPAPI extern const MYSQLND_STRING mysqlnd_stats_values_names[];
PHPAPI void			_mysqlnd_get_client_stats(MYSQLND_STATS * stats, zval *return_value ZEND_FILE_LINE_DC);


#ifndef MYSQLND_CORE_STATISTICS_DISABLED

#define MYSQLND_INC_GLOBAL_STATISTIC(statistic) \
	MYSQLND_INC_STATISTIC(MYSQLND_G(collect_statistics), mysqlnd_global_stats, (statistic))

#define MYSQLND_DEC_GLOBAL_STATISTIC(statistic) \
	MYSQLND_DEC_STATISTIC(MYSQLND_G(collect_statistics), mysqlnd_global_stats, (statistic))

#define MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(statistic1, value1, statistic2, value2) \
	MYSQLND_INC_STATISTIC_W_VALUE2(MYSQLND_G(collect_statistics), mysqlnd_global_stats, (statistic1), (value1), (statistic2), (value2))

#define MYSQLND_INC_CONN_STATISTIC(conn_stats, statistic) \
	MYSQLND_INC_STATISTIC(MYSQLND_G(collect_statistics), mysqlnd_global_stats, (statistic)); \
	MYSQLND_INC_STATISTIC(MYSQLND_G(collect_statistics), (conn_stats), (statistic));

#define MYSQLND_INC_CONN_STATISTIC_W_VALUE(conn_stats, statistic, value) \
	MYSQLND_INC_STATISTIC_W_VALUE(MYSQLND_G(collect_statistics), mysqlnd_global_stats, (statistic), (value)); \
	MYSQLND_INC_STATISTIC_W_VALUE(MYSQLND_G(collect_statistics), (conn_stats), (statistic), (value));

#define MYSQLND_INC_CONN_STATISTIC_W_VALUE2(conn_stats, statistic1, value1, statistic2, value2) \
	MYSQLND_INC_STATISTIC_W_VALUE2(MYSQLND_G(collect_statistics), mysqlnd_global_stats, (statistic1), (value1), (statistic2), (value2)); \
	MYSQLND_INC_STATISTIC_W_VALUE2(MYSQLND_G(collect_statistics), (conn_stats), (statistic1), (value1), (statistic2), (value2));

#define MYSQLND_INC_CONN_STATISTIC_W_VALUE3(conn_stats, statistic1, value1, statistic2, value2, statistic3, value3) \
	MYSQLND_INC_STATISTIC_W_VALUE3(MYSQLND_G(collect_statistics), mysqlnd_global_stats, (statistic1), (value1), (statistic2), (value2), (statistic3), (value3)); \
	MYSQLND_INC_STATISTIC_W_VALUE3(MYSQLND_G(collect_statistics), (conn_stats), (statistic1), (value1), (statistic2), (value2), (statistic3), (value3));

#else

#define MYSQLND_INC_GLOBAL_STATISTIC(statistic)
#define MYSQLND_DEC_GLOBAL_STATISTIC(statistic)
#define MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(statistic1, value1, statistic2, value2)
#define MYSQLND_INC_CONN_STATISTIC(conn_stats, statistic)
#define MYSQLND_INC_CONN_STATISTIC_W_VALUE(conn_stats, statistic, value)
#define MYSQLND_INC_CONN_STATISTIC_W_VALUE2(conn_stats, statistic1, value1, statistic2, value2)
#define MYSQLND_INC_CONN_STATISTIC_W_VALUE3(conn_stats, statistic1, value1, statistic2, value2, statistic3, value3)

#endif /* MYSQLND_CORE_STATISTICS_DISABLED */


/* double check the class name to avoid naming conflicts when using these: */
#define MYSQLND_METHOD(class, method) 			mysqlnd_##class##_##method##_pub
#define MYSQLND_METHOD_PRIVATE(class, method)	mysqlnd_##class##_##method##_priv

ZEND_BEGIN_MODULE_GLOBALS(mysqlnd)
	char *			debug;	/* The actual string */
	char *			trace_alloc_settings;	/* The actual string */
	MYSQLND_DEBUG *	dbg;	/* The DBG object for standard tracing */
	MYSQLND_DEBUG *	trace_alloc;	/* The DBG object for allocation tracing */
	zend_long		net_cmd_buffer_size;
	zend_long		net_read_buffer_size;
	zend_long		log_mask;
	zend_long		net_read_timeout;
	zend_long		mempool_default_size;
	zend_long		debug_emalloc_fail_threshold;
	zend_long		debug_ecalloc_fail_threshold;
	zend_long		debug_erealloc_fail_threshold;
	zend_long		debug_malloc_fail_threshold;
	zend_long		debug_calloc_fail_threshold;
	zend_long		debug_realloc_fail_threshold;
	char *			sha256_server_public_key;
	zend_bool		fetch_data_copy;
	zend_bool		collect_statistics;
	zend_bool		collect_memory_statistics;
ZEND_END_MODULE_GLOBALS(mysqlnd)

PHPAPI ZEND_EXTERN_MODULE_GLOBALS(mysqlnd)
#define MYSQLND_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(mysqlnd, v)

#if defined(ZTS) && defined(COMPILE_DL_MYSQLND)
ZEND_TSRMLS_CACHE_EXTERN()
#endif


PHPAPI void mysqlnd_minfo_print_hash(zval *values);

#endif	/* MYSQLND_H */


/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/ext/mysqlnd/mysqlnd_commands.h000064400000002726151730540470013360 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Andrey Hristov <andrey@php.net>                             |
  |          Ulf Wendel <uw@php.net>                                     |
  +----------------------------------------------------------------------+
*/

#ifndef MYSQLND_COMMANDS_H
#define MYSQLND_COMMANDS_H

extern func_mysqlnd__command_factory mysqlnd_command_factory;

#endif /* MYSQLND_COMMANDS_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/ext/mysqlnd/mysqlnd_charset.h000064400000004552151730540470013207 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Andrey Hristov <andrey@php.net>                             |
  |          Ulf Wendel <uw@php.net>                                     |
  |          Georg Richter <georg@php.net>                               |
  +----------------------------------------------------------------------+
*/

#ifndef MYSQLND_CHARSET_H
#define MYSQLND_CHARSET_H

PHPAPI zend_ulong mysqlnd_cset_escape_quotes(const MYSQLND_CHARSET * const charset, char *newstr,
										const char *escapestr, size_t escapestr_len);

PHPAPI zend_ulong mysqlnd_cset_escape_slashes(const MYSQLND_CHARSET * const cset, char *newstr,
										 const char *escapestr, size_t escapestr_len);

struct st_mysqlnd_plugin_charsets
{
	const struct st_mysqlnd_plugin_header plugin_header;
	struct
	{
		const MYSQLND_CHARSET * (*const find_charset_by_nr)(unsigned int charsetnr);
		const MYSQLND_CHARSET * (*const find_charset_by_name)(const char * const name);
		zend_ulong 			(*const escape_quotes)(const MYSQLND_CHARSET * const cset, char * newstr, const char * escapestr, size_t escapestr_len);
		zend_ulong			(*const escape_slashes)(const MYSQLND_CHARSET * const cset, char * newstr, const char * escapestr, size_t escapestr_len);
	} methods;
};

void mysqlnd_charsets_plugin_register(void);

#endif /* MYSQLND_CHARSET_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/ext/mysqlnd/mysqlnd_debug.h000064400000023731151730540500012636 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Andrey Hristov <andrey@php.net>                             |
  |          Ulf Wendel <uw@php.net>                                     |
  +----------------------------------------------------------------------+
*/

#ifndef MYSQLND_DEBUG_H
#define MYSQLND_DEBUG_H

#include "mysqlnd_alloc.h"
#include "zend_stack.h"

struct st_mysqlnd_debug_methods
{
	enum_func_status (*open)(MYSQLND_DEBUG * self, zend_bool reopen);
	void			 (*set_mode)(MYSQLND_DEBUG * self, const char * const mode);
	enum_func_status (*log)(MYSQLND_DEBUG * self, unsigned int line, const char * const file,
							unsigned int level, const char * type, const char *message);
	enum_func_status (*log_va)(MYSQLND_DEBUG * self, unsigned int line, const char * const file,
							   unsigned int level, const char * type, const char *format, ...);
	zend_bool (*func_enter)(MYSQLND_DEBUG * self, unsigned int line, const char * const file,
							const char * const func_name, unsigned int func_name_len);
	enum_func_status (*func_leave)(MYSQLND_DEBUG * self, unsigned int line, const char * const file, uint64_t call_time);
	enum_func_status (*close)(MYSQLND_DEBUG * self);
	enum_func_status (*free_handle)(MYSQLND_DEBUG * self);
};


struct st_mysqlnd_debug
{
	php_stream	*stream;
	unsigned int flags;
	unsigned int nest_level_limit;
	int pid;
	char * file_name;
	zend_stack call_stack;
	zend_stack call_time_stack;
	HashTable not_filtered_functions;
	HashTable function_profiles;
	struct st_mysqlnd_debug_methods *m;
	const char ** skip_functions;
};

struct st_mysqlnd_plugin_trace_log
{
	struct st_mysqlnd_plugin_header plugin_header;
	struct
	{
		MYSQLND_DEBUG * (*trace_instance_init)(const char * skip_functions[]);
	} methods;
};

void mysqlnd_debug_trace_plugin_register(void);

PHPAPI MYSQLND_DEBUG * mysqlnd_debug_init(const char * skip_functions[]);

#define MYSQLND_DEBUG_DUMP_TIME				1
#define MYSQLND_DEBUG_DUMP_TRACE			2
#define MYSQLND_DEBUG_DUMP_PID				4
#define MYSQLND_DEBUG_DUMP_LINE				8
#define MYSQLND_DEBUG_DUMP_FILE				16
#define MYSQLND_DEBUG_DUMP_LEVEL			32
#define MYSQLND_DEBUG_APPEND				64
#define MYSQLND_DEBUG_FLUSH					128
#define MYSQLND_DEBUG_TRACE_MEMORY_CALLS	256
#define MYSQLND_DEBUG_PROFILE_CALLS			512


#if defined(__GNUC__) || defined(PHP_WIN32)
#ifdef PHP_WIN32
#include "win32/time.h"
#else
#include <sys/time.h>
#endif

#ifndef MYSQLND_PROFILING_DISABLED
#define DBG_PROFILE_TIMEVAL_TO_DOUBLE(tp)	((tp.tv_sec * 1000000LL)+ tp.tv_usec)
#define DBG_PROFILE_START_TIME()		gettimeofday(&__dbg_prof_tp, NULL); __dbg_prof_start = DBG_PROFILE_TIMEVAL_TO_DOUBLE(__dbg_prof_tp);
#define DBG_PROFILE_END_TIME(duration)	gettimeofday(&__dbg_prof_tp, NULL); (duration) = (DBG_PROFILE_TIMEVAL_TO_DOUBLE(__dbg_prof_tp) - __dbg_prof_start);
#else
#define DBG_PROFILE_TIMEVAL_TO_DOUBLE(tp)
#define DBG_PROFILE_START_TIME()
#define DBG_PROFILE_END_TIME(duration)
#endif

#define DBG_INF_EX(dbg_obj, msg)		do { if (dbg_skip_trace == FALSE && (dbg_obj)) (dbg_obj)->m->log((dbg_obj), __LINE__, __FILE__, -1, "info : ", (msg)); } while (0)
#define DBG_ERR_EX(dbg_obj, msg)		do { if (dbg_skip_trace == FALSE && (dbg_obj)) (dbg_obj)->m->log((dbg_obj), __LINE__, __FILE__, -1, "error: ", (msg)); } while (0)
#define DBG_INF_FMT_EX(dbg_obj, ...)	do { if (dbg_skip_trace == FALSE && (dbg_obj)) (dbg_obj)->m->log_va((dbg_obj), __LINE__, __FILE__, -1, "info : ", __VA_ARGS__); } while (0)
#define DBG_ERR_FMT_EX(dbg_obj, ...)	do { if (dbg_skip_trace == FALSE && (dbg_obj)) (dbg_obj)->m->log_va((dbg_obj), __LINE__, __FILE__, -1, "error: ", __VA_ARGS__); } while (0)

#define DBG_BLOCK_ENTER_EX(dbg_obj, block_name) DBG_BLOCK_ENTER_EX2((dbg_obj), (MYSQLND_DEBUG *) NULL, (block_name))
#define DBG_BLOCK_LEAVE_EX(dbg_obj)				DBG_BLOCK_LEAVE_EX2((dbg_obj), (MYSQLND_DEBUG *) NULL)

#define DBG_BLOCK_ENTER_EX2(dbg_obj1, dbg_obj2, block_name) \
		{ \
			DBG_ENTER_EX2((dbg_obj1), (dbg_obj2), (block_name));

#define DBG_BLOCK_LEAVE_EX2(dbg_obj1, dbg_obj2) \
			DBG_LEAVE_EX2((dbg_obj1), (dbg_obj2), ;) \
		} \


#define DBG_ENTER_EX(dbg_obj, func_name)	DBG_ENTER_EX2((dbg_obj), (MYSQLND_DEBUG *) NULL, (func_name))
#define DBG_LEAVE_EX(dbg_obj, leave)		DBG_LEAVE_EX2((dbg_obj), (MYSQLND_DEBUG *) NULL, leave)

#define DBG_ENTER_EX2(dbg_obj1, dbg_obj2, func_name) \
					struct timeval __dbg_prof_tp = {0}; \
					uint64_t __dbg_prof_start = 0; /* initialization is needed */ \
					zend_bool dbg_skip_trace = TRUE; \
					((void)__dbg_prof_start); \
					if ((dbg_obj1)) { \
						dbg_skip_trace = !(dbg_obj1)->m->func_enter((dbg_obj1), __LINE__, __FILE__, func_name, strlen(func_name)); \
					} \
					if ((dbg_obj2)) { \
						dbg_skip_trace |= !(dbg_obj2)->m->func_enter((dbg_obj2), __LINE__, __FILE__, func_name, strlen(func_name)); \
					} \
					if (dbg_skip_trace) { \
						/* EMPTY */ ; /* shut compiler's mouth */	\
					} \
					do { \
						if (((dbg_obj1) && (dbg_obj1)->flags & MYSQLND_DEBUG_PROFILE_CALLS) || \
							((dbg_obj2) && (dbg_obj2)->flags & MYSQLND_DEBUG_PROFILE_CALLS)) \
						{ \
							DBG_PROFILE_START_TIME(); \
						} \
					} while (0);

#define DBG_LEAVE_EX2(dbg_obj1, dbg_obj2, leave)	\
			do {\
				uint64_t this_call_duration = 0; \
				if (((dbg_obj1) && (dbg_obj1)->flags & MYSQLND_DEBUG_PROFILE_CALLS) || \
					((dbg_obj2) && (dbg_obj2)->flags & MYSQLND_DEBUG_PROFILE_CALLS)) \
				{ \
					DBG_PROFILE_END_TIME(this_call_duration); \
				} \
				if ((dbg_obj1)) { \
					(dbg_obj1)->m->func_leave((dbg_obj1), __LINE__, __FILE__, this_call_duration); \
				} \
				if ((dbg_obj2)) { \
					(dbg_obj2)->m->func_leave((dbg_obj2), __LINE__, __FILE__, this_call_duration); \
				} \
				leave \
			} while (0);


#define DBG_RETURN_EX(dbg_obj, value)		DBG_LEAVE_EX((dbg_obj), return (value);)
#define DBG_VOID_RETURN_EX(dbg_obj)			DBG_LEAVE_EX((dbg_obj), return;)

#define DBG_RETURN_EX2(dbg_obj1, dbg_obj2, value)	DBG_LEAVE_EX2((dbg_obj1), (dbg_obj2), return (value);)
#define DBG_VOID_RETURN_EX2(dbg_obj1, dbg_obj2)		DBG_LEAVE_EX2((dbg_obj1), (dbg_obj2), return;)



#else  /* defined(__GNUC__) || defined(PHP_WIN32) */
static inline void DBG_INF_EX(MYSQLND_DEBUG * dbg_obj, const char * const msg) {}
static inline void DBG_ERR_EX(MYSQLND_DEBUG * dbg_obj, const char * const msg) {}
static inline void DBG_INF_FMT_EX(MYSQLND_DEBUG * dbg_obj, ...) {}
static inline void DBG_ERR_FMT_EX(MYSQLND_DEBUG * dbg_obj, ...) {}
static inline void DBG_ENTER_EX(MYSQLND_DEBUG * dbg_obj, const char * const func_name) {}
#define DBG_BLOCK_ENTER(bname)			{
#define DBG_RETURN_EX(dbg_obj, value)	return (value)
#define DBG_VOID_RETURN_EX(dbg_obj)		return
#define DBG_BLOCK_LEAVE_EX(dbg_obj)		}

#endif

#if MYSQLND_DBG_ENABLED == 1

#define DBG_INF(msg)		DBG_INF_EX(MYSQLND_G(dbg), (msg))
#define DBG_ERR(msg)		DBG_ERR_EX(MYSQLND_G(dbg), (msg))
#define DBG_INF_FMT(...)	DBG_INF_FMT_EX(MYSQLND_G(dbg), __VA_ARGS__)
#define DBG_ERR_FMT(...)	DBG_ERR_FMT_EX(MYSQLND_G(dbg), __VA_ARGS__)

#define DBG_ENTER(func_name)	DBG_ENTER_EX(MYSQLND_G(dbg), (func_name))
#define DBG_BLOCK_ENTER(bname)	DBG_BLOCK_ENTER_EX(MYSQLND_G(dbg), (bname))
#define DBG_RETURN(value)		DBG_RETURN_EX(MYSQLND_G(dbg), (value))
#define DBG_VOID_RETURN			DBG_VOID_RETURN_EX(MYSQLND_G(dbg))
#define DBG_BLOCK_LEAVE			DBG_BLOCK_LEAVE_EX(MYSQLND_G(dbg))


#define TRACE_ALLOC_INF(msg)			DBG_INF_EX(MYSQLND_G(trace_alloc), (msg))
#define TRACE_ALLOC_ERR(msg)			DBG_ERR_EX(MYSQLND_G(trace_alloc), (msg))
#define TRACE_ALLOC_INF_FMT(...)		DBG_INF_FMT_EX(MYSQLND_G(trace_alloc), __VA_ARGS__)
#define TRACE_ALLOC_ERR_FMT(...)		DBG_ERR_FMT_EX(MYSQLND_G(trace_alloc), __VA_ARGS__)

#define TRACE_ALLOC_ENTER(func_name)	DBG_ENTER_EX2(MYSQLND_G(dbg), MYSQLND_G(trace_alloc), (func_name))
#define TRACE_ALLOC_BLOCK_ENTER(bname)	DBG_BLOCK_ENTER_EX2(MYSQLND_G(dbg), MYSQLND_G(trace_alloc), (bname))
#define TRACE_ALLOC_RETURN(value)		DBG_RETURN_EX2(MYSQLND_G(dbg), MYSQLND_G(trace_alloc), (value))
#define TRACE_ALLOC_VOID_RETURN			DBG_VOID_RETURN_EX2(MYSQLND_G(dbg), MYSQLND_G(trace_alloc))
#define TRACE_ALLOC_BLOCK_LEAVE			DBG_BLOCK_LEAVE_EX2(MYSQLND_G(dbg), MYSQLND_G(trace_alloc))

#elif MYSQLND_DBG_ENABLED == 0

static inline void DBG_INF(const char * const msg) {}
static inline void DBG_ERR(const char * const msg) {}
static inline void DBG_INF_FMT(const char * const format, ...) {}
static inline void DBG_ERR_FMT(const char * const format, ...) {}
static inline void DBG_ENTER(const char * const func_name) {}
#define DBG_BLOCK_ENTER(bname)	{
#define DBG_RETURN(value)			return (value)
#define DBG_VOID_RETURN				return
#define DBG_BLOCK_LEAVE			}


static inline void TRACE_ALLOC_INF(const char * const msg) {}
static inline void TRACE_ALLOC_ERR(const char * const msg) {}
static inline void TRACE_ALLOC_INF_FMT(const char * const format, ...) {}
static inline void TRACE_ALLOC_ERR_FMT(const char * const format, ...) {}
static inline void TRACE_ALLOC_ENTER(const char * const func_name) {}
#define TRACE_ALLOC_BLOCK_ENTER(bname)	{
#define TRACE_ALLOC_RETURN(value)			return (value)
#define TRACE_ALLOC_VOID_RETURN				return
#define TRACE_ALLOC_BLOCK_LEAVE			}

#endif

#endif /* MYSQLND_DEBUG_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/ext/mysqlnd/mysql_float_to_double.h000064400000004117151730540500014364 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Keyur Govande <kgovande@gmail.com>                          |
  +----------------------------------------------------------------------+
*/

#ifndef MYSQL_FLOAT_TO_DOUBLE_H
#define MYSQL_FLOAT_TO_DOUBLE_H

#include "main/php.h"
#include <float.h>
#include "main/snprintf.h"

#define MAX_CHAR_BUF_LEN 255

#ifndef FLT_DIG
# define FLT_DIG 6
#endif

/*
 * Convert from a 4-byte float to a 8-byte decimal by first converting
 * the float to a string, and then the string to a double.
 * The decimals argument specifies the precision of the output. If decimals
 * is less than zero, then a gcvt(3) like logic is used with the significant
 * digits set to FLT_DIG i.e. 6.
 */
static inline double mysql_float_to_double(float fp4, int decimals) {
	char num_buf[MAX_CHAR_BUF_LEN]; /* Over allocated */

	if (decimals < 0) {
		php_gcvt(fp4, FLT_DIG, '.', 'e', num_buf);
	} else {
		php_sprintf(num_buf, "%.*f", decimals, fp4);
	}

	return zend_strtod(num_buf, NULL);
}

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */

#endif /* MYSQL_FLOAT_TO_DOUBLE_H */
php/ext/mysqlnd/mysqlnd_wireprotocol.h000064400000023536151730540510014304 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Andrey Hristov <andrey@php.net>                             |
  |          Ulf Wendel <uw@php.net>                                     |
  +----------------------------------------------------------------------+
*/

#ifndef MYSQLND_WIREPROTOCOL_H
#define MYSQLND_WIREPROTOCOL_H

#define MYSQLND_HEADER_SIZE 4
#define COMPRESSED_HEADER_SIZE 3

#define MYSQLND_NULL_LENGTH	(zend_ulong) ~0

/* Used in mysqlnd_debug.c */
PHPAPI extern const char mysqlnd_read_header_name[];
PHPAPI extern const char mysqlnd_read_body_name[];


/* Packet handling */
#define PACKET_WRITE(packet)	((packet)->header.m->write_to_net((packet)))
#define PACKET_READ(packet)		((packet)->header.m->read_from_net((packet)))
#define PACKET_FREE(packet) \
	do { \
		DBG_INF_FMT("PACKET_FREE(%p)", packet); \
		if ((packet)) { \
			((packet)->header.m->free_mem((packet), FALSE)); \
		} \
	} while (0);

PHPAPI extern const char * const mysqlnd_command_to_text[COM_END];

/* Low-level extraction functionality */
typedef struct st_mysqlnd_packet_methods {
	size_t				struct_size;
	enum_func_status	(*read_from_net)(void * packet);
	size_t				(*write_to_net)(void * packet);
	void				(*free_mem)(void *packet, zend_bool stack_allocation);
} mysqlnd_packet_methods;


typedef struct st_mysqlnd_packet_header {
	size_t		size;
	zend_uchar	packet_no;
	zend_bool	persistent;

	mysqlnd_packet_methods *m;

	MYSQLND_CONN_DATA * conn;
	MYSQLND_PFC * protocol_frame_codec;
	MYSQLND_VIO * vio;
	MYSQLND_ERROR_INFO * error_info;
	MYSQLND_STATS * stats;
	MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * factory;
	MYSQLND_CONNECTION_STATE * connection_state;
} MYSQLND_PACKET_HEADER;

/* Server greets the client */
typedef struct st_mysqlnd_packet_greet {
	MYSQLND_PACKET_HEADER		header;
	uint8_t		protocol_version;
	char		*server_version;
	uint32_t	thread_id;
	char		intern_auth_plugin_data[SCRAMBLE_LENGTH];
	MYSQLND_STRING authentication_plugin_data;
	/* 1 byte pad */
	uint32_t	server_capabilities;
	uint8_t		charset_no;
	uint16_t	server_status;
	/* 13 byte pad, in 5.5 first 2 bytes are more capabilities followed by 1 byte scramble_length */
	zend_bool	pre41;
	/* If error packet, we use these */
	char 		error[MYSQLND_ERRMSG_SIZE+1];
	char 		sqlstate[MYSQLND_SQLSTATE_LENGTH + 1];
	unsigned int	error_no;
	char		*auth_protocol;
} MYSQLND_PACKET_GREET;


/* Client authenticates */
typedef struct st_mysqlnd_packet_auth {
	MYSQLND_PACKET_HEADER		header;
	const char	*user;
	const zend_uchar	*auth_data;
	size_t		auth_data_len;
	const char	*db;
	const char	*auth_plugin_name;
	uint32_t	client_flags;
	uint32_t	max_packet_size;
	uint8_t		charset_no;
	/* Here the packet ends. This is user supplied data */
	zend_bool	send_auth_data;
	zend_bool	is_change_user_packet;
	zend_bool	silent;
	HashTable	*connect_attr;
	size_t		db_len;
} MYSQLND_PACKET_AUTH;

/* Auth response packet */
typedef struct st_mysqlnd_packet_auth_response {
	MYSQLND_PACKET_HEADER		header;
	uint8_t		response_code;
	uint64_t	affected_rows;
	uint64_t	last_insert_id;
	uint16_t	server_status;
	uint16_t	warning_count;
	char		*message;
	size_t		message_len;
	/* If error packet, we use these */
	char 		error[MYSQLND_ERRMSG_SIZE+1];
	char 		sqlstate[MYSQLND_SQLSTATE_LENGTH + 1];
	unsigned int 	error_no;

	char		*new_auth_protocol;
	size_t		new_auth_protocol_len;
	zend_uchar	*new_auth_protocol_data;
	size_t		new_auth_protocol_data_len;
} MYSQLND_PACKET_AUTH_RESPONSE;


/* Auth response packet */
typedef struct st_mysqlnd_packet_change_auth_response {
	MYSQLND_PACKET_HEADER		header;
	const zend_uchar	*auth_data;
	size_t				auth_data_len;
} MYSQLND_PACKET_CHANGE_AUTH_RESPONSE;


/* OK packet */
typedef struct st_mysqlnd_packet_ok {
	MYSQLND_PACKET_HEADER		header;
	uint8_t		field_count; /* always 0x0 */
	uint64_t	affected_rows;
	uint64_t	last_insert_id;
	uint16_t	server_status;
	uint16_t	warning_count;
	char		*message;
	size_t		message_len;
	/* If error packet, we use these */
	char 		error[MYSQLND_ERRMSG_SIZE+1];
	char 		sqlstate[MYSQLND_SQLSTATE_LENGTH + 1];
	unsigned int 	error_no;
} MYSQLND_PACKET_OK;


/* Command packet */
typedef struct st_mysqlnd_packet_command {
	MYSQLND_PACKET_HEADER			header;
	enum php_mysqlnd_server_command	command;
	MYSQLND_CSTRING	argument;
} MYSQLND_PACKET_COMMAND;


/* EOF packet */
typedef struct st_mysqlnd_packet_eof {
	MYSQLND_PACKET_HEADER		header;
	uint8_t		field_count; /* 0xFE */
	uint16_t	warning_count;
	uint16_t	server_status;
	/* If error packet, we use these */
	char 		error[MYSQLND_ERRMSG_SIZE+1];
	char 		sqlstate[MYSQLND_SQLSTATE_LENGTH + 1];
	unsigned int 	error_no;
} MYSQLND_PACKET_EOF;
/* EOF packet */


/* Result Set header*/
typedef struct st_mysqlnd_packet_rset_header {
	MYSQLND_PACKET_HEADER header;
	/*
	  0x00 => ok
	  ~0   => LOAD DATA LOCAL
	  error_no != 0 => error
	  others => result set -> Read res_field packets up to field_count
	*/
	zend_ulong		field_count;
	/*
	  These are filled if no SELECT query. For SELECT warning_count
	  and server status are in the last row packet, the EOF packet.
	*/
	uint16_t	warning_count;
	uint16_t	server_status;
	uint64_t	affected_rows;
	uint64_t	last_insert_id;
	/* This is for both LOAD DATA or info, when no result set */
	MYSQLND_STRING info_or_local_file;
	/* If error packet, we use these */
	MYSQLND_ERROR_INFO	error_info;
} MYSQLND_PACKET_RSET_HEADER;


/* Result set field packet */
typedef struct st_mysqlnd_packet_res_field {
	MYSQLND_PACKET_HEADER	header;
	MYSQLND_FIELD			*metadata;
	/* For table definitions, empty for result sets */
	zend_bool				skip_parsing;
	zend_bool				persistent_alloc;

	MYSQLND_ERROR_INFO		error_info;
} MYSQLND_PACKET_RES_FIELD;


/* Row packet */
typedef struct st_mysqlnd_packet_row {
	MYSQLND_PACKET_HEADER	header;
	zval		*fields;
	uint32_t	field_count;
	zend_bool	eof;
	/*
	  These are, of course, only for SELECT in the EOF packet,
	  which is detected by this packet
	*/
	uint16_t	warning_count;
	uint16_t	server_status;

	struct st_mysqlnd_memory_pool_chunk	*row_buffer;
	MYSQLND_MEMORY_POOL * result_set_memory_pool;

	zend_bool		skip_extraction;
	zend_bool		binary_protocol;
	zend_bool		persistent_alloc;
	MYSQLND_FIELD	*fields_metadata;

	/* If error packet, we use these */
	MYSQLND_ERROR_INFO	error_info;
} MYSQLND_PACKET_ROW;


/* Statistics packet */
typedef struct st_mysqlnd_packet_stats {
	MYSQLND_PACKET_HEADER	header;
	MYSQLND_STRING message;
} MYSQLND_PACKET_STATS;


/* COM_PREPARE response packet */
typedef struct st_mysqlnd_packet_prepare_response {
	MYSQLND_PACKET_HEADER	header;
	/* also known as field_count 0x00=OK , 0xFF=error */
	unsigned char	error_code;
	zend_ulong	stmt_id;
	unsigned int	field_count;
	unsigned int	param_count;
	unsigned int	warning_count;

	/* present in case of error */
	MYSQLND_ERROR_INFO	error_info;
} MYSQLND_PACKET_PREPARE_RESPONSE;


/* Statistics packet */
typedef struct st_mysqlnd_packet_chg_user_resp {
	MYSQLND_PACKET_HEADER	header;
	uint32_t			response_code;

	/* message_len is not part of the packet*/
	uint16_t			server_capabilities;
	/* If error packet, we use these */
	MYSQLND_ERROR_INFO	error_info;
	zend_bool			server_asked_323_auth;

	char		*new_auth_protocol;
	size_t		new_auth_protocol_len;
	zend_uchar	*new_auth_protocol_data;
	size_t		new_auth_protocol_data_len;
} MYSQLND_PACKET_CHG_USER_RESPONSE;


/* Command packet */
typedef struct st_mysqlnd_packet_sha256_pk_request {
	MYSQLND_PACKET_HEADER			header;
} MYSQLND_PACKET_SHA256_PK_REQUEST;

typedef struct  st_mysqlnd_packet_sha256_pk_request_response {
	MYSQLND_PACKET_HEADER	header;
	zend_uchar 				*public_key;
	size_t					public_key_len;
} MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE;


zend_ulong		php_mysqlnd_net_field_length(const zend_uchar **packet);
zend_uchar *	php_mysqlnd_net_store_length(zend_uchar *packet, const uint64_t length);
size_t			php_mysqlnd_net_store_length_size(uint64_t length);

PHPAPI extern const char * const mysqlnd_empty_string;

enum_func_status php_mysqlnd_rowp_read_binary_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval * fields,
										 unsigned int field_count, const MYSQLND_FIELD * fields_metadata,
										 zend_bool as_int_or_float, MYSQLND_STATS * stats);


enum_func_status php_mysqlnd_rowp_read_text_protocol_zval(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval * fields,
										 unsigned int field_count, const MYSQLND_FIELD * fields_metadata,
										 zend_bool as_int_or_float, MYSQLND_STATS * stats);

enum_func_status php_mysqlnd_rowp_read_text_protocol_c(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval * fields,
										 unsigned int field_count, const MYSQLND_FIELD * fields_metadata,
										 zend_bool as_int_or_float, MYSQLND_STATS * stats);


PHPAPI MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * mysqlnd_protocol_payload_decoder_factory_init(MYSQLND_CONN_DATA * conn, const zend_bool persistent);
PHPAPI void mysqlnd_protocol_payload_decoder_factory_free(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const payload_decoder_factory);

#endif /* MYSQLND_WIREPROTOCOL_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/ext/mysqlnd/mysqlnd_protocol_frame_codec.h000064400000003352151730540510015716 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Andrey Hristov <andrey@php.net>                             |
  |          Ulf Wendel <uw@php.net>                                     |
  +----------------------------------------------------------------------+
*/

#ifndef MYSQLND_PROTOCOL_FRAME_CODEC_H
#define MYSQLND_PROTOCOL_FRAME_CODEC_H

PHPAPI MYSQLND_PFC * mysqlnd_pfc_init(const zend_bool persistent, MYSQLND_CLASS_METHODS_TYPE(mysqlnd_object_factory) *object_factory, MYSQLND_STATS * stats, MYSQLND_ERROR_INFO * error_info);
PHPAPI void mysqlnd_pfc_free(MYSQLND_PFC * const pfc, MYSQLND_STATS * stats, MYSQLND_ERROR_INFO * error_info);

#endif /* MYSQLND_PROTOCOL_FRAME_CODEC_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/ext/mysqlnd/mysqlnd_plugin.h000064400000003121151730540510013036 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Andrey Hristov <andrey@php.net>                             |
  |          Ulf Wendel <uw@php.net>                                     |
  +----------------------------------------------------------------------+
*/

#ifndef MYSQLND_PLUGIN_H
#define MYSQLND_PLUGIN_H


void mysqlnd_plugin_subsystem_init(void);
void mysqlnd_plugin_subsystem_end(void);

void mysqlnd_register_builtin_authentication_plugins(void);

void mysqlnd_example_plugin_register(void);

#endif	/* MYSQLND_PLUGIN_H */


/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/ext/mysqlnd/mysqlnd_alloc.h000064400000011536151730540520012644 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Andrey Hristov <andrey@php.net>                             |
  |          Ulf Wendel <uw@php.net>                                     |
  +----------------------------------------------------------------------+
*/

#ifndef MYSQLND_ALLOC_H
#define MYSQLND_ALLOC_H

PHPAPI extern const char * mysqlnd_debug_std_no_trace_funcs[];

#define MYSQLND_MEM_D	ZEND_FILE_LINE_DC
#define MYSQLND_MEM_C	ZEND_FILE_LINE_CC

struct st_mysqlnd_allocator_methods
{
	void *	(*m_emalloc)(size_t size MYSQLND_MEM_D);
	void *	(*m_pemalloc)(size_t size, zend_bool persistent MYSQLND_MEM_D);
	void *	(*m_ecalloc)(unsigned int nmemb, size_t size MYSQLND_MEM_D);
	void *	(*m_pecalloc)(unsigned int nmemb, size_t size, zend_bool persistent MYSQLND_MEM_D);
	void *	(*m_erealloc)(void *ptr, size_t new_size MYSQLND_MEM_D);
	void *	(*m_perealloc)(void *ptr, size_t new_size, zend_bool persistent MYSQLND_MEM_D);
	void	(*m_efree)(void *ptr MYSQLND_MEM_D);
	void	(*m_pefree)(void *ptr, zend_bool persistent MYSQLND_MEM_D);
	void *	(*m_malloc)(size_t size MYSQLND_MEM_D);
	void *	(*m_calloc)(unsigned int nmemb, size_t size MYSQLND_MEM_D);
	void *	(*m_realloc)(void *ptr, size_t new_size MYSQLND_MEM_D);
	void	(*m_free)(void *ptr MYSQLND_MEM_D);
	char *	(*m_pememdup)(const char * const ptr, size_t size, zend_bool persistent MYSQLND_MEM_D);
	char *	(*m_pestrndup)(const char * const ptr, size_t size, zend_bool persistent MYSQLND_MEM_D);
	char *	(*m_pestrdup)(const char * const ptr, zend_bool persistent MYSQLND_MEM_D);
	int		(*m_sprintf)(char **pbuf, size_t max_len, const char *format, ...);
	int		(*m_vsprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
	void	(*m_sprintf_free)(char * p);
};

PHPAPI extern struct st_mysqlnd_allocator_methods mysqlnd_allocator;

#define mnd_emalloc(size)				mysqlnd_allocator.m_emalloc((size) MYSQLND_MEM_C)
#define mnd_pemalloc(size, pers)		mysqlnd_allocator.m_pemalloc((size), (pers) MYSQLND_MEM_C)
#define mnd_ecalloc(nmemb, size)		mysqlnd_allocator.m_ecalloc((nmemb), (size) MYSQLND_MEM_C)
#define mnd_pecalloc(nmemb, size, p)	mysqlnd_allocator.m_pecalloc((nmemb), (size), (p) MYSQLND_MEM_C)
#define mnd_erealloc(ptr, new_size)		mysqlnd_allocator.m_erealloc((ptr), (new_size) MYSQLND_MEM_C)
#define mnd_perealloc(ptr, new_size, p)	mysqlnd_allocator.m_perealloc((ptr), (new_size), (p) MYSQLND_MEM_C)
#define mnd_efree(ptr)					mysqlnd_allocator.m_efree((ptr) MYSQLND_MEM_C)
#define mnd_pefree(ptr, pers)			mysqlnd_allocator.m_pefree((ptr), (pers) MYSQLND_MEM_C)
#define mnd_malloc(size)				mysqlnd_allocator.m_malloc((size) MYSQLND_MEM_C)
#define mnd_calloc(nmemb, size)			mysqlnd_allocator.m_calloc((nmemb), (size) MYSQLND_MEM_C)
#define mnd_realloc(ptr, new_size)		mysqlnd_allocator.m_realloc((ptr), (new_size) MYSQLND_MEM_C)
#define mnd_free(ptr)					mysqlnd_allocator.m_free((ptr) MYSQLND_MEM_C)
#define mnd_pememdup(ptr, size, pers)	mysqlnd_allocator.m_pememdup((ptr), (size), (pers) MYSQLND_MEM_C)
#define mnd_pestrndup(ptr, size, pers)	mysqlnd_allocator.m_pestrndup((ptr), (size), (pers) MYSQLND_MEM_C)
#define mnd_pestrdup(ptr, pers)			mysqlnd_allocator.m_pestrdup((ptr), (pers) MYSQLND_MEM_C)
#define mnd_sprintf(p, mx_len, fmt,...) mysqlnd_allocator.m_sprintf((p), (mx_len), (fmt), __VA_ARGS__)
#define mnd_vsprintf(p, mx_len, fmt,ap) mysqlnd_allocator.m_vsprintf((p), (mx_len), (fmt), (ap))
#define mnd_sprintf_free(p)				mysqlnd_allocator.m_sprintf_free((p))

static inline MYSQLND_STRING mnd_dup_cstring(const MYSQLND_CSTRING str, const zend_bool persistent)
{
	const MYSQLND_STRING ret = {(char*) mnd_pemalloc(str.l + 1, persistent), str.l};
	if (ret.s) {
		memcpy(ret.s, str.s, str.l);
		ret.s[str.l] = '\0';
	}
	return ret;
}

static inline MYSQLND_CSTRING mnd_str2c(const MYSQLND_STRING str)
{
	const MYSQLND_CSTRING ret = {str.s, str.l};
	return ret;
}

#endif /* MYSQLND_ALLOC_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/ext/mysqlnd/mysqlnd_vio.h000064400000003261151730540520012343 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Andrey Hristov <andrey@php.net>                             |
  |          Ulf Wendel <uw@php.net>                                     |
  +----------------------------------------------------------------------+
*/

#ifndef MYSQLND_VIO_H
#define MYSQLND_VIO_H

PHPAPI MYSQLND_VIO * mysqlnd_vio_init(zend_bool persistent, MYSQLND_CLASS_METHODS_TYPE(mysqlnd_object_factory) *object_factory, MYSQLND_STATS * stats, MYSQLND_ERROR_INFO * error_info);
PHPAPI void mysqlnd_vio_free(MYSQLND_VIO * const vio, MYSQLND_STATS * stats, MYSQLND_ERROR_INFO * error_info);

#endif /* MYSQLND_VIO_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/ext/mysqlnd/mysqlnd_reverse_api.h000064400000003726151730540530014061 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Andrey Hristov <andrey@php.net>                             |
  |          Ulf Wendel <uw@php.net>                                     |
  |          Georg Richter <georg@php.net>                               |
  +----------------------------------------------------------------------+
*/

#ifndef MYSQLND_REVERSE_API_H
#define MYSQLND_REVERSE_API_H
typedef struct st_mysqlnd_reverse_api
{
	zend_module_entry * module;
	MYSQLND *(*conversion_cb)(zval * zv);
} MYSQLND_REVERSE_API;


PHPAPI void mysqlnd_reverse_api_init(void);
PHPAPI void mysqlnd_reverse_api_end(void);

PHPAPI HashTable * mysqlnd_reverse_api_get_api_list(void);

PHPAPI void mysqlnd_reverse_api_register_api(MYSQLND_REVERSE_API * apiext);
PHPAPI MYSQLND * zval_to_mysqlnd(zval * zv, const unsigned int client_api_capabilities, unsigned int * save_client_api_capabilities);

#endif	/* MYSQLND_REVERSE_API_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/ext/mysqlnd/mysqlnd_priv.h000064400000004546151730540530012536 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Andrey Hristov <andrey@php.net>                             |
  |          Ulf Wendel <uw@php.net>                                     |
  +----------------------------------------------------------------------+
*/

#ifndef MYSQLND_PRIV_H
#define MYSQLND_PRIV_H
PHPAPI extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_object_factory);
PHPAPI extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_conn);
PHPAPI extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_conn_data);
PHPAPI extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_res);
PHPAPI extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_result_unbuffered);
PHPAPI extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_result_buffered);
PHPAPI extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_protocol_payload_decoder_factory);
PHPAPI extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_protocol_packet_frame_codec);
PHPAPI extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_vio);
PHPAPI extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_upsert_status);
PHPAPI extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_error_info);

enum_func_status mysqlnd_handle_local_infile(MYSQLND_CONN_DATA * conn, const char * const filename, zend_bool * is_warning);
#endif	/* MYSQLND_PRIV_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/ext/mysqlnd/mysqlnd_portability.h000064400000041324151730540530014113 0ustar00/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB
This file is public domain and comes with NO WARRANTY of any kind */

/*
  Parts of the original, which are not applicable to mysqlnd have been removed.

  With small modifications, mostly casting but adding few more macros by
  Andrey Hristov <andrey@php.net> . The additions are in the public domain and
  were added to improve the header file, to get it more consistent.
*/

#ifndef MYSQLND_PORTABILITY_H
#define MYSQLND_PORTABILITY_H



/* Comes from global.h as OFFSET, renamed to STRUCT_OFFSET */
#define STRUCT_OFFSET(t, f)   ((size_t)(char *)&((t *)0)->f)

#ifndef __attribute
#if !defined(__GNUC__)
#define __attribute(A)
#endif
#endif

#ifdef __CYGWIN__
/* We use a Unix API, so pretend it's not Windows */
#undef WIN
#undef WIN32
#undef _WIN
#undef _WIN32
#undef _WIN64
#undef __WIN__
#undef __WIN32__
#endif /* __CYGWIN__ */

#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
#  include "ext/mysqlnd/config-win.h"
#endif /* _WIN32... */

#if __STDC_VERSION__ < 199901L && !defined(atoll)
  /* "inline" is a keyword */
  #define atoll atol
#endif

#include "php_stdint.h"

#if SIZEOF_LONG_LONG > 4 && !defined(_LONG_LONG)
#define _LONG_LONG 1        /* For AIX string library */
#endif


/* Go around some bugs in different OS and compilers */
#if defined(_HPUX_SOURCE) && defined(HAVE_SYS_STREAM_H)
#include <sys/stream.h>        /* HPUX 10.20 defines ulong here. UGLY !!! */
#define HAVE_ULONG
#endif


#if SIZEOF_LONG_LONG > 4
#define HAVE_LONG_LONG 1
#endif

#ifdef PHP_WIN32
#define MYSQLND_LLU_SPEC "%I64u"
#define MYSQLND_LL_SPEC "%I64d"
#define MYSQLND_SZ_T_SPEC "%Id"
#ifndef L64
#define L64(x) x##i64
#endif
#else

#if __i386__
#define MYSQLND_LL_SPEC	"%lli"
#define MYSQLND_LLU_SPEC "%llu"
#endif

#if __ia64__
#define MYSQLND_LL_SPEC	"%li"
#define MYSQLND_LLU_SPEC "%lu"
#endif

#if __powerpc64__ || __ppc64__
#define MYSQLND_LL_SPEC	"%li"
#define MYSQLND_LLU_SPEC "%lu"
#endif

#if (__powerpc__ || __ppc__ ) && !(__powerpc64__ || __ppc64__)
#define MYSQLND_LL_SPEC	"%lli"
#define MYSQLND_LLU_SPEC "%llu"
#endif

#if __x86_64__
#define MYSQLND_LL_SPEC	"%li"
#define MYSQLND_LLU_SPEC "%lu"
#endif

#if __s390x__
#define MYSQLND_LL_SPEC	"%li"
#define MYSQLND_LLU_SPEC "%lu"
#endif

#if __s390__ && !__s390x__
#define MYSQLND_LL_SPEC	"%lli"
#define MYSQLND_LLU_SPEC "%llu"
#endif

#ifdef _AIX
#define MYSQLND_LL_SPEC "%lli"
#define MYSQLND_LLU_SPEC "%llu"
#endif

#ifndef MYSQLND_LL_SPEC
  #if SIZEOF_LONG == 8
    #define MYSQLND_LL_SPEC "%li"
  #elif SIZEOF_LONG == 4
    #define MYSQLND_LL_SPEC "%lli"
  #endif
#endif

#ifndef MYSQLND_LLU_SPEC
  #if SIZEOF_LONG == 8
    #define MYSQLND_LLU_SPEC "%lu"
  #elif SIZEOF_LONG == 4
    #define MYSQLND_LLU_SPEC "%llu"
   #endif
#endif /* MYSQLND_LLU_SPEC*/


#define MYSQLND_SZ_T_SPEC "%zd"
#ifndef L64
#define L64(x) x##LL
#endif
#endif


#define int1store(T,A)	do { *((int8_t*) (T)) = (A); } while(0)
#define uint1korr(A)	(*(((uint8_t*)(A))))

/* Bit values are sent in reverted order of bytes, compared to normal !!! */
#define bit_uint2korr(A) ((uint16_t) (((uint16_t) (((unsigned char*) (A))[1])) +\
                                   ((uint16_t) (((unsigned char*) (A))[0]) << 8)))
#define bit_uint3korr(A) ((uint32_t) (((uint32_t) (((unsigned char*) (A))[2])) +\
                                   (((uint32_t) (((unsigned char*) (A))[1])) << 8) +\
                                   (((uint32_t) (((unsigned char*) (A))[0])) << 16)))
#define bit_uint4korr(A) ((uint32_t) (((uint32_t) (((unsigned char*) (A))[3])) +\
                                   (((uint32_t) (((unsigned char*) (A))[2])) << 8) +\
                                   (((uint32_t) (((unsigned char*) (A))[1])) << 16) +\
                                   (((uint32_t) (((unsigned char*) (A))[0])) << 24)))
#define bit_uint5korr(A) ((uint64_t)(((uint32_t) (((unsigned char*) (A))[4])) +\
                                    (((uint32_t) (((unsigned char*) (A))[3])) << 8) +\
                                    (((uint32_t) (((unsigned char*) (A))[2])) << 16) +\
                                   (((uint32_t) (((unsigned char*) (A))[1])) << 24)) +\
                                    (((uint64_t) (((unsigned char*) (A))[0])) << 32))
#define bit_uint6korr(A) ((uint64_t)(((uint32_t) (((unsigned char*) (A))[5])) +\
                                    (((uint32_t) (((unsigned char*) (A))[4])) << 8) +\
                                    (((uint32_t) (((unsigned char*) (A))[3])) << 16) +\
                                    (((uint32_t) (((unsigned char*) (A))[2])) << 24)) +\
                        (((uint64_t) (((uint32_t) (((unsigned char*) (A))[1])) +\
                                    (((uint32_t) (((unsigned char*) (A))[0]) << 8)))) <<\
                                     32))
#define bit_uint7korr(A) ((uint64_t)(((uint32_t) (((unsigned char*) (A))[6])) +\
                                    (((uint32_t) (((unsigned char*) (A))[5])) << 8) +\
                                    (((uint32_t) (((unsigned char*) (A))[4])) << 16) +\
                                   (((uint32_t) (((unsigned char*) (A))[3])) << 24)) +\
                        (((uint64_t) (((uint32_t) (((unsigned char*) (A))[2])) +\
                                    (((uint32_t) (((unsigned char*) (A))[1])) << 8) +\
                                    (((uint32_t) (((unsigned char*) (A))[0])) << 16))) <<\
                                     32))
#define bit_uint8korr(A) ((uint64_t)(((uint32_t) (((unsigned char*) (A))[7])) +\
                                    (((uint32_t) (((unsigned char*) (A))[6])) << 8) +\
                                    (((uint32_t) (((unsigned char*) (A))[5])) << 16) +\
                                    (((uint32_t) (((unsigned char*) (A))[4])) << 24)) +\
                        (((uint64_t) (((uint32_t) (((unsigned char*) (A))[3])) +\
                                    (((uint32_t) (((unsigned char*) (A))[2])) << 8) +\
                                    (((uint32_t) (((unsigned char*) (A))[1])) << 16) +\
                                    (((uint32_t) (((unsigned char*) (A))[0])) << 24))) <<\
                                    32))


/*
** Define-funktions for reading and storing in machine independent format
**  (low byte first)
*/

/* Optimized store functions for Intel x86, non-valid for WIN64. __i386__ is GCC */
#if defined(__i386__) && !defined(_WIN64)
#define sint2korr(A)    (*((int16_t *) (A)))
#define sint3korr(A)    ((int32_t) ((((zend_uchar) (A)[2]) & 128) ? \
                   (((uint32_t) 255L << 24) | \
                   (((uint32_t) (zend_uchar) (A)[2]) << 16) |\
                   (((uint32_t) (zend_uchar) (A)[1]) << 8) | \
                    ((uint32_t) (zend_uchar) (A)[0])) : \
                   (((uint32_t) (zend_uchar) (A)[2]) << 16) |\
                   (((uint32_t) (zend_uchar) (A)[1]) << 8) | \
                    ((uint32_t) (zend_uchar) (A)[0])))
#define sint4korr(A)  (*((zend_long *) (A)))

#define uint2korr(A)  (*((uint16_t *) (A)))
#define uint3korr(A)  (uint32_t) (((uint32_t) ((zend_uchar) (A)[0])) +\
                               (((uint32_t) ((zend_uchar) (A)[1])) << 8) +\
                               (((uint32_t) ((zend_uchar) (A)[2])) << 16))
#define uint4korr(A)  (*((zend_ulong *) (A)))



#define uint8korr(A)    (*((uint64_t *) (A)))
#define sint8korr(A)    (*((int64_t *) (A)))
#define int2store(T,A)    *((uint16_t*) (T))= (uint16_t) (A)
#define int3store(T,A)   { \
                  *(T)=  (zend_uchar) ((A));\
                  *(T+1)=(zend_uchar) (((uint32_t) (A) >> 8));\
                  *(T+2)=(zend_uchar) (((A) >> 16)); }
#define int4store(T,A)    *((zend_long *) (T))= (zend_long) (A)
#define int5store(T,A)    { \
              *((zend_uchar *)(T))= (zend_uchar)((A));\
              *(((zend_uchar *)(T))+1)=(zend_uchar) (((A) >> 8));\
              *(((zend_uchar *)(T))+2)=(zend_uchar) (((A) >> 16));\
              *(((zend_uchar *)(T))+3)=(zend_uchar) (((A) >> 24)); \
              *(((zend_uchar *)(T))+4)=(zend_uchar) (((A) >> 32)); }

/* From Andrey Hristov, based on int5store() */
#define int6store(T,A)    { \
              *(((zend_uchar *)(T)))= (zend_uchar)((A));\
              *(((zend_uchar *)(T))+1))=(zend_uchar) (((A) >> 8));\
              *(((zend_uchar *)(T))+2))=(zend_uchar) (((A) >> 16));\
              *(((zend_uchar *)(T))+3))=(zend_uchar) (((A) >> 24)); \
              *(((zend_uchar *)(T))+4))=(zend_uchar) (((A) >> 32)); \
              *(((zend_uchar *)(T))+5))=(zend_uchar) (((A) >> 40)); }

#define int8store(T,A)    *((uint64_t *) (T))= (uint64_t) (A)

typedef union {
  double v;
  zend_long m[2];
} float8get_union;
#define float8get(V,M)    { ((float8get_union *)&(V))->m[0] = *((zend_long*) (M)); \
                            ((float8get_union *)&(V))->m[1] = *(((zend_long*) (M))+1); }
#define float8store(T,V) { *((zend_long *) (T))     = ((float8get_union *)&(V))->m[0]; \
                           *(((zend_long *) (T))+1) = ((float8get_union *)&(V))->m[1]; }
#define float4get(V,M)	{ *((float *) &(V)) = *((float*) (M)); }
/* From Andrey Hristov based on float8get */
#define floatget(V,M)    memcpy((char*) &(V),(char*) (M),sizeof(float))
#endif /* __i386__ */


/* If we haven't defined sint2korr, which is because the platform is not x86 or it's WIN64 */
#ifndef sint2korr
#define sint2korr(A)    (int16_t) (((int16_t) ((zend_uchar) (A)[0])) +\
                                 ((int16_t) ((int16_t) (A)[1]) << 8))
#define sint3korr(A)    ((int32_t) ((((zend_uchar) (A)[2]) & 128) ? \
                  (((uint32_t) 255L << 24) | \
                  (((uint32_t) (zend_uchar) (A)[2]) << 16) |\
                  (((uint32_t) (zend_uchar) (A)[1]) << 8) | \
                   ((uint32_t) (zend_uchar) (A)[0])) : \
                  (((uint32_t) (zend_uchar) (A)[2]) << 16) |\
                  (((uint32_t) (zend_uchar) (A)[1]) << 8) | \
                  ((uint32_t) (zend_uchar) (A)[0])))
#define sint4korr(A)  (int32_t) (((int32_t) ((zend_uchar) (A)[0])) +\
                              (((int32_t) ((zend_uchar) (A)[1]) << 8)) +\
                              (((int32_t) ((zend_uchar) (A)[2]) << 16)) +\
                              (((int32_t) ((int16_t) (A)[3]) << 24)))

#define sint8korr(A)  (int64_t) uint8korr(A)
#define uint2korr(A)  (uint16_t) (((uint16_t) ((zend_uchar) (A)[0])) +\
                               ((uint16_t) ((zend_uchar) (A)[1]) << 8))
#define uint3korr(A)  (uint32_t) (((uint32_t) ((zend_uchar) (A)[0])) +\
                               (((uint32_t) ((zend_uchar) (A)[1])) << 8) +\
                               (((uint32_t) ((zend_uchar) (A)[2])) << 16))
#define uint4korr(A)  (uint32_t) (((uint32_t) ((zend_uchar) (A)[0])) +\
                               (((uint32_t) ((zend_uchar) (A)[1])) << 8) +\
                               (((uint32_t) ((zend_uchar) (A)[2])) << 16) +\
                               (((uint32_t) ((zend_uchar) (A)[3])) << 24))

#define uint8korr(A)	((uint64_t)(((uint32_t) ((zend_uchar) (A)[0])) +\
									(((uint32_t) ((zend_uchar) (A)[1])) << 8) +\
									(((uint32_t) ((zend_uchar) (A)[2])) << 16) +\
									(((uint32_t) ((zend_uchar) (A)[3])) << 24)) +\
									(((uint64_t) (((uint32_t) ((zend_uchar) (A)[4])) +\
									(((uint32_t) ((zend_uchar) (A)[5])) << 8) +\
									(((uint32_t) ((zend_uchar) (A)[6])) << 16) +\
									(((uint32_t) ((zend_uchar) (A)[7])) << 24))) << 32))


#define int2store(T,A)  do { uint32_t def_temp= (uint32_t) (A) ;\
                  *((zend_uchar*) (T))  =  (zend_uchar)(def_temp); \
                  *((zend_uchar*) (T+1)) = (zend_uchar)((def_temp >> 8)); } while (0)
#define int3store(T,A)  do { /*lint -save -e734 */\
                  *(((char *)(T)))   = (char) ((A));\
                  *(((char *)(T))+1) = (char) (((A) >> 8));\
                  *(((char *)(T))+2) = (char) (((A) >> 16)); \
                  /*lint -restore */} while (0)
#define int4store(T,A)  do { \
                  *(((char *)(T)))   = (char) ((A));\
                  *(((char *)(T))+1) = (char) (((A) >> 8));\
                  *(((char *)(T))+2) = (char) (((A) >> 16));\
                  *(((char *)(T))+3) = (char) (((A) >> 24)); } while (0)
#define int5store(T,A)  do { \
                  *(((char *)(T)))   = (char)((A));\
                  *(((char *)(T))+1) = (char)(((A) >> 8));\
                  *(((char *)(T))+2) = (char)(((A) >> 16));\
                  *(((char *)(T))+3) = (char)(((A) >> 24)); \
                  *(((char *)(T))+4) = (char)(((A) >> 32)); } while (0)
/* Based on int5store() from Andrey Hristov */
#define int6store(T,A)  do { \
                  *(((char *)(T)))   = (char)((A));\
                  *(((char *)(T))+1) = (char)(((A) >> 8));\
                  *(((char *)(T))+2) = (char)(((A) >> 16));\
                  *(((char *)(T))+3) = (char)(((A) >> 24)); \
                  *(((char *)(T))+4) = (char)(((A) >> 32)); \
                  *(((char *)(T))+5) = (char)(((A) >> 40)); } while (0)
#define int8store(T,A)        { uint32_t def_temp= (uint32_t) (A), def_temp2= (uint32_t) ((A) >> 32); \
                  int4store((T),def_temp); \
                  int4store((T+4),def_temp2); \
                }
#ifdef WORDS_BIGENDIAN
#define float4get(V,M)   do { float def_temp;\
                          ((char*) &def_temp)[0] = (M)[3];\
                          ((char*) &def_temp)[1] = (M)[2];\
                          ((char*) &def_temp)[2] = (M)[1];\
                          ((char*) &def_temp)[3] = (M)[0];\
                          (V)=def_temp; } while (0)
#define float8store(T,V)  do { \
                           *(((char *)(T)))   = (char) ((char *) &(V))[7];\
                           *(((char *)(T))+1) = (char) ((char *) &(V))[6];\
                           *(((char *)(T))+2) = (char) ((char *) &(V))[5];\
                           *(((char *)(T))+3) = (char) ((char *) &(V))[4];\
                           *(((char *)(T))+4) = (char) ((char *) &(V))[3];\
                           *(((char *)(T))+5) = (char) ((char *) &(V))[2];\
                           *(((char *)(T))+6) = (char) ((char *) &(V))[1];\
                           *(((char *)(T))+7) = (char) ((char *) &(V))[0]; } while (0)

#define float8get(V,M)   do { double def_temp;\
                          ((char*) &def_temp)[0] = (M)[7];\
                          ((char*) &def_temp)[1] = (M)[6];\
                          ((char*) &def_temp)[2] = (M)[5];\
                          ((char*) &def_temp)[3] = (M)[4];\
                          ((char*) &def_temp)[4] = (M)[3];\
                          ((char*) &def_temp)[5] = (M)[2];\
                          ((char*) &def_temp)[6] = (M)[1];\
                          ((char*) &def_temp)[7] = (M)[0];\
                          (V) = def_temp; \
                         } while (0)
#else
#define float4get(V,M)   memcpy((char*) &(V),(char*) (M),sizeof(float))

#if defined(__FLOAT_WORD_ORDER) && (__FLOAT_WORD_ORDER == __BIG_ENDIAN)
#define float8store(T,V)  do { \
                         *(((char *)(T)))= ((char *) &(V))[4];\
                         *(((char *)(T))+1)=(char) ((char *) &(V))[5];\
                         *(((char *)(T))+2)=(char) ((char *) &(V))[6];\
                         *(((char *)(T))+3)=(char) ((char *) &(V))[7];\
                         *(((char *)(T))+4)=(char) ((char *) &(V))[0];\
                         *(((char *)(T))+5)=(char) ((char *) &(V))[1];\
                         *(((char *)(T))+6)=(char) ((char *) &(V))[2];\
                         *(((char *)(T))+7)=(char) ((char *) &(V))[3];} while (0)
#define float8get(V,M) do { double def_temp;\
                         ((char*) &def_temp)[0]=(M)[4];\
                         ((char*) &def_temp)[1]=(M)[5];\
                         ((char*) &def_temp)[2]=(M)[6];\
                         ((char*) &def_temp)[3]=(M)[7];\
                         ((char*) &def_temp)[4]=(M)[0];\
                         ((char*) &def_temp)[5]=(M)[1];\
                         ((char*) &def_temp)[6]=(M)[2];\
                         ((char*) &def_temp)[7]=(M)[3];\
                         (V) = def_temp; } while (0)
#endif /* __FLOAT_WORD_ORDER */

#endif /* WORDS_BIGENDIAN */

#endif /* sint2korr */
/* To here if the platform is not x86 or it's WIN64 */


/* Define-funktions for reading and storing in machine format from/to
   short/long to/from some place in memory V should be a (not
   register) variable, M is a pointer to byte */

#ifndef float8get

#ifdef WORDS_BIGENDIAN
#define float8get(V,M)		memcpy((char*) &(V),(char*)  (M), sizeof(double))
#define float8store(T,V)	memcpy((char*)  (T),(char*) &(V), sizeof(double))
#else
#define float8get(V,M)    memcpy((char*) &(V),(char*) (M),sizeof(double))
#define float8store(T,V)  memcpy((char*) (T),(char*) &(V),sizeof(double))
#endif /* WORDS_BIGENDIAN */

#endif /* float8get */

#endif /* MYSQLND_PORTABILITY_H */


/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/ext/mysqlnd/mysqlnd_read_buffer.h000064400000002545151730540530014017 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Andrey Hristov <andrey@php.net>                             |
  |          Ulf Wendel <uw@php.net>                                     |
  +----------------------------------------------------------------------+
*/

#ifndef MYSQLND_READ_BUFFER_H
#define MYSQLND_READ_BUFFER_H

PHPAPI MYSQLND_READ_BUFFER * mysqlnd_create_read_buffer(const size_t count);

#endif /* MYSQLND_READ_BUFFER_H */
php/ext/mysqlnd/mysqlnd_enum_n_def.h000064400000051414151730540530013651 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Andrey Hristov <andrey@php.net>                             |
  |          Ulf Wendel <uw@php.net>                                     |
  |          Georg Richter <georg@php.net>                               |
  +----------------------------------------------------------------------+
*/

#ifndef MYSQLND_ENUM_N_DEF_H
#define MYSQLND_ENUM_N_DEF_H

#ifndef TRUE
#define TRUE 1
#endif

#ifndef FALSE
#define FALSE 0
#endif


#define MYSQLND_MIN_COMPRESS_LEN 0

#define MYSQLND_MAX_PACKET_SIZE (256L*256L*256L-1)

#define MYSQLND_ASSEMBLED_PACKET_MAX_SIZE 3UL*1024UL*1024UL*1024UL

#define MYSQLND_DEFAULT_AUTH_PROTOCOL "mysql_native_password"

#define MYSQLND_ERRMSG_SIZE			512
#define MYSQLND_SQLSTATE_LENGTH		5
#define MYSQLND_SQLSTATE_NULL		"00000"

#define MYSQLND_MAX_ALLOWED_USER_LEN	252		/* 63 char * 4byte . MySQL supports now only 16 char, but let it be forward compatible */
#define MYSQLND_MAX_ALLOWED_DB_LEN		1024	/* 256 char * 4byte. MySQL supports now only 64 char in the tables, but on the FS could be different. Forward compatible. */

#define MYSQLND_NET_CMD_BUFFER_MIN_SIZE			4096
#define MYSQLND_NET_CMD_BUFFER_MIN_SIZE_STR		"4096"

#define MYSQLND_STMT_ID_LENGTH 4


#define SERVER_STATUS_IN_TRANS					1	/* Transaction has started */
#define SERVER_STATUS_AUTOCOMMIT				2	/* Server in auto_commit mode */
#define SERVER_MORE_RESULTS_EXISTS				8	/* Multi query - next query exists */
#define SERVER_QUERY_NO_GOOD_INDEX_USED	16
#define SERVER_QUERY_NO_INDEX_USED		32
/*
  The server was able to fulfill the clients request and opened a
  read-only non-scrollable cursor for a query. This flag comes
  in reply to COM_STMT_EXECUTE and COM_STMT_FETCH commands.
*/
#define SERVER_STATUS_CURSOR_EXISTS				64
/*
  This flag is sent when a read-only cursor is exhausted, in reply to
  COM_STMT_FETCH command.
*/
#define SERVER_STATUS_LAST_ROW_SENT				128
#define SERVER_STATUS_DB_DROPPED				256 /* A database was dropped */
#define SERVER_STATUS_NO_BACKSLASH_ESCAPES		512
#define SERVER_QUERY_WAS_SLOW					2048
#define SERVER_PS_OUT_PARAMS            		4096

#define MYSQLND_NO_DATA			100
#define MYSQLND_DATA_TRUNCATED	101

#define SHA1_MAX_LENGTH 20
#define SCRAMBLE_LENGTH 20
#define SCRAMBLE_LENGTH_323 8

#define CLIENT_LONG_PASSWORD		1		/* new more secure passwords */
#define CLIENT_FOUND_ROWS			2		/* Found instead of affected rows */
#define CLIENT_LONG_FLAG			4		/* Get all column flags */
#define CLIENT_CONNECT_WITH_DB		8		/* One can specify db on connect */
#define CLIENT_NO_SCHEMA			16		/* Don't allow database.table.column */
#define CLIENT_COMPRESS				32		/* Can use compression protocol */
#define CLIENT_ODBC					64		/* Odbc client */
#define CLIENT_LOCAL_FILES			128		/* Can use LOAD DATA LOCAL */
#define CLIENT_IGNORE_SPACE			256		/* Ignore spaces before '(' */
#define CLIENT_PROTOCOL_41			512		/* New 4.1 protocol */
#define CLIENT_INTERACTIVE			1024	/* This is an interactive client */
#define CLIENT_SSL					2048	/* Switch to SSL after handshake */
#define CLIENT_IGNORE_SIGPIPE		4096	/* IGNORE sigpipes */
#define CLIENT_TRANSACTIONS			8192	/* Client knows about transactions */
#define CLIENT_RESERVED				16384	/* Old flag for 4.1 protocol */
#define CLIENT_SECURE_CONNECTION	32768	/* New 4.1 authentication */
#define CLIENT_MULTI_STATEMENTS		(1UL << 16) /* Enable/disable multi-stmt support */
#define CLIENT_MULTI_RESULTS		(1UL << 17) /* Enable/disable multi-results */
#define CLIENT_PS_MULTI_RESULTS		(1UL << 18) /* Multi-results in PS-protocol */
#define CLIENT_PLUGIN_AUTH			(1UL << 19) /* Client supports plugin authentication */
#define CLIENT_CONNECT_ATTRS		(1UL << 20) /* Client supports connection attributes */
#define CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA	(1UL << 21) /* Enable authentication response packet to be larger than 255 bytes. */
#define CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS		(1UL << 22) /* Don't close the connection for a connection with expired password. */
#define CLIENT_SESSION_TRACK					(1UL << 23) /* Extended OK */
/*
  This is a mysqlnd extension. CLIENT_ODBC is not used anyway. We will reuse it for our case and translate it to not using SSL peer verification
*/
#define CLIENT_SSL_DONT_VERIFY_SERVER_CERT	CLIENT_ODBC
#define CLIENT_SSL_VERIFY_SERVER_CERT	(1UL << 30)
#define CLIENT_REMEMBER_OPTIONS			(1UL << 31)

#define MYSQLND_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_TRANSACTIONS | \
				CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION | \
				CLIENT_MULTI_RESULTS  | CLIENT_LOCAL_FILES | CLIENT_PLUGIN_AUTH)

#define MYSQLND_PROTOCOL_FLAG_USE_COMPRESSION 1


/* Client Error codes */
#define CR_UNKNOWN_ERROR		2000
#define CR_CONNECTION_ERROR		2002
#define CR_SERVER_GONE_ERROR	2006
#define CR_OUT_OF_MEMORY		2008
#define CR_SERVER_LOST			2013
#define CR_COMMANDS_OUT_OF_SYNC	2014
#define CR_CANT_FIND_CHARSET	2019
#define CR_MALFORMED_PACKET		2027
#define CR_NOT_IMPLEMENTED		2054
#define CR_NO_PREPARE_STMT		2030
#define CR_PARAMS_NOT_BOUND		2031
#define CR_INVALID_PARAMETER_NO	2034
#define CR_INVALID_BUFFER_USE	2035

#define MYSQLND_EE_FILENOTFOUND	 7890

#define UNKNOWN_SQLSTATE		"HY000"

#define MAX_CHARSET_LEN			32


#define TRANS_START_NO_OPT						0
#define TRANS_START_WITH_CONSISTENT_SNAPSHOT	1
#define TRANS_START_READ_WRITE					2
#define TRANS_START_READ_ONLY					4

#define TRANS_COR_NO_OPT		0
#define TRANS_COR_AND_CHAIN		1
#define TRANS_COR_AND_NO_CHAIN	2
#define TRANS_COR_RELEASE		4
#define TRANS_COR_NO_RELEASE	8

typedef enum mysqlnd_extension
{
	MYSQLND_MYSQL = 0,
	MYSQLND_MYSQLI
} enum_mysqlnd_extension;

enum
{
	MYSQLND_FETCH_ASSOC = 1,
	MYSQLND_FETCH_NUM = 2,
	MYSQLND_FETCH_BOTH = 1|2
};

/* Follow libmysql convention */
typedef enum func_status
{
	PASS = 0,
	FAIL = 1
} enum_func_status;

typedef enum mysqlnd_query_type
{
	QUERY_UPSERT,
	QUERY_SELECT,
	QUERY_LOAD_LOCAL
} enum_mysqlnd_query_type;

typedef enum mysqlnd_res_type
{
	MYSQLND_RES_NORMAL = 1,
	MYSQLND_RES_PS_BUF,
	MYSQLND_RES_PS_UNBUF
} enum_mysqlnd_res_type;

typedef enum mysqlnd_send_query_type
{
	MYSQLND_SEND_QUERY_IMPLICIT = 0,
	MYSQLND_SEND_QUERY_EXPLICIT
} enum_mysqlnd_send_query_type;

typedef enum mysqlnd_reap_result_type
{
	MYSQLND_REAP_RESULT_IMPLICIT = 0,
	MYSQLND_REAP_RESULT_EXPLICIT
} enum_mysqlnd_reap_result_type;

typedef enum mysqlnd_send_execute_type
{
	MYSQLND_SEND_EXECUTE_IMPLICIT = 0,
	MYSQLND_SEND_EXECUTE_EXPLICIT
} enum_mysqlnd_send_execute_type;

typedef enum mysqlnd_parse_exec_response_type
{
	MYSQLND_PARSE_EXEC_RESPONSE_IMPLICIT = 0,
	MYSQLND_PARSE_EXEC_RESPONSE_IMPLICIT_NEXT_RESULT,
	MYSQLND_PARSE_EXEC_RESPONSE_IMPLICIT_OUT_VARIABLES,
	MYSQLND_PARSE_EXEC_RESPONSE_EXPLICIT,
} enum_mysqlnd_parse_exec_response_type;

typedef enum mysqlnd_client_option
{
	MYSQL_OPT_CONNECT_TIMEOUT,
	MYSQL_OPT_COMPRESS,
	MYSQL_OPT_NAMED_PIPE,
	MYSQL_INIT_COMMAND,
	MYSQL_READ_DEFAULT_FILE,
	MYSQL_READ_DEFAULT_GROUP,
	MYSQL_SET_CHARSET_DIR,
	MYSQL_SET_CHARSET_NAME,
	MYSQL_OPT_LOCAL_INFILE,
	MYSQL_OPT_PROTOCOL,
	MYSQL_SHARED_MEMORY_BASE_NAME,
	MYSQL_OPT_READ_TIMEOUT,
	MYSQL_OPT_WRITE_TIMEOUT,
	MYSQL_OPT_USE_RESULT,
	MYSQL_OPT_USE_REMOTE_CONNECTION,
	MYSQL_OPT_USE_EMBEDDED_CONNECTION,
	MYSQL_OPT_GUESS_CONNECTION,
	MYSQL_SET_CLIENT_IP,
	MYSQL_SECURE_AUTH,
	MYSQL_REPORT_DATA_TRUNCATION,
	MYSQL_OPT_RECONNECT,
	MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
	MYSQL_PLUGIN_DIR,
	MYSQL_DEFAULT_AUTH,
	MYSQL_OPT_BIND,
	MYSQL_OPT_SSL_KEY,
	MYSQL_OPT_SSL_CERT,
	MYSQL_OPT_SSL_CA,
	MYSQL_OPT_SSL_CAPATH,
	MYSQL_OPT_SSL_CIPHER,
	MYSQL_OPT_SSL_CRL,
	MYSQL_OPT_SSL_CRLPATH,
	MYSQL_OPT_CONNECT_ATTR_RESET,
	MYSQL_OPT_CONNECT_ATTR_ADD,
	MYSQL_OPT_CONNECT_ATTR_DELETE,
	MYSQL_SERVER_PUBLIC_KEY,
	MYSQL_ENABLE_CLEARTEXT_PLUGIN,
	MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS,
	MYSQL_OPT_SSL_ENFORCE,
	MYSQL_OPT_MAX_ALLOWED_PACKET,
	MYSQL_OPT_NET_BUFFER_LENGTH,
	MYSQL_OPT_TLS_VERSION,
	MYSQL_OPT_SSL_MODE,
	MYSQLND_DEPRECATED_ENUM1 = 200,
#ifdef MYSQLND_STRING_TO_INT_CONVERSION
	MYSQLND_OPT_INT_AND_FLOAT_NATIVE = 201,
#endif
	MYSQLND_OPT_NET_CMD_BUFFER_SIZE = 202,
	MYSQLND_OPT_NET_READ_BUFFER_SIZE = 203,
	MYSQLND_OPT_SSL_KEY = 204,
	MYSQLND_OPT_SSL_CERT = 205,
	MYSQLND_OPT_SSL_CA = 206,
	MYSQLND_OPT_SSL_CAPATH = 207,
	MYSQLND_OPT_SSL_CIPHER = 208,
	MYSQLND_OPT_SSL_PASSPHRASE = 209,
	MYSQLND_OPT_MAX_ALLOWED_PACKET = 210,
	MYSQLND_OPT_AUTH_PROTOCOL = 211
} enum_mysqlnd_client_option;

typedef enum mysqlnd_session_protocol_type
{
	MYSQL_PROTOCOL_DEFAULT = 0,
	MYSQL_PROTOCOL_TCP,		/* all, supported */
	MYSQL_PROTOCOL_SOCKET,	/* unix, supported */
	MYSQL_PROTOCOL_PIPE,	/* win32, not-supported */
	MYSQL_PROTOCOL_MEMORY,	/* win32, not-supported */
	MYSQL_PROTOCOL_LAST
} enum_mysqlnd_session_protocol_type;

typedef enum mysqlnd_field_types
{
	MYSQL_TYPE_DECIMAL	= 0,
	MYSQL_TYPE_TINY		= 1,
	MYSQL_TYPE_SHORT	= 2,
	MYSQL_TYPE_LONG		= 3,
	MYSQL_TYPE_FLOAT	= 4,
	MYSQL_TYPE_DOUBLE	= 5,
	MYSQL_TYPE_NULL		= 6,
	MYSQL_TYPE_TIMESTAMP= 7,
	MYSQL_TYPE_LONGLONG	= 8,
	MYSQL_TYPE_INT24	= 9,
	MYSQL_TYPE_DATE		= 10,
	MYSQL_TYPE_TIME		= 11,
	MYSQL_TYPE_DATETIME	= 12,
	MYSQL_TYPE_YEAR		= 13,
	MYSQL_TYPE_NEWDATE	= 14,
	MYSQL_TYPE_VARCHAR	= 15,
	MYSQL_TYPE_BIT		= 16,
	MYSQL_TYPE_JSON=245,
	MYSQL_TYPE_NEWDECIMAL=246,
	MYSQL_TYPE_ENUM=247,
	MYSQL_TYPE_SET=248,
	MYSQL_TYPE_TINY_BLOB=249,
	MYSQL_TYPE_MEDIUM_BLOB=250,
	MYSQL_TYPE_LONG_BLOB=251,
	MYSQL_TYPE_BLOB=252,
	MYSQL_TYPE_VAR_STRING=253,
	MYSQL_TYPE_STRING=254,
	MYSQL_TYPE_GEOMETRY=255
} enum_mysqlnd_field_types;

/* Please update this if there is a new type after MYSQL_TYPE_GEOMETRY */
#define MYSQL_TYPE_LAST		MYSQL_TYPE_GEOMETRY


typedef enum mysqlnd_server_option
{
	MYSQL_OPTION_MULTI_STATEMENTS_ON,
	MYSQL_OPTION_MULTI_STATEMENTS_OFF
} enum_mysqlnd_server_option;


#define FIELD_TYPE_DECIMAL		MYSQL_TYPE_DECIMAL
#define FIELD_TYPE_NEWDECIMAL	MYSQL_TYPE_NEWDECIMAL
#define FIELD_TYPE_TINY			MYSQL_TYPE_TINY
#define FIELD_TYPE_SHORT		MYSQL_TYPE_SHORT
#define FIELD_TYPE_LONG			MYSQL_TYPE_LONG
#define FIELD_TYPE_FLOAT		MYSQL_TYPE_FLOAT
#define FIELD_TYPE_DOUBLE		MYSQL_TYPE_DOUBLE
#define FIELD_TYPE_NULL			MYSQL_TYPE_NULL
#define FIELD_TYPE_TIMESTAMP	MYSQL_TYPE_TIMESTAMP
#define FIELD_TYPE_LONGLONG		MYSQL_TYPE_LONGLONG
#define FIELD_TYPE_INT24		MYSQL_TYPE_INT24
#define FIELD_TYPE_DATE			MYSQL_TYPE_DATE
#define FIELD_TYPE_TIME			MYSQL_TYPE_TIME
#define FIELD_TYPE_DATETIME		MYSQL_TYPE_DATETIME
#define FIELD_TYPE_YEAR			MYSQL_TYPE_YEAR
#define FIELD_TYPE_NEWDATE		MYSQL_TYPE_NEWDATE
#define FIELD_TYPE_ENUM			MYSQL_TYPE_ENUM
#define FIELD_TYPE_SET			MYSQL_TYPE_SET
#define FIELD_TYPE_JSON 		MYSQL_TYPE_JSON
#define FIELD_TYPE_TINY_BLOB	MYSQL_TYPE_TINY_BLOB
#define FIELD_TYPE_MEDIUM_BLOB	MYSQL_TYPE_MEDIUM_BLOB
#define FIELD_TYPE_LONG_BLOB	MYSQL_TYPE_LONG_BLOB
#define FIELD_TYPE_BLOB			MYSQL_TYPE_BLOB
#define FIELD_TYPE_VAR_STRING	MYSQL_TYPE_VAR_STRING
#define FIELD_TYPE_STRING		MYSQL_TYPE_STRING
#define FIELD_TYPE_CHAR			MYSQL_TYPE_TINY
#define FIELD_TYPE_INTERVAL		MYSQL_TYPE_ENUM
#define FIELD_TYPE_GEOMETRY		MYSQL_TYPE_GEOMETRY
#define FIELD_TYPE_BIT			MYSQL_TYPE_BIT

#define NOT_NULL_FLAG			    1
#define PRI_KEY_FLAG			    2
#define UNIQUE_KEY_FLAG			    4
#define MULTIPLE_KEY_FLAG		    8
#define BLOB_FLAG				   16
#define UNSIGNED_FLAG			   32
#define ZEROFILL_FLAG			   64
#define BINARY_FLAG				  128
#define ENUM_FLAG				  256
#define AUTO_INCREMENT_FLAG		  512
#define TIMESTAMP_FLAG			 1024
#define SET_FLAG				 2048
#define NO_DEFAULT_VALUE_FLAG	 4096
#define ON_UPDATE_NOW_FLAG		 8192
#define PART_KEY_FLAG			16384
#define GROUP_FLAG				32768
#define NUM_FLAG				32768

#define IS_PRI_KEY(n)	((n) & PRI_KEY_FLAG)
#define IS_NOT_NULL(n)	((n) & NOT_NULL_FLAG)
#define IS_BLOB(n)		((n) & BLOB_FLAG)
#define IS_NUM(t)		((t) <= FIELD_TYPE_INT24 || (t) == FIELD_TYPE_YEAR || (t) == FIELD_TYPE_NEWDECIMAL)


/* see mysqlnd_charset.c for more information */
#define MYSQLND_BINARY_CHARSET_NR	63


/*
		/-----> CONN_CLOSE  <---------------\
		|           ^                         \
		|           |                         \
	CONN_READY -> CONN_QUERY_SENT -> CONN_FETCHING_DATA
		^                                      |
		\-------------------------------------/
*/
typedef enum mysqlnd_connection_state
{
	CONN_ALLOCED = 0,
	CONN_READY = 1,
	CONN_QUERY_SENT = 2,
	CONN_SENDING_LOAD_DATA = 3,
	CONN_FETCHING_DATA = 4,
	CONN_NEXT_RESULT_PENDING = 5,
	CONN_QUIT_SENT = 6 /* object is "destroyed" at this stage */
} enum_mysqlnd_connection_state;


typedef enum mysqlnd_stmt_state
{
	MYSQLND_STMT_INITTED = 0,
	MYSQLND_STMT_PREPARED = 1,
	MYSQLND_STMT_EXECUTED = 2,
	MYSQLND_STMT_WAITING_USE_OR_STORE = 3,
	MYSQLND_STMT_USE_OR_STORE_CALLED = 4,
	MYSQLND_STMT_USER_FETCHING = 5/* fetch_row_buff or fetch_row_unbuf */
} enum_mysqlnd_stmt_state;


typedef enum param_bind_flags
{
	MYSQLND_PARAM_BIND_BLOB_USED = 1
} enum_param_bind_flags;


/* PS */
enum mysqlnd_stmt_attr
{
	STMT_ATTR_UPDATE_MAX_LENGTH,
	STMT_ATTR_CURSOR_TYPE,
	STMT_ATTR_PREFETCH_ROWS
};

enum myslqnd_cursor_type
{
	CURSOR_TYPE_NO_CURSOR= 0,
	CURSOR_TYPE_READ_ONLY= 1,
	CURSOR_TYPE_FOR_UPDATE= 2,
	CURSOR_TYPE_SCROLLABLE= 4
};

typedef enum mysqlnd_connection_close_type
{
	MYSQLND_CLOSE_EXPLICIT = 0,
	MYSQLND_CLOSE_IMPLICIT,
	MYSQLND_CLOSE_DISCONNECTED,
	MYSQLND_CLOSE_LAST	/* for checking, should always be last */
} enum_connection_close_type;


typedef enum mysqlnd_collected_stats
{
	STAT_BYTES_SENT,
	STAT_BYTES_RECEIVED,
	STAT_PACKETS_SENT,
	STAT_PACKETS_RECEIVED,
	STAT_PROTOCOL_OVERHEAD_IN,
	STAT_PROTOCOL_OVERHEAD_OUT,
	STAT_BYTES_RECEIVED_OK,
	STAT_BYTES_RECEIVED_EOF,
	STAT_BYTES_RECEIVED_RSET_HEADER,
	STAT_BYTES_RECEIVED_RSET_FIELD_META,
	STAT_BYTES_RECEIVED_RSET_ROW,
	STAT_BYTES_RECEIVED_PREPARE_RESPONSE,
	STAT_BYTES_RECEIVED_CHANGE_USER,
	STAT_PACKETS_SENT_CMD,
	STAT_PACKETS_RECEIVED_OK,
	STAT_PACKETS_RECEIVED_EOF,
	STAT_PACKETS_RECEIVED_RSET_HEADER,
	STAT_PACKETS_RECEIVED_RSET_FIELD_META,
	STAT_PACKETS_RECEIVED_RSET_ROW,
	STAT_PACKETS_RECEIVED_PREPARE_RESPONSE,
	STAT_PACKETS_RECEIVED_CHANGE_USER,
	STAT_RSET_QUERY,
	STAT_NON_RSET_QUERY,
	STAT_NO_INDEX_USED,
	STAT_BAD_INDEX_USED,
	STAT_QUERY_WAS_SLOW,
	STAT_BUFFERED_SETS,
	STAT_UNBUFFERED_SETS,
	STAT_PS_BUFFERED_SETS,
	STAT_PS_UNBUFFERED_SETS,
	STAT_FLUSHED_NORMAL_SETS,
	STAT_FLUSHED_PS_SETS,
	STAT_PS_PREPARED_NEVER_EXECUTED,
	STAT_PS_PREPARED_ONCE_USED,
	STAT_ROWS_FETCHED_FROM_SERVER_NORMAL,
	STAT_ROWS_FETCHED_FROM_SERVER_PS,
	STAT_ROWS_BUFFERED_FROM_CLIENT_NORMAL,
	STAT_ROWS_BUFFERED_FROM_CLIENT_PS,
	STAT_ROWS_FETCHED_FROM_CLIENT_NORMAL_BUF,
	STAT_ROWS_FETCHED_FROM_CLIENT_NORMAL_UNBUF,
	STAT_ROWS_FETCHED_FROM_CLIENT_PS_BUF,
	STAT_ROWS_FETCHED_FROM_CLIENT_PS_UNBUF,
	STAT_ROWS_FETCHED_FROM_CLIENT_PS_CURSOR,
	STAT_ROWS_AFFECTED_NORMAL,
	STAT_ROWS_AFFECTED_PS,
	STAT_ROWS_SKIPPED_NORMAL,
	STAT_ROWS_SKIPPED_PS,
	STAT_COPY_ON_WRITE_SAVED,
	STAT_COPY_ON_WRITE_PERFORMED,
	STAT_CMD_BUFFER_TOO_SMALL,
	STAT_CONNECT_SUCCESS,
	STAT_CONNECT_FAILURE,
	STAT_CONNECT_REUSED,
	STAT_RECONNECT,
	STAT_PCONNECT_SUCCESS,
	STAT_OPENED_CONNECTIONS,
	STAT_OPENED_PERSISTENT_CONNECTIONS,
	STAT_CLOSE_EXPLICIT,
	STAT_CLOSE_IMPLICIT,
	STAT_CLOSE_DISCONNECT,
	STAT_CLOSE_IN_MIDDLE,
	STAT_FREE_RESULT_EXPLICIT,
	STAT_FREE_RESULT_IMPLICIT,
	STAT_STMT_CLOSE_EXPLICIT,
	STAT_STMT_CLOSE_IMPLICIT,
	STAT_MEM_EMALLOC_COUNT,
	STAT_MEM_EMALLOC_AMOUNT,
	STAT_MEM_ECALLOC_COUNT,
	STAT_MEM_ECALLOC_AMOUNT,
	STAT_MEM_EREALLOC_COUNT,
	STAT_MEM_EREALLOC_AMOUNT,
	STAT_MEM_EFREE_COUNT,
	STAT_MEM_EFREE_AMOUNT,
	STAT_MEM_MALLOC_COUNT,
	STAT_MEM_MALLOC_AMOUNT,
	STAT_MEM_CALLOC_COUNT,
	STAT_MEM_CALLOC_AMOUNT,
	STAT_MEM_REALLOC_COUNT,
	STAT_MEM_REALLOC_AMOUNT,
	STAT_MEM_FREE_COUNT,
	STAT_MEM_FREE_AMOUNT,
	STAT_MEM_ESTRNDUP_COUNT,
	STAT_MEM_STRNDUP_COUNT,
	STAT_MEM_ESTRDUP_COUNT,
	STAT_MEM_STRDUP_COUNT,
	STAT_MEM_EDUP_COUNT,
	STAT_MEM_DUP_COUNT,
	STAT_TEXT_TYPE_FETCHED_NULL,
	STAT_TEXT_TYPE_FETCHED_BIT,
	STAT_TEXT_TYPE_FETCHED_INT8,
	STAT_TEXT_TYPE_FETCHED_INT16,
	STAT_TEXT_TYPE_FETCHED_INT24,
	STAT_TEXT_TYPE_FETCHED_INT32,
	STAT_TEXT_TYPE_FETCHED_INT64,
	STAT_TEXT_TYPE_FETCHED_DECIMAL,
	STAT_TEXT_TYPE_FETCHED_FLOAT,
	STAT_TEXT_TYPE_FETCHED_DOUBLE,
	STAT_TEXT_TYPE_FETCHED_DATE,
	STAT_TEXT_TYPE_FETCHED_YEAR,
	STAT_TEXT_TYPE_FETCHED_TIME,
	STAT_TEXT_TYPE_FETCHED_DATETIME,
	STAT_TEXT_TYPE_FETCHED_TIMESTAMP,
	STAT_TEXT_TYPE_FETCHED_STRING,
	STAT_TEXT_TYPE_FETCHED_JSON,
	STAT_TEXT_TYPE_FETCHED_BLOB,
	STAT_TEXT_TYPE_FETCHED_ENUM,
	STAT_TEXT_TYPE_FETCHED_SET,
	STAT_TEXT_TYPE_FETCHED_GEOMETRY,
	STAT_TEXT_TYPE_FETCHED_OTHER,
	STAT_BINARY_TYPE_FETCHED_NULL,
	STAT_BINARY_TYPE_FETCHED_BIT,
	STAT_BINARY_TYPE_FETCHED_INT8,
	STAT_BINARY_TYPE_FETCHED_INT16,
	STAT_BINARY_TYPE_FETCHED_INT24,
	STAT_BINARY_TYPE_FETCHED_INT32,
	STAT_BINARY_TYPE_FETCHED_INT64,
	STAT_BINARY_TYPE_FETCHED_DECIMAL,
	STAT_BINARY_TYPE_FETCHED_FLOAT,
	STAT_BINARY_TYPE_FETCHED_DOUBLE,
	STAT_BINARY_TYPE_FETCHED_DATE,
	STAT_BINARY_TYPE_FETCHED_YEAR,
	STAT_BINARY_TYPE_FETCHED_TIME,
	STAT_BINARY_TYPE_FETCHED_DATETIME,
	STAT_BINARY_TYPE_FETCHED_TIMESTAMP,
	STAT_BINARY_TYPE_FETCHED_STRING,
	STAT_BINARY_TYPE_FETCHED_BLOB,
	STAT_BINARY_TYPE_FETCHED_ENUM,
	STAT_BINARY_TYPE_FETCHED_SET,
	STAT_BINARY_TYPE_FETCHED_GEOMETRY,
	STAT_BINARY_TYPE_FETCHED_OTHER,
	STAT_INIT_COMMAND_EXECUTED_COUNT,
	STAT_INIT_COMMAND_FAILED_COUNT,
	STAT_COM_QUIT,
	STAT_COM_INIT_DB,
	STAT_COM_QUERY,
	STAT_COM_FIELD_LIST,
	STAT_COM_CREATE_DB,
	STAT_COM_DROP_DB,
	STAT_COM_REFRESH,
	STAT_COM_SHUTDOWN,
	STAT_COM_STATISTICS,
	STAT_COM_PROCESS_INFO,
	STAT_COM_CONNECT,
	STAT_COM_PROCESS_KILL,
	STAT_COM_DEBUG,
	STAT_COM_PING,
	STAT_COM_TIME,
	STAT_COM_DELAYED_INSERT,
	STAT_COM_CHANGE_USER,
	STAT_COM_BINLOG_DUMP,
	STAT_COM_TABLE_DUMP,
	STAT_COM_CONNECT_OUT,
	STAT_COM_REGISTER_SLAVE,
	STAT_COM_STMT_PREPARE,
	STAT_COM_STMT_EXECUTE,
	STAT_COM_STMT_SEND_LONG_DATA,
	STAT_COM_STMT_CLOSE,
	STAT_COM_STMT_RESET,
	STAT_COM_SET_OPTION,
	STAT_COM_STMT_FETCH,
	STAT_COM_DAEMON,
	STAT_BYTES_RECEIVED_PURE_DATA_TEXT,
	STAT_BYTES_RECEIVED_PURE_DATA_PS,
	STAT_LAST /* Should be always the last */
} enum_mysqlnd_collected_stats;


/* Enums */
enum mysqlnd_packet_type
{
	PROT_GREET_PACKET= 0,
	PROT_AUTH_PACKET,
	PROT_AUTH_RESP_PACKET,
	PROT_CHANGE_AUTH_RESP_PACKET,
	PROT_OK_PACKET,
	PROT_EOF_PACKET,
	PROT_CMD_PACKET,
	PROT_RSET_HEADER_PACKET,
	PROT_RSET_FLD_PACKET,
	PROT_ROW_PACKET,
	PROT_STATS_PACKET,
	PROT_PREPARE_RESP_PACKET,
	PROT_CHG_USER_RESP_PACKET,
	PROT_SHA256_PK_REQUEST_PACKET,
	PROT_SHA256_PK_REQUEST_RESPONSE_PACKET,
	PROT_LAST /* should always be last */
};


/*
  After adding new elements please update
  `mysqlnd_command_to_text` in mysqlnd_wireprotocol.c
*/
enum php_mysqlnd_server_command
{
	COM_SLEEP = 0,
	COM_QUIT,
	COM_INIT_DB,
	COM_QUERY,
	COM_FIELD_LIST,
	COM_CREATE_DB,
	COM_DROP_DB,
	COM_REFRESH,
	COM_SHUTDOWN,
	COM_STATISTICS,
	COM_PROCESS_INFO,
	COM_CONNECT,
	COM_PROCESS_KILL,
	COM_DEBUG,
	COM_PING,
	COM_TIME = 15,
	COM_DELAYED_INSERT,
	COM_CHANGE_USER,
	COM_BINLOG_DUMP,
	COM_TABLE_DUMP,
	COM_CONNECT_OUT = 20,
	COM_REGISTER_SLAVE,
	COM_STMT_PREPARE = 22,
	COM_STMT_EXECUTE = 23,
	COM_STMT_SEND_LONG_DATA = 24,
	COM_STMT_CLOSE = 25,
	COM_STMT_RESET = 26,
	COM_SET_OPTION = 27,
	COM_STMT_FETCH = 28,
	COM_DAEMON = 29,
	COM_BINLOG_DUMP_GTID = 30,
	COM_RESET_CONNECTION = 31,
	COM_STMT_EXECUTE_BATCH = 32,
	COM_END,
	/* Here follow own, non-protocol, commands */
	COM_REAP_RESULT=240,	/* own command */
	COM_ENABLE_SSL,			/* own command */
	COM_HANDSHAKE,			/* own command */
};


#define MYSQLND_DEFAULT_PREFETCH_ROWS (zend_ulong) 1

#define MYSQLND_REFRESH_GRANT		1	/* Refresh grant tables */
#define MYSQLND_REFRESH_LOG			2	/* Start on new log file */
#define MYSQLND_REFRESH_TABLES		4	/* close all tables */
#define MYSQLND_REFRESH_HOSTS		8	/* Flush host cache */
#define MYSQLND_REFRESH_STATUS		16	/* Flush status variables */
#define MYSQLND_REFRESH_THREADS		32	/* Flush thread cache */
#define MYSQLND_REFRESH_SLAVE		64	/* Reset master info and restart slave */
#define MYSQLND_REFRESH_MASTER		128	/* Remove all bin logs in the index */
#define MYSQLND_REFRESH_BACKUP_LOG	0x200000L


#define MYSQLND_STORE_PS		1
#define MYSQLND_STORE_NO_COPY	2
#define MYSQLND_STORE_COPY		4

enum mysqlnd_buffered_type
{
	MYSQLND_BUFFERED_TYPE_ZVAL = 1,
	MYSQLND_BUFFERED_TYPE_C
};


#define MYSQLND_CLIENT_NO_FLAG				0
#define MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA	1

#endif	/* MYSQLND_ENUM_N_DEF_H */


/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/ext/mysqlnd/mysqlnd_result_meta.h000064400000003442151730540540014075 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Andrey Hristov <andrey@php.net>                             |
  |          Johannes Schl�ter <johannes@php.net>                        |
  |          Ulf Wendel <uw@php.net>                                     |
  +----------------------------------------------------------------------+
*/

#ifndef MYSQLND_RESULT_META_H
#define MYSQLND_RESULT_META_H

PHPAPI MYSQLND_RES_METADATA * mysqlnd_result_meta_init(unsigned int field_count, zend_bool persistent);
PHPAPI struct st_mysqlnd_res_meta_methods * mysqlnd_result_metadata_get_methods();
PHPAPI void ** _mysqlnd_plugin_get_plugin_result_metadata_data(const MYSQLND_RES_METADATA * meta, unsigned int plugin_id);

#endif /* MYSQLND_RESULT_META_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/ext/mysqlnd/mysqlnd_libmysql_compat.h000064400000016651151730540540014756 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Andrey Hristov <andrey@php.net>                             |
  |          Ulf Wendel <uw@php.net>                                     |
  |          Georg Richter <georg@php.net>                               |
  +----------------------------------------------------------------------+
*/
#ifndef MYSQLND_LIBMYSQL_COMPAT_H
#define MYSQLND_LIBMYSQL_COMPAT_H

/* Global types and definitions*/
#define MYSQL_NO_DATA			MYSQLND_NO_DATA
#define MYSQL_DATA_TRUNCATED	MYSQLND_DATA_TRUNCATED
#define MYSQL_STMT				MYSQLND_STMT
#define MYSQL_FIELD				MYSQLND_FIELD
#define MYSQL_RES				MYSQLND_RES
#define MYSQL_ROW				MYSQLND_ROW_C
#define MYSQL					MYSQLND
#define my_bool					zend_bool
#define my_ulonglong			uint64_t

#define MYSQL_VERSION_ID		MYSQLND_VERSION_ID
#define MYSQL_SERVER_VERSION	PHP_MYSQLND_VERSION
#define MYSQL_ERRMSG_SIZE		MYSQLND_ERRMSG_SIZE
#define SQLSTATE_LENGTH			MYSQLND_SQLSTATE_LENGTH

/* functions */
#define mysql_affected_rows(r)			mysqlnd_affected_rows((r))
#define mysql_autocommit(r,m)			mysqlnd_autocommit((r),(m))
#define mysql_change_user(r,a,b,c)		mysqlnd_change_user((r), (a), (b), (c), FALSE)
#define mysql_character_set_name(c)		mysqlnd_character_set_name((c))
#define mysql_close(r)					mysqlnd_close((r), MYSQLND_CLOSE_EXPLICIT)
#define mysql_commit(r)					mysqlnd_commit((r), TRANS_COR_NO_OPT, NULL)
#define mysql_data_seek(r,o)			mysqlnd_data_seek((r),(o))
#define mysql_debug(x)					mysqlnd_debug((x))
#define mysql_dump_debug_info(r)		mysqlnd_dump_debug_info((r))
#define mysql_errno(r)					mysqlnd_errno((r))
#define mysql_error(r)					mysqlnd_error((r))
#define mysql_escape_string(a,b,c)		mysqlnd_escape_string((a), (b), (c))
#define mysql_fetch_field(r)			mysqlnd_fetch_field((r))
#define mysql_fetch_field_direct(r,o)	mysqlnd_fetch_field_direct((r), (o))
#define mysql_fetch_fields(r)			mysqlnd_fetch_fields((r))
#define mysql_fetch_lengths(r)			mysqlnd_fetch_lengths((r))
#define mysql_fetch_row(r)				mysqlnd_fetch_row_c((r))
#define mysql_field_count(r)			mysqlnd_field_count((r))
#define mysql_field_seek(r,o)			mysqlnd_field_seek((r), (o))
#define mysql_field_tell(r)				mysqlnd_field_tell((r))
#define mysql_init(a)					mysqlnd_connection_init((a), false)
#define mysql_insert_id(r)				mysqlnd_insert_id((r))
#define mysql_kill(r,n)					mysqlnd_kill((r), (n))
#define mysql_list_dbs(c, wild)			mysqlnd_list_dbs((c), (wild))
#define mysql_list_processes(c)			mysqlnd_list_processes((c))
#define mysql_list_tables(c, wild)		mysqlnd_list_tables((c), (wild))
#define mysql_more_results(r)			mysqlnd_more_results((r))
#define mysql_next_result(r)			mysqlnd_next_result((r))
#define mysql_num_fields(r)				mysqlnd_num_fields((r))
#define mysql_num_rows(r)				mysqlnd_num_rows((r))
#define mysql_ping(r)					mysqlnd_ping((r))
#define mysql_real_escape_string(r,a,b,c) mysqlnd_real_escape_string((r), (a), (b), (c))
#define mysql_real_query(r,a,b)			mysqlnd_query((r), (a), (b))
#define mysql_refresh(conn, options)	mysqlnd_refresh((conn), (options))
#define mysql_rollback(r)				mysqlnd_rollback((r), TRANS_COR_NO_OPT, NULL)
#define mysql_select_db(r,a)			mysqlnd_select_db((r), (a) ,strlen((a)))
#define mysql_set_server_option(r,o)	mysqlnd_set_server_option((r), (o))
#define mysql_set_character_set(r,a)	mysqlnd_set_character_set((r), (a))
#define mysql_sqlstate(r)				mysqlnd_sqlstate((r))
#define mysql_ssl_set(c,key,cert,ca,capath,cipher)	mysqlnd_ssl_set((c), (key), (cert), (ca), (capath), (cipher))
#define mysql_stmt_affected_rows(s)		mysqlnd_stmt_affected_rows((s))
#define mysql_stmt_field_count(s)		mysqlnd_stmt_field_count((s))
#define mysql_stmt_param_count(s)		mysqlnd_stmt_param_count((s))
#define mysql_stmt_num_rows(s)			mysqlnd_stmt_num_rows((s))
#define mysql_stmt_insert_id(s)			mysqlnd_stmt_insert_id((s))
#define mysql_stmt_close(s)				mysqlnd_stmt_close((s))
#define mysql_stmt_bind_param(s,b)		mysqlnd_stmt_bind_param((s), (b))
#define mysql_stmt_bind_result(s,b)		mysqlnd_stmt_bind_result((s), (b))
#define mysql_stmt_errno(s)				mysqlnd_stmt_errno((s))
#define mysql_stmt_error(s)				mysqlnd_stmt_error((s))
#define mysql_stmt_sqlstate(s)			mysqlnd_stmt_sqlstate((s))
#define mysql_stmt_prepare(s,q,l)		mysqlnd_stmt_prepare((s), (q), (l))
#define mysql_stmt_execute(s)			mysqlnd_stmt_execute((s))
#define mysql_stmt_reset(s)				mysqlnd_stmt_reset((s))
#define mysql_stmt_store_result(s)		mysqlnd_stmt_store_result((s))
#define mysql_stmt_free_result(s)		mysqlnd_stmt_free_result((s))
#define mysql_stmt_data_seek(s,r)		mysqlnd_stmt_data_seek((s), (r))
#define mysql_stmt_send_long_data(s,p,d,l) mysqlnd_stmt_send_long_data((s), (p), (d), (l))
#define mysql_stmt_attr_get(s,a,v)		mysqlnd_stmt_attr_get((s), (a), (v))
#define mysql_stmt_attr_set(s,a,v)		mysqlnd_stmt_attr_set((s), (a), (v))
#define mysql_stmt_param_metadata(s)	mysqlnd_stmt_param_metadata((s))
#define mysql_stmt_result_metadata(s)	mysqlnd_stmt_result_metadata((s))
#define mysql_stmt_next_result(s)		mysqlnd_stmt_next_result((s))
#define mysql_stmt_more_results(s)		mysqlnd_stmt_more_results((s))
#define mysql_thread_safe()				mysqlnd_thread_safe()
#define mysql_info(r)					mysqlnd_info((r))
#define mysql_options(c,a,v)			mysqlnd_options((c), (a), (v))
#define mysql_options4(c,a,k,v)			mysqlnd_options4((c), (a), (k), (v))
#define mysql_stmt_init(r)				mysqlnd_stmt_init((r))
#define mysql_free_result(r)			mysqlnd_free_result((r), FALSE)
#define mysql_store_result(r)			mysqlnd_store_result((r))
#define mysql_use_result(r)				mysqlnd_use_result((r))
#define mysql_async_store_result(r)		mysqlnd_async_store_result((r))
#define mysql_thread_id(r)				mysqlnd_thread_id((r))
#define mysql_get_client_info()			mysqlnd_get_client_info()
#define mysql_get_client_version()		mysqlnd_get_client_version()
#define mysql_get_host_info(r)			mysqlnd_get_host_info((r))
#define mysql_get_proto_info(r)			mysqlnd_get_proto_info((r))
#define mysql_get_server_info(r)		mysqlnd_get_server_info((r))
#define mysql_get_server_version(r)		mysqlnd_get_server_version((r))
#define mysql_warning_count(r)			mysqlnd_warning_count((r))
#define mysql_eof(r)					(((r)->unbuf && (r)->unbuf->eof_reached) || (r)->stored_data)

#define REFRESH_GRANT		MYSQLND_REFRESH_GRANT
#define REFRESH_LOG			MYSQLND_REFRESH_LOG
#define REFRESH_TABLES		MYSQLND_REFRESH_TABLES
#define REFRESH_HOSTS		MYSQLND_REFRESH_HOSTS
#define REFRESH_STATUS		MYSQLND_REFRESH_STATUS
#define REFRESH_THREADS		MYSQLND_REFRESH_THREADS
#define REFRESH_SLAVE		MYSQLND_REFRESH_SLAVE
#define REFRESH_MASTER		MYSQLND_REFRESH_MASTER
#define REFRESH_BACKUP_LOG	MYSQLND_REFRESH_BACKUP_LOG

#endif /* MYSQLND_LIBMYSQL_COMPAT_H */
php/ext/mysqli/mysqli_mysqlnd.h000064400000005074151730540540012721 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Georg Richter <georg@php.net>                               |
  |          Andrey Hristov <andrey@php.net>                             |
  |          Ulf Wendel <uw@php.net>                                     |
  +----------------------------------------------------------------------+

*/

#ifndef MYSQLI_MYSQLND_H
#define MYSQLI_MYSQLND_H

#include "ext/mysqlnd/mysqlnd_libmysql_compat.h"
#include "ext/mysqlnd/mysqlnd_portability.h"

/* Here comes non-libmysql API to have less ifdefs in mysqli*/
#define MYSQLI_CLOSE_EXPLICIT                  MYSQLND_CLOSE_EXPLICIT
#define MYSQLI_CLOSE_IMPLICIT                  MYSQLND_CLOSE_IMPLICIT
#define MYSQLI_CLOSE_DISCONNECTED              MYSQLND_CLOSE_DISCONNECTED

#define mysqli_result_is_unbuffered(r)	((r)->unbuf)
#define mysqli_result_is_unbuffered_and_not_everything_is_fetched(r)	((r)->unbuf && !(r)->unbuf->eof_reached)
#define mysqli_server_status(c)			mysqlnd_get_server_status((c))
#define mysqli_stmt_get_id(s)			((s)->data->stmt_id)
#define mysqli_stmt_warning_count(s)	mysqlnd_stmt_warning_count((s))
#define mysqli_stmt_server_status(s)	mysqlnd_stmt_server_status((s))
#define mysqli_stmt_get_connection(s)	(s)->data->conn
#define mysqli_close(c, how)			mysqlnd_close((c), (how))
#define mysqli_stmt_close(c, implicit)	mysqlnd_stmt_close((c), (implicit))
#define mysqli_free_result(r, implicit)	mysqlnd_free_result((r), (implicit))
#define mysqli_async_query(c, q, l)		mysqlnd_async_query((c), (q), (l))
#define mysqli_change_user_silent(c, u, p, d, p_len)   mysqlnd_change_user_ex((c), (u), (p), (d), TRUE, (size_t)(p_len))

#define HAVE_STMT_NEXT_RESULT

#endif
php/ext/mysqli/php_mysqli_structs.h000064400000023403151730540540013604 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Georg Richter <georg@php.net>                               |
  |          Andrey Hristov <andrey@php.net>                             |
  |          Ulf Wendel <uw@php.net>                                     |
  +----------------------------------------------------------------------+

  $Id$
*/

#ifndef PHP_MYSQLI_STRUCTS_H
#define PHP_MYSQLI_STRUCTS_H

/* A little hack to prevent build break, when mysql is used together with
 * c-client, which also defines LIST.
 */
#ifdef LIST
#undef LIST
#endif

#ifndef TRUE
#define TRUE 1
#endif

#ifndef FALSE
#define FALSE 0
#endif

#ifdef MYSQLI_USE_MYSQLND
#include "ext/mysqlnd/mysqlnd.h"
#include "mysqli_mysqlnd.h"
#else

/*
  The libmysql headers (a PITA) also define it and there will be an warning.
  Undef it and later we might need to define it again.
*/
#ifdef HAVE_MBRLEN
#undef HAVE_MBRLEN
#define WE_HAD_MBRLEN
#endif
#ifdef HAVE_MBSTATE_T
#undef HAVE_MBSTATE_T
#define WE_HAD_MBSTATE_T
#endif

#if defined(ulong) && !defined(HAVE_ULONG)
#define HAVE_ULONG
#endif

#include <my_global.h>

#if !defined(HAVE_MBRLEN) && defined(WE_HAD_MBRLEN)
#define HAVE_MBRLEN 1
#endif

#if !defined(HAVE_MBSTATE_T) && defined(WE_HAD_MBSTATE_T)
#define HAVE_MBSTATE_T 1
#endif

/*
  We need more than mysql.h because we need CHARSET_INFO in one place.
  This order has been borrowed from the ODBC driver. Nothing can be removed
  from the list of headers :(
*/

#include <my_sys.h>
#include <mysql.h>
#include <errmsg.h>
#include <my_list.h>
#include <m_string.h>
#include <mysqld_error.h>
#include <my_list.h>
#include <m_ctype.h>
#include "mysqli_libmysql.h"
#endif /* MYSQLI_USE_MYSQLND */


#define MYSQLI_VERSION_ID		101009

enum mysqli_status {
	MYSQLI_STATUS_UNKNOWN=0,
	MYSQLI_STATUS_CLEARED,
	MYSQLI_STATUS_INITIALIZED,
	MYSQLI_STATUS_VALID
};

typedef struct {
	char		*val;
	zend_ulong		buflen;
	zend_ulong		output_len;
	zend_ulong		type;
} VAR_BUFFER;

typedef struct {
	unsigned int	var_cnt;
	VAR_BUFFER		*buf;
	zval			*vars;
	char			*is_null;
} BIND_BUFFER;

typedef struct {
	MYSQL_STMT	*stmt;
	BIND_BUFFER	param;
	BIND_BUFFER	result;
	char		*query;
#ifndef MYSQLI_USE_MYSQLND
	/* used to manage refcount with libmysql (already implement in mysqlnd) */
	zval		link_handle;
#endif
} MY_STMT;

typedef struct {
	MYSQL			*mysql;
	zend_string		*hash_key;
	zval			li_read;
	php_stream		*li_stream;
	unsigned int 	multi_query;
	zend_bool		persistent;
#if defined(MYSQLI_USE_MYSQLND)
	int				async_result_fetch_type;
#endif
} MY_MYSQL;

typedef struct {
	void				*ptr;		/* resource: (mysql, result, stmt)   */
	void				*info;		/* additional buffer				 */
	enum mysqli_status	status;		/* object status */
} MYSQLI_RESOURCE;

typedef struct _mysqli_object {
	void 				*ptr;
	HashTable 			*prop_handler;
	zend_object 		zo;
} mysqli_object; /* extends zend_object */

static inline mysqli_object *php_mysqli_fetch_object(zend_object *obj) {
	return (mysqli_object *)((char*)(obj) - XtOffsetOf(mysqli_object, zo));
}

#define Z_MYSQLI_P(zv) php_mysqli_fetch_object(Z_OBJ_P((zv)))

typedef struct st_mysqli_warning MYSQLI_WARNING;

struct st_mysqli_warning {
	zval	reason;
	zval	sqlstate;
	int		errorno;
   	MYSQLI_WARNING	*next;
};

typedef struct _mysqli_property_entry {
	const char *pname;
	size_t pname_length;
	zval *(*r_func)(mysqli_object *obj, zval *retval);
	int (*w_func)(mysqli_object *obj, zval *value);
} mysqli_property_entry;

typedef struct {
	zend_ptr_stack free_links;
} mysqli_plist_entry;

#ifdef PHP_WIN32
#define PHP_MYSQLI_API __declspec(dllexport)
#define MYSQLI_LLU_SPEC "%I64u"
#define MYSQLI_LL_SPEC "%I64d"
#ifndef L64
#define L64(x) x##i64
#endif
typedef __int64 my_longlong;
#else
# if defined(__GNUC__) && __GNUC__ >= 4
#  define PHP_MYSQLI_API __attribute__ ((visibility("default")))
# else
#  define PHP_MYSQLI_API
# endif
/* we need this for PRIu64 and PRId64 */
#include <inttypes.h>
#define MYSQLI_LLU_SPEC "%" PRIu64
#define MYSQLI_LL_SPEC "%" PRId64
#ifndef L64
#define L64(x) x##LL
#endif
typedef int64_t my_longlong;
#endif

#ifdef ZTS
#include "TSRM.h"
#endif

extern zend_class_entry *mysqli_link_class_entry;
extern zend_class_entry *mysqli_stmt_class_entry;
extern zend_class_entry *mysqli_result_class_entry;
extern zend_class_entry *mysqli_driver_class_entry;
extern zend_class_entry *mysqli_warning_class_entry;
extern zend_class_entry *mysqli_exception_class_entry;
extern int php_le_pmysqli(void);
extern void php_mysqli_dtor_p_elements(void *data);

extern void php_mysqli_close(MY_MYSQL * mysql, int close_type, int resource_status);

extern zend_object_iterator_funcs php_mysqli_result_iterator_funcs;
extern zend_object_iterator *php_mysqli_result_get_iterator(zend_class_entry *ce, zval *object, int by_ref);

extern void php_mysqli_fetch_into_hash_aux(zval *return_value, MYSQL_RES * result, zend_long fetchtype);

#define MYSQLI_DISABLE_MQ if (mysql->multi_query) { \
	mysql_set_server_option(mysql->mysql, MYSQL_OPTION_MULTI_STATEMENTS_OFF); \
	mysql->multi_query = 0; \
}

#define MYSQLI_ENABLE_MQ if (!mysql->multi_query) { \
	mysql_set_server_option(mysql->mysql, MYSQL_OPTION_MULTI_STATEMENTS_ON); \
	mysql->multi_query = 1; \
}

#define REGISTER_MYSQLI_CLASS_ENTRY(name, mysqli_entry, class_functions) { \
	zend_class_entry ce; \
	INIT_CLASS_ENTRY(ce, name,class_functions); \
	ce.create_object = mysqli_objects_new; \
	mysqli_entry = zend_register_internal_class(&ce); \
} \

#define MYSQLI_REGISTER_RESOURCE_EX(__ptr, __zval)  \
	(Z_MYSQLI_P(__zval))->ptr = __ptr;

#define MYSQLI_RETURN_RESOURCE(__ptr, __ce) \
	RETVAL_OBJ(mysqli_objects_new(__ce)); \
	MYSQLI_REGISTER_RESOURCE_EX(__ptr, return_value)

#define MYSQLI_REGISTER_RESOURCE(__ptr, __ce) \
{\
	zval *object = getThis(); \
	if (!object || !instanceof_function(Z_OBJCE_P(object), mysqli_link_class_entry)) { \
		object = return_value; \
		ZVAL_OBJ(object, mysqli_objects_new(__ce)); \
	} \
	MYSQLI_REGISTER_RESOURCE_EX(__ptr, object)\
}

#define MYSQLI_FETCH_RESOURCE(__ptr, __type, __id, __name, __check) \
{ \
	MYSQLI_RESOURCE *my_res; \
	mysqli_object *intern = Z_MYSQLI_P(__id); \
	if (!(my_res = (MYSQLI_RESOURCE *)intern->ptr)) {\
  		php_error_docref(NULL, E_WARNING, "Couldn't fetch %s", ZSTR_VAL(intern->zo.ce->name));\
  		RETURN_NULL();\
  	}\
	__ptr = (__type)my_res->ptr; \
	if (__check && my_res->status < __check) { \
		php_error_docref(NULL, E_WARNING, "invalid object or resource %s\n", ZSTR_VAL(intern->zo.ce->name)); \
		RETURN_NULL();\
	}\
}

#define MYSQLI_FETCH_RESOURCE_BY_OBJ(__ptr, __type, __obj, __name, __check) \
{ \
	MYSQLI_RESOURCE *my_res; \
	if (!(my_res = (MYSQLI_RESOURCE *)(__obj->ptr))) {\
  		php_error_docref(NULL, E_WARNING, "Couldn't fetch %s", ZSTR_VAL(intern->zo.ce->name));\
  		return;\
  	}\
	__ptr = (__type)my_res->ptr; \
	if (__check && my_res->status < __check) { \
		php_error_docref(NULL, E_WARNING, "invalid object or resource %s\n", ZSTR_VAL(intern->zo.ce->name)); \
		return;\
	}\
}

#define MYSQLI_FETCH_RESOURCE_CONN(__ptr, __id, __check) \
{ \
	MYSQLI_FETCH_RESOURCE((__ptr), MY_MYSQL *, (__id), "mysqli_link", (__check)); \
	if (!(__ptr)->mysql) { \
		mysqli_object *intern = Z_MYSQLI_P(__id); \
		php_error_docref(NULL, E_WARNING, "invalid object or resource %s\n", ZSTR_VAL(intern->zo.ce->name)); \
		RETURN_NULL(); \
	} \
}

#define MYSQLI_FETCH_RESOURCE_STMT(__ptr, __id, __check) \
{ \
	MYSQLI_FETCH_RESOURCE((__ptr), MY_STMT *, (__id), "mysqli_stmt", (__check)); \
	if (!(__ptr)->stmt) { \
		mysqli_object *intern = Z_MYSQLI_P(__id); \
		php_error_docref(NULL, E_WARNING, "invalid object or resource %s\n", ZSTR_VAL(intern->zo.ce->name)); \
		RETURN_NULL();\
	} \
}

#define MYSQLI_SET_STATUS(__id, __value) \
{ \
	mysqli_object *intern = Z_MYSQLI_P(__id); \
	((MYSQLI_RESOURCE *)intern->ptr)->status = __value; \
} \

#define MYSQLI_CLEAR_RESOURCE(__id) \
{ \
	mysqli_object *intern = Z_MYSQLI_P(__id); \
	efree(intern->ptr); \
	intern->ptr = NULL; \
}


ZEND_BEGIN_MODULE_GLOBALS(mysqli)
	zend_long			default_link;
	zend_long			num_links;
	zend_long			max_links;
	zend_long 			num_active_persistent;
	zend_long 			num_inactive_persistent;
	zend_long			max_persistent;
	zend_long			allow_persistent;
	zend_ulong	default_port;
	char			*default_host;
	char			*default_user;
	char			*default_socket;
	char			*default_pw;
	zend_long			reconnect;
	zend_long			allow_local_infile;
	zend_long			strict;
	zend_long			error_no;
	char			*error_msg;
	zend_long			report_mode;
	HashTable		*report_ht;
	zend_ulong	multi_query;
	zend_ulong	embedded;
	zend_bool 		rollback_on_cached_plink;
ZEND_END_MODULE_GLOBALS(mysqli)

#define MyG(v) ZEND_MODULE_GLOBALS_ACCESSOR(mysqli, v)

#if defined(ZTS) && defined(COMPILE_DL_MYSQLI)
ZEND_TSRMLS_CACHE_EXTERN()
#endif

#define my_estrdup(x) (x) ? estrdup(x) : NULL
#define my_efree(x) if (x) efree(x)

ZEND_EXTERN_MODULE_GLOBALS(mysqli)

#endif	/* PHP_MYSQLI_STRUCTS.H */


/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/ext/hash/php_hash_snefru.h000064400000003572151730540540012416 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Michael Wallner <mike@php.net>                               |
   +----------------------------------------------------------------------+
*/

/* $Id: php_hash_snefru.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_HASH_SNEFRU_H
#define PHP_HASH_SNEFRU_H

/* SNEFRU-2.5a with 8 passes and 256 bit hash output
 * AKA "Xerox Secure Hash Function" 
 */

#include "ext/standard/basic_functions.h"

/* SNEFRU context */
typedef struct {
	php_hash_uint32 state[16];
	php_hash_uint32 count[2];
	unsigned char length;
	unsigned char buffer[32];
} PHP_SNEFRU_CTX;

PHP_HASH_API void PHP_SNEFRUInit(PHP_SNEFRU_CTX *);
PHP_HASH_API void PHP_SNEFRUUpdate(PHP_SNEFRU_CTX *, const unsigned char *, size_t);
PHP_HASH_API void PHP_SNEFRUFinal(unsigned char[32], PHP_SNEFRU_CTX *);

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/ext/hash/php_hash_sha.h000064400000006673151730540550011675 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | SHA1 Author: Stefan Esser <sesser@php.net>                           |
   | SHA256 Author: Sara Golemon <pollita@php.net>                        |
   +----------------------------------------------------------------------+
*/

/* $Id: php_hash_sha.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_HASH_SHA_H
#define PHP_HASH_SHA_H

/* When SHA is removed from Core,
	the ext/standard/sha1.c file can be removed
	and the ext/standard/sha1.h file can be reduced to:
		#define PHP_HASH_SHA1_NOT_IN_CORE
		#include "ext/hash/php_hash_sha.h"
	Don't forget to remove sha1() and sha1_file() from basic_functions.c
 */
#include "ext/standard/sha1.h"
#include "ext/standard/basic_functions.h"

#ifdef PHP_HASH_SHA1_NOT_IN_CORE

/* SHA1 context. */
typedef struct {
	php_hash_uint32 state[5];		/* state (ABCD) */
	php_hash_uint32 count[2];		/* number of bits, modulo 2^64 */
	unsigned char buffer[64];	/* input buffer */
} PHP_SHA1_CTX;

PHP_HASH_API void PHP_SHA1Init(PHP_SHA1_CTX *);
PHP_HASH_API void PHP_SHA1Update(PHP_SHA1_CTX *, const unsigned char *, unsigned int);
PHP_HASH_API void PHP_SHA1Final(unsigned char[20], PHP_SHA1_CTX *);

PHP_FUNCTION(sha1);
PHP_FUNCTION(sha1_file);

#endif /* PHP_HASH_SHA1_NOT_IN_CORE */

/* SHA256 context. */
typedef struct {
	php_hash_uint32 state[8];		/* state */
	php_hash_uint32 count[2];		/* number of bits, modulo 2^64 */
	unsigned char buffer[64];	/* input buffer */
} PHP_SHA256_CTX;

PHP_HASH_API void PHP_SHA256Init(PHP_SHA256_CTX *);
PHP_HASH_API void PHP_SHA256Update(PHP_SHA256_CTX *, const unsigned char *, unsigned int);
PHP_HASH_API void PHP_SHA256Final(unsigned char[32], PHP_SHA256_CTX *);

/* SHA384 context */
typedef struct {
	php_hash_uint64 state[8];	/* state */
	php_hash_uint64 count[2];	/* number of bits, modulo 2^128 */
	unsigned char buffer[128];	/* input buffer */
} PHP_SHA384_CTX;

PHP_HASH_API void PHP_SHA384Init(PHP_SHA384_CTX *);
PHP_HASH_API void PHP_SHA384Update(PHP_SHA384_CTX *, const unsigned char *, unsigned int);
PHP_HASH_API void PHP_SHA384Final(unsigned char[48], PHP_SHA384_CTX *);

/* SHA512 context */
typedef struct {
	php_hash_uint64 state[8];	/* state */
	php_hash_uint64 count[2];	/* number of bits, modulo 2^128 */
	unsigned char buffer[128];	/* input buffer */
} PHP_SHA512_CTX;

PHP_HASH_API void PHP_SHA512Init(PHP_SHA512_CTX *);
PHP_HASH_API void PHP_SHA512Update(PHP_SHA512_CTX *, const unsigned char *, unsigned int);
PHP_HASH_API void PHP_SHA512Final(unsigned char[64], PHP_SHA512_CTX *);

#endif /* PHP_HASH_SHA_H */
php/ext/hash/php_hash_crc32.h000064400000003463151730540550012030 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Michael Wallner <mike@php.net>                               |
   +----------------------------------------------------------------------+
*/

/* $Id: php_hash_crc32.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_HASH_CRC32_H
#define PHP_HASH_CRC32_H

#include "ext/standard/basic_functions.h"

typedef struct {
	php_hash_uint32 state;
} PHP_CRC32_CTX;

PHP_HASH_API void PHP_CRC32Init(PHP_CRC32_CTX *context);
PHP_HASH_API void PHP_CRC32Update(PHP_CRC32_CTX *context, const unsigned char *input, size_t len);
PHP_HASH_API void PHP_CRC32BUpdate(PHP_CRC32_CTX *context, const unsigned char *input, size_t len);
PHP_HASH_API void PHP_CRC32Final(unsigned char digest[4], PHP_CRC32_CTX *context);

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/ext/hash/php_hash_joaat.h000064400000003254151730540550012210 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: Martin Jansen <mj@php.net>                                   |
  +----------------------------------------------------------------------+
*/

/* $Id*/

#ifndef PHP_HASH_JOAAT_H
#define PHP_HASH_JOAAT_H

typedef struct {
	uint32_t state;
} PHP_JOAAT_CTX;

PHP_HASH_API void PHP_JOAATInit(PHP_JOAAT_CTX *context);
PHP_HASH_API void PHP_JOAATUpdate(PHP_JOAAT_CTX *context, const unsigned char *input, unsigned int inputLen);
PHP_HASH_API void PHP_JOAATFinal(unsigned char digest[16], PHP_JOAAT_CTX * context);

static uint32_t joaat_buf(void *buf, size_t len, uint32_t hval);

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/ext/hash/php_hash_md.h000064400000007540151730540560011515 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Original Author: Rasmus Lerdorf <rasmus@lerdorf.on.ca>               |
   | Modified for pHASH by: Sara Golemon <pollita@php.net>
   +----------------------------------------------------------------------+
*/

/* $Id: php_hash_md.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_HASH_MD_H
#define PHP_HASH_MD_H

/* When SHA is removed from Core,
    the ext/standard/sha1.c file can be removed
    and the ext/standard/sha1.h file can be reduced to:
        #define PHP_HASH_SHA1_NOT_IN_CORE
        #include "ext/hash/php_hash_sha.h"
	Don't forget to remove md5() and md5_file() entries from basic_functions.c
 */

#include "ext/standard/md5.h"

#ifdef PHP_HASH_MD5_NOT_IN_CORE
/* MD5.H - header file for MD5C.C
 */

/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
   rights reserved.

   License to copy and use this software is granted provided that it
   is identified as the "RSA Data Security, Inc. MD5 Message-Digest
   Algorithm" in all material mentioning or referencing this software
   or this function.

   License is also granted to make and use derivative works provided
   that such works are identified as "derived from the RSA Data
   Security, Inc. MD5 Message-Digest Algorithm" in all material
   mentioning or referencing the derived work.

   RSA Data Security, Inc. makes no representations concerning either
   the merchantability of this software or the suitability of this
   software for any particular purpose. It is provided "as is"
   without express or implied warranty of any kind.

   These notices must be retained in any copies of any part of this
   documentation and/or software.
 */

/* MD5 context. */
typedef struct {
	php_hash_uint32 state[4];				/* state (ABCD) */
	php_hash_uint32 count[2];				/* number of bits, modulo 2^64 (lsb first) */
	unsigned char buffer[64];	/* input buffer */
} PHP_MD5_CTX;

PHP_HASH_API void make_digest(char *md5str, unsigned char *digest);
PHP_HASH_API void PHP_MD5Init(PHP_MD5_CTX *);
PHP_HASH_API void PHP_MD5Update(PHP_MD5_CTX *, const unsigned char *, unsigned int);
PHP_HASH_API void PHP_MD5Final(unsigned char[16], PHP_MD5_CTX *);

PHP_NAMED_FUNCTION(php_if_md5);
PHP_NAMED_FUNCTION(php_if_md5_file);
#endif /* PHP_HASH_MD5_NOT_IN_CORE */

/* MD4 context */
typedef struct {
	php_hash_uint32 state[4];
	php_hash_uint32 count[2];
	unsigned char buffer[64];
} PHP_MD4_CTX;

#define PHP_MD4Init			PHP_MD5Init
PHP_HASH_API void PHP_MD4Update(PHP_MD4_CTX *context, const unsigned char *, unsigned int);
PHP_HASH_API void PHP_MD4Final(unsigned char[16], PHP_MD4_CTX *);

/* MD2 context */
typedef struct {
	unsigned char state[48];
	unsigned char checksum[16];
	unsigned char buffer[16];
	char in_buffer;
} PHP_MD2_CTX;

PHP_HASH_API void PHP_MD2Init(PHP_MD2_CTX *context);
PHP_HASH_API void PHP_MD2Update(PHP_MD2_CTX *context, const unsigned char *, unsigned int);
PHP_HASH_API void PHP_MD2Final(unsigned char[16], PHP_MD2_CTX *);

#endif
php/ext/hash/php_hash_ripemd.h000064400000006066151730540560012377 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Sara Golemon <pollita@php.net>                               |
   +----------------------------------------------------------------------+
*/

/* $Id: php_hash_ripemd.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_HASH_RIPEMD_H
#define PHP_HASH_RIPEMD_H
#include "ext/standard/basic_functions.h"

/* RIPEMD context. */
typedef struct {
	php_hash_uint32 state[4];		/* state (ABCD) */
	php_hash_uint32 count[2];		/* number of bits, modulo 2^64 (lsb first) */
	unsigned char buffer[64];	/* input buffer */
} PHP_RIPEMD128_CTX;

typedef struct {
	php_hash_uint32 state[5];		/* state (ABCD) */
	php_hash_uint32 count[2];		/* number of bits, modulo 2^64 (lsb first) */
	unsigned char buffer[64];	/* input buffer */
} PHP_RIPEMD160_CTX;

typedef struct {
	php_hash_uint32 state[8];		/* state (ABCD) */
	php_hash_uint32 count[2];		/* number of bits, modulo 2^64 (lsb first) */
	unsigned char buffer[64];	/* input buffer */
} PHP_RIPEMD256_CTX;

typedef struct {
	php_hash_uint32 state[10];		/* state (ABCD) */
	php_hash_uint32 count[2];		/* number of bits, modulo 2^64 (lsb first) */
	unsigned char buffer[64];	/* input buffer */
} PHP_RIPEMD320_CTX;

PHP_HASH_API void PHP_RIPEMD128Init(PHP_RIPEMD128_CTX *);
PHP_HASH_API void PHP_RIPEMD128Update(PHP_RIPEMD128_CTX *, const unsigned char *, unsigned int);
PHP_HASH_API void PHP_RIPEMD128Final(unsigned char[16], PHP_RIPEMD128_CTX *);

PHP_HASH_API void PHP_RIPEMD160Init(PHP_RIPEMD160_CTX *);
PHP_HASH_API void PHP_RIPEMD160Update(PHP_RIPEMD160_CTX *, const unsigned char *, unsigned int);
PHP_HASH_API void PHP_RIPEMD160Final(unsigned char[20], PHP_RIPEMD160_CTX *);

PHP_HASH_API void PHP_RIPEMD256Init(PHP_RIPEMD256_CTX *);
PHP_HASH_API void PHP_RIPEMD256Update(PHP_RIPEMD256_CTX *, const unsigned char *, unsigned int);
PHP_HASH_API void PHP_RIPEMD256Final(unsigned char[32], PHP_RIPEMD256_CTX *);

PHP_HASH_API void PHP_RIPEMD320Init(PHP_RIPEMD320_CTX *);
PHP_HASH_API void PHP_RIPEMD320Update(PHP_RIPEMD320_CTX *, const unsigned char *, unsigned int);
PHP_HASH_API void PHP_RIPEMD320Final(unsigned char[40], PHP_RIPEMD320_CTX *);

#endif /* PHP_HASH_RIPEMD_H */
php/ext/hash/php_hash_adler32.h000064400000003343151730540570012347 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Michael Wallner <mike@php.net>                               |
   +----------------------------------------------------------------------+
*/

/* $Id: php_hash_adler32.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_HASH_ADLER32_H
#define PHP_HASH_ADLER32_H

#include "ext/standard/basic_functions.h"

typedef struct {
	php_hash_uint32 state;
} PHP_ADLER32_CTX;

PHP_HASH_API void PHP_ADLER32Init(PHP_ADLER32_CTX *context);
PHP_HASH_API void PHP_ADLER32Update(PHP_ADLER32_CTX *context, const unsigned char *input, size_t len);
PHP_HASH_API void PHP_ADLER32Final(unsigned char digest[4], PHP_ADLER32_CTX *context);

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/ext/hash/php_hash_fnv.h000064400000005674151730540570011715 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 7                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: Michael Maclean <mgdm@php.net>                               |
  +----------------------------------------------------------------------+
*/

/* $Id$ */

#ifndef PHP_HASH_FNV_H
#define PHP_HASH_FNV_H

#define PHP_FNV1_32_INIT ((uint32_t)0x811c9dc5)
#define PHP_FNV1_32A_INIT PHP_FNV1_32_INIT

#define PHP_FNV_32_PRIME ((uint32_t)0x01000193)

#define PHP_FNV1_64_INIT ((uint64_t)0xcbf29ce484222325ULL)
#define PHP_FNV1A_64_INIT FNV1_64_INIT

#define PHP_FNV_64_PRIME ((uint64_t)0x100000001b3ULL)


/*
 * hash types
 */
enum php_fnv_type {
	PHP_FNV_NONE  = 0,	/* invalid FNV hash type */
	PHP_FNV0_32   = 1,	/* FNV-0 32 bit hash */
	PHP_FNV1_32   = 2,	/* FNV-1 32 bit hash */
	PHP_FNV1a_32  = 3,	/* FNV-1a 32 bit hash */
	PHP_FNV0_64   = 4,	/* FNV-0 64 bit hash */
	PHP_FNV1_64   = 5,	/* FNV-1 64 bit hash */
	PHP_FNV1a_64  = 6,	/* FNV-1a 64 bit hash */
};

typedef struct {
	uint32_t state;
} PHP_FNV132_CTX;

typedef struct {
	uint64_t state;
} PHP_FNV164_CTX;


PHP_HASH_API void PHP_FNV132Init(PHP_FNV132_CTX *context);
PHP_HASH_API void PHP_FNV132Update(PHP_FNV132_CTX *context, const unsigned char *input, unsigned int inputLen);
PHP_HASH_API void PHP_FNV1a32Update(PHP_FNV132_CTX *context, const unsigned char *input, unsigned int inputLen);
PHP_HASH_API void PHP_FNV132Final(unsigned char digest[16], PHP_FNV132_CTX * context);

PHP_HASH_API void PHP_FNV164Init(PHP_FNV164_CTX *context);
PHP_HASH_API void PHP_FNV164Update(PHP_FNV164_CTX *context, const unsigned char *input, unsigned int inputLen);
PHP_HASH_API void PHP_FNV1a64Update(PHP_FNV164_CTX *context, const unsigned char *input, unsigned int inputLen);
PHP_HASH_API void PHP_FNV164Final(unsigned char digest[16], PHP_FNV164_CTX * context);

static uint32_t fnv_32_buf(void *buf, size_t len, uint32_t hval, int alternate);
static uint64_t fnv_64_buf(void *buf, size_t len, uint64_t hval, int alternate);

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/ext/hash/php_hash_whirlpool.h000064400000003447151730540600013131 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Michael Wallner <mike@php.net>                               |
   +----------------------------------------------------------------------+
*/

/* $Id: php_hash_whirlpool.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_HASH_WHIRLPOOL_H
#define PHP_HASH_WHIRLPOOL_H

/* WHIRLPOOL context */
typedef struct {
	php_hash_uint64 state[8];
	unsigned char bitlength[32];
	struct {
		int pos;
		int bits;
		unsigned char data[64];
	} buffer;
} PHP_WHIRLPOOL_CTX;

PHP_HASH_API void PHP_WHIRLPOOLInit(PHP_WHIRLPOOL_CTX *);
PHP_HASH_API void PHP_WHIRLPOOLUpdate(PHP_WHIRLPOOL_CTX *, const unsigned char *, size_t);
PHP_HASH_API void PHP_WHIRLPOOLFinal(unsigned char[64], PHP_WHIRLPOOL_CTX *);

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/ext/hash/php_hash.h000064400000011065151730540600011025 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 5                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2010 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: Sara Golemon <pollita@php.net>                               |
  +----------------------------------------------------------------------+
*/

/* $Id: php_hash.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_HASH_H
#define PHP_HASH_H

#include "php.h"
#include "php_hash_types.h"

#define PHP_HASH_EXTNAME	"hash"
#define PHP_HASH_EXTVER		"1.0"
#define PHP_HASH_RESNAME	"Hash Context"

#define PHP_HASH_HMAC		0x0001

typedef void (*php_hash_init_func_t)(void *context);
typedef void (*php_hash_update_func_t)(void *context, const unsigned char *buf, unsigned int count);
typedef void (*php_hash_final_func_t)(unsigned char *digest, void *context);

typedef struct _php_hash_ops {
	php_hash_init_func_t hash_init;
	php_hash_update_func_t hash_update;
	php_hash_final_func_t hash_final;

	int digest_size;
	int block_size;
	int context_size;
} php_hash_ops;

typedef struct _php_hash_data {
	const php_hash_ops *ops;
	void *context;

	long options;
	unsigned char *key;
} php_hash_data;

extern const php_hash_ops php_hash_md2_ops;
extern const php_hash_ops php_hash_md4_ops;
extern const php_hash_ops php_hash_md5_ops;
extern const php_hash_ops php_hash_sha1_ops;
extern const php_hash_ops php_hash_sha256_ops;
extern const php_hash_ops php_hash_sha384_ops;
extern const php_hash_ops php_hash_sha512_ops;
extern const php_hash_ops php_hash_ripemd128_ops;
extern const php_hash_ops php_hash_ripemd160_ops;
extern const php_hash_ops php_hash_ripemd256_ops;
extern const php_hash_ops php_hash_ripemd320_ops;
extern const php_hash_ops php_hash_whirlpool_ops;
extern const php_hash_ops php_hash_3tiger128_ops;
extern const php_hash_ops php_hash_3tiger160_ops;
extern const php_hash_ops php_hash_3tiger192_ops;
extern const php_hash_ops php_hash_4tiger128_ops;
extern const php_hash_ops php_hash_4tiger160_ops;
extern const php_hash_ops php_hash_4tiger192_ops;
extern const php_hash_ops php_hash_snefru_ops;
extern const php_hash_ops php_hash_gost_ops;
extern const php_hash_ops php_hash_adler32_ops;
extern const php_hash_ops php_hash_crc32_ops;
extern const php_hash_ops php_hash_crc32b_ops;

#define PHP_HASH_HAVAL_OPS(p,b)	extern const php_hash_ops php_hash_##p##haval##b##_ops;

PHP_HASH_HAVAL_OPS(3,128)
PHP_HASH_HAVAL_OPS(3,160)
PHP_HASH_HAVAL_OPS(3,192)
PHP_HASH_HAVAL_OPS(3,224)
PHP_HASH_HAVAL_OPS(3,256)

PHP_HASH_HAVAL_OPS(4,128)
PHP_HASH_HAVAL_OPS(4,160)
PHP_HASH_HAVAL_OPS(4,192)
PHP_HASH_HAVAL_OPS(4,224)
PHP_HASH_HAVAL_OPS(4,256)

PHP_HASH_HAVAL_OPS(5,128)
PHP_HASH_HAVAL_OPS(5,160)
PHP_HASH_HAVAL_OPS(5,192)
PHP_HASH_HAVAL_OPS(5,224)
PHP_HASH_HAVAL_OPS(5,256)

extern zend_module_entry hash_module_entry;
#define phpext_hash_ptr &hash_module_entry

#ifdef PHP_WIN32
#define PHP_HASH_API __declspec(dllexport)
#else
#define PHP_HASH_API
#endif

#ifdef ZTS
#include "TSRM.h"
#endif

PHP_FUNCTION(hash);
PHP_FUNCTION(hash_file);
PHP_FUNCTION(hash_hmac);
PHP_FUNCTION(hash_hmac_file);
PHP_FUNCTION(hash_init);
PHP_FUNCTION(hash_update);
PHP_FUNCTION(hash_update_stream);
PHP_FUNCTION(hash_update_file);
PHP_FUNCTION(hash_final);
PHP_FUNCTION(hash_algos);

PHP_HASH_API const php_hash_ops *php_hash_fetch_ops(const char *algo, int algo_len);
PHP_HASH_API void php_hash_register_algo(const char *algo, const php_hash_ops *ops);

static inline void php_hash_bin2hex(char *out, const unsigned char *in, int in_len)
{
	static const char hexits[17] = "0123456789abcdef";
	int i;

	for(i = 0; i < in_len; i++) {
		out[i * 2]       = hexits[in[i] >> 4];
		out[(i * 2) + 1] = hexits[in[i] &  0x0F];
	}
}

#endif	/* PHP_HASH_H */


/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/ext/hash/php_hash_gost.h000064400000003405151730540610012061 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Michael Wallner <mike@php.net>                               |
   +----------------------------------------------------------------------+
*/

/* $Id: php_hash_gost.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_HASH_GOST_H
#define PHP_HASH_GOST_H

#include "ext/standard/basic_functions.h"

/* GOST context */
typedef struct {
	php_hash_uint32 state[16];
	php_hash_uint32 count[2];
	unsigned char length;
	unsigned char buffer[32];
} PHP_GOST_CTX;

PHP_HASH_API void PHP_GOSTInit(PHP_GOST_CTX *);
PHP_HASH_API void PHP_GOSTUpdate(PHP_GOST_CTX *, const unsigned char *, size_t);
PHP_HASH_API void PHP_GOSTFinal(unsigned char[64], PHP_GOST_CTX *);

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/ext/hash/php_hash_haval.h000064400000004416151730540610012203 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Sara Golemon <pollita@php.net>                               |
   +----------------------------------------------------------------------+
*/

/* $Id: php_hash_haval.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_HASH_HAVAL_H
#define PHP_HASH_HAVAL_H

#include "ext/standard/basic_functions.h"
/* HAVAL context. */
typedef struct {
	php_hash_uint32 state[8];
	php_hash_uint32 count[2];
	unsigned char buffer[128];

	char passes;
	short output;
	void (*Transform)(php_hash_uint32 state[8], const unsigned char block[128]);
} PHP_HAVAL_CTX;

#define PHP_HASH_HAVAL_INIT_DECL(p,b)	PHP_HASH_API void PHP_##p##HAVAL##b##Init(PHP_HAVAL_CTX *); \
										PHP_HASH_API void PHP_HAVAL##b##Final(unsigned char*, PHP_HAVAL_CTX *);

PHP_HASH_API void PHP_HAVALUpdate(PHP_HAVAL_CTX *, const unsigned char *, unsigned int);

PHP_HASH_HAVAL_INIT_DECL(3,128)
PHP_HASH_HAVAL_INIT_DECL(3,160)
PHP_HASH_HAVAL_INIT_DECL(3,192)
PHP_HASH_HAVAL_INIT_DECL(3,224)
PHP_HASH_HAVAL_INIT_DECL(3,256)

PHP_HASH_HAVAL_INIT_DECL(4,128)
PHP_HASH_HAVAL_INIT_DECL(4,160)
PHP_HASH_HAVAL_INIT_DECL(4,192)
PHP_HASH_HAVAL_INIT_DECL(4,224)
PHP_HASH_HAVAL_INIT_DECL(4,256)

PHP_HASH_HAVAL_INIT_DECL(5,128)
PHP_HASH_HAVAL_INIT_DECL(5,160)
PHP_HASH_HAVAL_INIT_DECL(5,192)
PHP_HASH_HAVAL_INIT_DECL(5,224)
PHP_HASH_HAVAL_INIT_DECL(5,256)

#endif
php/ext/hash/php_hash_sha3.h000064400000004763151730540620011754 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 7                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2018 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Sara Golemon <pollita@php.net>                               |
   +----------------------------------------------------------------------+
*/

#ifndef PHP_HASH_SHA3_H
#define PHP_HASH_SHA3_H

#include "php.h"

typedef struct {
#ifdef HAVE_SLOW_HASH3
	unsigned char state[200]; // 5 * 5 * sizeof(uint64)
	uint32_t pos;
#else
	void *hashinstance;
#endif
} PHP_SHA3_CTX;

typedef PHP_SHA3_CTX PHP_SHA3_224_CTX;
typedef PHP_SHA3_CTX PHP_SHA3_256_CTX;
typedef PHP_SHA3_CTX PHP_SHA3_384_CTX;
typedef PHP_SHA3_CTX PHP_SHA3_512_CTX;

PHP_HASH_API void PHP_SHA3224Init(PHP_SHA3_224_CTX*);
PHP_HASH_API void PHP_SHA3224Update(PHP_SHA3_224_CTX*, const unsigned char*, unsigned int);
PHP_HASH_API void PHP_SAH3224Final(unsigned char[32], PHP_SHA3_224_CTX*);

PHP_HASH_API void PHP_SHA3256Init(PHP_SHA3_256_CTX*);
PHP_HASH_API void PHP_SHA3256Update(PHP_SHA3_256_CTX*, const unsigned char*, unsigned int);
PHP_HASH_API void PHP_SAH3256Final(unsigned char[32], PHP_SHA3_256_CTX*);

PHP_HASH_API void PHP_SHA3384Init(PHP_SHA3_384_CTX*);
PHP_HASH_API void PHP_SHA3384Update(PHP_SHA3_384_CTX*, const unsigned char*, unsigned int);
PHP_HASH_API void PHP_SAH3384Final(unsigned char[32], PHP_SHA3_384_CTX*);

PHP_HASH_API void PHP_SHA3512Init(PHP_SHA3_512_CTX*);
PHP_HASH_API void PHP_SHA3512Update(PHP_SHA3_512_CTX*, const unsigned char*, unsigned int);
PHP_HASH_API void PHP_SAH3512Final(unsigned char[32], PHP_SHA3_512_CTX*);

#endif
/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/ext/hash/php_hash_tiger.h000064400000004010151730540620012211 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Michael Wallner <mike@php.net>                               |
   +----------------------------------------------------------------------+
*/

/* $Id: php_hash_tiger.h 301252 2010-07-13 23:59:54Z kalle $ */

#ifndef PHP_HASH_TIGER_H
#define PHP_HASH_TIGER_H

/* TIGER context */
typedef struct {
	php_hash_uint64 state[3];
	php_hash_uint64 passed;
	unsigned int passes:1;
	unsigned int length:7;
	unsigned char buffer[64];
} PHP_TIGER_CTX;

PHP_HASH_API void PHP_3TIGERInit(PHP_TIGER_CTX *context);
PHP_HASH_API void PHP_4TIGERInit(PHP_TIGER_CTX *context);
PHP_HASH_API void PHP_TIGERUpdate(PHP_TIGER_CTX *context, const unsigned char *input, size_t len);
PHP_HASH_API void PHP_TIGER128Final(unsigned char digest[16], PHP_TIGER_CTX *context);
PHP_HASH_API void PHP_TIGER160Final(unsigned char digest[20], PHP_TIGER_CTX *context);
PHP_HASH_API void PHP_TIGER192Final(unsigned char digest[24], PHP_TIGER_CTX *context);

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/ext/date/php_date.h000064400000007011151730540620011007 0ustar00/* 
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Derick Rethans <derick@derickrethans.nl>                    |
   +----------------------------------------------------------------------+
*/

/* $Id: php_date.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_DATE_H
#define PHP_DATE_H

#include "lib/timelib.h"
#include "Zend/zend_hash.h"

extern zend_module_entry date_module_entry;
#define phpext_date_ptr &date_module_entry

PHP_FUNCTION(date);
PHP_FUNCTION(idate);
PHP_FUNCTION(gmdate);
PHP_FUNCTION(strtotime);

PHP_FUNCTION(mktime);
PHP_FUNCTION(gmmktime);

PHP_FUNCTION(checkdate);

#ifdef HAVE_STRFTIME
PHP_FUNCTION(strftime);
PHP_FUNCTION(gmstrftime);
#endif

PHP_FUNCTION(time);
PHP_FUNCTION(localtime);
PHP_FUNCTION(getdate);

/* Advanced Interface */
PHP_METHOD(DateTime, __construct);
PHP_FUNCTION(date_create);
PHP_FUNCTION(date_parse);
PHP_FUNCTION(date_format);
PHP_FUNCTION(date_modify);
PHP_FUNCTION(date_timezone_get);
PHP_FUNCTION(date_timezone_set);
PHP_FUNCTION(date_offset_get);

PHP_FUNCTION(date_time_set);
PHP_FUNCTION(date_date_set);
PHP_FUNCTION(date_isodate_set);

PHP_METHOD(DateTimeZone, __construct);
PHP_FUNCTION(timezone_open);
PHP_FUNCTION(timezone_name_get);
PHP_FUNCTION(timezone_name_from_abbr);
PHP_FUNCTION(timezone_offset_get);
PHP_FUNCTION(timezone_transitions_get);
PHP_FUNCTION(timezone_identifiers_list);
PHP_FUNCTION(timezone_abbreviations_list);

/* Options and Configuration */
PHP_FUNCTION(date_default_timezone_set);
PHP_FUNCTION(date_default_timezone_get);

/* Astro functions */
PHP_FUNCTION(date_sunrise);
PHP_FUNCTION(date_sunset);
PHP_FUNCTION(date_sun_info);

PHP_RINIT_FUNCTION(date);
PHP_RSHUTDOWN_FUNCTION(date);
PHP_MINIT_FUNCTION(date);
PHP_MSHUTDOWN_FUNCTION(date);
PHP_MINFO_FUNCTION(date);

ZEND_BEGIN_MODULE_GLOBALS(date)
	char      *default_timezone;
	char      *timezone;
	HashTable *tzcache;
ZEND_END_MODULE_GLOBALS(date)

#ifdef ZTS
#define DATEG(v) TSRMG(date_globals_id, zend_date_globals *, v)
#else
#define DATEG(v) (date_globals.v)
#endif

/* Backwards compability wrapper */
PHPAPI signed long php_parse_date(char *string, signed long *now);
PHPAPI void php_mktime(INTERNAL_FUNCTION_PARAMETERS, int gmt);
PHPAPI int php_idate(char format, time_t ts, int localtime);
#if HAVE_STRFTIME
#define _php_strftime php_strftime
PHPAPI void php_strftime(INTERNAL_FUNCTION_PARAMETERS, int gm);
#endif
PHPAPI char *php_format_date(char *format, int format_len, time_t ts, int localtime TSRMLS_DC);

/* Mechanism to set new TZ database */
PHPAPI void php_date_set_tzdb(timelib_tzdb *tzdb);
PHPAPI timelib_tzinfo *get_timezone_info(TSRMLS_D);

#endif /* PHP_DATE_H */
php/ext/date/lib/timelib_config.h000064400000000120151730540630012736 0ustar00#ifdef PHP_WIN32
# include "config.w32.h"
#else
# include <php_config.h>
#endif
php/ext/date/lib/timelib.h000064400000011241151730540630011417 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Derick Rethans <derick@derickrethans.nl>                    |
   +----------------------------------------------------------------------+
 */

/* $Id: timelib.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef __TIMELIB_H__
#define __TIMELIB_H__

#include "timelib_structs.h"
#if HAVE_LIMITS_H
#include <limits.h>
#endif

#define TIMELIB_NONE             0x00
#define TIMELIB_OVERRIDE_TIME    0x01
#define TIMELIB_NO_CLONE         0x02

#define TIMELIB_SPECIAL_WEEKDAY  0x01

#ifndef LONG_MAX
#define LONG_MAX 2147483647L
#endif

#ifndef LONG_MIN
#define LONG_MIN (- LONG_MAX - 1)
#endif

#if defined(_MSC_VER) && !defined(strcasecmp)
#define strcasecmp stricmp
#endif

#if defined(_MSC_VER) && !defined(strncasecmp)
#define strncasecmp strnicmp
#endif

/* From dow.c */
timelib_sll timelib_day_of_week(timelib_sll y, timelib_sll m, timelib_sll d);
timelib_sll timelib_iso_day_of_week(timelib_sll y, timelib_sll m, timelib_sll d);
timelib_sll timelib_day_of_year(timelib_sll y, timelib_sll m, timelib_sll d);
timelib_sll timelib_daynr_from_weeknr(timelib_sll y, timelib_sll w, timelib_sll d);
timelib_sll timelib_days_in_month(timelib_sll y, timelib_sll m);
void timelib_isoweek_from_date(timelib_sll y, timelib_sll m, timelib_sll d, timelib_sll *iw, timelib_sll *iy);

/* From parse_date.re */
timelib_time *timelib_strtotime(char *s, int len, timelib_error_container **errors, const timelib_tzdb *tzdb);
void timelib_fill_holes(timelib_time *parsed, timelib_time *now, int options);
char *timelib_timezone_id_from_abbr(const char *abbr, long gmtoffset, int isdst);
const timelib_tz_lookup_table *timelib_timezone_abbreviations_list(void);

/* From tm2unixtime.c */
void timelib_update_ts(timelib_time* time, timelib_tzinfo* tzi);

/* From unixtime2tm.c */
int timelib_apply_localtime(timelib_time *t, unsigned int localtime);
void timelib_unixtime2gmt(timelib_time* tm, timelib_sll ts);
void timelib_unixtime2local(timelib_time *tm, timelib_sll ts);
void timelib_update_from_sse(timelib_time *tm);
void timelib_set_timezone(timelib_time *t, timelib_tzinfo *tz);

/* From parse_tz.c */
int timelib_timezone_id_is_valid(char *timezone, const timelib_tzdb *tzdb);
timelib_tzinfo *timelib_parse_tzfile(char *timezone, const timelib_tzdb *tzdb);
int timelib_timestamp_is_in_dst(timelib_sll ts, timelib_tzinfo *tz);
timelib_time_offset *timelib_get_time_zone_info(timelib_sll ts, timelib_tzinfo *tz);
timelib_sll timelib_get_current_offset(timelib_time *t);
void timelib_dump_tzinfo(timelib_tzinfo *tz);
const timelib_tzdb *timelib_builtin_db(void);
const timelib_tzdb_index_entry *timelib_timezone_builtin_identifiers_list(int *count);

/* From timelib.c */
timelib_tzinfo* timelib_tzinfo_ctor(char *name);
void timelib_time_tz_abbr_update(timelib_time* tm, char* tz_abbr);
void timelib_time_tz_name_update(timelib_time* tm, char* tz_name);
void timelib_tzinfo_dtor(timelib_tzinfo *tz);
timelib_tzinfo* timelib_tzinfo_clone(timelib_tzinfo *tz);

timelib_time* timelib_time_ctor(void);
void timelib_time_set_option(timelib_time* tm, int option, void* option_value);
void timelib_time_dtor(timelib_time* t);

timelib_time_offset* timelib_time_offset_ctor(void);
void timelib_time_offset_dtor(timelib_time_offset* t);

void timelib_error_container_dtor(timelib_error_container *errors);

signed long timelib_date_to_int(timelib_time *d, int *error);
void timelib_dump_date(timelib_time *d, int options);

void timelib_decimal_hour_to_hms(double h, int *hour, int *min, int *sec);

/* from astro.c */
double timelib_ts_to_juliandate(timelib_sll ts);
int timelib_astro_rise_set_altitude(timelib_time *time, double lon, double lat, double altit, int upper_limb, double *h_rise, double *h_set, timelib_sll *ts_rise, timelib_sll *ts_set, timelib_sll *ts_transit);

#endif
php/ext/phar/php_phar.h000064400000003374151730540640011053 0ustar00/*
  +----------------------------------------------------------------------+
  | phar php single-file executable PHP extension                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 2005-2018 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt.                                 |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Gregory Beaver <cellog@php.net>                             |
  |          Marcus Boerger <helly@php.net>                              |
  +----------------------------------------------------------------------+
*/

/* $Id$ */

#ifndef PHP_PHAR_H
#define PHP_PHAR_H

#define PHP_PHAR_VERSION "2.0.2"

#include "ext/standard/basic_functions.h"
extern zend_module_entry phar_module_entry;
#define phpext_phar_ptr &phar_module_entry

#ifdef PHP_WIN32
#define PHP_PHAR_API __declspec(dllexport)
#else
#define PHP_PHAR_API PHPAPI
#endif

PHP_PHAR_API int phar_resolve_alias(char *alias, int alias_len, char **filename, int *filename_len);

#endif /* PHP_PHAR_H */


/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/ext/gd/php_gd.h000064400000014003151730540640010142 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Rasmus Lerdorf <rasmus@php.net>                             |
   |          Stig Bakken <ssb@php.net>                                   |
   +----------------------------------------------------------------------+
*/

/* $Id: php_gd.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_GD_H
#define PHP_GD_H

#define HAVE_GDIMAGECREATEFROMPNG 1

#if HAVE_LIBTTF|HAVE_LIBFREETYPE
#define ENABLE_GD_TTF
#endif

#if HAVE_LIBGD

/* open_basedir and safe_mode checks */
#define PHP_GD_CHECK_OPEN_BASEDIR(filename, errormsg)                                   \
	if (!filename || php_check_open_basedir(filename TSRMLS_CC) ||                      \
		(PG(safe_mode) && !php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR))   \
	) {                                                                                 \
		php_error_docref(NULL TSRMLS_CC, E_WARNING, errormsg);                          \
		RETURN_FALSE;                                                                   \
	}

#define PHP_GDIMG_TYPE_GIF      1
#define PHP_GDIMG_TYPE_PNG      2
#define PHP_GDIMG_TYPE_JPG      3
#define PHP_GDIMG_TYPE_WBM      4
#define PHP_GDIMG_TYPE_XBM      5
#define PHP_GDIMG_TYPE_XPM      6
#define PHP_GDIMG_CONVERT_WBM   7
#define PHP_GDIMG_TYPE_GD       8
#define PHP_GDIMG_TYPE_GD2      9
#define PHP_GDIMG_TYPE_GD2PART 10

#ifdef PHP_WIN32
#define PHP_GD_API __declspec(dllexport)
#else
#define PHP_GD_API
#endif

PHPAPI extern const char php_sig_gif[3];
PHPAPI extern const char php_sig_jpg[3];
PHPAPI extern const char php_sig_png[3];

extern zend_module_entry gd_module_entry;
#define phpext_gd_ptr &gd_module_entry

/* gd.c functions */
PHP_MINFO_FUNCTION(gd);
PHP_MINIT_FUNCTION(gd);
#if HAVE_LIBT1 || HAVE_GD_FONTMUTEX
PHP_MSHUTDOWN_FUNCTION(gd);
#endif
#if HAVE_LIBGD20 && HAVE_GD_STRINGFT
PHP_RSHUTDOWN_FUNCTION(gd);
#endif

PHP_FUNCTION(gd_info);
PHP_FUNCTION(imagearc);
PHP_FUNCTION(imageellipse);
PHP_FUNCTION(imagechar);
PHP_FUNCTION(imagecharup);
PHP_FUNCTION(imageistruecolor);
PHP_FUNCTION(imagecolorallocate);
PHP_FUNCTION(imagepalettecopy);
PHP_FUNCTION(imagecolorat);
PHP_FUNCTION(imagecolorclosest);
PHP_FUNCTION(imagecolorclosesthwb);
PHP_FUNCTION(imagecolordeallocate);
PHP_FUNCTION(imagecolorresolve);
PHP_FUNCTION(imagecolorexact);
PHP_FUNCTION(imagecolorset);
PHP_FUNCTION(imagecolorstotal);
PHP_FUNCTION(imagecolorsforindex);
PHP_FUNCTION(imagecolortransparent);
PHP_FUNCTION(imagecopy);
PHP_FUNCTION(imagecopymerge);
PHP_FUNCTION(imagecopyresized);
PHP_FUNCTION(imagetypes);
PHP_FUNCTION(imagecreate);
PHP_FUNCTION(imageftbbox);
PHP_FUNCTION(imagefttext);

#ifdef HAVE_LIBGD20
PHP_FUNCTION(imagecreatetruecolor);
PHP_FUNCTION(imagetruecolortopalette);
PHP_FUNCTION(imagesetthickness);
PHP_FUNCTION(imagefilledellipse);
PHP_FUNCTION(imagefilledarc);
PHP_FUNCTION(imagealphablending);
PHP_FUNCTION(imagesavealpha);
PHP_FUNCTION(imagecolorallocatealpha);
PHP_FUNCTION(imagecolorresolvealpha);
PHP_FUNCTION(imagecolorclosestalpha);
PHP_FUNCTION(imagecolorexactalpha);
PHP_FUNCTION(imagecopyresampled);
#endif

#ifdef PHP_WIN32
PHP_FUNCTION(imagegrabwindow);
PHP_FUNCTION(imagegrabscreen);
#endif

#ifdef HAVE_GD_BUNDLED
PHP_FUNCTION(imagerotate);
PHP_FUNCTION(imageantialias);
#endif

PHP_FUNCTION(imagesetthickness);
PHP_FUNCTION(imagecopymergegray);
PHP_FUNCTION(imagesetbrush);
PHP_FUNCTION(imagesettile);
PHP_FUNCTION(imagesetstyle);

PHP_FUNCTION(imagecreatefromstring);
PHP_FUNCTION(imagecreatefromgif);
PHP_FUNCTION(imagecreatefromjpeg);
PHP_FUNCTION(imagecreatefromxbm);
PHP_FUNCTION(imagecreatefrompng);
PHP_FUNCTION(imagecreatefromwbmp);
PHP_FUNCTION(imagecreatefromgd);
PHP_FUNCTION(imagecreatefromgd2);
PHP_FUNCTION(imagecreatefromgd2part);
#if defined(HAVE_GD_XPM) && defined(HAVE_GD_BUNDLED)
PHP_FUNCTION(imagecreatefromxpm);
#endif

PHP_FUNCTION(imagegammacorrect);
PHP_FUNCTION(imagedestroy);
PHP_FUNCTION(imagefill);
PHP_FUNCTION(imagefilledpolygon);
PHP_FUNCTION(imagefilledrectangle);
PHP_FUNCTION(imagefilltoborder);
PHP_FUNCTION(imagefontwidth);
PHP_FUNCTION(imagefontheight);

PHP_FUNCTION(imagegif );
PHP_FUNCTION(imagejpeg );
PHP_FUNCTION(imagepng);
PHP_FUNCTION(imagewbmp);
PHP_FUNCTION(imagegd);
PHP_FUNCTION(imagegd2);

PHP_FUNCTION(imageinterlace);
PHP_FUNCTION(imageline);
PHP_FUNCTION(imageloadfont);
PHP_FUNCTION(imagepolygon);
PHP_FUNCTION(imagerectangle);
PHP_FUNCTION(imagesetpixel);
PHP_FUNCTION(imagestring);
PHP_FUNCTION(imagestringup);
PHP_FUNCTION(imagesx);
PHP_FUNCTION(imagesy);
PHP_FUNCTION(imagedashedline);
PHP_FUNCTION(imagettfbbox);
PHP_FUNCTION(imagettftext);
PHP_FUNCTION(imagepsloadfont);
/*
PHP_FUNCTION(imagepscopyfont);
*/
PHP_FUNCTION(imagepsfreefont);
PHP_FUNCTION(imagepsencodefont);
PHP_FUNCTION(imagepsextendfont);
PHP_FUNCTION(imagepsslantfont);
PHP_FUNCTION(imagepstext);
PHP_FUNCTION(imagepsbbox);

PHP_FUNCTION(jpeg2wbmp);
PHP_FUNCTION(png2wbmp);
PHP_FUNCTION(image2wbmp);

#if HAVE_GD_BUNDLED
PHP_FUNCTION(imagelayereffect);
PHP_FUNCTION(imagecolormatch);
PHP_FUNCTION(imagefilter);
PHP_FUNCTION(imageconvolution);
PHP_FUNCTION(imagexbm);
#endif

PHP_GD_API int phpi_get_le_gd(void);

#else

#define phpext_gd_ptr NULL

#endif

#endif /* PHP_GD_H */
php/ext/gd/gd_compat.h000064400000000457151730540650010647 0ustar00#ifndef GD_COMPAT_H
#define GD_COMPAT_H 1

#ifndef HAVE_GD_BUNDLED
/* from gd_compat.c */
const char * gdPngGetVersionString();
const char * gdJpegGetVersionString();
int gdJpegGetVersionInt();
#endif

/* from gd_compat.c of libgd/gd_security.c */
int overflow2(int a, int b);

#endif /* GD_COMPAT_H */
php/ext/gd/gdcache.h000064400000005460151730540650010267 0ustar00/*
 * $Id: gdcache.h 147409 2003-12-28 21:08:46Z iliaa $
 *
 * Caches of pointers to user structs in which the least-recently-used
 * element is replaced in the event of a cache miss after the cache has
 * reached a given size.
 *
 * John Ellson  (ellson@lucent.com)  Oct 31, 1997
 *
 * Test this with:
 *		 gcc -o gdcache -g -Wall -DTEST gdcache.c
 *
 * The cache is implemented by a singly-linked list of elements
 * each containing a pointer to a user struct that is being managed by
 * the cache.
 *
 * The head structure has a pointer to the most-recently-used
 * element, and elements are moved to this position in the list each
 * time they are used.  The head also contains pointers to three
 * user defined functions:
 *		- a function to test if a cached userdata matches some keydata
 *		- a function to provide a new userdata struct to the cache
 *          if there has been a cache miss.
 *		- a function to release a userdata struct when it is
 *          no longer being managed by the cache
 *
 * In the event of a cache miss the cache is allowed to grow up to
 * a specified maximum size.  After the maximum size is reached then
 * the least-recently-used element is discarded to make room for the
 * new.  The most-recently-returned value is always left at the
 * beginning of the list after retrieval.
 *
 * In the current implementation the cache is traversed by a linear
 * search from most-recent to least-recent.  This linear search
 * probably limits the usefulness of this implementation to cache
 * sizes of a few tens of elements.
 */

/*********************************************************/
/* header                                                */
/*********************************************************/

#if (!defined(_OSD_POSIX) && !defined(__FreeBSD__)) && HAVE_MALLOC_H
#include <malloc.h>
#else
#include <stdlib.h> /* BS2000/OSD defines malloc() & friends in stdlib.h */
#endif
#ifndef NULL
#define NULL (void *)0
#endif

/* user defined function templates */
typedef int (*gdCacheTestFn_t)(void *userdata, void *keydata);
typedef void *(*gdCacheFetchFn_t)(char **error, void *keydata);
typedef void (*gdCacheReleaseFn_t)(void *userdata);

/* element structure */
typedef struct gdCache_element_s gdCache_element_t;
struct gdCache_element_s {
	gdCache_element_t	*next;
	void			*userdata;
};

/* head structure */
typedef struct gdCache_head_s gdCache_head_t;
struct gdCache_head_s {
	gdCache_element_t	*mru;
	int					size;
	char				*error;
	gdCacheTestFn_t		gdCacheTest;
	gdCacheFetchFn_t	gdCacheFetch;
	gdCacheReleaseFn_t	gdCacheRelease;
};

/* function templates */
gdCache_head_t *
gdCacheCreate(
	int					size,
	gdCacheTestFn_t		gdCacheTest,
	gdCacheFetchFn_t	gdCacheFetch,
	gdCacheReleaseFn_t	gdCacheRelease );

void
gdCacheDelete( gdCache_head_t *head );

void *
gdCacheGet( gdCache_head_t *head, void *keydata );
php/ext/gd/libgd/jisx0208.h000064400000213266151730540660011267 0ustar00#ifndef JISX0208_H
#define JISX0208_H
/* This file was derived from "src/VF_Ftype.c" in VFlib2-2.24.2
   by Dr. Kakugawa */

/* JIS -> Unicode mapping table */
static unsigned short UnicodeTbl[][94] = {
{ /* category 01 */
0x0000, 0x3001, 0x3002, 0xFF0C, 0xFF0E, 0x30FB, 0xFF1A, 0xFF1B,
0xFF1F, 0xFF01, 0x309B, 0x309C, 0x00B4, 0xFF40, 0x00A8, 0xFF3E,
0xFFE3, 0xFF3F, 0x30FD, 0x30FE, 0x309D, 0x309E, 0x3003, 0x4EDD,
0x3005, 0x3006, 0x3007, 0x30FC, 0x2015, 0x2010, 0xFF0F, 0xFF3C,
0xFF5E, 0x2225, 0xFF5C, 0x2026, 0x2025, 0x2018, 0x2019, 0x201C,
0x201D, 0xFF08, 0xFF09, 0x3014, 0x3015, 0xFF3B, 0xFF3D, 0xFF5B,
0xFF5D, 0x3008, 0x3009, 0x300A, 0x300B, 0x300C, 0x300D, 0x300E,
0x300F, 0x3010, 0x3011, 0xFF0B, 0xFF0D, 0x00B1, 0x00D7, 0x00F7,
0xFF1D, 0x2260, 0xFF1C, 0xFF1E, 0x2266, 0x2267, 0x221E, 0x2234,
0x2642, 0x2640, 0x00B0, 0x2032, 0x2033, 0x2103, 0xFFE5, 0xFF04,
0xFFE0, 0xFFE1, 0xFF05, 0xFF03, 0xFF06, 0xFF0A, 0xFF20, 0x00A7,
0x2606, 0x2605, 0x25CB, 0x25CF, 0x25CE, 0x25C7},
{ /* category 02 */
0x25C6, 0x25A1, 0x25A0, 0x25B3, 0x25B2, 0x25BD, 0x25BC, 0x203B,
0x3012, 0x2192, 0x2190, 0x2191, 0x2193, 0x3013, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x2208, 0x220B, 0x2286, 0x2287, 0x2282, 0x2283, 0x222A,
0x2229, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x2227, 0x2228, 0xFFE2, 0x21D2, 0x21D4, 0x2200, 0x2203,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x2220, 0x22A5, 0x2312, 0x2202, 0x2207,
0x2261, 0x2252, 0x226A, 0x226B, 0x221A, 0x223D, 0x221D, 0x2235,
0x222B, 0x222C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x212B, 0x2030, 0x266F, 0x266D, 0x266A, 0x2020, 0x2021, /**/
0x00B6, 0x0000, 0x0000, 0x0000, 0x0000, 0x25EF},
{ /* category 03 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFF10,
0xFF11, 0xFF12, 0xFF13, 0xFF14, 0xFF15, 0xFF16, 0xFF17, 0xFF18,
0xFF19, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28,
0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30,
0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38,
0xFF39, 0xFF3A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48,
0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50,
0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58,
0xFF59, 0xFF5A, 0x0000, 0x0000, 0x0000, 0x0000},
{ /* category 04 */
0x3041, 0x3042, 0x3043, 0x3044, 0x3045, 0x3046, 0x3047, 0x3048,
0x3049, 0x304A, 0x304B, 0x304C, 0x304D, 0x304E, 0x304F, 0x3050,
0x3051, 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057, 0x3058,
0x3059, 0x305A, 0x305B, 0x305C, 0x305D, 0x305E, 0x305F, 0x3060,
0x3061, 0x3062, 0x3063, 0x3064, 0x3065, 0x3066, 0x3067, 0x3068,
0x3069, 0x306A, 0x306B, 0x306C, 0x306D, 0x306E, 0x306F, 0x3070,
0x3071, 0x3072, 0x3073, 0x3074, 0x3075, 0x3076, 0x3077, 0x3078,
0x3079, 0x307A, 0x307B, 0x307C, 0x307D, 0x307E, 0x307F, 0x3080,
0x3081, 0x3082, 0x3083, 0x3084, 0x3085, 0x3086, 0x3087, 0x3088,
0x3089, 0x308A, 0x308B, 0x308C, 0x308D, 0x308E, 0x308F, 0x3090,
0x3091, 0x3092, 0x3093, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
{ /* category 05 */
0x30A1, 0x30A2, 0x30A3, 0x30A4, 0x30A5, 0x30A6, 0x30A7, 0x30A8,
0x30A9, 0x30AA, 0x30AB, 0x30AC, 0x30AD, 0x30AE, 0x30AF, 0x30B0,
0x30B1, 0x30B2, 0x30B3, 0x30B4, 0x30B5, 0x30B6, 0x30B7, 0x30B8,
0x30B9, 0x30BA, 0x30BB, 0x30BC, 0x30BD, 0x30BE, 0x30BF, 0x30C0,
0x30C1, 0x30C2, 0x30C3, 0x30C4, 0x30C5, 0x30C6, 0x30C7, 0x30C8,
0x30C9, 0x30CA, 0x30CB, 0x30CC, 0x30CD, 0x30CE, 0x30CF, 0x30D0,
0x30D1, 0x30D2, 0x30D3, 0x30D4, 0x30D5, 0x30D6, 0x30D7, 0x30D8,
0x30D9, 0x30DA, 0x30DB, 0x30DC, 0x30DD, 0x30DE, 0x30DF, 0x30E0,
0x30E1, 0x30E2, 0x30E3, 0x30E4, 0x30E5, 0x30E6, 0x30E7, 0x30E8,
0x30E9, 0x30EA, 0x30EB, 0x30EC, 0x30ED, 0x30EE, 0x30EF, 0x30F0,
0x30F1, 0x30F2, 0x30F3, 0x30F4, 0x30F5, 0x30F6, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
{ /* category 06 */
0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398,
0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0,
0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8,
0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0,
0x03C1, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
{ /* category 07 */
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0401, 0x0416,
0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E,
0x041F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426,
0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E,
0x042F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0451, 0x0436,
0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E,
0x043F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446,
0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E,
0x044F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
{ /* category 08 */
0x2500, 0x2502, 0x250C, 0x2510, 0x2518, 0x2514, 0x251C, 0x252C,
0x2524, 0x2534, 0x253C, 0x2501, 0x2503, 0x250F, 0x2513, 0x251B,
0x2517, 0x2523, 0x2533, 0x252B, 0x253B, 0x254B, 0x2520, 0x252F,
0x2528, 0x2537, 0x253F, 0x251D, 0x2530, 0x2525, 0x2538, 0x2542,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
{ /* category 09 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
{ /* category 10 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
{ /* category 11 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
{ /* category 12 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
{ /* category 13 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
{ /* category 14 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
{ /* category 15 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
{ /* category 16 */
0x4E9C, 0x5516, 0x5A03, 0x963F, 0x54C0, 0x611B, 0x6328, 0x59F6,
0x9022, 0x8475, 0x831C, 0x7A50, 0x60AA, 0x63E1, 0x6E25, 0x65ED,
0x8466, 0x82A6, 0x9BF5, 0x6893, 0x5727, 0x65A1, 0x6271, 0x5B9B,
0x59D0, 0x867B, 0x98F4, 0x7D62, 0x7DBE, 0x9B8E, 0x6216, 0x7C9F,
0x88B7, 0x5B89, 0x5EB5, 0x6309, 0x6697, 0x6848, 0x95C7, 0x978D,
0x674F, 0x4EE5, 0x4F0A, 0x4F4D, 0x4F9D, 0x5049, 0x56F2, 0x5937,
0x59D4, 0x5A01, 0x5C09, 0x60DF, 0x610F, 0x6170, 0x6613, 0x6905,
0x70BA, 0x754F, 0x7570, 0x79FB, 0x7DAD, 0x7DEF, 0x80C3, 0x840E,
0x8863, 0x8B02, 0x9055, 0x907A, 0x533B, 0x4E95, 0x4EA5, 0x57DF,
0x80B2, 0x90C1, 0x78EF, 0x4E00, 0x58F1, 0x6EA2, 0x9038, 0x7A32,
0x8328, 0x828B, 0x9C2F, 0x5141, 0x5370, 0x54BD, 0x54E1, 0x56E0,
0x59FB, 0x5F15, 0x98F2, 0x6DEB, 0x80E4, 0x852D},
{ /* category 17 */
0x9662, 0x9670, 0x96A0, 0x97FB, 0x540B, 0x53F3, 0x5B87, 0x70CF,
0x7FBD, 0x8FC2, 0x96E8, 0x536F, 0x9D5C, 0x7ABA, 0x4E11, 0x7893,
0x81FC, 0x6E26, 0x5618, 0x5504, 0x6B1D, 0x851A, 0x9C3B, 0x59E5,
0x53A9, 0x6D66, 0x74DC, 0x958F, 0x5642, 0x4E91, 0x904B, 0x96F2,
0x834F, 0x990C, 0x53E1, 0x55B6, 0x5B30, 0x5F71, 0x6620, 0x66F3,
0x6804, 0x6C38, 0x6CF3, 0x6D29, 0x745B, 0x76C8, 0x7A4E, 0x9834,
0x82F1, 0x885B, 0x8A60, 0x92ED, 0x6DB2, 0x75AB, 0x76CA, 0x99C5,
0x60A6, 0x8B01, 0x8D8A, 0x95B2, 0x698E, 0x53AD, 0x5186, 0x5712,
0x5830, 0x5944, 0x5BB4, 0x5EF6, 0x6028, 0x63A9, 0x63F4, 0x6CBF,
0x6F14, 0x708E, 0x7114, 0x7159, 0x71D5, 0x733F, 0x7E01, 0x8276,
0x82D1, 0x8597, 0x9060, 0x925B, 0x9D1B, 0x5869, 0x65BC, 0x6C5A,
0x7525, 0x51F9, 0x592E, 0x5965, 0x5F80, 0x5FDC},
{ /* category 18 */
0x62BC, 0x65FA, 0x6A2A, 0x6B27, 0x6BB4, 0x738B, 0x7FC1, 0x8956,
0x9D2C, 0x9D0E, 0x9EC4, 0x5CA1, 0x6C96, 0x837B, 0x5104, 0x5C4B,
0x61B6, 0x81C6, 0x6876, 0x7261, 0x4E59, 0x4FFA, 0x5378, 0x6069,
0x6E29, 0x7A4F, 0x97F3, 0x4E0B, 0x5316, 0x4EEE, 0x4F55, 0x4F3D,
0x4FA1, 0x4F73, 0x52A0, 0x53EF, 0x5609, 0x590F, 0x5AC1, 0x5BB6,
0x5BE1, 0x79D1, 0x6687, 0x679C, 0x67B6, 0x6B4C, 0x6CB3, 0x706B,
0x73C2, 0x798D, 0x79BE, 0x7A3C, 0x7B87, 0x82B1, 0x82DB, 0x8304,
0x8377, 0x83EF, 0x83D3, 0x8766, 0x8AB2, 0x5629, 0x8CA8, 0x8FE6,
0x904E, 0x971E, 0x868A, 0x4FC4, 0x5CE8, 0x6211, 0x7259, 0x753B,
0x81E5, 0x82BD, 0x86FE, 0x8CC0, 0x96C5, 0x9913, 0x99D5, 0x4ECB,
0x4F1A, 0x89E3, 0x56DE, 0x584A, 0x58CA, 0x5EFB, 0x5FEB, 0x602A,
0x6094, 0x6062, 0x61D0, 0x6212, 0x62D0, 0x6539},
{ /* category 19 */
0x9B41, 0x6666, 0x68B0, 0x6D77, 0x7070, 0x754C, 0x7686, 0x7D75,
0x82A5, 0x87F9, 0x958B, 0x968E, 0x8C9D, 0x51F1, 0x52BE, 0x5916,
0x54B3, 0x5BB3, 0x5D16, 0x6168, 0x6982, 0x6DAF, 0x788D, 0x84CB,
0x8857, 0x8A72, 0x93A7, 0x9AB8, 0x6D6C, 0x99A8, 0x86D9, 0x57A3,
0x67FF, 0x86CE, 0x920E, 0x5283, 0x5687, 0x5404, 0x5ED3, 0x62E1,
0x64B9, 0x683C, 0x6838, 0x6BBB, 0x7372, 0x78BA, 0x7A6B, 0x899A,
0x89D2, 0x8D6B, 0x8F03, 0x90ED, 0x95A3, 0x9694, 0x9769, 0x5B66,
0x5CB3, 0x697D, 0x984D, 0x984E, 0x639B, 0x7B20, 0x6A2B, 0x6A7F,
0x68B6, 0x9C0D, 0x6F5F, 0x5272, 0x559D, 0x6070, 0x62EC, 0x6D3B,
0x6E07, 0x6ED1, 0x845B, 0x8910, 0x8F44, 0x4E14, 0x9C39, 0x53F6,
0x691B, 0x6A3A, 0x9784, 0x682A, 0x515C, 0x7AC3, 0x84B2, 0x91DC,
0x938C, 0x565B, 0x9D28, 0x6822, 0x8305, 0x8431},
{ /* category 20 */
0x7CA5, 0x5208, 0x82C5, 0x74E6, 0x4E7E, 0x4F83, 0x51A0, 0x5BD2,
0x520A, 0x52D8, 0x52E7, 0x5DFB, 0x559A, 0x582A, 0x59E6, 0x5B8C,
0x5B98, 0x5BDB, 0x5E72, 0x5E79, 0x60A3, 0x611F, 0x6163, 0x61BE,
0x63DB, 0x6562, 0x67D1, 0x6853, 0x68FA, 0x6B3E, 0x6B53, 0x6C57,
0x6F22, 0x6F97, 0x6F45, 0x74B0, 0x7518, 0x76E3, 0x770B, 0x7AFF,
0x7BA1, 0x7C21, 0x7DE9, 0x7F36, 0x7FF0, 0x809D, 0x8266, 0x839E,
0x89B3, 0x8ACC, 0x8CAB, 0x9084, 0x9451, 0x9593, 0x9591, 0x95A2,
0x9665, 0x97D3, 0x9928, 0x8218, 0x4E38, 0x542B, 0x5CB8, 0x5DCC,
0x73A9, 0x764C, 0x773C, 0x5CA9, 0x7FEB, 0x8D0B, 0x96C1, 0x9811,
0x9854, 0x9858, 0x4F01, 0x4F0E, 0x5371, 0x559C, 0x5668, 0x57FA,
0x5947, 0x5B09, 0x5BC4, 0x5C90, 0x5E0C, 0x5E7E, 0x5FCC, 0x63EE,
0x673A, 0x65D7, 0x65E2, 0x671F, 0x68CB, 0x68C4},
{ /* category 21 */
0x6A5F, 0x5E30, 0x6BC5, 0x6C17, 0x6C7D, 0x757F, 0x7948, 0x5B63,
0x7A00, 0x7D00, 0x5FBD, 0x898F, 0x8A18, 0x8CB4, 0x8D77, 0x8ECC,
0x8F1D, 0x98E2, 0x9A0E, 0x9B3C, 0x4E80, 0x507D, 0x5100, 0x5993,
0x5B9C, 0x622F, 0x6280, 0x64EC, 0x6B3A, 0x72A0, 0x7591, 0x7947,
0x7FA9, 0x87FB, 0x8ABC, 0x8B70, 0x63AC, 0x83CA, 0x97A0, 0x5409,
0x5403, 0x55AB, 0x6854, 0x6A58, 0x8A70, 0x7827, 0x6775, 0x9ECD,
0x5374, 0x5BA2, 0x811A, 0x8650, 0x9006, 0x4E18, 0x4E45, 0x4EC7,
0x4F11, 0x53CA, 0x5438, 0x5BAE, 0x5F13, 0x6025, 0x6551, 0x673D,
0x6C42, 0x6C72, 0x6CE3, 0x7078, 0x7403, 0x7A76, 0x7AAE, 0x7B08,
0x7D1A, 0x7CFE, 0x7D66, 0x65E7, 0x725B, 0x53BB, 0x5C45, 0x5DE8,
0x62D2, 0x62E0, 0x6319, 0x6E20, 0x865A, 0x8A31, 0x8DDD, 0x92F8,
0x6F01, 0x79A6, 0x9B5A, 0x4EA8, 0x4EAB, 0x4EAC},
{ /* category 22 */
0x4F9B, 0x4FA0, 0x50D1, 0x5147, 0x7AF6, 0x5171, 0x51F6, 0x5354,
0x5321, 0x537F, 0x53EB, 0x55AC, 0x5883, 0x5CE1, 0x5F37, 0x5F4A,
0x602F, 0x6050, 0x606D, 0x631F, 0x6559, 0x6A4B, 0x6CC1, 0x72C2,
0x72ED, 0x77EF, 0x80F8, 0x8105, 0x8208, 0x854E, 0x90F7, 0x93E1,
0x97FF, 0x9957, 0x9A5A, 0x4EF0, 0x51DD, 0x5C2D, 0x6681, 0x696D,
0x5C40, 0x66F2, 0x6975, 0x7389, 0x6850, 0x7C81, 0x50C5, 0x52E4,
0x5747, 0x5DFE, 0x9326, 0x65A4, 0x6B23, 0x6B3D, 0x7434, 0x7981,
0x79BD, 0x7B4B, 0x7DCA, 0x82B9, 0x83CC, 0x887F, 0x895F, 0x8B39,
0x8FD1, 0x91D1, 0x541F, 0x9280, 0x4E5D, 0x5036, 0x53E5, 0x533A,
0x72D7, 0x7396, 0x77E9, 0x82E6, 0x8EAF, 0x99C6, 0x99C8, 0x99D2,
0x5177, 0x611A, 0x865E, 0x55B0, 0x7A7A, 0x5076, 0x5BD3, 0x9047,
0x9685, 0x4E32, 0x6ADB, 0x91E7, 0x5C51, 0x5C48},
{ /* category 23 */
0x6398, 0x7A9F, 0x6C93, 0x9774, 0x8F61, 0x7AAA, 0x718A, 0x9688,
0x7C82, 0x6817, 0x7E70, 0x6851, 0x936C, 0x52F2, 0x541B, 0x85AB,
0x8A13, 0x7FA4, 0x8ECD, 0x90E1, 0x5366, 0x8888, 0x7941, 0x4FC2,
0x50BE, 0x5211, 0x5144, 0x5553, 0x572D, 0x73EA, 0x578B, 0x5951,
0x5F62, 0x5F84, 0x6075, 0x6176, 0x6167, 0x61A9, 0x63B2, 0x643A,
0x656C, 0x666F, 0x6842, 0x6E13, 0x7566, 0x7A3D, 0x7CFB, 0x7D4C,
0x7D99, 0x7E4B, 0x7F6B, 0x830E, 0x834A, 0x86CD, 0x8A08, 0x8A63,
0x8B66, 0x8EFD, 0x981A, 0x9D8F, 0x82B8, 0x8FCE, 0x9BE8, 0x5287,
0x621F, 0x6483, 0x6FC0, 0x9699, 0x6841, 0x5091, 0x6B20, 0x6C7A,
0x6F54, 0x7A74, 0x7D50, 0x8840, 0x8A23, 0x6708, 0x4EF6, 0x5039,
0x5026, 0x5065, 0x517C, 0x5238, 0x5263, 0x55A7, 0x570F, 0x5805,
0x5ACC, 0x5EFA, 0x61B2, 0x61F8, 0x62F3, 0x6372},
{ /* category 24 */
0x691C, 0x6A29, 0x727D, 0x72AC, 0x732E, 0x7814, 0x786F, 0x7D79,
0x770C, 0x80A9, 0x898B, 0x8B19, 0x8CE2, 0x8ED2, 0x9063, 0x9375,
0x967A, 0x9855, 0x9A13, 0x9E78, 0x5143, 0x539F, 0x53B3, 0x5E7B,
0x5F26, 0x6E1B, 0x6E90, 0x7384, 0x73FE, 0x7D43, 0x8237, 0x8A00,
0x8AFA, 0x9650, 0x4E4E, 0x500B, 0x53E4, 0x547C, 0x56FA, 0x59D1,
0x5B64, 0x5DF1, 0x5EAB, 0x5F27, 0x6238, 0x6545, 0x67AF, 0x6E56,
0x72D0, 0x7CCA, 0x88B4, 0x80A1, 0x80E1, 0x83F0, 0x864E, 0x8A87,
0x8DE8, 0x9237, 0x96C7, 0x9867, 0x9F13, 0x4E94, 0x4E92, 0x4F0D,
0x5348, 0x5449, 0x543E, 0x5A2F, 0x5F8C, 0x5FA1, 0x609F, 0x68A7,
0x6A8E, 0x745A, 0x7881, 0x8A9E, 0x8AA4, 0x8B77, 0x9190, 0x4E5E,
0x9BC9, 0x4EA4, 0x4F7C, 0x4FAF, 0x5019, 0x5016, 0x5149, 0x516C,
0x529F, 0x52B9, 0x52FE, 0x539A, 0x53E3, 0x5411},
{ /* category 25 */
0x540E, 0x5589, 0x5751, 0x57A2, 0x597D, 0x5B54, 0x5B5D, 0x5B8F,
0x5DE5, 0x5DE7, 0x5DF7, 0x5E78, 0x5E83, 0x5E9A, 0x5EB7, 0x5F18,
0x6052, 0x614C, 0x6297, 0x62D8, 0x63A7, 0x653B, 0x6602, 0x6643,
0x66F4, 0x676D, 0x6821, 0x6897, 0x69CB, 0x6C5F, 0x6D2A, 0x6D69,
0x6E2F, 0x6E9D, 0x7532, 0x7687, 0x786C, 0x7A3F, 0x7CE0, 0x7D05,
0x7D18, 0x7D5E, 0x7DB1, 0x8015, 0x8003, 0x80AF, 0x80B1, 0x8154,
0x818F, 0x822A, 0x8352, 0x884C, 0x8861, 0x8B1B, 0x8CA2, 0x8CFC,
0x90CA, 0x9175, 0x9271, 0x783F, 0x92FC, 0x95A4, 0x964D, 0x9805,
0x9999, 0x9AD8, 0x9D3B, 0x525B, 0x52AB, 0x53F7, 0x5408, 0x58D5,
0x62F7, 0x6FE0, 0x8C6A, 0x8F5F, 0x9EB9, 0x514B, 0x523B, 0x544A,
0x56FD, 0x7A40, 0x9177, 0x9D60, 0x9ED2, 0x7344, 0x6F09, 0x8170,
0x7511, 0x5FFD, 0x60DA, 0x9AA8, 0x72DB, 0x8FBC},
{ /* category 26 */
0x6B64, 0x9803, 0x4ECA, 0x56F0, 0x5764, 0x58BE, 0x5A5A, 0x6068,
0x61C7, 0x660F, 0x6606, 0x6839, 0x68B1, 0x6DF7, 0x75D5, 0x7D3A,
0x826E, 0x9B42, 0x4E9B, 0x4F50, 0x53C9, 0x5506, 0x5D6F, 0x5DE6,
0x5DEE, 0x67FB, 0x6C99, 0x7473, 0x7802, 0x8A50, 0x9396, 0x88DF,
0x5750, 0x5EA7, 0x632B, 0x50B5, 0x50AC, 0x518D, 0x6700, 0x54C9,
0x585E, 0x59BB, 0x5BB0, 0x5F69, 0x624D, 0x63A1, 0x683D, 0x6B73,
0x6E08, 0x707D, 0x91C7, 0x7280, 0x7815, 0x7826, 0x796D, 0x658E,
0x7D30, 0x83DC, 0x88C1, 0x8F09, 0x969B, 0x5264, 0x5728, 0x6750,
0x7F6A, 0x8CA1, 0x51B4, 0x5742, 0x962A, 0x583A, 0x698A, 0x80B4,
0x54B2, 0x5D0E, 0x57FC, 0x7895, 0x9DFA, 0x4F5C, 0x524A, 0x548B,
0x643E, 0x6628, 0x6714, 0x67F5, 0x7A84, 0x7B56, 0x7D22, 0x932F,
0x685C, 0x9BAD, 0x7B39, 0x5319, 0x518A, 0x5237},
{ /* category 27 */
0x5BDF, 0x62F6, 0x64AE, 0x64E6, 0x672D, 0x6BBA, 0x85A9, 0x96D1,
0x7690, 0x9BD6, 0x634C, 0x9306, 0x9BAB, 0x76BF, 0x6652, 0x4E09,
0x5098, 0x53C2, 0x5C71, 0x60E8, 0x6492, 0x6563, 0x685F, 0x71E6,
0x73CA, 0x7523, 0x7B97, 0x7E82, 0x8695, 0x8B83, 0x8CDB, 0x9178,
0x9910, 0x65AC, 0x66AB, 0x6B8B, 0x4ED5, 0x4ED4, 0x4F3A, 0x4F7F,
0x523A, 0x53F8, 0x53F2, 0x55E3, 0x56DB, 0x58EB, 0x59CB, 0x59C9,
0x59FF, 0x5B50, 0x5C4D, 0x5E02, 0x5E2B, 0x5FD7, 0x601D, 0x6307,
0x652F, 0x5B5C, 0x65AF, 0x65BD, 0x65E8, 0x679D, 0x6B62, 0x6B7B,
0x6C0F, 0x7345, 0x7949, 0x79C1, 0x7CF8, 0x7D19, 0x7D2B, 0x80A2,
0x8102, 0x81F3, 0x8996, 0x8A5E, 0x8A69, 0x8A66, 0x8A8C, 0x8AEE,
0x8CC7, 0x8CDC, 0x96CC, 0x98FC, 0x6B6F, 0x4E8B, 0x4F3C, 0x4F8D,
0x5150, 0x5B57, 0x5BFA, 0x6148, 0x6301, 0x6642},
{ /* category 28 */
0x6B21, 0x6ECB, 0x6CBB, 0x723E, 0x74BD, 0x75D4, 0x78C1, 0x793A,
0x800C, 0x8033, 0x81EA, 0x8494, 0x8F9E, 0x6C50, 0x9E7F, 0x5F0F,
0x8B58, 0x9D2B, 0x7AFA, 0x8EF8, 0x5B8D, 0x96EB, 0x4E03, 0x53F1,
0x57F7, 0x5931, 0x5AC9, 0x5BA4, 0x6089, 0x6E7F, 0x6F06, 0x75BE,
0x8CEA, 0x5B9F, 0x8500, 0x7BE0, 0x5072, 0x67F4, 0x829D, 0x5C61,
0x854A, 0x7E1E, 0x820E, 0x5199, 0x5C04, 0x6368, 0x8D66, 0x659C,
0x716E, 0x793E, 0x7D17, 0x8005, 0x8B1D, 0x8ECA, 0x906E, 0x86C7,
0x90AA, 0x501F, 0x52FA, 0x5C3A, 0x6753, 0x707C, 0x7235, 0x914C,
0x91C8, 0x932B, 0x82E5, 0x5BC2, 0x5F31, 0x60F9, 0x4E3B, 0x53D6,
0x5B88, 0x624B, 0x6731, 0x6B8A, 0x72E9, 0x73E0, 0x7A2E, 0x816B,
0x8DA3, 0x9152, 0x9996, 0x5112, 0x53D7, 0x546A, 0x5BFF, 0x6388,
0x6A39, 0x7DAC, 0x9700, 0x56DA, 0x53CE, 0x5468},
{ /* category 29 */
0x5B97, 0x5C31, 0x5DDE, 0x4FEE, 0x6101, 0x62FE, 0x6D32, 0x79C0,
0x79CB, 0x7D42, 0x7E4D, 0x7FD2, 0x81ED, 0x821F, 0x8490, 0x8846,
0x8972, 0x8B90, 0x8E74, 0x8F2F, 0x9031, 0x914B, 0x916C, 0x96C6,
0x919C, 0x4EC0, 0x4F4F, 0x5145, 0x5341, 0x5F93, 0x620E, 0x67D4,
0x6C41, 0x6E0B, 0x7363, 0x7E26, 0x91CD, 0x9283, 0x53D4, 0x5919,
0x5BBF, 0x6DD1, 0x795D, 0x7E2E, 0x7C9B, 0x587E, 0x719F, 0x51FA,
0x8853, 0x8FF0, 0x4FCA, 0x5CFB, 0x6625, 0x77AC, 0x7AE3, 0x821C,
0x99FF, 0x51C6, 0x5FAA, 0x65EC, 0x696F, 0x6B89, 0x6DF3, 0x6E96,
0x6F64, 0x76FE, 0x7D14, 0x5DE1, 0x9075, 0x9187, 0x9806, 0x51E6,
0x521D, 0x6240, 0x6691, 0x66D9, 0x6E1A, 0x5EB6, 0x7DD2, 0x7F72,
0x66F8, 0x85AF, 0x85F7, 0x8AF8, 0x52A9, 0x53D9, 0x5973, 0x5E8F,
0x5F90, 0x6055, 0x92E4, 0x9664, 0x50B7, 0x511F},
{ /* category 30 */
0x52DD, 0x5320, 0x5347, 0x53EC, 0x54E8, 0x5546, 0x5531, 0x5617,
0x5968, 0x59BE, 0x5A3C, 0x5BB5, 0x5C06, 0x5C0F, 0x5C11, 0x5C1A,
0x5E84, 0x5E8A, 0x5EE0, 0x5F70, 0x627F, 0x6284, 0x62DB, 0x638C,
0x6377, 0x6607, 0x660C, 0x662D, 0x6676, 0x677E, 0x68A2, 0x6A1F,
0x6A35, 0x6CBC, 0x6D88, 0x6E09, 0x6E58, 0x713C, 0x7126, 0x7167,
0x75C7, 0x7701, 0x785D, 0x7901, 0x7965, 0x79F0, 0x7AE0, 0x7B11,
0x7CA7, 0x7D39, 0x8096, 0x83D6, 0x848B, 0x8549, 0x885D, 0x88F3,
0x8A1F, 0x8A3C, 0x8A54, 0x8A73, 0x8C61, 0x8CDE, 0x91A4, 0x9266,
0x937E, 0x9418, 0x969C, 0x9798, 0x4E0A, 0x4E08, 0x4E1E, 0x4E57,
0x5197, 0x5270, 0x57CE, 0x5834, 0x58CC, 0x5B22, 0x5E38, 0x60C5,
0x64FE, 0x6761, 0x6756, 0x6D44, 0x72B6, 0x7573, 0x7A63, 0x84B8,
0x8B72, 0x91B8, 0x9320, 0x5631, 0x57F4, 0x98FE},
{ /* category 31 */
0x62ED, 0x690D, 0x6B96, 0x71ED, 0x7E54, 0x8077, 0x8272, 0x89E6,
0x98DF, 0x8755, 0x8FB1, 0x5C3B, 0x4F38, 0x4FE1, 0x4FB5, 0x5507,
0x5A20, 0x5BDD, 0x5BE9, 0x5FC3, 0x614E, 0x632F, 0x65B0, 0x664B,
0x68EE, 0x699B, 0x6D78, 0x6DF1, 0x7533, 0x75B9, 0x771F, 0x795E,
0x79E6, 0x7D33, 0x81E3, 0x82AF, 0x85AA, 0x89AA, 0x8A3A, 0x8EAB,
0x8F9B, 0x9032, 0x91DD, 0x9707, 0x4EBA, 0x4EC1, 0x5203, 0x5875,
0x58EC, 0x5C0B, 0x751A, 0x5C3D, 0x814E, 0x8A0A, 0x8FC5, 0x9663,
0x976D, 0x7B25, 0x8ACF, 0x9808, 0x9162, 0x56F3, 0x53A8, 0x9017,
0x5439, 0x5782, 0x5E25, 0x63A8, 0x6C34, 0x708A, 0x7761, 0x7C8B,
0x7FE0, 0x8870, 0x9042, 0x9154, 0x9310, 0x9318, 0x968F, 0x745E,
0x9AC4, 0x5D07, 0x5D69, 0x6570, 0x67A2, 0x8DA8, 0x96DB, 0x636E,
0x6749, 0x6919, 0x83C5, 0x9817, 0x96C0, 0x88FE},
{ /* category 32 */
0x6F84, 0x647A, 0x5BF8, 0x4E16, 0x702C, 0x755D, 0x662F, 0x51C4,
0x5236, 0x52E2, 0x59D3, 0x5F81, 0x6027, 0x6210, 0x653F, 0x6574,
0x661F, 0x6674, 0x68F2, 0x6816, 0x6B63, 0x6E05, 0x7272, 0x751F,
0x76DB, 0x7CBE, 0x8056, 0x58F0, 0x88FD, 0x897F, 0x8AA0, 0x8A93,
0x8ACB, 0x901D, 0x9192, 0x9752, 0x9759, 0x6589, 0x7A0E, 0x8106,
0x96BB, 0x5E2D, 0x60DC, 0x621A, 0x65A5, 0x6614, 0x6790, 0x77F3,
0x7A4D, 0x7C4D, 0x7E3E, 0x810A, 0x8CAC, 0x8D64, 0x8DE1, 0x8E5F,
0x78A9, 0x5207, 0x62D9, 0x63A5, 0x6442, 0x6298, 0x8A2D, 0x7A83,
0x7BC0, 0x8AAC, 0x96EA, 0x7D76, 0x820C, 0x8749, 0x4ED9, 0x5148,
0x5343, 0x5360, 0x5BA3, 0x5C02, 0x5C16, 0x5DDD, 0x6226, 0x6247,
0x64B0, 0x6813, 0x6834, 0x6CC9, 0x6D45, 0x6D17, 0x67D3, 0x6F5C,
0x714E, 0x717D, 0x65CB, 0x7A7F, 0x7BAD, 0x7DDA},
{ /* category 33 */
0x7E4A, 0x7FA8, 0x817A, 0x821B, 0x8239, 0x85A6, 0x8A6E, 0x8CCE,
0x8DF5, 0x9078, 0x9077, 0x92AD, 0x9291, 0x9583, 0x9BAE, 0x524D,
0x5584, 0x6F38, 0x7136, 0x5168, 0x7985, 0x7E55, 0x81B3, 0x7CCE,
0x564C, 0x5851, 0x5CA8, 0x63AA, 0x66FE, 0x66FD, 0x695A, 0x72D9,
0x758F, 0x758E, 0x790E, 0x7956, 0x79DF, 0x7C97, 0x7D20, 0x7D44,
0x8607, 0x8A34, 0x963B, 0x9061, 0x9F20, 0x50E7, 0x5275, 0x53CC,
0x53E2, 0x5009, 0x55AA, 0x58EE, 0x594F, 0x723D, 0x5B8B, 0x5C64,
0x531D, 0x60E3, 0x60F3, 0x635C, 0x6383, 0x633F, 0x63BB, 0x64CD,
0x65E9, 0x66F9, 0x5DE3, 0x69CD, 0x69FD, 0x6F15, 0x71E5, 0x4E89,
0x75E9, 0x76F8, 0x7A93, 0x7CDF, 0x7DCF, 0x7D9C, 0x8061, 0x8349,
0x8358, 0x846C, 0x84BC, 0x85FB, 0x88C5, 0x8D70, 0x9001, 0x906D,
0x9397, 0x971C, 0x9A12, 0x50CF, 0x5897, 0x618E},
{ /* category 34 */
0x81D3, 0x8535, 0x8D08, 0x9020, 0x4FC3, 0x5074, 0x5247, 0x5373,
0x606F, 0x6349, 0x675F, 0x6E2C, 0x8DB3, 0x901F, 0x4FD7, 0x5C5E,
0x8CCA, 0x65CF, 0x7D9A, 0x5352, 0x8896, 0x5176, 0x63C3, 0x5B58,
0x5B6B, 0x5C0A, 0x640D, 0x6751, 0x905C, 0x4ED6, 0x591A, 0x592A,
0x6C70, 0x8A51, 0x553E, 0x5815, 0x59A5, 0x60F0, 0x6253, 0x67C1,
0x8235, 0x6955, 0x9640, 0x99C4, 0x9A28, 0x4F53, 0x5806, 0x5BFE,
0x8010, 0x5CB1, 0x5E2F, 0x5F85, 0x6020, 0x614B, 0x6234, 0x66FF,
0x6CF0, 0x6EDE, 0x80CE, 0x817F, 0x82D4, 0x888B, 0x8CB8, 0x9000,
0x902E, 0x968A, 0x9EDB, 0x9BDB, 0x4EE3, 0x53F0, 0x5927, 0x7B2C,
0x918D, 0x984C, 0x9DF9, 0x6EDD, 0x7027, 0x5353, 0x5544, 0x5B85,
0x6258, 0x629E, 0x62D3, 0x6CA2, 0x6FEF, 0x7422, 0x8A17, 0x9438,
0x6FC1, 0x8AFE, 0x8338, 0x51E7, 0x86F8, 0x53EA},
{ /* category 35 */
0x53E9, 0x4F46, 0x9054, 0x8FB0, 0x596A, 0x8131, 0x5DFD, 0x7AEA,
0x8FBF, 0x68DA, 0x8C37, 0x72F8, 0x9C48, 0x6A3D, 0x8AB0, 0x4E39,
0x5358, 0x5606, 0x5766, 0x62C5, 0x63A2, 0x65E6, 0x6B4E, 0x6DE1,
0x6E5B, 0x70AD, 0x77ED, 0x7AEF, 0x7BAA, 0x7DBB, 0x803D, 0x80C6,
0x86CB, 0x8A95, 0x935B, 0x56E3, 0x58C7, 0x5F3E, 0x65AD, 0x6696,
0x6A80, 0x6BB5, 0x7537, 0x8AC7, 0x5024, 0x77E5, 0x5730, 0x5F1B,
0x6065, 0x667A, 0x6C60, 0x75F4, 0x7A1A, 0x7F6E, 0x81F4, 0x8718,
0x9045, 0x99B3, 0x7BC9, 0x755C, 0x7AF9, 0x7B51, 0x84C4, 0x9010,
0x79E9, 0x7A92, 0x8336, 0x5AE1, 0x7740, 0x4E2D, 0x4EF2, 0x5B99,
0x5FE0, 0x62BD, 0x663C, 0x67F1, 0x6CE8, 0x866B, 0x8877, 0x8A3B,
0x914E, 0x92F3, 0x99D0, 0x6A17, 0x7026, 0x732A, 0x82E7, 0x8457,
0x8CAF, 0x4E01, 0x5146, 0x51CB, 0x558B, 0x5BF5},
{ /* category 36 */
0x5E16, 0x5E33, 0x5E81, 0x5F14, 0x5F35, 0x5F6B, 0x5FB4, 0x61F2,
0x6311, 0x66A2, 0x671D, 0x6F6E, 0x7252, 0x753A, 0x773A, 0x8074,
0x8139, 0x8178, 0x8776, 0x8ABF, 0x8ADC, 0x8D85, 0x8DF3, 0x929A,
0x9577, 0x9802, 0x9CE5, 0x52C5, 0x6357, 0x76F4, 0x6715, 0x6C88,
0x73CD, 0x8CC3, 0x93AE, 0x9673, 0x6D25, 0x589C, 0x690E, 0x69CC,
0x8FFD, 0x939A, 0x75DB, 0x901A, 0x585A, 0x6802, 0x63B4, 0x69FB,
0x4F43, 0x6F2C, 0x67D8, 0x8FBB, 0x8526, 0x7DB4, 0x9354, 0x693F,
0x6F70, 0x576A, 0x58F7, 0x5B2C, 0x7D2C, 0x722A, 0x540A, 0x91E3,
0x9DB4, 0x4EAD, 0x4F4E, 0x505C, 0x5075, 0x5243, 0x8C9E, 0x5448,
0x5824, 0x5B9A, 0x5E1D, 0x5E95, 0x5EAD, 0x5EF7, 0x5F1F, 0x608C,
0x62B5, 0x633A, 0x63D0, 0x68AF, 0x6C40, 0x7887, 0x798E, 0x7A0B,
0x7DE0, 0x8247, 0x8A02, 0x8AE6, 0x8E44, 0x9013},
{ /* category 37 */
0x90B8, 0x912D, 0x91D8, 0x9F0E, 0x6CE5, 0x6458, 0x64E2, 0x6575,
0x6EF4, 0x7684, 0x7B1B, 0x9069, 0x93D1, 0x6EBA, 0x54F2, 0x5FB9,
0x64A4, 0x8F4D, 0x8FED, 0x9244, 0x5178, 0x586B, 0x5929, 0x5C55,
0x5E97, 0x6DFB, 0x7E8F, 0x751C, 0x8CBC, 0x8EE2, 0x985B, 0x70B9,
0x4F1D, 0x6BBF, 0x6FB1, 0x7530, 0x96FB, 0x514E, 0x5410, 0x5835,
0x5857, 0x59AC, 0x5C60, 0x5F92, 0x6597, 0x675C, 0x6E21, 0x767B,
0x83DF, 0x8CED, 0x9014, 0x90FD, 0x934D, 0x7825, 0x783A, 0x52AA,
0x5EA6, 0x571F, 0x5974, 0x6012, 0x5012, 0x515A, 0x51AC, 0x51CD,
0x5200, 0x5510, 0x5854, 0x5858, 0x5957, 0x5B95, 0x5CF6, 0x5D8B,
0x60BC, 0x6295, 0x642D, 0x6771, 0x6843, 0x68BC, 0x68DF, 0x76D7,
0x6DD8, 0x6E6F, 0x6D9B, 0x706F, 0x71C8, 0x5F53, 0x75D8, 0x7977,
0x7B49, 0x7B54, 0x7B52, 0x7CD6, 0x7D71, 0x5230},
{ /* category 38 */
0x8463, 0x8569, 0x85E4, 0x8A0E, 0x8B04, 0x8C46, 0x8E0F, 0x9003,
0x900F, 0x9419, 0x9676, 0x982D, 0x9A30, 0x95D8, 0x50CD, 0x52D5,
0x540C, 0x5802, 0x5C0E, 0x61A7, 0x649E, 0x6D1E, 0x77B3, 0x7AE5,
0x80F4, 0x8404, 0x9053, 0x9285, 0x5CE0, 0x9D07, 0x533F, 0x5F97,
0x5FB3, 0x6D9C, 0x7279, 0x7763, 0x79BF, 0x7BE4, 0x6BD2, 0x72EC,
0x8AAD, 0x6803, 0x6A61, 0x51F8, 0x7A81, 0x6934, 0x5C4A, 0x9CF6,
0x82EB, 0x5BC5, 0x9149, 0x701E, 0x5678, 0x5C6F, 0x60C7, 0x6566,
0x6C8C, 0x8C5A, 0x9041, 0x9813, 0x5451, 0x66C7, 0x920D, 0x5948,
0x90A3, 0x5185, 0x4E4D, 0x51EA, 0x8599, 0x8B0E, 0x7058, 0x637A,
0x934B, 0x6962, 0x99B4, 0x7E04, 0x7577, 0x5357, 0x6960, 0x8EDF,
0x96E3, 0x6C5D, 0x4E8C, 0x5C3C, 0x5F10, 0x8FE9, 0x5302, 0x8CD1,
0x8089, 0x8679, 0x5EFF, 0x65E5, 0x4E73, 0x5165},
{ /* category 39 */
0x5982, 0x5C3F, 0x97EE, 0x4EFB, 0x598A, 0x5FCD, 0x8A8D, 0x6FE1,
0x79B0, 0x7962, 0x5BE7, 0x8471, 0x732B, 0x71B1, 0x5E74, 0x5FF5,
0x637B, 0x649A, 0x71C3, 0x7C98, 0x4E43, 0x5EFC, 0x4E4B, 0x57DC,
0x56A2, 0x60A9, 0x6FC3, 0x7D0D, 0x80FD, 0x8133, 0x81BF, 0x8FB2,
0x8997, 0x86A4, 0x5DF4, 0x628A, 0x64AD, 0x8987, 0x6777, 0x6CE2,
0x6D3E, 0x7436, 0x7834, 0x5A46, 0x7F75, 0x82AD, 0x99AC, 0x4FF3,
0x5EC3, 0x62DD, 0x6392, 0x6557, 0x676F, 0x76C3, 0x724C, 0x80CC,
0x80BA, 0x8F29, 0x914D, 0x500D, 0x57F9, 0x5A92, 0x6885, 0x6973,
0x7164, 0x72FD, 0x8CB7, 0x58F2, 0x8CE0, 0x966A, 0x9019, 0x877F,
0x79E4, 0x77E7, 0x8429, 0x4F2F, 0x5265, 0x535A, 0x62CD, 0x67CF,
0x6CCA, 0x767D, 0x7B94, 0x7C95, 0x8236, 0x8584, 0x8FEB, 0x66DD,
0x6F20, 0x7206, 0x7E1B, 0x83AB, 0x99C1, 0x9EA6},
{ /* category 40 */
0x51FD, 0x7BB1, 0x7872, 0x7BB8, 0x8087, 0x7B48, 0x6AE8, 0x5E61,
0x808C, 0x7551, 0x7560, 0x516B, 0x9262, 0x6E8C, 0x767A, 0x9197,
0x9AEA, 0x4F10, 0x7F70, 0x629C, 0x7B4F, 0x95A5, 0x9CE9, 0x567A,
0x5859, 0x86E4, 0x96BC, 0x4F34, 0x5224, 0x534A, 0x53CD, 0x53DB,
0x5E06, 0x642C, 0x6591, 0x677F, 0x6C3E, 0x6C4E, 0x7248, 0x72AF,
0x73ED, 0x7554, 0x7E41, 0x822C, 0x85E9, 0x8CA9, 0x7BC4, 0x91C6,
0x7169, 0x9812, 0x98EF, 0x633D, 0x6669, 0x756A, 0x76E4, 0x78D0,
0x8543, 0x86EE, 0x532A, 0x5351, 0x5426, 0x5983, 0x5E87, 0x5F7C,
0x60B2, 0x6249, 0x6279, 0x62AB, 0x6590, 0x6BD4, 0x6CCC, 0x75B2,
0x76AE, 0x7891, 0x79D8, 0x7DCB, 0x7F77, 0x80A5, 0x88AB, 0x8AB9,
0x8CBB, 0x907F, 0x975E, 0x98DB, 0x6A0B, 0x7C38, 0x5099, 0x5C3E,
0x5FAE, 0x6787, 0x6BD8, 0x7435, 0x7709, 0x7F8E},
{ /* category 41 */
0x9F3B, 0x67CA, 0x7A17, 0x5339, 0x758B, 0x9AED, 0x5F66, 0x819D,
0x83F1, 0x8098, 0x5F3C, 0x5FC5, 0x7562, 0x7B46, 0x903C, 0x6867,
0x59EB, 0x5A9B, 0x7D10, 0x767E, 0x8B2C, 0x4FF5, 0x5F6A, 0x6A19,
0x6C37, 0x6F02, 0x74E2, 0x7968, 0x8868, 0x8A55, 0x8C79, 0x5EDF,
0x63CF, 0x75C5, 0x79D2, 0x82D7, 0x9328, 0x92F2, 0x849C, 0x86ED,
0x9C2D, 0x54C1, 0x5F6C, 0x658C, 0x6D5C, 0x7015, 0x8CA7, 0x8CD3,
0x983B, 0x654F, 0x74F6, 0x4E0D, 0x4ED8, 0x57E0, 0x592B, 0x5A66,
0x5BCC, 0x51A8, 0x5E03, 0x5E9C, 0x6016, 0x6276, 0x6577, 0x65A7,
0x666E, 0x6D6E, 0x7236, 0x7B26, 0x8150, 0x819A, 0x8299, 0x8B5C,
0x8CA0, 0x8CE6, 0x8D74, 0x961C, 0x9644, 0x4FAE, 0x64AB, 0x6B66,
0x821E, 0x8461, 0x856A, 0x90E8, 0x5C01, 0x6953, 0x98A8, 0x847A,
0x8557, 0x4F0F, 0x526F, 0x5FA9, 0x5E45, 0x670D},
{ /* category 42 */
0x798F, 0x8179, 0x8907, 0x8986, 0x6DF5, 0x5F17, 0x6255, 0x6CB8,
0x4ECF, 0x7269, 0x9B92, 0x5206, 0x543B, 0x5674, 0x58B3, 0x61A4,
0x626E, 0x711A, 0x596E, 0x7C89, 0x7CDE, 0x7D1B, 0x96F0, 0x6587,
0x805E, 0x4E19, 0x4F75, 0x5175, 0x5840, 0x5E63, 0x5E73, 0x5F0A,
0x67C4, 0x4E26, 0x853D, 0x9589, 0x965B, 0x7C73, 0x9801, 0x50FB,
0x58C1, 0x7656, 0x78A7, 0x5225, 0x77A5, 0x8511, 0x7B86, 0x504F,
0x5909, 0x7247, 0x7BC7, 0x7DE8, 0x8FBA, 0x8FD4, 0x904D, 0x4FBF,
0x52C9, 0x5A29, 0x5F01, 0x97AD, 0x4FDD, 0x8217, 0x92EA, 0x5703,
0x6355, 0x6B69, 0x752B, 0x88DC, 0x8F14, 0x7A42, 0x52DF, 0x5893,
0x6155, 0x620A, 0x66AE, 0x6BCD, 0x7C3F, 0x83E9, 0x5023, 0x4FF8,
0x5305, 0x5446, 0x5831, 0x5949, 0x5B9D, 0x5CF0, 0x5CEF, 0x5D29,
0x5E96, 0x62B1, 0x6367, 0x653E, 0x65B9, 0x670B},
{ /* category 43 */
0x6CD5, 0x6CE1, 0x70F9, 0x7832, 0x7E2B, 0x80DE, 0x82B3, 0x840C,
0x84EC, 0x8702, 0x8912, 0x8A2A, 0x8C4A, 0x90A6, 0x92D2, 0x98FD,
0x9CF3, 0x9D6C, 0x4E4F, 0x4EA1, 0x508D, 0x5256, 0x574A, 0x59A8,
0x5E3D, 0x5FD8, 0x5FD9, 0x623F, 0x66B4, 0x671B, 0x67D0, 0x68D2,
0x5192, 0x7D21, 0x80AA, 0x81A8, 0x8B00, 0x8C8C, 0x8CBF, 0x927E,
0x9632, 0x5420, 0x982C, 0x5317, 0x50D5, 0x535C, 0x58A8, 0x64B2,
0x6734, 0x7267, 0x7766, 0x7A46, 0x91E6, 0x52C3, 0x6CA1, 0x6B86,
0x5800, 0x5E4C, 0x5954, 0x672C, 0x7FFB, 0x51E1, 0x76C6, 0x6469,
0x78E8, 0x9B54, 0x9EBB, 0x57CB, 0x59B9, 0x6627, 0x679A, 0x6BCE,
0x54E9, 0x69D9, 0x5E55, 0x819C, 0x6795, 0x9BAA, 0x67FE, 0x9C52,
0x685D, 0x4EA6, 0x4FE3, 0x53C8, 0x62B9, 0x672B, 0x6CAB, 0x8FC4,
0x4FAD, 0x7E6D, 0x9EBF, 0x4E07, 0x6162, 0x6E80},
{ /* category 44 */
0x6F2B, 0x8513, 0x5473, 0x672A, 0x9B45, 0x5DF3, 0x7B95, 0x5CAC,
0x5BC6, 0x871C, 0x6E4A, 0x84D1, 0x7A14, 0x8108, 0x5999, 0x7C8D,
0x6C11, 0x7720, 0x52D9, 0x5922, 0x7121, 0x725F, 0x77DB, 0x9727,
0x9D61, 0x690B, 0x5A7F, 0x5A18, 0x51A5, 0x540D, 0x547D, 0x660E,
0x76DF, 0x8FF7, 0x9298, 0x9CF4, 0x59EA, 0x725D, 0x6EC5, 0x514D,
0x68C9, 0x7DBF, 0x7DEC, 0x9762, 0x9EBA, 0x6478, 0x6A21, 0x8302,
0x5984, 0x5B5F, 0x6BDB, 0x731B, 0x76F2, 0x7DB2, 0x8017, 0x8499,
0x5132, 0x6728, 0x9ED9, 0x76EE, 0x6762, 0x52FF, 0x9905, 0x5C24,
0x623B, 0x7C7E, 0x8CB0, 0x554F, 0x60B6, 0x7D0B, 0x9580, 0x5301,
0x4E5F, 0x51B6, 0x591C, 0x723A, 0x8036, 0x91CE, 0x5F25, 0x77E2,
0x5384, 0x5F79, 0x7D04, 0x85AC, 0x8A33, 0x8E8D, 0x9756, 0x67F3,
0x85AE, 0x9453, 0x6109, 0x6108, 0x6CB9, 0x7652},
{ /* category 45 */
0x8AED, 0x8F38, 0x552F, 0x4F51, 0x512A, 0x52C7, 0x53CB, 0x5BA5,
0x5E7D, 0x60A0, 0x6182, 0x63D6, 0x6709, 0x67DA, 0x6E67, 0x6D8C,
0x7336, 0x7337, 0x7531, 0x7950, 0x88D5, 0x8A98, 0x904A, 0x9091,
0x90F5, 0x96C4, 0x878D, 0x5915, 0x4E88, 0x4F59, 0x4E0E, 0x8A89,
0x8F3F, 0x9810, 0x50AD, 0x5E7C, 0x5996, 0x5BB9, 0x5EB8, 0x63DA,
0x63FA, 0x64C1, 0x66DC, 0x694A, 0x69D8, 0x6D0B, 0x6EB6, 0x7194,
0x7528, 0x7AAF, 0x7F8A, 0x8000, 0x8449, 0x84C9, 0x8981, 0x8B21,
0x8E0A, 0x9065, 0x967D, 0x990A, 0x617E, 0x6291, 0x6B32, 0x6C83,
0x6D74, 0x7FCC, 0x7FFC, 0x6DC0, 0x7F85, 0x87BA, 0x88F8, 0x6765,
0x83B1, 0x983C, 0x96F7, 0x6D1B, 0x7D61, 0x843D, 0x916A, 0x4E71,
0x5375, 0x5D50, 0x6B04, 0x6FEB, 0x85CD, 0x862D, 0x89A7, 0x5229,
0x540F, 0x5C65, 0x674E, 0x68A8, 0x7406, 0x7483},
{ /* category 46 */
0x75E2, 0x88CF, 0x88E1, 0x91CC, 0x96E2, 0x9678, 0x5F8B, 0x7387,
0x7ACB, 0x844E, 0x63A0, 0x7565, 0x5289, 0x6D41, 0x6E9C, 0x7409,
0x7559, 0x786B, 0x7C92, 0x9686, 0x7ADC, 0x9F8D, 0x4FB6, 0x616E,
0x65C5, 0x865C, 0x4E86, 0x4EAE, 0x50DA, 0x4E21, 0x51CC, 0x5BEE,
0x6599, 0x6881, 0x6DBC, 0x731F, 0x7642, 0x77AD, 0x7A1C, 0x7CE7,
0x826F, 0x8AD2, 0x907C, 0x91CF, 0x9675, 0x9818, 0x529B, 0x7DD1,
0x502B, 0x5398, 0x6797, 0x6DCB, 0x71D0, 0x7433, 0x81E8, 0x8F2A,
0x96A3, 0x9C57, 0x9E9F, 0x7460, 0x5841, 0x6D99, 0x7D2F, 0x985E,
0x4EE4, 0x4F36, 0x4F8B, 0x51B7, 0x52B1, 0x5DBA, 0x601C, 0x73B2,
0x793C, 0x82D3, 0x9234, 0x96B7, 0x96F6, 0x970A, 0x9E97, 0x9F62,
0x66A6, 0x6B74, 0x5217, 0x52A3, 0x70C8, 0x88C2, 0x5EC9, 0x604B,
0x6190, 0x6F23, 0x7149, 0x7C3E, 0x7DF4, 0x806F},
{ /* category 47 */
0x84EE, 0x9023, 0x932C, 0x5442, 0x9B6F, 0x6AD3, 0x7089, 0x8CC2,
0x8DEF, 0x9732, 0x52B4, 0x5A41, 0x5ECA, 0x5F04, 0x6717, 0x697C,
0x6994, 0x6D6A, 0x6F0F, 0x7262, 0x72FC, 0x7BED, 0x8001, 0x807E,
0x874B, 0x90CE, 0x516D, 0x9E93, 0x7984, 0x808B, 0x9332, 0x8AD6,
0x502D, 0x548C, 0x8A71, 0x6B6A, 0x8CC4, 0x8107, 0x60D1, 0x67A0,
0x9DF2, 0x4E99, 0x4E98, 0x9C10, 0x8A6B, 0x85C1, 0x8568, 0x6900,
0x6E7E, 0x7897, 0x8155, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
{ /* category 48 */
0x5F0C, 0x4E10, 0x4E15, 0x4E2A, 0x4E31, 0x4E36, 0x4E3C, 0x4E3F,
0x4E42, 0x4E56, 0x4E58, 0x4E82, 0x4E85, 0x8C6B, 0x4E8A, 0x8212,
0x5F0D, 0x4E8E, 0x4E9E, 0x4E9F, 0x4EA0, 0x4EA2, 0x4EB0, 0x4EB3,
0x4EB6, 0x4ECE, 0x4ECD, 0x4EC4, 0x4EC6, 0x4EC2, 0x4ED7, 0x4EDE,
0x4EED, 0x4EDF, 0x4EF7, 0x4F09, 0x4F5A, 0x4F30, 0x4F5B, 0x4F5D,
0x4F57, 0x4F47, 0x4F76, 0x4F88, 0x4F8F, 0x4F98, 0x4F7B, 0x4F69,
0x4F70, 0x4F91, 0x4F6F, 0x4F86, 0x4F96, 0x5118, 0x4FD4, 0x4FDF,
0x4FCE, 0x4FD8, 0x4FDB, 0x4FD1, 0x4FDA, 0x4FD0, 0x4FE4, 0x4FE5,
0x501A, 0x5028, 0x5014, 0x502A, 0x5025, 0x5005, 0x4F1C, 0x4FF6,
0x5021, 0x5029, 0x502C, 0x4FFE, 0x4FEF, 0x5011, 0x5006, 0x5043,
0x5047, 0x6703, 0x5055, 0x5050, 0x5048, 0x505A, 0x5056, 0x506C,
0x5078, 0x5080, 0x509A, 0x5085, 0x50B4, 0x50B2},
{ /* category 49 */
0x50C9, 0x50CA, 0x50B3, 0x50C2, 0x50D6, 0x50DE, 0x50E5, 0x50ED,
0x50E3, 0x50EE, 0x50F9, 0x50F5, 0x5109, 0x5101, 0x5102, 0x5116,
0x5115, 0x5114, 0x511A, 0x5121, 0x513A, 0x5137, 0x513C, 0x513B,
0x513F, 0x5140, 0x5152, 0x514C, 0x5154, 0x5162, 0x7AF8, 0x5169,
0x516A, 0x516E, 0x5180, 0x5182, 0x56D8, 0x518C, 0x5189, 0x518F,
0x5191, 0x5193, 0x5195, 0x5196, 0x51A4, 0x51A6, 0x51A2, 0x51A9,
0x51AA, 0x51AB, 0x51B3, 0x51B1, 0x51B2, 0x51B0, 0x51B5, 0x51BD,
0x51C5, 0x51C9, 0x51DB, 0x51E0, 0x8655, 0x51E9, 0x51ED, 0x51F0,
0x51F5, 0x51FE, 0x5204, 0x520B, 0x5214, 0x520E, 0x5227, 0x522A,
0x522E, 0x5233, 0x5239, 0x524F, 0x5244, 0x524B, 0x524C, 0x525E,
0x5254, 0x526A, 0x5274, 0x5269, 0x5273, 0x527F, 0x527D, 0x528D,
0x5294, 0x5292, 0x5271, 0x5288, 0x5291, 0x8FA8},
{ /* category 50 */
0x8FA7, 0x52AC, 0x52AD, 0x52BC, 0x52B5, 0x52C1, 0x52CD, 0x52D7,
0x52DE, 0x52E3, 0x52E6, 0x98ED, 0x52E0, 0x52F3, 0x52F5, 0x52F8,
0x52F9, 0x5306, 0x5308, 0x7538, 0x530D, 0x5310, 0x530F, 0x5315,
0x531A, 0x5323, 0x532F, 0x5331, 0x5333, 0x5338, 0x5340, 0x5346,
0x5345, 0x4E17, 0x5349, 0x534D, 0x51D6, 0x535E, 0x5369, 0x536E,
0x5918, 0x537B, 0x5377, 0x5382, 0x5396, 0x53A0, 0x53A6, 0x53A5,
0x53AE, 0x53B0, 0x53B6, 0x53C3, 0x7C12, 0x96D9, 0x53DF, 0x66FC,
0x71EE, 0x53EE, 0x53E8, 0x53ED, 0x53FA, 0x5401, 0x543D, 0x5440,
0x542C, 0x542D, 0x543C, 0x542E, 0x5436, 0x5429, 0x541D, 0x544E,
0x548F, 0x5475, 0x548E, 0x545F, 0x5471, 0x5477, 0x5470, 0x5492,
0x547B, 0x5480, 0x5476, 0x5484, 0x5490, 0x5486, 0x54C7, 0x54A2,
0x54B8, 0x54A5, 0x54AC, 0x54C4, 0x54C8, 0x54A8},
{ /* category 51 */
0x54AB, 0x54C2, 0x54A4, 0x54BE, 0x54BC, 0x54D8, 0x54E5, 0x54E6,
0x550F, 0x5514, 0x54FD, 0x54EE, 0x54ED, 0x54FA, 0x54E2, 0x5539,
0x5540, 0x5563, 0x554C, 0x552E, 0x555C, 0x5545, 0x5556, 0x5557,
0x5538, 0x5533, 0x555D, 0x5599, 0x5580, 0x54AF, 0x558A, 0x559F,
0x557B, 0x557E, 0x5598, 0x559E, 0x55AE, 0x557C, 0x5583, 0x55A9,
0x5587, 0x55A8, 0x55DA, 0x55C5, 0x55DF, 0x55C4, 0x55DC, 0x55E4,
0x55D4, 0x5614, 0x55F7, 0x5616, 0x55FE, 0x55FD, 0x561B, 0x55F9,
0x564E, 0x5650, 0x71DF, 0x5634, 0x5636, 0x5632, 0x5638, 0x566B,
0x5664, 0x562F, 0x566C, 0x566A, 0x5686, 0x5680, 0x568A, 0x56A0,
0x5694, 0x568F, 0x56A5, 0x56AE, 0x56B6, 0x56B4, 0x56C2, 0x56BC,
0x56C1, 0x56C3, 0x56C0, 0x56C8, 0x56CE, 0x56D1, 0x56D3, 0x56D7,
0x56EE, 0x56F9, 0x5700, 0x56FF, 0x5704, 0x5709},
{ /* category 52 */
0x5708, 0x570B, 0x570D, 0x5713, 0x5718, 0x5716, 0x55C7, 0x571C,
0x5726, 0x5737, 0x5738, 0x574E, 0x573B, 0x5740, 0x574F, 0x5769,
0x57C0, 0x5788, 0x5761, 0x577F, 0x5789, 0x5793, 0x57A0, 0x57B3,
0x57A4, 0x57AA, 0x57B0, 0x57C3, 0x57C6, 0x57D4, 0x57D2, 0x57D3,
0x580A, 0x57D6, 0x57E3, 0x580B, 0x5819, 0x581D, 0x5872, 0x5821,
0x5862, 0x584B, 0x5870, 0x6BC0, 0x5852, 0x583D, 0x5879, 0x5885,
0x58B9, 0x589F, 0x58AB, 0x58BA, 0x58DE, 0x58BB, 0x58B8, 0x58AE,
0x58C5, 0x58D3, 0x58D1, 0x58D7, 0x58D9, 0x58D8, 0x58E5, 0x58DC,
0x58E4, 0x58DF, 0x58EF, 0x58FA, 0x58F9, 0x58FB, 0x58FC, 0x58FD,
0x5902, 0x590A, 0x5910, 0x591B, 0x68A6, 0x5925, 0x592C, 0x592D,
0x5932, 0x5938, 0x593E, 0x7AD2, 0x5955, 0x5950, 0x594E, 0x595A,
0x5958, 0x5962, 0x5960, 0x5967, 0x596C, 0x5969},
{ /* category 53 */
0x5978, 0x5981, 0x599D, 0x4F5E, 0x4FAB, 0x59A3, 0x59B2, 0x59C6,
0x59E8, 0x59DC, 0x598D, 0x59D9, 0x59DA, 0x5A25, 0x5A1F, 0x5A11,
0x5A1C, 0x5A09, 0x5A1A, 0x5A40, 0x5A6C, 0x5A49, 0x5A35, 0x5A36,
0x5A62, 0x5A6A, 0x5A9A, 0x5ABC, 0x5ABE, 0x5ACB, 0x5AC2, 0x5ABD,
0x5AE3, 0x5AD7, 0x5AE6, 0x5AE9, 0x5AD6, 0x5AFA, 0x5AFB, 0x5B0C,
0x5B0B, 0x5B16, 0x5B32, 0x5AD0, 0x5B2A, 0x5B36, 0x5B3E, 0x5B43,
0x5B45, 0x5B40, 0x5B51, 0x5B55, 0x5B5A, 0x5B5B, 0x5B65, 0x5B69,
0x5B70, 0x5B73, 0x5B75, 0x5B78, 0x6588, 0x5B7A, 0x5B80, 0x5B83,
0x5BA6, 0x5BB8, 0x5BC3, 0x5BC7, 0x5BC9, 0x5BD4, 0x5BD0, 0x5BE4,
0x5BE6, 0x5BE2, 0x5BDE, 0x5BE5, 0x5BEB, 0x5BF0, 0x5BF6, 0x5BF3,
0x5C05, 0x5C07, 0x5C08, 0x5C0D, 0x5C13, 0x5C20, 0x5C22, 0x5C28,
0x5C38, 0x5C39, 0x5C41, 0x5C46, 0x5C4E, 0x5C53},
{ /* category 54 */
0x5C50, 0x5C4F, 0x5B71, 0x5C6C, 0x5C6E, 0x4E62, 0x5C76, 0x5C79,
0x5C8C, 0x5C91, 0x5C94, 0x599B, 0x5CAB, 0x5CBB, 0x5CB6, 0x5CBC,
0x5CB7, 0x5CC5, 0x5CBE, 0x5CC7, 0x5CD9, 0x5CE9, 0x5CFD, 0x5CFA,
0x5CED, 0x5D8C, 0x5CEA, 0x5D0B, 0x5D15, 0x5D17, 0x5D5C, 0x5D1F,
0x5D1B, 0x5D11, 0x5D14, 0x5D22, 0x5D1A, 0x5D19, 0x5D18, 0x5D4C,
0x5D52, 0x5D4E, 0x5D4B, 0x5D6C, 0x5D73, 0x5D76, 0x5D87, 0x5D84,
0x5D82, 0x5DA2, 0x5D9D, 0x5DAC, 0x5DAE, 0x5DBD, 0x5D90, 0x5DB7,
0x5DBC, 0x5DC9, 0x5DCD, 0x5DD3, 0x5DD2, 0x5DD6, 0x5DDB, 0x5DEB,
0x5DF2, 0x5DF5, 0x5E0B, 0x5E1A, 0x5E19, 0x5E11, 0x5E1B, 0x5E36,
0x5E37, 0x5E44, 0x5E43, 0x5E40, 0x5E4E, 0x5E57, 0x5E54, 0x5E5F,
0x5E62, 0x5E64, 0x5E47, 0x5E75, 0x5E76, 0x5E7A, 0x9EBC, 0x5E7F,
0x5EA0, 0x5EC1, 0x5EC2, 0x5EC8, 0x5ED0, 0x5ECF},
{ /* category 55 */
0x5ED6, 0x5EE3, 0x5EDD, 0x5EDA, 0x5EDB, 0x5EE2, 0x5EE1, 0x5EE8,
0x5EE9, 0x5EEC, 0x5EF1, 0x5EF3, 0x5EF0, 0x5EF4, 0x5EF8, 0x5EFE,
0x5F03, 0x5F09, 0x5F5D, 0x5F5C, 0x5F0B, 0x5F11, 0x5F16, 0x5F29,
0x5F2D, 0x5F38, 0x5F41, 0x5F48, 0x5F4C, 0x5F4E, 0x5F2F, 0x5F51,
0x5F56, 0x5F57, 0x5F59, 0x5F61, 0x5F6D, 0x5F73, 0x5F77, 0x5F83,
0x5F82, 0x5F7F, 0x5F8A, 0x5F88, 0x5F91, 0x5F87, 0x5F9E, 0x5F99,
0x5F98, 0x5FA0, 0x5FA8, 0x5FAD, 0x5FBC, 0x5FD6, 0x5FFB, 0x5FE4,
0x5FF8, 0x5FF1, 0x5FDD, 0x60B3, 0x5FFF, 0x6021, 0x6060, 0x6019,
0x6010, 0x6029, 0x600E, 0x6031, 0x601B, 0x6015, 0x602B, 0x6026,
0x600F, 0x603A, 0x605A, 0x6041, 0x606A, 0x6077, 0x605F, 0x604A,
0x6046, 0x604D, 0x6063, 0x6043, 0x6064, 0x6042, 0x606C, 0x606B,
0x6059, 0x6081, 0x608D, 0x60E7, 0x6083, 0x609A},
{ /* category 56 */
0x6084, 0x609B, 0x6096, 0x6097, 0x6092, 0x60A7, 0x608B, 0x60E1,
0x60B8, 0x60E0, 0x60D3, 0x60B4, 0x5FF0, 0x60BD, 0x60C6, 0x60B5,
0x60D8, 0x614D, 0x6115, 0x6106, 0x60F6, 0x60F7, 0x6100, 0x60F4,
0x60FA, 0x6103, 0x6121, 0x60FB, 0x60F1, 0x610D, 0x610E, 0x6147,
0x613E, 0x6128, 0x6127, 0x614A, 0x613F, 0x613C, 0x612C, 0x6134,
0x613D, 0x6142, 0x6144, 0x6173, 0x6177, 0x6158, 0x6159, 0x615A,
0x616B, 0x6174, 0x616F, 0x6165, 0x6171, 0x615F, 0x615D, 0x6153,
0x6175, 0x6199, 0x6196, 0x6187, 0x61AC, 0x6194, 0x619A, 0x618A,
0x6191, 0x61AB, 0x61AE, 0x61CC, 0x61CA, 0x61C9, 0x61F7, 0x61C8,
0x61C3, 0x61C6, 0x61BA, 0x61CB, 0x7F79, 0x61CD, 0x61E6, 0x61E3,
0x61F6, 0x61FA, 0x61F4, 0x61FF, 0x61FD, 0x61FC, 0x61FE, 0x6200,
0x6208, 0x6209, 0x620D, 0x620C, 0x6214, 0x621B},
{ /* category 57 */
0x621E, 0x6221, 0x622A, 0x622E, 0x6230, 0x6232, 0x6233, 0x6241,
0x624E, 0x625E, 0x6263, 0x625B, 0x6260, 0x6268, 0x627C, 0x6282,
0x6289, 0x627E, 0x6292, 0x6293, 0x6296, 0x62D4, 0x6283, 0x6294,
0x62D7, 0x62D1, 0x62BB, 0x62CF, 0x62FF, 0x62C6, 0x64D4, 0x62C8,
0x62DC, 0x62CC, 0x62CA, 0x62C2, 0x62C7, 0x629B, 0x62C9, 0x630C,
0x62EE, 0x62F1, 0x6327, 0x6302, 0x6308, 0x62EF, 0x62F5, 0x6350,
0x633E, 0x634D, 0x641C, 0x634F, 0x6396, 0x638E, 0x6380, 0x63AB,
0x6376, 0x63A3, 0x638F, 0x6389, 0x639F, 0x63B5, 0x636B, 0x6369,
0x63BE, 0x63E9, 0x63C0, 0x63C6, 0x63E3, 0x63C9, 0x63D2, 0x63F6,
0x63C4, 0x6416, 0x6434, 0x6406, 0x6413, 0x6426, 0x6436, 0x651D,
0x6417, 0x6428, 0x640F, 0x6467, 0x646F, 0x6476, 0x644E, 0x652A,
0x6495, 0x6493, 0x64A5, 0x64A9, 0x6488, 0x64BC},
{ /* category 58 */
0x64DA, 0x64D2, 0x64C5, 0x64C7, 0x64BB, 0x64D8, 0x64C2, 0x64F1,
0x64E7, 0x8209, 0x64E0, 0x64E1, 0x62AC, 0x64E3, 0x64EF, 0x652C,
0x64F6, 0x64F4, 0x64F2, 0x64FA, 0x6500, 0x64FD, 0x6518, 0x651C,
0x6505, 0x6524, 0x6523, 0x652B, 0x6534, 0x6535, 0x6537, 0x6536,
0x6538, 0x754B, 0x6548, 0x6556, 0x6555, 0x654D, 0x6558, 0x655E,
0x655D, 0x6572, 0x6578, 0x6582, 0x6583, 0x8B8A, 0x659B, 0x659F,
0x65AB, 0x65B7, 0x65C3, 0x65C6, 0x65C1, 0x65C4, 0x65CC, 0x65D2,
0x65DB, 0x65D9, 0x65E0, 0x65E1, 0x65F1, 0x6772, 0x660A, 0x6603,
0x65FB, 0x6773, 0x6635, 0x6636, 0x6634, 0x661C, 0x664F, 0x6644,
0x6649, 0x6641, 0x665E, 0x665D, 0x6664, 0x6667, 0x6668, 0x665F,
0x6662, 0x6670, 0x6683, 0x6688, 0x668E, 0x6689, 0x6684, 0x6698,
0x669D, 0x66C1, 0x66B9, 0x66C9, 0x66BE, 0x66BC},
{ /* category 59 */
0x66C4, 0x66B8, 0x66D6, 0x66DA, 0x66E0, 0x663F, 0x66E6, 0x66E9,
0x66F0, 0x66F5, 0x66F7, 0x670F, 0x6716, 0x671E, 0x6726, 0x6727,
0x9738, 0x672E, 0x673F, 0x6736, 0x6741, 0x6738, 0x6737, 0x6746,
0x675E, 0x6760, 0x6759, 0x6763, 0x6764, 0x6789, 0x6770, 0x67A9,
0x677C, 0x676A, 0x678C, 0x678B, 0x67A6, 0x67A1, 0x6785, 0x67B7,
0x67EF, 0x67B4, 0x67EC, 0x67B3, 0x67E9, 0x67B8, 0x67E4, 0x67DE,
0x67DD, 0x67E2, 0x67EE, 0x67B9, 0x67CE, 0x67C6, 0x67E7, 0x6A9C,
0x681E, 0x6846, 0x6829, 0x6840, 0x684D, 0x6832, 0x684E, 0x68B3,
0x682B, 0x6859, 0x6863, 0x6877, 0x687F, 0x689F, 0x688F, 0x68AD,
0x6894, 0x689D, 0x689B, 0x6883, 0x6AAE, 0x68B9, 0x6874, 0x68B5,
0x68A0, 0x68BA, 0x690F, 0x688D, 0x687E, 0x6901, 0x68CA, 0x6908,
0x68D8, 0x6922, 0x6926, 0x68E1, 0x690C, 0x68CD},
{ /* category 60 */
0x68D4, 0x68E7, 0x68D5, 0x6936, 0x6912, 0x6904, 0x68D7, 0x68E3,
0x6925, 0x68F9, 0x68E0, 0x68EF, 0x6928, 0x692A, 0x691A, 0x6923,
0x6921, 0x68C6, 0x6979, 0x6977, 0x695C, 0x6978, 0x696B, 0x6954,
0x697E, 0x696E, 0x6939, 0x6974, 0x693D, 0x6959, 0x6930, 0x6961,
0x695E, 0x695D, 0x6981, 0x696A, 0x69B2, 0x69AE, 0x69D0, 0x69BF,
0x69C1, 0x69D3, 0x69BE, 0x69CE, 0x5BE8, 0x69CA, 0x69DD, 0x69BB,
0x69C3, 0x69A7, 0x6A2E, 0x6991, 0x69A0, 0x699C, 0x6995, 0x69B4,
0x69DE, 0x69E8, 0x6A02, 0x6A1B, 0x69FF, 0x6B0A, 0x69F9, 0x69F2,
0x69E7, 0x6A05, 0x69B1, 0x6A1E, 0x69ED, 0x6A14, 0x69EB, 0x6A0A,
0x6A12, 0x6AC1, 0x6A23, 0x6A13, 0x6A44, 0x6A0C, 0x6A72, 0x6A36,
0x6A78, 0x6A47, 0x6A62, 0x6A59, 0x6A66, 0x6A48, 0x6A38, 0x6A22,
0x6A90, 0x6A8D, 0x6AA0, 0x6A84, 0x6AA2, 0x6AA3},
{ /* category 61 */
0x6A97, 0x8617, 0x6ABB, 0x6AC3, 0x6AC2, 0x6AB8, 0x6AB3, 0x6AAC,
0x6ADE, 0x6AD1, 0x6ADF, 0x6AAA, 0x6ADA, 0x6AEA, 0x6AFB, 0x6B05,
0x8616, 0x6AFA, 0x6B12, 0x6B16, 0x9B31, 0x6B1F, 0x6B38, 0x6B37,
0x76DC, 0x6B39, 0x98EE, 0x6B47, 0x6B43, 0x6B49, 0x6B50, 0x6B59,
0x6B54, 0x6B5B, 0x6B5F, 0x6B61, 0x6B78, 0x6B79, 0x6B7F, 0x6B80,
0x6B84, 0x6B83, 0x6B8D, 0x6B98, 0x6B95, 0x6B9E, 0x6BA4, 0x6BAA,
0x6BAB, 0x6BAF, 0x6BB2, 0x6BB1, 0x6BB3, 0x6BB7, 0x6BBC, 0x6BC6,
0x6BCB, 0x6BD3, 0x6BDF, 0x6BEC, 0x6BEB, 0x6BF3, 0x6BEF, 0x9EBE,
0x6C08, 0x6C13, 0x6C14, 0x6C1B, 0x6C24, 0x6C23, 0x6C5E, 0x6C55,
0x6C62, 0x6C6A, 0x6C82, 0x6C8D, 0x6C9A, 0x6C81, 0x6C9B, 0x6C7E,
0x6C68, 0x6C73, 0x6C92, 0x6C90, 0x6CC4, 0x6CF1, 0x6CD3, 0x6CBD,
0x6CD7, 0x6CC5, 0x6CDD, 0x6CAE, 0x6CB1, 0x6CBE},
{ /* category 62 */
0x6CBA, 0x6CDB, 0x6CEF, 0x6CD9, 0x6CEA, 0x6D1F, 0x884D, 0x6D36,
0x6D2B, 0x6D3D, 0x6D38, 0x6D19, 0x6D35, 0x6D33, 0x6D12, 0x6D0C,
0x6D63, 0x6D93, 0x6D64, 0x6D5A, 0x6D79, 0x6D59, 0x6D8E, 0x6D95,
0x6FE4, 0x6D85, 0x6DF9, 0x6E15, 0x6E0A, 0x6DB5, 0x6DC7, 0x6DE6,
0x6DB8, 0x6DC6, 0x6DEC, 0x6DDE, 0x6DCC, 0x6DE8, 0x6DD2, 0x6DC5,
0x6DFA, 0x6DD9, 0x6DE4, 0x6DD5, 0x6DEA, 0x6DEE, 0x6E2D, 0x6E6E,
0x6E2E, 0x6E19, 0x6E72, 0x6E5F, 0x6E3E, 0x6E23, 0x6E6B, 0x6E2B,
0x6E76, 0x6E4D, 0x6E1F, 0x6E43, 0x6E3A, 0x6E4E, 0x6E24, 0x6EFF,
0x6E1D, 0x6E38, 0x6E82, 0x6EAA, 0x6E98, 0x6EC9, 0x6EB7, 0x6ED3,
0x6EBD, 0x6EAF, 0x6EC4, 0x6EB2, 0x6ED4, 0x6ED5, 0x6E8F, 0x6EA5,
0x6EC2, 0x6E9F, 0x6F41, 0x6F11, 0x704C, 0x6EEC, 0x6EF8, 0x6EFE,
0x6F3F, 0x6EF2, 0x6F31, 0x6EEF, 0x6F32, 0x6ECC},
{ /* category 63 */
0x6F3E, 0x6F13, 0x6EF7, 0x6F86, 0x6F7A, 0x6F78, 0x6F81, 0x6F80,
0x6F6F, 0x6F5B, 0x6FF3, 0x6F6D, 0x6F82, 0x6F7C, 0x6F58, 0x6F8E,
0x6F91, 0x6FC2, 0x6F66, 0x6FB3, 0x6FA3, 0x6FA1, 0x6FA4, 0x6FB9,
0x6FC6, 0x6FAA, 0x6FDF, 0x6FD5, 0x6FEC, 0x6FD4, 0x6FD8, 0x6FF1,
0x6FEE, 0x6FDB, 0x7009, 0x700B, 0x6FFA, 0x7011, 0x7001, 0x700F,
0x6FFE, 0x701B, 0x701A, 0x6F74, 0x701D, 0x7018, 0x701F, 0x7030,
0x703E, 0x7032, 0x7051, 0x7063, 0x7099, 0x7092, 0x70AF, 0x70F1,
0x70AC, 0x70B8, 0x70B3, 0x70AE, 0x70DF, 0x70CB, 0x70DD, 0x70D9,
0x7109, 0x70FD, 0x711C, 0x7119, 0x7165, 0x7155, 0x7188, 0x7166,
0x7162, 0x714C, 0x7156, 0x716C, 0x718F, 0x71FB, 0x7184, 0x7195,
0x71A8, 0x71AC, 0x71D7, 0x71B9, 0x71BE, 0x71D2, 0x71C9, 0x71D4,
0x71CE, 0x71E0, 0x71EC, 0x71E7, 0x71F5, 0x71FC},
{ /* category 64 */
0x71F9, 0x71FF, 0x720D, 0x7210, 0x721B, 0x7228, 0x722D, 0x722C,
0x7230, 0x7232, 0x723B, 0x723C, 0x723F, 0x7240, 0x7246, 0x724B,
0x7258, 0x7274, 0x727E, 0x7282, 0x7281, 0x7287, 0x7292, 0x7296,
0x72A2, 0x72A7, 0x72B9, 0x72B2, 0x72C3, 0x72C6, 0x72C4, 0x72CE,
0x72D2, 0x72E2, 0x72E0, 0x72E1, 0x72F9, 0x72F7, 0x500F, 0x7317,
0x730A, 0x731C, 0x7316, 0x731D, 0x7334, 0x732F, 0x7329, 0x7325,
0x733E, 0x734E, 0x734F, 0x9ED8, 0x7357, 0x736A, 0x7368, 0x7370,
0x7378, 0x7375, 0x737B, 0x737A, 0x73C8, 0x73B3, 0x73CE, 0x73BB,
0x73C0, 0x73E5, 0x73EE, 0x73DE, 0x74A2, 0x7405, 0x746F, 0x7425,
0x73F8, 0x7432, 0x743A, 0x7455, 0x743F, 0x745F, 0x7459, 0x7441,
0x745C, 0x7469, 0x7470, 0x7463, 0x746A, 0x7476, 0x747E, 0x748B,
0x749E, 0x74A7, 0x74CA, 0x74CF, 0x74D4, 0x73F1},
{ /* category 65 */
0x74E0, 0x74E3, 0x74E7, 0x74E9, 0x74EE, 0x74F2, 0x74F0, 0x74F1,
0x74F8, 0x74F7, 0x7504, 0x7503, 0x7505, 0x750C, 0x750E, 0x750D,
0x7515, 0x7513, 0x751E, 0x7526, 0x752C, 0x753C, 0x7544, 0x754D,
0x754A, 0x7549, 0x755B, 0x7546, 0x755A, 0x7569, 0x7564, 0x7567,
0x756B, 0x756D, 0x7578, 0x7576, 0x7586, 0x7587, 0x7574, 0x758A,
0x7589, 0x7582, 0x7594, 0x759A, 0x759D, 0x75A5, 0x75A3, 0x75C2,
0x75B3, 0x75C3, 0x75B5, 0x75BD, 0x75B8, 0x75BC, 0x75B1, 0x75CD,
0x75CA, 0x75D2, 0x75D9, 0x75E3, 0x75DE, 0x75FE, 0x75FF, 0x75FC,
0x7601, 0x75F0, 0x75FA, 0x75F2, 0x75F3, 0x760B, 0x760D, 0x7609,
0x761F, 0x7627, 0x7620, 0x7621, 0x7622, 0x7624, 0x7634, 0x7630,
0x763B, 0x7647, 0x7648, 0x7646, 0x765C, 0x7658, 0x7661, 0x7662,
0x7668, 0x7669, 0x766A, 0x7667, 0x766C, 0x7670},
{ /* category 66 */
0x7672, 0x7676, 0x7678, 0x767C, 0x7680, 0x7683, 0x7688, 0x768B,
0x768E, 0x7696, 0x7693, 0x7699, 0x769A, 0x76B0, 0x76B4, 0x76B8,
0x76B9, 0x76BA, 0x76C2, 0x76CD, 0x76D6, 0x76D2, 0x76DE, 0x76E1,
0x76E5, 0x76E7, 0x76EA, 0x862F, 0x76FB, 0x7708, 0x7707, 0x7704,
0x7729, 0x7724, 0x771E, 0x7725, 0x7726, 0x771B, 0x7737, 0x7738,
0x7747, 0x775A, 0x7768, 0x776B, 0x775B, 0x7765, 0x777F, 0x777E,
0x7779, 0x778E, 0x778B, 0x7791, 0x77A0, 0x779E, 0x77B0, 0x77B6,
0x77B9, 0x77BF, 0x77BC, 0x77BD, 0x77BB, 0x77C7, 0x77CD, 0x77D7,
0x77DA, 0x77DC, 0x77E3, 0x77EE, 0x77FC, 0x780C, 0x7812, 0x7926,
0x7820, 0x792A, 0x7845, 0x788E, 0x7874, 0x7886, 0x787C, 0x789A,
0x788C, 0x78A3, 0x78B5, 0x78AA, 0x78AF, 0x78D1, 0x78C6, 0x78CB,
0x78D4, 0x78BE, 0x78BC, 0x78C5, 0x78CA, 0x78EC},
{ /* category 67 */
0x78E7, 0x78DA, 0x78FD, 0x78F4, 0x7907, 0x7912, 0x7911, 0x7919,
0x792C, 0x792B, 0x7940, 0x7960, 0x7957, 0x795F, 0x795A, 0x7955,
0x7953, 0x797A, 0x797F, 0x798A, 0x799D, 0x79A7, 0x9F4B, 0x79AA,
0x79AE, 0x79B3, 0x79B9, 0x79BA, 0x79C9, 0x79D5, 0x79E7, 0x79EC,
0x79E1, 0x79E3, 0x7A08, 0x7A0D, 0x7A18, 0x7A19, 0x7A20, 0x7A1F,
0x7980, 0x7A31, 0x7A3B, 0x7A3E, 0x7A37, 0x7A43, 0x7A57, 0x7A49,
0x7A61, 0x7A62, 0x7A69, 0x9F9D, 0x7A70, 0x7A79, 0x7A7D, 0x7A88,
0x7A97, 0x7A95, 0x7A98, 0x7A96, 0x7AA9, 0x7AC8, 0x7AB0, 0x7AB6,
0x7AC5, 0x7AC4, 0x7ABF, 0x9083, 0x7AC7, 0x7ACA, 0x7ACD, 0x7ACF,
0x7AD5, 0x7AD3, 0x7AD9, 0x7ADA, 0x7ADD, 0x7AE1, 0x7AE2, 0x7AE6,
0x7AED, 0x7AF0, 0x7B02, 0x7B0F, 0x7B0A, 0x7B06, 0x7B33, 0x7B18,
0x7B19, 0x7B1E, 0x7B35, 0x7B28, 0x7B36, 0x7B50},
{ /* category 68 */
0x7B7A, 0x7B04, 0x7B4D, 0x7B0B, 0x7B4C, 0x7B45, 0x7B75, 0x7B65,
0x7B74, 0x7B67, 0x7B70, 0x7B71, 0x7B6C, 0x7B6E, 0x7B9D, 0x7B98,
0x7B9F, 0x7B8D, 0x7B9C, 0x7B9A, 0x7B8B, 0x7B92, 0x7B8F, 0x7B5D,
0x7B99, 0x7BCB, 0x7BC1, 0x7BCC, 0x7BCF, 0x7BB4, 0x7BC6, 0x7BDD,
0x7BE9, 0x7C11, 0x7C14, 0x7BE6, 0x7BE5, 0x7C60, 0x7C00, 0x7C07,
0x7C13, 0x7BF3, 0x7BF7, 0x7C17, 0x7C0D, 0x7BF6, 0x7C23, 0x7C27,
0x7C2A, 0x7C1F, 0x7C37, 0x7C2B, 0x7C3D, 0x7C4C, 0x7C43, 0x7C54,
0x7C4F, 0x7C40, 0x7C50, 0x7C58, 0x7C5F, 0x7C64, 0x7C56, 0x7C65,
0x7C6C, 0x7C75, 0x7C83, 0x7C90, 0x7CA4, 0x7CAD, 0x7CA2, 0x7CAB,
0x7CA1, 0x7CA8, 0x7CB3, 0x7CB2, 0x7CB1, 0x7CAE, 0x7CB9, 0x7CBD,
0x7CC0, 0x7CC5, 0x7CC2, 0x7CD8, 0x7CD2, 0x7CDC, 0x7CE2, 0x9B3B,
0x7CEF, 0x7CF2, 0x7CF4, 0x7CF6, 0x7CFA, 0x7D06},
{ /* category 69 */
0x7D02, 0x7D1C, 0x7D15, 0x7D0A, 0x7D45, 0x7D4B, 0x7D2E, 0x7D32,
0x7D3F, 0x7D35, 0x7D46, 0x7D73, 0x7D56, 0x7D4E, 0x7D72, 0x7D68,
0x7D6E, 0x7D4F, 0x7D63, 0x7D93, 0x7D89, 0x7D5B, 0x7D8F, 0x7D7D,
0x7D9B, 0x7DBA, 0x7DAE, 0x7DA3, 0x7DB5, 0x7DC7, 0x7DBD, 0x7DAB,
0x7E3D, 0x7DA2, 0x7DAF, 0x7DDC, 0x7DB8, 0x7D9F, 0x7DB0, 0x7DD8,
0x7DDD, 0x7DE4, 0x7DDE, 0x7DFB, 0x7DF2, 0x7DE1, 0x7E05, 0x7E0A,
0x7E23, 0x7E21, 0x7E12, 0x7E31, 0x7E1F, 0x7E09, 0x7E0B, 0x7E22,
0x7E46, 0x7E66, 0x7E3B, 0x7E35, 0x7E39, 0x7E43, 0x7E37, 0x7E32,
0x7E3A, 0x7E67, 0x7E5D, 0x7E56, 0x7E5E, 0x7E59, 0x7E5A, 0x7E79,
0x7E6A, 0x7E69, 0x7E7C, 0x7E7B, 0x7E83, 0x7DD5, 0x7E7D, 0x8FAE,
0x7E7F, 0x7E88, 0x7E89, 0x7E8C, 0x7E92, 0x7E90, 0x7E93, 0x7E94,
0x7E96, 0x7E8E, 0x7E9B, 0x7E9C, 0x7F38, 0x7F3A},
{ /* category 70 */
0x7F45, 0x7F4C, 0x7F4D, 0x7F4E, 0x7F50, 0x7F51, 0x7F55, 0x7F54,
0x7F58, 0x7F5F, 0x7F60, 0x7F68, 0x7F69, 0x7F67, 0x7F78, 0x7F82,
0x7F86, 0x7F83, 0x7F88, 0x7F87, 0x7F8C, 0x7F94, 0x7F9E, 0x7F9D,
0x7F9A, 0x7FA3, 0x7FAF, 0x7FB2, 0x7FB9, 0x7FAE, 0x7FB6, 0x7FB8,
0x8B71, 0x7FC5, 0x7FC6, 0x7FCA, 0x7FD5, 0x7FD4, 0x7FE1, 0x7FE6,
0x7FE9, 0x7FF3, 0x7FF9, 0x98DC, 0x8006, 0x8004, 0x800B, 0x8012,
0x8018, 0x8019, 0x801C, 0x8021, 0x8028, 0x803F, 0x803B, 0x804A,
0x8046, 0x8052, 0x8058, 0x805A, 0x805F, 0x8062, 0x8068, 0x8073,
0x8072, 0x8070, 0x8076, 0x8079, 0x807D, 0x807F, 0x8084, 0x8086,
0x8085, 0x809B, 0x8093, 0x809A, 0x80AD, 0x5190, 0x80AC, 0x80DB,
0x80E5, 0x80D9, 0x80DD, 0x80C4, 0x80DA, 0x80D6, 0x8109, 0x80EF,
0x80F1, 0x811B, 0x8129, 0x8123, 0x812F, 0x814B},
{ /* category 71 */
0x968B, 0x8146, 0x813E, 0x8153, 0x8151, 0x80FC, 0x8171, 0x816E,
0x8165, 0x8166, 0x8174, 0x8183, 0x8188, 0x818A, 0x8180, 0x8182,
0x81A0, 0x8195, 0x81A4, 0x81A3, 0x815F, 0x8193, 0x81A9, 0x81B0,
0x81B5, 0x81BE, 0x81B8, 0x81BD, 0x81C0, 0x81C2, 0x81BA, 0x81C9,
0x81CD, 0x81D1, 0x81D9, 0x81D8, 0x81C8, 0x81DA, 0x81DF, 0x81E0,
0x81E7, 0x81FA, 0x81FB, 0x81FE, 0x8201, 0x8202, 0x8205, 0x8207,
0x820A, 0x820D, 0x8210, 0x8216, 0x8229, 0x822B, 0x8238, 0x8233,
0x8240, 0x8259, 0x8258, 0x825D, 0x825A, 0x825F, 0x8264, 0x8262,
0x8268, 0x826A, 0x826B, 0x822E, 0x8271, 0x8277, 0x8278, 0x827E,
0x828D, 0x8292, 0x82AB, 0x829F, 0x82BB, 0x82AC, 0x82E1, 0x82E3,
0x82DF, 0x82D2, 0x82F4, 0x82F3, 0x82FA, 0x8393, 0x8303, 0x82FB,
0x82F9, 0x82DE, 0x8306, 0x82DC, 0x8309, 0x82D9},
{ /* category 72 */
0x8335, 0x8334, 0x8316, 0x8332, 0x8331, 0x8340, 0x8339, 0x8350,
0x8345, 0x832F, 0x832B, 0x8317, 0x8318, 0x8385, 0x839A, 0x83AA,
0x839F, 0x83A2, 0x8396, 0x8323, 0x838E, 0x8387, 0x838A, 0x837C,
0x83B5, 0x8373, 0x8375, 0x83A0, 0x8389, 0x83A8, 0x83F4, 0x8413,
0x83EB, 0x83CE, 0x83FD, 0x8403, 0x83D8, 0x840B, 0x83C1, 0x83F7,
0x8407, 0x83E0, 0x83F2, 0x840D, 0x8422, 0x8420, 0x83BD, 0x8438,
0x8506, 0x83FB, 0x846D, 0x842A, 0x843C, 0x855A, 0x8484, 0x8477,
0x846B, 0x84AD, 0x846E, 0x8482, 0x8469, 0x8446, 0x842C, 0x846F,
0x8479, 0x8435, 0x84CA, 0x8462, 0x84B9, 0x84BF, 0x849F, 0x84D9,
0x84CD, 0x84BB, 0x84DA, 0x84D0, 0x84C1, 0x84C6, 0x84D6, 0x84A1,
0x8521, 0x84FF, 0x84F4, 0x8517, 0x8518, 0x852C, 0x851F, 0x8515,
0x8514, 0x84FC, 0x8540, 0x8563, 0x8558, 0x8548},
{ /* category 73 */
0x8541, 0x8602, 0x854B, 0x8555, 0x8580, 0x85A4, 0x8588, 0x8591,
0x858A, 0x85A8, 0x856D, 0x8594, 0x859B, 0x85EA, 0x8587, 0x859C,
0x8577, 0x857E, 0x8590, 0x85C9, 0x85BA, 0x85CF, 0x85B9, 0x85D0,
0x85D5, 0x85DD, 0x85E5, 0x85DC, 0x85F9, 0x860A, 0x8613, 0x860B,
0x85FE, 0x85FA, 0x8606, 0x8622, 0x861A, 0x8630, 0x863F, 0x864D,
0x4E55, 0x8654, 0x865F, 0x8667, 0x8671, 0x8693, 0x86A3, 0x86A9,
0x86AA, 0x868B, 0x868C, 0x86B6, 0x86AF, 0x86C4, 0x86C6, 0x86B0,
0x86C9, 0x8823, 0x86AB, 0x86D4, 0x86DE, 0x86E9, 0x86EC, 0x86DF,
0x86DB, 0x86EF, 0x8712, 0x8706, 0x8708, 0x8700, 0x8703, 0x86FB,
0x8711, 0x8709, 0x870D, 0x86F9, 0x870A, 0x8734, 0x873F, 0x8737,
0x873B, 0x8725, 0x8729, 0x871A, 0x8760, 0x875F, 0x8778, 0x874C,
0x874E, 0x8774, 0x8757, 0x8768, 0x876E, 0x8759},
{ /* category 74 */
0x8753, 0x8763, 0x876A, 0x8805, 0x87A2, 0x879F, 0x8782, 0x87AF,
0x87CB, 0x87BD, 0x87C0, 0x87D0, 0x96D6, 0x87AB, 0x87C4, 0x87B3,
0x87C7, 0x87C6, 0x87BB, 0x87EF, 0x87F2, 0x87E0, 0x880F, 0x880D,
0x87FE, 0x87F6, 0x87F7, 0x880E, 0x87D2, 0x8811, 0x8816, 0x8815,
0x8822, 0x8821, 0x8831, 0x8836, 0x8839, 0x8827, 0x883B, 0x8844,
0x8842, 0x8852, 0x8859, 0x885E, 0x8862, 0x886B, 0x8881, 0x887E,
0x889E, 0x8875, 0x887D, 0x88B5, 0x8872, 0x8882, 0x8897, 0x8892,
0x88AE, 0x8899, 0x88A2, 0x888D, 0x88A4, 0x88B0, 0x88BF, 0x88B1,
0x88C3, 0x88C4, 0x88D4, 0x88D8, 0x88D9, 0x88DD, 0x88F9, 0x8902,
0x88FC, 0x88F4, 0x88E8, 0x88F2, 0x8904, 0x890C, 0x890A, 0x8913,
0x8943, 0x891E, 0x8925, 0x892A, 0x892B, 0x8941, 0x8944, 0x893B,
0x8936, 0x8938, 0x894C, 0x891D, 0x8960, 0x895E},
{ /* category 75 */
0x8966, 0x8964, 0x896D, 0x896A, 0x896F, 0x8974, 0x8977, 0x897E,
0x8983, 0x8988, 0x898A, 0x8993, 0x8998, 0x89A1, 0x89A9, 0x89A6,
0x89AC, 0x89AF, 0x89B2, 0x89BA, 0x89BD, 0x89BF, 0x89C0, 0x89DA,
0x89DC, 0x89DD, 0x89E7, 0x89F4, 0x89F8, 0x8A03, 0x8A16, 0x8A10,
0x8A0C, 0x8A1B, 0x8A1D, 0x8A25, 0x8A36, 0x8A41, 0x8A5B, 0x8A52,
0x8A46, 0x8A48, 0x8A7C, 0x8A6D, 0x8A6C, 0x8A62, 0x8A85, 0x8A82,
0x8A84, 0x8AA8, 0x8AA1, 0x8A91, 0x8AA5, 0x8AA6, 0x8A9A, 0x8AA3,
0x8AC4, 0x8ACD, 0x8AC2, 0x8ADA, 0x8AEB, 0x8AF3, 0x8AE7, 0x8AE4,
0x8AF1, 0x8B14, 0x8AE0, 0x8AE2, 0x8AF7, 0x8ADE, 0x8ADB, 0x8B0C,
0x8B07, 0x8B1A, 0x8AE1, 0x8B16, 0x8B10, 0x8B17, 0x8B20, 0x8B33,
0x97AB, 0x8B26, 0x8B2B, 0x8B3E, 0x8B28, 0x8B41, 0x8B4C, 0x8B4F,
0x8B4E, 0x8B49, 0x8B56, 0x8B5B, 0x8B5A, 0x8B6B},
{ /* category 76 */
0x8B5F, 0x8B6C, 0x8B6F, 0x8B74, 0x8B7D, 0x8B80, 0x8B8C, 0x8B8E,
0x8B92, 0x8B93, 0x8B96, 0x8B99, 0x8B9A, 0x8C3A, 0x8C41, 0x8C3F,
0x8C48, 0x8C4C, 0x8C4E, 0x8C50, 0x8C55, 0x8C62, 0x8C6C, 0x8C78,
0x8C7A, 0x8C82, 0x8C89, 0x8C85, 0x8C8A, 0x8C8D, 0x8C8E, 0x8C94,
0x8C7C, 0x8C98, 0x621D, 0x8CAD, 0x8CAA, 0x8CBD, 0x8CB2, 0x8CB3,
0x8CAE, 0x8CB6, 0x8CC8, 0x8CC1, 0x8CE4, 0x8CE3, 0x8CDA, 0x8CFD,
0x8CFA, 0x8CFB, 0x8D04, 0x8D05, 0x8D0A, 0x8D07, 0x8D0F, 0x8D0D,
0x8D10, 0x9F4E, 0x8D13, 0x8CCD, 0x8D14, 0x8D16, 0x8D67, 0x8D6D,
0x8D71, 0x8D73, 0x8D81, 0x8D99, 0x8DC2, 0x8DBE, 0x8DBA, 0x8DCF,
0x8DDA, 0x8DD6, 0x8DCC, 0x8DDB, 0x8DCB, 0x8DEA, 0x8DEB, 0x8DDF,
0x8DE3, 0x8DFC, 0x8E08, 0x8E09, 0x8DFF, 0x8E1D, 0x8E1E, 0x8E10,
0x8E1F, 0x8E42, 0x8E35, 0x8E30, 0x8E34, 0x8E4A},
{ /* category 77 */
0x8E47, 0x8E49, 0x8E4C, 0x8E50, 0x8E48, 0x8E59, 0x8E64, 0x8E60,
0x8E2A, 0x8E63, 0x8E55, 0x8E76, 0x8E72, 0x8E7C, 0x8E81, 0x8E87,
0x8E85, 0x8E84, 0x8E8B, 0x8E8A, 0x8E93, 0x8E91, 0x8E94, 0x8E99,
0x8EAA, 0x8EA1, 0x8EAC, 0x8EB0, 0x8EC6, 0x8EB1, 0x8EBE, 0x8EC5,
0x8EC8, 0x8ECB, 0x8EDB, 0x8EE3, 0x8EFC, 0x8EFB, 0x8EEB, 0x8EFE,
0x8F0A, 0x8F05, 0x8F15, 0x8F12, 0x8F19, 0x8F13, 0x8F1C, 0x8F1F,
0x8F1B, 0x8F0C, 0x8F26, 0x8F33, 0x8F3B, 0x8F39, 0x8F45, 0x8F42,
0x8F3E, 0x8F4C, 0x8F49, 0x8F46, 0x8F4E, 0x8F57, 0x8F5C, 0x8F62,
0x8F63, 0x8F64, 0x8F9C, 0x8F9F, 0x8FA3, 0x8FAD, 0x8FAF, 0x8FB7,
0x8FDA, 0x8FE5, 0x8FE2, 0x8FEA, 0x8FEF, 0x9087, 0x8FF4, 0x9005,
0x8FF9, 0x8FFA, 0x9011, 0x9015, 0x9021, 0x900D, 0x901E, 0x9016,
0x900B, 0x9027, 0x9036, 0x9035, 0x9039, 0x8FF8},
{ /* category 78 */
0x904F, 0x9050, 0x9051, 0x9052, 0x900E, 0x9049, 0x903E, 0x9056,
0x9058, 0x905E, 0x9068, 0x906F, 0x9076, 0x96A8, 0x9072, 0x9082,
0x907D, 0x9081, 0x9080, 0x908A, 0x9089, 0x908F, 0x90A8, 0x90AF,
0x90B1, 0x90B5, 0x90E2, 0x90E4, 0x6248, 0x90DB, 0x9102, 0x9112,
0x9119, 0x9132, 0x9130, 0x914A, 0x9156, 0x9158, 0x9163, 0x9165,
0x9169, 0x9173, 0x9172, 0x918B, 0x9189, 0x9182, 0x91A2, 0x91AB,
0x91AF, 0x91AA, 0x91B5, 0x91B4, 0x91BA, 0x91C0, 0x91C1, 0x91C9,
0x91CB, 0x91D0, 0x91D6, 0x91DF, 0x91E1, 0x91DB, 0x91FC, 0x91F5,
0x91F6, 0x921E, 0x91FF, 0x9214, 0x922C, 0x9215, 0x9211, 0x925E,
0x9257, 0x9245, 0x9249, 0x9264, 0x9248, 0x9295, 0x923F, 0x924B,
0x9250, 0x929C, 0x9296, 0x9293, 0x929B, 0x925A, 0x92CF, 0x92B9,
0x92B7, 0x92E9, 0x930F, 0x92FA, 0x9344, 0x932E},
{ /* category 79 */
0x9319, 0x9322, 0x931A, 0x9323, 0x933A, 0x9335, 0x933B, 0x935C,
0x9360, 0x937C, 0x936E, 0x9356, 0x93B0, 0x93AC, 0x93AD, 0x9394,
0x93B9, 0x93D6, 0x93D7, 0x93E8, 0x93E5, 0x93D8, 0x93C3, 0x93DD,
0x93D0, 0x93C8, 0x93E4, 0x941A, 0x9414, 0x9413, 0x9403, 0x9407,
0x9410, 0x9436, 0x942B, 0x9435, 0x9421, 0x943A, 0x9441, 0x9452,
0x9444, 0x945B, 0x9460, 0x9462, 0x945E, 0x946A, 0x9229, 0x9470,
0x9475, 0x9477, 0x947D, 0x945A, 0x947C, 0x947E, 0x9481, 0x947F,
0x9582, 0x9587, 0x958A, 0x9594, 0x9596, 0x9598, 0x9599, 0x95A0,
0x95A8, 0x95A7, 0x95AD, 0x95BC, 0x95BB, 0x95B9, 0x95BE, 0x95CA,
0x6FF6, 0x95C3, 0x95CD, 0x95CC, 0x95D5, 0x95D4, 0x95D6, 0x95DC,
0x95E1, 0x95E5, 0x95E2, 0x9621, 0x9628, 0x962E, 0x962F, 0x9642,
0x964C, 0x964F, 0x964B, 0x9677, 0x965C, 0x965E},
{ /* category 80 */
0x965D, 0x965F, 0x9666, 0x9672, 0x966C, 0x968D, 0x9698, 0x9695,
0x9697, 0x96AA, 0x96A7, 0x96B1, 0x96B2, 0x96B0, 0x96B4, 0x96B6,
0x96B8, 0x96B9, 0x96CE, 0x96CB, 0x96C9, 0x96CD, 0x894D, 0x96DC,
0x970D, 0x96D5, 0x96F9, 0x9704, 0x9706, 0x9708, 0x9713, 0x970E,
0x9711, 0x970F, 0x9716, 0x9719, 0x9724, 0x972A, 0x9730, 0x9739,
0x973D, 0x973E, 0x9744, 0x9746, 0x9748, 0x9742, 0x9749, 0x975C,
0x9760, 0x9764, 0x9766, 0x9768, 0x52D2, 0x976B, 0x9771, 0x9779,
0x9785, 0x977C, 0x9781, 0x977A, 0x9786, 0x978B, 0x978F, 0x9790,
0x979C, 0x97A8, 0x97A6, 0x97A3, 0x97B3, 0x97B4, 0x97C3, 0x97C6,
0x97C8, 0x97CB, 0x97DC, 0x97ED, 0x9F4F, 0x97F2, 0x7ADF, 0x97F6,
0x97F5, 0x980F, 0x980C, 0x9838, 0x9824, 0x9821, 0x9837, 0x983D,
0x9846, 0x984F, 0x984B, 0x986B, 0x986F, 0x9870},
{ /* category 81 */
0x9871, 0x9874, 0x9873, 0x98AA, 0x98AF, 0x98B1, 0x98B6, 0x98C4,
0x98C3, 0x98C6, 0x98E9, 0x98EB, 0x9903, 0x9909, 0x9912, 0x9914,
0x9918, 0x9921, 0x991D, 0x991E, 0x9924, 0x9920, 0x992C, 0x992E,
0x993D, 0x993E, 0x9942, 0x9949, 0x9945, 0x9950, 0x994B, 0x9951,
0x9952, 0x994C, 0x9955, 0x9997, 0x9998, 0x99A5, 0x99AD, 0x99AE,
0x99BC, 0x99DF, 0x99DB, 0x99DD, 0x99D8, 0x99D1, 0x99ED, 0x99EE,
0x99F1, 0x99F2, 0x99FB, 0x99F8, 0x9A01, 0x9A0F, 0x9A05, 0x99E2,
0x9A19, 0x9A2B, 0x9A37, 0x9A45, 0x9A42, 0x9A40, 0x9A43, 0x9A3E,
0x9A55, 0x9A4D, 0x9A5B, 0x9A57, 0x9A5F, 0x9A62, 0x9A65, 0x9A64,
0x9A69, 0x9A6B, 0x9A6A, 0x9AAD, 0x9AB0, 0x9ABC, 0x9AC0, 0x9ACF,
0x9AD1, 0x9AD3, 0x9AD4, 0x9ADE, 0x9ADF, 0x9AE2, 0x9AE3, 0x9AE6,
0x9AEF, 0x9AEB, 0x9AEE, 0x9AF4, 0x9AF1, 0x9AF7},
{ /* category 82 */
0x9AFB, 0x9B06, 0x9B18, 0x9B1A, 0x9B1F, 0x9B22, 0x9B23, 0x9B25,
0x9B27, 0x9B28, 0x9B29, 0x9B2A, 0x9B2E, 0x9B2F, 0x9B32, 0x9B44,
0x9B43, 0x9B4F, 0x9B4D, 0x9B4E, 0x9B51, 0x9B58, 0x9B74, 0x9B93,
0x9B83, 0x9B91, 0x9B96, 0x9B97, 0x9B9F, 0x9BA0, 0x9BA8, 0x9BB4,
0x9BC0, 0x9BCA, 0x9BB9, 0x9BC6, 0x9BCF, 0x9BD1, 0x9BD2, 0x9BE3,
0x9BE2, 0x9BE4, 0x9BD4, 0x9BE1, 0x9C3A, 0x9BF2, 0x9BF1, 0x9BF0,
0x9C15, 0x9C14, 0x9C09, 0x9C13, 0x9C0C, 0x9C06, 0x9C08, 0x9C12,
0x9C0A, 0x9C04, 0x9C2E, 0x9C1B, 0x9C25, 0x9C24, 0x9C21, 0x9C30,
0x9C47, 0x9C32, 0x9C46, 0x9C3E, 0x9C5A, 0x9C60, 0x9C67, 0x9C76,
0x9C78, 0x9CE7, 0x9CEC, 0x9CF0, 0x9D09, 0x9D08, 0x9CEB, 0x9D03,
0x9D06, 0x9D2A, 0x9D26, 0x9DAF, 0x9D23, 0x9D1F, 0x9D44, 0x9D15,
0x9D12, 0x9D41, 0x9D3F, 0x9D3E, 0x9D46, 0x9D48},
{ /* category 83 */
0x9D5D, 0x9D5E, 0x9D64, 0x9D51, 0x9D50, 0x9D59, 0x9D72, 0x9D89,
0x9D87, 0x9DAB, 0x9D6F, 0x9D7A, 0x9D9A, 0x9DA4, 0x9DA9, 0x9DB2,
0x9DC4, 0x9DC1, 0x9DBB, 0x9DB8, 0x9DBA, 0x9DC6, 0x9DCF, 0x9DC2,
0x9DD9, 0x9DD3, 0x9DF8, 0x9DE6, 0x9DED, 0x9DEF, 0x9DFD, 0x9E1A,
0x9E1B, 0x9E1E, 0x9E75, 0x9E79, 0x9E7D, 0x9E81, 0x9E88, 0x9E8B,
0x9E8C, 0x9E92, 0x9E95, 0x9E91, 0x9E9D, 0x9EA5, 0x9EA9, 0x9EB8,
0x9EAA, 0x9EAD, 0x9761, 0x9ECC, 0x9ECE, 0x9ECF, 0x9ED0, 0x9ED4,
0x9EDC, 0x9EDE, 0x9EDD, 0x9EE0, 0x9EE5, 0x9EE8, 0x9EEF, 0x9EF4,
0x9EF6, 0x9EF7, 0x9EF9, 0x9EFB, 0x9EFC, 0x9EFD, 0x9F07, 0x9F08,
0x76B7, 0x9F15, 0x9F21, 0x9F2C, 0x9F3E, 0x9F4A, 0x9F52, 0x9F54,
0x9F63, 0x9F5F, 0x9F60, 0x9F61, 0x9F66, 0x9F67, 0x9F6C, 0x9F6A,
0x9F77, 0x9F72, 0x9F76, 0x9F95, 0x9F9C, 0x9FA0},
{ /* category 84 */
0x582F, 0x69C7, 0x9059, 0x7464, 0x51DC, 0x7199, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
{ /* category 85 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
{ /* category 86 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
{ /* category 87 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
{ /* category 88 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
{ /* category 89 */
0x7E8A, 0x891C, 0x9348, 0x9288, 0x84DC, 0x4FC9, 0x70BB, 0x6631,
0x68C8, 0x92F9, 0x66FB, 0x5F45, 0x4E28, 0x4EE1, 0x4EFC, 0x4F00,
0x4F03, 0x4F39, 0x4F56, 0x4F92, 0x4F8A, 0x4F9A, 0x4F94, 0x4FCD,
0x5040, 0x5022, 0x4FFF, 0x501E, 0x5046, 0x5070, 0x5042, 0x5094,
0x50F4, 0x50D8, 0x514A, 0x5164, 0x519D, 0x51BE, 0x51EC, 0x5215,
0x529C, 0x52A6, 0x52C0, 0x52DB, 0x5300, 0x5307, 0x5324, 0x5372,
0x5393, 0x53B2, 0x53DD, 0xFA0E, 0x549C, 0x548A, 0x54A9, 0x54FF,
0x5586, 0x5759, 0x5765, 0x57AC, 0x57C8, 0x57C7, 0xFA0F, 0xFA10,
0x589E, 0x58B2, 0x590B, 0x5953, 0x595B, 0x595D, 0x5963, 0x59A4,
0x59BA, 0x5B56, 0x5BC0, 0x752F, 0x5BD8, 0x5BEC, 0x5C1E, 0x5CA6,
0x5CBA, 0x5CF5, 0x5D27, 0x5D53, 0xFA11, 0x5D42, 0x5D6D, 0x5DB8,
0x5DB9, 0x5DD0, 0x5F21, 0x5F34, 0x5F67, 0x5FB7},
{ /* category 90 */
0x5FDE, 0x605D, 0x6085, 0x608A, 0x60DE, 0x60D5, 0x6120, 0x60F2,
0x6111, 0x6137, 0x6130, 0x6198, 0x6213, 0x62A6, 0x63F5, 0x6460,
0x649D, 0x64CE, 0x654E, 0x6600, 0x6615, 0x663B, 0x6609, 0x662E,
0x661E, 0x6624, 0x6665, 0x6657, 0x6659, 0xFA12, 0x6673, 0x6699,
0x66A0, 0x66B2, 0x66BF, 0x66FA, 0x670E, 0xF929, 0x6766, 0x67BB,
0x6852, 0x67C0, 0x6801, 0x6844, 0x68CF, 0xFA13, 0x6968, 0xFA14,
0x6998, 0x69E2, 0x6A30, 0x6A6B, 0x6A46, 0x6A73, 0x6A7E, 0x6AE2,
0x6AE4, 0x6BD6, 0x6C3F, 0x6C5C, 0x6C86, 0x6C6F, 0x6CDA, 0x6D04,
0x6D87, 0x6D6F, 0x6D96, 0x6DAC, 0x6DCF, 0x6DF8, 0x6DF2, 0x6DFC,
0x6E39, 0x6E5C, 0x6E27, 0x6E3C, 0x6EBF, 0x6F88, 0x6FB5, 0x6FF5,
0x7005, 0x7007, 0x7028, 0x7085, 0x70AB, 0x710F, 0x7104, 0x715C,
0x7146, 0x7147, 0xFA15, 0x71C1, 0x71FE, 0x72B1},
{ /* category 91 */
0x72BE, 0x7324, 0xFA16, 0x7377, 0x73BD, 0x73C9, 0x73D6, 0x73E3,
0x73D2, 0x7407, 0x73F5, 0x7426, 0x742A, 0x7429, 0x742E, 0x7462,
0x7489, 0x749F, 0x7501, 0x756F, 0x7682, 0x769C, 0x769E, 0x769B,
0x76A6, 0xFA17, 0x7746, 0x52AF, 0x7821, 0x784E, 0x7864, 0x787A,
0x7930, 0xFA18, 0xFA19, 0xFA1A, 0x7994, 0xFA1B, 0x799B, 0x7AD1,
0x7AE7, 0xFA1C, 0x7AEB, 0x7B9E, 0xFA1D, 0x7D48, 0x7D5C, 0x7DB7,
0x7DA0, 0x7DD6, 0x7E52, 0x7F47, 0x7FA1, 0xFA1E, 0x8301, 0x8362,
0x837F, 0x83C7, 0x83F6, 0x8448, 0x84B4, 0x8553, 0x8559, 0x856B,
0xFA1F, 0x85B0, 0xFA20, 0xFA21, 0x8807, 0x88F5, 0x8A12, 0x8A37,
0x8A79, 0x8AA7, 0x8ABE, 0x8ADF, 0xFA22, 0x8AF6, 0x8B53, 0x8B7F,
0x8CF0, 0x8CF4, 0x8D12, 0x8D76, 0xFA23, 0x8ECF, 0xFA24, 0xFA25,
0x9067, 0x90DE, 0xFA26, 0x9115, 0x9127, 0x91DA},
{ /* category 92 */
0x91D7, 0x91DE, 0x91ED, 0x91EE, 0x91E4, 0x91E5, 0x9206, 0x9210,
0x920A, 0x923A, 0x9240, 0x923C, 0x924E, 0x9259, 0x9251, 0x9239,
0x9267, 0x92A7, 0x9277, 0x9278, 0x92E7, 0x92D7, 0x92D9, 0x92D0,
0xFA27, 0x92D5, 0x92E0, 0x92D3, 0x9325, 0x9321, 0x92FB, 0xFA28,
0x931E, 0x92FF, 0x931D, 0x9302, 0x9370, 0x9357, 0x93A4, 0x93C6,
0x93DE, 0x93F8, 0x9431, 0x9445, 0x9448, 0x9592, 0xF9DC, 0xFA29,
0x969D, 0x96AF, 0x9733, 0x973B, 0x9743, 0x974D, 0x974F, 0x9751,
0x9755, 0x9857, 0x9865, 0xFA2A, 0xFA2B, 0x9927, 0xFA2C, 0x999E,
0x9A4E, 0x9AD9, 0x9ADC, 0x9B75, 0x9B72, 0x9B8F, 0x9BB1, 0x9BBB,
0x9C00, 0x9D70, 0x9D6B, 0xFA2D, 0x9E19, 0x9ED1, 0x0000, 0x0000,
0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177,
0x2178, 0x2179, 0xFFE2, 0xFFE4, 0xFF07, 0xFF02}};

#endif /* JISX0208_H */
php/ext/gd/libgd/wbmp.h000064400000002403151730540670010733 0ustar00/* WBMP
** ----
** WBMP Level 0: B/W, Uncompressed
** This implements the WBMP format as specified in WAPSpec 1.1 and 1.2.
** It does not support ExtHeaders as defined in the spec. The spec states
** that a WAP client does not need to implement ExtHeaders.
**
** (c) 2000 Johan Van den Brande <johan@vandenbrande.com>
**
** Header file
*/
#ifndef __WBMP_H
#define __WBMP_H	1

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php_compat.h"

/* WBMP struct
** -----------
** A Wireless bitmap structure
**
*/

typedef struct Wbmp_
{
    int type;           /* type of the wbmp */
    int width;          /* width of the image */
    int height;         /* height of the image */
    int *bitmap;        /* pointer to data: 0 = WHITE , 1 = BLACK */
} Wbmp;

#define WBMP_WHITE  1
#define WBMP_BLACK  0


/* Proto's
** -------
**
*/
void		putmbi( int i, void (*putout)(int c, void *out), void *out);
int 	getmbi ( int (*getin)(void *in), void *in );
int     skipheader( int (*getin)(void *in), void *in );
Wbmp   *createwbmp( int width, int height, int color );
int     readwbmp( int (*getin)(void *in), void *in, Wbmp **wbmp );
int		writewbmp( Wbmp *wbmp, void (*putout)( int c, void *out), void *out);
void    freewbmp( Wbmp *wbmp );
void    printwbmp( Wbmp *wbmp );

#endif
php/ext/gd/libgd/gd_io.h000064400000001666151730540670011061 0ustar00#ifndef GD_IO_H
#define GD_IO_H 1

#include <stdio.h>

#ifdef VMS
#define Putchar gdPutchar
#endif

typedef struct gdIOCtx {
	int	(*getC)(struct gdIOCtx*);
	int	(*getBuf)(struct gdIOCtx*, void*, int);

	void	(*putC)(struct gdIOCtx*, int);
	int	(*putBuf)(struct gdIOCtx*, const void*, int);

	int	(*seek)(struct gdIOCtx*, const int);
	long	(*tell)(struct gdIOCtx*);

	void	(*gd_free)(struct gdIOCtx*);

} gdIOCtx;

typedef struct gdIOCtx	*gdIOCtxPtr;

void Putword(int w, gdIOCtx *ctx);
void Putchar(int c, gdIOCtx *ctx);

void gdPutC(const unsigned char c, gdIOCtx *ctx);
int gdPutBuf(const void *, int, gdIOCtx*);
void gdPutWord(int w, gdIOCtx *ctx);
void gdPutInt(int w, gdIOCtx *ctx);

int gdGetC(gdIOCtx *ctx);
int gdGetBuf(void *, int, gdIOCtx*);
int gdGetByte(int *result, gdIOCtx *ctx);
int gdGetWord(int *result, gdIOCtx *ctx);
int gdGetInt(int *result, gdIOCtx *ctx);

int gdSeek(gdIOCtx *ctx, const int);
long gdTell(gdIOCtx *ctx);

#endif
php/ext/gd/libgd/gdfontg.h000064400000001021151730540700011403 0ustar00
#ifndef _GDFONTG_H_
#define _GDFONTG_H_ 1

#ifdef __cplusplus
extern "C" {
#endif

/*
	This is a header file for gd font, generated using
	bdftogd version 0.51 by Jan Pazdziora, adelton@fi.muni.cz
	from bdf font
	-Misc-Fixed-Bold-R-Normal-Sans-15-140-75-75-C-90-ISO8859-2
	at Mon Jan 26 14:45:58 1998.
	The original bdf was holding following copyright:
	"Libor Skarvada, libor@informatics.muni.cz"
 */


#include "gd.h"

extern gdFontPtr gdFontGiant;
extern gdFontPtr gdFontGetGiant(void);

#ifdef __cplusplus
}
#endif

#endif

php/ext/gd/libgd/gdfonts.h000064400000000753151730540700011432 0ustar00
#ifndef _GDFONTS_H_
#define _GDFONTS_H_ 1

#ifdef __cplusplus
extern "C" {
#endif

/*
	This is a header file for gd font, generated using
	bdftogd version 0.5 by Jan Pazdziora, adelton@fi.muni.cz
	from bdf font
	-misc-fixed-medium-r-semicondensed-sans-12-116-75-75-c-60-iso8859-2
	at Thu Jan  8 14:13:20 1998.
	No copyright info was found in the original bdf.
 */


#include "gd.h"

extern gdFontPtr gdFontSmall;
extern gdFontPtr gdFontGetSmall(void);

#ifdef __cplusplus
}
#endif

#endif

php/ext/gd/libgd/gdfontmb.h000064400000000757151730540710011573 0ustar00
#ifndef _GDFONTMB_H_
#define _GDFONTMB_H_ 1

#ifdef __cplusplus
extern "C" {
#endif

/*
	This is a header file for gd font, generated using
	bdftogd version 0.5 by Jan Pazdziora, adelton@fi.muni.cz
	from bdf font
	-misc-fixed-bold-r-normal-sans-13-94-100-100-c-70-iso8859-2
	at Thu Jan  8 13:54:57 1998.
	No copyright info was found in the original bdf.
 */


#include "gd.h"

extern gdFontPtr gdFontMediumBold;
extern gdFontPtr gdFontGetMediumBold(void);

#ifdef __cplusplus
}
#endif

#endif

php/ext/gd/libgd/gdfontl.h000064400000001017151730540710011416 0ustar00
#ifndef _GDFONTL_H_
#define _GDFONTL_H_ 1

#ifdef __cplusplus
extern "C" {
#endif

/*
	This is a header file for gd font, generated using
	bdftogd version 0.5 by Jan Pazdziora, adelton@fi.muni.cz
	from bdf font
	-misc-fixed-medium-r-normal--16-140-75-75-c-80-iso8859-2
	at Tue Jan  6 19:39:27 1998.

	The original bdf was holding following copyright:
	"Libor Skarvada, libor@informatics.muni.cz"
 */


#include "gd.h"

extern gdFontPtr gdFontLarge;
extern gdFontPtr gdFontGetLarge(void);

#ifdef __cplusplus
}
#endif

#endif

php/ext/gd/libgd/gd.h000064400000062412151730540720010362 0ustar00#ifndef GD_H
#define GD_H 1

#ifdef __cplusplus
extern "C" {
#endif

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php_compat.h"

#define GD_MAJOR_VERSION 2
#define GD_MINOR_VERSION 0
#define GD_RELEASE_VERSION 35
#define GD_EXTRA_VERSION ""
#define GD_VERSION_STRING "2.0.35"

#ifdef NETWARE
/* default fontpath for netware systems */
#define DEFAULT_FONTPATH "sys:/java/nwgfx/lib/x11/fonts/ttf;."
#define PATHSEPARATOR ";"
#elif defined(WIN32)
/* default fontpath for windows systems */
#define DEFAULT_FONTPATH "c:\\winnt\\fonts;c:\\windows\\fonts;."
#define PATHSEPARATOR ";"
#else
/* default fontpath for unix systems */
#define DEFAULT_FONTPATH "/usr/X11R6/lib/X11/fonts/TrueType:/usr/X11R6/lib/X11/fonts/truetype:/usr/X11R6/lib/X11/fonts/TTF:/usr/share/fonts/TrueType:/usr/share/fonts/truetype:/usr/openwin/lib/X11/fonts/TrueType:/usr/X11R6/lib/X11/fonts/Type1:."
#define PATHSEPARATOR ":"
#endif

/* gd.h: declarations file for the graphic-draw module.
 * 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." Thomas Boutell and
 * Boutell.Com, Inc. disclaim all warranties, either express or implied,
 * including but not limited to implied warranties of merchantability and
 * fitness for a particular purpose, with respect to this code and accompanying
 * documentation. */

/* stdio is needed for file I/O. */
#include <stdio.h>
#include "gd_io.h"

void php_gd_error_ex(int type, const char *format, ...);

void php_gd_error(const char *format, ...);


/* The maximum number of palette entries in palette-based images.
	In the wonderful new world of gd 2.0, you can of course have
	many more colors when using truecolor mode. */

#define gdMaxColors 256

/* 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. */

/* If 'truecolor' is set true, the image is truecolor;
	pixels are represented by integers, which
	must be 32 bits wide or more.

	True colors are repsented as follows:

	ARGB

	Where 'A' (alpha channel) occupies only the
	LOWER 7 BITS of the MSB. This very small
	loss of alpha channel resolution allows gd 2.x
	to keep backwards compatibility by allowing
	signed integers to be used to represent colors,
	and negative numbers to represent special cases,
	just as in gd 1.x. */

#define gdAlphaMax 127
#define gdAlphaOpaque 0
#define gdAlphaTransparent 127
#define gdRedMax 255
#define gdGreenMax 255
#define gdBlueMax 255
#define gdTrueColorGetAlpha(c) (((c) & 0x7F000000) >> 24)
#define gdTrueColorGetRed(c) (((c) & 0xFF0000) >> 16)
#define gdTrueColorGetGreen(c) (((c) & 0x00FF00) >> 8)
#define gdTrueColorGetBlue(c) ((c) & 0x0000FF)
#define gdEffectReplace 0
#define gdEffectAlphaBlend 1
#define gdEffectNormal 2
#define gdEffectOverlay 3


/* This function accepts truecolor pixel values only. The
	source color is composited with the destination color
	based on the alpha channel value of the source color.
	The resulting color is opaque. */

int gdAlphaBlend(int dest, int src);

typedef struct gdImageStruct {
	/* Palette-based image pixels */
	unsigned char ** pixels;
	int sx;
	int sy;
	/* These are valid in palette images only. See also
		'alpha', which appears later in the structure to
		preserve binary backwards compatibility */
	int colorsTotal;
	int red[gdMaxColors];
	int green[gdMaxColors];
	int blue[gdMaxColors];
	int open[gdMaxColors];
	/* For backwards compatibility, this is set to the
		first palette entry with 100% transparency,
		and is also set and reset by the
		gdImageColorTransparent function. Newer
		applications can allocate palette entries
		with any desired level of transparency; however,
		bear in mind that many viewers, notably
		many web browsers, fail to implement
		full alpha channel for PNG and provide
		support for full opacity or transparency only. */
	int transparent;
	int *polyInts;
	int polyAllocated;
	struct gdImageStruct *brush;
	struct gdImageStruct *tile;
	int brushColorMap[gdMaxColors];
	int tileColorMap[gdMaxColors];
	int styleLength;
	int stylePos;
	int *style;
	int interlace;
	/* New in 2.0: thickness of line. Initialized to 1. */
	int thick;
	/* New in 2.0: alpha channel for palettes. Note that only
		Macintosh Internet Explorer and (possibly) Netscape 6
		really support multiple levels of transparency in
		palettes, to my knowledge, as of 2/15/01. Most
		common browsers will display 100% opaque and
		100% transparent correctly, and do something
		unpredictable and/or undesirable for levels
		in between. TBB */
	int alpha[gdMaxColors];
	/* Truecolor flag and pixels. New 2.0 fields appear here at the
		end to minimize breakage of existing object code. */
	int trueColor;
	int ** tpixels;
	/* Should alpha channel be copied, or applied, each time a
		pixel is drawn? This applies to truecolor images only.
		No attempt is made to alpha-blend in palette images,
		even if semitransparent palette entries exist.
		To do that, build your image as a truecolor image,
		then quantize down to 8 bits. */
	int alphaBlendingFlag;
	/* Should antialias functions be used */
	int antialias;
	/* Should the alpha channel of the image be saved? This affects
		PNG at the moment; other future formats may also
		have that capability. JPEG doesn't. */
	int saveAlphaFlag;


	/* 2.0.12: anti-aliased globals */
	int AA;
	int AA_color;
	int AA_dont_blend;
	unsigned char **AA_opacity;
	int AA_polygon;
	/* Stored and pre-computed variables for determining the perpendicular
	 * distance from a point to the anti-aliased line being drawn:
	 */
	int AAL_x1;
	int AAL_y1;
	int AAL_x2;
	int AAL_y2;
	int AAL_Bx_Ax;
	int AAL_By_Ay;
	int AAL_LAB_2;
	float AAL_LAB;

	/* 2.0.12: simple clipping rectangle. These values must be checked for safety when set; please use gdImageSetClip */
	int cx1;
	int cy1;
	int cx2;
	int cy2;
} gdImage;

typedef gdImage * gdImagePtr;

typedef struct {
	/* # of characters in font */
	int nchars;
	/* First character is numbered... (usually 32 = space) */
	int offset;
	/* Character width and height */
	int w;
	int h;
	/* Font data; array of characters, one row after another.
		Easily included in code, also easily loaded from
		data files. */
	char *data;
} gdFont;

/* Text functions take these. */
typedef gdFont *gdFontPtr;

/* For backwards compatibility only. Use gdImageSetStyle()
	for MUCH more flexible line drawing. Also see
	gdImageSetBrush(). */
#define gdDashSize 4

/* Special colors. */

#define gdStyled (-2)
#define gdBrushed (-3)
#define gdStyledBrushed (-4)
#define gdTiled (-5)

/* NOT the same as the transparent color index.
	This is used in line styles only. */
#define gdTransparent (-6)

#define gdAntiAliased (-7)

/* Functions to manipulate images. */

/* Creates a palette-based image (up to 256 colors). */
gdImagePtr gdImageCreate(int sx, int sy);

/* An alternate name for the above (2.0). */
#define gdImageCreatePalette gdImageCreate

/* Creates a truecolor image (millions of colors). */
gdImagePtr gdImageCreateTrueColor(int sx, int sy);

/* Creates an image from various file types. These functions
	return a palette or truecolor image based on the
	nature of the file being loaded. Truecolor PNG
	stays truecolor; palette PNG stays palette-based;
	JPEG is always truecolor. */
gdImagePtr gdImageCreateFromPng(FILE *fd);
gdImagePtr gdImageCreateFromPngCtx(gdIOCtxPtr in);
gdImagePtr gdImageCreateFromWBMP(FILE *inFile);
gdImagePtr gdImageCreateFromWBMPCtx(gdIOCtx *infile);
gdImagePtr gdImageCreateFromJpeg(FILE *infile, int ignore_warning);
gdImagePtr gdImageCreateFromJpegCtx(gdIOCtx *infile, int ignore_warning);

/* A custom data source. */
/* The source function must return -1 on error, otherwise the number
        of bytes fetched. 0 is EOF, not an error! */
/* context will be passed to your source function. */

typedef struct {
        int (*source) (void *context, char *buffer, int len);
        void *context;
} gdSource, *gdSourcePtr;

gdImagePtr gdImageCreateFromPngSource(gdSourcePtr in);

gdImagePtr gdImageCreateFromGd(FILE *in);
gdImagePtr gdImageCreateFromGdCtx(gdIOCtxPtr in);

gdImagePtr gdImageCreateFromGd2(FILE *in);
gdImagePtr gdImageCreateFromGd2Ctx(gdIOCtxPtr in);

gdImagePtr gdImageCreateFromGd2Part(FILE *in, int srcx, int srcy, int w, int h);
gdImagePtr gdImageCreateFromGd2PartCtx(gdIOCtxPtr in, int srcx, int srcy, int w, int h);

gdImagePtr gdImageCreateFromXbm(FILE *fd);
void gdImageXbmCtx(gdImagePtr image, char* file_name, int fg, gdIOCtx * out);

gdImagePtr gdImageCreateFromXpm (char *filename);

void gdImageDestroy(gdImagePtr im);

/* Replaces or blends with the background depending on the
	most recent call to gdImageAlphaBlending and the
	alpha channel value of 'color'; default is to overwrite.
	Tiling and line styling are also implemented
	here. All other gd drawing functions pass through this call,
	allowing for many useful effects. */

void gdImageSetPixel(gdImagePtr im, int x, int y, int color);

int gdImageGetPixel(gdImagePtr im, int x, int y);

void gdImageAABlend(gdImagePtr im);

void gdImageLine(gdImagePtr im, int x1, int y1, int x2, int y2, int color);
void gdImageAALine(gdImagePtr im, int x1, int y1, int x2, int y2, int color);

/* For backwards compatibility only. Use gdImageSetStyle()
	for much more flexible line drawing. */
void gdImageDashedLine(gdImagePtr im, int x1, int y1, int x2, int y2, int color);
/* Corners specified (not width and height). Upper left first, lower right
 	second. */
void gdImageRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color);
/* Solid bar. Upper left corner first, lower right corner second. */
void gdImageFilledRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color);
void gdImageSetClip(gdImagePtr im, int x1, int y1, int x2, int y2);
void gdImageGetClip(gdImagePtr im, int *x1P, int *y1P, int *x2P, int *y2P);
void gdImageChar(gdImagePtr im, gdFontPtr f, int x, int y, int c, int color);
void gdImageCharUp(gdImagePtr im, gdFontPtr f, int x, int y, int c, int color);
void gdImageString(gdImagePtr im, gdFontPtr f, int x, int y, unsigned char *s, int color);
void gdImageStringUp(gdImagePtr im, gdFontPtr f, int x, int y, unsigned char *s, int color);
void gdImageString16(gdImagePtr im, gdFontPtr f, int x, int y, unsigned short *s, int color);
void gdImageStringUp16(gdImagePtr im, gdFontPtr f, int x, int y, unsigned short *s, int color);

/*
 * The following functions are required to be called prior to the
 * use of any sort of threads in a module load / shutdown function
 * respectively.
 */
void gdFontCacheMutexSetup();
void gdFontCacheMutexShutdown();

/* 2.0.16: for thread-safe use of gdImageStringFT and friends,
 * call this before allowing any thread to call gdImageStringFT.
 * Otherwise it is invoked by the first thread to invoke
 * gdImageStringFT, with a very small but real risk of a race condition.
 * Return 0 on success, nonzero on failure to initialize freetype.
 */
int gdFontCacheSetup(void);

/* Optional: clean up after application is done using fonts in gdImageStringFT(). */
void gdFontCacheShutdown(void);

/* Calls gdImageStringFT. Provided for backwards compatibility only. */
char *gdImageStringTTF(gdImage *im, int *brect, int fg, char *fontlist,
                double ptsize, double angle, int x, int y, char *string);

/* FreeType 2 text output */
char *gdImageStringFT(gdImage *im, int *brect, int fg, char *fontlist,
                double ptsize, double angle, int x, int y, char *string);

typedef struct {
	double linespacing;	/* fine tune line spacing for '\n' */
	int flags;		/* Logical OR of gdFTEX_ values */
	int charmap;		/* TBB: 2.0.12: may be gdFTEX_Unicode,
				   gdFTEX_Shift_JIS, or gdFTEX_Big5;
				   when not specified, maps are searched
				   for in the above order. */
	int hdpi;
	int vdpi;
}
 gdFTStringExtra, *gdFTStringExtraPtr;

#define gdFTEX_LINESPACE 1
#define gdFTEX_CHARMAP 2
#define gdFTEX_RESOLUTION 4

/* These are NOT flags; set one in 'charmap' if you set the gdFTEX_CHARMAP bit in 'flags'. */
#define gdFTEX_Unicode 0
#define gdFTEX_Shift_JIS 1
#define gdFTEX_Big5 2

/* FreeType 2 text output with fine tuning */
char *
gdImageStringFTEx(gdImage * im, int *brect, int fg, char * fontlist,
		double ptsize, double angle, int x, int y, char * string,
		gdFTStringExtraPtr strex);


/* Point type for use in polygon drawing. */
typedef struct {
	int x, y;
} gdPoint, *gdPointPtr;

void gdImagePolygon(gdImagePtr im, gdPointPtr p, int n, int c);
void gdImageFilledPolygon(gdImagePtr im, gdPointPtr p, int n, int c);

/* These functions still work with truecolor images,
	for which they never return error. */
int gdImageColorAllocate(gdImagePtr im, int r, int g, int b);
/* gd 2.0: palette entries with non-opaque transparency are permitted. */
int gdImageColorAllocateAlpha(gdImagePtr im, int r, int g, int b, int a);
/* Assumes opaque is the preferred alpha channel value */
int gdImageColorClosest(gdImagePtr im, int r, int g, int b);
/* Closest match taking all four parameters into account.
	A slightly different color with the same transparency
	beats the exact same color with radically different
	transparency */
int gdImageColorClosestAlpha(gdImagePtr im, int r, int g, int b, int a);
/* An alternate method */
int gdImageColorClosestHWB(gdImagePtr im, int r, int g, int b);
/* Returns exact, 100% opaque matches only */
int gdImageColorExact(gdImagePtr im, int r, int g, int b);
/* Returns an exact match only, including alpha */
int gdImageColorExactAlpha(gdImagePtr im, int r, int g, int b, int a);
/* Opaque only */
int gdImageColorResolve(gdImagePtr im, int r, int g, int b);
/* Based on gdImageColorExactAlpha and gdImageColorClosestAlpha */
int gdImageColorResolveAlpha(gdImagePtr im, int r, int g, int b, int a);

/* A simpler way to obtain an opaque truecolor value for drawing on a
	truecolor image. Not for use with palette images! */

#define gdTrueColor(r, g, b) (((r) << 16) + \
	((g) << 8) + \
	(b))

/* Returns a truecolor value with an alpha channel component.
	gdAlphaMax (127, **NOT 255**) is transparent, 0 is completely
	opaque. */

#define gdTrueColorAlpha(r, g, b, a) (((a) << 24) + \
	((r) << 16) + \
	((g) << 8) + \
	(b))

void gdImageColorDeallocate(gdImagePtr im, int color);

/* Converts a truecolor image to a palette-based image,
	using a high-quality two-pass quantization routine
	which attempts to preserve alpha channel information
	as well as R/G/B color information when creating
	a palette. If ditherFlag is set, the image will be
	dithered to approximate colors better, at the expense
	of some obvious "speckling." colorsWanted can be
	anything up to 256. If the original source image
	includes photographic information or anything that
	came out of a JPEG, 256 is strongly recommended.

	Better yet, don't use this function -- write real
	truecolor PNGs and JPEGs. The disk space gain of
        conversion to palette is not great (for small images
        it can be negative) and the quality loss is ugly. */

gdImagePtr gdImageCreatePaletteFromTrueColor (gdImagePtr im, int ditherFlag, int colorsWanted);

void gdImageTrueColorToPalette(gdImagePtr im, int ditherFlag, int colorsWanted);


/* An attempt at getting the results of gdImageTrueColorToPalette
	to look a bit more like the original (im1 is the original
	and im2 is the palette version */
int gdImageColorMatch(gdImagePtr im1, gdImagePtr im2);

/* Specifies a color index (if a palette image) or an
	RGB color (if a truecolor image) which should be
	considered 100% transparent. FOR TRUECOLOR IMAGES,
	THIS IS IGNORED IF AN ALPHA CHANNEL IS BEING
	SAVED. Use gdImageSaveAlpha(im, 0); to
	turn off the saving of a full alpha channel in
	a truecolor image. Note that gdImageColorTransparent
	is usually compatible with older browsers that
	do not understand full alpha channels well. TBB */
void gdImageColorTransparent(gdImagePtr im, int color);

void gdImagePaletteCopy(gdImagePtr dst, gdImagePtr src);
void gdImagePng(gdImagePtr im, FILE *out);
void gdImagePngCtx(gdImagePtr im, gdIOCtx *out);
void gdImageGif(gdImagePtr im, FILE *out);
void gdImageGifCtx(gdImagePtr im, gdIOCtx *out);
/* 2.0.12: Compression level: 0-9 or -1, where 0 is NO COMPRESSION at all,
 * 1 is FASTEST but produces larger files, 9 provides the best
 * compression (smallest files) but takes a long time to compress, and
 * -1 selects the default compiled into the zlib library.
 */
void gdImagePngEx(gdImagePtr im, FILE * out, int level, int basefilter);
void gdImagePngCtxEx(gdImagePtr im, gdIOCtx * out, int level, int basefilter);

void gdImageWBMP(gdImagePtr image, int fg, FILE *out);
void gdImageWBMPCtx(gdImagePtr image, int fg, gdIOCtx *out);

/* Guaranteed to correctly free memory returned
	by the gdImage*Ptr functions */
void gdFree(void *m);

/* Best to free this memory with gdFree(), not free() */
void *gdImageWBMPPtr(gdImagePtr im, int *size, int fg);

/* 100 is highest quality (there is always a little loss with JPEG).
       0 is lowest. 10 is about the lowest useful setting. */
void gdImageJpeg(gdImagePtr im, FILE *out, int quality);
void gdImageJpegCtx(gdImagePtr im, gdIOCtx *out, int quality);

/* Best to free this memory with gdFree(), not free() */
void *gdImageJpegPtr(gdImagePtr im, int *size, int quality);

gdImagePtr gdImageCreateFromGif(FILE *fd);
gdImagePtr gdImageCreateFromGifCtx(gdIOCtxPtr in);
gdImagePtr gdImageCreateFromGifSource(gdSourcePtr in);

/* A custom data sink. For backwards compatibility. Use
	gdIOCtx instead. */
/* The sink function must return -1 on error, otherwise the number
        of bytes written, which must be equal to len. */
/* context will be passed to your sink function. */
typedef struct {
        int (*sink) (void *context, const char *buffer, int len);
        void *context;
} gdSink, *gdSinkPtr;

void gdImagePngToSink(gdImagePtr im, gdSinkPtr out);

void gdImageGd(gdImagePtr im, FILE *out);
void gdImageGd2(gdImagePtr im, FILE *out, int cs, int fmt);

/* Best to free this memory with gdFree(), not free() */
void* gdImagePngPtr(gdImagePtr im, int *size);

/* Best to free this memory with gdFree(), not free() */
void* gdImageGdPtr(gdImagePtr im, int *size);
void *gdImagePngPtrEx(gdImagePtr im, int *size, int level, int basefilter);

/* Best to free this memory with gdFree(), not free() */
void* gdImageGd2Ptr(gdImagePtr im, int cs, int fmt, int *size);

void gdImageEllipse(gdImagePtr im, int cx, int cy, int w, int h, int c);

/* Style is a bitwise OR ( | operator ) of these.
	gdArc and gdChord are mutually exclusive;
	gdChord just connects the starting and ending
	angles with a straight line, while gdArc produces
	a rounded edge. gdPie is a synonym for gdArc.
	gdNoFill indicates that the arc or chord should be
	outlined, not filled. gdEdged, used together with
	gdNoFill, indicates that the beginning and ending
	angles should be connected to the center; this is
	a good way to outline (rather than fill) a
	'pie slice'. */
#define gdArc   0
#define gdPie   gdArc
#define gdChord 1
#define gdNoFill 2
#define gdEdged 4

void gdImageFilledArc(gdImagePtr im, int cx, int cy, int w, int h, int s, int e, int color, int style);
void gdImageArc(gdImagePtr im, int cx, int cy, int w, int h, int s, int e, int color);
void gdImageFilledEllipse(gdImagePtr im, int cx, int cy, int w, int h, int color);
void gdImageFillToBorder(gdImagePtr im, int x, int y, int border, int color);
void gdImageFill(gdImagePtr im, int x, int y, int color);
void gdImageCopy(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h);
void gdImageCopyMerge(gdImagePtr dst, gdImagePtr src, int dstX, int dstY,
			int srcX, int srcY, int w, int h, int pct);
void gdImageCopyMergeGray(gdImagePtr dst, gdImagePtr src, int dstX, int dstY,
                        int srcX, int srcY, int w, int h, int pct);

/* Stretches or shrinks to fit, as needed. Does NOT attempt
	to average the entire set of source pixels that scale down onto the
	destination pixel. */
void gdImageCopyResized(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int dstW, int dstH, int srcW, int srcH);

/* gd 2.0: stretches or shrinks to fit, as needed. When called with a
	truecolor destination image, this function averages the
	entire set of source pixels that scale down onto the
	destination pixel, taking into account what portion of the
	destination pixel each source pixel represents. This is a
	floating point operation, but this is not a performance issue
	on modern hardware, except for some embedded devices. If the
	destination is a palette image, gdImageCopyResized is
	substituted automatically. */
void gdImageCopyResampled(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int dstW, int dstH, int srcW, int srcH);

gdImagePtr gdImageRotate90(gdImagePtr src, int ignoretransparent);
gdImagePtr gdImageRotate180(gdImagePtr src, int ignoretransparent);
gdImagePtr gdImageRotate270(gdImagePtr src, int ignoretransparent);
gdImagePtr gdImageRotate45(gdImagePtr src, double dAngle, int clrBack, int ignoretransparent);
gdImagePtr gdImageRotate (gdImagePtr src, double dAngle, int clrBack, int ignoretransparent);

void gdImageSetBrush(gdImagePtr im, gdImagePtr brush);
void gdImageSetTile(gdImagePtr im, gdImagePtr tile);
void gdImageSetAntiAliased(gdImagePtr im, int c);
void gdImageSetAntiAliasedDontBlend(gdImagePtr im, int c, int dont_blend);
void gdImageSetStyle(gdImagePtr im, int *style, int noOfPixels);
/* Line thickness (defaults to 1). Affects lines, ellipses,
	rectangles, polygons and so forth. */
void gdImageSetThickness(gdImagePtr im, int thickness);
/* On or off (1 or 0) for all three of these. */
void gdImageInterlace(gdImagePtr im, int interlaceArg);
void gdImageAlphaBlending(gdImagePtr im, int alphaBlendingArg);
void gdImageAntialias(gdImagePtr im, int antialias);
void gdImageSaveAlpha(gdImagePtr im, int saveAlphaArg);

/* Macros to access information about images. */

/* Returns nonzero if the image is a truecolor image,
	zero for a palette image. */

#define gdImageTrueColor(im) ((im)->trueColor)

#define gdImageSX(im) ((im)->sx)
#define gdImageSY(im) ((im)->sy)
#define gdImageColorsTotal(im) ((im)->colorsTotal)
#define gdImageRed(im, c) ((im)->trueColor ? gdTrueColorGetRed(c) : \
	(im)->red[(c)])
#define gdImageGreen(im, c) ((im)->trueColor ? gdTrueColorGetGreen(c) : \
	(im)->green[(c)])
#define gdImageBlue(im, c) ((im)->trueColor ? gdTrueColorGetBlue(c) : \
	(im)->blue[(c)])
#define gdImageAlpha(im, c) ((im)->trueColor ? gdTrueColorGetAlpha(c) : \
	(im)->alpha[(c)])
#define gdImageGetTransparent(im) ((im)->transparent)
#define gdImageGetInterlaced(im) ((im)->interlace)

/* These macros provide direct access to pixels in
	palette-based and truecolor images, respectively.
	If you use these macros, you must perform your own
	bounds checking. Use of the macro for the correct type
	of image is also your responsibility. */
#define gdImagePalettePixel(im, x, y) (im)->pixels[(y)][(x)]
#define gdImageTrueColorPixel(im, x, y) (im)->tpixels[(y)][(x)]

/* I/O Support routines. */

gdIOCtx* gdNewFileCtx(FILE*);
gdIOCtx* gdNewDynamicCtx(int, void*);
gdIOCtx *gdNewDynamicCtxEx(int size, void *data, int freeFlag);
gdIOCtx* gdNewSSCtx(gdSourcePtr in, gdSinkPtr out);
void* gdDPExtractData(struct gdIOCtx* ctx, int *size);

#define GD2_CHUNKSIZE           128
#define GD2_CHUNKSIZE_MIN	64
#define GD2_CHUNKSIZE_MAX       4096

#define GD2_VERS                2
#define GD2_ID                  "gd2"
#define GD2_FMT_RAW             1
#define GD2_FMT_COMPRESSED      2


/* filters section
 *
 * Negate the imag src, white becomes black,
 * The red, green, and blue intensities of an image are negated.
 * White becomes black, yellow becomes blue, etc.
 */
int gdImageNegate(gdImagePtr src);

/* Convert the image src to a grayscale image */
int gdImageGrayScale(gdImagePtr src);

/* Set the brightness level <brightness> for the image src */
int gdImageBrightness(gdImagePtr src, int brightness);

/* Set the contrast level <contrast> for the image <src> */
int gdImageContrast(gdImagePtr src, double contrast);

/* Simply adds or substracts respectively red, green or blue to a pixel */
int gdImageColor(gdImagePtr src, const int red, const int green, const int blue, const int alpha);

/* Image convolution by a 3x3 custom matrix */
int gdImageConvolution(gdImagePtr src, float ft[3][3], float filter_div, float offset);

int gdImageEdgeDetectQuick(gdImagePtr src);

int gdImageGaussianBlur(gdImagePtr im);

int gdImageSelectiveBlur( gdImagePtr src);

int gdImageEmboss(gdImagePtr im);

int gdImageMeanRemoval(gdImagePtr im);

int gdImageSmooth(gdImagePtr im, float weight);

/* Image comparison definitions */
int gdImageCompare(gdImagePtr im1, gdImagePtr im2);

#define GD_CMP_IMAGE		1	/* Actual image IS different */
#define GD_CMP_NUM_COLORS	2	/* Number of Colours in pallette differ */
#define GD_CMP_COLOR		4	/* Image colours differ */
#define GD_CMP_SIZE_X		8	/* Image width differs */
#define GD_CMP_SIZE_Y		16	/* Image heights differ */
#define GD_CMP_TRANSPARENT	32	/* Transparent colour */
#define GD_CMP_BACKGROUND	64	/* Background colour */
#define GD_CMP_INTERLACE	128	/* Interlaced setting */
#define GD_CMP_TRUECOLOR	256	/* Truecolor vs palette differs */

/* resolution affects ttf font rendering, particularly hinting */
#define GD_RESOLUTION           96      /* pixels per inch */

#ifdef __cplusplus
}
#endif

/* 2.0.12: this now checks the clipping rectangle */
#define gdImageBoundsSafe(im, x, y) (!((((y) < (im)->cy1) || ((y) > (im)->cy2)) || (((x) < (im)->cx1) || ((x) > (im)->cx2))))

#endif /* GD_H */
php/ext/gd/libgd/gdhelpers.h000064400000002507151730540720011744 0ustar00#ifndef GDHELPERS_H
#define GDHELPERS_H 1

#include <sys/types.h>
#include "php.h"

/* TBB: strtok_r is not universal; provide an implementation of it. */

extern char *gd_strtok_r(char *s, char *sep, char **state);

/* These functions wrap memory management. gdFree is
	in gd.h, where callers can utilize it to correctly
	free memory allocated by these functions with the
	right version of free(). */
#define gdCalloc(nmemb, size)	ecalloc(nmemb, size)
#define gdMalloc(size)		emalloc(size)
#define gdRealloc(ptr, size)	erealloc(ptr, size)
#define gdEstrdup(ptr)		estrdup(ptr)
#define gdFree(ptr)		efree(ptr)
#define gdPMalloc(ptr)		pemalloc(ptr, 1)
#define gdPFree(ptr)		pefree(ptr, 1)
#define gdPEstrdup(ptr)		pestrdup(ptr, 1)

/* Returns nonzero if multiplying the two quantities will
	result in integer overflow. Also returns nonzero if 
	either quantity is negative. By Phil Knirsch based on
	netpbm fixes by Alan Cox. */

int overflow2(int a, int b);

#ifdef ZTS
#define gdMutexDeclare(x) MUTEX_T x
#define gdMutexSetup(x) x = tsrm_mutex_alloc()
#define gdMutexShutdown(x) tsrm_mutex_free(x)
#define gdMutexLock(x) tsrm_mutex_lock(x)
#define gdMutexUnlock(x) tsrm_mutex_unlock(x)
#else
#define gdMutexDeclare(x)
#define gdMutexSetup(x)
#define gdMutexShutdown(x)
#define gdMutexLock(x)
#define gdMutexUnlock(x)
#endif

#endif /* GDHELPERS_H */

php/ext/gd/libgd/gdcache.h000064400000005234151730540720011345 0ustar00/*
 * gdcache.h
 *
 * Caches of pointers to user structs in which the least-recently-used
 * element is replaced in the event of a cache miss after the cache has
 * reached a given size.
 *
 * John Ellson  (ellson@graphviz.org)  Oct 31, 1997
 *
 * Test this with:
 *		 gcc -o gdcache -g -Wall -DTEST gdcache.c
 *
 * The cache is implemented by a singly-linked list of elements
 * each containing a pointer to a user struct that is being managed by
 * the cache.
 *
 * The head structure has a pointer to the most-recently-used
 * element, and elements are moved to this position in the list each
 * time they are used.  The head also contains pointers to three
 * user defined functions:
 *		- a function to test if a cached userdata matches some keydata
 *		- a function to provide a new userdata struct to the cache
 *          if there has been a cache miss.
 *		- a function to release a userdata struct when it is
 *          no longer being managed by the cache
 *
 * In the event of a cache miss the cache is allowed to grow up to
 * a specified maximum size.  After the maximum size is reached then
 * the least-recently-used element is discarded to make room for the
 * new.  The most-recently-returned value is always left at the
 * beginning of the list after retrieval.
 *
 * In the current implementation the cache is traversed by a linear
 * search from most-recent to least-recent.  This linear search
 * probably limits the usefulness of this implementation to cache
 * sizes of a few tens of elements.
 */

/*********************************************************/
/* header                                                */
/*********************************************************/

#include <stdlib.h>
#ifdef HAVE_MALLOC_H
 #include <malloc.h>
#endif
#ifndef NULL
#define NULL (void *)0
#endif

/* user defined function templates */
typedef int (*gdCacheTestFn_t)(void *userdata, void *keydata);
typedef void *(*gdCacheFetchFn_t)(char **error, void *keydata);
typedef void (*gdCacheReleaseFn_t)(void *userdata);

/* element structure */
typedef struct gdCache_element_s gdCache_element_t;
struct gdCache_element_s {
	gdCache_element_t	*next;
	void			*userdata;
};

/* head structure */
typedef struct gdCache_head_s gdCache_head_t;
struct gdCache_head_s {
	gdCache_element_t	*mru;
	int					size;
	char				*error;
	gdCacheTestFn_t		gdCacheTest;
	gdCacheFetchFn_t	gdCacheFetch;
	gdCacheReleaseFn_t	gdCacheRelease;
};

/* function templates */
gdCache_head_t *
gdCacheCreate(
	int					size,
	gdCacheTestFn_t		gdCacheTest,
	gdCacheFetchFn_t	gdCacheFetch,
	gdCacheReleaseFn_t	gdCacheRelease );

void
gdCacheDelete( gdCache_head_t *head );

void *
gdCacheGet( gdCache_head_t *head, void *keydata );
php/ext/gd/libgd/bmp.h000064400000004622151730540720010545 0ustar00/* $Id$ */
#ifdef __cplusplus
extern "C" {
#endif

	/*
		gd_bmp.c

		Bitmap format support for libgd

		* Written 2007, Scott MacVicar
		---------------------------------------------------------------------------

		Todo:

		RLE4, RLE8 and Bitfield encoding
		Add full support for Windows v4 and Windows v5 header formats

		----------------------------------------------------------------------------
	 */

#ifndef BMP_H
#define BMP_H	1

#define BMP_PALETTE_3 1
#define BMP_PALETTE_4 2

#define BMP_WINDOWS_V3 40
#define BMP_OS2_V1 12
#define BMP_OS2_V2 64
#define BMP_WINDOWS_V4 108
#define BMP_WINDOWS_V5 124

#define BMP_BI_RGB 0
#define BMP_BI_RLE8 1
#define BMP_BI_RLE4 2
#define BMP_BI_BITFIELDS 3
#define BMP_BI_JPEG 4
#define BMP_BI_PNG 5

#define BMP_RLE_COMMAND 0
#define BMP_RLE_ENDOFLINE 0
#define BMP_RLE_ENDOFBITMAP 1
#define BMP_RLE_DELTA 2

#define BMP_RLE_TYPE_RAW 0
#define BMP_RLE_TYPE_RLE 1

	/* BMP header. */
	typedef struct {
		/* 16 bit - header identifying the type */
		signed short int magic;

		/* 32bit - size of the file */
		int size;

		/* 16bit - these two are in the spec but "reserved" */
		signed short int reserved1;
		signed short int reserved2;

		/* 32 bit - offset of the bitmap header from data in bytes */
		signed int off;

	} bmp_hdr_t;

	/* BMP info. */
	typedef struct {
		/* 16bit - Type, ie Windows or OS/2 for the palette info */
		signed short int type;
		/* 32bit - The length of the bitmap information header in bytes. */
		signed int len;

		/* 32bit - The width of the bitmap in pixels. */
		signed int width;

		/* 32bit - The height of the bitmap in pixels. */
		signed int height;

		/* 8 bit - The bitmap data is specified in top-down order. */
		signed char topdown;

		/* 16 bit - The number of planes.  This must be set to a value of one. */
		signed short int numplanes;

		/* 16 bit - The number of bits per pixel. */
		signed short int depth;

		/* 32bit - The type of compression used. */
		signed int enctype;

		/* 32bit - The size of the image in bytes. */
		signed int size;

		/* 32bit - The horizontal resolution in pixels/metre. */
		signed int hres;

		/* 32bit - The vertical resolution in pixels/metre. */
		signed int vres;

		/* 32bit - The number of color indices used by the bitmap. */
		signed int numcolors;

		/* 32bit - The number of color indices important for displaying the bitmap. */
		signed int mincolors;

	} bmp_info_t;

#endif

#ifdef __cplusplus
}
#endif
php/ext/gd/libgd/gdfontt.h000064400000001012151730540730011423 0ustar00
#ifndef _GDFONTT_H_
#define _GDFONTT_H_ 1

#ifdef __cplusplus
extern "C" {
#endif

/*
	This is a header file for gd font, generated using
	bdftogd version 0.5 by Jan Pazdziora, adelton@fi.muni.cz
	from bdf font
	-Misc-Fixed-Medium-R-Normal--8-80-75-75-C-50-ISO8859-2
	at Thu Jan  8 13:49:54 1998.
	The original bdf was holding following copyright:
	"Libor Skarvada, libor@informatics.muni.cz"
 */


#include "gd.h"

extern gdFontPtr gdFontTiny;
extern gdFontPtr gdFontGetTiny(void);

#ifdef __cplusplus
}
#endif

#endif

php/ext/gd/libgd/gd_errors.h000064400000001241151730540730011750 0ustar00#ifndef GD_ERRORS_H
#define GD_ERRORS_H

#ifndef _WIN32
# include <syslog.h>
#else
# include "win32/syslog.h"
#endif

/*
LOG_EMERG      system is unusable
LOG_ALERT      action must be taken immediately
LOG_CRIT       critical conditions
LOG_ERR        error conditions
LOG_WARNING    warning conditions
LOG_NOTICE     normal, but significant, condition
LOG_INFO       informational message
LOG_DEBUG      debug-level message
*/

#define GD_ERROR LOG_ERR
#define GD_WARNING LOG_WARNING
#define GD_NOTICE LOG_NOTICE
#define GD_INFO LOG_INFO
#define GD_DEBUG LOG_DEBUG

void gd_error(const char *format, ...);
void gd_error_ex(int priority, const char *format, ...);

#endif
php/ext/gd/libgd/gd_intern.h000064400000000405151730540740011735 0ustar00#ifndef GD_INTERN_H
#define GD_INTERN_H
#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
#endif
#define MIN3(a,b,c) ((a)<(b)?(MIN(a,c)):(MIN(b,c)))
#ifndef MAX
#define MAX(a,b) ((a)<(b)?(b):(a))
#endif
#define MAX3(a,b,c) ((a)<(b)?(MAX(b,c)):(MAX(a,c)))

#endif

php/ext/dom/xml_common.h000064400000006634151730540740011252 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 5                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2010 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Christian Stocker <chregu@php.net>                          |
  |          Rob Richards <rrichards@php.net>                            |
  +----------------------------------------------------------------------+
*/

/* $Id: xml_common.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_XML_COMMON_H
#define PHP_XML_COMMON_H

#include "ext/libxml/php_libxml.h"

typedef libxml_doc_props *dom_doc_propsptr;

typedef struct _dom_object {
	zend_object  std;
	void *ptr;
	php_libxml_ref_obj *document;
	HashTable *prop_handler;
	zend_object_handle handle;
} dom_object;

#ifdef PHP_WIN32
#ifdef PHPAPI
#undef PHPAPI
#endif
#ifdef DOM_EXPORTS
#define PHPAPI __declspec(dllexport)
#else
#define PHPAPI __declspec(dllimport)
#endif /* DOM_EXPORTS */
#endif /* PHP_WIN32 */

#define PHP_DOM_EXPORT PHPAPI

PHP_DOM_EXPORT extern zend_class_entry *dom_node_class_entry;
PHP_DOM_EXPORT dom_object *php_dom_object_get_data(xmlNodePtr obj);
PHP_DOM_EXPORT zval *php_dom_create_object(xmlNodePtr obj, int *found, zval *in, zval* return_value, dom_object *domobj TSRMLS_DC);
PHP_DOM_EXPORT xmlNodePtr dom_object_get_node(dom_object *obj);

#define DOM_XMLNS_NAMESPACE \
    (const xmlChar *) "http://www.w3.org/2000/xmlns/"

#define NODE_GET_OBJ(__ptr, __id, __prtype, __intern) { \
	__intern = (php_libxml_node_object *)zend_object_store_get_object(__id TSRMLS_CC); \
	if (__intern->node == NULL || !(__ptr = (__prtype)__intern->node->node)) { \
  		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't fetch %s", __intern->std.ce->name);\
  		RETURN_NULL();\
  	} \
}

#define DOC_GET_OBJ(__ptr, __id, __prtype, __intern) { \
	__intern = (php_libxml_node_object *)zend_object_store_get_object(__id TSRMLS_CC); \
	if (__intern->document != NULL) { \
		if (!(__ptr = (__prtype)__intern->document->ptr)) { \
  			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't fetch %s", __intern->std.ce->name);\
  			RETURN_NULL();\
  		} \
	} \
}

#define DOM_RET_OBJ(zval, obj, ret, domobject) \
	if (NULL == (zval = php_dom_create_object(obj, ret, zval, return_value, domobject TSRMLS_CC))) { \
		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object"); \
		RETURN_FALSE; \
	}

#define DOM_GET_THIS(zval) \
	if (NULL == (zval = getThis())) { \
		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Underlying object missing"); \
		RETURN_FALSE; \
	}

#define DOM_GET_THIS_OBJ(__ptr, __id, __prtype, __intern) \
	DOM_GET_THIS(__id); \
	DOM_GET_OBJ(__ptr, __id, __prtype, __intern);

#endif
php/ext/standard/php_type.h000064400000003153151730540750011745 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Rasmus Lerdorf <rasmus@lerdorf.on.ca>                        |
   +----------------------------------------------------------------------+
*/

/* $Id: php_type.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_TYPE_H
#define PHP_TYPE_H

PHP_FUNCTION(intval);
PHP_FUNCTION(floatval);
PHP_FUNCTION(strval);
PHP_FUNCTION(gettype);
PHP_FUNCTION(settype);
PHP_FUNCTION(is_null);
PHP_FUNCTION(is_resource);
PHP_FUNCTION(is_bool);
PHP_FUNCTION(is_long);
PHP_FUNCTION(is_float);
PHP_FUNCTION(is_numeric);
PHP_FUNCTION(is_string);
PHP_FUNCTION(is_array);
PHP_FUNCTION(is_object);
PHP_FUNCTION(is_scalar);
PHP_FUNCTION(is_callable);

#endif
php/ext/standard/php_iptc.h000064400000002455151730540750011727 0ustar00/* 
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Thies C. Arntzen <thies@thieso.net>                          |
   +----------------------------------------------------------------------+
*/

/* $Id: php_iptc.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_IPTC_H
#define PHP_IPTC_H

PHP_FUNCTION(iptcparse);
PHP_FUNCTION(iptcembed);

#endif /* PHP_IPTC_H */
php/ext/standard/php_smart_string_public.h000064400000002450151730540750015035 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 7                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2018 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Sascha Schumann <sascha@schumann.cx>                         |
   |         Xinchen Hui <laruence@php.net>                               |
   +----------------------------------------------------------------------+
 */

/* Header moved to Zend. This file is retained for BC. */
#include "zend_smart_string_public.h"
php/ext/standard/credits.h000064400000003373151730540750011556 0ustar00/* 
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Rasmus Lerdorf <rasmus@php.net>                             |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: credits.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef CREDITS_H
#define CREDITS_H

#ifndef HAVE_CREDITS_DEFS
#define HAVE_CREDITS_DEFS

#define PHP_CREDITS_GROUP			(1<<0)
#define PHP_CREDITS_GENERAL			(1<<1)
#define PHP_CREDITS_SAPI			(1<<2)
#define PHP_CREDITS_MODULES			(1<<3)
#define PHP_CREDITS_DOCS			(1<<4)
#define PHP_CREDITS_FULLPAGE		(1<<5)
#define PHP_CREDITS_QA				(1<<6)
#define PHP_CREDITS_WEB				(1<<7)
#define PHP_CREDITS_ALL				0xFFFFFFFF

#endif /* HAVE_CREDITS_DEFS */

PHPAPI void php_print_credits(int flag TSRMLS_DC);

#endif
php/ext/standard/php_smart_string.h000064400000002441151730540760013500 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 7                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2018 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Sascha Schumann <sascha@schumann.cx>                         |
   |         Xinchen Hui <laruence@php.net>                               |
   +----------------------------------------------------------------------+
 */

/* Header moved to Zend. This file is retained for BC. */
#include "zend_smart_string.h"
php/ext/standard/basic_functions.h000064400000015013151730540760013265 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: basic_functions.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef BASIC_FUNCTIONS_H
#define BASIC_FUNCTIONS_H

#include <sys/stat.h>

#ifdef HAVE_WCHAR_H
#include <wchar.h>
#endif

#include "php_filestat.h"

#include "zend_highlight.h"

#include "url_scanner_ex.h"

extern zend_module_entry basic_functions_module;
#define basic_functions_module_ptr &basic_functions_module

PHP_MINIT_FUNCTION(basic);
PHP_MSHUTDOWN_FUNCTION(basic);
PHP_RINIT_FUNCTION(basic);
PHP_RSHUTDOWN_FUNCTION(basic);
PHP_MINFO_FUNCTION(basic);

PHP_FUNCTION(constant);
PHP_FUNCTION(sleep);
PHP_FUNCTION(usleep);
#if HAVE_NANOSLEEP
PHP_FUNCTION(time_nanosleep);
PHP_FUNCTION(time_sleep_until);
#endif
PHP_FUNCTION(flush);
#ifdef HAVE_INET_NTOP
PHP_NAMED_FUNCTION(php_inet_ntop);
#endif
#ifdef HAVE_INET_PTON
PHP_NAMED_FUNCTION(php_inet_pton);
#endif
PHP_FUNCTION(ip2long);
PHP_FUNCTION(long2ip);

/* system functions */
PHP_FUNCTION(getenv);
PHP_FUNCTION(putenv);

PHP_FUNCTION(getopt);

PHP_FUNCTION(get_current_user);
PHP_FUNCTION(set_time_limit);

PHP_FUNCTION(get_cfg_var);
PHP_FUNCTION(set_magic_quotes_runtime);
PHP_FUNCTION(get_magic_quotes_runtime);
PHP_FUNCTION(get_magic_quotes_gpc);

PHP_FUNCTION(import_request_variables);

PHP_FUNCTION(error_log);
PHP_FUNCTION(error_get_last);

PHP_FUNCTION(call_user_func);
PHP_FUNCTION(call_user_func_array);
PHP_FUNCTION(call_user_method);
PHP_FUNCTION(call_user_method_array);

PHP_FUNCTION(register_shutdown_function);
PHP_FUNCTION(highlight_file);
PHP_FUNCTION(highlight_string);
PHP_FUNCTION(php_strip_whitespace);
ZEND_API void php_get_highlight_struct(zend_syntax_highlighter_ini *syntax_highlighter_ini);

PHP_FUNCTION(ini_get);
PHP_FUNCTION(ini_get_all);
PHP_FUNCTION(ini_set);
PHP_FUNCTION(ini_restore);
PHP_FUNCTION(get_include_path);
PHP_FUNCTION(set_include_path);
PHP_FUNCTION(restore_include_path);

PHP_FUNCTION(print_r);
PHP_FUNCTION(fprintf);
PHP_FUNCTION(vfprintf);

PHP_FUNCTION(connection_aborted);
PHP_FUNCTION(connection_status);
PHP_FUNCTION(ignore_user_abort);

PHP_FUNCTION(getservbyname);
PHP_FUNCTION(getservbyport);
PHP_FUNCTION(getprotobyname);
PHP_FUNCTION(getprotobynumber);

PHP_NAMED_FUNCTION(php_if_crc32);

PHP_FUNCTION(register_tick_function);
PHP_FUNCTION(unregister_tick_function);
#ifdef HAVE_GETLOADAVG
PHP_FUNCTION(sys_getloadavg);
#endif

PHP_FUNCTION(is_uploaded_file);
PHP_FUNCTION(move_uploaded_file);

/* From the INI parser */
PHP_FUNCTION(parse_ini_file);

PHP_FUNCTION(str_rot13);
PHP_FUNCTION(stream_get_filters);
PHP_FUNCTION(stream_filter_register);
PHP_FUNCTION(stream_bucket_make_writeable);
PHP_FUNCTION(stream_bucket_prepend);
PHP_FUNCTION(stream_bucket_append);
PHP_FUNCTION(stream_bucket_new);
PHP_MINIT_FUNCTION(user_filters);
PHP_RSHUTDOWN_FUNCTION(user_filters);

/* Left for BC (not binary safe!) */
PHPAPI int _php_error_log(int opt_err, char *message, char *opt, char *headers TSRMLS_DC);
PHPAPI int _php_error_log_ex(int opt_err, char *message, int message_len, char *opt, char *headers TSRMLS_DC);

#if SIZEOF_INT == 4
/* Most 32-bit and 64-bit systems have 32-bit ints */
typedef unsigned int php_uint32;
typedef signed int php_int32;
#elif SIZEOF_LONG == 4
/* 16-bit systems? */
typedef unsigned long php_uint32;
typedef signed long php_int32;
#else
#error Need type which holds 32 bits
#endif

#define MT_N (624)

typedef struct _php_basic_globals {
	HashTable *user_shutdown_function_names;
	HashTable putenv_ht;
	zval *strtok_zval;
	char *strtok_string;
	char *locale_string;
	char *strtok_last;
	char strtok_table[256];
	ulong strtok_len;
	char str_ebuf[40];
	zval **array_walk_func_name;
	zval **user_compare_func_name;
	zend_fcall_info_cache user_compare_fci_cache;
	zend_llist *user_tick_functions;

	zval *active_ini_file_section;

	HashTable sm_protected_env_vars;
	char *sm_allowed_env_vars;
	
	/* pageinfo.c */
	long page_uid;
	long page_gid;
	long page_inode;
	long page_mtime;

	/* filestat.c && main/streams/streams.c */
	char *CurrentStatFile, *CurrentLStatFile;
	php_stream_statbuf ssb, lssb;

	/* rand.c */
	php_uint32   state[MT_N+1];  /* state vector + 1 extra to not violate ANSI C */
	php_uint32   *next;       /* next random value is computed from here */
	int      left;        /* can *next++ this many times before reloading */

	unsigned int rand_seed; /* Seed for rand(), in ts version */

	zend_bool rand_is_seeded; /* Whether rand() has been seeded */
	zend_bool mt_rand_is_seeded; /* Whether mt_rand() has been seeded */
    
	/* syslog.c */
	int syslog_started;
	char *syslog_device;

	/* var.c */
	zend_class_entry *incomplete_class;

	/* url_scanner_ex.re */
	url_adapt_state_ex_t url_adapt_state_ex;

#ifdef HAVE_MMAP
	void *mmap_file;
	size_t mmap_len;
#endif

	HashTable *user_filter_map;

	/* file.c */
#if defined(_REENTRANT) && defined(HAVE_MBRLEN) && defined(HAVE_MBSTATE_T)
	mbstate_t mblen_state;
#endif

	int umask;
} php_basic_globals;

#ifdef ZTS
#define BG(v) TSRMG(basic_globals_id, php_basic_globals *, v)
PHPAPI extern int basic_globals_id;
#else
#define BG(v) (basic_globals.v)
PHPAPI extern php_basic_globals basic_globals;
#endif

#if HAVE_PUTENV
typedef struct {
	char *putenv_string;
	char *previous_value;
	char *key;
	int key_len;
} putenv_entry;
#endif

/* Values are comma-delimited
 */
#define SAFE_MODE_PROTECTED_ENV_VARS	"LD_LIBRARY_PATH"
#define SAFE_MODE_ALLOWED_ENV_VARS		"PHP_"

PHPAPI double php_get_nan(void);
PHPAPI double php_get_inf(void);

#endif /* BASIC_FUNCTIONS_H */
php/ext/standard/credits_ext.h000064400000012446151730540760012440 0ustar00/* 
                      DO NOT EDIT THIS FILE!

 it has been automaticaly created by php5/scripts/credits from  
 the information found in the various php5/ext/.../CREDITS and
 php5/sapi/.../CREDITS files 
 
 if you want to change an entry you have to edit the appropriate 
 CREDITS file instead

*/

CREDIT_LINE("Assert", "Thies C. Arntzen");
CREDIT_LINE("BC Math", "Andi Gutmans");
CREDIT_LINE("Bzip2", "Sterling Hughes");
CREDIT_LINE("Calendar", "Shane Caraveo, Colin Viebrock, Hartmut Holzgraefe, Wez Furlong");
CREDIT_LINE("COM and .Net", "Wez Furlong");
CREDIT_LINE("ctype", "Hartmut Holzgraefe");
CREDIT_LINE("cURL", "Sterling Hughes");
CREDIT_LINE("Date/Time Support", "Derick Rethans");
CREDIT_LINE("DBA", "Sascha Schumann, Marcus Boerger");
CREDIT_LINE("dBase", "Jim Winstead");
CREDIT_LINE("DB-LIB (MS SQL, Sybase)", "Wez Furlong, Frank M. Kromann");
CREDIT_LINE("DOM", "Christian Stocker, Rob Richards, Marcus Boerger");
CREDIT_LINE("EXIF", "Rasmus Lerdorf, Marcus Boerger");
CREDIT_LINE("FBSQL", "Frank M. Kromann");
CREDIT_LINE("FDF", "Uwe Steinmann");
CREDIT_LINE("Firebird/InterBase driver for PDO", "Ard Biesheuvel");
CREDIT_LINE("FTP", "Stefan Esser, Andrew Skalski");
CREDIT_LINE("GD imaging", "Rasmus Lerdorf, Stig Bakken, Jim Winstead, Jouni Ahto, Ilia Alshanetsky, Pierre-Alain Joye, Marcus Boerger");
CREDIT_LINE("GetText", "Alex Plotnick");
CREDIT_LINE("GNU GMP support", "Stanislav Malyshev");
CREDIT_LINE("Iconv", "Rui Hirokawa, Stig Bakken, Moriyoshi Koizumi ");
CREDIT_LINE("IMAP", "Rex Logan, Mark Musone, Brian Wang, Kaj-Michael Lang, Antoni Pamies Olive, Rasmus Lerdorf, Andrew Skalski, Chuck Hagenbuch, Daniel R Kalowsky");
CREDIT_LINE("Input Filter", "Rasmus Lerdorf, Derick Rethans, Pierre-Alain Joye, Ilia Alshanetsky");
CREDIT_LINE("InterBase", "Jouni Ahto, Andrew Avdeev, Ard Biesheuvel");
CREDIT_LINE("JSON", "Omar Kilani");
CREDIT_LINE("LDAP", "Amitay Isaacs, Eric Warnke, Rasmus Lerdorf, Gerrit Thomson, Stig Venaas");
CREDIT_LINE("LIBXML", "Christian Stocker, Rob Richards, Marcus Boerger, Wez Furlong, Shane Caraveo");
CREDIT_LINE("mcrypt", "Sascha Schumann, Derick Rethans");
CREDIT_LINE("mhash", "Sascha Schumann");
CREDIT_LINE("mime_magic", "Hartmut Holzgraefe");
CREDIT_LINE("MING", "Dave Hayden, Frank M. Kromann");
CREDIT_LINE("mSQL", "Zeev Suraski");
CREDIT_LINE("MS SQL", "Frank M. Kromann");
CREDIT_LINE("Multibyte String Functions", "Tsukada Takuya, Rui Hirokawa");
CREDIT_LINE("mySQL driver for PDO", "George Schlossnagle, Wez Furlong, Ilia Alshanetsky");
CREDIT_LINE("MySQLi", "Zak Greant, Georg Richter, Andrey Hristov, Ulf Wendel");
CREDIT_LINE("MySQL", "Zeev Suraski, Zak Greant, Georg Richter");
CREDIT_LINE("ncurses", "Ilia Alshanetsky, Wez Furlong, Hartmut Holzgraefe, Georg Richter");
CREDIT_LINE("OCI8", "Stig Bakken, Thies C. Arntzen, Andy Sautins, David Benson, Maxim Maletsky, Harald Radi, Antony Dovgal, Andi Gutmans, Wez Furlong");
CREDIT_LINE("ODBC driver for PDO", "Wez Furlong");
CREDIT_LINE("ODBC", "Stig Bakken, Andreas Karajannis, Frank M. Kromann, Daniel R. Kalowsky");
CREDIT_LINE("OpenSSL", "Stig Venaas, Wez Furlong, Sascha Kettler");
CREDIT_LINE("Oracle (OCI) driver for PDO", "Wez Furlong");
CREDIT_LINE("pcntl", "Jason Greene");
CREDIT_LINE("Perl Compatible Regexps", "Andrei Zmievski");
CREDIT_LINE("PHP Data Objects", "Wez Furlong, Marcus Boerger, Sterling Hughes, George Schlossnagle, Ilia Alshanetsky");
CREDIT_LINE("PHP hash", "Sara Golemon, Rasmus Lerdorf, Stefan Esser, Michael Wallner");
CREDIT_LINE("Posix", "Kristian Koehntopp");
CREDIT_LINE("PostgreSQL driver for PDO", "Edin Kadribasic, Ilia Alshanetsky");
CREDIT_LINE("PostgreSQL", "Jouni Ahto, Zeev Suraski, Yasuo Ohgaki, Chris Kings-Lynne");
CREDIT_LINE("Pspell", "Vlad Krupin");
CREDIT_LINE("Readline", "Thies C. Arntzen");
CREDIT_LINE("Recode", "Kristian K�hntopp");
CREDIT_LINE("Reflection", "Marcus Boerger, Timm Friebe, George Schlossnagle, Andrei Zmievski, Johannes Schlueter");
CREDIT_LINE("Sessions", "Sascha Schumann, Andrei Zmievski");
CREDIT_LINE("Shared Memory Operations", "Slava Poliakov, Ilia Alshanetsky");
CREDIT_LINE("SimpleXML", "Sterling Hughes, Marcus Boerger, Rob Richards");
CREDIT_LINE("SNMP", "Rasmus Lerdorf, Harrie Hazewinkel, Mike Jackson, Steven Lawrance, Johann Hanne");
CREDIT_LINE("SOAP", "Brad Lafountain, Shane Caraveo, Dmitry Stogov");
CREDIT_LINE("Sockets", "Chris Vandomelen, Sterling Hughes, Daniel Beulshausen, Jason Greene");
CREDIT_LINE("SPL", "Marcus Boerger");
CREDIT_LINE("SQLite 3.x driver for PDO", "Wez Furlong");
CREDIT_LINE("SQLite", "Wez Furlong, Tal Peer, Marcus Boerger, Ilia Alshanetsky");
CREDIT_LINE("Sybase-CT", "Zeev Suraski, Tom May, Timm Friebe");
CREDIT_LINE("Sybase-DB", "Zeev Suraski");
CREDIT_LINE("System V Message based IPC", "Wez Furlong");
CREDIT_LINE("System V Semaphores", "Tom May");
CREDIT_LINE("System V Shared Memory", "Christian Cartus");
CREDIT_LINE("tidy", "John Coggeshall, Ilia Alshanetsky");
CREDIT_LINE("tokenizer", "Andrei Zmievski, Johannes Schlueter");
CREDIT_LINE("WDDX", "Andrei Zmievski");
CREDIT_LINE("XMLReader", "Rob Richards");
CREDIT_LINE("xmlrpc", "Dan Libby");
CREDIT_LINE("XML", "Stig Bakken, Thies C. Arntzen, Sterling Hughes");
CREDIT_LINE("XMLWriter", "Rob Richards, Pierre-Alain Joye");
CREDIT_LINE("XSL", "Christian Stocker, Rob Richards");
CREDIT_LINE("Zip", "Pierre-Alain Joye");
CREDIT_LINE("Zlib", "Rasmus Lerdorf, Stefan Roehrich, Zeev Suraski, Jade Nicoletti");
php/ext/standard/crypt_freesec.h000064400000001231151730540770012747 0ustar00/* $Id$ */

#ifndef _CRYPT_FREESEC_H
#define _CRYPT_FREESEC_H

#ifdef PHP_WIN32
# ifndef inline
# define inline __inline
# endif
#endif

#include "php_stdint.h"

#define MD5_HASH_MAX_LEN 120

struct php_crypt_extended_data {
	int initialized;
	uint32_t saltbits;
	uint32_t old_salt;
	uint32_t en_keysl[16], en_keysr[16];
	uint32_t de_keysl[16], de_keysr[16];
	uint32_t old_rawkey0, old_rawkey1;
	char output[21];
};

/*
 * _crypt_extended_init() must be called explicitly before first use of
 * _crypt_extended_r().
 */

void _crypt_extended_init(void);

char *_crypt_extended_r(const char *key, const char *setting,
	struct php_crypt_extended_data *data);

#endif
php/ext/standard/sha1.h000064400000003406151730540770010754 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Stefan Esser <sesser@php.net>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: sha1.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef SHA1_H
#define SHA1_H

#include "ext/standard/basic_functions.h"

/* SHA1 context. */
typedef struct {
	php_uint32 state[5];		/* state (ABCD) */
	php_uint32 count[2];		/* number of bits, modulo 2^64 (lsb first) */
	unsigned char buffer[64];	/* input buffer */
} PHP_SHA1_CTX;

PHPAPI void PHP_SHA1Init(PHP_SHA1_CTX *);
PHPAPI void PHP_SHA1Update(PHP_SHA1_CTX *, const unsigned char *, unsigned int);
PHPAPI void PHP_SHA1Final(unsigned char[20], PHP_SHA1_CTX *);
PHPAPI void make_sha1_digest(char *sha1str, unsigned char *digest);

PHP_FUNCTION(sha1);
PHP_FUNCTION(sha1_file);

#endif
php/ext/standard/crc32.h000064400000011517151730541000011021 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Rasmus Lerdorf <rasmus@php.net>                              |
   +----------------------------------------------------------------------+
*/

/* $Id: crc32.h 293036 2010-01-03 09:23:27Z sebastian $ */

/*
 * This code implements the AUTODIN II polynomial
 * The variable corresponding to the macro argument "crc" should
 * be an unsigned long.
 * Oroginal code  by Spencer Garrett <srg@quick.com>
 */

#define CRC32(crc, ch)	 (crc = (crc >> 8) ^ crc32tab[(crc ^ (ch)) & 0xff])

/* generated using the AUTODIN II polynomial
 *	x^32 + x^26 + x^23 + x^22 + x^16 +
 *	x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1
 */

static const unsigned int crc32tab[256] = {
	0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
	0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
	0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
	0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
	0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
	0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
	0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
	0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
	0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
	0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
	0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
	0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
	0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
	0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
	0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
	0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
	0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
	0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
	0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
	0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
	0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
	0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
	0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
	0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
	0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
	0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
	0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
	0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
	0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
	0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
	0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
	0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
	0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
	0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
	0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
	0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
	0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
	0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
	0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
	0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
	0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
	0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
	0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
	0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
	0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
	0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
	0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
	0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
	0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
	0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
	0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
	0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
	0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
	0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
	0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
	0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
	0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
	0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
	0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
	0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
	0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
	0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
	0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
	0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
};

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/ext/standard/php_random.h000064400000004176151730541000012237 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 7                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2018 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Sammy Kaye Powers <me@sammyk.me>                            |
   +----------------------------------------------------------------------+
*/

/* $Id$ */

#ifndef PHP_RANDOM_H
#define PHP_RANDOM_H

PHP_FUNCTION(random_bytes);
PHP_FUNCTION(random_int);

PHP_MINIT_FUNCTION(random);
PHP_MSHUTDOWN_FUNCTION(random);

typedef struct {
	int fd;
} php_random_globals;

#define php_random_bytes_throw(b, s) php_random_bytes((b), (s), 1)
#define php_random_bytes_silent(b, s) php_random_bytes((b), (s), 0)

#define php_random_int_throw(min, max, result) \
	php_random_int((min), (max), (result), 1)
#define php_random_int_silent(min, max, result) \
	php_random_int((min), (max), (result), 0)

PHPAPI int php_random_bytes(void *bytes, size_t size, zend_bool should_throw);
PHPAPI int php_random_int(zend_long min, zend_long max, zend_long *result, zend_bool should_throw);

#ifdef ZTS
# define RANDOM_G(v) ZEND_TSRMG(random_globals_id, php_random_globals *, v)
extern PHPAPI int random_globals_id;
#else
# define RANDOM_G(v) random_globals.v
extern PHPAPI php_random_globals random_globals;
#endif

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 */
php/ext/standard/php_string.h000064400000013775151730541010012273 0ustar00/* 
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Rasmus Lerdorf <rasmus@php.net>                             |
   |          Stig S�ther Bakken <ssb@php.net>                            |
   +----------------------------------------------------------------------+
*/

/* $Id: php_string.h 293036 2010-01-03 09:23:27Z sebastian $ */

/* Synced with php 3.0 revision 1.43 1999-06-16 [ssb] */

#ifndef PHP_STRING_H
#define PHP_STRING_H

PHP_FUNCTION(strspn);
PHP_FUNCTION(strcspn);
PHP_FUNCTION(str_replace);
PHP_FUNCTION(str_ireplace);
PHP_FUNCTION(rtrim);
PHP_FUNCTION(trim);
PHP_FUNCTION(ltrim);
PHP_FUNCTION(soundex);
PHP_FUNCTION(levenshtein);

PHP_FUNCTION(count_chars);
PHP_FUNCTION(wordwrap);
PHP_FUNCTION(explode);
PHP_FUNCTION(implode);
PHP_FUNCTION(strtok);
PHP_FUNCTION(strtoupper);
PHP_FUNCTION(strtolower);
PHP_FUNCTION(basename);
PHP_FUNCTION(dirname);
PHP_FUNCTION(pathinfo);
PHP_FUNCTION(strstr);
PHP_FUNCTION(strpos);
PHP_FUNCTION(stripos);
PHP_FUNCTION(strrpos);
PHP_FUNCTION(strripos);
PHP_FUNCTION(strrchr);
PHP_FUNCTION(substr);
PHP_FUNCTION(quotemeta);
PHP_FUNCTION(ucfirst);
PHP_FUNCTION(ucwords);
PHP_FUNCTION(strtr);
PHP_FUNCTION(strrev);
PHP_FUNCTION(hebrev);
PHP_FUNCTION(hebrevc);
PHP_FUNCTION(user_sprintf);
PHP_FUNCTION(user_printf);
PHP_FUNCTION(vprintf);
PHP_FUNCTION(vsprintf);
PHP_FUNCTION(addcslashes);
PHP_FUNCTION(addslashes);
PHP_FUNCTION(stripcslashes);
PHP_FUNCTION(stripslashes);
PHP_FUNCTION(chr);
PHP_FUNCTION(ord);
PHP_FUNCTION(nl2br);
PHP_FUNCTION(setlocale);
PHP_FUNCTION(localeconv);
PHP_FUNCTION(nl_langinfo);
PHP_FUNCTION(stristr);
PHP_FUNCTION(chunk_split);
PHP_FUNCTION(parse_str);
PHP_FUNCTION(bin2hex);
PHP_FUNCTION(similar_text);
PHP_FUNCTION(strip_tags);
PHP_FUNCTION(str_repeat);
PHP_FUNCTION(substr_replace);
PHP_FUNCTION(strnatcmp);
PHP_FUNCTION(strnatcasecmp);
PHP_FUNCTION(substr_count);
PHP_FUNCTION(str_pad);
PHP_FUNCTION(sscanf);
PHP_FUNCTION(str_shuffle);
PHP_FUNCTION(str_word_count);
PHP_FUNCTION(str_split);
PHP_FUNCTION(strpbrk);
PHP_FUNCTION(substr_compare);
#ifdef HAVE_STRCOLL
PHP_FUNCTION(strcoll);
#endif
#if HAVE_STRFMON
PHP_FUNCTION(money_format);
#endif

#if defined(HAVE_LOCALECONV) && defined(ZTS)
PHP_MINIT_FUNCTION(localeconv);
PHP_MSHUTDOWN_FUNCTION(localeconv);
#endif
#if HAVE_NL_LANGINFO
PHP_MINIT_FUNCTION(nl_langinfo);
#endif

#define strnatcmp(a, b) \
	strnatcmp_ex(a, strlen(a), b, strlen(b), 0)
#define strnatcasecmp(a, b) \
	strnatcmp_ex(a, strlen(a), b, strlen(b), 1)
PHPAPI int strnatcmp_ex(char const *a, size_t a_len, char const *b, size_t b_len, int fold_case);

#ifdef HAVE_LOCALECONV
PHPAPI struct lconv *localeconv_r(struct lconv *out);
#endif

PHPAPI char *php_strtoupper(char *s, size_t len);
PHPAPI char *php_strtolower(char *s, size_t len);
PHPAPI char *php_strtr(char *str, int len, char *str_from, char *str_to, int trlen);
PHPAPI char *php_addslashes(char *str, int length, int *new_length, int freeit TSRMLS_DC);
PHPAPI char *php_addslashes_ex(char *str, int length, int *new_length, int freeit, int ignore_sybase TSRMLS_DC);
PHPAPI char *php_addcslashes(char *str, int length, int *new_length, int freeit, char *what, int wlength TSRMLS_DC);
PHPAPI void php_stripslashes(char *str, int *len TSRMLS_DC);
PHPAPI void php_stripcslashes(char *str, int *len);
PHPAPI void php_basename(char *s, size_t len, char *suffix, size_t sufflen, char **p_ret, size_t *p_len TSRMLS_DC);
PHPAPI size_t php_dirname(char *str, size_t len);
PHPAPI char *php_stristr(unsigned char *s, unsigned char *t, size_t s_len, size_t t_len);
PHPAPI char *php_str_to_str_ex(char *haystack, int length, char *needle,
		int needle_len, char *str, int str_len, int *_new_length, int case_sensitivity, int *replace_count);
PHPAPI char *php_str_to_str(char *haystack, int length, char *needle,
		int needle_len, char *str, int str_len, int *_new_length);
PHPAPI char *php_trim(char *c, int len, char *what, int what_len, zval *return_value, int mode TSRMLS_DC);
PHPAPI size_t php_strip_tags(char *rbuf, int len, int *state, char *allow, int allow_len);
PHPAPI size_t php_strip_tags_ex(char *rbuf, int len, int *stateptr, char *allow, int allow_len, zend_bool allow_tag_spaces);
PHPAPI int php_char_to_str_ex(char *str, uint len, char from, char *to, int to_len, zval *result, int case_sensitivity, int *replace_count);
PHPAPI int php_char_to_str(char *str, uint len, char from, char *to, int to_len, zval *result);
PHPAPI void php_implode(zval *delim, zval *arr, zval *return_value TSRMLS_DC);
PHPAPI void php_explode(zval *delim, zval *str, zval *return_value, int limit);

PHPAPI size_t php_strspn(char *s1, char *s2, char *s1_end, char *s2_end); 
PHPAPI size_t php_strcspn(char *s1, char *s2, char *s1_end, char *s2_end); 

#ifndef HAVE_STRERROR
PHPAPI char *php_strerror(int errnum);
#define strerror php_strerror
#endif

#ifndef HAVE_MBLEN
# define php_mblen(ptr, len) 1
#else
# if defined(_REENTRANT) && defined(HAVE_MBRLEN) && defined(HAVE_MBSTATE_T)
#  define php_mblen(ptr, len) ((ptr) == NULL ? mbsinit(&BG(mblen_state)): (int)mbrlen(ptr, len, &BG(mblen_state)))
# else
#  define php_mblen(ptr, len) mblen(ptr, len)
# endif
#endif

void register_string_constants(INIT_FUNC_ARGS);

#endif /* PHP_STRING_H */
php/ext/standard/url_scanner_ex.h000064400000004226151730541010013114 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 5                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2010 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: Sascha Schumann <sascha@schumann.cx>                         |
  +----------------------------------------------------------------------+
*/

/* $Id: url_scanner_ex.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef URL_SCANNER_EX_H
#define URL_SCANNER_EX_H

PHP_MINIT_FUNCTION(url_scanner_ex);
PHP_MSHUTDOWN_FUNCTION(url_scanner_ex);

PHP_RINIT_FUNCTION(url_scanner_ex);
PHP_RSHUTDOWN_FUNCTION(url_scanner_ex);

PHPAPI char *php_url_scanner_adapt_single_url(const char *url, size_t urllen, const char *name, const char *value, size_t *newlen TSRMLS_DC);
PHPAPI int php_url_scanner_add_var(char *name, int name_len, char *value, int value_len, int urlencode TSRMLS_DC);
PHPAPI int php_url_scanner_reset_vars(TSRMLS_D);

#include "php_smart_str_public.h"

typedef struct {
	/* Used by the mainloop of the scanner */
	smart_str tag; /* read only */
	smart_str arg; /* read only */
	smart_str val; /* read only */
	smart_str buf;

	/* The result buffer */
	smart_str result;

	/* The data which is appended to each relative URL/FORM */
	smart_str form_app, url_app;

	int active;

	char *lookup_data;
	int state;
	
	/* Everything above is zeroed in RINIT */
	HashTable *tags;
} url_adapt_state_ex_t;

#endif
php/ext/standard/scanf.h000064400000004504151730541010011176 0ustar00/* 
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Clayton Collie <clcollie@mindspring.com>                     |
   +----------------------------------------------------------------------+
*/

/* $Id: scanf.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef  SCANF_H
#define  SCANF_H


#define SCAN_MAX_ARGS   0xFF    /* Maximum number of variable which can be      */
                                /* passed to (f|s)scanf. This is an artifical   */
                                /* upper limit to keep resources in check and   */
                                /* minimize the possibility of exploits         */

#define SCAN_SUCCESS			SUCCESS	
#define SCAN_ERROR_EOF			-1	/* indicates premature termination of scan 	*/
									/* can be caused by bad parameters or format*/
									/* string.									*/
#define SCAN_ERROR_INVALID_FORMAT		(SCAN_ERROR_EOF - 1)
#define SCAN_ERROR_VAR_PASSED_BYVAL		(SCAN_ERROR_INVALID_FORMAT - 1)
#define SCAN_ERROR_WRONG_PARAM_COUNT	(SCAN_ERROR_VAR_PASSED_BYVAL - 1)
#define SCAN_ERROR_INTERNAL             (SCAN_ERROR_WRONG_PARAM_COUNT - 1)


/*  
 * The following are here solely for the benefit of the scanf type functions
 * e.g. fscanf
 */
PHPAPI int ValidateFormat(char *format, int numVars, int *totalVars);
PHPAPI int php_sscanf_internal(char *string,char *format,int argCount,zval ***args,
				int varStart, zval **return_value TSRMLS_DC);


#endif /* SCANF_H */
php/ext/standard/streamsfuncs.h000064400000005117151730541020012623 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 5                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2010 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Wez Furlong <wez@thebrainroom.com>                          |
  +----------------------------------------------------------------------+
*/

/* $Id: streamsfuncs.h 293036 2010-01-03 09:23:27Z sebastian $ */

/* Flags for stream_socket_client */
#define PHP_STREAM_CLIENT_PERSISTENT	1
#define PHP_STREAM_CLIENT_ASYNC_CONNECT	2
#define PHP_STREAM_CLIENT_CONNECT		4

PHP_FUNCTION(stream_socket_client);
PHP_FUNCTION(stream_socket_server);
PHP_FUNCTION(stream_socket_accept);
PHP_FUNCTION(stream_socket_get_name);
PHP_FUNCTION(stream_socket_recvfrom);
PHP_FUNCTION(stream_socket_sendto);

PHP_FUNCTION(stream_copy_to_stream);
PHP_FUNCTION(stream_get_contents);

PHP_FUNCTION(stream_set_blocking);
PHP_FUNCTION(stream_select);
PHP_FUNCTION(stream_set_timeout);
PHP_FUNCTION(stream_set_write_buffer);
PHP_FUNCTION(stream_get_transports);
PHP_FUNCTION(stream_get_wrappers);
PHP_FUNCTION(stream_get_line);
PHP_FUNCTION(stream_get_meta_data);
PHP_FUNCTION(stream_wrapper_register);
PHP_FUNCTION(stream_wrapper_unregister);
PHP_FUNCTION(stream_wrapper_restore);
PHP_FUNCTION(stream_context_create);
PHP_FUNCTION(stream_context_set_params);
PHP_FUNCTION(stream_context_set_option);
PHP_FUNCTION(stream_context_get_options);
PHP_FUNCTION(stream_context_get_default);
PHP_FUNCTION(stream_filter_prepend);
PHP_FUNCTION(stream_filter_append);
PHP_FUNCTION(stream_filter_remove);
PHP_FUNCTION(stream_socket_enable_crypto);
PHP_FUNCTION(stream_socket_shutdown);
PHP_FUNCTION(stream_socket_pair);
PHP_FUNCTION(stream_is_local);

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */

php/ext/standard/microtime.h000064400000002611151730541020012072 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Paul Panotzki - Bunyip Information Systems                   |
   +----------------------------------------------------------------------+
*/

/* $Id: microtime.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef MICROTIME_H
#define MICROTIME_H

#ifdef HAVE_GETTIMEOFDAY
PHP_FUNCTION(microtime);
PHP_FUNCTION(gettimeofday);
#endif
#ifdef HAVE_GETRUSAGE
PHP_FUNCTION(getrusage);
#endif

#endif /* MICROTIME_H */
php/ext/standard/php_link.h000064400000002562151730541030011714 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author:                                                              |
   +----------------------------------------------------------------------+
*/

/* $Id: php_link.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_LINK_H
#define PHP_LINK_H

#ifdef HAVE_SYMLINK

PHP_FUNCTION(link);
PHP_FUNCTION(readlink);
PHP_FUNCTION(linkinfo);
PHP_FUNCTION(symlink);

#endif

#endif /* PHP_LINK_H */
php/ext/standard/php_fopen_wrappers.h000064400000003723151730541030014011 0ustar00/* 
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Rasmus Lerdorf <rasmus@php.net>                             |
   |          Jim Winstead <jimw@php.net>                                 |
   |          Hartmut Holzgraefe <hholzgra@php.net>                       |
   +----------------------------------------------------------------------+
*/

/* $Id: php_fopen_wrappers.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_FOPEN_WRAPPERS_H
#define PHP_FOPEN_WRAPPERS_H

php_stream *php_stream_url_wrap_http(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC);
php_stream *php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC);
extern PHPAPI php_stream_wrapper php_stream_http_wrapper;
extern PHPAPI php_stream_wrapper php_stream_ftp_wrapper;
extern php_stream_wrapper php_stream_php_wrapper;
extern php_stream_wrapper php_plain_files_wrapper;

#endif
php/ext/standard/winver.h000064400000014351151730541040011422 0ustar00#ifndef _PHP_WINVER_H
#define _PHP_WINVER_H

#ifndef SM_TABLETPC
#define SM_TABLETPC 86
#endif
#ifndef SM_MEDIACENTER
#define SM_MEDIACENTER 87
#endif
#ifndef SM_STARTER
#define SM_STARTER 88
#endif
#ifndef SM_SERVERR2
#define SM_SERVERR2 89
#endif
#ifndef VER_SUITE_WH_SERVER
#define VER_SUITE_WH_SERVER 0x8000
#endif

#ifndef PRODUCT_ULTIMATE
#define PRODUCT_UNDEFINED                           0x00000000
#define PRODUCT_ULTIMATE                            0x00000001
#define PRODUCT_HOME_BASIC                          0x00000002
#define PRODUCT_HOME_PREMIUM                        0x00000003
#define PRODUCT_ENTERPRISE                          0x00000004
#define PRODUCT_HOME_BASIC_N                        0x00000005
#define PRODUCT_BUSINESS                            0x00000006
#define PRODUCT_STANDARD_SERVER                     0x00000007
#define PRODUCT_DATACENTER_SERVER                   0x00000008
#define PRODUCT_SMALLBUSINESS_SERVER                0x00000009
#define PRODUCT_ENTERPRISE_SERVER                   0x0000000A
#define PRODUCT_STARTER                             0x0000000B
#define PRODUCT_DATACENTER_SERVER_CORE              0x0000000C
#define PRODUCT_STANDARD_SERVER_CORE                0x0000000D
#define PRODUCT_ENTERPRISE_SERVER_CORE              0x0000000E
#define PRODUCT_ENTERPRISE_SERVER_IA64              0x0000000F
#define PRODUCT_BUSINESS_N                          0x00000010
#define PRODUCT_WEB_SERVER                          0x00000011
#define PRODUCT_CLUSTER_SERVER                      0x00000012
#define PRODUCT_HOME_SERVER                         0x00000013
#define PRODUCT_STORAGE_EXPRESS_SERVER              0x00000014
#define PRODUCT_STORAGE_STANDARD_SERVER             0x00000015
#define PRODUCT_STORAGE_WORKGROUP_SERVER            0x00000016
#define PRODUCT_STORAGE_ENTERPRISE_SERVER           0x00000017
#define PRODUCT_SERVER_FOR_SMALLBUSINESS            0x00000018
#define PRODUCT_SMALLBUSINESS_SERVER_PREMIUM        0x00000019
#define PRODUCT_HOME_PREMIUM_N                      0x0000001A
#define PRODUCT_ENTERPRISE_N                        0x0000001B
#define PRODUCT_ULTIMATE_N                          0x0000001C
#define PRODUCT_WEB_SERVER_CORE                     0x0000001D
#define PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT    0x0000001E
#define PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY      0x0000001F
#define PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING     0x00000020
#define PRODUCT_SERVER_FOUNDATION                   0x00000021
#define PRODUCT_HOME_PREMIUM_SERVER                 0x00000022
#define PRODUCT_SERVER_FOR_SMALLBUSINESS_V          0x00000023
#define PRODUCT_STANDARD_SERVER_V                   0x00000024
#define PRODUCT_DATACENTER_SERVER_V                 0x00000025
#define PRODUCT_ENTERPRISE_SERVER_V                 0x00000026
#define PRODUCT_DATACENTER_SERVER_CORE_V            0x00000027
#define PRODUCT_STANDARD_SERVER_CORE_V              0x00000028
#define PRODUCT_ENTERPRISE_SERVER_CORE_V            0x00000029
#define PRODUCT_HYPERV                              0x0000002A
#define PRODUCT_STORAGE_EXPRESS_SERVER_CORE         0x0000002B
#define PRODUCT_STORAGE_STANDARD_SERVER_CORE        0x0000002C
#define PRODUCT_STORAGE_WORKGROUP_SERVER_CORE       0x0000002D
#define PRODUCT_STORAGE_ENTERPRISE_SERVER_CORE      0x0000002E
#define PRODUCT_STARTER_N                           0x0000002F
#define PRODUCT_PROFESSIONAL                        0x00000030
#define PRODUCT_PROFESSIONAL_N                      0x00000031
#define PRODUCT_SB_SOLUTION_SERVER                  0x00000032
#define PRODUCT_SERVER_FOR_SB_SOLUTIONS             0x00000033
#define PRODUCT_STANDARD_SERVER_SOLUTIONS           0x00000034
#define PRODUCT_STANDARD_SERVER_SOLUTIONS_CORE      0x00000035
#define PRODUCT_SB_SOLUTION_SERVER_EM               0x00000036
#define PRODUCT_SERVER_FOR_SB_SOLUTIONS_EM          0x00000037
#define PRODUCT_SOLUTION_EMBEDDEDSERVER             0x00000038
#define PRODUCT_ESSENTIALBUSINESS_SERVER_MGMT       0x0000003B
#define PRODUCT_ESSENTIALBUSINESS_SERVER_ADDL       0x0000003C
#define PRODUCT_ESSENTIALBUSINESS_SERVER_MGMTSVC    0x0000003D
#define PRODUCT_ESSENTIALBUSINESS_SERVER_ADDLSVC    0x0000003E
#define PRODUCT_SMALLBUSINESS_SERVER_PREMIUM_CORE   0x0000003F
#define PRODUCT_CLUSTER_SERVER_V                    0x00000040
#define PRODUCT_ENTERPRISE_EVALUATION               0x00000048
#define PRODUCT_MULTIPOINT_STANDARD_SERVER          0x0000004C
#define PRODUCT_MULTIPOINT_PREMIUM_SERVER           0x0000004D
#define PRODUCT_STANDARD_EVALUATION_SERVER          0x0000004F
#define PRODUCT_DATACENTER_EVALUATION_SERVER        0x00000050
#define PRODUCT_ENTERPRISE_N_EVALUATION             0x00000054
#define PRODUCT_STORAGE_WORKGROUP_EVALUATION_SERVER 0x0000005F
#define PRODUCT_STORAGE_STANDARD_EVALUATION_SERVER  0x00000060
#define PRODUCT_CORE_N                              0x00000062
#define PRODUCT_CORE_COUNTRYSPECIFIC                0x00000063
#define PRODUCT_CORE_SINGLELANGUAGE                 0x00000064
#define PRODUCT_CORE                                0x00000065
#define PRODUCT_PROFESSIONAL_WMC                    0x00000067
#endif

#ifndef VER_NT_WORKSTATION
#define VER_NT_WORKSTATION              0x0000001
#define VER_NT_DOMAIN_CONTROLLER        0x0000002
#define VER_NT_SERVER                   0x0000003
#endif

#ifndef VER_SUITE_SMALLBUSINESS
#define VER_SUITE_SMALLBUSINESS             0x00000001
#define VER_SUITE_ENTERPRISE                0x00000002
#define VER_SUITE_BACKOFFICE                0x00000004
#define VER_SUITE_COMMUNICATIONS            0x00000008
#define VER_SUITE_TERMINAL                  0x00000010
#define VER_SUITE_SMALLBUSINESS_RESTRICTED  0x00000020
#define VER_SUITE_EMBEDDEDNT                0x00000040
#define VER_SUITE_DATACENTER                0x00000080
#define VER_SUITE_SINGLEUSERTS              0x00000100
#define VER_SUITE_PERSONAL                  0x00000200
#define VER_SUITE_BLADE                     0x00000400
#define VER_SUITE_EMBEDDED_RESTRICTED       0x00000800
#define VER_SUITE_SECURITY_APPLIANCE        0x00001000
#endif

#ifndef VER_SUITE_STORAGE_SERVER
# define VER_SUITE_STORAGE_SERVER            0x00002000
#endif

#ifndef VER_SUITE_COMPUTE_SERVER
# define VER_SUITE_COMPUTE_SERVER            0x00004000
#endif

#ifndef PROCESSOR_ARCHITECTURE_AMD64
#define PROCESSOR_ARCHITECTURE_AMD64            9
#endif

#endif
php/ext/standard/md5.h000064400000005433151730541050010577 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Rasmus Lerdorf <rasmus@lerdorf.on.ca>                        |
   +----------------------------------------------------------------------+
*/

/* $Id: md5.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef MD5_H
#define MD5_H
/* MD5.H - header file for MD5C.C
 */

/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
   rights reserved.

   License to copy and use this software is granted provided that it
   is identified as the "RSA Data Security, Inc. MD5 Message-Digest
   Algorithm" in all material mentioning or referencing this software
   or this function.

   License is also granted to make and use derivative works provided
   that such works are identified as "derived from the RSA Data
   Security, Inc. MD5 Message-Digest Algorithm" in all material
   mentioning or referencing the derived work.

   RSA Data Security, Inc. makes no representations concerning either
   the merchantability of this software or the suitability of this
   software for any particular purpose. It is provided "as is"
   without express or implied warranty of any kind.

   These notices must be retained in any copies of any part of this
   documentation and/or software.
 */

#include "ext/standard/basic_functions.h"

/* MD5 context. */
typedef struct {
	php_uint32 state[4];				/* state (ABCD) */
	php_uint32 count[2];				/* number of bits, modulo 2^64 (lsb first) */
	unsigned char buffer[64];	/* input buffer */
} PHP_MD5_CTX;

PHPAPI void make_digest(char *md5str, unsigned char *digest);
PHPAPI void make_digest_ex(char *md5str, unsigned char *digest, int len);
PHPAPI void PHP_MD5Init(PHP_MD5_CTX *);
PHPAPI void PHP_MD5Update(PHP_MD5_CTX *, const unsigned char *, unsigned int);
PHPAPI void PHP_MD5Final(unsigned char[16], PHP_MD5_CTX *);

PHP_NAMED_FUNCTION(php_if_md5);
PHP_NAMED_FUNCTION(php_if_md5_file);

#endif
php/ext/standard/credits_sapi.h000064400000002630151730541050012557 0ustar00/* 
                      DO NOT EDIT THIS FILE!

 it has been automaticaly created by php5/scripts/credits from  
 the information found in the various php5/ext/.../CREDITS and
 php5/sapi/.../CREDITS files 
 
 if you want to change an entry you have to edit the appropriate 
 CREDITS file instead

*/

CREDIT_LINE("AOLserver", "Sascha Schumann");
CREDIT_LINE("Apache 1.3 (apache_hooks)", "Rasmus Lerdorf, Zeev Suraski, Stig Bakken, David Sklar, George Schlossnagle, Lukas Schroeder");
CREDIT_LINE("Apache 1.3", "Rasmus Lerdorf, Zeev Suraski, Stig Bakken, David Sklar");
CREDIT_LINE("Apache 2.0 Filter", "Sascha Schumann, Aaron Bannert");
CREDIT_LINE("Apache 2.0 Handler", "Ian Holsman, Justin Erenkrantz (based on Apache 2.0 Filter code)");
CREDIT_LINE("Caudium / Roxen", "David Hedbor");
CREDIT_LINE("CGI / FastCGI", "Rasmus Lerdorf, Stig Bakken, Shane Caraveo, Dmitry Stogov");
CREDIT_LINE("CLI", "Edin Kadribasic, Marcus Boerger, Johannes Schlueter");
CREDIT_LINE("Continuity", "Alex Leigh (based on nsapi code)");
CREDIT_LINE("Embed", "Edin Kadribasic");
CREDIT_LINE("ISAPI", "Andi Gutmans, Zeev Suraski");
CREDIT_LINE("NSAPI", "Jayakumar Muthukumarasamy, Uwe Schindler");
CREDIT_LINE("phttpd", "Thies C. Arntzen");
CREDIT_LINE("pi3web", "Holger Zimmermann");
CREDIT_LINE("Sendmail Milter", "Harald Radi");
CREDIT_LINE("thttpd", "Sascha Schumann");
CREDIT_LINE("tux", "Sascha Schumann");
CREDIT_LINE("WebJames", "Alex Waugh");
php/ext/standard/file.h000064400000010322151730541050011022 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Rasmus Lerdorf <rasmus@lerdorf.on.ca>                        |
   +----------------------------------------------------------------------+
*/

/* $Id: file.h 293036 2010-01-03 09:23:27Z sebastian $ */

/* Synced with php 3.0 revision 1.30 1999-06-16 [ssb] */

#ifndef FILE_H
#define FILE_H

PHP_MINIT_FUNCTION(file);
PHP_MSHUTDOWN_FUNCTION(file);

PHP_FUNCTION(tempnam);
PHP_NAMED_FUNCTION(php_if_tmpfile);
PHP_NAMED_FUNCTION(php_if_fopen);
PHPAPI PHP_FUNCTION(fclose);
PHP_FUNCTION(popen);
PHP_FUNCTION(pclose);
PHPAPI PHP_FUNCTION(feof);
PHPAPI PHP_FUNCTION(fread);
PHPAPI PHP_FUNCTION(fgetc);
PHPAPI PHP_FUNCTION(fgets);
PHP_FUNCTION(fscanf);
PHPAPI PHP_FUNCTION(fgetss);
PHP_FUNCTION(fgetcsv);
PHP_FUNCTION(fputcsv);
PHPAPI PHP_FUNCTION(fwrite);
PHPAPI PHP_FUNCTION(fflush);
PHPAPI PHP_FUNCTION(rewind);
PHPAPI PHP_FUNCTION(ftell);
PHPAPI PHP_FUNCTION(fseek);
PHP_FUNCTION(mkdir);
PHP_FUNCTION(rmdir);
PHPAPI PHP_FUNCTION(fpassthru);
PHP_FUNCTION(readfile);
PHP_FUNCTION(umask);
PHP_FUNCTION(rename);
PHP_FUNCTION(unlink);
PHP_FUNCTION(copy);
PHP_FUNCTION(file);
PHP_FUNCTION(file_get_contents);
PHP_FUNCTION(file_put_contents);
PHP_FUNCTION(get_meta_tags);
PHP_FUNCTION(flock);
PHP_FUNCTION(fd_set);
PHP_FUNCTION(fd_isset);
#if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
PHP_FUNCTION(realpath);
#endif
#ifdef HAVE_FNMATCH
PHP_FUNCTION(fnmatch);
#endif
PHP_NAMED_FUNCTION(php_if_ftruncate);
PHP_NAMED_FUNCTION(php_if_fstat);
PHP_FUNCTION(sys_get_temp_dir);

PHP_MINIT_FUNCTION(user_streams);

PHPAPI int php_le_stream_context(void);
PHPAPI int php_set_sock_blocking(int socketd, int block TSRMLS_DC);
PHPAPI int php_copy_file(char *src, char *dest TSRMLS_DC);
PHPAPI int php_copy_file_ex(char *src, char *dest, int src_chk TSRMLS_DC);
PHPAPI int php_mkdir_ex(char *dir, long mode, int options TSRMLS_DC);
PHPAPI int php_mkdir(char *dir, long mode TSRMLS_DC);
PHPAPI void php_fgetcsv(php_stream *stream, char delimiter, char enclosure, size_t buf_len, char *buf, zval *return_value TSRMLS_DC);

#define META_DEF_BUFSIZE 8192

#define PHP_FILE_USE_INCLUDE_PATH 1
#define PHP_FILE_IGNORE_NEW_LINES 2
#define PHP_FILE_SKIP_EMPTY_LINES 4
#define PHP_FILE_APPEND 8
#define PHP_FILE_NO_DEFAULT_CONTEXT 16

typedef enum _php_meta_tags_token {
	TOK_EOF = 0,
	TOK_OPENTAG,
	TOK_CLOSETAG,
	TOK_SLASH,
	TOK_EQUAL,
	TOK_SPACE,
	TOK_ID,
	TOK_STRING,
	TOK_OTHER
} php_meta_tags_token;

typedef struct _php_meta_tags_data {
	php_stream *stream;
	int ulc;
	int lc;
	char *input_buffer;
	char *token_data;
	int token_len;
	int in_meta;
} php_meta_tags_data;

php_meta_tags_token php_next_meta_token(php_meta_tags_data * TSRMLS_DC);

typedef struct {
  	int pclose_ret;
	size_t def_chunk_size;
	long auto_detect_line_endings;
	long default_socket_timeout;
	char *user_agent;
	char *user_stream_current_filename; /* for simple recursion protection */
	php_stream_context *default_context;
	HashTable *stream_wrappers;			/* per-request copy of url_stream_wrappers_hash */
	HashTable *stream_filters;			/* per-request copy of stream_filters_hash */
} php_file_globals;

#ifdef ZTS
#define FG(v) TSRMG(file_globals_id, php_file_globals *, v)
extern PHPAPI int file_globals_id;
#else
#define FG(v) (file_globals.v)
extern PHPAPI php_file_globals file_globals;
#endif


#endif /* FILE_H */

php/ext/standard/php_assert.h000064400000002712151730541060012260 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Thies C. Arntzen <thies@thieso.net>                          |
   +----------------------------------------------------------------------+
*/

/* $Id: php_assert.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_ASSERT_H
#define PHP_ASSERT_H

PHP_MINIT_FUNCTION(assert);
PHP_MSHUTDOWN_FUNCTION(assert);
PHP_RINIT_FUNCTION(assert);
PHP_RSHUTDOWN_FUNCTION(assert);
PHP_MINFO_FUNCTION(assert);
PHP_FUNCTION(assert);
PHP_FUNCTION(assert_options);

#endif /* PHP_ASSERT_H */
php/ext/standard/html.h000064400000004211151730541060011050 0ustar00/* 
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Rasmus Lerdorf <rasmus@lerdorf.on.ca>                        |
   +----------------------------------------------------------------------+
*/

/* $Id: html.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef HTML_H
#define HTML_H

#define ENT_HTML_QUOTE_NONE		0
#define ENT_HTML_QUOTE_SINGLE	1
#define ENT_HTML_QUOTE_DOUBLE	2

#define ENT_COMPAT    ENT_HTML_QUOTE_DOUBLE
#define ENT_QUOTES    (ENT_HTML_QUOTE_DOUBLE | ENT_HTML_QUOTE_SINGLE)
#define ENT_NOQUOTES  ENT_HTML_QUOTE_NONE

void register_html_constants(INIT_FUNC_ARGS);

PHP_FUNCTION(htmlspecialchars);
PHP_FUNCTION(htmlentities);
PHP_FUNCTION(htmlspecialchars_decode);
PHP_FUNCTION(html_entity_decode);
PHP_FUNCTION(get_html_translation_table);

PHPAPI char *php_escape_html_entities(unsigned char *old, int oldlen, int *newlen, int all, int quote_style, char *hint_charset TSRMLS_DC);
PHPAPI char *php_escape_html_entities_ex(unsigned char *old, int oldlen, int *newlen, int all, int quote_style, char *hint_charset, zend_bool double_encode TSRMLS_DC);
PHPAPI char *php_unescape_html_entities(unsigned char *old, int oldlen, int *newlen, int all, int quote_style, char *hint_charset TSRMLS_DC);

#endif /* HTML_H */
php/ext/standard/cyr_convert.h000064400000002453151730541070012450 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Kirill Maximov <kir@rus.net>                                 |
   +----------------------------------------------------------------------+
*/

/* $Id: cyr_convert.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef CYR_CONVERT_H
#define CYR_CONVERT_H

PHP_FUNCTION(convert_cyr_string);

#endif /* CYR_CONVERT_H */



php/ext/standard/html_tables.h000064400001660661151730541070012425 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 7                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2018 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
*/

/* $Id$ */

#ifndef HTML_TABLES_H
#define HTML_TABLES_H

/**************************************************************************
***************************************************************************
**        THIS FILE IS AUTOMATICALLY GENERATED. DO NOT MODIFY IT.        **
***************************************************************************
** Please change html_tables/html_table_gen.php instead and then         **
** run it in order to generate this file                                 **
***************************************************************************
**************************************************************************/

enum entity_charset { cs_utf_8, cs_8859_1, cs_cp1252, cs_8859_15, cs_cp1251,
					  cs_8859_5, cs_cp866, cs_macroman, cs_koi8r, cs_big5,
					  cs_gb2312, cs_big5hkscs, cs_sjis, cs_eucjp,
					  cs_numelems /* used to count the number of charsets */
					};
#define CHARSET_UNICODE_COMPAT(cs)	((cs) <= cs_8859_1)
#define CHARSET_SINGLE_BYTE(cs)		((cs) > cs_utf_8 && (cs) < cs_big5)
#define CHARSET_PARTIAL_SUPPORT(cs)	((cs) >= cs_big5)

static const struct {
	const char *codeset;
	uint32_t codeset_len;
	enum entity_charset charset;
} charset_map[] = {
	{ "ISO-8859-1",		sizeof("ISO-8859-1")-1,		cs_8859_1 },
	{ "ISO8859-1",		sizeof("ISO8859-1")-1,		cs_8859_1 },
	{ "ISO-8859-15",	sizeof("ISO-8859-15")-1,	cs_8859_15 },
	{ "ISO8859-15",		sizeof("ISO8859-15")-1,		cs_8859_15 },
	{ "utf-8",			sizeof("utf-8")-1,			cs_utf_8 },
	{ "cp1252", 		sizeof("cp1252")-1, 		cs_cp1252 },
	{ "Windows-1252",	sizeof("Windows-1252")-1,	cs_cp1252 },
	{ "1252",			sizeof("1252")-1,			cs_cp1252 },
	{ "BIG5",			sizeof("BIG5")-1,			cs_big5 },
	{ "950",			sizeof("950")-1,			cs_big5 },
	{ "GB2312",			sizeof("GB2312")-1,			cs_gb2312 },
	{ "936",			sizeof("936")-1,			cs_gb2312 },
	{ "BIG5-HKSCS",		sizeof("BIG5-HKSCS")-1,		cs_big5hkscs },
	{ "Shift_JIS",		sizeof("Shift_JIS")-1,		cs_sjis },
	{ "SJIS",			sizeof("SJIS")-1,			cs_sjis },
	{ "932",			sizeof("932")-1,			cs_sjis },
	{ "SJIS-win",		sizeof("SJIS-win")-1,		cs_sjis },
	{ "CP932",			sizeof("CP932")-1,			cs_sjis },
	{ "EUCJP",			sizeof("EUCJP")-1,			cs_eucjp },
	{ "EUC-JP",			sizeof("EUC-JP")-1,			cs_eucjp },
	{ "eucJP-win",		sizeof("eucJP-win")-1,		cs_eucjp },
	{ "KOI8-R",			sizeof("KOI8-R")-1,			cs_koi8r },
	{ "koi8-ru",		sizeof("koi8-ru")-1,		cs_koi8r },
	{ "koi8r",			sizeof("koi8r")-1,			cs_koi8r },
	{ "cp1251",			sizeof("cp1251")-1,			cs_cp1251 },
	{ "Windows-1251",	sizeof("Windows-1251")-1,	cs_cp1251 },
	{ "win-1251",		sizeof("win-1251")-1,		cs_cp1251 },
	{ "iso8859-5",		sizeof("iso8859-5")-1,		cs_8859_5 },
	{ "iso-8859-5",		sizeof("iso-8859-5")-1,		cs_8859_5 },
	{ "cp866",			sizeof("cp866")-1,			cs_cp866 },
	{ "866",			sizeof("866")-1,			cs_cp866 },
	{ "ibm866",			sizeof("ibm866")-1,			cs_cp866 },
	{ "MacRoman",		sizeof("MacRoman")-1,		cs_macroman }
};

/* longest entity name length excluding & and ; */
#define LONGEST_ENTITY_LENGTH 31

/* Definitions for mappings *to* Unicode.
 * The origin charset must have at most 256 code points.
 * The multi-byte encodings are not supported */
typedef struct {
    unsigned short uni_cp[64];
} enc_to_uni_stage2;

typedef struct {
    const enc_to_uni_stage2 *inner[4];
} enc_to_uni;

/* bits 7-8 bits (only single bytes encodings supported )*/
#define ENT_ENC_TO_UNI_STAGE1(k) ((k & 0xC0) >> 6)
/* bits 1-6 */
#define ENT_ENC_TO_UNI_STAGE2(k) ((k) & 0x3F)

/* {{{ Mappings *to* Unicode for ISO-8859-1 */

/* {{{ Stage 2 tables for ISO-8859-1 */

static const enc_to_uni_stage2 enc_to_uni_s2_iso88591_00 = { {
	0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005,
	0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B,
	0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011,
	0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
	0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D,
	0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023,
	0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029,
	0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
	0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035,
	0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B,
	0x003C, 0x003D, 0x003E, 0x003F,
} };

static const enc_to_uni_stage2 enc_to_uni_s2_iso88591_40 = { {
	0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045,
	0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B,
	0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051,
	0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
	0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D,
	0x005E, 0x005F, 0x0060, 0x0061, 0x0062, 0x0063,
	0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069,
	0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
	0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075,
	0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B,
	0x007C, 0x007D, 0x007E, 0x007F,
} };

static const enc_to_uni_stage2 enc_to_uni_s2_iso88591_80 = { {
	0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085,
	0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B,
	0x008C, 0x008D, 0x008E, 0x008F, 0x0090, 0x0091,
	0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
	0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D,
	0x009E, 0x009F, 0x00A0, 0x00A1, 0x00A2, 0x00A3,
	0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9,
	0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
	0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5,
	0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB,
	0x00BC, 0x00BD, 0x00BE, 0x00BF,
} };

static const enc_to_uni_stage2 enc_to_uni_s2_iso88591_C0 = { {
	0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5,
	0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB,
	0x00CC, 0x00CD, 0x00CE, 0x00CF, 0x00D0, 0x00D1,
	0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
	0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD,
	0x00DE, 0x00DF, 0x00E0, 0x00E1, 0x00E2, 0x00E3,
	0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9,
	0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
	0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5,
	0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB,
	0x00FC, 0x00FD, 0x00FE, 0x00FF,
} };

/* end of stage 2 tables for ISO-8859-1 }}} */

/* {{{ Stage 1 table for ISO-8859-1 */
static const enc_to_uni enc_to_uni_iso88591 = { {
	&enc_to_uni_s2_iso88591_00,
	&enc_to_uni_s2_iso88591_40,
	&enc_to_uni_s2_iso88591_80,
	&enc_to_uni_s2_iso88591_C0 }
};
/* end of stage 1 table for ISO-8859-1 }}} */

/* {{{ Mappings *to* Unicode for ISO-8859-5 */

/* {{{ Stage 2 tables for ISO-8859-5 */

static const enc_to_uni_stage2 enc_to_uni_s2_iso88595_80 = { {
	0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085,
	0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B,
	0x008C, 0x008D, 0x008E, 0x008F, 0x0090, 0x0091,
	0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
	0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D,
	0x009E, 0x009F, 0x00A0, 0x0401, 0x0402, 0x0403,
	0x0404, 0x0405, 0x0406, 0x0407, 0x0408, 0x0409,
	0x040A, 0x040B, 0x040C, 0x00AD, 0x040E, 0x040F,
	0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415,
	0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B,
	0x041C, 0x041D, 0x041E, 0x041F,
} };

static const enc_to_uni_stage2 enc_to_uni_s2_iso88595_C0 = { {
	0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425,
	0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B,
	0x042C, 0x042D, 0x042E, 0x042F, 0x0430, 0x0431,
	0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
	0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D,
	0x043E, 0x043F, 0x0440, 0x0441, 0x0442, 0x0443,
	0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449,
	0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
	0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455,
	0x0456, 0x0457, 0x0458, 0x0459, 0x045A, 0x045B,
	0x045C, 0x00A7, 0x045E, 0x045F,
} };

/* end of stage 2 tables for ISO-8859-5 }}} */

/* {{{ Stage 1 table for ISO-8859-5 */
static const enc_to_uni enc_to_uni_iso88595 = { {
	&enc_to_uni_s2_iso88591_00,
	&enc_to_uni_s2_iso88591_40,
	&enc_to_uni_s2_iso88595_80,
	&enc_to_uni_s2_iso88595_C0 }
};
/* end of stage 1 table for ISO-8859-5 }}} */

/* {{{ Mappings *to* Unicode for ISO-8859-15 */

/* {{{ Stage 2 tables for ISO-8859-15 */

static const enc_to_uni_stage2 enc_to_uni_s2_iso885915_80 = { {
	0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085,
	0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B,
	0x008C, 0x008D, 0x008E, 0x008F, 0x0090, 0x0091,
	0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
	0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D,
	0x009E, 0x009F, 0x00A0, 0x00A1, 0x00A2, 0x00A3,
	0x20AC, 0x00A5, 0x0160, 0x00A7, 0x0161, 0x00A9,
	0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
	0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x017D, 0x00B5,
	0x00B6, 0x00B7, 0x017E, 0x00B9, 0x00BA, 0x00BB,
	0x0152, 0x0153, 0x0178, 0x00BF,
} };

/* end of stage 2 tables for ISO-8859-15 }}} */

/* {{{ Stage 1 table for ISO-8859-15 */
static const enc_to_uni enc_to_uni_iso885915 = { {
	&enc_to_uni_s2_iso88591_00,
	&enc_to_uni_s2_iso88591_40,
	&enc_to_uni_s2_iso885915_80,
	&enc_to_uni_s2_iso88591_C0 }
};
/* end of stage 1 table for ISO-8859-15 }}} */

/* {{{ Mappings *to* Unicode for Windows-1252 */

/* {{{ Stage 2 tables for Windows-1252 */

static const enc_to_uni_stage2 enc_to_uni_s2_win1252_80 = { {
	0x20AC, 0xFFFF, 0x201A, 0x0192, 0x201E, 0x2026,
	0x2020, 0x2021, 0x02C6, 0x2030, 0x0160, 0x2039,
	0x0152, 0xFFFF, 0x017D, 0xFFFF, 0xFFFF, 0x2018,
	0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
	0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0xFFFF,
	0x017E, 0x0178, 0x00A0, 0x00A1, 0x00A2, 0x00A3,
	0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9,
	0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
	0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5,
	0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB,
	0x00BC, 0x00BD, 0x00BE, 0x00BF,
} };

/* end of stage 2 tables for Windows-1252 }}} */

/* {{{ Stage 1 table for Windows-1252 */
static const enc_to_uni enc_to_uni_win1252 = { {
	&enc_to_uni_s2_iso88591_00,
	&enc_to_uni_s2_iso88591_40,
	&enc_to_uni_s2_win1252_80,
	&enc_to_uni_s2_iso88591_C0 }
};
/* end of stage 1 table for Windows-1252 }}} */

/* {{{ Mappings *to* Unicode for Windows-1251 */

/* {{{ Stage 2 tables for Windows-1251 */

static const enc_to_uni_stage2 enc_to_uni_s2_win1251_80 = { {
	0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026,
	0x2020, 0x2021, 0x20AC, 0x2030, 0x0409, 0x2039,
	0x040A, 0x040C, 0x040B, 0x040F, 0x0452, 0x2018,
	0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
	0xFFFF, 0x2122, 0x0459, 0x203A, 0x045A, 0x045C,
	0x045B, 0x045F, 0x00A0, 0x040E, 0x045E, 0x0408,
	0x00A4, 0x0490, 0x00A6, 0x00A7, 0x0401, 0x00A9,
	0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407,
	0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5,
	0x00B6, 0x00B7, 0x0451, 0x2116, 0x0454, 0x00BB,
	0x0458, 0x0405, 0x0455, 0x0457,
} };

static const enc_to_uni_stage2 enc_to_uni_s2_win1251_C0 = { {
	0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415,
	0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B,
	0x041C, 0x041D, 0x041E, 0x041F, 0x0420, 0x0421,
	0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
	0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D,
	0x042E, 0x042F, 0x0430, 0x0431, 0x0432, 0x0433,
	0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439,
	0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
	0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445,
	0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B,
	0x044C, 0x044D, 0x044E, 0x044F,
} };

/* end of stage 2 tables for Windows-1251 }}} */

/* {{{ Stage 1 table for Windows-1251 */
static const enc_to_uni enc_to_uni_win1251 = { {
	&enc_to_uni_s2_iso88591_00,
	&enc_to_uni_s2_iso88591_40,
	&enc_to_uni_s2_win1251_80,
	&enc_to_uni_s2_win1251_C0 }
};
/* end of stage 1 table for Windows-1251 }}} */

/* {{{ Mappings *to* Unicode for KOI8-R */

/* {{{ Stage 2 tables for KOI8-R */

static const enc_to_uni_stage2 enc_to_uni_s2_koi8r_80 = { {
	0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518,
	0x251C, 0x2524, 0x252C, 0x2534, 0x253C, 0x2580,
	0x2584, 0x2588, 0x258C, 0x2590, 0x2591, 0x2592,
	0x2593, 0x2320, 0x25A0, 0x2219, 0x221A, 0x2248,
	0x2264, 0x2265, 0x00A0, 0x2321, 0x00B0, 0x00B2,
	0x00B7, 0x00F7, 0x2550, 0x2551, 0x2552, 0x0451,
	0x2553, 0x2554, 0x2555, 0x2556, 0x2557, 0x2558,
	0x2559, 0x255A, 0x255B, 0x255C, 0x255D, 0x255E,
	0x255F, 0x2560, 0x2561, 0x0401, 0x2562, 0x2563,
	0x2564, 0x2565, 0x2566, 0x2567, 0x2568, 0x2569,
	0x256A, 0x256B, 0x256C, 0x00A9,
} };

static const enc_to_uni_stage2 enc_to_uni_s2_koi8r_C0 = { {
	0x044E, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435,
	0x0444, 0x0433, 0x0445, 0x0438, 0x0439, 0x043A,
	0x043B, 0x043C, 0x043D, 0x043E, 0x043F, 0x044F,
	0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432,
	0x044C, 0x044B, 0x0437, 0x0448, 0x044D, 0x0449,
	0x0447, 0x044A, 0x042E, 0x0410, 0x0411, 0x0426,
	0x0414, 0x0415, 0x0424, 0x0413, 0x0425, 0x0418,
	0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E,
	0x041F, 0x042F, 0x0420, 0x0421, 0x0422, 0x0423,
	0x0416, 0x0412, 0x042C, 0x042B, 0x0417, 0x0428,
	0x042D, 0x0429, 0x0427, 0x042A,
} };

/* end of stage 2 tables for KOI8-R }}} */

/* {{{ Stage 1 table for KOI8-R */
static const enc_to_uni enc_to_uni_koi8r = { {
	&enc_to_uni_s2_iso88591_00,
	&enc_to_uni_s2_iso88591_40,
	&enc_to_uni_s2_koi8r_80,
	&enc_to_uni_s2_koi8r_C0 }
};
/* end of stage 1 table for KOI8-R }}} */

/* {{{ Mappings *to* Unicode for CP-866 */

/* {{{ Stage 2 tables for CP-866 */

static const enc_to_uni_stage2 enc_to_uni_s2_cp866_80 = { {
	0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415,
	0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B,
	0x041C, 0x041D, 0x041E, 0x041F, 0x0420, 0x0421,
	0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
	0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D,
	0x042E, 0x042F, 0x0430, 0x0431, 0x0432, 0x0433,
	0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439,
	0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561,
	0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557,
	0x255D, 0x255C, 0x255B, 0x2510,
} };

static const enc_to_uni_stage2 enc_to_uni_s2_cp866_C0 = { {
	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C,
	0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566,
	0x2560, 0x2550, 0x256C, 0x2567, 0x2568, 0x2564,
	0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
	0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C,
	0x2590, 0x2580, 0x0440, 0x0441, 0x0442, 0x0443,
	0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449,
	0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
	0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457,
	0x040E, 0x045E, 0x00B0, 0x2219, 0x00B7, 0x221A,
	0x2116, 0x00A4, 0x25A0, 0x00A0,
} };

/* end of stage 2 tables for CP-866 }}} */

/* {{{ Stage 1 table for CP-866 */
static const enc_to_uni enc_to_uni_cp866 = { {
	&enc_to_uni_s2_iso88591_00,
	&enc_to_uni_s2_iso88591_40,
	&enc_to_uni_s2_cp866_80,
	&enc_to_uni_s2_cp866_C0 }
};
/* end of stage 1 table for CP-866 }}} */

/* {{{ Mappings *to* Unicode for MacRoman */

/* {{{ Stage 2 tables for MacRoman */

static const enc_to_uni_stage2 enc_to_uni_s2_macroman_00 = { {
	0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
	0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
	0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
	0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
	0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
	0xFFFF, 0xFFFF, 0x0020, 0x0021, 0x0022, 0x0023,
	0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029,
	0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
	0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035,
	0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B,
	0x003C, 0x003D, 0x003E, 0x003F,
} };

static const enc_to_uni_stage2 enc_to_uni_s2_macroman_40 = { {
	0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045,
	0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B,
	0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051,
	0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
	0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D,
	0x005E, 0x005F, 0x0060, 0x0061, 0x0062, 0x0063,
	0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069,
	0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
	0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075,
	0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B,
	0x007C, 0x007D, 0x007E, 0xFFFF,
} };

static const enc_to_uni_stage2 enc_to_uni_s2_macroman_80 = { {
	0x00C4, 0x00C5, 0x00C7, 0x00C9, 0x00D1, 0x00D6,
	0x00DC, 0x00E1, 0x00E0, 0x00E2, 0x00E4, 0x00E3,
	0x00E5, 0x00E7, 0x00E9, 0x00E8, 0x00EA, 0x00EB,
	0x00ED, 0x00EC, 0x00EE, 0x00EF, 0x00F1, 0x00F3,
	0x00F2, 0x00F4, 0x00F6, 0x00F5, 0x00FA, 0x00F9,
	0x00FB, 0x00FC, 0x2020, 0x00B0, 0x00A2, 0x00A3,
	0x00A7, 0x2022, 0x00B6, 0x00DF, 0x00AE, 0x00A9,
	0x2122, 0x00B4, 0x00A8, 0x2260, 0x00C6, 0x00D8,
	0x221E, 0x00B1, 0x2264, 0x2265, 0x00A5, 0x00B5,
	0x2202, 0x2211, 0x220F, 0x03C0, 0x222B, 0x00AA,
	0x00BA, 0x03A9, 0x00E6, 0x00F8,
} };

static const enc_to_uni_stage2 enc_to_uni_s2_macroman_C0 = { {
	0x00BF, 0x00A1, 0x00AC, 0x221A, 0x0192, 0x2248,
	0x2206, 0x00AB, 0x00BB, 0x2026, 0x00A0, 0x00C0,
	0x00C3, 0x00D5, 0x0152, 0x0153, 0x2013, 0x2014,
	0x201C, 0x201D, 0x2018, 0x2019, 0x00F7, 0x25CA,
	0x00FF, 0x0178, 0x2044, 0x20AC, 0x2039, 0x203A,
	0xFB01, 0xFB02, 0x2021, 0x00B7, 0x201A, 0x201E,
	0x2030, 0x00C2, 0x00CA, 0x00C1, 0x00CB, 0x00C8,
	0x00CD, 0x00CE, 0x00CF, 0x00CC, 0x00D3, 0x00D4,
	0xF8FF, 0x00D2, 0x00DA, 0x00DB, 0x00D9, 0x0131,
	0x02C6, 0x02DC, 0x00AF, 0x02D8, 0x02D9, 0x02DA,
	0x00B8, 0x02DD, 0x02DB, 0x02C7,
} };

/* end of stage 2 tables for MacRoman }}} */

/* {{{ Stage 1 table for MacRoman */
static const enc_to_uni enc_to_uni_macroman = { {
	&enc_to_uni_s2_macroman_00,
	&enc_to_uni_s2_macroman_40,
	&enc_to_uni_s2_macroman_80,
	&enc_to_uni_s2_macroman_C0 }
};
/* end of stage 1 table for MacRoman }}} */

/* {{{ Index of tables for encoding conversion */
static const enc_to_uni *const enc_to_uni_index[cs_numelems] = {
	NULL,
	&enc_to_uni_iso88591,
	&enc_to_uni_win1252,
	&enc_to_uni_iso885915,
	&enc_to_uni_win1251,
	&enc_to_uni_iso88595,
	&enc_to_uni_cp866,
	&enc_to_uni_macroman,
	&enc_to_uni_koi8r,
};
/* }}} */

/* Definitions for mappings *from* Unicode */

typedef struct {
	unsigned short un_code_point; /* we don't need bigger */
	unsigned char cs_code; /* currently, we only have maps to single-byte encodings */
} uni_to_enc;

/* {{{ Mappings *from* Unicode for ISO-8859-15 */
static const uni_to_enc unimap_iso885915[] = {
	{ 0x00A5, 0xA5 },	/* yen sign */
	{ 0x00A7, 0xA7 },	/* section sign */
	{ 0x00A9, 0xA9 },	/* copyright sign */
	{ 0x00AA, 0xAA },	/* feminine ordinal indicator */
	{ 0x00AB, 0xAB },	/* left-pointing double angle quotation mark */
	{ 0x00AC, 0xAC },	/* not sign */
	{ 0x00AD, 0xAD },	/* soft hyphen */
	{ 0x00AE, 0xAE },	/* registered sign */
	{ 0x00AF, 0xAF },	/* macron */
	{ 0x00B0, 0xB0 },	/* degree sign */
	{ 0x00B1, 0xB1 },	/* plus-minus sign */
	{ 0x00B2, 0xB2 },	/* superscript two */
	{ 0x00B3, 0xB3 },	/* superscript three */
	{ 0x00B5, 0xB5 },	/* micro sign */
	{ 0x00B6, 0xB6 },	/* pilcrow sign */
	{ 0x00B7, 0xB7 },	/* middle dot */
	{ 0x00B9, 0xB9 },	/* superscript one */
	{ 0x00BA, 0xBA },	/* masculine ordinal indicator */
	{ 0x00BB, 0xBB },	/* right-pointing double angle quotation mark */
	{ 0x0152, 0xBC },	/* latin capital ligature oe */
	{ 0x0153, 0xBD },	/* latin small ligature oe */
	{ 0x0160, 0xA6 },	/* latin capital letter s with caron */
	{ 0x0161, 0xA8 },	/* latin small letter s with caron */
	{ 0x0178, 0xBE },	/* latin capital letter y with diaeresis */
	{ 0x017D, 0xB4 },	/* latin capital letter z with caron */
	{ 0x017E, 0xB8 },	/* latin small letter z with caron */
	{ 0x20AC, 0xA4 },	/* euro sign */
};
/* {{{ end of mappings *from* Unicode for ISO-8859-15 */

/* {{{ Mappings *from* Unicode for Windows-1252 */
static const uni_to_enc unimap_win1252[] = {
	{ 0x0152, 0x8C },	/* latin capital ligature oe */
	{ 0x0153, 0x9C },	/* latin small ligature oe */
	{ 0x0160, 0x8A },	/* latin capital letter s with caron */
	{ 0x0161, 0x9A },	/* latin small letter s with caron */
	{ 0x0178, 0x9F },	/* latin capital letter y with diaeresis */
	{ 0x017D, 0x8E },	/* latin capital letter z with caron */
	{ 0x017E, 0x9E },	/* latin small letter z with caron */
	{ 0x0192, 0x83 },	/* latin small letter f with hook */
	{ 0x02C6, 0x88 },	/* modifier letter circumflex accent */
	{ 0x02DC, 0x98 },	/* small tilde */
	{ 0x2013, 0x96 },	/* en dash */
	{ 0x2014, 0x97 },	/* em dash */
	{ 0x2018, 0x91 },	/* left single quotation mark */
	{ 0x2019, 0x92 },	/* right single quotation mark */
	{ 0x201A, 0x82 },	/* single low-9 quotation mark */
	{ 0x201C, 0x93 },	/* left double quotation mark */
	{ 0x201D, 0x94 },	/* right double quotation mark */
	{ 0x201E, 0x84 },	/* double low-9 quotation mark */
	{ 0x2020, 0x86 },	/* dagger */
	{ 0x2021, 0x87 },	/* double dagger */
	{ 0x2022, 0x95 },	/* bullet */
	{ 0x2026, 0x85 },	/* horizontal ellipsis */
	{ 0x2030, 0x89 },	/* per mille sign */
	{ 0x2039, 0x8B },	/* single left-pointing angle quotation mark */
	{ 0x203A, 0x9B },	/* single right-pointing angle quotation mark */
	{ 0x20AC, 0x80 },	/* euro sign */
	{ 0x2122, 0x99 },	/* trade mark sign */
};
/* {{{ end of mappings *from* Unicode for Windows-1252 */

/* {{{ Mappings *from* Unicode for Windows-1251 */
static const uni_to_enc unimap_win1251[] = {
	{ 0x00A0, 0xA0 },	/* no-break space */
	{ 0x00A4, 0xA4 },	/* currency sign */
	{ 0x00A6, 0xA6 },	/* broken bar */
	{ 0x00A7, 0xA7 },	/* section sign */
	{ 0x00A9, 0xA9 },	/* copyright sign */
	{ 0x00AB, 0xAB },	/* left-pointing double angle quotation mark */
	{ 0x00AC, 0xAC },	/* not sign */
	{ 0x00AD, 0xAD },	/* soft hyphen */
	{ 0x00AE, 0xAE },	/* registered sign */
	{ 0x00B0, 0xB0 },	/* degree sign */
	{ 0x00B1, 0xB1 },	/* plus-minus sign */
	{ 0x00B5, 0xB5 },	/* micro sign */
	{ 0x00B6, 0xB6 },	/* pilcrow sign */
	{ 0x00B7, 0xB7 },	/* middle dot */
	{ 0x00BB, 0xBB },	/* right-pointing double angle quotation mark */
	{ 0x0401, 0xA8 },	/* cyrillic capital letter io */
	{ 0x0402, 0x80 },	/* cyrillic capital letter dje */
	{ 0x0403, 0x81 },	/* cyrillic capital letter gje */
	{ 0x0404, 0xAA },	/* cyrillic capital letter ukrainian ie */
	{ 0x0405, 0xBD },	/* cyrillic capital letter dze */
	{ 0x0406, 0xB2 },	/* cyrillic capital letter byelorussian-ukrainian i */
	{ 0x0407, 0xAF },	/* cyrillic capital letter yi */
	{ 0x0408, 0xA3 },	/* cyrillic capital letter je */
	{ 0x0409, 0x8A },	/* cyrillic capital letter lje */
	{ 0x040A, 0x8C },	/* cyrillic capital letter nje */
	{ 0x040B, 0x8E },	/* cyrillic capital letter tshe */
	{ 0x040C, 0x8D },	/* cyrillic capital letter kje */
	{ 0x040E, 0xA1 },	/* cyrillic capital letter short u */
	{ 0x040F, 0x8F },	/* cyrillic capital letter dzhe */
	{ 0x0410, 0xC0 },	/* cyrillic capital letter a */
	{ 0x0411, 0xC1 },	/* cyrillic capital letter be */
	{ 0x0412, 0xC2 },	/* cyrillic capital letter ve */
	{ 0x0413, 0xC3 },	/* cyrillic capital letter ghe */
	{ 0x0414, 0xC4 },	/* cyrillic capital letter de */
	{ 0x0415, 0xC5 },	/* cyrillic capital letter ie */
	{ 0x0416, 0xC6 },	/* cyrillic capital letter zhe */
	{ 0x0417, 0xC7 },	/* cyrillic capital letter ze */
	{ 0x0418, 0xC8 },	/* cyrillic capital letter i */
	{ 0x0419, 0xC9 },	/* cyrillic capital letter short i */
	{ 0x041A, 0xCA },	/* cyrillic capital letter ka */
	{ 0x041B, 0xCB },	/* cyrillic capital letter el */
	{ 0x041C, 0xCC },	/* cyrillic capital letter em */
	{ 0x041D, 0xCD },	/* cyrillic capital letter en */
	{ 0x041E, 0xCE },	/* cyrillic capital letter o */
	{ 0x041F, 0xCF },	/* cyrillic capital letter pe */
	{ 0x0420, 0xD0 },	/* cyrillic capital letter er */
	{ 0x0421, 0xD1 },	/* cyrillic capital letter es */
	{ 0x0422, 0xD2 },	/* cyrillic capital letter te */
	{ 0x0423, 0xD3 },	/* cyrillic capital letter u */
	{ 0x0424, 0xD4 },	/* cyrillic capital letter ef */
	{ 0x0425, 0xD5 },	/* cyrillic capital letter ha */
	{ 0x0426, 0xD6 },	/* cyrillic capital letter tse */
	{ 0x0427, 0xD7 },	/* cyrillic capital letter che */
	{ 0x0428, 0xD8 },	/* cyrillic capital letter sha */
	{ 0x0429, 0xD9 },	/* cyrillic capital letter shcha */
	{ 0x042A, 0xDA },	/* cyrillic capital letter hard sign */
	{ 0x042B, 0xDB },	/* cyrillic capital letter yeru */
	{ 0x042C, 0xDC },	/* cyrillic capital letter soft sign */
	{ 0x042D, 0xDD },	/* cyrillic capital letter e */
	{ 0x042E, 0xDE },	/* cyrillic capital letter yu */
	{ 0x042F, 0xDF },	/* cyrillic capital letter ya */
	{ 0x0430, 0xE0 },	/* cyrillic small letter a */
	{ 0x0431, 0xE1 },	/* cyrillic small letter be */
	{ 0x0432, 0xE2 },	/* cyrillic small letter ve */
	{ 0x0433, 0xE3 },	/* cyrillic small letter ghe */
	{ 0x0434, 0xE4 },	/* cyrillic small letter de */
	{ 0x0435, 0xE5 },	/* cyrillic small letter ie */
	{ 0x0436, 0xE6 },	/* cyrillic small letter zhe */
	{ 0x0437, 0xE7 },	/* cyrillic small letter ze */
	{ 0x0438, 0xE8 },	/* cyrillic small letter i */
	{ 0x0439, 0xE9 },	/* cyrillic small letter short i */
	{ 0x043A, 0xEA },	/* cyrillic small letter ka */
	{ 0x043B, 0xEB },	/* cyrillic small letter el */
	{ 0x043C, 0xEC },	/* cyrillic small letter em */
	{ 0x043D, 0xED },	/* cyrillic small letter en */
	{ 0x043E, 0xEE },	/* cyrillic small letter o */
	{ 0x043F, 0xEF },	/* cyrillic small letter pe */
	{ 0x0440, 0xF0 },	/* cyrillic small letter er */
	{ 0x0441, 0xF1 },	/* cyrillic small letter es */
	{ 0x0442, 0xF2 },	/* cyrillic small letter te */
	{ 0x0443, 0xF3 },	/* cyrillic small letter u */
	{ 0x0444, 0xF4 },	/* cyrillic small letter ef */
	{ 0x0445, 0xF5 },	/* cyrillic small letter ha */
	{ 0x0446, 0xF6 },	/* cyrillic small letter tse */
	{ 0x0447, 0xF7 },	/* cyrillic small letter che */
	{ 0x0448, 0xF8 },	/* cyrillic small letter sha */
	{ 0x0449, 0xF9 },	/* cyrillic small letter shcha */
	{ 0x044A, 0xFA },	/* cyrillic small letter hard sign */
	{ 0x044B, 0xFB },	/* cyrillic small letter yeru */
	{ 0x044C, 0xFC },	/* cyrillic small letter soft sign */
	{ 0x044D, 0xFD },	/* cyrillic small letter e */
	{ 0x044E, 0xFE },	/* cyrillic small letter yu */
	{ 0x044F, 0xFF },	/* cyrillic small letter ya */
	{ 0x0451, 0xB8 },	/* cyrillic small letter io */
	{ 0x0452, 0x90 },	/* cyrillic small letter dje */
	{ 0x0453, 0x83 },	/* cyrillic small letter gje */
	{ 0x0454, 0xBA },	/* cyrillic small letter ukrainian ie */
	{ 0x0455, 0xBE },	/* cyrillic small letter dze */
	{ 0x0456, 0xB3 },	/* cyrillic small letter byelorussian-ukrainian i */
	{ 0x0457, 0xBF },	/* cyrillic small letter yi */
	{ 0x0458, 0xBC },	/* cyrillic small letter je */
	{ 0x0459, 0x9A },	/* cyrillic small letter lje */
	{ 0x045A, 0x9C },	/* cyrillic small letter nje */
	{ 0x045B, 0x9E },	/* cyrillic small letter tshe */
	{ 0x045C, 0x9D },	/* cyrillic small letter kje */
	{ 0x045E, 0xA2 },	/* cyrillic small letter short u */
	{ 0x045F, 0x9F },	/* cyrillic small letter dzhe */
	{ 0x0490, 0xA5 },	/* cyrillic capital letter ghe with upturn */
	{ 0x0491, 0xB4 },	/* cyrillic small letter ghe with upturn */
	{ 0x2013, 0x96 },	/* en dash */
	{ 0x2014, 0x97 },	/* em dash */
	{ 0x2018, 0x91 },	/* left single quotation mark */
	{ 0x2019, 0x92 },	/* right single quotation mark */
	{ 0x201A, 0x82 },	/* single low-9 quotation mark */
	{ 0x201C, 0x93 },	/* left double quotation mark */
	{ 0x201D, 0x94 },	/* right double quotation mark */
	{ 0x201E, 0x84 },	/* double low-9 quotation mark */
	{ 0x2020, 0x86 },	/* dagger */
	{ 0x2021, 0x87 },	/* double dagger */
	{ 0x2022, 0x95 },	/* bullet */
	{ 0x2026, 0x85 },	/* horizontal ellipsis */
	{ 0x2030, 0x89 },	/* per mille sign */
	{ 0x2039, 0x8B },	/* single left-pointing angle quotation mark */
	{ 0x203A, 0x9B },	/* single right-pointing angle quotation mark */
	{ 0x20AC, 0x88 },	/* euro sign */
	{ 0x2116, 0xB9 },	/* numero sign */
	{ 0x2122, 0x99 },	/* trade mark sign */
};
/* {{{ end of mappings *from* Unicode for Windows-1251 */

/* {{{ Mappings *from* Unicode for KOI8-R */
static const uni_to_enc unimap_koi8r[] = {
	{ 0x00A0, 0x9A },	/* no-break space */
	{ 0x00A9, 0xBF },	/* copyright sign */
	{ 0x00B0, 0x9C },	/* degree sign */
	{ 0x00B2, 0x9D },	/* superscript two */
	{ 0x00B7, 0x9E },	/* middle dot */
	{ 0x00F7, 0x9F },	/* division sign */
	{ 0x0401, 0xB3 },	/* cyrillic capital letter io */
	{ 0x0410, 0xE1 },	/* cyrillic capital letter a */
	{ 0x0411, 0xE2 },	/* cyrillic capital letter be */
	{ 0x0412, 0xF7 },	/* cyrillic capital letter ve */
	{ 0x0413, 0xE7 },	/* cyrillic capital letter ghe */
	{ 0x0414, 0xE4 },	/* cyrillic capital letter de */
	{ 0x0415, 0xE5 },	/* cyrillic capital letter ie */
	{ 0x0416, 0xF6 },	/* cyrillic capital letter zhe */
	{ 0x0417, 0xFA },	/* cyrillic capital letter ze */
	{ 0x0418, 0xE9 },	/* cyrillic capital letter i */
	{ 0x0419, 0xEA },	/* cyrillic capital letter short i */
	{ 0x041A, 0xEB },	/* cyrillic capital letter ka */
	{ 0x041B, 0xEC },	/* cyrillic capital letter el */
	{ 0x041C, 0xED },	/* cyrillic capital letter em */
	{ 0x041D, 0xEE },	/* cyrillic capital letter en */
	{ 0x041E, 0xEF },	/* cyrillic capital letter o */
	{ 0x041F, 0xF0 },	/* cyrillic capital letter pe */
	{ 0x0420, 0xF2 },	/* cyrillic capital letter er */
	{ 0x0421, 0xF3 },	/* cyrillic capital letter es */
	{ 0x0422, 0xF4 },	/* cyrillic capital letter te */
	{ 0x0423, 0xF5 },	/* cyrillic capital letter u */
	{ 0x0424, 0xE6 },	/* cyrillic capital letter ef */
	{ 0x0425, 0xE8 },	/* cyrillic capital letter ha */
	{ 0x0426, 0xE3 },	/* cyrillic capital letter tse */
	{ 0x0427, 0xFE },	/* cyrillic capital letter che */
	{ 0x0428, 0xFB },	/* cyrillic capital letter sha */
	{ 0x0429, 0xFD },	/* cyrillic capital letter shcha */
	{ 0x042A, 0xFF },	/* cyrillic capital letter hard sign */
	{ 0x042B, 0xF9 },	/* cyrillic capital letter yeru */
	{ 0x042C, 0xF8 },	/* cyrillic capital letter soft sign */
	{ 0x042D, 0xFC },	/* cyrillic capital letter e */
	{ 0x042E, 0xE0 },	/* cyrillic capital letter yu */
	{ 0x042F, 0xF1 },	/* cyrillic capital letter ya */
	{ 0x0430, 0xC1 },	/* cyrillic small letter a */
	{ 0x0431, 0xC2 },	/* cyrillic small letter be */
	{ 0x0432, 0xD7 },	/* cyrillic small letter ve */
	{ 0x0433, 0xC7 },	/* cyrillic small letter ghe */
	{ 0x0434, 0xC4 },	/* cyrillic small letter de */
	{ 0x0435, 0xC5 },	/* cyrillic small letter ie */
	{ 0x0436, 0xD6 },	/* cyrillic small letter zhe */
	{ 0x0437, 0xDA },	/* cyrillic small letter ze */
	{ 0x0438, 0xC9 },	/* cyrillic small letter i */
	{ 0x0439, 0xCA },	/* cyrillic small letter short i */
	{ 0x043A, 0xCB },	/* cyrillic small letter ka */
	{ 0x043B, 0xCC },	/* cyrillic small letter el */
	{ 0x043C, 0xCD },	/* cyrillic small letter em */
	{ 0x043D, 0xCE },	/* cyrillic small letter en */
	{ 0x043E, 0xCF },	/* cyrillic small letter o */
	{ 0x043F, 0xD0 },	/* cyrillic small letter pe */
	{ 0x0440, 0xD2 },	/* cyrillic small letter er */
	{ 0x0441, 0xD3 },	/* cyrillic small letter es */
	{ 0x0442, 0xD4 },	/* cyrillic small letter te */
	{ 0x0443, 0xD5 },	/* cyrillic small letter u */
	{ 0x0444, 0xC6 },	/* cyrillic small letter ef */
	{ 0x0445, 0xC8 },	/* cyrillic small letter ha */
	{ 0x0446, 0xC3 },	/* cyrillic small letter tse */
	{ 0x0447, 0xDE },	/* cyrillic small letter che */
	{ 0x0448, 0xDB },	/* cyrillic small letter sha */
	{ 0x0449, 0xDD },	/* cyrillic small letter shcha */
	{ 0x044A, 0xDF },	/* cyrillic small letter hard sign */
	{ 0x044B, 0xD9 },	/* cyrillic small letter yeru */
	{ 0x044C, 0xD8 },	/* cyrillic small letter soft sign */
	{ 0x044D, 0xDC },	/* cyrillic small letter e */
	{ 0x044E, 0xC0 },	/* cyrillic small letter yu */
	{ 0x044F, 0xD1 },	/* cyrillic small letter ya */
	{ 0x0451, 0xA3 },	/* cyrillic small letter io */
	{ 0x2219, 0x95 },	/* bullet operator */
	{ 0x221A, 0x96 },	/* square root */
	{ 0x2248, 0x97 },	/* almost equal to */
	{ 0x2264, 0x98 },	/* less-than or equal to */
	{ 0x2265, 0x99 },	/* greater-than or equal to */
	{ 0x2320, 0x93 },	/* top half integral */
	{ 0x2321, 0x9B },	/* bottom half integral */
	{ 0x2500, 0x80 },	/* box drawings light horizontal */
	{ 0x2502, 0x81 },	/* box drawings light vertical */
	{ 0x250C, 0x82 },	/* box drawings light down and right */
	{ 0x2510, 0x83 },	/* box drawings light down and left */
	{ 0x2514, 0x84 },	/* box drawings light up and right */
	{ 0x2518, 0x85 },	/* box drawings light up and left */
	{ 0x251C, 0x86 },	/* box drawings light vertical and right */
	{ 0x2524, 0x87 },	/* box drawings light vertical and left */
	{ 0x252C, 0x88 },	/* box drawings light down and horizontal */
	{ 0x2534, 0x89 },	/* box drawings light up and horizontal */
	{ 0x253C, 0x8A },	/* box drawings light vertical and horizontal */
	{ 0x2550, 0xA0 },	/* box drawings double horizontal */
	{ 0x2551, 0xA1 },	/* box drawings double vertical */
	{ 0x2552, 0xA2 },	/* box drawings down single and right double */
	{ 0x2553, 0xA4 },	/* box drawings down double and right single */
	{ 0x2554, 0xA5 },	/* box drawings double down and right */
	{ 0x2555, 0xA6 },	/* box drawings down single and left double */
	{ 0x2556, 0xA7 },	/* box drawings down double and left single */
	{ 0x2557, 0xA8 },	/* box drawings double down and left */
	{ 0x2558, 0xA9 },	/* box drawings up single and right double */
	{ 0x2559, 0xAA },	/* box drawings up double and right single */
	{ 0x255A, 0xAB },	/* box drawings double up and right */
	{ 0x255B, 0xAC },	/* box drawings up single and left double */
	{ 0x255C, 0xAD },	/* box drawings up double and left single */
	{ 0x255D, 0xAE },	/* box drawings double up and left */
	{ 0x255E, 0xAF },	/* box drawings vertical single and right double */
	{ 0x255F, 0xB0 },	/* box drawings vertical double and right single */
	{ 0x2560, 0xB1 },	/* box drawings double vertical and right */
	{ 0x2561, 0xB2 },	/* box drawings vertical single and left double */
	{ 0x2562, 0xB4 },	/* box drawings vertical double and left single */
	{ 0x2563, 0xB5 },	/* box drawings double vertical and left */
	{ 0x2564, 0xB6 },	/* box drawings down single and horizontal double */
	{ 0x2565, 0xB7 },	/* box drawings down double and horizontal single */
	{ 0x2566, 0xB8 },	/* box drawings double down and horizontal */
	{ 0x2567, 0xB9 },	/* box drawings up single and horizontal double */
	{ 0x2568, 0xBA },	/* box drawings up double and horizontal single */
	{ 0x2569, 0xBB },	/* box drawings double up and horizontal */
	{ 0x256A, 0xBC },	/* box drawings vertical single and horizontal double */
	{ 0x256B, 0xBD },	/* box drawings vertical double and horizontal single */
	{ 0x256C, 0xBE },	/* box drawings double vertical and horizontal */
	{ 0x2580, 0x8B },	/* upper half block */
	{ 0x2584, 0x8C },	/* lower half block */
	{ 0x2588, 0x8D },	/* full block */
	{ 0x258C, 0x8E },	/* left half block */
	{ 0x2590, 0x8F },	/* right half block */
	{ 0x2591, 0x90 },	/* light shade */
	{ 0x2592, 0x91 },	/* medium shade */
	{ 0x2593, 0x92 },	/* dark shade */
	{ 0x25A0, 0x94 },	/* black square */
};
/* {{{ end of mappings *from* Unicode for KOI8-R */

/* {{{ Mappings *from* Unicode for CP-866 */
static const uni_to_enc unimap_cp866[] = {
	{ 0x00A0, 0xFF },	/* no-break space */
	{ 0x00A4, 0xFD },	/* currency sign */
	{ 0x00B0, 0xF8 },	/* degree sign */
	{ 0x00B7, 0xFA },	/* middle dot */
	{ 0x0401, 0xF0 },	/* cyrillic capital letter io */
	{ 0x0404, 0xF2 },	/* cyrillic capital letter ukrainian ie */
	{ 0x0407, 0xF4 },	/* cyrillic capital letter yi */
	{ 0x040E, 0xF6 },	/* cyrillic capital letter short u */
	{ 0x0410, 0x80 },	/* cyrillic capital letter a */
	{ 0x0411, 0x81 },	/* cyrillic capital letter be */
	{ 0x0412, 0x82 },	/* cyrillic capital letter ve */
	{ 0x0413, 0x83 },	/* cyrillic capital letter ghe */
	{ 0x0414, 0x84 },	/* cyrillic capital letter de */
	{ 0x0415, 0x85 },	/* cyrillic capital letter ie */
	{ 0x0416, 0x86 },	/* cyrillic capital letter zhe */
	{ 0x0417, 0x87 },	/* cyrillic capital letter ze */
	{ 0x0418, 0x88 },	/* cyrillic capital letter i */
	{ 0x0419, 0x89 },	/* cyrillic capital letter short i */
	{ 0x041A, 0x8A },	/* cyrillic capital letter ka */
	{ 0x041B, 0x8B },	/* cyrillic capital letter el */
	{ 0x041C, 0x8C },	/* cyrillic capital letter em */
	{ 0x041D, 0x8D },	/* cyrillic capital letter en */
	{ 0x041E, 0x8E },	/* cyrillic capital letter o */
	{ 0x041F, 0x8F },	/* cyrillic capital letter pe */
	{ 0x0420, 0x90 },	/* cyrillic capital letter er */
	{ 0x0421, 0x91 },	/* cyrillic capital letter es */
	{ 0x0422, 0x92 },	/* cyrillic capital letter te */
	{ 0x0423, 0x93 },	/* cyrillic capital letter u */
	{ 0x0424, 0x94 },	/* cyrillic capital letter ef */
	{ 0x0425, 0x95 },	/* cyrillic capital letter ha */
	{ 0x0426, 0x96 },	/* cyrillic capital letter tse */
	{ 0x0427, 0x97 },	/* cyrillic capital letter che */
	{ 0x0428, 0x98 },	/* cyrillic capital letter sha */
	{ 0x0429, 0x99 },	/* cyrillic capital letter shcha */
	{ 0x042A, 0x9A },	/* cyrillic capital letter hard sign */
	{ 0x042B, 0x9B },	/* cyrillic capital letter yeru */
	{ 0x042C, 0x9C },	/* cyrillic capital letter soft sign */
	{ 0x042D, 0x9D },	/* cyrillic capital letter e */
	{ 0x042E, 0x9E },	/* cyrillic capital letter yu */
	{ 0x042F, 0x9F },	/* cyrillic capital letter ya */
	{ 0x0430, 0xA0 },	/* cyrillic small letter a */
	{ 0x0431, 0xA1 },	/* cyrillic small letter be */
	{ 0x0432, 0xA2 },	/* cyrillic small letter ve */
	{ 0x0433, 0xA3 },	/* cyrillic small letter ghe */
	{ 0x0434, 0xA4 },	/* cyrillic small letter de */
	{ 0x0435, 0xA5 },	/* cyrillic small letter ie */
	{ 0x0436, 0xA6 },	/* cyrillic small letter zhe */
	{ 0x0437, 0xA7 },	/* cyrillic small letter ze */
	{ 0x0438, 0xA8 },	/* cyrillic small letter i */
	{ 0x0439, 0xA9 },	/* cyrillic small letter short i */
	{ 0x043A, 0xAA },	/* cyrillic small letter ka */
	{ 0x043B, 0xAB },	/* cyrillic small letter el */
	{ 0x043C, 0xAC },	/* cyrillic small letter em */
	{ 0x043D, 0xAD },	/* cyrillic small letter en */
	{ 0x043E, 0xAE },	/* cyrillic small letter o */
	{ 0x043F, 0xAF },	/* cyrillic small letter pe */
	{ 0x0440, 0xE0 },	/* cyrillic small letter er */
	{ 0x0441, 0xE1 },	/* cyrillic small letter es */
	{ 0x0442, 0xE2 },	/* cyrillic small letter te */
	{ 0x0443, 0xE3 },	/* cyrillic small letter u */
	{ 0x0444, 0xE4 },	/* cyrillic small letter ef */
	{ 0x0445, 0xE5 },	/* cyrillic small letter ha */
	{ 0x0446, 0xE6 },	/* cyrillic small letter tse */
	{ 0x0447, 0xE7 },	/* cyrillic small letter che */
	{ 0x0448, 0xE8 },	/* cyrillic small letter sha */
	{ 0x0449, 0xE9 },	/* cyrillic small letter shcha */
	{ 0x044A, 0xEA },	/* cyrillic small letter hard sign */
	{ 0x044B, 0xEB },	/* cyrillic small letter yeru */
	{ 0x044C, 0xEC },	/* cyrillic small letter soft sign */
	{ 0x044D, 0xED },	/* cyrillic small letter e */
	{ 0x044E, 0xEE },	/* cyrillic small letter yu */
	{ 0x044F, 0xEF },	/* cyrillic small letter ya */
	{ 0x0451, 0xF1 },	/* cyrillic small letter io */
	{ 0x0454, 0xF3 },	/* cyrillic small letter ukrainian ie */
	{ 0x0457, 0xF5 },	/* cyrillic small letter yi */
	{ 0x045E, 0xF7 },	/* cyrillic small letter short u */
	{ 0x2116, 0xFC },	/* numero sign */
	{ 0x2219, 0xF9 },	/* bullet operator */
	{ 0x221A, 0xFB },	/* square root */
	{ 0x2500, 0xC4 },	/* box drawings light horizontal */
	{ 0x2502, 0xB3 },	/* box drawings light vertical */
	{ 0x250C, 0xDA },	/* box drawings light down and right */
	{ 0x2510, 0xBF },	/* box drawings light down and left */
	{ 0x2514, 0xC0 },	/* box drawings light up and right */
	{ 0x2518, 0xD9 },	/* box drawings light up and left */
	{ 0x251C, 0xC3 },	/* box drawings light vertical and right */
	{ 0x2524, 0xB4 },	/* box drawings light vertical and left */
	{ 0x252C, 0xC2 },	/* box drawings light down and horizontal */
	{ 0x2534, 0xC1 },	/* box drawings light up and horizontal */
	{ 0x253C, 0xC5 },	/* box drawings light vertical and horizontal */
	{ 0x2550, 0xCD },	/* box drawings double horizontal */
	{ 0x2551, 0xBA },	/* box drawings double vertical */
	{ 0x2552, 0xD5 },	/* box drawings down single and right double */
	{ 0x2553, 0xD6 },	/* box drawings down double and right single */
	{ 0x2554, 0xC9 },	/* box drawings double down and right */
	{ 0x2555, 0xB8 },	/* box drawings down single and left double */
	{ 0x2556, 0xB7 },	/* box drawings down double and left single */
	{ 0x2557, 0xBB },	/* box drawings double down and left */
	{ 0x2558, 0xD4 },	/* box drawings up single and right double */
	{ 0x2559, 0xD3 },	/* box drawings up double and right single */
	{ 0x255A, 0xC8 },	/* box drawings double up and right */
	{ 0x255B, 0xBE },	/* box drawings up single and left double */
	{ 0x255C, 0xBD },	/* box drawings up double and left single */
	{ 0x255D, 0xBC },	/* box drawings double up and left */
	{ 0x255E, 0xC6 },	/* box drawings vertical single and right double */
	{ 0x255F, 0xC7 },	/* box drawings vertical double and right single */
	{ 0x2560, 0xCC },	/* box drawings double vertical and right */
	{ 0x2561, 0xB5 },	/* box drawings vertical single and left double */
	{ 0x2562, 0xB6 },	/* box drawings vertical double and left single */
	{ 0x2563, 0xB9 },	/* box drawings double vertical and left */
	{ 0x2564, 0xD1 },	/* box drawings down single and horizontal double */
	{ 0x2565, 0xD2 },	/* box drawings down double and horizontal single */
	{ 0x2566, 0xCB },	/* box drawings double down and horizontal */
	{ 0x2567, 0xCF },	/* box drawings up single and horizontal double */
	{ 0x2568, 0xD0 },	/* box drawings up double and horizontal single */
	{ 0x2569, 0xCA },	/* box drawings double up and horizontal */
	{ 0x256A, 0xD8 },	/* box drawings vertical single and horizontal double */
	{ 0x256B, 0xD7 },	/* box drawings vertical double and horizontal single */
	{ 0x256C, 0xCE },	/* box drawings double vertical and horizontal */
	{ 0x2580, 0xDF },	/* upper half block */
	{ 0x2584, 0xDC },	/* lower half block */
	{ 0x2588, 0xDB },	/* full block */
	{ 0x258C, 0xDD },	/* left half block */
	{ 0x2590, 0xDE },	/* right half block */
	{ 0x2591, 0xB0 },	/* light shade */
	{ 0x2592, 0xB1 },	/* medium shade */
	{ 0x2593, 0xB2 },	/* dark shade */
	{ 0x25A0, 0xFE },	/* black square */
};
/* {{{ end of mappings *from* Unicode for CP-866 */

/* {{{ Mappings *from* Unicode for MacRoman */
static const uni_to_enc unimap_macroman[] = {
	{ 0x00A0, 0xCA },	/* no-break space */
	{ 0x00A1, 0xC1 },	/* inverted exclamation mark */
	{ 0x00A2, 0xA2 },	/* cent sign */
	{ 0x00A3, 0xA3 },	/* pound sign */
	{ 0x00A5, 0xB4 },	/* yen sign */
	{ 0x00A7, 0xA4 },	/* section sign */
	{ 0x00A8, 0xAC },	/* diaeresis */
	{ 0x00A9, 0xA9 },	/* copyright sign */
	{ 0x00AA, 0xBB },	/* feminine ordinal indicator */
	{ 0x00AB, 0xC7 },	/* left-pointing double angle quotation mark */
	{ 0x00AC, 0xC2 },	/* not sign */
	{ 0x00AE, 0xA8 },	/* registered sign */
	{ 0x00AF, 0xF8 },	/* macron */
	{ 0x00B0, 0xA1 },	/* degree sign */
	{ 0x00B1, 0xB1 },	/* plus-minus sign */
	{ 0x00B4, 0xAB },	/* acute accent */
	{ 0x00B5, 0xB5 },	/* micro sign */
	{ 0x00B6, 0xA6 },	/* pilcrow sign */
	{ 0x00B7, 0xE1 },	/* middle dot */
	{ 0x00B8, 0xFC },	/* cedilla */
	{ 0x00BA, 0xBC },	/* masculine ordinal indicator */
	{ 0x00BB, 0xC8 },	/* right-pointing double angle quotation mark */
	{ 0x00BF, 0xC0 },	/* inverted question mark */
	{ 0x00C0, 0xCB },	/* latin capital letter a with grave */
	{ 0x00C1, 0xE7 },	/* latin capital letter a with acute */
	{ 0x00C2, 0xE5 },	/* latin capital letter a with circumflex */
	{ 0x00C3, 0xCC },	/* latin capital letter a with tilde */
	{ 0x00C4, 0x80 },	/* latin capital letter a with diaeresis */
	{ 0x00C5, 0x81 },	/* latin capital letter a with ring above */
	{ 0x00C6, 0xAE },	/* latin capital letter ae */
	{ 0x00C7, 0x82 },	/* latin capital letter c with cedilla */
	{ 0x00C8, 0xE9 },	/* latin capital letter e with grave */
	{ 0x00C9, 0x83 },	/* latin capital letter e with acute */
	{ 0x00CA, 0xE6 },	/* latin capital letter e with circumflex */
	{ 0x00CB, 0xE8 },	/* latin capital letter e with diaeresis */
	{ 0x00CC, 0xED },	/* latin capital letter i with grave */
	{ 0x00CD, 0xEA },	/* latin capital letter i with acute */
	{ 0x00CE, 0xEB },	/* latin capital letter i with circumflex */
	{ 0x00CF, 0xEC },	/* latin capital letter i with diaeresis */
	{ 0x00D1, 0x84 },	/* latin capital letter n with tilde */
	{ 0x00D2, 0xF1 },	/* latin capital letter o with grave */
	{ 0x00D3, 0xEE },	/* latin capital letter o with acute */
	{ 0x00D4, 0xEF },	/* latin capital letter o with circumflex */
	{ 0x00D5, 0xCD },	/* latin capital letter o with tilde */
	{ 0x00D6, 0x85 },	/* latin capital letter o with diaeresis */
	{ 0x00D8, 0xAF },	/* latin capital letter o with stroke */
	{ 0x00D9, 0xF4 },	/* latin capital letter u with grave */
	{ 0x00DA, 0xF2 },	/* latin capital letter u with acute */
	{ 0x00DB, 0xF3 },	/* latin capital letter u with circumflex */
	{ 0x00DC, 0x86 },	/* latin capital letter u with diaeresis */
	{ 0x00DF, 0xA7 },	/* latin small letter sharp s */
	{ 0x00E0, 0x88 },	/* latin small letter a with grave */
	{ 0x00E1, 0x87 },	/* latin small letter a with acute */
	{ 0x00E2, 0x89 },	/* latin small letter a with circumflex */
	{ 0x00E3, 0x8B },	/* latin small letter a with tilde */
	{ 0x00E4, 0x8A },	/* latin small letter a with diaeresis */
	{ 0x00E5, 0x8C },	/* latin small letter a with ring above */
	{ 0x00E6, 0xBE },	/* latin small letter ae */
	{ 0x00E7, 0x8D },	/* latin small letter c with cedilla */
	{ 0x00E8, 0x8F },	/* latin small letter e with grave */
	{ 0x00E9, 0x8E },	/* latin small letter e with acute */
	{ 0x00EA, 0x90 },	/* latin small letter e with circumflex */
	{ 0x00EB, 0x91 },	/* latin small letter e with diaeresis */
	{ 0x00EC, 0x93 },	/* latin small letter i with grave */
	{ 0x00ED, 0x92 },	/* latin small letter i with acute */
	{ 0x00EE, 0x94 },	/* latin small letter i with circumflex */
	{ 0x00EF, 0x95 },	/* latin small letter i with diaeresis */
	{ 0x00F1, 0x96 },	/* latin small letter n with tilde */
	{ 0x00F2, 0x98 },	/* latin small letter o with grave */
	{ 0x00F3, 0x97 },	/* latin small letter o with acute */
	{ 0x00F4, 0x99 },	/* latin small letter o with circumflex */
	{ 0x00F5, 0x9B },	/* latin small letter o with tilde */
	{ 0x00F6, 0x9A },	/* latin small letter o with diaeresis */
	{ 0x00F7, 0xD6 },	/* division sign */
	{ 0x00F8, 0xBF },	/* latin small letter o with stroke */
	{ 0x00F9, 0x9D },	/* latin small letter u with grave */
	{ 0x00FA, 0x9C },	/* latin small letter u with acute */
	{ 0x00FB, 0x9E },	/* latin small letter u with circumflex */
	{ 0x00FC, 0x9F },	/* latin small letter u with diaeresis */
	{ 0x00FF, 0xD8 },	/* latin small letter y with diaeresis */
	{ 0x0131, 0xF5 },	/* latin small letter dotless i */
	{ 0x0152, 0xCE },	/* latin capital ligature oe */
	{ 0x0153, 0xCF },	/* latin small ligature oe */
	{ 0x0178, 0xD9 },	/* latin capital letter y with diaeresis */
	{ 0x0192, 0xC4 },	/* latin small letter f with hook */
	{ 0x02C6, 0xF6 },	/* modifier letter circumflex accent */
	{ 0x02C7, 0xFF },	/* caron */
	{ 0x02D8, 0xF9 },	/* breve */
	{ 0x02D9, 0xFA },	/* dot above */
	{ 0x02DA, 0xFB },	/* ring above */
	{ 0x02DB, 0xFE },	/* ogonek */
	{ 0x02DC, 0xF7 },	/* small tilde */
	{ 0x02DD, 0xFD },	/* double acute accent */
	{ 0x03A9, 0xBD },	/* greek capital letter omega */
	{ 0x03C0, 0xB9 },	/* greek small letter pi */
	{ 0x2013, 0xD0 },	/* en dash */
	{ 0x2014, 0xD1 },	/* em dash */
	{ 0x2018, 0xD4 },	/* left single quotation mark */
	{ 0x2019, 0xD5 },	/* right single quotation mark */
	{ 0x201A, 0xE2 },	/* single low-9 quotation mark */
	{ 0x201C, 0xD2 },	/* left double quotation mark */
	{ 0x201D, 0xD3 },	/* right double quotation mark */
	{ 0x201E, 0xE3 },	/* double low-9 quotation mark */
	{ 0x2020, 0xA0 },	/* dagger */
	{ 0x2021, 0xE0 },	/* double dagger */
	{ 0x2022, 0xA5 },	/* bullet */
	{ 0x2026, 0xC9 },	/* horizontal ellipsis */
	{ 0x2030, 0xE4 },	/* per mille sign */
	{ 0x2039, 0xDC },	/* single left-pointing angle quotation mark */
	{ 0x203A, 0xDD },	/* single right-pointing angle quotation mark */
	{ 0x2044, 0xDA },	/* fraction slash */
	{ 0x20AC, 0xDB },	/* euro sign */
	{ 0x2122, 0xAA },	/* trade mark sign */
	{ 0x2202, 0xB6 },	/* partial differential */
	{ 0x2206, 0xC6 },	/* increment */
	{ 0x220F, 0xB8 },	/* n-ary product */
	{ 0x2211, 0xB7 },	/* n-ary summation */
	{ 0x221A, 0xC3 },	/* square root */
	{ 0x221E, 0xB0 },	/* infinity */
	{ 0x222B, 0xBA },	/* integral */
	{ 0x2248, 0xC5 },	/* almost equal to */
	{ 0x2260, 0xAD },	/* not equal to */
	{ 0x2264, 0xB2 },	/* less-than or equal to */
	{ 0x2265, 0xB3 },	/* greater-than or equal to */
	{ 0x25CA, 0xD7 },	/* lozenge */
	{ 0xF8FF, 0xF0 },	/* apple logo */
	{ 0xFB01, 0xDE },	/* latin small ligature fi */
	{ 0xFB02, 0xDF },	/* latin small ligature fl */
};
/* {{{ end of mappings *from* Unicode for MacRoman */

/* HTML 5 has many more named entities.
 * Some of them map to two unicode code points, not one.
 * We're going to use a three-stage table (with an extra one for the entities
 * with two code points). */

#define ENT_STAGE1_INDEX(k) (((k) & 0xFFF000) >> 12) /* > 1D, we have no mapping */
#define ENT_STAGE2_INDEX(k) (((k) & 0xFC0) >> 6)
#define ENT_STAGE3_INDEX(k) ((k) & 0x3F)
#define ENT_CODE_POINT_FROM_STAGES(i,j,k) (((i) << 12) | ((j) << 6) | (k))

/* The default entity may be NULL. Binary search is still possible while
   is senseless as there are just two rows (see also find_entity_for_char()). */
typedef union {
	struct {
		const char *default_entity;
		unsigned size; /* number of remaining entries in the table */
		unsigned short default_entity_len;
	} leading_entry;
	struct {
		const char *entity;
		unsigned second_cp; /* second code point */
		unsigned short entity_len;
	} normal_entry;
} entity_multicodepoint_row;

/* blocks of these should start at code points k where k % 0xFC0 == 0 */
typedef struct {
	char ambiguous; /* if 0 look into entity */
	union {
		struct {
			const char *entity; /* may be NULL */
			unsigned short entity_len;
		} ent;
		const entity_multicodepoint_row *multicodepoint_table;
	} data;
} entity_stage3_row;

/* Calculate k & 0x3F Use as offset */
typedef const entity_stage3_row *entity_stage2_row; /* 64 elements */

/* Calculate k & 0xFC0 >> 6. Use as offset */
typedef const entity_stage3_row *const *entity_stage1_row; /* 64 elements */

/* For stage 1, Calculate k & 0xFFF000 >> 3*4.
 * If larger than 1D, we have no mapping. Otherwise lookup that index */

typedef struct {
	const entity_stage1_row *ms_table;
	/* for tables with only basic entities, this member is to be accessed
	 * directly for better performance: */
	const entity_stage3_row *table;
} entity_table_opt;

/* Replaced "GT" > "gt" and "QUOT" > "quot" for consistency's sake. */

/* {{{ Start of HTML5 multi-stage table for codepoint -> entity */

/* {{{ Start of double code point tables for HTML5 */

static const entity_multicodepoint_row multi_cp_html5_0003C[] = {
	{ {"lt",                 	01,		 2} },
	{ {"nvlt",               	0x020D2,	 4} },
};
static const entity_multicodepoint_row multi_cp_html5_0003D[] = {
	{ {"equals",             	01,		 6} },
	{ {"bne",                	0x020E5,	 3} },
};
static const entity_multicodepoint_row multi_cp_html5_0003E[] = {
	{ {"gt",                 	01,		 2} },
	{ {"nvgt",               	0x020D2,	 4} },
};
static const entity_multicodepoint_row multi_cp_html5_00066[] = {
	{ {NULL,                 	01,		0} },
	{ {"fjlig",              	0x0006A,	 5} },
};
static const entity_multicodepoint_row multi_cp_html5_0205F[] = {
	{ {"MediumSpace",        	01,		11} },
	{ {"ThickSpace",         	0x0200A,	10} },
};
static const entity_multicodepoint_row multi_cp_html5_0219D[] = {
	{ {"rarrw",              	01,		 5} },
	{ {"nrarrw",             	0x00338,	 6} },
};
static const entity_multicodepoint_row multi_cp_html5_02202[] = {
	{ {"part",               	01,		 4} },
	{ {"npart",              	0x00338,	 5} },
};
static const entity_multicodepoint_row multi_cp_html5_02220[] = {
	{ {"angle",              	01,		 5} },
	{ {"nang",               	0x020D2,	 4} },
};
static const entity_multicodepoint_row multi_cp_html5_02229[] = {
	{ {"cap",                	01,		 3} },
	{ {"caps",               	0x0FE00,	 4} },
};
static const entity_multicodepoint_row multi_cp_html5_0222A[] = {
	{ {"cup",                	01,		 3} },
	{ {"cups",               	0x0FE00,	 4} },
};
static const entity_multicodepoint_row multi_cp_html5_0223C[] = {
	{ {"sim",                	01,		 3} },
	{ {"nvsim",              	0x020D2,	 5} },
};
static const entity_multicodepoint_row multi_cp_html5_0223D[] = {
	{ {"bsim",               	01,		 4} },
	{ {"race",               	0x00331,	 4} },
};
static const entity_multicodepoint_row multi_cp_html5_0223E[] = {
	{ {"ac",                 	01,		 2} },
	{ {"acE",                	0x00333,	 3} },
};
static const entity_multicodepoint_row multi_cp_html5_02242[] = {
	{ {"esim",               	01,		 4} },
	{ {"nesim",              	0x00338,	 5} },
};
static const entity_multicodepoint_row multi_cp_html5_0224B[] = {
	{ {"apid",               	01,		 4} },
	{ {"napid",              	0x00338,	 5} },
};
static const entity_multicodepoint_row multi_cp_html5_0224D[] = {
	{ {"CupCap",             	01,		 6} },
	{ {"nvap",               	0x020D2,	 4} },
};
static const entity_multicodepoint_row multi_cp_html5_0224E[] = {
	{ {"bump",               	01,		 4} },
	{ {"nbump",              	0x00338,	 5} },
};
static const entity_multicodepoint_row multi_cp_html5_0224F[] = {
	{ {"HumpEqual",          	01,		 9} },
	{ {"nbumpe",             	0x00338,	 6} },
};
static const entity_multicodepoint_row multi_cp_html5_02250[] = {
	{ {"esdot",              	01,		 5} },
	{ {"nedot",              	0x00338,	 5} },
};
static const entity_multicodepoint_row multi_cp_html5_02261[] = {
	{ {"Congruent",          	01,		 9} },
	{ {"bnequiv",            	0x020E5,	 7} },
};
static const entity_multicodepoint_row multi_cp_html5_02264[] = {
	{ {"leq",                	01,		 3} },
	{ {"nvle",               	0x020D2,	 4} },
};
static const entity_multicodepoint_row multi_cp_html5_02265[] = {
	{ {"ge",                 	01,		 2} },
	{ {"nvge",               	0x020D2,	 4} },
};
static const entity_multicodepoint_row multi_cp_html5_02266[] = {
	{ {"lE",                 	01,		 2} },
	{ {"nlE",                	0x00338,	 3} },
};
static const entity_multicodepoint_row multi_cp_html5_02267[] = {
	{ {"geqq",               	01,		 4} },
	{ {"NotGreaterFullEqual",	0x00338,	19} },
};
static const entity_multicodepoint_row multi_cp_html5_02268[] = {
	{ {"lneqq",              	01,		 5} },
	{ {"lvertneqq",          	0x0FE00,	 9} },
};
static const entity_multicodepoint_row multi_cp_html5_02269[] = {
	{ {"gneqq",              	01,		 5} },
	{ {"gvertneqq",          	0x0FE00,	 9} },
};
static const entity_multicodepoint_row multi_cp_html5_0226A[] = {
	{ {"ll",                 	02,		 2} },
	{ {"nLtv",               	0x00338,	 4} },
	{ {"nLt",                	0x020D2,	 3} },
};
static const entity_multicodepoint_row multi_cp_html5_0226B[] = {
	{ {"gg",                 	02,		 2} },
	{ {"NotGreaterGreater",  	0x00338,	17} },
	{ {"nGt",                	0x020D2,	 3} },
};
static const entity_multicodepoint_row multi_cp_html5_0227F[] = {
	{ {"SucceedsTilde",      	01,		13} },
	{ {"NotSucceedsTilde",   	0x00338,	16} },
};
static const entity_multicodepoint_row multi_cp_html5_02282[] = {
	{ {"sub",                	01,		 3} },
	{ {"vnsub",              	0x020D2,	 5} },
};
static const entity_multicodepoint_row multi_cp_html5_02283[] = {
	{ {"sup",                	01,		 3} },
	{ {"nsupset",            	0x020D2,	 7} },
};
static const entity_multicodepoint_row multi_cp_html5_0228A[] = {
	{ {"subsetneq",          	01,		 9} },
	{ {"vsubne",             	0x0FE00,	 6} },
};
static const entity_multicodepoint_row multi_cp_html5_0228B[] = {
	{ {"supsetneq",          	01,		 9} },
	{ {"vsupne",             	0x0FE00,	 6} },
};
static const entity_multicodepoint_row multi_cp_html5_0228F[] = {
	{ {"sqsub",              	01,		 5} },
	{ {"NotSquareSubset",    	0x00338,	15} },
};
static const entity_multicodepoint_row multi_cp_html5_02290[] = {
	{ {"sqsupset",           	01,		 8} },
	{ {"NotSquareSuperset",  	0x00338,	17} },
};
static const entity_multicodepoint_row multi_cp_html5_02293[] = {
	{ {"sqcap",              	01,		 5} },
	{ {"sqcaps",             	0x0FE00,	 6} },
};
static const entity_multicodepoint_row multi_cp_html5_02294[] = {
	{ {"sqcup",              	01,		 5} },
	{ {"sqcups",             	0x0FE00,	 6} },
};
static const entity_multicodepoint_row multi_cp_html5_022B4[] = {
	{ {"LeftTriangleEqual",  	01,		17} },
	{ {"nvltrie",            	0x020D2,	 7} },
};
static const entity_multicodepoint_row multi_cp_html5_022B5[] = {
	{ {"RightTriangleEqual", 	01,		18} },
	{ {"nvrtrie",            	0x020D2,	 7} },
};
static const entity_multicodepoint_row multi_cp_html5_022D8[] = {
	{ {"Ll",                 	01,		 2} },
	{ {"nLl",                	0x00338,	 3} },
};
static const entity_multicodepoint_row multi_cp_html5_022D9[] = {
	{ {"Gg",                 	01,		 2} },
	{ {"nGg",                	0x00338,	 3} },
};
static const entity_multicodepoint_row multi_cp_html5_022DA[] = {
	{ {"lesseqgtr",          	01,		 9} },
	{ {"lesg",               	0x0FE00,	 4} },
};
static const entity_multicodepoint_row multi_cp_html5_022DB[] = {
	{ {"gtreqless",          	01,		 9} },
	{ {"gesl",               	0x0FE00,	 4} },
};
static const entity_multicodepoint_row multi_cp_html5_022F5[] = {
	{ {"isindot",            	01,		 7} },
	{ {"notindot",           	0x00338,	 8} },
};
static const entity_multicodepoint_row multi_cp_html5_022F9[] = {
	{ {"isinE",              	01,		 5} },
	{ {"notinE",             	0x00338,	 6} },
};
static const entity_multicodepoint_row multi_cp_html5_02933[] = {
	{ {"rarrc",              	01,		 5} },
	{ {"nrarrc",             	0x00338,	 6} },
};
static const entity_multicodepoint_row multi_cp_html5_029CF[] = {
	{ {"LeftTriangleBar",    	01,		15} },
	{ {"NotLeftTriangleBar", 	0x00338,	18} },
};
static const entity_multicodepoint_row multi_cp_html5_029D0[] = {
	{ {"RightTriangleBar",   	01,		16} },
	{ {"NotRightTriangleBar",	0x00338,	19} },
};
static const entity_multicodepoint_row multi_cp_html5_02A6D[] = {
	{ {"congdot",            	01,		 7} },
	{ {"ncongdot",           	0x00338,	 8} },
};
static const entity_multicodepoint_row multi_cp_html5_02A70[] = {
	{ {"apE",                	01,		 3} },
	{ {"napE",               	0x00338,	 4} },
};
static const entity_multicodepoint_row multi_cp_html5_02A7D[] = {
	{ {"les",                	01,		 3} },
	{ {"nles",               	0x00338,	 4} },
};
static const entity_multicodepoint_row multi_cp_html5_02A7E[] = {
	{ {"ges",                	01,		 3} },
	{ {"nges",               	0x00338,	 4} },
};
static const entity_multicodepoint_row multi_cp_html5_02AA1[] = {
	{ {"LessLess",           	01,		 8} },
	{ {"NotNestedLessLess",  	0x00338,	17} },
};
static const entity_multicodepoint_row multi_cp_html5_02AA2[] = {
	{ {"GreaterGreater",     	01,		14} },
	{ {"NotNestedGreaterGreater",	0x00338,	23} },
};
static const entity_multicodepoint_row multi_cp_html5_02AAC[] = {
	{ {"smte",               	01,		 4} },
	{ {"smtes",              	0x0FE00,	 5} },
};
static const entity_multicodepoint_row multi_cp_html5_02AAD[] = {
	{ {"late",               	01,		 4} },
	{ {"lates",              	0x0FE00,	 5} },
};
static const entity_multicodepoint_row multi_cp_html5_02AAF[] = {
	{ {"preceq",             	01,		 6} },
	{ {"NotPrecedesEqual",   	0x00338,	16} },
};
static const entity_multicodepoint_row multi_cp_html5_02AB0[] = {
	{ {"SucceedsEqual",      	01,		13} },
	{ {"NotSucceedsEqual",   	0x00338,	16} },
};
static const entity_multicodepoint_row multi_cp_html5_02AC5[] = {
	{ {"subE",               	01,		 4} },
	{ {"nsubE",              	0x00338,	 5} },
};
static const entity_multicodepoint_row multi_cp_html5_02AC6[] = {
	{ {"supseteqq",          	01,		 9} },
	{ {"nsupseteqq",         	0x00338,	10} },
};
static const entity_multicodepoint_row multi_cp_html5_02ACB[] = {
	{ {"subsetneqq",         	01,		10} },
	{ {"vsubnE",             	0x0FE00,	 6} },
};
static const entity_multicodepoint_row multi_cp_html5_02ACC[] = {
	{ {"supnE",              	01,		 5} },
	{ {"varsupsetneqq",      	0x0FE00,	13} },
};
static const entity_multicodepoint_row multi_cp_html5_02AFD[] = {
	{ {"parsl",              	01,		 5} },
	{ {"nparsl",             	0x020E5,	 6} },
};

/* End of double code point tables }}} */

/* {{{ Stage 3 Tables for HTML5 */

static const entity_stage3_row empty_stage3_table[] = {
	/* 64 elements */
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};
static const entity_stage3_row stage3_table_html5_00000[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"Tab", 3} } }, {0, { {"NewLine", 7} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"excl", 4} } }, {0, { {"quot", 4} } }, {0, { {"num", 3} } },
	{0, { {"dollar", 6} } }, {0, { {"percnt", 6} } }, {0, { {"amp", 3} } }, {0, { {"apos", 4} } },
	{0, { {"lpar", 4} } }, {0, { {"rpar", 4} } }, {0, { {"ast", 3} } }, {0, { {"plus", 4} } },
	{0, { {"comma", 5} } }, {0, { {NULL, 0} } }, {0, { {"period", 6} } }, {0, { {"sol", 3} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"colon", 5} } }, {0, { {"semi", 4} } },
	{1, { {(void *)multi_cp_html5_0003C, 0} } }, {1, { {(void *)multi_cp_html5_0003D, 0} } }, {1, { {(void *)multi_cp_html5_0003E, 0} } }, {0, { {"quest", 5} } },
};

static const entity_stage3_row stage3_table_html5_00040[] = {
	{0, { {"commat", 6} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"lbrack", 6} } },
	{0, { {"bsol", 4} } }, {0, { {"rsqb", 4} } }, {0, { {"Hat", 3} } }, {0, { {"lowbar", 6} } },
	{0, { {"grave", 5} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {1, { {(void *)multi_cp_html5_00066, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"lbrace", 6} } },
	{0, { {"vert", 4} } }, {0, { {"rcub", 4} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html5_00080[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"nbsp", 4} } }, {0, { {"iexcl", 5} } }, {0, { {"cent", 4} } }, {0, { {"pound", 5} } },
	{0, { {"curren", 6} } }, {0, { {"yen", 3} } }, {0, { {"brvbar", 6} } }, {0, { {"sect", 4} } },
	{0, { {"DoubleDot", 9} } }, {0, { {"copy", 4} } }, {0, { {"ordf", 4} } }, {0, { {"laquo", 5} } },
	{0, { {"not", 3} } }, {0, { {"shy", 3} } }, {0, { {"reg", 3} } }, {0, { {"macr", 4} } },
	{0, { {"deg", 3} } }, {0, { {"plusmn", 6} } }, {0, { {"sup2", 4} } }, {0, { {"sup3", 4} } },
	{0, { {"DiacriticalAcute", 16} } }, {0, { {"micro", 5} } }, {0, { {"para", 4} } }, {0, { {"CenterDot", 9} } },
	{0, { {"Cedilla", 7} } }, {0, { {"sup1", 4} } }, {0, { {"ordm", 4} } }, {0, { {"raquo", 5} } },
	{0, { {"frac14", 6} } }, {0, { {"half", 4} } }, {0, { {"frac34", 6} } }, {0, { {"iquest", 6} } },
};

static const entity_stage3_row stage3_table_html5_000C0[] = {
	{0, { {"Agrave", 6} } }, {0, { {"Aacute", 6} } }, {0, { {"Acirc", 5} } }, {0, { {"Atilde", 6} } },
	{0, { {"Auml", 4} } }, {0, { {"Aring", 5} } }, {0, { {"AElig", 5} } }, {0, { {"Ccedil", 6} } },
	{0, { {"Egrave", 6} } }, {0, { {"Eacute", 6} } }, {0, { {"Ecirc", 5} } }, {0, { {"Euml", 4} } },
	{0, { {"Igrave", 6} } }, {0, { {"Iacute", 6} } }, {0, { {"Icirc", 5} } }, {0, { {"Iuml", 4} } },
	{0, { {"ETH", 3} } }, {0, { {"Ntilde", 6} } }, {0, { {"Ograve", 6} } }, {0, { {"Oacute", 6} } },
	{0, { {"Ocirc", 5} } }, {0, { {"Otilde", 6} } }, {0, { {"Ouml", 4} } }, {0, { {"times", 5} } },
	{0, { {"Oslash", 6} } }, {0, { {"Ugrave", 6} } }, {0, { {"Uacute", 6} } }, {0, { {"Ucirc", 5} } },
	{0, { {"Uuml", 4} } }, {0, { {"Yacute", 6} } }, {0, { {"THORN", 5} } }, {0, { {"szlig", 5} } },
	{0, { {"agrave", 6} } }, {0, { {"aacute", 6} } }, {0, { {"acirc", 5} } }, {0, { {"atilde", 6} } },
	{0, { {"auml", 4} } }, {0, { {"aring", 5} } }, {0, { {"aelig", 5} } }, {0, { {"ccedil", 6} } },
	{0, { {"egrave", 6} } }, {0, { {"eacute", 6} } }, {0, { {"ecirc", 5} } }, {0, { {"euml", 4} } },
	{0, { {"igrave", 6} } }, {0, { {"iacute", 6} } }, {0, { {"icirc", 5} } }, {0, { {"iuml", 4} } },
	{0, { {"eth", 3} } }, {0, { {"ntilde", 6} } }, {0, { {"ograve", 6} } }, {0, { {"oacute", 6} } },
	{0, { {"ocirc", 5} } }, {0, { {"otilde", 6} } }, {0, { {"ouml", 4} } }, {0, { {"divide", 6} } },
	{0, { {"oslash", 6} } }, {0, { {"ugrave", 6} } }, {0, { {"uacute", 6} } }, {0, { {"ucirc", 5} } },
	{0, { {"uuml", 4} } }, {0, { {"yacute", 6} } }, {0, { {"thorn", 5} } }, {0, { {"yuml", 4} } },
};

static const entity_stage3_row stage3_table_html5_00100[] = {
	{0, { {"Amacr", 5} } }, {0, { {"amacr", 5} } }, {0, { {"Abreve", 6} } }, {0, { {"abreve", 6} } },
	{0, { {"Aogon", 5} } }, {0, { {"aogon", 5} } }, {0, { {"Cacute", 6} } }, {0, { {"cacute", 6} } },
	{0, { {"Ccirc", 5} } }, {0, { {"ccirc", 5} } }, {0, { {"Cdot", 4} } }, {0, { {"cdot", 4} } },
	{0, { {"Ccaron", 6} } }, {0, { {"ccaron", 6} } }, {0, { {"Dcaron", 6} } }, {0, { {"dcaron", 6} } },
	{0, { {"Dstrok", 6} } }, {0, { {"dstrok", 6} } }, {0, { {"Emacr", 5} } }, {0, { {"emacr", 5} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"Edot", 4} } }, {0, { {"edot", 4} } },
	{0, { {"Eogon", 5} } }, {0, { {"eogon", 5} } }, {0, { {"Ecaron", 6} } }, {0, { {"ecaron", 6} } },
	{0, { {"Gcirc", 5} } }, {0, { {"gcirc", 5} } }, {0, { {"Gbreve", 6} } }, {0, { {"gbreve", 6} } },
	{0, { {"Gdot", 4} } }, {0, { {"gdot", 4} } }, {0, { {"Gcedil", 6} } }, {0, { {NULL, 0} } },
	{0, { {"Hcirc", 5} } }, {0, { {"hcirc", 5} } }, {0, { {"Hstrok", 6} } }, {0, { {"hstrok", 6} } },
	{0, { {"Itilde", 6} } }, {0, { {"itilde", 6} } }, {0, { {"Imacr", 5} } }, {0, { {"imacr", 5} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"Iogon", 5} } }, {0, { {"iogon", 5} } },
	{0, { {"Idot", 4} } }, {0, { {"inodot", 6} } }, {0, { {"IJlig", 5} } }, {0, { {"ijlig", 5} } },
	{0, { {"Jcirc", 5} } }, {0, { {"jcirc", 5} } }, {0, { {"Kcedil", 6} } }, {0, { {"kcedil", 6} } },
	{0, { {"kgreen", 6} } }, {0, { {"Lacute", 6} } }, {0, { {"lacute", 6} } }, {0, { {"Lcedil", 6} } },
	{0, { {"lcedil", 6} } }, {0, { {"Lcaron", 6} } }, {0, { {"lcaron", 6} } }, {0, { {"Lmidot", 6} } },
};

static const entity_stage3_row stage3_table_html5_00140[] = {
	{0, { {"lmidot", 6} } }, {0, { {"Lstrok", 6} } }, {0, { {"lstrok", 6} } }, {0, { {"Nacute", 6} } },
	{0, { {"nacute", 6} } }, {0, { {"Ncedil", 6} } }, {0, { {"ncedil", 6} } }, {0, { {"Ncaron", 6} } },
	{0, { {"ncaron", 6} } }, {0, { {"napos", 5} } }, {0, { {"ENG", 3} } }, {0, { {"eng", 3} } },
	{0, { {"Omacr", 5} } }, {0, { {"omacr", 5} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"Odblac", 6} } }, {0, { {"odblac", 6} } }, {0, { {"OElig", 5} } }, {0, { {"oelig", 5} } },
	{0, { {"Racute", 6} } }, {0, { {"racute", 6} } }, {0, { {"Rcedil", 6} } }, {0, { {"rcedil", 6} } },
	{0, { {"Rcaron", 6} } }, {0, { {"rcaron", 6} } }, {0, { {"Sacute", 6} } }, {0, { {"sacute", 6} } },
	{0, { {"Scirc", 5} } }, {0, { {"scirc", 5} } }, {0, { {"Scedil", 6} } }, {0, { {"scedil", 6} } },
	{0, { {"Scaron", 6} } }, {0, { {"scaron", 6} } }, {0, { {"Tcedil", 6} } }, {0, { {"tcedil", 6} } },
	{0, { {"Tcaron", 6} } }, {0, { {"tcaron", 6} } }, {0, { {"Tstrok", 6} } }, {0, { {"tstrok", 6} } },
	{0, { {"Utilde", 6} } }, {0, { {"utilde", 6} } }, {0, { {"Umacr", 5} } }, {0, { {"umacr", 5} } },
	{0, { {"Ubreve", 6} } }, {0, { {"ubreve", 6} } }, {0, { {"Uring", 5} } }, {0, { {"uring", 5} } },
	{0, { {"Udblac", 6} } }, {0, { {"udblac", 6} } }, {0, { {"Uogon", 5} } }, {0, { {"uogon", 5} } },
	{0, { {"Wcirc", 5} } }, {0, { {"wcirc", 5} } }, {0, { {"Ycirc", 5} } }, {0, { {"ycirc", 5} } },
	{0, { {"Yuml", 4} } }, {0, { {"Zacute", 6} } }, {0, { {"zacute", 6} } }, {0, { {"Zdot", 4} } },
	{0, { {"zdot", 4} } }, {0, { {"Zcaron", 6} } }, {0, { {"zcaron", 6} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html5_00180[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"fnof", 4} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"imped", 5} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html5_001C0[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"gacute", 6} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html5_00200[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"jmath", 5} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html5_002C0[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"circ", 4} } }, {0, { {"Hacek", 5} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"Breve", 5} } }, {0, { {"dot", 3} } }, {0, { {"ring", 4} } }, {0, { {"ogon", 4} } },
	{0, { {"DiacriticalTilde", 16} } }, {0, { {"DiacriticalDoubleAcute", 22} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html5_00300[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"DownBreve", 9} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html5_00380[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"Alpha", 5} } }, {0, { {"Beta", 4} } }, {0, { {"Gamma", 5} } },
	{0, { {"Delta", 5} } }, {0, { {"Epsilon", 7} } }, {0, { {"Zeta", 4} } }, {0, { {"Eta", 3} } },
	{0, { {"Theta", 5} } }, {0, { {"Iota", 4} } }, {0, { {"Kappa", 5} } }, {0, { {"Lambda", 6} } },
	{0, { {"Mu", 2} } }, {0, { {"Nu", 2} } }, {0, { {"Xi", 2} } }, {0, { {"Omicron", 7} } },
	{0, { {"Pi", 2} } }, {0, { {"Rho", 3} } }, {0, { {NULL, 0} } }, {0, { {"Sigma", 5} } },
	{0, { {"Tau", 3} } }, {0, { {"Upsilon", 7} } }, {0, { {"Phi", 3} } }, {0, { {"Chi", 3} } },
	{0, { {"Psi", 3} } }, {0, { {"Omega", 5} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"alpha", 5} } }, {0, { {"beta", 4} } }, {0, { {"gamma", 5} } },
	{0, { {"delta", 5} } }, {0, { {"epsi", 4} } }, {0, { {"zeta", 4} } }, {0, { {"eta", 3} } },
	{0, { {"theta", 5} } }, {0, { {"iota", 4} } }, {0, { {"kappa", 5} } }, {0, { {"lambda", 6} } },
	{0, { {"mu", 2} } }, {0, { {"nu", 2} } }, {0, { {"xi", 2} } }, {0, { {"omicron", 7} } },
};

static const entity_stage3_row stage3_table_html5_003C0[] = {
	{0, { {"pi", 2} } }, {0, { {"rho", 3} } }, {0, { {"sigmav", 6} } }, {0, { {"sigma", 5} } },
	{0, { {"tau", 3} } }, {0, { {"upsi", 4} } }, {0, { {"phi", 3} } }, {0, { {"chi", 3} } },
	{0, { {"psi", 3} } }, {0, { {"omega", 5} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"thetasym", 8} } }, {0, { {"upsih", 5} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"straightphi", 11} } }, {0, { {"piv", 3} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"Gammad", 6} } }, {0, { {"gammad", 6} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"varkappa", 8} } }, {0, { {"rhov", 4} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"straightepsilon", 15} } }, {0, { {"backepsilon", 11} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html5_00400[] = {
	{0, { {NULL, 0} } }, {0, { {"IOcy", 4} } }, {0, { {"DJcy", 4} } }, {0, { {"GJcy", 4} } },
	{0, { {"Jukcy", 5} } }, {0, { {"DScy", 4} } }, {0, { {"Iukcy", 5} } }, {0, { {"YIcy", 4} } },
	{0, { {"Jsercy", 6} } }, {0, { {"LJcy", 4} } }, {0, { {"NJcy", 4} } }, {0, { {"TSHcy", 5} } },
	{0, { {"KJcy", 4} } }, {0, { {NULL, 0} } }, {0, { {"Ubrcy", 5} } }, {0, { {"DZcy", 4} } },
	{0, { {"Acy", 3} } }, {0, { {"Bcy", 3} } }, {0, { {"Vcy", 3} } }, {0, { {"Gcy", 3} } },
	{0, { {"Dcy", 3} } }, {0, { {"IEcy", 4} } }, {0, { {"ZHcy", 4} } }, {0, { {"Zcy", 3} } },
	{0, { {"Icy", 3} } }, {0, { {"Jcy", 3} } }, {0, { {"Kcy", 3} } }, {0, { {"Lcy", 3} } },
	{0, { {"Mcy", 3} } }, {0, { {"Ncy", 3} } }, {0, { {"Ocy", 3} } }, {0, { {"Pcy", 3} } },
	{0, { {"Rcy", 3} } }, {0, { {"Scy", 3} } }, {0, { {"Tcy", 3} } }, {0, { {"Ucy", 3} } },
	{0, { {"Fcy", 3} } }, {0, { {"KHcy", 4} } }, {0, { {"TScy", 4} } }, {0, { {"CHcy", 4} } },
	{0, { {"SHcy", 4} } }, {0, { {"SHCHcy", 6} } }, {0, { {"HARDcy", 6} } }, {0, { {"Ycy", 3} } },
	{0, { {"SOFTcy", 6} } }, {0, { {"Ecy", 3} } }, {0, { {"YUcy", 4} } }, {0, { {"YAcy", 4} } },
	{0, { {"acy", 3} } }, {0, { {"bcy", 3} } }, {0, { {"vcy", 3} } }, {0, { {"gcy", 3} } },
	{0, { {"dcy", 3} } }, {0, { {"iecy", 4} } }, {0, { {"zhcy", 4} } }, {0, { {"zcy", 3} } },
	{0, { {"icy", 3} } }, {0, { {"jcy", 3} } }, {0, { {"kcy", 3} } }, {0, { {"lcy", 3} } },
	{0, { {"mcy", 3} } }, {0, { {"ncy", 3} } }, {0, { {"ocy", 3} } }, {0, { {"pcy", 3} } },
};

static const entity_stage3_row stage3_table_html5_00440[] = {
	{0, { {"rcy", 3} } }, {0, { {"scy", 3} } }, {0, { {"tcy", 3} } }, {0, { {"ucy", 3} } },
	{0, { {"fcy", 3} } }, {0, { {"khcy", 4} } }, {0, { {"tscy", 4} } }, {0, { {"chcy", 4} } },
	{0, { {"shcy", 4} } }, {0, { {"shchcy", 6} } }, {0, { {"hardcy", 6} } }, {0, { {"ycy", 3} } },
	{0, { {"softcy", 6} } }, {0, { {"ecy", 3} } }, {0, { {"yucy", 4} } }, {0, { {"yacy", 4} } },
	{0, { {NULL, 0} } }, {0, { {"iocy", 4} } }, {0, { {"djcy", 4} } }, {0, { {"gjcy", 4} } },
	{0, { {"jukcy", 5} } }, {0, { {"dscy", 4} } }, {0, { {"iukcy", 5} } }, {0, { {"yicy", 4} } },
	{0, { {"jsercy", 6} } }, {0, { {"ljcy", 4} } }, {0, { {"njcy", 4} } }, {0, { {"tshcy", 5} } },
	{0, { {"kjcy", 4} } }, {0, { {NULL, 0} } }, {0, { {"ubrcy", 5} } }, {0, { {"dzcy", 4} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html5_02000[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"ensp", 4} } }, {0, { {"emsp", 4} } },
	{0, { {"emsp13", 6} } }, {0, { {"emsp14", 6} } }, {0, { {NULL, 0} } }, {0, { {"numsp", 5} } },
	{0, { {"puncsp", 6} } }, {0, { {"ThinSpace", 9} } }, {0, { {"hairsp", 6} } }, {0, { {"ZeroWidthSpace", 14} } },
	{0, { {"zwnj", 4} } }, {0, { {"zwj", 3} } }, {0, { {"lrm", 3} } }, {0, { {"rlm", 3} } },
	{0, { {"hyphen", 6} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"ndash", 5} } },
	{0, { {"mdash", 5} } }, {0, { {"horbar", 6} } }, {0, { {"Verbar", 6} } }, {0, { {NULL, 0} } },
	{0, { {"OpenCurlyQuote", 14} } }, {0, { {"rsquo", 5} } }, {0, { {"sbquo", 5} } }, {0, { {NULL, 0} } },
	{0, { {"OpenCurlyDoubleQuote", 20} } }, {0, { {"rdquo", 5} } }, {0, { {"bdquo", 5} } }, {0, { {NULL, 0} } },
	{0, { {"dagger", 6} } }, {0, { {"Dagger", 6} } }, {0, { {"bull", 4} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"nldr", 4} } }, {0, { {"hellip", 6} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"permil", 6} } }, {0, { {"pertenk", 7} } }, {0, { {"prime", 5} } }, {0, { {"Prime", 5} } },
	{0, { {"tprime", 6} } }, {0, { {"backprime", 9} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"lsaquo", 6} } }, {0, { {"rsaquo", 6} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"oline", 5} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html5_02040[] = {
	{0, { {NULL, 0} } }, {0, { {"caret", 5} } }, {0, { {NULL, 0} } }, {0, { {"hybull", 6} } },
	{0, { {"frasl", 5} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"bsemi", 5} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"qprime", 6} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {1, { {(void *)multi_cp_html5_0205F, 0} } },
	{0, { {"NoBreak", 7} } }, {0, { {"af", 2} } }, {0, { {"InvisibleTimes", 14} } }, {0, { {"ic", 2} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html5_02080[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"euro", 4} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html5_020C0[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"TripleDot", 9} } },
	{0, { {"DotDot", 6} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html5_02100[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"complexes", 9} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"incare", 6} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"gscr", 4} } }, {0, { {"HilbertSpace", 12} } },
	{0, { {"Hfr", 3} } }, {0, { {"Hopf", 4} } }, {0, { {"planckh", 7} } }, {0, { {"planck", 6} } },
	{0, { {"imagline", 8} } }, {0, { {"Ifr", 3} } }, {0, { {"lagran", 6} } }, {0, { {"ell", 3} } },
	{0, { {NULL, 0} } }, {0, { {"naturals", 8} } }, {0, { {"numero", 6} } }, {0, { {"copysr", 6} } },
	{0, { {"wp", 2} } }, {0, { {"primes", 6} } }, {0, { {"rationals", 9} } }, {0, { {"realine", 7} } },
	{0, { {"Rfr", 3} } }, {0, { {"Ropf", 4} } }, {0, { {"rx", 2} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"trade", 5} } }, {0, { {NULL, 0} } },
	{0, { {"Zopf", 4} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"mho", 3} } },
	{0, { {"Zfr", 3} } }, {0, { {"iiota", 5} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"Bscr", 4} } }, {0, { {"Cfr", 3} } }, {0, { {NULL, 0} } }, {0, { {"escr", 4} } },
	{0, { {"expectation", 11} } }, {0, { {"Fouriertrf", 10} } }, {0, { {NULL, 0} } }, {0, { {"Mellintrf", 9} } },
	{0, { {"orderof", 7} } }, {0, { {"aleph", 5} } }, {0, { {"beth", 4} } }, {0, { {"gimel", 5} } },
	{0, { {"daleth", 6} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html5_02140[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"CapitalDifferentialD", 20} } }, {0, { {"DifferentialD", 13} } }, {0, { {"exponentiale", 12} } },
	{0, { {"ImaginaryI", 10} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"frac13", 6} } },
	{0, { {"frac23", 6} } }, {0, { {"frac15", 6} } }, {0, { {"frac25", 6} } }, {0, { {"frac35", 6} } },
	{0, { {"frac45", 6} } }, {0, { {"frac16", 6} } }, {0, { {"frac56", 6} } }, {0, { {"frac18", 6} } },
	{0, { {"frac38", 6} } }, {0, { {"frac58", 6} } }, {0, { {"frac78", 6} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html5_02180[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"larr", 4} } }, {0, { {"uarr", 4} } }, {0, { {"srarr", 5} } }, {0, { {"darr", 4} } },
	{0, { {"harr", 4} } }, {0, { {"UpDownArrow", 11} } }, {0, { {"nwarrow", 7} } }, {0, { {"UpperRightArrow", 15} } },
	{0, { {"LowerRightArrow", 15} } }, {0, { {"swarr", 5} } }, {0, { {"nleftarrow", 10} } }, {0, { {"nrarr", 5} } },
	{0, { {NULL, 0} } }, {1, { {(void *)multi_cp_html5_0219D, 0} } }, {0, { {"Larr", 4} } }, {0, { {"Uarr", 4} } },
	{0, { {"twoheadrightarrow", 17} } }, {0, { {"Darr", 4} } }, {0, { {"larrtl", 6} } }, {0, { {"rarrtl", 6} } },
	{0, { {"LeftTeeArrow", 12} } }, {0, { {"UpTeeArrow", 10} } }, {0, { {"map", 3} } }, {0, { {"DownTeeArrow", 12} } },
	{0, { {NULL, 0} } }, {0, { {"larrhk", 6} } }, {0, { {"rarrhk", 6} } }, {0, { {"larrlp", 6} } },
	{0, { {"looparrowright", 14} } }, {0, { {"harrw", 5} } }, {0, { {"nleftrightarrow", 15} } }, {0, { {NULL, 0} } },
	{0, { {"Lsh", 3} } }, {0, { {"rsh", 3} } }, {0, { {"ldsh", 4} } }, {0, { {"rdsh", 4} } },
	{0, { {NULL, 0} } }, {0, { {"crarr", 5} } }, {0, { {"curvearrowleft", 14} } }, {0, { {"curarr", 6} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"olarr", 5} } }, {0, { {"orarr", 5} } },
	{0, { {"leftharpoonup", 13} } }, {0, { {"leftharpoondown", 15} } }, {0, { {"RightUpVector", 13} } }, {0, { {"uharl", 5} } },
};

static const entity_stage3_row stage3_table_html5_021C0[] = {
	{0, { {"rharu", 5} } }, {0, { {"rhard", 5} } }, {0, { {"RightDownVector", 15} } }, {0, { {"dharl", 5} } },
	{0, { {"rightleftarrows", 15} } }, {0, { {"udarr", 5} } }, {0, { {"lrarr", 5} } }, {0, { {"llarr", 5} } },
	{0, { {"upuparrows", 10} } }, {0, { {"rrarr", 5} } }, {0, { {"downdownarrows", 14} } }, {0, { {"leftrightharpoons", 17} } },
	{0, { {"rightleftharpoons", 17} } }, {0, { {"nLeftarrow", 10} } }, {0, { {"nhArr", 5} } }, {0, { {"nrArr", 5} } },
	{0, { {"DoubleLeftArrow", 15} } }, {0, { {"DoubleUpArrow", 13} } }, {0, { {"Implies", 7} } }, {0, { {"Downarrow", 9} } },
	{0, { {"hArr", 4} } }, {0, { {"Updownarrow", 11} } }, {0, { {"nwArr", 5} } }, {0, { {"neArr", 5} } },
	{0, { {"seArr", 5} } }, {0, { {"swArr", 5} } }, {0, { {"lAarr", 5} } }, {0, { {"rAarr", 5} } },
	{0, { {NULL, 0} } }, {0, { {"zigrarr", 7} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"LeftArrowBar", 12} } }, {0, { {"RightArrowBar", 13} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"DownArrowUpArrow", 16} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"loarr", 5} } }, {0, { {"roarr", 5} } }, {0, { {"hoarr", 5} } },
};

static const entity_stage3_row stage3_table_html5_02200[] = {
	{0, { {"forall", 6} } }, {0, { {"comp", 4} } }, {1, { {(void *)multi_cp_html5_02202, 0} } }, {0, { {"Exists", 6} } },
	{0, { {"nexist", 6} } }, {0, { {"empty", 5} } }, {0, { {NULL, 0} } }, {0, { {"nabla", 5} } },
	{0, { {"isinv", 5} } }, {0, { {"notin", 5} } }, {0, { {NULL, 0} } }, {0, { {"ReverseElement", 14} } },
	{0, { {"notniva", 7} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"prod", 4} } },
	{0, { {"Coproduct", 9} } }, {0, { {"sum", 3} } }, {0, { {"minus", 5} } }, {0, { {"MinusPlus", 9} } },
	{0, { {"plusdo", 6} } }, {0, { {NULL, 0} } }, {0, { {"ssetmn", 6} } }, {0, { {"lowast", 6} } },
	{0, { {"compfn", 6} } }, {0, { {NULL, 0} } }, {0, { {"Sqrt", 4} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"prop", 4} } }, {0, { {"infin", 5} } }, {0, { {"angrt", 5} } },
	{1, { {(void *)multi_cp_html5_02220, 0} } }, {0, { {"angmsd", 6} } }, {0, { {"angsph", 6} } }, {0, { {"mid", 3} } },
	{0, { {"nshortmid", 9} } }, {0, { {"shortparallel", 13} } }, {0, { {"nparallel", 9} } }, {0, { {"and", 3} } },
	{0, { {"or", 2} } }, {1, { {(void *)multi_cp_html5_02229, 0} } }, {1, { {(void *)multi_cp_html5_0222A, 0} } }, {0, { {"Integral", 8} } },
	{0, { {"Int", 3} } }, {0, { {"tint", 4} } }, {0, { {"ContourIntegral", 15} } }, {0, { {"DoubleContourIntegral", 21} } },
	{0, { {"Cconint", 7} } }, {0, { {"cwint", 5} } }, {0, { {"cwconint", 8} } }, {0, { {"awconint", 8} } },
	{0, { {"there4", 6} } }, {0, { {"Because", 7} } }, {0, { {"ratio", 5} } }, {0, { {"Colon", 5} } },
	{0, { {"minusd", 6} } }, {0, { {NULL, 0} } }, {0, { {"mDDot", 5} } }, {0, { {"homtht", 6} } },
	{1, { {(void *)multi_cp_html5_0223C, 0} } }, {1, { {(void *)multi_cp_html5_0223D, 0} } }, {1, { {(void *)multi_cp_html5_0223E, 0} } }, {0, { {"acd", 3} } },
};

static const entity_stage3_row stage3_table_html5_02240[] = {
	{0, { {"wr", 2} } }, {0, { {"NotTilde", 8} } }, {1, { {(void *)multi_cp_html5_02242, 0} } }, {0, { {"simeq", 5} } },
	{0, { {"nsime", 5} } }, {0, { {"TildeFullEqual", 14} } }, {0, { {"simne", 5} } }, {0, { {"ncong", 5} } },
	{0, { {"approx", 6} } }, {0, { {"napprox", 7} } }, {0, { {"ape", 3} } }, {1, { {(void *)multi_cp_html5_0224B, 0} } },
	{0, { {"bcong", 5} } }, {1, { {(void *)multi_cp_html5_0224D, 0} } }, {1, { {(void *)multi_cp_html5_0224E, 0} } }, {1, { {(void *)multi_cp_html5_0224F, 0} } },
	{1, { {(void *)multi_cp_html5_02250, 0} } }, {0, { {"doteqdot", 8} } }, {0, { {"fallingdotseq", 13} } }, {0, { {"risingdotseq", 12} } },
	{0, { {"coloneq", 7} } }, {0, { {"eqcolon", 7} } }, {0, { {"ecir", 4} } }, {0, { {"circeq", 6} } },
	{0, { {NULL, 0} } }, {0, { {"wedgeq", 6} } }, {0, { {"veeeq", 5} } }, {0, { {NULL, 0} } },
	{0, { {"triangleq", 9} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"equest", 6} } },
	{0, { {"NotEqual", 8} } }, {1, { {(void *)multi_cp_html5_02261, 0} } }, {0, { {"NotCongruent", 12} } }, {0, { {NULL, 0} } },
	{1, { {(void *)multi_cp_html5_02264, 0} } }, {1, { {(void *)multi_cp_html5_02265, 0} } }, {1, { {(void *)multi_cp_html5_02266, 0} } }, {1, { {(void *)multi_cp_html5_02267, 0} } },
	{1, { {(void *)multi_cp_html5_02268, 0} } }, {1, { {(void *)multi_cp_html5_02269, 0} } }, {1, { {(void *)multi_cp_html5_0226A, 0} } }, {1, { {(void *)multi_cp_html5_0226B, 0} } },
	{0, { {"between", 7} } }, {0, { {"NotCupCap", 9} } }, {0, { {"NotLess", 7} } }, {0, { {"ngtr", 4} } },
	{0, { {"NotLessEqual", 12} } }, {0, { {"ngeq", 4} } }, {0, { {"LessTilde", 9} } }, {0, { {"GreaterTilde", 12} } },
	{0, { {"nlsim", 5} } }, {0, { {"ngsim", 5} } }, {0, { {"lessgtr", 7} } }, {0, { {"gl", 2} } },
	{0, { {"ntlg", 4} } }, {0, { {"NotGreaterLess", 14} } }, {0, { {"prec", 4} } }, {0, { {"succ", 4} } },
	{0, { {"PrecedesSlantEqual", 18} } }, {0, { {"succcurlyeq", 11} } }, {0, { {"precsim", 7} } }, {1, { {(void *)multi_cp_html5_0227F, 0} } },
};

static const entity_stage3_row stage3_table_html5_02280[] = {
	{0, { {"npr", 3} } }, {0, { {"NotSucceeds", 11} } }, {1, { {(void *)multi_cp_html5_02282, 0} } }, {1, { {(void *)multi_cp_html5_02283, 0} } },
	{0, { {"nsub", 4} } }, {0, { {"nsup", 4} } }, {0, { {"SubsetEqual", 11} } }, {0, { {"supe", 4} } },
	{0, { {"NotSubsetEqual", 14} } }, {0, { {"NotSupersetEqual", 16} } }, {1, { {(void *)multi_cp_html5_0228A, 0} } }, {1, { {(void *)multi_cp_html5_0228B, 0} } },
	{0, { {NULL, 0} } }, {0, { {"cupdot", 6} } }, {0, { {"UnionPlus", 9} } }, {1, { {(void *)multi_cp_html5_0228F, 0} } },
	{1, { {(void *)multi_cp_html5_02290, 0} } }, {0, { {"SquareSubsetEqual", 17} } }, {0, { {"SquareSupersetEqual", 19} } }, {1, { {(void *)multi_cp_html5_02293, 0} } },
	{1, { {(void *)multi_cp_html5_02294, 0} } }, {0, { {"CirclePlus", 10} } }, {0, { {"ominus", 6} } }, {0, { {"CircleTimes", 11} } },
	{0, { {"osol", 4} } }, {0, { {"CircleDot", 9} } }, {0, { {"ocir", 4} } }, {0, { {"oast", 4} } },
	{0, { {NULL, 0} } }, {0, { {"odash", 5} } }, {0, { {"boxplus", 7} } }, {0, { {"boxminus", 8} } },
	{0, { {"timesb", 6} } }, {0, { {"sdotb", 5} } }, {0, { {"vdash", 5} } }, {0, { {"dashv", 5} } },
	{0, { {"DownTee", 7} } }, {0, { {"perp", 4} } }, {0, { {NULL, 0} } }, {0, { {"models", 6} } },
	{0, { {"DoubleRightTee", 14} } }, {0, { {"Vdash", 5} } }, {0, { {"Vvdash", 6} } }, {0, { {"VDash", 5} } },
	{0, { {"nvdash", 6} } }, {0, { {"nvDash", 6} } }, {0, { {"nVdash", 6} } }, {0, { {"nVDash", 6} } },
	{0, { {"prurel", 6} } }, {0, { {NULL, 0} } }, {0, { {"vartriangleleft", 15} } }, {0, { {"vrtri", 5} } },
	{1, { {(void *)multi_cp_html5_022B4, 0} } }, {1, { {(void *)multi_cp_html5_022B5, 0} } }, {0, { {"origof", 6} } }, {0, { {"imof", 4} } },
	{0, { {"mumap", 5} } }, {0, { {"hercon", 6} } }, {0, { {"intcal", 6} } }, {0, { {"veebar", 6} } },
	{0, { {NULL, 0} } }, {0, { {"barvee", 6} } }, {0, { {"angrtvb", 7} } }, {0, { {"lrtri", 5} } },
};

static const entity_stage3_row stage3_table_html5_022C0[] = {
	{0, { {"xwedge", 6} } }, {0, { {"xvee", 4} } }, {0, { {"bigcap", 6} } }, {0, { {"bigcup", 6} } },
	{0, { {"diamond", 7} } }, {0, { {"sdot", 4} } }, {0, { {"Star", 4} } }, {0, { {"divonx", 6} } },
	{0, { {"bowtie", 6} } }, {0, { {"ltimes", 6} } }, {0, { {"rtimes", 6} } }, {0, { {"lthree", 6} } },
	{0, { {"rthree", 6} } }, {0, { {"backsimeq", 9} } }, {0, { {"curlyvee", 8} } }, {0, { {"curlywedge", 10} } },
	{0, { {"Sub", 3} } }, {0, { {"Supset", 6} } }, {0, { {"Cap", 3} } }, {0, { {"Cup", 3} } },
	{0, { {"pitchfork", 9} } }, {0, { {"epar", 4} } }, {0, { {"lessdot", 7} } }, {0, { {"gtrdot", 6} } },
	{1, { {(void *)multi_cp_html5_022D8, 0} } }, {1, { {(void *)multi_cp_html5_022D9, 0} } }, {1, { {(void *)multi_cp_html5_022DA, 0} } }, {1, { {(void *)multi_cp_html5_022DB, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"curlyeqprec", 11} } }, {0, { {"cuesc", 5} } },
	{0, { {"NotPrecedesSlantEqual", 21} } }, {0, { {"NotSucceedsSlantEqual", 21} } }, {0, { {"NotSquareSubsetEqual", 20} } }, {0, { {"NotSquareSupersetEqual", 22} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"lnsim", 5} } }, {0, { {"gnsim", 5} } },
	{0, { {"precnsim", 8} } }, {0, { {"scnsim", 6} } }, {0, { {"nltri", 5} } }, {0, { {"ntriangleright", 14} } },
	{0, { {"nltrie", 6} } }, {0, { {"NotRightTriangleEqual", 21} } }, {0, { {"vellip", 6} } }, {0, { {"ctdot", 5} } },
	{0, { {"utdot", 5} } }, {0, { {"dtdot", 5} } }, {0, { {"disin", 5} } }, {0, { {"isinsv", 6} } },
	{0, { {"isins", 5} } }, {1, { {(void *)multi_cp_html5_022F5, 0} } }, {0, { {"notinvc", 7} } }, {0, { {"notinvb", 7} } },
	{0, { {NULL, 0} } }, {1, { {(void *)multi_cp_html5_022F9, 0} } }, {0, { {"nisd", 4} } }, {0, { {"xnis", 4} } },
	{0, { {"nis", 3} } }, {0, { {"notnivc", 7} } }, {0, { {"notnivb", 7} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html5_02300[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"barwed", 6} } }, {0, { {"doublebarwedge", 14} } }, {0, { {NULL, 0} } },
	{0, { {"lceil", 5} } }, {0, { {"RightCeiling", 12} } }, {0, { {"LeftFloor", 9} } }, {0, { {"RightFloor", 10} } },
	{0, { {"drcrop", 6} } }, {0, { {"dlcrop", 6} } }, {0, { {"urcrop", 6} } }, {0, { {"ulcrop", 6} } },
	{0, { {"bnot", 4} } }, {0, { {NULL, 0} } }, {0, { {"profline", 8} } }, {0, { {"profsurf", 8} } },
	{0, { {NULL, 0} } }, {0, { {"telrec", 6} } }, {0, { {"target", 6} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"ulcorner", 8} } }, {0, { {"urcorner", 8} } }, {0, { {"llcorner", 8} } }, {0, { {"drcorn", 6} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"frown", 5} } }, {0, { {"smile", 5} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"cylcty", 6} } }, {0, { {"profalar", 8} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"topbot", 6} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"ovbar", 5} } }, {0, { {NULL, 0} } }, {0, { {"solbar", 6} } },
};

static const entity_stage3_row stage3_table_html5_02340[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"angzarr", 7} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html5_02380[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"lmoust", 6} } }, {0, { {"rmoust", 6} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"OverBracket", 11} } }, {0, { {"bbrk", 4} } }, {0, { {"bbrktbrk", 8} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html5_023C0[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"OverParenthesis", 15} } }, {0, { {"UnderParenthesis", 16} } }, {0, { {"OverBrace", 9} } }, {0, { {"UnderBrace", 10} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"trpezium", 8} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"elinters", 8} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html5_02400[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"blank", 5} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html5_024C0[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"oS", 2} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html5_02500[] = {
	{0, { {"HorizontalLine", 14} } }, {0, { {NULL, 0} } }, {0, { {"boxv", 4} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"boxdr", 5} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"boxdl", 5} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"boxur", 5} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"boxul", 5} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"boxvr", 5} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"boxvl", 5} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"boxhd", 5} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"boxhu", 5} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"boxvh", 5} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html5_02540[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"boxH", 4} } }, {0, { {"boxV", 4} } }, {0, { {"boxdR", 5} } }, {0, { {"boxDr", 5} } },
	{0, { {"boxDR", 5} } }, {0, { {"boxdL", 5} } }, {0, { {"boxDl", 5} } }, {0, { {"boxDL", 5} } },
	{0, { {"boxuR", 5} } }, {0, { {"boxUr", 5} } }, {0, { {"boxUR", 5} } }, {0, { {"boxuL", 5} } },
	{0, { {"boxUl", 5} } }, {0, { {"boxUL", 5} } }, {0, { {"boxvR", 5} } }, {0, { {"boxVr", 5} } },
	{0, { {"boxVR", 5} } }, {0, { {"boxvL", 5} } }, {0, { {"boxVl", 5} } }, {0, { {"boxVL", 5} } },
	{0, { {"boxHd", 5} } }, {0, { {"boxhD", 5} } }, {0, { {"boxHD", 5} } }, {0, { {"boxHu", 5} } },
	{0, { {"boxhU", 5} } }, {0, { {"boxHU", 5} } }, {0, { {"boxvH", 5} } }, {0, { {"boxVh", 5} } },
	{0, { {"boxVH", 5} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html5_02580[] = {
	{0, { {"uhblk", 5} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"lhblk", 5} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"block", 5} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"blk14", 5} } }, {0, { {"blk12", 5} } }, {0, { {"blk34", 5} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"Square", 6} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"squarf", 6} } }, {0, { {"EmptyVerySmallSquare", 20} } },
	{0, { {NULL, 0} } }, {0, { {"rect", 4} } }, {0, { {"marker", 6} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"fltns", 5} } }, {0, { {NULL, 0} } }, {0, { {"bigtriangleup", 13} } },
	{0, { {"blacktriangle", 13} } }, {0, { {"triangle", 8} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"blacktriangleright", 18} } }, {0, { {"rtri", 4} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"bigtriangledown", 15} } }, {0, { {"blacktriangledown", 17} } }, {0, { {"triangledown", 12} } },
};

static const entity_stage3_row stage3_table_html5_025C0[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"blacktriangleleft", 17} } }, {0, { {"ltri", 4} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"lozenge", 7} } }, {0, { {"cir", 3} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"tridot", 6} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"bigcirc", 7} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"ultri", 5} } }, {0, { {"urtri", 5} } }, {0, { {"lltri", 5} } }, {0, { {"EmptySmallSquare", 16} } },
	{0, { {"FilledSmallSquare", 17} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html5_02600[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"starf", 5} } }, {0, { {"star", 4} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"phone", 5} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html5_02640[] = {
	{0, { {"female", 6} } }, {0, { {NULL, 0} } }, {0, { {"male", 4} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"spadesuit", 9} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"clubs", 5} } },
	{0, { {NULL, 0} } }, {0, { {"hearts", 6} } }, {0, { {"diamondsuit", 11} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"sung", 4} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"flat", 4} } }, {0, { {"natur", 5} } }, {0, { {"sharp", 5} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html5_02700[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"check", 5} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"cross", 5} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"maltese", 7} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"sext", 4} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html5_02740[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"VerticalSeparator", 17} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"lbbrk", 5} } }, {0, { {"rbbrk", 5} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html5_027C0[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"bsolhsub", 8} } }, {0, { {"suphsol", 7} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"LeftDoubleBracket", 17} } }, {0, { {"RightDoubleBracket", 18} } },
	{0, { {"langle", 6} } }, {0, { {"RightAngleBracket", 17} } }, {0, { {"Lang", 4} } }, {0, { {"Rang", 4} } },
	{0, { {"loang", 5} } }, {0, { {"roang", 5} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"longleftarrow", 13} } }, {0, { {"LongRightArrow", 14} } }, {0, { {"LongLeftRightArrow", 18} } },
	{0, { {"xlArr", 5} } }, {0, { {"DoubleLongRightArrow", 20} } }, {0, { {"xhArr", 5} } }, {0, { {NULL, 0} } },
	{0, { {"xmap", 4} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"dzigrarr", 8} } },
};

static const entity_stage3_row stage3_table_html5_02900[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"nvlArr", 6} } }, {0, { {"nvrArr", 6} } },
	{0, { {"nvHarr", 6} } }, {0, { {"Map", 3} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"lbarr", 5} } }, {0, { {"bkarow", 6} } }, {0, { {"lBarr", 5} } }, {0, { {"dbkarow", 7} } },
	{0, { {"drbkarow", 8} } }, {0, { {"DDotrahd", 8} } }, {0, { {"UpArrowBar", 10} } }, {0, { {"DownArrowBar", 12} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"Rarrtl", 6} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"latail", 6} } }, {0, { {"ratail", 6} } }, {0, { {"lAtail", 6} } },
	{0, { {"rAtail", 6} } }, {0, { {"larrfs", 6} } }, {0, { {"rarrfs", 6} } }, {0, { {"larrbfs", 7} } },
	{0, { {"rarrbfs", 7} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"nwarhk", 6} } },
	{0, { {"nearhk", 6} } }, {0, { {"searhk", 6} } }, {0, { {"swarhk", 6} } }, {0, { {"nwnear", 6} } },
	{0, { {"toea", 4} } }, {0, { {"seswar", 6} } }, {0, { {"swnwar", 6} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {1, { {(void *)multi_cp_html5_02933, 0} } },
	{0, { {NULL, 0} } }, {0, { {"cudarrr", 7} } }, {0, { {"ldca", 4} } }, {0, { {"rdca", 4} } },
	{0, { {"cudarrl", 7} } }, {0, { {"larrpl", 6} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"curarrm", 7} } }, {0, { {"cularrp", 7} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html5_02940[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"rarrpl", 6} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"harrcir", 7} } }, {0, { {"Uarrocir", 8} } }, {0, { {"lurdshar", 8} } }, {0, { {"ldrushar", 8} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"LeftRightVector", 15} } }, {0, { {"RightUpDownVector", 17} } },
	{0, { {"DownLeftRightVector", 19} } }, {0, { {"LeftUpDownVector", 16} } }, {0, { {"LeftVectorBar", 13} } }, {0, { {"RightVectorBar", 14} } },
	{0, { {"RightUpVectorBar", 16} } }, {0, { {"RightDownVectorBar", 18} } }, {0, { {"DownLeftVectorBar", 17} } }, {0, { {"DownRightVectorBar", 18} } },
	{0, { {"LeftUpVectorBar", 15} } }, {0, { {"LeftDownVectorBar", 17} } }, {0, { {"LeftTeeVector", 13} } }, {0, { {"RightTeeVector", 14} } },
	{0, { {"RightUpTeeVector", 16} } }, {0, { {"RightDownTeeVector", 18} } }, {0, { {"DownLeftTeeVector", 17} } }, {0, { {"DownRightTeeVector", 18} } },
	{0, { {"LeftUpTeeVector", 15} } }, {0, { {"LeftDownTeeVector", 17} } }, {0, { {"lHar", 4} } }, {0, { {"uHar", 4} } },
	{0, { {"rHar", 4} } }, {0, { {"dHar", 4} } }, {0, { {"luruhar", 7} } }, {0, { {"ldrdhar", 7} } },
	{0, { {"ruluhar", 7} } }, {0, { {"rdldhar", 7} } }, {0, { {"lharul", 6} } }, {0, { {"llhard", 6} } },
	{0, { {"rharul", 6} } }, {0, { {"lrhard", 6} } }, {0, { {"udhar", 5} } }, {0, { {"ReverseUpEquilibrium", 20} } },
	{0, { {"RoundImplies", 12} } }, {0, { {"erarr", 5} } }, {0, { {"simrarr", 7} } }, {0, { {"larrsim", 7} } },
	{0, { {"rarrsim", 7} } }, {0, { {"rarrap", 6} } }, {0, { {"ltlarr", 6} } }, {0, { {NULL, 0} } },
	{0, { {"gtrarr", 6} } }, {0, { {"subrarr", 7} } }, {0, { {NULL, 0} } }, {0, { {"suplarr", 7} } },
	{0, { {"lfisht", 6} } }, {0, { {"rfisht", 6} } }, {0, { {"ufisht", 6} } }, {0, { {"dfisht", 6} } },
};

static const entity_stage3_row stage3_table_html5_02980[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"lopar", 5} } }, {0, { {"ropar", 5} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"lbrke", 5} } },
	{0, { {"rbrke", 5} } }, {0, { {"lbrkslu", 7} } }, {0, { {"rbrksld", 7} } }, {0, { {"lbrksld", 7} } },
	{0, { {"rbrkslu", 7} } }, {0, { {"langd", 5} } }, {0, { {"rangd", 5} } }, {0, { {"lparlt", 6} } },
	{0, { {"rpargt", 6} } }, {0, { {"gtlPar", 6} } }, {0, { {"ltrPar", 6} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"vzigzag", 7} } }, {0, { {NULL, 0} } },
	{0, { {"vangrt", 6} } }, {0, { {"angrtvbd", 8} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"ange", 4} } }, {0, { {"range", 5} } }, {0, { {"dwangle", 7} } }, {0, { {"uwangle", 7} } },
	{0, { {"angmsdaa", 8} } }, {0, { {"angmsdab", 8} } }, {0, { {"angmsdac", 8} } }, {0, { {"angmsdad", 8} } },
	{0, { {"angmsdae", 8} } }, {0, { {"angmsdaf", 8} } }, {0, { {"angmsdag", 8} } }, {0, { {"angmsdah", 8} } },
	{0, { {"bemptyv", 7} } }, {0, { {"demptyv", 7} } }, {0, { {"cemptyv", 7} } }, {0, { {"raemptyv", 8} } },
	{0, { {"laemptyv", 8} } }, {0, { {"ohbar", 5} } }, {0, { {"omid", 4} } }, {0, { {"opar", 4} } },
	{0, { {NULL, 0} } }, {0, { {"operp", 5} } }, {0, { {NULL, 0} } }, {0, { {"olcross", 7} } },
	{0, { {"odsold", 6} } }, {0, { {NULL, 0} } }, {0, { {"olcir", 5} } }, {0, { {"ofcir", 5} } },
};

static const entity_stage3_row stage3_table_html5_029C0[] = {
	{0, { {"olt", 3} } }, {0, { {"ogt", 3} } }, {0, { {"cirscir", 7} } }, {0, { {"cirE", 4} } },
	{0, { {"solb", 4} } }, {0, { {"bsolb", 5} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"boxbox", 6} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"trisb", 5} } }, {0, { {"rtriltri", 8} } }, {1, { {(void *)multi_cp_html5_029CF, 0} } },
	{1, { {(void *)multi_cp_html5_029D0, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"iinfin", 6} } }, {0, { {"infintie", 8} } }, {0, { {"nvinfin", 7} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"eparsl", 6} } },
	{0, { {"smeparsl", 8} } }, {0, { {"eqvparsl", 8} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"lozf", 4} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"RuleDelayed", 11} } }, {0, { {NULL, 0} } }, {0, { {"dsol", 4} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html5_02A00[] = {
	{0, { {"xodot", 5} } }, {0, { {"bigoplus", 8} } }, {0, { {"bigotimes", 9} } }, {0, { {NULL, 0} } },
	{0, { {"biguplus", 8} } }, {0, { {NULL, 0} } }, {0, { {"bigsqcup", 8} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"iiiint", 6} } }, {0, { {"fpartint", 8} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"cirfnint", 8} } }, {0, { {"awint", 5} } }, {0, { {"rppolint", 8} } }, {0, { {"scpolint", 8} } },
	{0, { {"npolint", 7} } }, {0, { {"pointint", 8} } }, {0, { {"quatint", 7} } }, {0, { {"intlarhk", 8} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"pluscir", 7} } }, {0, { {"plusacir", 8} } },
	{0, { {"simplus", 7} } }, {0, { {"plusdu", 6} } }, {0, { {"plussim", 7} } }, {0, { {"plustwo", 7} } },
	{0, { {NULL, 0} } }, {0, { {"mcomma", 6} } }, {0, { {"minusdu", 7} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"loplus", 6} } }, {0, { {"roplus", 6} } }, {0, { {"Cross", 5} } },
	{0, { {"timesd", 6} } }, {0, { {"timesbar", 8} } }, {0, { {NULL, 0} } }, {0, { {"smashp", 6} } },
	{0, { {"lotimes", 7} } }, {0, { {"rotimes", 7} } }, {0, { {"otimesas", 8} } }, {0, { {"Otimes", 6} } },
	{0, { {"odiv", 4} } }, {0, { {"triplus", 7} } }, {0, { {"triminus", 8} } }, {0, { {"tritime", 7} } },
	{0, { {"iprod", 5} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"amalg", 5} } },
};

static const entity_stage3_row stage3_table_html5_02A40[] = {
	{0, { {"capdot", 6} } }, {0, { {NULL, 0} } }, {0, { {"ncup", 4} } }, {0, { {"ncap", 4} } },
	{0, { {"capand", 6} } }, {0, { {"cupor", 5} } }, {0, { {"cupcap", 6} } }, {0, { {"capcup", 6} } },
	{0, { {"cupbrcap", 8} } }, {0, { {"capbrcup", 8} } }, {0, { {"cupcup", 6} } }, {0, { {"capcap", 6} } },
	{0, { {"ccups", 5} } }, {0, { {"ccaps", 5} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"ccupssm", 7} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"And", 3} } },
	{0, { {"Or", 2} } }, {0, { {"andand", 6} } }, {0, { {"oror", 4} } }, {0, { {"orslope", 7} } },
	{0, { {"andslope", 8} } }, {0, { {NULL, 0} } }, {0, { {"andv", 4} } }, {0, { {"orv", 3} } },
	{0, { {"andd", 4} } }, {0, { {"ord", 3} } }, {0, { {NULL, 0} } }, {0, { {"wedbar", 6} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"sdote", 5} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"simdot", 6} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {1, { {(void *)multi_cp_html5_02A6D, 0} } }, {0, { {"easter", 6} } }, {0, { {"apacir", 6} } },
	{1, { {(void *)multi_cp_html5_02A70, 0} } }, {0, { {"eplus", 5} } }, {0, { {"pluse", 5} } }, {0, { {"Esim", 4} } },
	{0, { {"Colone", 6} } }, {0, { {"Equal", 5} } }, {0, { {NULL, 0} } }, {0, { {"ddotseq", 7} } },
	{0, { {"equivDD", 7} } }, {0, { {"ltcir", 5} } }, {0, { {"gtcir", 5} } }, {0, { {"ltquest", 7} } },
	{0, { {"gtquest", 7} } }, {1, { {(void *)multi_cp_html5_02A7D, 0} } }, {1, { {(void *)multi_cp_html5_02A7E, 0} } }, {0, { {"lesdot", 6} } },
};

static const entity_stage3_row stage3_table_html5_02A80[] = {
	{0, { {"gesdot", 6} } }, {0, { {"lesdoto", 7} } }, {0, { {"gesdoto", 7} } }, {0, { {"lesdotor", 8} } },
	{0, { {"gesdotol", 8} } }, {0, { {"lap", 3} } }, {0, { {"gap", 3} } }, {0, { {"lne", 3} } },
	{0, { {"gne", 3} } }, {0, { {"lnap", 4} } }, {0, { {"gnap", 4} } }, {0, { {"lesseqqgtr", 10} } },
	{0, { {"gEl", 3} } }, {0, { {"lsime", 5} } }, {0, { {"gsime", 5} } }, {0, { {"lsimg", 5} } },
	{0, { {"gsiml", 5} } }, {0, { {"lgE", 3} } }, {0, { {"glE", 3} } }, {0, { {"lesges", 6} } },
	{0, { {"gesles", 6} } }, {0, { {"els", 3} } }, {0, { {"egs", 3} } }, {0, { {"elsdot", 6} } },
	{0, { {"egsdot", 6} } }, {0, { {"el", 2} } }, {0, { {"eg", 2} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"siml", 4} } }, {0, { {"simg", 4} } }, {0, { {"simlE", 5} } },
	{0, { {"simgE", 5} } }, {1, { {(void *)multi_cp_html5_02AA1, 0} } }, {1, { {(void *)multi_cp_html5_02AA2, 0} } }, {0, { {NULL, 0} } },
	{0, { {"glj", 3} } }, {0, { {"gla", 3} } }, {0, { {"ltcc", 4} } }, {0, { {"gtcc", 4} } },
	{0, { {"lescc", 5} } }, {0, { {"gescc", 5} } }, {0, { {"smt", 3} } }, {0, { {"lat", 3} } },
	{1, { {(void *)multi_cp_html5_02AAC, 0} } }, {1, { {(void *)multi_cp_html5_02AAD, 0} } }, {0, { {"bumpE", 5} } }, {1, { {(void *)multi_cp_html5_02AAF, 0} } },
	{1, { {(void *)multi_cp_html5_02AB0, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"prE", 3} } },
	{0, { {"scE", 3} } }, {0, { {"precneqq", 8} } }, {0, { {"scnE", 4} } }, {0, { {"precapprox", 10} } },
	{0, { {"succapprox", 10} } }, {0, { {"precnapprox", 11} } }, {0, { {"succnapprox", 11} } }, {0, { {"Pr", 2} } },
	{0, { {"Sc", 2} } }, {0, { {"subdot", 6} } }, {0, { {"supdot", 6} } }, {0, { {"subplus", 7} } },
};

static const entity_stage3_row stage3_table_html5_02AC0[] = {
	{0, { {"supplus", 7} } }, {0, { {"submult", 7} } }, {0, { {"supmult", 7} } }, {0, { {"subedot", 7} } },
	{0, { {"supedot", 7} } }, {1, { {(void *)multi_cp_html5_02AC5, 0} } }, {1, { {(void *)multi_cp_html5_02AC6, 0} } }, {0, { {"subsim", 6} } },
	{0, { {"supsim", 6} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {1, { {(void *)multi_cp_html5_02ACB, 0} } },
	{1, { {(void *)multi_cp_html5_02ACC, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"csub", 4} } },
	{0, { {"csup", 4} } }, {0, { {"csube", 5} } }, {0, { {"csupe", 5} } }, {0, { {"subsup", 6} } },
	{0, { {"supsub", 6} } }, {0, { {"subsub", 6} } }, {0, { {"supsup", 6} } }, {0, { {"suphsub", 7} } },
	{0, { {"supdsub", 7} } }, {0, { {"forkv", 5} } }, {0, { {"topfork", 7} } }, {0, { {"mlcp", 4} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"Dashv", 5} } }, {0, { {NULL, 0} } }, {0, { {"Vdashl", 6} } }, {0, { {"Barv", 4} } },
	{0, { {"vBar", 4} } }, {0, { {"vBarv", 5} } }, {0, { {NULL, 0} } }, {0, { {"Vbar", 4} } },
	{0, { {"Not", 3} } }, {0, { {"bNot", 4} } }, {0, { {"rnmid", 5} } }, {0, { {"cirmid", 6} } },
	{0, { {"midcir", 6} } }, {0, { {"topcir", 6} } }, {0, { {"nhpar", 5} } }, {0, { {"parsim", 6} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {1, { {(void *)multi_cp_html5_02AFD, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html5_0FB00[] = {
	{0, { {"fflig", 5} } }, {0, { {"filig", 5} } }, {0, { {"fllig", 5} } }, {0, { {"ffilig", 6} } },
	{0, { {"ffllig", 6} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html5_1D480[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"Ascr", 4} } }, {0, { {NULL, 0} } }, {0, { {"Cscr", 4} } }, {0, { {"Dscr", 4} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"Gscr", 4} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"Jscr", 4} } }, {0, { {"Kscr", 4} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"Nscr", 4} } }, {0, { {"Oscr", 4} } }, {0, { {"Pscr", 4} } },
	{0, { {"Qscr", 4} } }, {0, { {NULL, 0} } }, {0, { {"Sscr", 4} } }, {0, { {"Tscr", 4} } },
	{0, { {"Uscr", 4} } }, {0, { {"Vscr", 4} } }, {0, { {"Wscr", 4} } }, {0, { {"Xscr", 4} } },
	{0, { {"Yscr", 4} } }, {0, { {"Zscr", 4} } }, {0, { {"ascr", 4} } }, {0, { {"bscr", 4} } },
	{0, { {"cscr", 4} } }, {0, { {"dscr", 4} } }, {0, { {NULL, 0} } }, {0, { {"fscr", 4} } },
	{0, { {NULL, 0} } }, {0, { {"hscr", 4} } }, {0, { {"iscr", 4} } }, {0, { {"jscr", 4} } },
};

static const entity_stage3_row stage3_table_html5_1D4C0[] = {
	{0, { {"kscr", 4} } }, {0, { {"lscr", 4} } }, {0, { {"mscr", 4} } }, {0, { {"nscr", 4} } },
	{0, { {NULL, 0} } }, {0, { {"pscr", 4} } }, {0, { {"qscr", 4} } }, {0, { {"rscr", 4} } },
	{0, { {"sscr", 4} } }, {0, { {"tscr", 4} } }, {0, { {"uscr", 4} } }, {0, { {"vscr", 4} } },
	{0, { {"wscr", 4} } }, {0, { {"xscr", 4} } }, {0, { {"yscr", 4} } }, {0, { {"zscr", 4} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html5_1D500[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"Afr", 3} } }, {0, { {"Bfr", 3} } }, {0, { {NULL, 0} } }, {0, { {"Dfr", 3} } },
	{0, { {"Efr", 3} } }, {0, { {"Ffr", 3} } }, {0, { {"Gfr", 3} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"Jfr", 3} } }, {0, { {"Kfr", 3} } }, {0, { {"Lfr", 3} } },
	{0, { {"Mfr", 3} } }, {0, { {"Nfr", 3} } }, {0, { {"Ofr", 3} } }, {0, { {"Pfr", 3} } },
	{0, { {"Qfr", 3} } }, {0, { {NULL, 0} } }, {0, { {"Sfr", 3} } }, {0, { {"Tfr", 3} } },
	{0, { {"Ufr", 3} } }, {0, { {"Vfr", 3} } }, {0, { {"Wfr", 3} } }, {0, { {"Xfr", 3} } },
	{0, { {"Yfr", 3} } }, {0, { {NULL, 0} } }, {0, { {"afr", 3} } }, {0, { {"bfr", 3} } },
	{0, { {"cfr", 3} } }, {0, { {"dfr", 3} } }, {0, { {"efr", 3} } }, {0, { {"ffr", 3} } },
	{0, { {"gfr", 3} } }, {0, { {"hfr", 3} } }, {0, { {"ifr", 3} } }, {0, { {"jfr", 3} } },
	{0, { {"kfr", 3} } }, {0, { {"lfr", 3} } }, {0, { {"mfr", 3} } }, {0, { {"nfr", 3} } },
	{0, { {"ofr", 3} } }, {0, { {"pfr", 3} } }, {0, { {"qfr", 3} } }, {0, { {"rfr", 3} } },
	{0, { {"sfr", 3} } }, {0, { {"tfr", 3} } }, {0, { {"ufr", 3} } }, {0, { {"vfr", 3} } },
	{0, { {"wfr", 3} } }, {0, { {"xfr", 3} } }, {0, { {"yfr", 3} } }, {0, { {"zfr", 3} } },
	{0, { {"Aopf", 4} } }, {0, { {"Bopf", 4} } }, {0, { {NULL, 0} } }, {0, { {"Dopf", 4} } },
	{0, { {"Eopf", 4} } }, {0, { {"Fopf", 4} } }, {0, { {"Gopf", 4} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html5_1D540[] = {
	{0, { {"Iopf", 4} } }, {0, { {"Jopf", 4} } }, {0, { {"Kopf", 4} } }, {0, { {"Lopf", 4} } },
	{0, { {"Mopf", 4} } }, {0, { {NULL, 0} } }, {0, { {"Oopf", 4} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"Sopf", 4} } }, {0, { {"Topf", 4} } },
	{0, { {"Uopf", 4} } }, {0, { {"Vopf", 4} } }, {0, { {"Wopf", 4} } }, {0, { {"Xopf", 4} } },
	{0, { {"Yopf", 4} } }, {0, { {NULL, 0} } }, {0, { {"aopf", 4} } }, {0, { {"bopf", 4} } },
	{0, { {"copf", 4} } }, {0, { {"dopf", 4} } }, {0, { {"eopf", 4} } }, {0, { {"fopf", 4} } },
	{0, { {"gopf", 4} } }, {0, { {"hopf", 4} } }, {0, { {"iopf", 4} } }, {0, { {"jopf", 4} } },
	{0, { {"kopf", 4} } }, {0, { {"lopf", 4} } }, {0, { {"mopf", 4} } }, {0, { {"nopf", 4} } },
	{0, { {"oopf", 4} } }, {0, { {"popf", 4} } }, {0, { {"qopf", 4} } }, {0, { {"ropf", 4} } },
	{0, { {"sopf", 4} } }, {0, { {"topf", 4} } }, {0, { {"uopf", 4} } }, {0, { {"vopf", 4} } },
	{0, { {"wopf", 4} } }, {0, { {"xopf", 4} } }, {0, { {"yopf", 4} } }, {0, { {"zopf", 4} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

/* end of stage 3 Tables for HTML5 }}} */

/* {{{ Stage 2 Tables for HTML5 */

static const entity_stage2_row empty_stage2_table[] = {
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
};
static const entity_stage2_row stage2_table_html5_00000[] = {
	stage3_table_html5_00000, stage3_table_html5_00040, stage3_table_html5_00080, stage3_table_html5_000C0,
	stage3_table_html5_00100, stage3_table_html5_00140, stage3_table_html5_00180, stage3_table_html5_001C0,
	stage3_table_html5_00200, empty_stage3_table, empty_stage3_table, stage3_table_html5_002C0,
	stage3_table_html5_00300, empty_stage3_table, stage3_table_html5_00380, stage3_table_html5_003C0,
	stage3_table_html5_00400, stage3_table_html5_00440, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
};

static const entity_stage2_row stage2_table_html5_02000[] = {
	stage3_table_html5_02000, stage3_table_html5_02040, stage3_table_html5_02080, stage3_table_html5_020C0,
	stage3_table_html5_02100, stage3_table_html5_02140, stage3_table_html5_02180, stage3_table_html5_021C0,
	stage3_table_html5_02200, stage3_table_html5_02240, stage3_table_html5_02280, stage3_table_html5_022C0,
	stage3_table_html5_02300, stage3_table_html5_02340, stage3_table_html5_02380, stage3_table_html5_023C0,
	stage3_table_html5_02400, empty_stage3_table, empty_stage3_table, stage3_table_html5_024C0,
	stage3_table_html5_02500, stage3_table_html5_02540, stage3_table_html5_02580, stage3_table_html5_025C0,
	stage3_table_html5_02600, stage3_table_html5_02640, empty_stage3_table, empty_stage3_table,
	stage3_table_html5_02700, stage3_table_html5_02740, empty_stage3_table, stage3_table_html5_027C0,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	stage3_table_html5_02900, stage3_table_html5_02940, stage3_table_html5_02980, stage3_table_html5_029C0,
	stage3_table_html5_02A00, stage3_table_html5_02A40, stage3_table_html5_02A80, stage3_table_html5_02AC0,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
};

static const entity_stage2_row stage2_table_html5_0F000[] = {
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	stage3_table_html5_0FB00, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
};

static const entity_stage2_row stage2_table_html5_1D000[] = {
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, stage3_table_html5_1D480, stage3_table_html5_1D4C0,
	stage3_table_html5_1D500, stage3_table_html5_1D540, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
};

/* end of stage 2 tables for HTML5 }}} */

static const entity_stage1_row entity_ms_table_html5[] = {
	stage2_table_html5_00000,
	empty_stage2_table,
	stage2_table_html5_02000,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	stage2_table_html5_0F000,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	stage2_table_html5_1D000,
};

/* end of HTML5 multi-stage table for codepoint -> entity }}} */

/* {{{ HTML5 hash table for entity -> codepoint */

typedef struct {
	const char *entity;
	unsigned short entity_len;
	unsigned int codepoint1;
	unsigned int codepoint2;
} entity_cp_map;

typedef const entity_cp_map *entity_ht_bucket;

typedef struct {
	unsigned num_elems; /* power of 2 */
	const entity_ht_bucket *buckets; /* .num_elems elements */
} entity_ht;

static const entity_cp_map ht_bucket_empty[] = { {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_000[] = { {"realpart", 8, 0x0211C, 0}, {"varr", 4, 0x02195, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_001[] = { {"angrt", 5, 0x0221F, 0}, {"iogon", 5, 0x0012F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_003[] = { {"lessdot", 7, 0x022D6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_005[] = { {"simrarr", 7, 0x02972, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_007[] = { {"Zscr", 4, 0x1D4B5, 0}, {"midast", 6, 0x0002A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_00D[] = { {"copf", 4, 0x1D554, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_00F[] = { {"female", 6, 0x02640, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_017[] = { {"NegativeThickSpace", 18, 0x0200B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_020[] = { {"copy", 4, 0x000A9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_022[] = { {"angst", 5, 0x000C5, 0}, {"searr", 5, 0x02198, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_024[] = { {"sqcups", 6, 0x02294, 0x0FE00}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_027[] = { {"Acirc", 5, 0x000C2, 0}, {"gtdot", 5, 0x022D7, 0}, {"varpi", 5, 0x003D6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_028[] = { {"UpTee", 5, 0x022A5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_029[] = { {"TildeTilde", 10, 0x02248, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_02A[] = { {"mfr", 3, 0x1D52A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_02B[] = { {"RightVectorBar", 14, 0x02953, 0}, {"gesdot", 6, 0x02A80, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_02C[] = { {"Uarrocir", 8, 0x02949, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_02E[] = { {"RightTriangleBar", 16, 0x029D0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_030[] = { {"Ocy", 3, 0x0041E, 0}, {"int", 3, 0x0222B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_034[] = { {"preccurlyeq", 11, 0x0227C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_038[] = { {"sccue", 5, 0x0227D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_040[] = { {"DoubleContourIntegral", 21, 0x0222F, 0}, {"nexist", 6, 0x02204, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_047[] = { {"acirc", 5, 0x000E2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_04C[] = { {"setmn", 5, 0x02216, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_04E[] = { {"Dopf", 4, 0x1D53B, 0}, {"LeftTee", 7, 0x022A3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_051[] = { {"SquareSuperset", 14, 0x02290, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_059[] = { {"udhar", 5, 0x0296E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_05D[] = { {"Equal", 5, 0x02A75, 0}, {"pscr", 4, 0x1D4C5, 0}, {"xvee", 4, 0x022C1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_05F[] = { {"approx", 6, 0x02248, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_060[] = { {"HARDcy", 6, 0x0042A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_061[] = { {"nGg", 3, 0x022D9, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_063[] = { {"yopf", 4, 0x1D56A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_064[] = { {"prcue", 5, 0x0227C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_065[] = { {"loarr", 5, 0x021FD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_069[] = { {"mho", 3, 0x02127, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_06A[] = { {"otimesas", 8, 0x02A36, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_06D[] = { {"capcap", 6, 0x02A4B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_06E[] = { {"eplus", 5, 0x02A71, 0}, {"nGt", 3, 0x0226B, 0x020D2}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_06F[] = { {"Bumpeq", 6, 0x0224E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_071[] = { {"submult", 7, 0x02AC1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_073[] = { {"subplus", 7, 0x02ABF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_074[] = { {"auml", 4, 0x000E4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_07A[] = { {"RightDoubleBracket", 18, 0x027E7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_07B[] = { {"varkappa", 8, 0x003F0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_07C[] = { {"plusdo", 6, 0x02214, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_07F[] = { {"mid", 3, 0x02223, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_082[] = { {"plusdu", 6, 0x02A25, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_084[] = { {"notniva", 7, 0x0220C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_085[] = { {"notnivb", 7, 0x022FE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_086[] = { {"notnivc", 7, 0x022FD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_088[] = { {"varepsilon", 10, 0x003F5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_089[] = { {"nspar", 5, 0x02226, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_08C[] = { {"Ofr", 3, 0x1D512, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_08E[] = { {"Omega", 5, 0x003A9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_090[] = { {"equals", 6, 0x0003D, 0}, {"harrcir", 7, 0x02948, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_094[] = { {"Succeeds", 8, 0x0227B, 0}, {"cupdot", 6, 0x0228D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_097[] = { {"lsqb", 4, 0x0005B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_09E[] = { {"Qscr", 4, 0x1D4AC, 0}, {"urcorn", 6, 0x0231D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_0A4[] = { {"Zopf", 4, 0x02124, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_0A6[] = { {"triangleleft", 12, 0x025C3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_0AB[] = { {"supdsub", 7, 0x02AD8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_0AC[] = { {"chcy", 4, 0x00447, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_0AD[] = { {"sqsupset", 8, 0x02290, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_0AE[] = { {"omega", 5, 0x003C9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_0AF[] = { {"rthree", 6, 0x022CC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_0B0[] = { {"THORN", 5, 0x000DE, 0}, {"clubsuit", 8, 0x02663, 0}, {"filig", 5, 0x0FB01, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_0B2[] = { {"ocir", 4, 0x0229A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_0B8[] = { {"ShortDownArrow", 14, 0x02193, 0}, {"atilde", 6, 0x000E3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_0B9[] = { {"DownLeftTeeVector", 17, 0x0295E, 0}, {"LeftTeeArrow", 12, 0x021A4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_0BA[] = { {"GreaterFullEqual", 16, 0x02267, 0}, {"emsp", 4, 0x02003, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_0C0[] = { {"lozf", 4, 0x029EB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_0C4[] = { {"ThinSpace", 9, 0x02009, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_0CE[] = { {"fnof", 4, 0x00192, 0}, {"multimap", 8, 0x022B8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_0D1[] = { {"Zacute", 6, 0x00179, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_0D2[] = { {"mdash", 5, 0x02014, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_0D3[] = { {"minusb", 6, 0x0229F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_0D5[] = { {"minusd", 6, 0x02238, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_0DF[] = { {"varsigma", 8, 0x003C2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_0E5[] = { {"ntilde", 6, 0x000F1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_0E6[] = { {"Lambda", 6, 0x0039B, 0}, {"integers", 8, 0x02124, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_0E8[] = { {"gesles", 6, 0x02A94, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_0EC[] = { {"NotSubset", 9, 0x02282, 0x020D2}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_0EF[] = { {"NotLeftTriangleEqual", 20, 0x022EC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_0F3[] = { {"LessLess", 8, 0x02AA1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_0F4[] = { {"gscr", 4, 0x0210A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_0FA[] = { {"popf", 4, 0x1D561, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_0FB[] = { {"Agrave", 6, 0x000C0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_0FD[] = { {"nvinfin", 7, 0x029DE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_0FE[] = { {"gacute", 6, 0x001F5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_100[] = { {"diam", 4, 0x022C4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_101[] = { {"nesim", 5, 0x02242, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_103[] = { {"YIcy", 4, 0x00407, 0}, {"bcy", 3, 0x00431, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_105[] = { {"Exists", 6, 0x02203, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_106[] = { {"vert", 4, 0x0007C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_109[] = { {"ropar", 5, 0x02986, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_10A[] = { {"topfork", 7, 0x02ADA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_10B[] = { {"nLl", 3, 0x022D8, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_10D[] = { {"notin", 5, 0x02209, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_10E[] = { {"SucceedsSlantEqual", 18, 0x0227D, 0}, {"toea", 4, 0x02928, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_10F[] = { {"ImaginaryI", 10, 0x02148, 0}, {"srarr", 5, 0x02192, 0}, {"ulcorner", 8, 0x0231C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_110[] = { {"LeftArrowBar", 12, 0x021E4, 0}, {"ldsh", 4, 0x021B2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_111[] = { {"DownBreve", 9, 0x00311, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_113[] = { {"nLt", 3, 0x0226A, 0x020D2}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_116[] = { {"vltri", 5, 0x022B2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_11B[] = { {"VDash", 5, 0x022AB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_11C[] = { {"Dstrok", 6, 0x00110, 0}, {"Intersection", 12, 0x022C2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_11E[] = { {"lrhar", 5, 0x021CB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_121[] = { {"RightTee", 8, 0x022A2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_124[] = { {"RightArrowLeftArrow", 19, 0x021C4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_129[] = { {"Ccirc", 5, 0x00108, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_12A[] = { {"ntrianglelefteq", 15, 0x022EC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_12C[] = { {"leftharpoonup", 13, 0x021BC, 0}, {"scap", 4, 0x02AB8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_12E[] = { {"darr", 4, 0x02193, 0}, {"qfr", 3, 0x1D52E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_12F[] = { {"cdot", 4, 0x0010B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_130[] = { {"supseteqq", 9, 0x02AC6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_134[] = { {"Scy", 3, 0x00421, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_135[] = { {"Hscr", 4, 0x0210B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_137[] = { {"LowerRightArrow", 15, 0x02198, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_13A[] = { {"divide", 6, 0x000F7, 0}, {"tcedil", 6, 0x00163, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_13B[] = { {"LeftArrow", 9, 0x02190, 0}, {"Qopf", 4, 0x0211A, 0}, {"vDash", 5, 0x022A8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_145[] = { {"dash", 4, 0x02010, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_147[] = { {"oror", 4, 0x02A56, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_149[] = { {"ccirc", 5, 0x00109, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_14B[] = { {"LongLeftArrow", 13, 0x027F5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_14C[] = { {"straightphi", 11, 0x003D5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_14E[] = { {"xlarr", 5, 0x027F5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_14F[] = { {"DJcy", 4, 0x00402, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_158[] = { {"nbsp", 4, 0x000A0, 0}, {"succcurlyeq", 11, 0x0227D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_159[] = { {"njcy", 4, 0x0045A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_15B[] = { {"Leftarrow", 9, 0x021D0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_15E[] = { {"dtrif", 5, 0x025BE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_15F[] = { {"bfr", 3, 0x1D51F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_161[] = { {"GreaterTilde", 12, 0x02273, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_164[] = { {"hamilt", 6, 0x0210B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_165[] = { {"Dcy", 3, 0x00414, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_168[] = { {"LeftUpVector", 12, 0x021BF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_16A[] = { {"bigoplus", 8, 0x02A01, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_170[] = { {"nwarhk", 6, 0x02923, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_173[] = { {"diams", 5, 0x02666, 0}, {"suphsol", 7, 0x027C9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_17A[] = { {"boxminus", 8, 0x0229F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_17B[] = { {"leftarrow", 9, 0x02190, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_17C[] = { {"andd", 4, 0x02A5C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_17F[] = { {"NonBreakingSpace", 16, 0x000A0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_181[] = { {"xutri", 5, 0x025B3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_189[] = { {"Longleftrightarrow", 18, 0x027FA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_18B[] = { {"Longleftarrow", 13, 0x027F8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_18C[] = { {"gtrapprox", 9, 0x02A86, 0}, {"phmmat", 6, 0x02133, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_18E[] = { {"andv", 4, 0x02A5A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_18F[] = { {"equiv", 5, 0x02261, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_190[] = { {"Sfr", 3, 0x1D516, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_191[] = { {"gopf", 4, 0x1D558, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_193[] = { {"sqsub", 5, 0x0228F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_195[] = { {"approxeq", 8, 0x0224A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_19A[] = { {"Del", 3, 0x02207, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_19C[] = { {"nrightarrow", 11, 0x0219B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_19F[] = { {"SquareUnion", 11, 0x02294, 0}, {"strns", 5, 0x000AF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1A0[] = { {"Itilde", 6, 0x00128, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1A1[] = { {"sqsup", 5, 0x02290, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1A2[] = { {"Ouml", 4, 0x000D6, 0}, {"PrecedesTilde", 13, 0x0227E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1A3[] = { {"AMP", 3, 0x00026, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1A4[] = { {"plusmn", 6, 0x000B1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1A5[] = { {"xcup", 4, 0x022C3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1A8[] = { {"radic", 5, 0x0221A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1AB[] = { {"longleftarrow", 13, 0x027F5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1AC[] = { {"lrcorner", 8, 0x0231F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1AD[] = { {"notni", 5, 0x0220C, 0}, {"updownarrow", 11, 0x02195, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1AE[] = { {"szlig", 5, 0x000DF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1AF[] = { {"ugrave", 6, 0x000F9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1B0[] = { {"imof", 4, 0x022B7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1B2[] = { {"csub", 4, 0x02ACF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1B5[] = { {"gsim", 4, 0x02273, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1B9[] = { {"leftleftarrows", 14, 0x021C7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1BD[] = { {"backcong", 8, 0x0224C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1BE[] = { {"clubs", 5, 0x02663, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1C0[] = { {"csup", 4, 0x02AD0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1C1[] = { {"Dfr", 3, 0x1D507, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1C4[] = { {"profline", 8, 0x02312, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1C6[] = { {"Zdot", 4, 0x0017B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1C9[] = { {"ClockwiseContourIntegral", 24, 0x02232, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1CA[] = { {"roplus", 6, 0x02A2E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1CD[] = { {"Rang", 4, 0x027EB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1CE[] = { {"bcong", 5, 0x0224C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1D0[] = { {"tshcy", 5, 0x0045B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1D1[] = { {"eDot", 4, 0x02251, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1D2[] = { {"Hopf", 4, 0x0210D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1D4[] = { {"lpar", 4, 0x00028, 0}, {"odash", 5, 0x0229D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1D5[] = { {"capbrcup", 8, 0x02A49, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1D6[] = { {"ucy", 3, 0x00443, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1D8[] = { {"ofcir", 5, 0x029BF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1D9[] = { {"Breve", 5, 0x002D8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1DA[] = { {"barvee", 6, 0x022BD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1DF[] = { {"backsim", 7, 0x0223D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1E0[] = { {"ange", 4, 0x029A4, 0}, {"half", 4, 0x000BD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1E1[] = { {"tscr", 4, 0x1D4C9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1E5[] = { {"realine", 7, 0x0211B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1E6[] = { {"Oacute", 6, 0x000D3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1E7[] = { {"dfisht", 6, 0x0297F, 0}, {"swnwar", 6, 0x0292A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1E8[] = { {"tscy", 4, 0x00446, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1EB[] = { {"lsquor", 6, 0x0201A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1EF[] = { {"naturals", 8, 0x02115, 0}, {"utrif", 5, 0x025B4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1F0[] = { {"DiacriticalTilde", 16, 0x002DC, 0}, {"RightUpVectorBar", 16, 0x02954, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1F2[] = { {"rHar", 4, 0x02964, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1F4[] = { {"curlyeqprec", 11, 0x022DE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1F8[] = { {"dtri", 4, 0x025BF, 0}, {"euml", 4, 0x000EB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1F9[] = { {"breve", 5, 0x002D8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1FA[] = { {"Barwed", 6, 0x02306, 0}, {"nvlArr", 6, 0x02902, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1FC[] = { {"dcaron", 6, 0x0010F, 0}, {"natural", 7, 0x0266E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1FE[] = { {"nsupseteqq", 10, 0x02AC6, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_1FF[] = { {"nedot", 5, 0x02250, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_205[] = { {"bigtriangledown", 15, 0x025BD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_207[] = { {"fcy", 3, 0x00444, 0}, {"marker", 6, 0x025AE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_20E[] = { {"Union", 5, 0x022C3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_212[] = { {"varpropto", 9, 0x0221D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_213[] = { {"CloseCurlyDoubleQuote", 21, 0x0201D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_219[] = { {"DoubleLongRightArrow", 20, 0x027F9, 0}, {"GreaterGreater", 14, 0x02AA2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_21D[] = { {"Umacr", 5, 0x0016A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_220[] = { {"Colon", 5, 0x02237, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_222[] = { {"Hat", 3, 0x0005E, 0}, {"Uscr", 4, 0x1D4B0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_227[] = { {"SHCHcy", 6, 0x00429, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_229[] = { {"nLeftarrow", 10, 0x021CD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_22B[] = { {"Ecirc", 5, 0x000CA, 0}, {"Jukcy", 5, 0x00404, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_22C[] = { {"nbumpe", 6, 0x0224F, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_22D[] = { {"NotLess", 7, 0x0226E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_22F[] = { {"gtlPar", 6, 0x02995, 0}, {"suphsub", 7, 0x02AD7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_230[] = { {"gtreqqless", 10, 0x02A8C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_232[] = { {"ufr", 3, 0x1D532, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_234[] = { {"cirscir", 7, 0x029C2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_239[] = { {"LeftDownTeeVector", 17, 0x02961, 0}, {"duhar", 5, 0x0296F, 0}, {"nrtrie", 6, 0x022ED, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_23C[] = { {"llhard", 6, 0x0296B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_23D[] = { {"umacr", 5, 0x0016B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_23E[] = { {"lates", 5, 0x02AAD, 0x0FE00}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_240[] = { {"colon", 5, 0x0003A, 0}, {"iacute", 6, 0x000ED, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_241[] = { {"NotPrecedes", 11, 0x02280, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_242[] = { {"cirfnint", 8, 0x02A10, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_246[] = { {"barwedge", 8, 0x02305, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_249[] = { {"nleftarrow", 10, 0x0219A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_24A[] = { {"Ubrcy", 5, 0x0040E, 0}, {"leftthreetimes", 14, 0x022CB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_24B[] = { {"andand", 6, 0x02A55, 0}, {"ecirc", 5, 0x000EA, 0}, {"jukcy", 5, 0x00454, 0}, {"quatint", 7, 0x02A16, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_24D[] = { {"lharul", 6, 0x0296A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_251[] = { {"smtes", 5, 0x02AAC, 0x0FE00}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_252[] = { {"UnionPlus", 9, 0x0228E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_257[] = { {"NotLeftTriangle", 15, 0x022EA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_25A[] = { {"bne", 3, 0x0003D, 0x020E5}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_25B[] = { {"gtrsim", 6, 0x02273, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_25C[] = { {"Rarr", 4, 0x021A0, 0}, {"ldquor", 6, 0x0201E, 0}, {"phiv", 4, 0x003D5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_25D[] = { {"because", 7, 0x02235, 0}, {"gEl", 3, 0x02A8C, 0}, {"setminus", 8, 0x02216, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_263[] = { {"ffr", 3, 0x1D523, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_26A[] = { {"ubrcy", 5, 0x0045E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_26B[] = { {"elinters", 8, 0x023E7, 0}, {"plusb", 5, 0x0229E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_26E[] = { {"pluse", 5, 0x02A72, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_274[] = { {"CapitalDifferentialD", 20, 0x02145, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_277[] = { {"daleth", 6, 0x02138, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_278[] = { {"kscr", 4, 0x1D4C0, 0}, {"ogon", 4, 0x002DB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_27C[] = { {"SHcy", 4, 0x00428, 0}, {"equest", 6, 0x0225F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_27E[] = { {"rbarr", 5, 0x0290D, 0}, {"topf", 4, 0x1D565, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_283[] = { {"tritime", 7, 0x02A3B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_28A[] = { {"bot", 3, 0x022A5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_294[] = { {"Wfr", 3, 0x1D51A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_297[] = { {"HumpEqual", 9, 0x0224F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_298[] = { {"rightleftharpoons", 17, 0x021CC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_29D[] = { {"frasl", 5, 0x02044, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_29F[] = { {"UnderBracket", 12, 0x023B5, 0}, {"ovbar", 5, 0x0233D, 0}, {"upharpoonright", 14, 0x021BE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_2A0[] = { {"euro", 4, 0x020AC, 0}, {"nhArr", 5, 0x021CE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_2A9[] = { {"NotSupersetEqual", 16, 0x02289, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_2AE[] = { {"cularr", 6, 0x021B6, 0}, {"scnE", 4, 0x02AB6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_2B1[] = { {"napid", 5, 0x0224B, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_2B2[] = { {"harr", 4, 0x02194, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_2B3[] = { {"gdot", 4, 0x00121, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_2B9[] = { {"Lscr", 4, 0x02112, 0}, {"zeta", 4, 0x003B6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_2BF[] = { {"ENG", 3, 0x0014A, 0}, {"Uopf", 4, 0x1D54C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_2C4[] = { {"esdot", 5, 0x02250, 0}, {"scsim", 5, 0x0227F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_2C5[] = { {"Hfr", 3, 0x0210C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_2CE[] = { {"RightArrow", 10, 0x02192, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_2CF[] = { {"Sqrt", 4, 0x0221A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_2D3[] = { {"xodot", 5, 0x02A00, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_2DA[] = { {"ycy", 3, 0x0044B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_2DB[] = { {"hkswarow", 8, 0x02926, 0}, {"urtri", 5, 0x025F9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_2DC[] = { {"roang", 5, 0x027ED, 0}, {"tosa", 4, 0x02929, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_2E3[] = { {"CircleMinus", 11, 0x02296, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_2E4[] = { {"Lcaron", 6, 0x0013D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_2EB[] = { {"ShortLeftArrow", 14, 0x02190, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_2EC[] = { {"Dot", 3, 0x000A8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_2EE[] = { {"Rightarrow", 10, 0x021D2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_2F0[] = { {"prsim", 5, 0x0227E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_2F2[] = { {"notinE", 6, 0x022F9, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_2F8[] = { {"becaus", 6, 0x02235, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_300[] = { {"NotEqualTilde", 13, 0x02242, 0x00338}, {"nparallel", 9, 0x02226, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_301[] = { {"capcup", 6, 0x02A47, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_304[] = { {"simeq", 5, 0x02243, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_305[] = { {"forall", 6, 0x02200, 0}, {"straightepsilon", 15, 0x003F5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_308[] = { {"ruluhar", 7, 0x02968, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_30B[] = { {"jcy", 3, 0x00439, 0}, {"ltcc", 4, 0x02AA6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_30F[] = { {"bscr", 4, 0x1D4B7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_311[] = { {"ExponentialE", 12, 0x02147, 0}, {"weierp", 6, 0x02118, 0}, {"yen", 3, 0x000A5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_313[] = { {"blacksquare", 11, 0x025AA, 0}, {"uml", 3, 0x000A8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_315[] = { {"backsimeq", 9, 0x022CD, 0}, {"kopf", 4, 0x1D55C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_319[] = { {"NotPrecedesEqual", 16, 0x02AAF, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_31A[] = { {"simgE", 5, 0x02AA0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_31B[] = { {"tridot", 6, 0x025EC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_326[] = { {"DoubleLongLeftArrow", 19, 0x027F8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_329[] = { {"models", 6, 0x022A7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_32A[] = { {"emptyv", 6, 0x02205, 0}, {"eqslantgtr", 10, 0x02A96, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_32D[] = { {"Gcirc", 5, 0x0011C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_330[] = { {"bernou", 6, 0x0212C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_331[] = { {"HumpDownHump", 12, 0x0224E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_336[] = { {"yfr", 3, 0x1D536, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_338[] = { {"blacktriangle", 13, 0x025B4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_33B[] = { {"yacy", 4, 0x0044F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_33F[] = { {"lsime", 5, 0x02A8D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_340[] = { {"NotTildeEqual", 13, 0x02244, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_341[] = { {"lsimg", 5, 0x02A8F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_347[] = { {"ncap", 4, 0x02A43, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_34D[] = { {"DD", 2, 0x02145, 0}, {"gcirc", 5, 0x0011D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_350[] = { {"Cscr", 4, 0x1D49E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_356[] = { {"Lopf", 4, 0x1D543, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_358[] = { {"lBarr", 5, 0x0290E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_359[] = { {"Leftrightarrow", 14, 0x021D4, 0}, {"gtrdot", 6, 0x022D7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_35D[] = { {"NotSquareSubset", 15, 0x0228F, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_35F[] = { {"sqsubset", 8, 0x0228F, 0}, {"subsetneq", 9, 0x0228A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_361[] = { {"doublebarwedge", 14, 0x02306, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_363[] = { {"blacktriangleleft", 17, 0x025C2, 0}, {"hellip", 6, 0x02026, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_365[] = { {"xscr", 4, 0x1D4CD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_367[] = { {"LessFullEqual", 13, 0x02266, 0}, {"jfr", 3, 0x1D527, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_369[] = { {"GreaterSlantEqual", 17, 0x02A7E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_36A[] = { {"Uring", 5, 0x0016E, 0}, {"VeryThinSpace", 13, 0x0200A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_36B[] = { {"roarr", 5, 0x021FE, 0}, {"scaron", 6, 0x00161, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_36D[] = { {"Lcy", 3, 0x0041B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_36E[] = { {"RightDownVector", 15, 0x021C2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_36F[] = { {"Sub", 3, 0x022D0, 0}, {"pitchfork", 9, 0x022D4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_372[] = { {"nvsim", 5, 0x0223C, 0x020D2}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_374[] = { {"xrArr", 5, 0x027F9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_378[] = { {"CloseCurlyQuote", 15, 0x02019, 0}, {"uwangle", 7, 0x029A7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_37A[] = { {"Sum", 3, 0x02211, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_37C[] = { {"iuml", 4, 0x000EF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_37D[] = { {"Sup", 3, 0x022D1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_37E[] = { {"planck", 6, 0x0210F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_37F[] = { {"Egrave", 6, 0x000C8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_380[] = { {"curlywedge", 10, 0x022CF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_382[] = { {"TildeFullEqual", 14, 0x02245, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_383[] = { {"searhk", 6, 0x02925, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_386[] = { {"ETH", 3, 0x000D0, 0}, {"napos", 5, 0x00149, 0}, {"upsi", 4, 0x003C5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_387[] = { {"twoheadleftarrow", 16, 0x0219E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_38A[] = { {"Assign", 6, 0x02254, 0}, {"uring", 5, 0x0016F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_38D[] = { {"SquareIntersection", 18, 0x02293, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_38E[] = { {"lmidot", 6, 0x00140, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_391[] = { {"kcedil", 6, 0x00137, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_394[] = { {"curren", 6, 0x000A4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_397[] = { {"acute", 5, 0x000B4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_398[] = { {"curlyeqsucc", 11, 0x022DF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_39C[] = { {"Omicron", 7, 0x0039F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_39F[] = { {"uarr", 4, 0x02191, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_3A0[] = { {"Hstrok", 6, 0x00126, 0}, {"UnderBrace", 10, 0x023DF, 0}, {"tdot", 4, 0x020DB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_3A1[] = { {"qint", 4, 0x02A0C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_3A4[] = { {"sfrown", 6, 0x02322, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_3A5[] = { {"trpezium", 8, 0x023E2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_3A6[] = { {"Yscr", 4, 0x1D4B4, 0}, {"cedil", 5, 0x000B8, 0}, {"planckh", 7, 0x0210E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_3A7[] = { {"lang", 4, 0x027E8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_3AC[] = { {"bopf", 4, 0x1D553, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_3B2[] = { {"lbbrk", 5, 0x02772, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_3B4[] = { {"khcy", 4, 0x00445, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_3BF[] = { {"Epsilon", 7, 0x00395, 0}, {"simlE", 5, 0x02A9F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_3C0[] = { {"GT", 2, 0x0003E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_3C4[] = { {"nap", 3, 0x02249, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_3C9[] = { {"Lfr", 3, 0x1D50F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_3CD[] = { {"succapprox", 10, 0x02AB8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_3D0[] = { {"bsim", 4, 0x0223D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_3D3[] = { {"Gg", 2, 0x022D9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_3D9[] = { {"angrtvb", 7, 0x022BE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_3DE[] = { {"xcirc", 5, 0x025EF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_3E0[] = { {"Gt", 2, 0x0226B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_3E1[] = { {"LeftRightVector", 15, 0x0294E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_3E3[] = { {"circledast", 10, 0x0229B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_3E4[] = { {"telrec", 6, 0x02315, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_3E6[] = { {"SucceedsTilde", 13, 0x0227F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_3E9[] = { {"nLtv", 4, 0x0226A, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_3ED[] = { {"Copf", 4, 0x02102, 0}, {"napprox", 7, 0x02249, 0}, {"nsupseteq", 9, 0x02289, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_3F1[] = { {"VerticalTilde", 13, 0x02240, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_3F2[] = { {"parallel", 8, 0x02225, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_3F7[] = { {"precnapprox", 11, 0x02AB9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_3FC[] = { {"oscr", 4, 0x02134, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_3FE[] = { {"supsetneqq", 10, 0x02ACC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_402[] = { {"xopf", 4, 0x1D569, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_405[] = { {"mumap", 5, 0x022B8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_407[] = { {"varsupsetneqq", 13, 0x02ACC, 0x0FE00}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_409[] = { {"ReverseEquilibrium", 18, 0x021CB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_40E[] = { {"Ubreve", 6, 0x0016C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_40F[] = { {"YUcy", 4, 0x0042E, 0}, {"ncy", 3, 0x0043D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_413[] = { {"ltimes", 6, 0x022C9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_41A[] = { {"UpperRightArrow", 15, 0x02197, 0}, {"nvap", 4, 0x0224D, 0x020D2}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_41B[] = { {"Im", 2, 0x02111, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_421[] = { {"simne", 5, 0x02246, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_423[] = { {"ccups", 5, 0x02A4C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_424[] = { {"nlArr", 5, 0x021CD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_425[] = { {"rarrsim", 7, 0x02974, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_426[] = { {"Ncaron", 6, 0x00147, 0}, {"vsupnE", 6, 0x02ACC, 0x0FE00}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_429[] = { {"succeq", 6, 0x02AB0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_42C[] = { {"Gammad", 6, 0x003DC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_42F[] = { {"Icirc", 5, 0x000CE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_430[] = { {"backepsilon", 11, 0x003F6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_432[] = { {"ddarr", 5, 0x021CA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_436[] = { {"larr", 4, 0x02190, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_439[] = { {"divideontimes", 13, 0x022C7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_43C[] = { {"succsim", 7, 0x0227F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_43D[] = { {"Pscr", 4, 0x1D4AB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_43E[] = { {"puncsp", 6, 0x02008, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_43F[] = { {"gtreqless", 9, 0x022DB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_440[] = { {"intcal", 6, 0x022BA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_441[] = { {"nsime", 5, 0x02244, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_443[] = { {"Yopf", 4, 0x1D550, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_446[] = { {"angsph", 6, 0x02222, 0}, {"vsupne", 6, 0x0228B, 0x0FE00}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_447[] = { {"NotNestedLessLess", 17, 0x02AA1, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_44A[] = { {"PrecedesSlantEqual", 18, 0x0227C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_44F[] = { {"icirc", 5, 0x000EE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_450[] = { {"DownLeftVectorBar", 17, 0x02956, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_454[] = { {"Auml", 4, 0x000C4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_457[] = { {"LJcy", 4, 0x00409, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_458[] = { {"sqsube", 6, 0x02291, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_45D[] = { {"nprec", 5, 0x02280, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_45F[] = { {"ngE", 3, 0x02267, 0x00338}, {"smile", 5, 0x02323, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_465[] = { {"LT", 2, 0x0003C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_466[] = { {"ldrdhar", 7, 0x02967, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_469[] = { {"utri", 4, 0x025B5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_46A[] = { {"Sacute", 6, 0x0015A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_46B[] = { {"late", 4, 0x02AAD, 0}, {"nfr", 3, 0x1D52B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_46D[] = { {"NotNestedGreaterGreater", 23, 0x02AA2, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_46F[] = { {"nwarr", 5, 0x02196, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_470[] = { {"biguplus", 8, 0x02A04, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_471[] = { {"Pcy", 3, 0x0041F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_472[] = { {"bigtriangleup", 13, 0x025B3, 0}, {"rationals", 9, 0x0211A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_473[] = { {"congdot", 7, 0x02A6D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_475[] = { {"PlusMinus", 9, 0x000B1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_479[] = { {"IOcy", 4, 0x00401, 0}, {"Scedil", 6, 0x0015E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_47C[] = { {"eqcirc", 6, 0x02256, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_47D[] = { {"Ll", 2, 0x022D8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_47F[] = { {"Cayleys", 7, 0x0212D, 0}, {"nge", 3, 0x02271, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_480[] = { {"NotGreater", 10, 0x0226F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_485[] = { {"Lt", 2, 0x0226A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_488[] = { {"rotimes", 7, 0x02A35, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_48C[] = { {"caps", 4, 0x02229, 0x0FE00}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_48E[] = { {"ngt", 3, 0x0226F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_48F[] = { {"Cross", 5, 0x02A2F, 0}, {"bumpeq", 6, 0x0224F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_490[] = { {"VerticalSeparator", 17, 0x02758, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_491[] = { {"plankv", 6, 0x0210F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_493[] = { {"fscr", 4, 0x1D4BB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_495[] = { {"bsol", 4, 0x0005C, 0}, {"sqsubseteq", 10, 0x02291, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_496[] = { {"boxH", 4, 0x02550, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_498[] = { {"rightarrowtail", 14, 0x021A3, 0}, {"ufisht", 6, 0x0297E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_499[] = { {"oopf", 4, 0x1D560, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_49F[] = { {"lobrk", 5, 0x027E6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4A2[] = { {"Acy", 3, 0x00410, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4A4[] = { {"NotSubsetEqual", 14, 0x02288, 0}, {"boxV", 4, 0x02551, 0}, {"dHar", 4, 0x02965, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4A6[] = { {"precnsim", 8, 0x022E8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4A7[] = { {"Mu", 2, 0x0039C, 0}, {"aelig", 5, 0x000E6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4AA[] = { {"gescc", 5, 0x02AA9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4AB[] = { {"origof", 6, 0x022B6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4AE[] = { {"upsih", 5, 0x003D2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4AF[] = { {"cross", 5, 0x02717, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4B2[] = { {"LeftFloor", 9, 0x0230A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4B6[] = { {"boxh", 4, 0x02500, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4B8[] = { {"NotGreaterEqual", 15, 0x02271, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4BC[] = { {"profalar", 8, 0x0232E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4C0[] = { {"nsmid", 5, 0x02224, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4C2[] = { {"hbar", 4, 0x0210F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4C3[] = { {"udarr", 5, 0x021C5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4C4[] = { {"boxv", 4, 0x02502, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4C5[] = { {"olarr", 5, 0x021BA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4C8[] = { {"Nu", 2, 0x0039D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4CB[] = { {"NotCongruent", 12, 0x02262, 0}, {"bkarow", 6, 0x0290D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4CD[] = { {"Pfr", 3, 0x1D513, 0}, {"forkv", 5, 0x02AD9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4CF[] = { {"nis", 3, 0x022FC, 0}, {"trianglerighteq", 15, 0x022B5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4D0[] = { {"ngeq", 4, 0x02271, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4D2[] = { {"cudarrl", 7, 0x02938, 0}, {"nges", 4, 0x02A7E, 0x00338}, {"niv", 3, 0x0220B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4D3[] = { {"SubsetEqual", 11, 0x02286, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4D4[] = { {"Gscr", 4, 0x1D4A2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4D5[] = { {"complexes", 9, 0x02102, 0}, {"eDDot", 5, 0x02A77, 0}, {"nvge", 4, 0x02265, 0x020D2}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4D8[] = { {"cudarrr", 7, 0x02935, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4DA[] = { {"Popf", 4, 0x02119, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4DE[] = { {"LongRightArrow", 14, 0x027F6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4DF[] = { {"supseteq", 8, 0x02287, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4E3[] = { {"dollar", 6, 0x00024, 0}, {"gnsim", 5, 0x022E7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4E4[] = { {"nvgt", 4, 0x0003E, 0x020D2}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4E6[] = { {"Or", 2, 0x02A54, 0}, {"Vert", 4, 0x02016, 0}, {"lneqq", 5, 0x02268, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4E7[] = { {"nLeftrightarrow", 15, 0x021CE, 0}, {"nbump", 5, 0x0224E, 0x00338}, {"ntriangleright", 14, 0x022EB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4E8[] = { {"ecir", 4, 0x02256, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4E9[] = { {"npolint", 7, 0x02A14, 0}, {"plus", 4, 0x0002B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4ED[] = { {"centerdot", 9, 0x000B7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4F1[] = { {"zacute", 6, 0x0017A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4F7[] = { {"odiv", 4, 0x02A38, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4F9[] = { {"cap", 3, 0x02229, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4FB[] = { {"ensp", 4, 0x02002, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_4FE[] = { {"Afr", 3, 0x1D504, 0}, {"Pi", 2, 0x003A0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_500[] = { {"iquest", 6, 0x000BF, 0}, {"ltri", 4, 0x025C3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_504[] = { {"nlE", 3, 0x02266, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_506[] = { {"Phi", 3, 0x003A6, 0}, {"lambda", 6, 0x003BB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_507[] = { {"Pr", 2, 0x02ABB, 0}, {"Vdashl", 6, 0x02AE6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_509[] = { {"SuchThat", 8, 0x0220B, 0}, {"Supset", 6, 0x022D1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_50E[] = { {"Darr", 4, 0x021A1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_50F[] = { {"Cdot", 4, 0x0010A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_513[] = { {"rcy", 3, 0x00440, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_516[] = { {"orderof", 7, 0x02134, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_518[] = { {"leqq", 4, 0x02266, 0}, {"precsim", 7, 0x0227E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_519[] = { {"RightTriangle", 13, 0x022B3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_51B[] = { {"agrave", 6, 0x000E0, 0}, {"succnapprox", 11, 0x02ABA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_51C[] = { {"Tab", 3, 0x00009, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_524[] = { {"nle", 3, 0x02270, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_525[] = { {"spades", 6, 0x02660, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_526[] = { {"gtcc", 4, 0x02AA7, 0}, {"llcorner", 8, 0x0231E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_52F[] = { {"Oslash", 6, 0x000D8, 0}, {"Tau", 3, 0x003A4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_530[] = { {"fopf", 4, 0x1D557, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_532[] = { {"Mellintrf", 9, 0x02133, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_533[] = { {"nlt", 3, 0x0226E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_534[] = { {"lparlt", 6, 0x02993, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_53B[] = { {"Ccaron", 6, 0x0010C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_53C[] = { {"Re", 2, 0x0211C, 0}, {"dstrok", 6, 0x00111, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_53F[] = { {"leftharpoondown", 15, 0x021BD, 0}, {"ssetmn", 6, 0x02216, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_542[] = { {"lrhard", 6, 0x0296D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_543[] = { {"reg", 3, 0x000AE, 0}, {"sharp", 5, 0x0266F, 0}, {"yicy", 4, 0x00457, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_545[] = { {"ShortUpArrow", 12, 0x02191, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_548[] = { {"plusacir", 8, 0x02A23, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_54F[] = { {"cent", 4, 0x000A2, 0}, {"natur", 5, 0x0266E, 0}, {"varphi", 6, 0x003D5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_550[] = { {"lesg", 4, 0x022DA, 0x0FE00}, {"supnE", 5, 0x02ACC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_551[] = { {"ohbar", 5, 0x029B5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_557[] = { {"NotLessGreater", 14, 0x02278, 0}, {"nleqslant", 9, 0x02A7D, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_55B[] = { {"Sc", 2, 0x02ABC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_55D[] = { {"NotSucceedsEqual", 16, 0x02AB0, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_55F[] = { {"DZcy", 4, 0x0040F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_564[] = { {"vartheta", 8, 0x003D1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_565[] = { {"ltrie", 5, 0x022B4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_566[] = { {"Otilde", 6, 0x000D5, 0}, {"ltrif", 5, 0x025C2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_56C[] = { {"Lsh", 3, 0x021B0, 0}, {"hookleftarrow", 13, 0x021A9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_56F[] = { {"rfr", 3, 0x1D52F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_570[] = { {"supne", 5, 0x0228B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_571[] = { {"Gopf", 4, 0x1D53E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_572[] = { {"UpEquilibrium", 13, 0x0296E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_575[] = { {"Tcy", 3, 0x00422, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_576[] = { {"ffilig", 6, 0x0FB03, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_577[] = { {"fork", 4, 0x022D4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_578[] = { {"oplus", 5, 0x02295, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_57A[] = { {"nvle", 4, 0x02264, 0x020D2}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_57B[] = { {"HilbertSpace", 12, 0x0210B, 0}, {"subedot", 7, 0x02AC3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_57C[] = { {"TripleDot", 9, 0x020DB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_580[] = { {"sscr", 4, 0x1D4C8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_582[] = { {"osol", 4, 0x02298, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_583[] = { {"plustwo", 7, 0x02A27, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_586[] = { {"LessGreater", 11, 0x02276, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_588[] = { {"lrarr", 5, 0x021C6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_589[] = { {"nvlt", 4, 0x0003C, 0x020D2}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_58D[] = { {"questeq", 7, 0x0225F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_58E[] = { {"LessTilde", 9, 0x02272, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_58F[] = { {"djcy", 4, 0x00452, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_590[] = { {"xoplus", 6, 0x02A01, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_595[] = { {"primes", 6, 0x02119, 0}, {"solb", 4, 0x029C4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_596[] = { {"not", 3, 0x000AC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_59A[] = { {"angzarr", 7, 0x0237C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_59D[] = { {"nearr", 5, 0x02197, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_59F[] = { {"lowast", 6, 0x02217, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5A0[] = { {"cfr", 3, 0x1D520, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5A3[] = { {"ltcir", 5, 0x02A79, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5A6[] = { {"Ecy", 3, 0x0042D, 0}, {"gesdotol", 8, 0x02A84, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5A9[] = { {"longleftrightarrow", 18, 0x027F7, 0}, {"para", 4, 0x000B6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5AC[] = { {"Uacute", 6, 0x000DA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5AD[] = { {"blank", 5, 0x02423, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5AE[] = { {"rho", 3, 0x003C1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5B0[] = { {"dharl", 5, 0x021C3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5B1[] = { {"rsquor", 6, 0x02019, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5B5[] = { {"NotSquareSubsetEqual", 20, 0x022E2, 0}, {"npr", 3, 0x02280, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5B6[] = { {"dharr", 5, 0x021C2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5B7[] = { {"NewLine", 7, 0x0000A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5BB[] = { {"odot", 4, 0x02299, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5BC[] = { {"part", 4, 0x02202, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5BD[] = { {"cuvee", 5, 0x022CE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5BF[] = { {"lesdoto", 7, 0x02A81, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5C0[] = { {"itilde", 6, 0x00129, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5C1[] = { {"Tscr", 4, 0x1D4AF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5C2[] = { {"nsubE", 5, 0x02AC5, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5C4[] = { {"ratio", 5, 0x02236, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5D0[] = { {"Conint", 6, 0x0222F, 0}, {"LeftDownVectorBar", 17, 0x02959, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5D1[] = { {"Tfr", 3, 0x1D517, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5D3[] = { {"fllig", 5, 0x0FB02, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5D5[] = { {"thksim", 6, 0x0223C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5D8[] = { {"Euml", 4, 0x000CB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5D9[] = { {"chi", 3, 0x003C7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5DB[] = { {"ncup", 4, 0x02A42, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5DD[] = { {"SOFTcy", 6, 0x0042C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5DF[] = { {"bnequiv", 7, 0x02261, 0x020E5}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5E2[] = { {"nsube", 5, 0x02288, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5E4[] = { {"mapstoleft", 10, 0x021A4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5E7[] = { {"NotLessSlantEqual", 17, 0x02A7D, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5EA[] = { {"ldrushar", 8, 0x0294B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5ED[] = { {"Equilibrium", 11, 0x021CC, 0}, {"Uogon", 5, 0x00172, 0}, {"supsetneq", 9, 0x0228B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5F0[] = { {"Vbar", 4, 0x02AEB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5F3[] = { {"vnsub", 5, 0x02282, 0x020D2}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5F6[] = { {"Square", 6, 0x025A1, 0}, {"lessapprox", 10, 0x02A85, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5F8[] = { {"And", 3, 0x02A53, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5FA[] = { {"gesdoto", 7, 0x02A82, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_5FD[] = { {"gap", 3, 0x02A86, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_601[] = { {"nsucc", 5, 0x02281, 0}, {"thicksim", 8, 0x0223C, 0}, {"vnsup", 5, 0x02283, 0x020D2}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_602[] = { {"Efr", 3, 0x1D508, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_603[] = { {"Igrave", 6, 0x000CC, 0}, {"cir", 3, 0x025CB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_606[] = { {"Xi", 2, 0x0039E, 0}, {"oacute", 6, 0x000F3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_609[] = { {"nsc", 3, 0x02281, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_60D[] = { {"uogon", 5, 0x00173, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_613[] = { {"rharul", 6, 0x0296C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_615[] = { {"RuleDelayed", 11, 0x029F4, 0}, {"apacir", 6, 0x02A6F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_617[] = { {"jscr", 4, 0x1D4BF, 0}, {"vcy", 3, 0x00432, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_61A[] = { {"barwed", 6, 0x02305, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_61D[] = { {"sopf", 4, 0x1D564, 0}, {"thkap", 5, 0x02248, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_61F[] = { {"lesseqgtr", 9, 0x022DA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_622[] = { {"rdquor", 6, 0x0201D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_624[] = { {"Lstrok", 6, 0x00141, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_626[] = { {"Product", 7, 0x0220F, 0}, {"sqsupe", 6, 0x02292, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_628[] = { {"awconint", 8, 0x02233, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_62C[] = { {"hearts", 6, 0x02665, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_630[] = { {"rlm", 3, 0x0200F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_632[] = { {"comma", 5, 0x0002C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_636[] = { {"PartialD", 8, 0x02202, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_63A[] = { {"wedbar", 6, 0x02A5F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_63C[] = { {"oline", 5, 0x0203E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_63D[] = { {"OverBracket", 11, 0x023B4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_63E[] = { {"RBarr", 5, 0x02910, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_641[] = { {"uharl", 5, 0x021BF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_642[] = { {"leftrightsquigarrow", 19, 0x021AD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_645[] = { {"RightFloor", 10, 0x0230B, 0}, {"intprod", 7, 0x02A3C, 0}, {"vee", 3, 0x02228, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_646[] = { {"zigrarr", 7, 0x021DD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_647[] = { {"uharr", 5, 0x021BE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_648[] = { {"gcy", 3, 0x00433, 0}, {"varsubsetneq", 12, 0x0228A, 0x0FE00}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_649[] = { {"leqslant", 8, 0x02A7D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_64A[] = { {"Odblac", 6, 0x00150, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_651[] = { {"minus", 5, 0x02212, 0}, {"scpolint", 8, 0x02A13, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_652[] = { {"lrtri", 5, 0x022BF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_653[] = { {"DiacriticalGrave", 16, 0x00060, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_655[] = { {"num", 3, 0x00023, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_657[] = { {"quest", 5, 0x0003F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_658[] = { {"Kscr", 4, 0x1D4A6, 0}, {"UnderBar", 8, 0x0005F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_659[] = { {"lsquo", 5, 0x02018, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_65C[] = { {"rArr", 4, 0x021D2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_65E[] = { {"Topf", 4, 0x1D54B, 0}, {"heartsuit", 9, 0x02665, 0}, {"rBarr", 5, 0x0290F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_660[] = { {"emptyset", 8, 0x02205, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_669[] = { {"UnderParenthesis", 16, 0x023DD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_670[] = { {"dotplus", 7, 0x02214, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_671[] = { {"Psi", 3, 0x003A8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_672[] = { {"GJcy", 4, 0x00403, 0}, {"exist", 5, 0x02203, 0}, {"simplus", 7, 0x02A24, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_673[] = { {"vfr", 3, 0x1D533, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_676[] = { {"tprime", 6, 0x02034, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_678[] = { {"leftrightharpoons", 17, 0x021CB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_679[] = { {"rbrksld", 7, 0x0298E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_67D[] = { {"Ecaron", 6, 0x0011A, 0}, {"gel", 3, 0x022DB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_680[] = { {"capdot", 6, 0x02A40, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_682[] = { {"geq", 3, 0x02265, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_684[] = { {"LowerLeftArrow", 14, 0x02199, 0}, {"ges", 3, 0x02A7E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_685[] = { {"Colone", 6, 0x02A74, 0}, {"NotLessEqual", 12, 0x02270, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_68A[] = { {"nrarr", 5, 0x0219B, 0}, {"rbrkslu", 7, 0x02990, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_68C[] = { {"flat", 4, 0x0266D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_691[] = { {"there4", 6, 0x02234, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_693[] = { {"Gdot", 4, 0x00120, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_694[] = { {"ijlig", 5, 0x00133, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_696[] = { {"blacklozenge", 12, 0x029EB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_699[] = { {"Zeta", 4, 0x00396, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6A3[] = { {"duarr", 5, 0x021F5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6A4[] = { {"DotEqual", 8, 0x02250, 0}, {"dtdot", 5, 0x022F1, 0}, {"gfr", 3, 0x1D524, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6A8[] = { {"cirE", 4, 0x029C3, 0}, {"period", 6, 0x0002E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6A9[] = { {"lmoust", 6, 0x023B0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6AA[] = { {"Icy", 3, 0x00418, 0}, {"Rcaron", 6, 0x00158, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6AB[] = { {"LeftCeiling", 11, 0x02308, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6AE[] = { {"ascr", 4, 0x1D4B6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6B0[] = { {"boxtimes", 8, 0x022A0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6B4[] = { {"jopf", 4, 0x1D55B, 0}, {"ntriangleleft", 13, 0x022EA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6B6[] = { {"eqcolon", 7, 0x02255, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6B8[] = { {"rbbrk", 5, 0x02773, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6B9[] = { {"homtht", 6, 0x0223B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6BA[] = { {"ggg", 3, 0x022D9, 0}, {"seswar", 6, 0x02929, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6BC[] = { {"perp", 4, 0x022A5, 0}, {"shcy", 4, 0x00448, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6BF[] = { {"phone", 5, 0x0260E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6C0[] = { {"NotDoubleVerticalBar", 20, 0x02226, 0}, {"ngtr", 4, 0x0226F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6C4[] = { {"ThickSpace", 10, 0x0205F, 0x0200A}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6C5[] = { {"ForAll", 6, 0x02200, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6C6[] = { {"circ", 4, 0x002C6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6C7[] = { {"Verbar", 6, 0x02016, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6C8[] = { {"cire", 4, 0x02257, 0}, {"lesges", 6, 0x02A93, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6C9[] = { {"slarr", 5, 0x02190, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6CC[] = { {"RightDownTeeVector", 18, 0x0295D, 0}, {"triangleq", 9, 0x0225C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6CE[] = { {"checkmark", 9, 0x02713, 0}, {"quot", 4, 0x00022, 0}, {"suplarr", 7, 0x0297B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6D1[] = { {"Backslash", 9, 0x02216, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6D2[] = { {"fallingdotseq", 13, 0x02252, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6D4[] = { {"swArr", 5, 0x021D9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6D5[] = { {"Xfr", 3, 0x1D51B, 0}, {"lbrke", 5, 0x0298B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6D9[] = { {"jmath", 5, 0x00237, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6DA[] = { {"lmoustache", 10, 0x023B0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6DB[] = { {"DownTee", 7, 0x022A4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6DC[] = { {"reals", 5, 0x0211D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6DE[] = { {"quaternions", 11, 0x0210D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6E7[] = { {"vzigzag", 7, 0x0299A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6EB[] = { {"pound", 5, 0x000A3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6EE[] = { {"permil", 6, 0x02030, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6EF[] = { {"Bscr", 4, 0x0212C, 0}, {"lfisht", 6, 0x0297C, 0}, {"vartriangleleft", 15, 0x022B2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6F5[] = { {"Kopf", 4, 0x1D542, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6F7[] = { {"Tilde", 5, 0x0223C, 0}, {"gtrarr", 6, 0x02978, 0}, {"lAarr", 5, 0x021DA, 0}, {"opar", 4, 0x029B7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_6FB[] = { {"triangle", 8, 0x025B5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_704[] = { {"lcaron", 6, 0x0013E, 0}, {"wscr", 4, 0x1D4CC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_705[] = { {"asympeq", 7, 0x0224D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_706[] = { {"Ifr", 3, 0x02111, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_707[] = { {"DoubleDot", 9, 0x000A8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_709[] = { {"nVdash", 6, 0x022AE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_70C[] = { {"hairsp", 6, 0x0200A, 0}, {"leftrightarrows", 15, 0x021C6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_70E[] = { {"lbrace", 6, 0x0007B, 0}, {"rightarrow", 10, 0x02192, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_70F[] = { {"Dagger", 6, 0x02021, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_712[] = { {"rsh", 3, 0x021B1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_714[] = { {"eqslantless", 11, 0x02A95, 0}, {"gnapprox", 8, 0x02A8A, 0}, {"lbrack", 6, 0x0005B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_715[] = { {"uHar", 4, 0x02963, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_717[] = { {"tilde", 5, 0x002DC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_719[] = { {"complement", 10, 0x02201, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_71B[] = { {"zcy", 3, 0x00437, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_71E[] = { {"boxDL", 5, 0x02557, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_71F[] = { {"micro", 5, 0x000B5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_723[] = { {"horbar", 6, 0x02015, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_724[] = { {"boxDR", 5, 0x02554, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_727[] = { {"bsolhsub", 8, 0x027C8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_729[] = { {"ac", 2, 0x0223E, 0}, {"nvdash", 6, 0x022AC, 0}, {"precapprox", 10, 0x02AB7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_72C[] = { {"af", 2, 0x02061, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_72D[] = { {"bullet", 6, 0x02022, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_72E[] = { {"demptyv", 7, 0x029B1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_733[] = { {"geqq", 4, 0x02267, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_734[] = { {"uuarr", 5, 0x021C8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_735[] = { {"Ocirc", 5, 0x000D4, 0}, {"utdot", 5, 0x022F0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_736[] = { {"ap", 2, 0x02248, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_738[] = { {"bNot", 4, 0x02AED, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_73B[] = { {"CirclePlus", 10, 0x02295, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_73D[] = { {"glE", 3, 0x02A92, 0}, {"midcir", 6, 0x02AF0, 0}, {"rppolint", 8, 0x02A12, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_73E[] = { {"boxDl", 5, 0x02556, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_73F[] = { {"sdot", 4, 0x022C5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_744[] = { {"boxDr", 5, 0x02553, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_745[] = { {"Xscr", 4, 0x1D4B3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_749[] = { {"dlcrop", 6, 0x0230D, 0}, {"gtrless", 7, 0x02277, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_74B[] = { {"aopf", 4, 0x1D552, 0}, {"operp", 5, 0x029B9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_74C[] = { {"kcy", 3, 0x0043A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_74F[] = { {"larrfs", 6, 0x0291D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_751[] = { {"rcub", 4, 0x0007D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_754[] = { {"nrtri", 5, 0x022EB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_755[] = { {"nparsl", 6, 0x02AFD, 0x020E5}, {"ocirc", 5, 0x000F4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_759[] = { {"gla", 3, 0x02AA5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_75C[] = { {"Iuml", 4, 0x000CF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_75F[] = { {"mcomma", 6, 0x02A29, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_762[] = { {"glj", 3, 0x02AA4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_763[] = { {"Map", 3, 0x02905, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_765[] = { {"copysr", 6, 0x02117, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_766[] = { {"DownTeeArrow", 12, 0x021A7, 0}, {"Upsi", 4, 0x003D2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_768[] = { {"awint", 5, 0x02A11, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_76E[] = { {"DownRightVector", 15, 0x021C1, 0}, {"NotEqual", 8, 0x02260, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_770[] = { {"gesl", 4, 0x022DB, 0x0FE00}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_772[] = { {"NotCupCap", 9, 0x0226D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_776[] = { {"blacktriangleright", 18, 0x025B8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_777[] = { {"zfr", 3, 0x1D537, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_779[] = { {"leftrightarrow", 14, 0x02194, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_77A[] = { {"Abreve", 6, 0x00102, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_77F[] = { {"Uarr", 4, 0x0219F, 0}, {"gnE", 3, 0x02269, 0}, {"supmult", 7, 0x02AC2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_781[] = { {"supplus", 7, 0x02AC0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_783[] = { {"nabla", 5, 0x02207, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_787[] = { {"Lang", 4, 0x027EA, 0}, {"laquo", 5, 0x000AB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_789[] = { {"larrhk", 6, 0x021A9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_78C[] = { {"Bopf", 4, 0x1D539, 0}, {"lowbar", 6, 0x0005F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_78D[] = { {"cup", 3, 0x0222A, 0}, {"dd", 2, 0x02146, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_78E[] = { {"nsce", 4, 0x02AB0, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_790[] = { {"nshortparallel", 14, 0x02226, 0}, {"nsupE", 5, 0x02AC6, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_794[] = { {"OpenCurlyQuote", 14, 0x02018, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_797[] = { {"bsolb", 5, 0x029C5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_798[] = { {"DScy", 4, 0x00405, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_79A[] = { {"boxHD", 5, 0x02566, 0}, {"ltrPar", 6, 0x02996, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_79B[] = { {"nscr", 4, 0x1D4C3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_79D[] = { {"lEg", 3, 0x02A8B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_79F[] = { {"egrave", 6, 0x000E8, 0}, {"gne", 3, 0x02A88, 0}, {"larrsim", 7, 0x02973, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7A0[] = { {"COPY", 4, 0x000A9, 0}, {"bdquo", 5, 0x0201E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7A1[] = { {"wopf", 4, 0x1D568, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7A2[] = { {"NotRightTriangleEqual", 21, 0x022ED, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7A5[] = { {"robrk", 5, 0x027E7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7A8[] = { {"kfr", 3, 0x1D528, 0}, {"nlsim", 5, 0x02274, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7AA[] = { {"xhArr", 5, 0x027FA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7AB[] = { {"boxHU", 5, 0x02569, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7AC[] = { {"lHar", 4, 0x02962, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7AE[] = { {"Mcy", 3, 0x0041C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7AF[] = { {"ee", 2, 0x02147, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7B0[] = { {"nsupe", 5, 0x02289, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7B1[] = { {"eg", 2, 0x02A9A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7B5[] = { {"trade", 5, 0x02122, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7B6[] = { {"el", 2, 0x02A99, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7B7[] = { {"nsucceq", 7, 0x02AB0, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7B8[] = { {"langle", 6, 0x027E8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7BA[] = { {"boxHd", 5, 0x02564, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7BB[] = { {"Subset", 6, 0x022D0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7BD[] = { {"DownArrowBar", 12, 0x02913, 0}, {"topbot", 6, 0x02336, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7BE[] = { {"OverBrace", 9, 0x023DE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7BF[] = { {"Eta", 3, 0x00397, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7C0[] = { {"hstrok", 6, 0x00127, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7C1[] = { {"Hacek", 5, 0x002C7, 0}, {"diamond", 7, 0x022C4, 0}, {"isinsv", 6, 0x022F3, 0}, {"rtriltri", 8, 0x029CE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7C9[] = { {"nvltrie", 7, 0x022B4, 0x020D2}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7CB[] = { {"boxHu", 5, 0x02567, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7CD[] = { {"fpartint", 8, 0x02A0D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7CE[] = { {"Proportional", 12, 0x0221D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7D1[] = { {"NotSuperset", 11, 0x02283, 0x020D2}, {"gE", 2, 0x02267, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7D2[] = { {"scnsim", 6, 0x022E9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7D5[] = { {"uparrow", 7, 0x02191, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7D6[] = { {"ltlarr", 6, 0x02976, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7D9[] = { {"rtimes", 6, 0x022CA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7DA[] = { {"ncong", 5, 0x02247, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7DC[] = { {"Oscr", 4, 0x1D4AA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7E0[] = { {"vArr", 4, 0x021D5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7E2[] = { {"Xopf", 4, 0x1D54F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7E4[] = { {"notinva", 7, 0x02209, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7E5[] = { {"notinvb", 7, 0x022F7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7E6[] = { {"notinvc", 7, 0x022F6, 0}, {"nsqsube", 7, 0x022E2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7EC[] = { {"Tcaron", 6, 0x00164, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7EF[] = { {"upsilon", 7, 0x003C5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7F1[] = { {"ge", 2, 0x02265, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7F3[] = { {"gg", 2, 0x0226B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7F6[] = { {"KJcy", 4, 0x0040C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7F8[] = { {"gl", 2, 0x02277, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7FB[] = { {"dblac", 5, 0x002DD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_7FC[] = { {"lAtail", 6, 0x0291B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_800[] = { {"gt", 2, 0x0003E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_802[] = { {"lotimes", 7, 0x02A34, 0}, {"seArr", 5, 0x021D8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_803[] = { {"Lacute", 6, 0x00139, 0}, {"Laplacetrf", 10, 0x02112, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_808[] = { {"uuml", 4, 0x000FC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_809[] = { {"Amacr", 5, 0x00100, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_80A[] = { {"Mfr", 3, 0x1D510, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_810[] = { {"Int", 3, 0x0222C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_811[] = { {"Vvdash", 6, 0x022AA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_812[] = { {"Lcedil", 6, 0x0013B, 0}, {"larrlp", 6, 0x021AB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_816[] = { {"Larr", 4, 0x0219E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_819[] = { {"CircleTimes", 11, 0x02297, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_81C[] = { {"NotReverseElement", 17, 0x0220C, 0}, {"latail", 6, 0x02919, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_81D[] = { {"ntrianglerighteq", 16, 0x022ED, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_821[] = { {"blk12", 5, 0x02592, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_822[] = { {"intlarhk", 8, 0x02A17, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_823[] = { {"blk14", 5, 0x02591, 0}, {"ccupssm", 7, 0x02A50, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_824[] = { {"hercon", 6, 0x022B9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_828[] = { {"bigotimes", 9, 0x02A02, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_829[] = { {"amacr", 5, 0x00101, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_82D[] = { {"nrarrc", 6, 0x02933, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_82E[] = { {"ubreve", 6, 0x0016D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_830[] = { {"Yacute", 6, 0x000DD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_831[] = { {"ic", 2, 0x02063, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_832[] = { {"escr", 4, 0x0212F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_837[] = { {"ii", 2, 0x02148, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_838[] = { {"DownArrowUpArrow", 16, 0x021F5, 0}, {"nopf", 4, 0x1D55F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_83C[] = { {"in", 2, 0x02208, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_83E[] = { {"bumpE", 5, 0x02AAE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_83F[] = { {"rightharpoonup", 14, 0x021C0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_841[] = { {"nrarrw", 6, 0x0219D, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_842[] = { {"it", 2, 0x02062, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_846[] = { {"ncaron", 6, 0x00148, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_84A[] = { {"succnsim", 8, 0x022E9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_84C[] = { {"gammad", 6, 0x003DD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_84F[] = { {"yucy", 4, 0x0044E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_850[] = { {"ocy", 3, 0x0043E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_855[] = { {"hybull", 6, 0x02043, 0}, {"rpargt", 6, 0x02994, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_857[] = { {"csube", 5, 0x02AD1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_85B[] = { {"iiota", 5, 0x02129, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_85C[] = { {"nsim", 4, 0x02241, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_85E[] = { {"LeftTriangleEqual", 17, 0x022B4, 0}, {"bumpe", 5, 0x0224F, 0}, {"nearhk", 6, 0x02924, 0}, {"nhpar", 5, 0x02AF2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_861[] = { {"risingdotseq", 12, 0x02253, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_865[] = { {"blk34", 5, 0x02593, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_866[] = { {"LeftTriangle", 12, 0x022B2, 0}, {"vBarv", 5, 0x02AE9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_867[] = { {"AElig", 5, 0x000C6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_868[] = { {"DoubleUpDownArrow", 17, 0x021D5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_86A[] = { {"cwint", 5, 0x02231, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_86B[] = { {"rtrie", 5, 0x022B5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_86C[] = { {"rtrif", 5, 0x025B8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_873[] = { {"Fscr", 4, 0x02131, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_876[] = { {"lE", 2, 0x02266, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_879[] = { {"Oopf", 4, 0x1D546, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_87B[] = { {"spar", 4, 0x02225, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_87E[] = { {"uplus", 5, 0x0228E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_88A[] = { {"sacute", 6, 0x0015B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_88C[] = { {"fltns", 5, 0x025B1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_88E[] = { {"rrarr", 5, 0x021C9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_892[] = { {"larrpl", 6, 0x02939, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_895[] = { {"ultri", 5, 0x025F8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_896[] = { {"le", 2, 0x02264, 0}, {"xuplus", 6, 0x02A04, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_897[] = { {"ljcy", 4, 0x00459, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_898[] = { {"lg", 2, 0x02276, 0}, {"vsubnE", 6, 0x02ACB, 0x0FE00}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_899[] = { {"scedil", 6, 0x0015F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_89D[] = { {"ll", 2, 0x0226A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8A5[] = { {"lt", 2, 0x0003C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8AC[] = { {"ofr", 3, 0x1D52C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8B3[] = { {"nexists", 7, 0x02204, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8B6[] = { {"smallsetminus", 13, 0x02216, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8B7[] = { {"InvisibleComma", 14, 0x02063, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8B8[] = { {"dotminus", 8, 0x02238, 0}, {"vsubne", 6, 0x0228A, 0x0FE00}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8B9[] = { {"iocy", 4, 0x00451, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8BA[] = { {"gsime", 5, 0x02A8E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8BC[] = { {"Rarrtl", 6, 0x02916, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8BD[] = { {"cirmid", 6, 0x02AEF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8C0[] = { {"ominus", 6, 0x02296, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8C1[] = { {"gsiml", 5, 0x02A90, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8C2[] = { {"Prime", 5, 0x02033, 0}, {"mp", 2, 0x02213, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8C4[] = { {"tint", 4, 0x0222D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8C7[] = { {"mu", 2, 0x003BC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8CF[] = { {"dbkarow", 7, 0x0290F, 0}, {"eopf", 4, 0x1D556, 0}, {"ogt", 3, 0x029C1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8D0[] = { {"Precedes", 8, 0x0227A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8D3[] = { {"UpTeeArrow", 10, 0x021A5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8D6[] = { {"varsupsetneq", 12, 0x0228B, 0x0FE00}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8D8[] = { {"ne", 2, 0x02260, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8DC[] = { {"ni", 2, 0x0220B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8DD[] = { {"mDDot", 5, 0x0223A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8DE[] = { {"cularrp", 7, 0x0293D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8DF[] = { {"rnmid", 5, 0x02AEE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8E0[] = { {"hardcy", 6, 0x0044A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8E2[] = { {"prime", 5, 0x02032, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8E3[] = { {"Bcy", 3, 0x00411, 0}, {"REG", 3, 0x000AE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8E7[] = { {"oS", 2, 0x024C8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8E8[] = { {"nu", 2, 0x003BD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8E9[] = { {"ohm", 3, 0x003A9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8EB[] = { {"langd", 5, 0x02991, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8F3[] = { {"backprime", 9, 0x02035, 0}, {"esim", 4, 0x02242, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8FB[] = { {"veeeq", 5, 0x0225A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8FE[] = { {"RightCeiling", 12, 0x02309, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_8FF[] = { {"crarr", 5, 0x021B5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_904[] = { {"eqsim", 5, 0x02242, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_906[] = { {"or", 2, 0x02228, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_907[] = { {"OverParenthesis", 15, 0x023DC, 0}, {"UpperLeftArrow", 14, 0x02196, 0}, {"nleftrightarrow", 15, 0x021AE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_909[] = { {"expectation", 11, 0x02130, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_90C[] = { {"coprod", 6, 0x02210, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_90E[] = { {"Qfr", 3, 0x1D514, 0}, {"dArr", 4, 0x021D3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_910[] = { {"Fopf", 4, 0x1D53D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_913[] = { {"Cconint", 7, 0x02230, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_916[] = { {"larrtl", 6, 0x021A2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_918[] = { {"Aacute", 6, 0x000C1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_919[] = { {"DownLeftRightVector", 19, 0x02950, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_91B[] = { {"circleddash", 11, 0x0229D, 0}, {"thinsp", 6, 0x02009, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_91E[] = { {"Longrightarrow", 14, 0x027F9, 0}, {"pi", 2, 0x003C0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_91F[] = { {"hookrightarrow", 14, 0x021AA, 0}, {"rscr", 4, 0x1D4C7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_920[] = { {"scE", 3, 0x02AB4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_922[] = { {"pm", 2, 0x000B1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_923[] = { {"ZHcy", 4, 0x00416, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_927[] = { {"pr", 2, 0x0227A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_929[] = { {"LongLeftRightArrow", 18, 0x027F7, 0}, {"supset", 6, 0x02283, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_92A[] = { {"UpArrowBar", 10, 0x02912, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_92C[] = { {"Utilde", 6, 0x00168, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_92E[] = { {"xlArr", 5, 0x027F8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_930[] = { {"DoubleUpArrow", 13, 0x021D1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_936[] = { {"alefsym", 7, 0x02135, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_939[] = { {"Scirc", 5, 0x0015C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_93B[] = { {"xotime", 6, 0x02A02, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_93F[] = { {"Bfr", 3, 0x1D505, 0}, {"rdca", 4, 0x02937, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_940[] = { {"sce", 3, 0x02AB0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_945[] = { {"Nacute", 6, 0x00143, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_947[] = { {"amalg", 5, 0x02A3F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_94D[] = { {"UpDownArrow", 11, 0x02195, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_94F[] = { {"EqualTilde", 10, 0x02242, 0}, {"boxUL", 5, 0x0255D, 0}, {"oslash", 6, 0x000F8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_950[] = { {"lnap", 4, 0x02A89, 0}, {"thorn", 5, 0x000FE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_952[] = { {"ssmile", 6, 0x02323, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_953[] = { {"ndash", 5, 0x02013, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_954[] = { {"Ncedil", 6, 0x00145, 0}, {"scy", 3, 0x00441, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_955[] = { {"boxUR", 5, 0x0255A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_956[] = { {"Aring", 5, 0x000C5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_959[] = { {"scirc", 5, 0x0015D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_95B[] = { {"ccaron", 6, 0x0010D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_95D[] = { {"dotsquare", 9, 0x022A1, 0}, {"nshortmid", 9, 0x02224, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_95F[] = { {"rsquo", 5, 0x02019, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_960[] = { {"Sscr", 4, 0x1D4AE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_963[] = { {"bigwedge", 8, 0x022C0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_964[] = { {"Bernoullis", 10, 0x0212C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_969[] = { {"harrw", 5, 0x021AD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_96C[] = { {"SquareSubset", 12, 0x0228F, 0}, {"boxVH", 5, 0x0256C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_96F[] = { {"boxUl", 5, 0x0255C, 0}, {"rx", 2, 0x0211E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_970[] = { {"boxVL", 5, 0x02563, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_974[] = { {"olt", 3, 0x029C0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_975[] = { {"boxUr", 5, 0x02559, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_976[] = { {"aring", 5, 0x000E5, 0}, {"boxVR", 5, 0x02560, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_97B[] = { {"sc", 2, 0x0227B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_97C[] = { {"NestedGreaterGreater", 20, 0x0226B, 0}, {"oast", 4, 0x0229B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_97F[] = { {"star", 4, 0x02606, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_981[] = { {"LeftTeeVector", 13, 0x0295A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_983[] = { {"bigsqcup", 8, 0x02A06, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_985[] = { {"dcy", 3, 0x00434, 0}, {"preceq", 6, 0x02AAF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_986[] = { {"otilde", 6, 0x000F5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_988[] = { {"luruhar", 7, 0x02966, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_98C[] = { {"boxVh", 5, 0x0256B, 0}, {"capand", 6, 0x02A44, 0}, {"yuml", 4, 0x000FF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_98D[] = { {"Updownarrow", 11, 0x021D5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_98F[] = { {"TildeEqual", 10, 0x02243, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_990[] = { {"boxVl", 5, 0x02562, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_996[] = { {"boxVr", 5, 0x0255F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_997[] = { {"HorizontalLine", 14, 0x02500, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_99B[] = { {"xmap", 4, 0x027FC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_99C[] = { {"sigmaf", 6, 0x003C2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_99E[] = { {"EmptySmallSquare", 16, 0x025FB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_99F[] = { {"dzcy", 4, 0x0045F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9A0[] = { {"cups", 4, 0x0222A, 0x0FE00}, {"zwj", 3, 0x0200D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9A1[] = { {"beta", 4, 0x003B2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9A6[] = { {"supsim", 6, 0x02AC8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9A8[] = { {"beth", 4, 0x02136, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9AA[] = { {"Iukcy", 5, 0x00406, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9AC[] = { {"eparsl", 6, 0x029E3, 0}, {"sigmav", 6, 0x003C2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9B0[] = { {"lhard", 5, 0x021BD, 0}, {"sfr", 3, 0x1D530, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9B4[] = { {"nsqsupe", 7, 0x022E3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9B5[] = { {"Jsercy", 6, 0x00408, 0}, {"deg", 3, 0x000B0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9B6[] = { {"Ucy", 3, 0x00423, 0}, {"iscr", 4, 0x1D4BE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9B7[] = { {"efDot", 5, 0x02252, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9BB[] = { {"uhblk", 5, 0x02580, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9BC[] = { {"ropf", 4, 0x1D563, 0}, {"vprop", 5, 0x0221D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9BD[] = { {"isinE", 5, 0x022F9, 0}, {"raemptyv", 8, 0x029B3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9C1[] = { {"lharu", 5, 0x021BC, 0}, {"ncongdot", 8, 0x02A6D, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9C2[] = { {"subnE", 5, 0x02ACB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9C3[] = { {"ngsim", 5, 0x02275, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9C5[] = { {"starf", 5, 0x02605, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9C9[] = { {"Ograve", 6, 0x000D2, 0}, {"hksearow", 8, 0x02925, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9CA[] = { {"iukcy", 5, 0x00456, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9CC[] = { {"uacute", 6, 0x000FA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9CF[] = { {"asymp", 5, 0x02248, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9D5[] = { {"lneq", 4, 0x02A87, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9D6[] = { {"Otimes", 6, 0x02A37, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9DA[] = { {"NotTildeTilde", 13, 0x02249, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9DB[] = { {"Integral", 8, 0x0222B, 0}, {"rbrke", 5, 0x0298C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9DD[] = { {"nsub", 4, 0x02284, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9DE[] = { {"rlhar", 5, 0x021CC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9E1[] = { {"dfr", 3, 0x1D521, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9E2[] = { {"subne", 5, 0x0228A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9E5[] = { {"varnothing", 10, 0x02205, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9E7[] = { {"Fcy", 3, 0x00424, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9E9[] = { {"DoubleLeftTee", 13, 0x02AE4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9EB[] = { {"isins", 5, 0x022F4, 0}, {"nsup", 4, 0x02285, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9ED[] = { {"circlearrowleft", 15, 0x021BA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9EE[] = { {"isinv", 5, 0x02208, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9EF[] = { {"IEcy", 4, 0x00415, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9F0[] = { {"conint", 6, 0x0222E, 0}, {"vBar", 4, 0x02AE8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9F1[] = { {"edot", 4, 0x00117, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9F2[] = { {"Kappa", 5, 0x0039A, 0}, {"MediumSpace", 11, 0x0205F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9F3[] = { {"lbrksld", 7, 0x0298F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9F4[] = { {"sect", 4, 0x000A7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9F5[] = { {"nldr", 4, 0x02025, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9F7[] = { {"Jscr", 4, 0x1D4A5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9F9[] = { {"shy", 3, 0x000AD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9FA[] = { {"ulcrop", 6, 0x0230F, 0}, {"veebar", 6, 0x022BB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_9FD[] = { {"Sopf", 4, 0x1D54A, 0}, {"cuwed", 5, 0x022CF, 0}, {"rAarr", 5, 0x021DB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A01[] = { {"erarr", 5, 0x02971, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A04[] = { {"lbrkslu", 7, 0x0298D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A05[] = { {"NotSucceeds", 11, 0x02281, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A06[] = { {"nsccue", 6, 0x022E1, 0}, {"subrarr", 7, 0x02979, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A08[] = { {"looparrowright", 14, 0x021AC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A0C[] = { {"wp", 2, 0x02118, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A0D[] = { {"Emacr", 5, 0x00112, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A0E[] = { {"sim", 3, 0x0223C, 0}, {"wr", 2, 0x02240, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A10[] = { {"Udblac", 6, 0x00170, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A12[] = { {"Ufr", 3, 0x1D518, 0}, {"kappa", 5, 0x003BA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A14[] = { {"notindot", 8, 0x022F5, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A15[] = { {"nleq", 4, 0x02270, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A16[] = { {"NestedLessLess", 14, 0x0226A, 0}, {"square", 6, 0x025A1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A17[] = { {"nles", 4, 0x02A7D, 0x00338}, {"squarf", 6, 0x025AA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A21[] = { {"order", 5, 0x02134, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A23[] = { {"igrave", 6, 0x000EC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A24[] = { {"precneqq", 8, 0x02AB5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A25[] = { {"csupe", 5, 0x02AD2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A26[] = { {"xi", 2, 0x003BE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A28[] = { {"NotHumpEqual", 12, 0x0224F, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A2A[] = { {"ord", 3, 0x02A5D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A2D[] = { {"emacr", 5, 0x00113, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A30[] = { {"nwnear", 6, 0x02927, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A32[] = { {"nprcue", 6, 0x022E0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A36[] = { {"NotExists", 9, 0x02204, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A37[] = { {"die", 3, 0x000A8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A39[] = { {"ddotseq", 7, 0x02A77, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A3B[] = { {"Dashv", 5, 0x02AE4, 0}, {"Ucirc", 5, 0x000DB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A3C[] = { {"orv", 3, 0x02A5B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A3D[] = { {"Because", 7, 0x02235, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A41[] = { {"kgreen", 6, 0x00138, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A43[] = { {"Ffr", 3, 0x1D509, 0}, {"LeftVector", 10, 0x021BC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A44[] = { {"lstrok", 6, 0x00142, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A45[] = { {"twixt", 5, 0x0226C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A48[] = { {"compfn", 6, 0x02218, 0}, {"div", 3, 0x000F7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A4F[] = { {"drcrop", 6, 0x0230C, 0}, {"shortmid", 8, 0x02223, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A53[] = { {"iopf", 4, 0x1D55A, 0}, {"triangledown", 12, 0x025BF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A54[] = { {"IJlig", 5, 0x00132, 0}, {"thetasym", 8, 0x003D1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A56[] = { {"Sigma", 5, 0x003A3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A57[] = { {"equivDD", 7, 0x02A78, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A5A[] = { {"Cacute", 6, 0x00106, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A5B[] = { {"dashv", 5, 0x022A3, 0}, {"ucirc", 5, 0x000FB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A61[] = { {"gneqq", 5, 0x02269, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A62[] = { {"gvertneqq", 9, 0x02269, 0x0FE00}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A63[] = { {"RightDownVectorBar", 18, 0x02955, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A64[] = { {"NotLessLess", 11, 0x0226A, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A69[] = { {"Ccedil", 6, 0x000C7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A6A[] = { {"odblac", 6, 0x00151, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A6B[] = { {"mstpos", 6, 0x0223E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A6D[] = { {"cemptyv", 7, 0x029B2, 0}, {"rarrap", 6, 0x02975, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A6F[] = { {"rmoust", 6, 0x023B1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A70[] = { {"elsdot", 6, 0x02A97, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A76[] = { {"sigma", 5, 0x003C3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A78[] = { {"Implies", 7, 0x021D2, 0}, {"isin", 4, 0x02208, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A7A[] = { {"bottom", 6, 0x022A5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A7E[] = { {"ShortRightArrow", 15, 0x02192, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A81[] = { {"cupcap", 6, 0x02A46, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A82[] = { {"NotSquareSuperset", 17, 0x02290, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A84[] = { {"LeftArrowRightArrow", 19, 0x021C6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A85[] = { {"FilledVerySmallSquare", 21, 0x025AA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A86[] = { {"LeftUpTeeVector", 15, 0x02960, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A89[] = { {"DoubleRightArrow", 16, 0x021D2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A8D[] = { {"raquo", 5, 0x000BB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A8E[] = { {"Ascr", 4, 0x1D49C, 0}, {"ReverseUpEquilibrium", 20, 0x0296F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A92[] = { {"hArr", 4, 0x021D4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A94[] = { {"Jopf", 4, 0x1D541, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A96[] = { {"npar", 4, 0x02226, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A98[] = { {"SupersetEqual", 13, 0x02287, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A99[] = { {"ffllig", 6, 0x0FB04, 0}, {"smt", 3, 0x02AAA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A9A[] = { {"twoheadrightarrow", 17, 0x021A0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A9D[] = { {"ecaron", 6, 0x0011B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_A9F[] = { {"NotRightTriangleBar", 19, 0x029D0, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_AA3[] = { {"apid", 4, 0x0224B, 0}, {"vscr", 4, 0x1D4CB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_AA4[] = { {"supdot", 6, 0x02ABE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_AA5[] = { {"colone", 6, 0x02254, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_AA7[] = { {"dwangle", 7, 0x029A6, 0}, {"shchcy", 6, 0x00449, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_AAC[] = { {"ltdot", 5, 0x022D6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_AB2[] = { {"downharpoonright", 16, 0x021C2, 0}, {"gjcy", 4, 0x00453, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_AB4[] = { {"wfr", 3, 0x1D534, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_AB5[] = { {"rfisht", 6, 0x0297D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_ABA[] = { {"Ycy", 3, 0x0042B, 0}, {"swarrow", 7, 0x02199, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_AC0[] = { {"nharr", 5, 0x021AE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_AC4[] = { {"frac12", 6, 0x000BD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_AC5[] = { {"frac13", 6, 0x02153, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_AC6[] = { {"frac14", 6, 0x000BC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_AC7[] = { {"GreaterEqual", 12, 0x02265, 0}, {"frac15", 6, 0x02155, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_AC8[] = { {"Gamma", 5, 0x00393, 0}, {"frac16", 6, 0x02159, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_ACA[] = { {"dzigrarr", 8, 0x027FF, 0}, {"frac18", 6, 0x0215B, 0}, {"rcaron", 6, 0x00159, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_ACC[] = { {"DownRightTeeVector", 18, 0x0295F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_ACF[] = { {"nvrtrie", 7, 0x022B5, 0x020D2}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_AD2[] = { {"iota", 4, 0x003B9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_AD3[] = { {"sol", 3, 0x0002F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_AD4[] = { {"rbrace", 6, 0x0007D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_ADA[] = { {"rbrack", 6, 0x0005D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_ADD[] = { {"rsqb", 4, 0x0005D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_ADF[] = { {"oint", 4, 0x0222E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_AE4[] = { {"Wscr", 4, 0x1D4B2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_AE5[] = { {"hfr", 3, 0x1D525, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_AE6[] = { {"frac23", 6, 0x02154, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_AE7[] = { {"dlcorn", 6, 0x0231E, 0}, {"verbar", 6, 0x0007C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_AE8[] = { {"frac25", 6, 0x02156, 0}, {"gamma", 5, 0x003B3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_AE9[] = { {"nVDash", 6, 0x022AF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_AEB[] = { {"Jcy", 3, 0x00419, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_AF5[] = { {"nwarrow", 7, 0x02196, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_AF6[] = { {"OverBar", 7, 0x0203E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_AF7[] = { {"rightsquigarrow", 15, 0x0219D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_AFA[] = { {"iexcl", 5, 0x000A1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_AFD[] = { {"sqcap", 5, 0x02293, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_AFE[] = { {"pertenk", 7, 0x02031, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B08[] = { {"PrecedesEqual", 13, 0x02AAF, 0}, {"frac34", 6, 0x000BE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B09[] = { {"Therefore", 9, 0x02234, 0}, {"frac35", 6, 0x02157, 0}, {"nvDash", 6, 0x022AD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B0A[] = { {"odsold", 6, 0x029BC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B0C[] = { {"dot", 3, 0x002D9, 0}, {"frac38", 6, 0x0215C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B10[] = { {"sqcaps", 6, 0x02293, 0x0FE00}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B11[] = { {"ZeroWidthSpace", 14, 0x0200B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B15[] = { {"rarrfs", 6, 0x0291E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B16[] = { {"Yfr", 3, 0x1D51C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B1E[] = { {"CircleDot", 9, 0x02299, 0}, {"gtcir", 5, 0x02A7A, 0}, {"squ", 3, 0x025A1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B1F[] = { {"angmsd", 6, 0x02221, 0}, {"nsubseteq", 9, 0x02288, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B23[] = { {"iprod", 5, 0x02A3C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B24[] = { {"bprime", 6, 0x02035, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B27[] = { {"supsub", 6, 0x02AD4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B29[] = { {"SquareSupersetEqual", 19, 0x02292, 0}, {"therefore", 9, 0x02234, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B2A[] = { {"frac45", 6, 0x02158, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B2B[] = { {"Aopf", 4, 0x1D538, 0}, {"NotGreaterFullEqual", 19, 0x02267, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B2C[] = { {"Tstrok", 6, 0x00166, 0}, {"rightleftarrows", 15, 0x021C4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B2D[] = { {"Fouriertrf", 10, 0x02131, 0}, {"epar", 4, 0x022D5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B2E[] = { {"omid", 4, 0x029B6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B2F[] = { {"OpenCurlyDoubleQuote", 20, 0x0201C, 0}, {"dagger", 6, 0x02020, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B33[] = { {"semi", 4, 0x0003B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B35[] = { {"supsup", 6, 0x02AD6, 0}, {"zeetrf", 6, 0x02128, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B36[] = { {"DifferentialD", 13, 0x02146, 0}, {"topcir", 6, 0x02AF1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B3A[] = { {"mscr", 4, 0x1D4C2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B3D[] = { {"Wcirc", 5, 0x00174, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B3E[] = { {"boxdL", 5, 0x02555, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B40[] = { {"Gbreve", 6, 0x0011E, 0}, {"vopf", 4, 0x1D567, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B42[] = { {"lap", 3, 0x02A85, 0}, {"llarr", 5, 0x021C7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B44[] = { {"boxdR", 5, 0x02552, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B46[] = { {"RightAngleBracket", 17, 0x027E9, 0}, {"lat", 3, 0x02AAB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B47[] = { {"Jfr", 3, 0x1D50D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B4C[] = { {"frac56", 6, 0x0215A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B4E[] = { {"frac58", 6, 0x0215D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B4F[] = { {"rarrhk", 6, 0x021AA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B50[] = { {"lesdot", 6, 0x02A7F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B51[] = { {"ApplyFunction", 13, 0x02061, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B52[] = { {"NotGreaterTilde", 15, 0x02275, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B53[] = { {"Cedilla", 7, 0x000B8, 0}, {"curvearrowright", 15, 0x021B7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B56[] = { {"rdsh", 4, 0x021B3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B58[] = { {"larrb", 5, 0x021E4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B5C[] = { {"vrtri", 5, 0x022B3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B5D[] = { {"nequiv", 6, 0x02262, 0}, {"wcirc", 5, 0x00175, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B5E[] = { {"boxdl", 5, 0x02510, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B63[] = { {"DoubleDownArrow", 15, 0x021D3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B64[] = { {"boxdr", 5, 0x0250C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B67[] = { {"pluscir", 7, 0x02A22, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B69[] = { {"longmapsto", 10, 0x027FC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B6B[] = { {"gnap", 4, 0x02A8A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B6D[] = { {"bigodot", 7, 0x02A00, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B72[] = { {"thickapprox", 11, 0x02248, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B73[] = { {"DotDot", 6, 0x020DC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B77[] = { {"incare", 6, 0x02105, 0}, {"rarrbfs", 7, 0x02920, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B78[] = { {"apos", 4, 0x00027, 0}, {"tbrk", 4, 0x023B4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B7A[] = { {"grave", 5, 0x00060, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B7B[] = { {"Nscr", 4, 0x1D4A9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B7E[] = { {"rangle", 6, 0x027E9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B7F[] = { {"uArr", 4, 0x021D1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B81[] = { {"Wopf", 4, 0x1D54E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B82[] = { {"doteq", 5, 0x02250, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B87[] = { {"times", 5, 0x000D7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B8D[] = { {"fflig", 5, 0x0FB00, 0}, {"lcy", 3, 0x0043B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B8F[] = { {"sub", 3, 0x02282, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B90[] = { {"frac78", 6, 0x0215E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B94[] = { {"xrarr", 5, 0x027F6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B98[] = { {"UpArrowDownArrow", 16, 0x021C5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B99[] = { {"bbrktbrk", 8, 0x023B6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B9A[] = { {"abreve", 6, 0x00103, 0}, {"lsaquo", 6, 0x02039, 0}, {"sum", 3, 0x02211, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B9C[] = { {"Eacute", 6, 0x000C9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_B9D[] = { {"sup", 3, 0x02283, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BA5[] = { {"ContourIntegral", 15, 0x0222E, 0}, {"DiacriticalDot", 14, 0x002D9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BA9[] = { {"trisb", 5, 0x029CD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BAE[] = { {"Hcirc", 5, 0x00124, 0}, {"lceil", 5, 0x02308, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BB2[] = { {"Zcaron", 6, 0x0017D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BB5[] = { {"looparrowleft", 13, 0x021AB, 0}, {"oelig", 5, 0x00153, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BB6[] = { {"LessSlantEqual", 14, 0x02A7D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BB7[] = { {"NegativeThinSpace", 17, 0x0200B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BBA[] = { {"boxhD", 5, 0x02565, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BBC[] = { {"omicron", 7, 0x003BF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BBD[] = { {"leg", 3, 0x022DA, 0}, {"rightthreetimes", 15, 0x022CC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BBF[] = { {"NotSucceedsSlantEqual", 21, 0x022E1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BC1[] = { {"angmsdaa", 8, 0x029A8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BC2[] = { {"angmsdab", 8, 0x029A9, 0}, {"rAtail", 6, 0x0291C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BC3[] = { {"angmsdac", 8, 0x029AA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BC4[] = { {"angmsdad", 8, 0x029AB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BC5[] = { {"angmsdae", 8, 0x029AC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BC6[] = { {"angmsdaf", 8, 0x029AD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BC7[] = { {"angmsdag", 8, 0x029AE, 0}, {"leq", 3, 0x02264, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BC8[] = { {"angmsdah", 8, 0x029AF, 0}, {"solbar", 6, 0x0233F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BC9[] = { {"Racute", 6, 0x00154, 0}, {"les", 3, 0x02A7D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BCB[] = { {"boxhU", 5, 0x02568, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BCE[] = { {"hcirc", 5, 0x00125, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BD1[] = { {"dscr", 4, 0x1D4B9, 0}, {"smashp", 6, 0x02A33, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BD7[] = { {"mopf", 4, 0x1D55E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BD8[] = { {"Rcedil", 6, 0x00156, 0}, {"dscy", 4, 0x00455, 0}, {"prap", 4, 0x02AB7, 0}, {"rarrlp", 6, 0x021AC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BD9[] = { {"Aogon", 5, 0x00104, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BDA[] = { {"boxhd", 5, 0x0252C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BDB[] = { {"subset", 6, 0x02282, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BDD[] = { {"lgE", 3, 0x02A91, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BDF[] = { {"epsilon", 7, 0x003B5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BE1[] = { {"curarrm", 7, 0x0293C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BE2[] = { {"ratail", 6, 0x0291A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BE4[] = { {"DoubleLongLeftRightArrow", 24, 0x027FA, 0}, {"rhov", 4, 0x003F1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BE7[] = { {"LeftDoubleBracket", 17, 0x027E6, 0}, {"Lleftarrow", 10, 0x021DA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BE8[] = { {"Uuml", 4, 0x000DC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BE9[] = { {"lfr", 3, 0x1D529, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BEA[] = { {"minusdu", 7, 0x02A2A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BEB[] = { {"boxhu", 5, 0x02534, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BEF[] = { {"Ncy", 3, 0x0041D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BF0[] = { {"gneq", 4, 0x02A88, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BF1[] = { {"rangd", 5, 0x02992, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BF2[] = { {"range", 5, 0x029A5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BF3[] = { {"lfloor", 6, 0x0230A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BF7[] = { {"NotSucceedsTilde", 16, 0x0227F, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BF9[] = { {"aogon", 5, 0x00105, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BFA[] = { {"NotGreaterSlantEqual", 20, 0x02A7E, 0x00338}, {"NotSquareSupersetEqual", 22, 0x022E3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_BFC[] = { {"profsurf", 8, 0x02313, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C02[] = { {"wedgeq", 6, 0x02259, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C0B[] = { {"Alpha", 5, 0x00391, 0}, {"DiacriticalDoubleAcute", 22, 0x002DD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C0C[] = { {"lltri", 5, 0x025FA, 0}, {"tcaron", 6, 0x00165, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C11[] = { {"Imacr", 5, 0x0012A, 0}, {"subseteq", 8, 0x02286, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C12[] = { {"Escr", 4, 0x02130, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C16[] = { {"lArr", 4, 0x021D0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C18[] = { {"Nopf", 4, 0x02115, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C1A[] = { {"rpar", 4, 0x00029, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C1D[] = { {"divonx", 6, 0x022C7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C1E[] = { {"olcir", 5, 0x029BE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C23[] = { {"lacute", 6, 0x0013A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C27[] = { {"zscr", 4, 0x1D4CF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C2B[] = { {"alpha", 5, 0x003B1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C31[] = { {"imacr", 5, 0x0012B, 0}, {"vellip", 6, 0x022EE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C32[] = { {"lcedil", 6, 0x0013C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C33[] = { {"sime", 4, 0x02243, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C34[] = { {"empty", 5, 0x02205, 0}, {"imped", 5, 0x001B5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C35[] = { {"simg", 4, 0x02A9E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C36[] = { {"kjcy", 4, 0x0045C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C3A[] = { {"siml", 4, 0x02A9D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C3E[] = { {"LessEqualGreater", 16, 0x022DA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C3F[] = { {"Ycirc", 5, 0x00176, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C40[] = { {"RoundImplies", 12, 0x02970, 0}, {"nvrArr", 6, 0x02903, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C43[] = { {"check", 5, 0x02713, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C44[] = { {"nlarr", 5, 0x0219A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C46[] = { {"middot", 6, 0x000B7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C48[] = { {"par", 3, 0x02225, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C4A[] = { {"NotGreaterGreater", 17, 0x0226B, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C4B[] = { {"Nfr", 3, 0x1D511, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C4F[] = { {"nwArr", 5, 0x021D6, 0}, {"prec", 4, 0x0227A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C50[] = { {"Barv", 4, 0x02AE7, 0}, {"yacute", 6, 0x000FD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C54[] = { {"DoubleLeftRightArrow", 20, 0x021D4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C58[] = { {"Coproduct", 9, 0x02210, 0}, {"rarrpl", 6, 0x02945, 0}, {"subsim", 6, 0x02AC7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C5A[] = { {"ntgl", 4, 0x02279, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C5B[] = { {"LeftTriangleBar", 15, 0x029CF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C5F[] = { {"ycirc", 5, 0x00177, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C69[] = { {"doteqdot", 8, 0x02251, 0}, {"nang", 4, 0x02220, 0x020D2}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C6B[] = { {"bigcap", 6, 0x022C2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C6C[] = { {"CHcy", 4, 0x00427, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C6E[] = { {"dopf", 4, 0x1D555, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C72[] = { {"inodot", 6, 0x00131, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C76[] = { {"nvHarr", 6, 0x02904, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C77[] = { {"laemptyv", 8, 0x029B4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C78[] = { {"bigcirc", 7, 0x025EF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C7A[] = { {"scnap", 5, 0x02ABA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C7B[] = { {"DownLeftVector", 14, 0x021BD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C80[] = { {"race", 4, 0x0223D, 0x00331}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C82[] = { {"vartriangleright", 16, 0x022B3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C89[] = { {"napE", 4, 0x02A70, 0x00338}, {"supedot", 7, 0x02AC4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C8E[] = { {"acE", 3, 0x0223E, 0x00333}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C91[] = { {"pcy", 3, 0x0043F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C93[] = { {"qprime", 6, 0x02057, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C94[] = { {"RightTeeVector", 14, 0x0295B, 0}, {"curlyvee", 8, 0x022CE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C95[] = { {"swarhk", 6, 0x02926, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_C98[] = { {"Atilde", 6, 0x000C3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CA6[] = { {"bbrk", 4, 0x023B5, 0}, {"prnap", 5, 0x02AB9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CA8[] = { {"image", 5, 0x02111, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CA9[] = { {"sext", 4, 0x02736, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CAA[] = { {"ldquo", 5, 0x0201C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CAC[] = { {"NotLeftTriangleBar", 18, 0x029CF, 0x00338}, {"epsiv", 5, 0x003F5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CAD[] = { {"CenterDot", 9, 0x000B7, 0}, {"acd", 3, 0x0223F, 0}, {"upuparrows", 10, 0x021C8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CAF[] = { {"Eopf", 4, 0x1D53C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CB0[] = { {"Jcirc", 5, 0x00134, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CB2[] = { {"smid", 4, 0x02223, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CB4[] = { {"bull", 4, 0x02022, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CB6[] = { {"rhard", 5, 0x021C1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CB7[] = { {"nsupset", 7, 0x02283, 0x020D2}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CBA[] = { {"npre", 4, 0x02AAF, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CBE[] = { {"qscr", 4, 0x1D4C6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CC2[] = { {"acy", 3, 0x00430, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CC4[] = { {"lnE", 3, 0x02268, 0}, {"zopf", 4, 0x1D56B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CC5[] = { {"Ntilde", 6, 0x000D1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CC7[] = { {"rharu", 5, 0x021C0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CC8[] = { {"kappav", 6, 0x003F0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CC9[] = { {"timesb", 6, 0x022A0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CCB[] = { {"iiiint", 6, 0x02A0C, 0}, {"timesd", 6, 0x02A30, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CD0[] = { {"jcirc", 5, 0x00135, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CD2[] = { {"nsimeq", 6, 0x02244, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CD3[] = { {"Esim", 4, 0x02A73, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CD9[] = { {"Cap", 3, 0x022D2, 0}, {"bump", 4, 0x0224E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CDA[] = { {"lvnE", 4, 0x02268, 0x0FE00}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CDC[] = { {"rarrtl", 6, 0x021A3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CE4[] = { {"lne", 3, 0x02A87, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CE6[] = { {"commat", 6, 0x00040, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CE8[] = { {"hslash", 6, 0x0210F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CE9[] = { {"lthree", 6, 0x022CB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CED[] = { {"Gcedil", 6, 0x00122, 0}, {"pfr", 3, 0x1D52D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CF1[] = { {"RightTriangleEqual", 18, 0x022B5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CF2[] = { {"ngeqslant", 9, 0x02A7E, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CF3[] = { {"Rcy", 3, 0x00420, 0}, {"gimel", 5, 0x02137, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CF4[] = { {"curarr", 6, 0x021B7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CFA[] = { {"ntlg", 4, 0x02278, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_CFF[] = { {"Rscr", 4, 0x0211B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D00[] = { {"urcrop", 6, 0x0230E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D06[] = { {"Poincareplane", 13, 0x0210C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D07[] = { {"NoBreak", 7, 0x02060, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D0B[] = { {"lcub", 4, 0x0007B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D0E[] = { {"nltri", 5, 0x022EA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D10[] = { {"blacktriangledown", 17, 0x025BE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D11[] = { {"fjlig", 5, 0x00066, 0x0006A}, {"percnt", 6, 0x00025, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D12[] = { {"rightharpoondown", 16, 0x021C1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D13[] = { {"LeftAngleBracket", 16, 0x027E8, 0}, {"npreceq", 7, 0x02AAF, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D15[] = { {"cupcup", 6, 0x02A4A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D18[] = { {"LeftVectorBar", 13, 0x02952, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D19[] = { {"NJcy", 4, 0x0040A, 0}, {"triangleright", 13, 0x025B9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D1A[] = { {"Tcedil", 6, 0x00162, 0}, {"loz", 3, 0x025CA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D1E[] = { {"afr", 3, 0x1D51E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D1F[] = { {"NotLessTilde", 12, 0x02274, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D20[] = { {"NotElement", 10, 0x02209, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D22[] = { {"NotHumpDownHump", 15, 0x0224E, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D24[] = { {"SquareSubsetEqual", 17, 0x02291, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D26[] = { {"nleqq", 5, 0x02266, 0x00338}, {"phi", 3, 0x003C6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D2A[] = { {"NotRightTriangle", 16, 0x022EB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D32[] = { {"lhblk", 5, 0x02584, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D34[] = { {"caret", 5, 0x02041, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D35[] = { {"bsemi", 5, 0x0204F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D38[] = { {"aacute", 6, 0x000E1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D39[] = { {"mapsto", 6, 0x021A6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D3A[] = { {"Congruent", 9, 0x02261, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D3B[] = { {"Vdash", 5, 0x022A9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D3E[] = { {"longrightarrow", 14, 0x027F6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D42[] = { {"iinfin", 6, 0x029DC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D44[] = { {"EmptyVerySmallSquare", 20, 0x025AB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D49[] = { {"real", 4, 0x0211C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D4C[] = { {"SucceedsEqual", 13, 0x02AB0, 0}, {"utilde", 6, 0x00169, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D4F[] = { {"Rfr", 3, 0x0211C, 0}, {"tau", 3, 0x003C4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D51[] = { {"Wedge", 5, 0x022C0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D54[] = { {"piv", 3, 0x003D6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D55[] = { {"hscr", 4, 0x1D4BD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D56[] = { {"subdot", 6, 0x02ABD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D57[] = { {"dsol", 4, 0x029F6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D5A[] = { {"prnE", 4, 0x02AB5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D5B[] = { {"qopf", 4, 0x1D562, 0}, {"vdash", 5, 0x022A2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D5F[] = { {"Star", 4, 0x022C6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D63[] = { {"sqsupseteq", 10, 0x02292, 0}, {"zhcy", 4, 0x00436, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D65[] = { {"nacute", 6, 0x00144, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D69[] = { {"lessgtr", 7, 0x02276, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D6A[] = { {"nless", 5, 0x0226E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D6C[] = { {"RightTeeArrow", 13, 0x021A6, 0}, {"Yuml", 4, 0x00178, 0}, {"target", 6, 0x02316, 0}, {"upharpoonleft", 13, 0x021BF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D6F[] = { {"between", 7, 0x0226C, 0}, {"boxuL", 5, 0x0255B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D70[] = { {"TSHcy", 5, 0x0040B, 0}, {"lrm", 3, 0x0200E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D71[] = { {"excl", 4, 0x00021, 0}, {"hyphen", 6, 0x02010, 0}, {"mlcp", 4, 0x02ADB, 0}, {"wedge", 5, 0x02227, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D74[] = { {"ncedil", 6, 0x00146, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D75[] = { {"boxuR", 5, 0x02558, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D76[] = { {"Not", 3, 0x02AEC, 0}, {"epsi", 4, 0x003B5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D7C[] = { {"disin", 5, 0x022F2, 0}, {"nRightarrow", 11, 0x021CF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D7D[] = { {"cylcty", 6, 0x0232D, 0}, {"neArr", 5, 0x021D7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D7E[] = { {"prnsim", 6, 0x022E8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D80[] = { {"Cfr", 3, 0x0212D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D81[] = { {"Beta", 4, 0x00392, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D85[] = { {"leftarrowtail", 13, 0x021A2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D87[] = { {"parsl", 5, 0x02AFD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D89[] = { {"xwedge", 6, 0x022C0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D8A[] = { {"olcross", 7, 0x029BB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D8C[] = { {"boxvH", 5, 0x0256A, 0}, {"lsh", 3, 0x021B0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D8D[] = { {"circledR", 8, 0x000AE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D8E[] = { {"Rho", 3, 0x003A1, 0}, {"circledS", 8, 0x024C8, 0}, {"cupor", 5, 0x02A45, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D8F[] = { {"Ugrave", 6, 0x000D9, 0}, {"boxul", 5, 0x02518, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D90[] = { {"boxvL", 5, 0x02561, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D91[] = { {"sqcup", 5, 0x02294, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D93[] = { {"rect", 4, 0x025AD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D94[] = { {"mldr", 4, 0x02026, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D95[] = { {"boxur", 5, 0x02514, 0}, {"digamma", 7, 0x003DD, 0}, {"tcy", 3, 0x00442, 0}, {"urcorner", 8, 0x0231D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D96[] = { {"DoubleLeftArrow", 15, 0x021D0, 0}, {"Iscr", 4, 0x02110, 0}, {"boxvR", 5, 0x0255E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D98[] = { {"ulcorn", 6, 0x0231C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D9A[] = { {"prod", 4, 0x0220F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_D9C[] = { {"Ropf", 4, 0x0211D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DA0[] = { {"rmoustache", 10, 0x023B1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DA5[] = { {"NegativeMediumSpace", 19, 0x0200B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DA6[] = { {"prop", 4, 0x0221D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DA8[] = { {"TScy", 4, 0x00426, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DA9[] = { {"xsqcup", 6, 0x02A06, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DAC[] = { {"bemptyv", 7, 0x029B0, 0}, {"boxvh", 5, 0x0253C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DB0[] = { {"boxvl", 5, 0x02524, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DB3[] = { {"NotTildeFullEqual", 17, 0x02247, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DB4[] = { {"subE", 4, 0x02AC5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DB6[] = { {"boxvr", 5, 0x0251C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DB7[] = { {"bigvee", 6, 0x022C1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DB9[] = { {"Chi", 3, 0x003A7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DBC[] = { {"circeq", 6, 0x02257, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DBE[] = { {"emsp13", 6, 0x02004, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DBF[] = { {"emsp14", 6, 0x02005, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DC2[] = { {"ouml", 4, 0x000F6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DC3[] = { {"RightArrowBar", 13, 0x021E5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DC6[] = { {"ecy", 3, 0x0044D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DC8[] = { {"succneqq", 8, 0x02AB6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DCA[] = { {"npart", 5, 0x02202, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DCF[] = { {"Element", 7, 0x02208, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DD1[] = { {"Edot", 4, 0x00116, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DD3[] = { {"RightUpDownVector", 17, 0x0294F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DD4[] = { {"sube", 4, 0x02286, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DD5[] = { {"jsercy", 6, 0x00458, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DD7[] = { {"varrho", 6, 0x003F1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DD9[] = { {"subsub", 6, 0x02AD5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DDC[] = { {"Dcaron", 6, 0x0010E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DDD[] = { {"Eogon", 5, 0x00118, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DE4[] = { {"geqslant", 8, 0x02A7E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DE6[] = { {"rdldhar", 7, 0x02969, 0}, {"zdot", 4, 0x0017C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DE7[] = { {"subsup", 6, 0x02AD3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DE9[] = { {"ograve", 6, 0x000F2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DEB[] = { {"ReverseElement", 14, 0x0220B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DED[] = { {"drcorn", 6, 0x0231F, 0}, {"rang", 4, 0x027E9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DF1[] = { {"tfr", 3, 0x1D531, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DF2[] = { {"hopf", 4, 0x1D559, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DF3[] = { {"succ", 4, 0x0227B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DF6[] = { {"otimes", 6, 0x02297, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DF7[] = { {"Vcy", 3, 0x00412, 0}, {"ltquest", 7, 0x02A7B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DF9[] = { {"lozenge", 7, 0x025CA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DFB[] = { {"LeftDownVector", 14, 0x021C3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_DFD[] = { {"eogon", 5, 0x00119, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E03[] = { {"amp", 3, 0x00026, 0}, {"lopar", 5, 0x02985, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E04[] = { {"loplus", 6, 0x02A2D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E08[] = { {"NotTilde", 8, 0x02241, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E09[] = { {"CounterClockwiseContourIntegral", 31, 0x02233, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E0C[] = { {"InvisibleTimes", 14, 0x02062, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E11[] = { {"lesdotor", 8, 0x02A83, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E18[] = { {"and", 3, 0x02227, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E1B[] = { {"RightUpVector", 13, 0x021BE, 0}, {"ang", 3, 0x02220, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E1C[] = { {"DoubleRightTee", 14, 0x022A8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E1D[] = { {"LeftUpVectorBar", 15, 0x02958, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E1E[] = { {"smte", 4, 0x02AAC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E20[] = { {"Iacute", 6, 0x000CD, 0}, {"triminus", 8, 0x02A3A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E22[] = { {"efr", 3, 0x1D522, 0}, {"iiint", 5, 0x0222D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E23[] = { {"ctdot", 5, 0x022EF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E24[] = { {"mnplus", 6, 0x02213, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E25[] = { {"Vee", 3, 0x022C1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E28[] = { {"Gcy", 3, 0x00413, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E2A[] = { {"lurdshar", 8, 0x0294A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E2C[] = { {"smeparsl", 8, 0x029E4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E2F[] = { {"DoubleVerticalBar", 17, 0x02225, 0}, {"iecy", 4, 0x00435, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E30[] = { {"udblac", 6, 0x00171, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E32[] = { {"gtquest", 7, 0x02A7C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E33[] = { {"Iopf", 4, 0x1D540, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E35[] = { {"bsime", 5, 0x022CD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E36[] = { {"RightVector", 11, 0x021C0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E37[] = { {"NotGreaterLess", 14, 0x02279, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E3B[] = { {"apE", 3, 0x02A70, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E41[] = { {"CupCap", 6, 0x0224D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E42[] = { {"uscr", 4, 0x1D4CA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E43[] = { {"erDot", 5, 0x02253, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E44[] = { {"egs", 3, 0x02A96, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E48[] = { {"rlarr", 5, 0x021C4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E4C[] = { {"prE", 3, 0x02AB3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E4E[] = { {"QUOT", 4, 0x00022, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E53[] = { {"Vfr", 3, 0x1D519, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E55[] = { {"cupbrcap", 8, 0x02A48, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E57[] = { {"intercal", 8, 0x022BA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E58[] = { {"imath", 5, 0x00131, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E59[] = { {"RightUpTeeVector", 16, 0x0295C, 0}, {"trie", 4, 0x0225C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E5B[] = { {"ape", 3, 0x0224A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E5D[] = { {"softcy", 6, 0x0044C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E5E[] = { {"rarrb", 5, 0x021E5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E5F[] = { {"FilledSmallSquare", 17, 0x025FC, 0}, {"rarrc", 5, 0x02933, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E60[] = { {"Superset", 8, 0x02283, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E61[] = { {"hoarr", 5, 0x021FF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E63[] = { {"DownRightVectorBar", 18, 0x02957, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E64[] = { {"brvbar", 6, 0x000A6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E65[] = { {"ecolon", 6, 0x02255, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E66[] = { {"GreaterLess", 11, 0x02277, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E6A[] = { {"nrArr", 5, 0x021CF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E6C[] = { {"pre", 3, 0x02AAF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E6F[] = { {"aleph", 5, 0x02135, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E70[] = { {"DiacriticalAcute", 16, 0x000B4, 0}, {"SmallCircle", 11, 0x02218, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E71[] = { {"parsim", 6, 0x02AF3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E73[] = { {"rarrw", 5, 0x0219D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E78[] = { {"caron", 5, 0x002C7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E7A[] = { {"cacute", 6, 0x00107, 0}, {"lagran", 6, 0x02112, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E7C[] = { {"rarr", 4, 0x02192, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E80[] = { {"Rrightarrow", 11, 0x021DB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E83[] = { {"Vscr", 4, 0x1D4B1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E84[] = { {"Gfr", 3, 0x1D50A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E89[] = { {"ccedil", 6, 0x000E7, 0}, {"propto", 6, 0x0221D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E8E[] = { {"zwnj", 4, 0x0200C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E91[] = { {"psi", 3, 0x003C8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E99[] = { {"infin", 5, 0x0221E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_E9C[] = { {"circledcirc", 11, 0x0229A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_EA1[] = { {"Proportion", 10, 0x02237, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_EA2[] = { {"subseteqq", 9, 0x02AC5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_EA4[] = { {"nGtv", 4, 0x0226B, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_EA8[] = { {"macr", 4, 0x000AF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_EA9[] = { {"orslope", 7, 0x02A57, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_EB1[] = { {"frown", 5, 0x02322, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_EB2[] = { {"Iota", 4, 0x00399, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_EB4[] = { {"rceil", 5, 0x02309, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_EB7[] = { {"spadesuit", 9, 0x02660, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_EB8[] = { {"sstarf", 6, 0x022C6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_ECA[] = { {"icy", 3, 0x00438, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_ECD[] = { {"ast", 3, 0x0002A, 0}, {"nmid", 4, 0x02224, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_ECF[] = { {"bowtie", 6, 0x022C8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_ED1[] = { {"thetav", 6, 0x003D1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_ED7[] = { {"vangrt", 6, 0x0299C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_ED8[] = { {"numsp", 5, 0x02007, 0}, {"triplus", 7, 0x02A39, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_ED9[] = { {"lscr", 4, 0x1D4C1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_EDA[] = { {"pointint", 8, 0x02A15, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_EDB[] = { {"Theta", 5, 0x00398, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_EDF[] = { {"rightrightarrows", 16, 0x021C9, 0}, {"uopf", 4, 0x1D566, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_EE2[] = { {"ell", 3, 0x02113, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_EE4[] = { {"cuepr", 5, 0x022DE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_EE5[] = { {"NotVerticalBar", 14, 0x02224, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_EE7[] = { {"xnis", 4, 0x022FB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_EE9[] = { {"els", 3, 0x02A95, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_EEF[] = { {"DDotrahd", 8, 0x02911, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_EF1[] = { {"larrbfs", 7, 0x0291F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_EF2[] = { {"Rsh", 3, 0x021B1, 0}, {"boxplus", 7, 0x0229E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_EF4[] = { {"swarr", 5, 0x02199, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_EF5[] = { {"gvnE", 4, 0x02269, 0x0FE00}, {"xfr", 3, 0x1D535, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_EF9[] = { {"ldca", 4, 0x02936, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_EFB[] = { {"NotPrecedesSlantEqual", 21, 0x022E0, 0}, {"YAcy", 4, 0x0042F, 0}, {"Zcy", 3, 0x00417, 0}, {"andslope", 8, 0x02A58, 0}, {"numero", 6, 0x02116, 0}, {"theta", 5, 0x003B8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_EFE[] = { {"mapstoup", 8, 0x021A5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_EFF[] = { {"bigcup", 6, 0x022C3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F03[] = { {"nesear", 6, 0x02928, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F05[] = { {"lesssim", 7, 0x02272, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F08[] = { {"DownArrow", 9, 0x02193, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F0B[] = { {"orarr", 5, 0x021BB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F0F[] = { {"ccaps", 5, 0x02A4D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F10[] = { {"xdtri", 5, 0x025BD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F11[] = { {"xcap", 4, 0x022C2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F13[] = { {"downdownarrows", 14, 0x021CA, 0}, {"nisd", 4, 0x022FA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F14[] = { {"VerticalBar", 11, 0x02223, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F15[] = { {"TRADE", 5, 0x02122, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F17[] = { {"Omacr", 5, 0x0014C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F18[] = { {"top", 3, 0x022A4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F19[] = { {"LeftRightArrow", 14, 0x02194, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F1A[] = { {"Mscr", 4, 0x02133, 0}, {"iff", 3, 0x021D4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F1F[] = { {"downharpoonleft", 15, 0x021C3, 0}, {"eng", 3, 0x0014B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F20[] = { {"Vopf", 4, 0x1D54D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F26[] = { {"ifr", 3, 0x1D526, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F28[] = { {"Downarrow", 9, 0x021D3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F2C[] = { {"Kcy", 3, 0x0041A, 0}, {"angle", 5, 0x02220, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F2F[] = { {"lescc", 5, 0x02AA8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F30[] = { {"lesseqqgtr", 10, 0x02A8B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F31[] = { {"bigstar", 7, 0x02605, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F33[] = { {"ddagger", 7, 0x02021, 0}, {"nltrie", 6, 0x022EC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F37[] = { {"omacr", 5, 0x0014D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F38[] = { {"cuesc", 5, 0x022DF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F40[] = { {"circlearrowright", 16, 0x021BB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F41[] = { {"ngeqq", 5, 0x02267, 0x00338}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F44[] = { {"squf", 4, 0x025AA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F46[] = { {"rtri", 4, 0x025B9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F47[] = { {"VerticalLine", 12, 0x0007C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F48[] = { {"downarrow", 9, 0x02193, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F4B[] = { {"Scaron", 6, 0x00160, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F4C[] = { {"tstrok", 6, 0x00167, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F50[] = { {"wreath", 6, 0x02240, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F51[] = { {"exponentiale", 12, 0x02147, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F55[] = { {"Idot", 4, 0x00130, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F57[] = { {"Zfr", 3, 0x02128, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F58[] = { {"bnot", 4, 0x02310, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F5B[] = { {"infintie", 8, 0x029DD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F5D[] = { {"angrtvbd", 8, 0x0299D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F5F[] = { {"prurel", 6, 0x022B0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F60[] = { {"gbreve", 6, 0x0011F, 0}, {"rsaquo", 6, 0x0203A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F62[] = { {"sung", 4, 0x0266A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F67[] = { {"lvertneqq", 9, 0x02268, 0x0FE00}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F68[] = { {"lnsim", 5, 0x022E6, 0}, {"searrow", 7, 0x02198, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F69[] = { {"nsubset", 7, 0x02282, 0x020D2}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F6D[] = { {"Cup", 3, 0x022D3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F6E[] = { {"Lmidot", 6, 0x0013F, 0}, {"sup1", 4, 0x000B9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F6F[] = { {"Delta", 5, 0x00394, 0}, {"sbquo", 5, 0x0201A, 0}, {"sup2", 4, 0x000B2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F70[] = { {"cscr", 4, 0x1D4B8, 0}, {"nsubseteqq", 10, 0x02AC5, 0x00338}, {"sup3", 4, 0x000B3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F71[] = { {"Kcedil", 6, 0x00136, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F72[] = { {"plussim", 7, 0x02A26, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F74[] = { {"KHcy", 4, 0x00425, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F75[] = { {"OElig", 5, 0x00152, 0}, {"simdot", 6, 0x02A6A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F76[] = { {"lopf", 4, 0x1D55D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F77[] = { {"boxbox", 6, 0x029C9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F78[] = { {"bepsi", 5, 0x003F6, 0}, {"lbarr", 5, 0x0290C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F79[] = { {"lnapprox", 8, 0x02A89, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F81[] = { {"sdotb", 5, 0x022A1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F82[] = { {"measuredangle", 13, 0x02221, 0}, {"supE", 4, 0x02AC6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F83[] = { {"map", 3, 0x021A6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F84[] = { {"sdote", 5, 0x02A66, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F86[] = { {"diamondsuit", 11, 0x02666, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F88[] = { {"Kfr", 3, 0x1D50E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F8B[] = { {"imagline", 8, 0x02110, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F8F[] = { {"delta", 5, 0x003B4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F91[] = { {"mapstodown", 10, 0x021A7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F93[] = { {"eqvparsl", 8, 0x029E5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F95[] = { {"UpArrow", 7, 0x02191, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F9A[] = { {"imagpart", 8, 0x02111, 0}, {"lsim", 4, 0x02272, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F9C[] = { {"trianglelefteq", 14, 0x022B4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_F9F[] = { {"isindot", 7, 0x022F5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FA0[] = { {"LeftUpDownVector", 16, 0x02951, 0}, {"curvearrowleft", 14, 0x021B6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FA1[] = { {"Diamond", 7, 0x022C4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FA2[] = { {"supe", 4, 0x02287, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FA3[] = { {"nearrow", 7, 0x02197, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FA9[] = { {"easter", 6, 0x02A6E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FB0[] = { {"rdquo", 5, 0x0201D, 0}, {"subsetneqq", 10, 0x02ACB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FB1[] = { {"Dscr", 4, 0x1D49F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FB4[] = { {"comp", 4, 0x02201, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FB5[] = { {"Uparrow", 7, 0x021D1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FB6[] = { {"coloneq", 7, 0x02254, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FB7[] = { {"Mopf", 4, 0x1D544, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FB9[] = { {"rfloor", 6, 0x0230B, 0}, {"varsubsetneqq", 13, 0x02ACB, 0x0FE00}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FBC[] = { {"eacute", 6, 0x000E9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FC2[] = { {"shortparallel", 13, 0x02225, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FC4[] = { {"male", 4, 0x02642, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FC6[] = { {"yscr", 4, 0x1D4CE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FCA[] = { {"xharr", 5, 0x027F7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FCC[] = { {"cong", 4, 0x02245, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FCE[] = { {"mcy", 3, 0x0043C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FCF[] = { {"Upsilon", 7, 0x003A5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FD0[] = { {"block", 5, 0x02588, 0}, {"maltese", 7, 0x02720, 0}, {"ordf", 4, 0x000AA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FD2[] = { {"zcaron", 6, 0x0017E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FD3[] = { {"malt", 4, 0x02720, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FD6[] = { {"loang", 5, 0x027EC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FD7[] = { {"ordm", 4, 0x000BA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FDD[] = { {"NegativeVeryThinSpace", 21, 0x0200B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FDF[] = { {"eta", 3, 0x003B7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FE1[] = { {"Iogon", 5, 0x0012E, 0}, {"drbkarow", 8, 0x02910, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FE6[] = { {"eth", 3, 0x000F0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FE9[] = { {"racute", 6, 0x00155, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FEA[] = { {"cwconint", 8, 0x02232, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FEB[] = { {"egsdot", 6, 0x02A98, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FF5[] = { {"MinusPlus", 9, 0x02213, 0}, {"ring", 4, 0x002DA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FF8[] = { {"rcedil", 6, 0x00157, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FFC[] = { {"timesbar", 8, 0x02A31, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html5_FFE[] = { {"GreaterEqualLess", 16, 0x022DB, 0}, {NULL, 0, 0, 0} };

static const entity_cp_map *const ht_buckets_html5[] = {
	ht_bucket_html5_000, ht_bucket_html5_001, ht_bucket_empty, ht_bucket_html5_003,
	ht_bucket_empty, ht_bucket_html5_005, ht_bucket_empty, ht_bucket_html5_007,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_00D, ht_bucket_empty, ht_bucket_html5_00F,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_017,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_020, ht_bucket_empty, ht_bucket_html5_022, ht_bucket_empty,
	ht_bucket_html5_024, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_027,
	ht_bucket_html5_028, ht_bucket_html5_029, ht_bucket_html5_02A, ht_bucket_html5_02B,
	ht_bucket_html5_02C, ht_bucket_empty, ht_bucket_html5_02E, ht_bucket_empty,
	ht_bucket_html5_030, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_034, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_038, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_040, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_047,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_04C, ht_bucket_empty, ht_bucket_html5_04E, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_051, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_059, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_05D, ht_bucket_empty, ht_bucket_html5_05F,
	ht_bucket_html5_060, ht_bucket_html5_061, ht_bucket_empty, ht_bucket_html5_063,
	ht_bucket_html5_064, ht_bucket_html5_065, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_069, ht_bucket_html5_06A, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_06D, ht_bucket_html5_06E, ht_bucket_html5_06F,
	ht_bucket_empty, ht_bucket_html5_071, ht_bucket_empty, ht_bucket_html5_073,
	ht_bucket_html5_074, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_07A, ht_bucket_html5_07B,
	ht_bucket_html5_07C, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_07F,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_082, ht_bucket_empty,
	ht_bucket_html5_084, ht_bucket_html5_085, ht_bucket_html5_086, ht_bucket_empty,
	ht_bucket_html5_088, ht_bucket_html5_089, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_08C, ht_bucket_empty, ht_bucket_html5_08E, ht_bucket_empty,
	ht_bucket_html5_090, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_094, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_097,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_09E, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_0A4, ht_bucket_empty, ht_bucket_html5_0A6, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_0AB,
	ht_bucket_html5_0AC, ht_bucket_html5_0AD, ht_bucket_html5_0AE, ht_bucket_html5_0AF,
	ht_bucket_html5_0B0, ht_bucket_empty, ht_bucket_html5_0B2, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_0B8, ht_bucket_html5_0B9, ht_bucket_html5_0BA, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_0C0, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_0C4, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_0CE, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_0D1, ht_bucket_html5_0D2, ht_bucket_html5_0D3,
	ht_bucket_empty, ht_bucket_html5_0D5, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_0DF,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_0E5, ht_bucket_html5_0E6, ht_bucket_empty,
	ht_bucket_html5_0E8, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_0EC, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_0EF,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_0F3,
	ht_bucket_html5_0F4, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_0FA, ht_bucket_html5_0FB,
	ht_bucket_empty, ht_bucket_html5_0FD, ht_bucket_html5_0FE, ht_bucket_empty,
	ht_bucket_html5_100, ht_bucket_html5_101, ht_bucket_empty, ht_bucket_html5_103,
	ht_bucket_empty, ht_bucket_html5_105, ht_bucket_html5_106, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_109, ht_bucket_html5_10A, ht_bucket_html5_10B,
	ht_bucket_empty, ht_bucket_html5_10D, ht_bucket_html5_10E, ht_bucket_html5_10F,
	ht_bucket_html5_110, ht_bucket_html5_111, ht_bucket_empty, ht_bucket_html5_113,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_116, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_11B,
	ht_bucket_html5_11C, ht_bucket_empty, ht_bucket_html5_11E, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_121, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_124, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_129, ht_bucket_html5_12A, ht_bucket_empty,
	ht_bucket_html5_12C, ht_bucket_empty, ht_bucket_html5_12E, ht_bucket_html5_12F,
	ht_bucket_html5_130, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_134, ht_bucket_html5_135, ht_bucket_empty, ht_bucket_html5_137,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_13A, ht_bucket_html5_13B,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_145, ht_bucket_empty, ht_bucket_html5_147,
	ht_bucket_empty, ht_bucket_html5_149, ht_bucket_empty, ht_bucket_html5_14B,
	ht_bucket_html5_14C, ht_bucket_empty, ht_bucket_html5_14E, ht_bucket_html5_14F,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_158, ht_bucket_html5_159, ht_bucket_empty, ht_bucket_html5_15B,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_15E, ht_bucket_html5_15F,
	ht_bucket_empty, ht_bucket_html5_161, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_164, ht_bucket_html5_165, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_168, ht_bucket_empty, ht_bucket_html5_16A, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_170, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_173,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_17A, ht_bucket_html5_17B,
	ht_bucket_html5_17C, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_17F,
	ht_bucket_empty, ht_bucket_html5_181, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_189, ht_bucket_empty, ht_bucket_html5_18B,
	ht_bucket_html5_18C, ht_bucket_empty, ht_bucket_html5_18E, ht_bucket_html5_18F,
	ht_bucket_html5_190, ht_bucket_html5_191, ht_bucket_empty, ht_bucket_html5_193,
	ht_bucket_empty, ht_bucket_html5_195, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_19A, ht_bucket_empty,
	ht_bucket_html5_19C, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_19F,
	ht_bucket_html5_1A0, ht_bucket_html5_1A1, ht_bucket_html5_1A2, ht_bucket_html5_1A3,
	ht_bucket_html5_1A4, ht_bucket_html5_1A5, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_1A8, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_1AB,
	ht_bucket_html5_1AC, ht_bucket_html5_1AD, ht_bucket_html5_1AE, ht_bucket_html5_1AF,
	ht_bucket_html5_1B0, ht_bucket_empty, ht_bucket_html5_1B2, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_1B5, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_1B9, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_1BD, ht_bucket_html5_1BE, ht_bucket_empty,
	ht_bucket_html5_1C0, ht_bucket_html5_1C1, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_1C4, ht_bucket_empty, ht_bucket_html5_1C6, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_1C9, ht_bucket_html5_1CA, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_1CD, ht_bucket_html5_1CE, ht_bucket_empty,
	ht_bucket_html5_1D0, ht_bucket_html5_1D1, ht_bucket_html5_1D2, ht_bucket_empty,
	ht_bucket_html5_1D4, ht_bucket_html5_1D5, ht_bucket_html5_1D6, ht_bucket_empty,
	ht_bucket_html5_1D8, ht_bucket_html5_1D9, ht_bucket_html5_1DA, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_1DF,
	ht_bucket_html5_1E0, ht_bucket_html5_1E1, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_1E5, ht_bucket_html5_1E6, ht_bucket_html5_1E7,
	ht_bucket_html5_1E8, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_1EB,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_1EF,
	ht_bucket_html5_1F0, ht_bucket_empty, ht_bucket_html5_1F2, ht_bucket_empty,
	ht_bucket_html5_1F4, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_1F8, ht_bucket_html5_1F9, ht_bucket_html5_1FA, ht_bucket_empty,
	ht_bucket_html5_1FC, ht_bucket_empty, ht_bucket_html5_1FE, ht_bucket_html5_1FF,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_205, ht_bucket_empty, ht_bucket_html5_207,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_20E, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_212, ht_bucket_html5_213,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_219, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_21D, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_220, ht_bucket_empty, ht_bucket_html5_222, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_227,
	ht_bucket_empty, ht_bucket_html5_229, ht_bucket_empty, ht_bucket_html5_22B,
	ht_bucket_html5_22C, ht_bucket_html5_22D, ht_bucket_empty, ht_bucket_html5_22F,
	ht_bucket_html5_230, ht_bucket_empty, ht_bucket_html5_232, ht_bucket_empty,
	ht_bucket_html5_234, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_239, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_23C, ht_bucket_html5_23D, ht_bucket_html5_23E, ht_bucket_empty,
	ht_bucket_html5_240, ht_bucket_html5_241, ht_bucket_html5_242, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_246, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_249, ht_bucket_html5_24A, ht_bucket_html5_24B,
	ht_bucket_empty, ht_bucket_html5_24D, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_251, ht_bucket_html5_252, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_257,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_25A, ht_bucket_html5_25B,
	ht_bucket_html5_25C, ht_bucket_html5_25D, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_263,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_26A, ht_bucket_html5_26B,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_26E, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_274, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_277,
	ht_bucket_html5_278, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_27C, ht_bucket_empty, ht_bucket_html5_27E, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_283,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_28A, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_294, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_297,
	ht_bucket_html5_298, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_29D, ht_bucket_empty, ht_bucket_html5_29F,
	ht_bucket_html5_2A0, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_2A9, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_2AE, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_2B1, ht_bucket_html5_2B2, ht_bucket_html5_2B3,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_2B9, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_2BF,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_2C4, ht_bucket_html5_2C5, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_2CE, ht_bucket_html5_2CF,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_2D3,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_2DA, ht_bucket_html5_2DB,
	ht_bucket_html5_2DC, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_2E3,
	ht_bucket_html5_2E4, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_2EB,
	ht_bucket_html5_2EC, ht_bucket_empty, ht_bucket_html5_2EE, ht_bucket_empty,
	ht_bucket_html5_2F0, ht_bucket_empty, ht_bucket_html5_2F2, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_2F8, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_300, ht_bucket_html5_301, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_304, ht_bucket_html5_305, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_308, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_30B,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_30F,
	ht_bucket_empty, ht_bucket_html5_311, ht_bucket_empty, ht_bucket_html5_313,
	ht_bucket_empty, ht_bucket_html5_315, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_319, ht_bucket_html5_31A, ht_bucket_html5_31B,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_326, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_329, ht_bucket_html5_32A, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_32D, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_330, ht_bucket_html5_331, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_336, ht_bucket_empty,
	ht_bucket_html5_338, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_33B,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_33F,
	ht_bucket_html5_340, ht_bucket_html5_341, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_347,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_34D, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_350, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_356, ht_bucket_empty,
	ht_bucket_html5_358, ht_bucket_html5_359, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_35D, ht_bucket_empty, ht_bucket_html5_35F,
	ht_bucket_empty, ht_bucket_html5_361, ht_bucket_empty, ht_bucket_html5_363,
	ht_bucket_empty, ht_bucket_html5_365, ht_bucket_empty, ht_bucket_html5_367,
	ht_bucket_empty, ht_bucket_html5_369, ht_bucket_html5_36A, ht_bucket_html5_36B,
	ht_bucket_empty, ht_bucket_html5_36D, ht_bucket_html5_36E, ht_bucket_html5_36F,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_372, ht_bucket_empty,
	ht_bucket_html5_374, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_378, ht_bucket_empty, ht_bucket_html5_37A, ht_bucket_empty,
	ht_bucket_html5_37C, ht_bucket_html5_37D, ht_bucket_html5_37E, ht_bucket_html5_37F,
	ht_bucket_html5_380, ht_bucket_empty, ht_bucket_html5_382, ht_bucket_html5_383,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_386, ht_bucket_html5_387,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_38A, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_38D, ht_bucket_html5_38E, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_391, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_394, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_397,
	ht_bucket_html5_398, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_39C, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_39F,
	ht_bucket_html5_3A0, ht_bucket_html5_3A1, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_3A4, ht_bucket_html5_3A5, ht_bucket_html5_3A6, ht_bucket_html5_3A7,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_3AC, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_3B2, ht_bucket_empty,
	ht_bucket_html5_3B4, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_3BF,
	ht_bucket_html5_3C0, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_3C4, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_3C9, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_3CD, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_3D0, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_3D3,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_3D9, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_3DE, ht_bucket_empty,
	ht_bucket_html5_3E0, ht_bucket_html5_3E1, ht_bucket_empty, ht_bucket_html5_3E3,
	ht_bucket_html5_3E4, ht_bucket_empty, ht_bucket_html5_3E6, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_3E9, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_3ED, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_3F1, ht_bucket_html5_3F2, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_3F7,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_3FC, ht_bucket_empty, ht_bucket_html5_3FE, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_402, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_405, ht_bucket_empty, ht_bucket_html5_407,
	ht_bucket_empty, ht_bucket_html5_409, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_40E, ht_bucket_html5_40F,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_413,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_41A, ht_bucket_html5_41B,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_421, ht_bucket_empty, ht_bucket_html5_423,
	ht_bucket_html5_424, ht_bucket_html5_425, ht_bucket_html5_426, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_429, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_42C, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_42F,
	ht_bucket_html5_430, ht_bucket_empty, ht_bucket_html5_432, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_436, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_439, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_43C, ht_bucket_html5_43D, ht_bucket_html5_43E, ht_bucket_html5_43F,
	ht_bucket_html5_440, ht_bucket_html5_441, ht_bucket_empty, ht_bucket_html5_443,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_446, ht_bucket_html5_447,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_44A, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_44F,
	ht_bucket_html5_450, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_454, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_457,
	ht_bucket_html5_458, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_45D, ht_bucket_empty, ht_bucket_html5_45F,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_465, ht_bucket_html5_466, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_469, ht_bucket_html5_46A, ht_bucket_html5_46B,
	ht_bucket_empty, ht_bucket_html5_46D, ht_bucket_empty, ht_bucket_html5_46F,
	ht_bucket_html5_470, ht_bucket_html5_471, ht_bucket_html5_472, ht_bucket_html5_473,
	ht_bucket_empty, ht_bucket_html5_475, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_479, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_47C, ht_bucket_html5_47D, ht_bucket_empty, ht_bucket_html5_47F,
	ht_bucket_html5_480, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_485, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_488, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_48C, ht_bucket_empty, ht_bucket_html5_48E, ht_bucket_html5_48F,
	ht_bucket_html5_490, ht_bucket_html5_491, ht_bucket_empty, ht_bucket_html5_493,
	ht_bucket_empty, ht_bucket_html5_495, ht_bucket_html5_496, ht_bucket_empty,
	ht_bucket_html5_498, ht_bucket_html5_499, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_49F,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_4A2, ht_bucket_empty,
	ht_bucket_html5_4A4, ht_bucket_empty, ht_bucket_html5_4A6, ht_bucket_html5_4A7,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_4AA, ht_bucket_html5_4AB,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_4AE, ht_bucket_html5_4AF,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_4B2, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_4B6, ht_bucket_empty,
	ht_bucket_html5_4B8, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_4BC, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_4C0, ht_bucket_empty, ht_bucket_html5_4C2, ht_bucket_html5_4C3,
	ht_bucket_html5_4C4, ht_bucket_html5_4C5, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_4C8, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_4CB,
	ht_bucket_empty, ht_bucket_html5_4CD, ht_bucket_empty, ht_bucket_html5_4CF,
	ht_bucket_html5_4D0, ht_bucket_empty, ht_bucket_html5_4D2, ht_bucket_html5_4D3,
	ht_bucket_html5_4D4, ht_bucket_html5_4D5, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_4D8, ht_bucket_empty, ht_bucket_html5_4DA, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_4DE, ht_bucket_html5_4DF,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_4E3,
	ht_bucket_html5_4E4, ht_bucket_empty, ht_bucket_html5_4E6, ht_bucket_html5_4E7,
	ht_bucket_html5_4E8, ht_bucket_html5_4E9, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_4ED, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_4F1, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_4F7,
	ht_bucket_empty, ht_bucket_html5_4F9, ht_bucket_empty, ht_bucket_html5_4FB,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_4FE, ht_bucket_empty,
	ht_bucket_html5_500, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_504, ht_bucket_empty, ht_bucket_html5_506, ht_bucket_html5_507,
	ht_bucket_empty, ht_bucket_html5_509, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_50E, ht_bucket_html5_50F,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_513,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_516, ht_bucket_empty,
	ht_bucket_html5_518, ht_bucket_html5_519, ht_bucket_empty, ht_bucket_html5_51B,
	ht_bucket_html5_51C, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_524, ht_bucket_html5_525, ht_bucket_html5_526, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_52F,
	ht_bucket_html5_530, ht_bucket_empty, ht_bucket_html5_532, ht_bucket_html5_533,
	ht_bucket_html5_534, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_53B,
	ht_bucket_html5_53C, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_53F,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_542, ht_bucket_html5_543,
	ht_bucket_empty, ht_bucket_html5_545, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_548, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_54F,
	ht_bucket_html5_550, ht_bucket_html5_551, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_557,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_55B,
	ht_bucket_empty, ht_bucket_html5_55D, ht_bucket_empty, ht_bucket_html5_55F,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_564, ht_bucket_html5_565, ht_bucket_html5_566, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_56C, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_56F,
	ht_bucket_html5_570, ht_bucket_html5_571, ht_bucket_html5_572, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_575, ht_bucket_html5_576, ht_bucket_html5_577,
	ht_bucket_html5_578, ht_bucket_empty, ht_bucket_html5_57A, ht_bucket_html5_57B,
	ht_bucket_html5_57C, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_580, ht_bucket_empty, ht_bucket_html5_582, ht_bucket_html5_583,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_586, ht_bucket_empty,
	ht_bucket_html5_588, ht_bucket_html5_589, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_58D, ht_bucket_html5_58E, ht_bucket_html5_58F,
	ht_bucket_html5_590, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_595, ht_bucket_html5_596, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_59A, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_59D, ht_bucket_empty, ht_bucket_html5_59F,
	ht_bucket_html5_5A0, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_5A3,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_5A6, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_5A9, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_5AC, ht_bucket_html5_5AD, ht_bucket_html5_5AE, ht_bucket_empty,
	ht_bucket_html5_5B0, ht_bucket_html5_5B1, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_5B5, ht_bucket_html5_5B6, ht_bucket_html5_5B7,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_5BB,
	ht_bucket_html5_5BC, ht_bucket_html5_5BD, ht_bucket_empty, ht_bucket_html5_5BF,
	ht_bucket_html5_5C0, ht_bucket_html5_5C1, ht_bucket_html5_5C2, ht_bucket_empty,
	ht_bucket_html5_5C4, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_5D0, ht_bucket_html5_5D1, ht_bucket_empty, ht_bucket_html5_5D3,
	ht_bucket_empty, ht_bucket_html5_5D5, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_5D8, ht_bucket_html5_5D9, ht_bucket_empty, ht_bucket_html5_5DB,
	ht_bucket_empty, ht_bucket_html5_5DD, ht_bucket_empty, ht_bucket_html5_5DF,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_5E2, ht_bucket_empty,
	ht_bucket_html5_5E4, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_5E7,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_5EA, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_5ED, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_5F0, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_5F3,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_5F6, ht_bucket_empty,
	ht_bucket_html5_5F8, ht_bucket_empty, ht_bucket_html5_5FA, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_5FD, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_601, ht_bucket_html5_602, ht_bucket_html5_603,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_606, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_609, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_60D, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_613,
	ht_bucket_empty, ht_bucket_html5_615, ht_bucket_empty, ht_bucket_html5_617,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_61A, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_61D, ht_bucket_empty, ht_bucket_html5_61F,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_622, ht_bucket_empty,
	ht_bucket_html5_624, ht_bucket_empty, ht_bucket_html5_626, ht_bucket_empty,
	ht_bucket_html5_628, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_62C, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_630, ht_bucket_empty, ht_bucket_html5_632, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_636, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_63A, ht_bucket_empty,
	ht_bucket_html5_63C, ht_bucket_html5_63D, ht_bucket_html5_63E, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_641, ht_bucket_html5_642, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_645, ht_bucket_html5_646, ht_bucket_html5_647,
	ht_bucket_html5_648, ht_bucket_html5_649, ht_bucket_html5_64A, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_651, ht_bucket_html5_652, ht_bucket_html5_653,
	ht_bucket_empty, ht_bucket_html5_655, ht_bucket_empty, ht_bucket_html5_657,
	ht_bucket_html5_658, ht_bucket_html5_659, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_65C, ht_bucket_empty, ht_bucket_html5_65E, ht_bucket_empty,
	ht_bucket_html5_660, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_669, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_670, ht_bucket_html5_671, ht_bucket_html5_672, ht_bucket_html5_673,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_676, ht_bucket_empty,
	ht_bucket_html5_678, ht_bucket_html5_679, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_67D, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_680, ht_bucket_empty, ht_bucket_html5_682, ht_bucket_empty,
	ht_bucket_html5_684, ht_bucket_html5_685, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_68A, ht_bucket_empty,
	ht_bucket_html5_68C, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_691, ht_bucket_empty, ht_bucket_html5_693,
	ht_bucket_html5_694, ht_bucket_empty, ht_bucket_html5_696, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_699, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_6A3,
	ht_bucket_html5_6A4, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_6A8, ht_bucket_html5_6A9, ht_bucket_html5_6AA, ht_bucket_html5_6AB,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_6AE, ht_bucket_empty,
	ht_bucket_html5_6B0, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_6B4, ht_bucket_empty, ht_bucket_html5_6B6, ht_bucket_empty,
	ht_bucket_html5_6B8, ht_bucket_html5_6B9, ht_bucket_html5_6BA, ht_bucket_empty,
	ht_bucket_html5_6BC, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_6BF,
	ht_bucket_html5_6C0, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_6C4, ht_bucket_html5_6C5, ht_bucket_html5_6C6, ht_bucket_html5_6C7,
	ht_bucket_html5_6C8, ht_bucket_html5_6C9, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_6CC, ht_bucket_empty, ht_bucket_html5_6CE, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_6D1, ht_bucket_html5_6D2, ht_bucket_empty,
	ht_bucket_html5_6D4, ht_bucket_html5_6D5, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_6D9, ht_bucket_html5_6DA, ht_bucket_html5_6DB,
	ht_bucket_html5_6DC, ht_bucket_empty, ht_bucket_html5_6DE, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_6E7,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_6EB,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_6EE, ht_bucket_html5_6EF,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_6F5, ht_bucket_empty, ht_bucket_html5_6F7,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_6FB,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_704, ht_bucket_html5_705, ht_bucket_html5_706, ht_bucket_html5_707,
	ht_bucket_empty, ht_bucket_html5_709, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_70C, ht_bucket_empty, ht_bucket_html5_70E, ht_bucket_html5_70F,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_712, ht_bucket_empty,
	ht_bucket_html5_714, ht_bucket_html5_715, ht_bucket_empty, ht_bucket_html5_717,
	ht_bucket_empty, ht_bucket_html5_719, ht_bucket_empty, ht_bucket_html5_71B,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_71E, ht_bucket_html5_71F,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_723,
	ht_bucket_html5_724, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_727,
	ht_bucket_empty, ht_bucket_html5_729, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_72C, ht_bucket_html5_72D, ht_bucket_html5_72E, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_733,
	ht_bucket_html5_734, ht_bucket_html5_735, ht_bucket_html5_736, ht_bucket_empty,
	ht_bucket_html5_738, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_73B,
	ht_bucket_empty, ht_bucket_html5_73D, ht_bucket_html5_73E, ht_bucket_html5_73F,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_744, ht_bucket_html5_745, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_749, ht_bucket_empty, ht_bucket_html5_74B,
	ht_bucket_html5_74C, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_74F,
	ht_bucket_empty, ht_bucket_html5_751, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_754, ht_bucket_html5_755, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_759, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_75C, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_75F,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_762, ht_bucket_html5_763,
	ht_bucket_empty, ht_bucket_html5_765, ht_bucket_html5_766, ht_bucket_empty,
	ht_bucket_html5_768, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_76E, ht_bucket_empty,
	ht_bucket_html5_770, ht_bucket_empty, ht_bucket_html5_772, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_776, ht_bucket_html5_777,
	ht_bucket_empty, ht_bucket_html5_779, ht_bucket_html5_77A, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_77F,
	ht_bucket_empty, ht_bucket_html5_781, ht_bucket_empty, ht_bucket_html5_783,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_787,
	ht_bucket_empty, ht_bucket_html5_789, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_78C, ht_bucket_html5_78D, ht_bucket_html5_78E, ht_bucket_empty,
	ht_bucket_html5_790, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_794, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_797,
	ht_bucket_html5_798, ht_bucket_empty, ht_bucket_html5_79A, ht_bucket_html5_79B,
	ht_bucket_empty, ht_bucket_html5_79D, ht_bucket_empty, ht_bucket_html5_79F,
	ht_bucket_html5_7A0, ht_bucket_html5_7A1, ht_bucket_html5_7A2, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_7A5, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_7A8, ht_bucket_empty, ht_bucket_html5_7AA, ht_bucket_html5_7AB,
	ht_bucket_html5_7AC, ht_bucket_empty, ht_bucket_html5_7AE, ht_bucket_html5_7AF,
	ht_bucket_html5_7B0, ht_bucket_html5_7B1, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_7B5, ht_bucket_html5_7B6, ht_bucket_html5_7B7,
	ht_bucket_html5_7B8, ht_bucket_empty, ht_bucket_html5_7BA, ht_bucket_html5_7BB,
	ht_bucket_empty, ht_bucket_html5_7BD, ht_bucket_html5_7BE, ht_bucket_html5_7BF,
	ht_bucket_html5_7C0, ht_bucket_html5_7C1, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_7C9, ht_bucket_empty, ht_bucket_html5_7CB,
	ht_bucket_empty, ht_bucket_html5_7CD, ht_bucket_html5_7CE, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_7D1, ht_bucket_html5_7D2, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_7D5, ht_bucket_html5_7D6, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_7D9, ht_bucket_html5_7DA, ht_bucket_empty,
	ht_bucket_html5_7DC, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_7E0, ht_bucket_empty, ht_bucket_html5_7E2, ht_bucket_empty,
	ht_bucket_html5_7E4, ht_bucket_html5_7E5, ht_bucket_html5_7E6, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_7EC, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_7EF,
	ht_bucket_empty, ht_bucket_html5_7F1, ht_bucket_empty, ht_bucket_html5_7F3,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_7F6, ht_bucket_empty,
	ht_bucket_html5_7F8, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_7FB,
	ht_bucket_html5_7FC, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_800, ht_bucket_empty, ht_bucket_html5_802, ht_bucket_html5_803,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_808, ht_bucket_html5_809, ht_bucket_html5_80A, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_810, ht_bucket_html5_811, ht_bucket_html5_812, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_816, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_819, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_81C, ht_bucket_html5_81D, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_821, ht_bucket_html5_822, ht_bucket_html5_823,
	ht_bucket_html5_824, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_828, ht_bucket_html5_829, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_82D, ht_bucket_html5_82E, ht_bucket_empty,
	ht_bucket_html5_830, ht_bucket_html5_831, ht_bucket_html5_832, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_837,
	ht_bucket_html5_838, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_83C, ht_bucket_empty, ht_bucket_html5_83E, ht_bucket_html5_83F,
	ht_bucket_empty, ht_bucket_html5_841, ht_bucket_html5_842, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_846, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_84A, ht_bucket_empty,
	ht_bucket_html5_84C, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_84F,
	ht_bucket_html5_850, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_855, ht_bucket_empty, ht_bucket_html5_857,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_85B,
	ht_bucket_html5_85C, ht_bucket_empty, ht_bucket_html5_85E, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_861, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_865, ht_bucket_html5_866, ht_bucket_html5_867,
	ht_bucket_html5_868, ht_bucket_empty, ht_bucket_html5_86A, ht_bucket_html5_86B,
	ht_bucket_html5_86C, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_873,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_876, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_879, ht_bucket_empty, ht_bucket_html5_87B,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_87E, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_88A, ht_bucket_empty,
	ht_bucket_html5_88C, ht_bucket_empty, ht_bucket_html5_88E, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_892, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_895, ht_bucket_html5_896, ht_bucket_html5_897,
	ht_bucket_html5_898, ht_bucket_html5_899, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_89D, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_8A5, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_8AC, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_8B3,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_8B6, ht_bucket_html5_8B7,
	ht_bucket_html5_8B8, ht_bucket_html5_8B9, ht_bucket_html5_8BA, ht_bucket_empty,
	ht_bucket_html5_8BC, ht_bucket_html5_8BD, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_8C0, ht_bucket_html5_8C1, ht_bucket_html5_8C2, ht_bucket_empty,
	ht_bucket_html5_8C4, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_8C7,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_8CF,
	ht_bucket_html5_8D0, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_8D3,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_8D6, ht_bucket_empty,
	ht_bucket_html5_8D8, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_8DC, ht_bucket_html5_8DD, ht_bucket_html5_8DE, ht_bucket_html5_8DF,
	ht_bucket_html5_8E0, ht_bucket_empty, ht_bucket_html5_8E2, ht_bucket_html5_8E3,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_8E7,
	ht_bucket_html5_8E8, ht_bucket_html5_8E9, ht_bucket_empty, ht_bucket_html5_8EB,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_8F3,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_8FB,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_8FE, ht_bucket_html5_8FF,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_904, ht_bucket_empty, ht_bucket_html5_906, ht_bucket_html5_907,
	ht_bucket_empty, ht_bucket_html5_909, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_90C, ht_bucket_empty, ht_bucket_html5_90E, ht_bucket_empty,
	ht_bucket_html5_910, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_913,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_916, ht_bucket_empty,
	ht_bucket_html5_918, ht_bucket_html5_919, ht_bucket_empty, ht_bucket_html5_91B,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_91E, ht_bucket_html5_91F,
	ht_bucket_html5_920, ht_bucket_empty, ht_bucket_html5_922, ht_bucket_html5_923,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_927,
	ht_bucket_empty, ht_bucket_html5_929, ht_bucket_html5_92A, ht_bucket_empty,
	ht_bucket_html5_92C, ht_bucket_empty, ht_bucket_html5_92E, ht_bucket_empty,
	ht_bucket_html5_930, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_936, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_939, ht_bucket_empty, ht_bucket_html5_93B,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_93F,
	ht_bucket_html5_940, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_945, ht_bucket_empty, ht_bucket_html5_947,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_94D, ht_bucket_empty, ht_bucket_html5_94F,
	ht_bucket_html5_950, ht_bucket_empty, ht_bucket_html5_952, ht_bucket_html5_953,
	ht_bucket_html5_954, ht_bucket_html5_955, ht_bucket_html5_956, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_959, ht_bucket_empty, ht_bucket_html5_95B,
	ht_bucket_empty, ht_bucket_html5_95D, ht_bucket_empty, ht_bucket_html5_95F,
	ht_bucket_html5_960, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_963,
	ht_bucket_html5_964, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_969, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_96C, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_96F,
	ht_bucket_html5_970, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_974, ht_bucket_html5_975, ht_bucket_html5_976, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_97B,
	ht_bucket_html5_97C, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_97F,
	ht_bucket_empty, ht_bucket_html5_981, ht_bucket_empty, ht_bucket_html5_983,
	ht_bucket_empty, ht_bucket_html5_985, ht_bucket_html5_986, ht_bucket_empty,
	ht_bucket_html5_988, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_98C, ht_bucket_html5_98D, ht_bucket_empty, ht_bucket_html5_98F,
	ht_bucket_html5_990, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_996, ht_bucket_html5_997,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_99B,
	ht_bucket_html5_99C, ht_bucket_empty, ht_bucket_html5_99E, ht_bucket_html5_99F,
	ht_bucket_html5_9A0, ht_bucket_html5_9A1, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_9A6, ht_bucket_empty,
	ht_bucket_html5_9A8, ht_bucket_empty, ht_bucket_html5_9AA, ht_bucket_empty,
	ht_bucket_html5_9AC, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_9B0, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_9B4, ht_bucket_html5_9B5, ht_bucket_html5_9B6, ht_bucket_html5_9B7,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_9BB,
	ht_bucket_html5_9BC, ht_bucket_html5_9BD, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_9C1, ht_bucket_html5_9C2, ht_bucket_html5_9C3,
	ht_bucket_empty, ht_bucket_html5_9C5, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_9C9, ht_bucket_html5_9CA, ht_bucket_empty,
	ht_bucket_html5_9CC, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_9CF,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_9D5, ht_bucket_html5_9D6, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_9DA, ht_bucket_html5_9DB,
	ht_bucket_empty, ht_bucket_html5_9DD, ht_bucket_html5_9DE, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_9E1, ht_bucket_html5_9E2, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_9E5, ht_bucket_empty, ht_bucket_html5_9E7,
	ht_bucket_empty, ht_bucket_html5_9E9, ht_bucket_empty, ht_bucket_html5_9EB,
	ht_bucket_empty, ht_bucket_html5_9ED, ht_bucket_html5_9EE, ht_bucket_html5_9EF,
	ht_bucket_html5_9F0, ht_bucket_html5_9F1, ht_bucket_html5_9F2, ht_bucket_html5_9F3,
	ht_bucket_html5_9F4, ht_bucket_html5_9F5, ht_bucket_empty, ht_bucket_html5_9F7,
	ht_bucket_empty, ht_bucket_html5_9F9, ht_bucket_html5_9FA, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_9FD, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_A01, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_A04, ht_bucket_html5_A05, ht_bucket_html5_A06, ht_bucket_empty,
	ht_bucket_html5_A08, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_A0C, ht_bucket_html5_A0D, ht_bucket_html5_A0E, ht_bucket_empty,
	ht_bucket_html5_A10, ht_bucket_empty, ht_bucket_html5_A12, ht_bucket_empty,
	ht_bucket_html5_A14, ht_bucket_html5_A15, ht_bucket_html5_A16, ht_bucket_html5_A17,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_A21, ht_bucket_empty, ht_bucket_html5_A23,
	ht_bucket_html5_A24, ht_bucket_html5_A25, ht_bucket_html5_A26, ht_bucket_empty,
	ht_bucket_html5_A28, ht_bucket_empty, ht_bucket_html5_A2A, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_A2D, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_A30, ht_bucket_empty, ht_bucket_html5_A32, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_A36, ht_bucket_html5_A37,
	ht_bucket_empty, ht_bucket_html5_A39, ht_bucket_empty, ht_bucket_html5_A3B,
	ht_bucket_html5_A3C, ht_bucket_html5_A3D, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_A41, ht_bucket_empty, ht_bucket_html5_A43,
	ht_bucket_html5_A44, ht_bucket_html5_A45, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_A48, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_A4F,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_A53,
	ht_bucket_html5_A54, ht_bucket_empty, ht_bucket_html5_A56, ht_bucket_html5_A57,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_A5A, ht_bucket_html5_A5B,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_A61, ht_bucket_html5_A62, ht_bucket_html5_A63,
	ht_bucket_html5_A64, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_A69, ht_bucket_html5_A6A, ht_bucket_html5_A6B,
	ht_bucket_empty, ht_bucket_html5_A6D, ht_bucket_empty, ht_bucket_html5_A6F,
	ht_bucket_html5_A70, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_A76, ht_bucket_empty,
	ht_bucket_html5_A78, ht_bucket_empty, ht_bucket_html5_A7A, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_A7E, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_A81, ht_bucket_html5_A82, ht_bucket_empty,
	ht_bucket_html5_A84, ht_bucket_html5_A85, ht_bucket_html5_A86, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_A89, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_A8D, ht_bucket_html5_A8E, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_A92, ht_bucket_empty,
	ht_bucket_html5_A94, ht_bucket_empty, ht_bucket_html5_A96, ht_bucket_empty,
	ht_bucket_html5_A98, ht_bucket_html5_A99, ht_bucket_html5_A9A, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_A9D, ht_bucket_empty, ht_bucket_html5_A9F,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_AA3,
	ht_bucket_html5_AA4, ht_bucket_html5_AA5, ht_bucket_empty, ht_bucket_html5_AA7,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_AAC, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_AB2, ht_bucket_empty,
	ht_bucket_html5_AB4, ht_bucket_html5_AB5, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_ABA, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_AC0, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_AC4, ht_bucket_html5_AC5, ht_bucket_html5_AC6, ht_bucket_html5_AC7,
	ht_bucket_html5_AC8, ht_bucket_empty, ht_bucket_html5_ACA, ht_bucket_empty,
	ht_bucket_html5_ACC, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_ACF,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_AD2, ht_bucket_html5_AD3,
	ht_bucket_html5_AD4, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_ADA, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_ADD, ht_bucket_empty, ht_bucket_html5_ADF,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_AE4, ht_bucket_html5_AE5, ht_bucket_html5_AE6, ht_bucket_html5_AE7,
	ht_bucket_html5_AE8, ht_bucket_html5_AE9, ht_bucket_empty, ht_bucket_html5_AEB,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_AF5, ht_bucket_html5_AF6, ht_bucket_html5_AF7,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_AFA, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_AFD, ht_bucket_html5_AFE, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_B08, ht_bucket_html5_B09, ht_bucket_html5_B0A, ht_bucket_empty,
	ht_bucket_html5_B0C, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_B10, ht_bucket_html5_B11, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_B15, ht_bucket_html5_B16, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_B1E, ht_bucket_html5_B1F,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_B23,
	ht_bucket_html5_B24, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_B27,
	ht_bucket_empty, ht_bucket_html5_B29, ht_bucket_html5_B2A, ht_bucket_html5_B2B,
	ht_bucket_html5_B2C, ht_bucket_html5_B2D, ht_bucket_html5_B2E, ht_bucket_html5_B2F,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_B33,
	ht_bucket_empty, ht_bucket_html5_B35, ht_bucket_html5_B36, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_B3A, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_B3D, ht_bucket_html5_B3E, ht_bucket_empty,
	ht_bucket_html5_B40, ht_bucket_empty, ht_bucket_html5_B42, ht_bucket_empty,
	ht_bucket_html5_B44, ht_bucket_empty, ht_bucket_html5_B46, ht_bucket_html5_B47,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_B4C, ht_bucket_empty, ht_bucket_html5_B4E, ht_bucket_html5_B4F,
	ht_bucket_html5_B50, ht_bucket_html5_B51, ht_bucket_html5_B52, ht_bucket_html5_B53,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_B56, ht_bucket_empty,
	ht_bucket_html5_B58, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_B5C, ht_bucket_html5_B5D, ht_bucket_html5_B5E, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_B63,
	ht_bucket_html5_B64, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_B67,
	ht_bucket_empty, ht_bucket_html5_B69, ht_bucket_empty, ht_bucket_html5_B6B,
	ht_bucket_empty, ht_bucket_html5_B6D, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_B72, ht_bucket_html5_B73,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_B77,
	ht_bucket_html5_B78, ht_bucket_empty, ht_bucket_html5_B7A, ht_bucket_html5_B7B,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_B7E, ht_bucket_html5_B7F,
	ht_bucket_empty, ht_bucket_html5_B81, ht_bucket_html5_B82, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_B87,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_B8D, ht_bucket_empty, ht_bucket_html5_B8F,
	ht_bucket_html5_B90, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_B94, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_B98, ht_bucket_html5_B99, ht_bucket_html5_B9A, ht_bucket_empty,
	ht_bucket_html5_B9C, ht_bucket_html5_B9D, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_BA5, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_BA9, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_BAE, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_BB2, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_BB5, ht_bucket_html5_BB6, ht_bucket_html5_BB7,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_BBA, ht_bucket_empty,
	ht_bucket_html5_BBC, ht_bucket_html5_BBD, ht_bucket_empty, ht_bucket_html5_BBF,
	ht_bucket_empty, ht_bucket_html5_BC1, ht_bucket_html5_BC2, ht_bucket_html5_BC3,
	ht_bucket_html5_BC4, ht_bucket_html5_BC5, ht_bucket_html5_BC6, ht_bucket_html5_BC7,
	ht_bucket_html5_BC8, ht_bucket_html5_BC9, ht_bucket_empty, ht_bucket_html5_BCB,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_BCE, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_BD1, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_BD7,
	ht_bucket_html5_BD8, ht_bucket_html5_BD9, ht_bucket_html5_BDA, ht_bucket_html5_BDB,
	ht_bucket_empty, ht_bucket_html5_BDD, ht_bucket_empty, ht_bucket_html5_BDF,
	ht_bucket_empty, ht_bucket_html5_BE1, ht_bucket_html5_BE2, ht_bucket_empty,
	ht_bucket_html5_BE4, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_BE7,
	ht_bucket_html5_BE8, ht_bucket_html5_BE9, ht_bucket_html5_BEA, ht_bucket_html5_BEB,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_BEF,
	ht_bucket_html5_BF0, ht_bucket_html5_BF1, ht_bucket_html5_BF2, ht_bucket_html5_BF3,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_BF7,
	ht_bucket_empty, ht_bucket_html5_BF9, ht_bucket_html5_BFA, ht_bucket_empty,
	ht_bucket_html5_BFC, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_C02, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_C0B,
	ht_bucket_html5_C0C, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_C11, ht_bucket_html5_C12, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_C16, ht_bucket_empty,
	ht_bucket_html5_C18, ht_bucket_empty, ht_bucket_html5_C1A, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_C1D, ht_bucket_html5_C1E, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_C23,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_C27,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_C2B,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_C31, ht_bucket_html5_C32, ht_bucket_html5_C33,
	ht_bucket_html5_C34, ht_bucket_html5_C35, ht_bucket_html5_C36, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_C3A, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_C3E, ht_bucket_html5_C3F,
	ht_bucket_html5_C40, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_C43,
	ht_bucket_html5_C44, ht_bucket_empty, ht_bucket_html5_C46, ht_bucket_empty,
	ht_bucket_html5_C48, ht_bucket_empty, ht_bucket_html5_C4A, ht_bucket_html5_C4B,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_C4F,
	ht_bucket_html5_C50, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_C54, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_C58, ht_bucket_empty, ht_bucket_html5_C5A, ht_bucket_html5_C5B,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_C5F,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_C69, ht_bucket_empty, ht_bucket_html5_C6B,
	ht_bucket_html5_C6C, ht_bucket_empty, ht_bucket_html5_C6E, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_C72, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_C76, ht_bucket_html5_C77,
	ht_bucket_html5_C78, ht_bucket_empty, ht_bucket_html5_C7A, ht_bucket_html5_C7B,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_C80, ht_bucket_empty, ht_bucket_html5_C82, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_C89, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_C8E, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_C91, ht_bucket_empty, ht_bucket_html5_C93,
	ht_bucket_html5_C94, ht_bucket_html5_C95, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_C98, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_CA6, ht_bucket_empty,
	ht_bucket_html5_CA8, ht_bucket_html5_CA9, ht_bucket_html5_CAA, ht_bucket_empty,
	ht_bucket_html5_CAC, ht_bucket_html5_CAD, ht_bucket_empty, ht_bucket_html5_CAF,
	ht_bucket_html5_CB0, ht_bucket_empty, ht_bucket_html5_CB2, ht_bucket_empty,
	ht_bucket_html5_CB4, ht_bucket_empty, ht_bucket_html5_CB6, ht_bucket_html5_CB7,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_CBA, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_CBE, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_CC2, ht_bucket_empty,
	ht_bucket_html5_CC4, ht_bucket_html5_CC5, ht_bucket_empty, ht_bucket_html5_CC7,
	ht_bucket_html5_CC8, ht_bucket_html5_CC9, ht_bucket_empty, ht_bucket_html5_CCB,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_CD0, ht_bucket_empty, ht_bucket_html5_CD2, ht_bucket_html5_CD3,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_CD9, ht_bucket_html5_CDA, ht_bucket_empty,
	ht_bucket_html5_CDC, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_CE4, ht_bucket_empty, ht_bucket_html5_CE6, ht_bucket_empty,
	ht_bucket_html5_CE8, ht_bucket_html5_CE9, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_CED, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_CF1, ht_bucket_html5_CF2, ht_bucket_html5_CF3,
	ht_bucket_html5_CF4, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_CFA, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_CFF,
	ht_bucket_html5_D00, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_D06, ht_bucket_html5_D07,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_D0B,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_D0E, ht_bucket_empty,
	ht_bucket_html5_D10, ht_bucket_html5_D11, ht_bucket_html5_D12, ht_bucket_html5_D13,
	ht_bucket_empty, ht_bucket_html5_D15, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_D18, ht_bucket_html5_D19, ht_bucket_html5_D1A, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_D1E, ht_bucket_html5_D1F,
	ht_bucket_html5_D20, ht_bucket_empty, ht_bucket_html5_D22, ht_bucket_empty,
	ht_bucket_html5_D24, ht_bucket_empty, ht_bucket_html5_D26, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_D2A, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_D32, ht_bucket_empty,
	ht_bucket_html5_D34, ht_bucket_html5_D35, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_D38, ht_bucket_html5_D39, ht_bucket_html5_D3A, ht_bucket_html5_D3B,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_D3E, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_D42, ht_bucket_empty,
	ht_bucket_html5_D44, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_D49, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_D4C, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_D4F,
	ht_bucket_empty, ht_bucket_html5_D51, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_D54, ht_bucket_html5_D55, ht_bucket_html5_D56, ht_bucket_html5_D57,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_D5A, ht_bucket_html5_D5B,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_D5F,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_D63,
	ht_bucket_empty, ht_bucket_html5_D65, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_D69, ht_bucket_html5_D6A, ht_bucket_empty,
	ht_bucket_html5_D6C, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_D6F,
	ht_bucket_html5_D70, ht_bucket_html5_D71, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_D74, ht_bucket_html5_D75, ht_bucket_html5_D76, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_D7C, ht_bucket_html5_D7D, ht_bucket_html5_D7E, ht_bucket_empty,
	ht_bucket_html5_D80, ht_bucket_html5_D81, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_D85, ht_bucket_empty, ht_bucket_html5_D87,
	ht_bucket_empty, ht_bucket_html5_D89, ht_bucket_html5_D8A, ht_bucket_empty,
	ht_bucket_html5_D8C, ht_bucket_html5_D8D, ht_bucket_html5_D8E, ht_bucket_html5_D8F,
	ht_bucket_html5_D90, ht_bucket_html5_D91, ht_bucket_empty, ht_bucket_html5_D93,
	ht_bucket_html5_D94, ht_bucket_html5_D95, ht_bucket_html5_D96, ht_bucket_empty,
	ht_bucket_html5_D98, ht_bucket_empty, ht_bucket_html5_D9A, ht_bucket_empty,
	ht_bucket_html5_D9C, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_DA0, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_DA5, ht_bucket_html5_DA6, ht_bucket_empty,
	ht_bucket_html5_DA8, ht_bucket_html5_DA9, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_DAC, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_DB0, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_DB3,
	ht_bucket_html5_DB4, ht_bucket_empty, ht_bucket_html5_DB6, ht_bucket_html5_DB7,
	ht_bucket_empty, ht_bucket_html5_DB9, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_DBC, ht_bucket_empty, ht_bucket_html5_DBE, ht_bucket_html5_DBF,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_DC2, ht_bucket_html5_DC3,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_DC6, ht_bucket_empty,
	ht_bucket_html5_DC8, ht_bucket_empty, ht_bucket_html5_DCA, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_DCF,
	ht_bucket_empty, ht_bucket_html5_DD1, ht_bucket_empty, ht_bucket_html5_DD3,
	ht_bucket_html5_DD4, ht_bucket_html5_DD5, ht_bucket_empty, ht_bucket_html5_DD7,
	ht_bucket_empty, ht_bucket_html5_DD9, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_DDC, ht_bucket_html5_DDD, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_DE4, ht_bucket_empty, ht_bucket_html5_DE6, ht_bucket_html5_DE7,
	ht_bucket_empty, ht_bucket_html5_DE9, ht_bucket_empty, ht_bucket_html5_DEB,
	ht_bucket_empty, ht_bucket_html5_DED, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_DF1, ht_bucket_html5_DF2, ht_bucket_html5_DF3,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_DF6, ht_bucket_html5_DF7,
	ht_bucket_empty, ht_bucket_html5_DF9, ht_bucket_empty, ht_bucket_html5_DFB,
	ht_bucket_empty, ht_bucket_html5_DFD, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_E03,
	ht_bucket_html5_E04, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_E08, ht_bucket_html5_E09, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_E0C, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_E11, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_E18, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_E1B,
	ht_bucket_html5_E1C, ht_bucket_html5_E1D, ht_bucket_html5_E1E, ht_bucket_empty,
	ht_bucket_html5_E20, ht_bucket_empty, ht_bucket_html5_E22, ht_bucket_html5_E23,
	ht_bucket_html5_E24, ht_bucket_html5_E25, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_E28, ht_bucket_empty, ht_bucket_html5_E2A, ht_bucket_empty,
	ht_bucket_html5_E2C, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_E2F,
	ht_bucket_html5_E30, ht_bucket_empty, ht_bucket_html5_E32, ht_bucket_html5_E33,
	ht_bucket_empty, ht_bucket_html5_E35, ht_bucket_html5_E36, ht_bucket_html5_E37,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_E3B,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_E41, ht_bucket_html5_E42, ht_bucket_html5_E43,
	ht_bucket_html5_E44, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_E48, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_E4C, ht_bucket_empty, ht_bucket_html5_E4E, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_E53,
	ht_bucket_empty, ht_bucket_html5_E55, ht_bucket_empty, ht_bucket_html5_E57,
	ht_bucket_html5_E58, ht_bucket_html5_E59, ht_bucket_empty, ht_bucket_html5_E5B,
	ht_bucket_empty, ht_bucket_html5_E5D, ht_bucket_html5_E5E, ht_bucket_html5_E5F,
	ht_bucket_html5_E60, ht_bucket_html5_E61, ht_bucket_empty, ht_bucket_html5_E63,
	ht_bucket_html5_E64, ht_bucket_html5_E65, ht_bucket_html5_E66, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_E6A, ht_bucket_empty,
	ht_bucket_html5_E6C, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_E6F,
	ht_bucket_html5_E70, ht_bucket_html5_E71, ht_bucket_empty, ht_bucket_html5_E73,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_E78, ht_bucket_empty, ht_bucket_html5_E7A, ht_bucket_empty,
	ht_bucket_html5_E7C, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_E80, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_E83,
	ht_bucket_html5_E84, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_E89, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_E8E, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_E91, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_E99, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_E9C, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_EA1, ht_bucket_html5_EA2, ht_bucket_empty,
	ht_bucket_html5_EA4, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_EA8, ht_bucket_html5_EA9, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_EB1, ht_bucket_html5_EB2, ht_bucket_empty,
	ht_bucket_html5_EB4, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_EB7,
	ht_bucket_html5_EB8, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_ECA, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_ECD, ht_bucket_empty, ht_bucket_html5_ECF,
	ht_bucket_empty, ht_bucket_html5_ED1, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_ED7,
	ht_bucket_html5_ED8, ht_bucket_html5_ED9, ht_bucket_html5_EDA, ht_bucket_html5_EDB,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_EDF,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_EE2, ht_bucket_empty,
	ht_bucket_html5_EE4, ht_bucket_html5_EE5, ht_bucket_empty, ht_bucket_html5_EE7,
	ht_bucket_empty, ht_bucket_html5_EE9, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_EEF,
	ht_bucket_empty, ht_bucket_html5_EF1, ht_bucket_html5_EF2, ht_bucket_empty,
	ht_bucket_html5_EF4, ht_bucket_html5_EF5, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_EF9, ht_bucket_empty, ht_bucket_html5_EFB,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_EFE, ht_bucket_html5_EFF,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_F03,
	ht_bucket_empty, ht_bucket_html5_F05, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_F08, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_F0B,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_F0F,
	ht_bucket_html5_F10, ht_bucket_html5_F11, ht_bucket_empty, ht_bucket_html5_F13,
	ht_bucket_html5_F14, ht_bucket_html5_F15, ht_bucket_empty, ht_bucket_html5_F17,
	ht_bucket_html5_F18, ht_bucket_html5_F19, ht_bucket_html5_F1A, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_F1F,
	ht_bucket_html5_F20, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_F26, ht_bucket_empty,
	ht_bucket_html5_F28, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_F2C, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_F2F,
	ht_bucket_html5_F30, ht_bucket_html5_F31, ht_bucket_empty, ht_bucket_html5_F33,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_F37,
	ht_bucket_html5_F38, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_F40, ht_bucket_html5_F41, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_F44, ht_bucket_empty, ht_bucket_html5_F46, ht_bucket_html5_F47,
	ht_bucket_html5_F48, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_F4B,
	ht_bucket_html5_F4C, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_F50, ht_bucket_html5_F51, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_F55, ht_bucket_empty, ht_bucket_html5_F57,
	ht_bucket_html5_F58, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_F5B,
	ht_bucket_empty, ht_bucket_html5_F5D, ht_bucket_empty, ht_bucket_html5_F5F,
	ht_bucket_html5_F60, ht_bucket_empty, ht_bucket_html5_F62, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_F67,
	ht_bucket_html5_F68, ht_bucket_html5_F69, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_F6D, ht_bucket_html5_F6E, ht_bucket_html5_F6F,
	ht_bucket_html5_F70, ht_bucket_html5_F71, ht_bucket_html5_F72, ht_bucket_empty,
	ht_bucket_html5_F74, ht_bucket_html5_F75, ht_bucket_html5_F76, ht_bucket_html5_F77,
	ht_bucket_html5_F78, ht_bucket_html5_F79, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_F81, ht_bucket_html5_F82, ht_bucket_html5_F83,
	ht_bucket_html5_F84, ht_bucket_empty, ht_bucket_html5_F86, ht_bucket_empty,
	ht_bucket_html5_F88, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_F8B,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_F8F,
	ht_bucket_empty, ht_bucket_html5_F91, ht_bucket_empty, ht_bucket_html5_F93,
	ht_bucket_empty, ht_bucket_html5_F95, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_F9A, ht_bucket_empty,
	ht_bucket_html5_F9C, ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_F9F,
	ht_bucket_html5_FA0, ht_bucket_html5_FA1, ht_bucket_html5_FA2, ht_bucket_html5_FA3,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_FA9, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_FB0, ht_bucket_html5_FB1, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_FB4, ht_bucket_html5_FB5, ht_bucket_html5_FB6, ht_bucket_html5_FB7,
	ht_bucket_empty, ht_bucket_html5_FB9, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_FBC, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_FC2, ht_bucket_empty,
	ht_bucket_html5_FC4, ht_bucket_empty, ht_bucket_html5_FC6, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_FCA, ht_bucket_empty,
	ht_bucket_html5_FCC, ht_bucket_empty, ht_bucket_html5_FCE, ht_bucket_html5_FCF,
	ht_bucket_html5_FD0, ht_bucket_empty, ht_bucket_html5_FD2, ht_bucket_html5_FD3,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_FD6, ht_bucket_html5_FD7,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_FDD, ht_bucket_empty, ht_bucket_html5_FDF,
	ht_bucket_empty, ht_bucket_html5_FE1, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html5_FE6, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_FE9, ht_bucket_html5_FEA, ht_bucket_html5_FEB,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html5_FF5, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_FF8, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html5_FFC, ht_bucket_empty, ht_bucket_html5_FFE, ht_bucket_empty,
};

static const entity_ht ent_ht_html5 = {
	0x1000,
	ht_buckets_html5
};

/* end of HTML5 hash table for entity -> codepoint }}} */

/* {{{ Start of HTML 4.01 multi-stage table for codepoint -> entity */

/* {{{ Stage 3 Tables for HTML 4.01 */

static const entity_stage3_row stage3_table_html4_00000[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"quot", 4} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"amp", 3} } }, {0, { {"#039", 4} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"lt", 2} } }, {0, { {NULL, 0} } }, {0, { {"gt", 2} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html4_00080[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"nbsp", 4} } }, {0, { {"iexcl", 5} } }, {0, { {"cent", 4} } }, {0, { {"pound", 5} } },
	{0, { {"curren", 6} } }, {0, { {"yen", 3} } }, {0, { {"brvbar", 6} } }, {0, { {"sect", 4} } },
	{0, { {"uml", 3} } }, {0, { {"copy", 4} } }, {0, { {"ordf", 4} } }, {0, { {"laquo", 5} } },
	{0, { {"not", 3} } }, {0, { {"shy", 3} } }, {0, { {"reg", 3} } }, {0, { {"macr", 4} } },
	{0, { {"deg", 3} } }, {0, { {"plusmn", 6} } }, {0, { {"sup2", 4} } }, {0, { {"sup3", 4} } },
	{0, { {"acute", 5} } }, {0, { {"micro", 5} } }, {0, { {"para", 4} } }, {0, { {"middot", 6} } },
	{0, { {"cedil", 5} } }, {0, { {"sup1", 4} } }, {0, { {"ordm", 4} } }, {0, { {"raquo", 5} } },
	{0, { {"frac14", 6} } }, {0, { {"frac12", 6} } }, {0, { {"frac34", 6} } }, {0, { {"iquest", 6} } },
};

static const entity_stage3_row stage3_table_html4_000C0[] = {
	{0, { {"Agrave", 6} } }, {0, { {"Aacute", 6} } }, {0, { {"Acirc", 5} } }, {0, { {"Atilde", 6} } },
	{0, { {"Auml", 4} } }, {0, { {"Aring", 5} } }, {0, { {"AElig", 5} } }, {0, { {"Ccedil", 6} } },
	{0, { {"Egrave", 6} } }, {0, { {"Eacute", 6} } }, {0, { {"Ecirc", 5} } }, {0, { {"Euml", 4} } },
	{0, { {"Igrave", 6} } }, {0, { {"Iacute", 6} } }, {0, { {"Icirc", 5} } }, {0, { {"Iuml", 4} } },
	{0, { {"ETH", 3} } }, {0, { {"Ntilde", 6} } }, {0, { {"Ograve", 6} } }, {0, { {"Oacute", 6} } },
	{0, { {"Ocirc", 5} } }, {0, { {"Otilde", 6} } }, {0, { {"Ouml", 4} } }, {0, { {"times", 5} } },
	{0, { {"Oslash", 6} } }, {0, { {"Ugrave", 6} } }, {0, { {"Uacute", 6} } }, {0, { {"Ucirc", 5} } },
	{0, { {"Uuml", 4} } }, {0, { {"Yacute", 6} } }, {0, { {"THORN", 5} } }, {0, { {"szlig", 5} } },
	{0, { {"agrave", 6} } }, {0, { {"aacute", 6} } }, {0, { {"acirc", 5} } }, {0, { {"atilde", 6} } },
	{0, { {"auml", 4} } }, {0, { {"aring", 5} } }, {0, { {"aelig", 5} } }, {0, { {"ccedil", 6} } },
	{0, { {"egrave", 6} } }, {0, { {"eacute", 6} } }, {0, { {"ecirc", 5} } }, {0, { {"euml", 4} } },
	{0, { {"igrave", 6} } }, {0, { {"iacute", 6} } }, {0, { {"icirc", 5} } }, {0, { {"iuml", 4} } },
	{0, { {"eth", 3} } }, {0, { {"ntilde", 6} } }, {0, { {"ograve", 6} } }, {0, { {"oacute", 6} } },
	{0, { {"ocirc", 5} } }, {0, { {"otilde", 6} } }, {0, { {"ouml", 4} } }, {0, { {"divide", 6} } },
	{0, { {"oslash", 6} } }, {0, { {"ugrave", 6} } }, {0, { {"uacute", 6} } }, {0, { {"ucirc", 5} } },
	{0, { {"uuml", 4} } }, {0, { {"yacute", 6} } }, {0, { {"thorn", 5} } }, {0, { {"yuml", 4} } },
};

static const entity_stage3_row stage3_table_html4_00140[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"OElig", 5} } }, {0, { {"oelig", 5} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"Scaron", 6} } }, {0, { {"scaron", 6} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"Yuml", 4} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html4_00180[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"fnof", 4} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html4_002C0[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"circ", 4} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"tilde", 5} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html4_00380[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"Alpha", 5} } }, {0, { {"Beta", 4} } }, {0, { {"Gamma", 5} } },
	{0, { {"Delta", 5} } }, {0, { {"Epsilon", 7} } }, {0, { {"Zeta", 4} } }, {0, { {"Eta", 3} } },
	{0, { {"Theta", 5} } }, {0, { {"Iota", 4} } }, {0, { {"Kappa", 5} } }, {0, { {"Lambda", 6} } },
	{0, { {"Mu", 2} } }, {0, { {"Nu", 2} } }, {0, { {"Xi", 2} } }, {0, { {"Omicron", 7} } },
	{0, { {"Pi", 2} } }, {0, { {"Rho", 3} } }, {0, { {NULL, 0} } }, {0, { {"Sigma", 5} } },
	{0, { {"Tau", 3} } }, {0, { {"Upsilon", 7} } }, {0, { {"Phi", 3} } }, {0, { {"Chi", 3} } },
	{0, { {"Psi", 3} } }, {0, { {"Omega", 5} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"alpha", 5} } }, {0, { {"beta", 4} } }, {0, { {"gamma", 5} } },
	{0, { {"delta", 5} } }, {0, { {"epsilon", 7} } }, {0, { {"zeta", 4} } }, {0, { {"eta", 3} } },
	{0, { {"theta", 5} } }, {0, { {"iota", 4} } }, {0, { {"kappa", 5} } }, {0, { {"lambda", 6} } },
	{0, { {"mu", 2} } }, {0, { {"nu", 2} } }, {0, { {"xi", 2} } }, {0, { {"omicron", 7} } },
};

static const entity_stage3_row stage3_table_html4_003C0[] = {
	{0, { {"pi", 2} } }, {0, { {"rho", 3} } }, {0, { {"sigmaf", 6} } }, {0, { {"sigma", 5} } },
	{0, { {"tau", 3} } }, {0, { {"upsilon", 7} } }, {0, { {"phi", 3} } }, {0, { {"chi", 3} } },
	{0, { {"psi", 3} } }, {0, { {"omega", 5} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"thetasym", 8} } }, {0, { {"upsih", 5} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"piv", 3} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html4_02000[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"ensp", 4} } }, {0, { {"emsp", 4} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"thinsp", 6} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"zwnj", 4} } }, {0, { {"zwj", 3} } }, {0, { {"lrm", 3} } }, {0, { {"rlm", 3} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"ndash", 5} } },
	{0, { {"mdash", 5} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"lsquo", 5} } }, {0, { {"rsquo", 5} } }, {0, { {"sbquo", 5} } }, {0, { {NULL, 0} } },
	{0, { {"ldquo", 5} } }, {0, { {"rdquo", 5} } }, {0, { {"bdquo", 5} } }, {0, { {NULL, 0} } },
	{0, { {"dagger", 6} } }, {0, { {"Dagger", 6} } }, {0, { {"bull", 4} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"hellip", 6} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"permil", 6} } }, {0, { {NULL, 0} } }, {0, { {"prime", 5} } }, {0, { {"Prime", 5} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"lsaquo", 6} } }, {0, { {"rsaquo", 6} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"oline", 5} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html4_02040[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"frasl", 5} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html4_02080[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"euro", 4} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html4_02100[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"image", 5} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"weierp", 6} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"real", 4} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"trade", 5} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"alefsym", 7} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html4_02180[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"larr", 4} } }, {0, { {"uarr", 4} } }, {0, { {"rarr", 4} } }, {0, { {"darr", 4} } },
	{0, { {"harr", 4} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"crarr", 5} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html4_021C0[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"lArr", 4} } }, {0, { {"uArr", 4} } }, {0, { {"rArr", 4} } }, {0, { {"dArr", 4} } },
	{0, { {"hArr", 4} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html4_02200[] = {
	{0, { {"forall", 6} } }, {0, { {NULL, 0} } }, {0, { {"part", 4} } }, {0, { {"exist", 5} } },
	{0, { {NULL, 0} } }, {0, { {"empty", 5} } }, {0, { {NULL, 0} } }, {0, { {"nabla", 5} } },
	{0, { {"isin", 4} } }, {0, { {"notin", 5} } }, {0, { {NULL, 0} } }, {0, { {"ni", 2} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"prod", 4} } },
	{0, { {NULL, 0} } }, {0, { {"sum", 3} } }, {0, { {"minus", 5} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"lowast", 6} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"radic", 5} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"prop", 4} } }, {0, { {"infin", 5} } }, {0, { {NULL, 0} } },
	{0, { {"ang", 3} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"and", 3} } },
	{0, { {"or", 2} } }, {0, { {"cap", 3} } }, {0, { {"cup", 3} } }, {0, { {"int", 3} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"there4", 6} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"sim", 3} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html4_02240[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"cong", 4} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"asymp", 5} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"ne", 2} } }, {0, { {"equiv", 5} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"le", 2} } }, {0, { {"ge", 2} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html4_02280[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"sub", 3} } }, {0, { {"sup", 3} } },
	{0, { {"nsub", 4} } }, {0, { {NULL, 0} } }, {0, { {"sube", 4} } }, {0, { {"supe", 4} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"oplus", 5} } }, {0, { {NULL, 0} } }, {0, { {"otimes", 6} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"perp", 4} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html4_022C0[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"sdot", 4} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html4_02300[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"lceil", 5} } }, {0, { {"rceil", 5} } }, {0, { {"lfloor", 6} } }, {0, { {"rfloor", 6} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {"lang", 4} } }, {0, { {"rang", 4} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html4_025C0[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"loz", 3} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

static const entity_stage3_row stage3_table_html4_02640[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"spades", 6} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"clubs", 5} } },
	{0, { {NULL, 0} } }, {0, { {"hearts", 6} } }, {0, { {"diams", 5} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
};

/* end of stage 3 Tables for HTML 4.01 }}} */

/* {{{ Stage 2 Tables for HTML 4.01 */

static const entity_stage2_row stage2_table_html4_00000[] = {
	stage3_table_html4_00000, empty_stage3_table, stage3_table_html4_00080, stage3_table_html4_000C0,
	empty_stage3_table, stage3_table_html4_00140, stage3_table_html4_00180, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, stage3_table_html4_002C0,
	empty_stage3_table, empty_stage3_table, stage3_table_html4_00380, stage3_table_html4_003C0,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
};

static const entity_stage2_row stage2_table_html4_02000[] = {
	stage3_table_html4_02000, stage3_table_html4_02040, stage3_table_html4_02080, empty_stage3_table,
	stage3_table_html4_02100, empty_stage3_table, stage3_table_html4_02180, stage3_table_html4_021C0,
	stage3_table_html4_02200, stage3_table_html4_02240, stage3_table_html4_02280, stage3_table_html4_022C0,
	stage3_table_html4_02300, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, stage3_table_html4_025C0,
	empty_stage3_table, stage3_table_html4_02640, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
	empty_stage3_table, empty_stage3_table, empty_stage3_table, empty_stage3_table,
};

/* end of stage 2 tables for HTML 4.01 }}} */

static const entity_stage1_row entity_ms_table_html4[] = {
	stage2_table_html4_00000,
	empty_stage2_table,
	stage2_table_html4_02000,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
	empty_stage2_table,
};

/* end of HTML 4.01 multi-stage table for codepoint -> entity }}} */

/* {{{ HTML 4.01 hash table for entity -> codepoint */

static const entity_cp_map ht_bucket_html4_000[] = { {"gt", 2, 0x0003E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_003[] = { {"Igrave", 6, 0x000CC, 0}, {"amp", 3, 0x00026, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_006[] = { {"oacute", 6, 0x000F3, 0}, {"Xi", 2, 0x0039E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_008[] = { {"uuml", 4, 0x000FC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_00B[] = { {"Alpha", 5, 0x00391, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_00E[] = { {"sim", 3, 0x0223C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_012[] = { {"kappa", 5, 0x003BA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_016[] = { {"lArr", 4, 0x021D0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_018[] = { {"and", 3, 0x02227, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_01B[] = { {"ang", 3, 0x02220, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_020[] = { {"copy", 4, 0x000A9, 0}, {"Iacute", 6, 0x000CD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_023[] = { {"igrave", 6, 0x000EC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_026[] = { {"xi", 2, 0x003BE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_027[] = { {"Acirc", 5, 0x000C2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_02B[] = { {"Ecirc", 5, 0x000CA, 0}, {"alpha", 5, 0x003B1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_02C[] = { {"hearts", 6, 0x02665, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_02F[] = { {"Icirc", 5, 0x000CE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_030[] = { {"Yacute", 6, 0x000DD, 0}, {"int", 3, 0x0222B, 0}, {"rlm", 3, 0x0200F, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_034[] = { {"empty", 5, 0x02205, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_036[] = { {"larr", 4, 0x02190, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_03B[] = { {"Ucirc", 5, 0x000DB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_03C[] = { {"oline", 5, 0x0203E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_040[] = { {"iacute", 6, 0x000ED, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_046[] = { {"middot", 6, 0x000B7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_047[] = { {"acirc", 5, 0x000E2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_04B[] = { {"ecirc", 5, 0x000EA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_04F[] = { {"icirc", 5, 0x000EE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_050[] = { {"yacute", 6, 0x000FD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_051[] = { {"minus", 5, 0x02212, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_054[] = { {"Auml", 4, 0x000C4, 0}, {"thetasym", 8, 0x003D1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_056[] = { {"Sigma", 5, 0x003A3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_059[] = { {"lsquo", 5, 0x02018, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_05B[] = { {"ucirc", 5, 0x000FB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_05C[] = { {"rArr", 4, 0x021D2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_064[] = { {"brvbar", 6, 0x000A6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_067[] = { {"AElig", 5, 0x000C6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_069[] = { {"Ccedil", 6, 0x000C7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_071[] = { {"Psi", 3, 0x003A8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_072[] = { {"exist", 5, 0x02203, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_074[] = { {"auml", 4, 0x000E4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_076[] = { {"sigma", 5, 0x003C3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_078[] = { {"isin", 4, 0x02208, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_07C[] = { {"rarr", 4, 0x02192, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_089[] = { {"ccedil", 6, 0x000E7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_08D[] = { {"raquo", 5, 0x000BB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_08E[] = { {"Omega", 5, 0x003A9, 0}, {"zwnj", 4, 0x0200C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_091[] = { {"psi", 3, 0x003C8, 0}, {"there4", 6, 0x02234, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_092[] = { {"hArr", 4, 0x021D4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_096[] = { {"le", 2, 0x02264, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_098[] = { {"Atilde", 6, 0x000C3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_099[] = { {"Zeta", 4, 0x00396, 0}, {"infin", 5, 0x0221E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_09D[] = { {"frasl", 5, 0x02044, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0A0[] = { {"euro", 4, 0x020AC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0A5[] = { {"lt", 2, 0x0003C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0A7[] = { {"aelig", 5, 0x000E6, 0}, {"Mu", 2, 0x0039C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0A8[] = { {"macr", 4, 0x000AF, 0}, {"image", 5, 0x02111, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0AA[] = { {"ldquo", 5, 0x0201C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0AE[] = { {"omega", 5, 0x003C9, 0}, {"upsih", 5, 0x003D2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0B0[] = { {"THORN", 5, 0x000DE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0B2[] = { {"Iota", 4, 0x00399, 0}, {"harr", 4, 0x02194, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0B4[] = { {"bull", 4, 0x02022, 0}, {"rceil", 5, 0x02309, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0B8[] = { {"atilde", 6, 0x000E3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0B9[] = { {"zeta", 4, 0x003B6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0BA[] = { {"emsp", 4, 0x02003, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0BC[] = { {"perp", 4, 0x022A5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0C2[] = { {"Prime", 5, 0x02033, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0C4[] = { {"frac12", 6, 0x000BD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0C5[] = { {"Ntilde", 6, 0x000D1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0C6[] = { {"frac14", 6, 0x000BC, 0}, {"circ", 4, 0x002C6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0C7[] = { {"mu", 2, 0x003BC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0C8[] = { {"Gamma", 5, 0x00393, 0}, {"Nu", 2, 0x0039D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0CE[] = { {"fnof", 4, 0x00192, 0}, {"quot", 4, 0x00022, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0D2[] = { {"iota", 4, 0x003B9, 0}, {"mdash", 5, 0x02014, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0D8[] = { {"ne", 2, 0x02260, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0DB[] = { {"Theta", 5, 0x00398, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0DC[] = { {"ni", 2, 0x0220B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0E2[] = { {"prime", 5, 0x02032, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0E5[] = { {"ntilde", 6, 0x000F1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0E6[] = { {"Lambda", 6, 0x0039B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0E8[] = { {"gamma", 5, 0x003B3, 0}, {"nu", 2, 0x003BD, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0EB[] = { {"pound", 5, 0x000A3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0EE[] = { {"permil", 6, 0x02030, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0F9[] = { {"cap", 3, 0x02229, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0FA[] = { {"iexcl", 5, 0x000A1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0FB[] = { {"Agrave", 6, 0x000C0, 0}, {"theta", 5, 0x003B8, 0}, {"ensp", 4, 0x02002, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0FE[] = { {"Pi", 2, 0x003A0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_0FF[] = { {"crarr", 5, 0x021B5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_100[] = { {"iquest", 6, 0x000BF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_105[] = { {"forall", 6, 0x02200, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_106[] = { {"Phi", 3, 0x003A6, 0}, {"lambda", 6, 0x003BB, 0}, {"or", 2, 0x02228, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_108[] = { {"frac34", 6, 0x000BE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_10D[] = { {"notin", 5, 0x02209, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_10E[] = { {"dArr", 4, 0x021D3, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_10F[] = { {"Dagger", 6, 0x02021, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_111[] = { {"yen", 3, 0x000A5, 0}, {"weierp", 6, 0x02118, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_113[] = { {"uml", 3, 0x000A8, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_117[] = { {"tilde", 5, 0x002DC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_118[] = { {"Aacute", 6, 0x000C1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_11A[] = { {"loz", 3, 0x025CA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_11B[] = { {"agrave", 6, 0x000E0, 0}, {"thinsp", 6, 0x02009, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_11E[] = { {"pi", 2, 0x003C0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_11F[] = { {"micro", 5, 0x000B5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_125[] = { {"spades", 6, 0x02660, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_126[] = { {"phi", 3, 0x003C6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_12E[] = { {"darr", 4, 0x02193, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_12F[] = { {"Oslash", 6, 0x000D8, 0}, {"Tau", 3, 0x003A4, 0}, {"dagger", 6, 0x02020, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_135[] = { {"Ocirc", 5, 0x000D4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_136[] = { {"alefsym", 7, 0x02135, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_138[] = { {"aacute", 6, 0x000E1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_13A[] = { {"divide", 6, 0x000F7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_13F[] = { {"sdot", 4, 0x022C5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_143[] = { {"reg", 3, 0x000AE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_149[] = { {"real", 4, 0x0211C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_14B[] = { {"Scaron", 6, 0x00160, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_14F[] = { {"cent", 4, 0x000A2, 0}, {"oslash", 6, 0x000F8, 0}, {"tau", 3, 0x003C4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_150[] = { {"thorn", 5, 0x000FE, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_153[] = { {"ndash", 5, 0x02013, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_154[] = { {"piv", 3, 0x003D6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_155[] = { {"ocirc", 5, 0x000F4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_156[] = { {"Aring", 5, 0x000C5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_158[] = { {"nbsp", 4, 0x000A0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_15C[] = { {"Iuml", 4, 0x000CF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_15F[] = { {"rsquo", 5, 0x02019, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_160[] = { {"rsaquo", 6, 0x0203A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_163[] = { {"hellip", 6, 0x02026, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_166[] = { {"Otilde", 6, 0x000D5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_16B[] = { {"scaron", 6, 0x00161, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_16C[] = { {"Yuml", 4, 0x00178, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_16E[] = { {"sup1", 4, 0x000B9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_16F[] = { {"sup2", 4, 0x000B2, 0}, {"Delta", 5, 0x00394, 0}, {"sbquo", 5, 0x0201A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_170[] = { {"sup3", 4, 0x000B3, 0}, {"lrm", 3, 0x0200E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_173[] = { {"diams", 5, 0x02666, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_175[] = { {"OElig", 5, 0x00152, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_176[] = { {"aring", 5, 0x000E5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_178[] = { {"oplus", 5, 0x02295, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_17C[] = { {"iuml", 4, 0x000EF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_17F[] = { {"Egrave", 6, 0x000C8, 0}, {"uArr", 4, 0x021D1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_181[] = { {"Beta", 4, 0x00392, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_183[] = { {"nabla", 5, 0x02207, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_186[] = { {"ETH", 3, 0x000D0, 0}, {"otilde", 6, 0x000F5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_187[] = { {"laquo", 5, 0x000AB, 0}, {"times", 5, 0x000D7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_18C[] = { {"yuml", 4, 0x000FF, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_18D[] = { {"cup", 3, 0x0222A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_18E[] = { {"Rho", 3, 0x003A1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_18F[] = { {"Ugrave", 6, 0x000D9, 0}, {"delta", 5, 0x003B4, 0}, {"equiv", 5, 0x02261, 0}, {"sub", 3, 0x02282, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_194[] = { {"curren", 6, 0x000A4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_196[] = { {"not", 3, 0x000AC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_197[] = { {"acute", 5, 0x000B4, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_19A[] = { {"prod", 4, 0x0220F, 0}, {"sum", 3, 0x02211, 0}, {"lsaquo", 6, 0x02039, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_19C[] = { {"Eacute", 6, 0x000C9, 0}, {"Omicron", 7, 0x0039F, 0}, {"sigmaf", 6, 0x003C2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_19D[] = { {"sup", 3, 0x02283, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_19F[] = { {"egrave", 6, 0x000E8, 0}, {"uarr", 4, 0x02191, 0}, {"lowast", 6, 0x02217, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1A0[] = { {"zwj", 3, 0x0200D, 0}, {"bdquo", 5, 0x0201E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1A1[] = { {"beta", 4, 0x003B2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1A2[] = { {"Ouml", 4, 0x000D6, 0}, {"supe", 4, 0x02287, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1A4[] = { {"plusmn", 6, 0x000B1, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1A6[] = { {"cedil", 5, 0x000B8, 0}, {"prop", 4, 0x0221D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1A7[] = { {"lang", 4, 0x02329, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1A8[] = { {"radic", 5, 0x0221A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1A9[] = { {"para", 4, 0x000B6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1AC[] = { {"Uacute", 6, 0x000DA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1AE[] = { {"szlig", 5, 0x000DF, 0}, {"rho", 3, 0x003C1, 0}, {"lceil", 5, 0x02308, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1AF[] = { {"ugrave", 6, 0x000F9, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1B0[] = { {"rdquo", 5, 0x0201D, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1B5[] = { {"deg", 3, 0x000B0, 0}, {"trade", 5, 0x02122, 0}, {"oelig", 5, 0x00153, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1B9[] = { {"Chi", 3, 0x003A7, 0}, {"rfloor", 6, 0x0230B, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1BC[] = { {"eacute", 6, 0x000E9, 0}, {"omicron", 7, 0x003BF, 0}, {"part", 4, 0x02202, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1BE[] = { {"clubs", 5, 0x02663, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1BF[] = { {"Epsilon", 7, 0x00395, 0}, {"Eta", 3, 0x00397, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1C2[] = { {"ouml", 4, 0x000F6, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1C4[] = { {"#039", 4, 0x00027, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1C9[] = { {"Ograve", 6, 0x000D2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1CC[] = { {"uacute", 6, 0x000FA, 0}, {"cong", 4, 0x02245, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1CF[] = { {"Upsilon", 7, 0x003A5, 0}, {"asymp", 5, 0x02248, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1D0[] = { {"ordf", 4, 0x000AA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1D4[] = { {"sube", 4, 0x02286, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1D7[] = { {"ordm", 4, 0x000BA, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1D8[] = { {"Euml", 4, 0x000CB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1D9[] = { {"chi", 3, 0x003C7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1DD[] = { {"nsub", 4, 0x02284, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1DF[] = { {"epsilon", 7, 0x003B5, 0}, {"eta", 3, 0x003B7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1E6[] = { {"Oacute", 6, 0x000D3, 0}, {"eth", 3, 0x000F0, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1E8[] = { {"Uuml", 4, 0x000DC, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1E9[] = { {"ograve", 6, 0x000F2, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1ED[] = { {"rang", 4, 0x0232A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1EF[] = { {"upsilon", 7, 0x003C5, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1F1[] = { {"ge", 2, 0x02265, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1F2[] = { {"Kappa", 5, 0x0039A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1F3[] = { {"lfloor", 6, 0x0230A, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1F4[] = { {"sect", 4, 0x000A7, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1F6[] = { {"otimes", 6, 0x02297, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1F8[] = { {"euml", 4, 0x000EB, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_html4_1F9[] = { {"shy", 3, 0x000AD, 0}, {NULL, 0, 0, 0} };

static const entity_cp_map *const ht_buckets_html4[] = {
	ht_bucket_html4_000, ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_003,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_006, ht_bucket_empty,
	ht_bucket_html4_008, ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_00B,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_00E, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_012, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_016, ht_bucket_empty,
	ht_bucket_html4_018, ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_01B,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html4_020, ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_023,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_026, ht_bucket_html4_027,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_02B,
	ht_bucket_html4_02C, ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_02F,
	ht_bucket_html4_030, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html4_034, ht_bucket_empty, ht_bucket_html4_036, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_03B,
	ht_bucket_html4_03C, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html4_040, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_046, ht_bucket_html4_047,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_04B,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_04F,
	ht_bucket_html4_050, ht_bucket_html4_051, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html4_054, ht_bucket_empty, ht_bucket_html4_056, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html4_059, ht_bucket_empty, ht_bucket_html4_05B,
	ht_bucket_html4_05C, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html4_064, ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_067,
	ht_bucket_empty, ht_bucket_html4_069, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html4_071, ht_bucket_html4_072, ht_bucket_empty,
	ht_bucket_html4_074, ht_bucket_empty, ht_bucket_html4_076, ht_bucket_empty,
	ht_bucket_html4_078, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html4_07C, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html4_089, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html4_08D, ht_bucket_html4_08E, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html4_091, ht_bucket_html4_092, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_096, ht_bucket_empty,
	ht_bucket_html4_098, ht_bucket_html4_099, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html4_09D, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html4_0A0, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html4_0A5, ht_bucket_empty, ht_bucket_html4_0A7,
	ht_bucket_html4_0A8, ht_bucket_empty, ht_bucket_html4_0AA, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_0AE, ht_bucket_empty,
	ht_bucket_html4_0B0, ht_bucket_empty, ht_bucket_html4_0B2, ht_bucket_empty,
	ht_bucket_html4_0B4, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html4_0B8, ht_bucket_html4_0B9, ht_bucket_html4_0BA, ht_bucket_empty,
	ht_bucket_html4_0BC, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_0C2, ht_bucket_empty,
	ht_bucket_html4_0C4, ht_bucket_html4_0C5, ht_bucket_html4_0C6, ht_bucket_html4_0C7,
	ht_bucket_html4_0C8, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_0CE, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_0D2, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html4_0D8, ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_0DB,
	ht_bucket_html4_0DC, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_0E2, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html4_0E5, ht_bucket_html4_0E6, ht_bucket_empty,
	ht_bucket_html4_0E8, ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_0EB,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_0EE, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html4_0F9, ht_bucket_html4_0FA, ht_bucket_html4_0FB,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_0FE, ht_bucket_html4_0FF,
	ht_bucket_html4_100, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html4_105, ht_bucket_html4_106, ht_bucket_empty,
	ht_bucket_html4_108, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html4_10D, ht_bucket_html4_10E, ht_bucket_html4_10F,
	ht_bucket_empty, ht_bucket_html4_111, ht_bucket_empty, ht_bucket_html4_113,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_117,
	ht_bucket_html4_118, ht_bucket_empty, ht_bucket_html4_11A, ht_bucket_html4_11B,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_11E, ht_bucket_html4_11F,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html4_125, ht_bucket_html4_126, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_12E, ht_bucket_html4_12F,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html4_135, ht_bucket_html4_136, ht_bucket_empty,
	ht_bucket_html4_138, ht_bucket_empty, ht_bucket_html4_13A, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_13F,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_143,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html4_149, ht_bucket_empty, ht_bucket_html4_14B,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_14F,
	ht_bucket_html4_150, ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_153,
	ht_bucket_html4_154, ht_bucket_html4_155, ht_bucket_html4_156, ht_bucket_empty,
	ht_bucket_html4_158, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html4_15C, ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_15F,
	ht_bucket_html4_160, ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_163,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_166, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_16B,
	ht_bucket_html4_16C, ht_bucket_empty, ht_bucket_html4_16E, ht_bucket_html4_16F,
	ht_bucket_html4_170, ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_173,
	ht_bucket_empty, ht_bucket_html4_175, ht_bucket_html4_176, ht_bucket_empty,
	ht_bucket_html4_178, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html4_17C, ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_17F,
	ht_bucket_empty, ht_bucket_html4_181, ht_bucket_empty, ht_bucket_html4_183,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_186, ht_bucket_html4_187,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html4_18C, ht_bucket_html4_18D, ht_bucket_html4_18E, ht_bucket_html4_18F,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html4_194, ht_bucket_empty, ht_bucket_html4_196, ht_bucket_html4_197,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_19A, ht_bucket_empty,
	ht_bucket_html4_19C, ht_bucket_html4_19D, ht_bucket_empty, ht_bucket_html4_19F,
	ht_bucket_html4_1A0, ht_bucket_html4_1A1, ht_bucket_html4_1A2, ht_bucket_empty,
	ht_bucket_html4_1A4, ht_bucket_empty, ht_bucket_html4_1A6, ht_bucket_html4_1A7,
	ht_bucket_html4_1A8, ht_bucket_html4_1A9, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html4_1AC, ht_bucket_empty, ht_bucket_html4_1AE, ht_bucket_html4_1AF,
	ht_bucket_html4_1B0, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html4_1B5, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html4_1B9, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html4_1BC, ht_bucket_empty, ht_bucket_html4_1BE, ht_bucket_html4_1BF,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_1C2, ht_bucket_empty,
	ht_bucket_html4_1C4, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html4_1C9, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html4_1CC, ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_1CF,
	ht_bucket_html4_1D0, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_html4_1D4, ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_1D7,
	ht_bucket_html4_1D8, ht_bucket_html4_1D9, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html4_1DD, ht_bucket_empty, ht_bucket_html4_1DF,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_html4_1E6, ht_bucket_empty,
	ht_bucket_html4_1E8, ht_bucket_html4_1E9, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_html4_1ED, ht_bucket_empty, ht_bucket_html4_1EF,
	ht_bucket_empty, ht_bucket_html4_1F1, ht_bucket_html4_1F2, ht_bucket_html4_1F3,
	ht_bucket_html4_1F4, ht_bucket_empty, ht_bucket_html4_1F6, ht_bucket_empty,
	ht_bucket_html4_1F8, ht_bucket_html4_1F9, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
};

static const entity_ht ent_ht_html4 = {
	0x200,
	ht_buckets_html4
};

/* end of HTML 4.01 hash table for entity -> codepoint }}} */

/* {{{ Start of Basic entities (no apos) table for codepoint -> entity */

static const entity_stage3_row stage3_table_be_noapos_00000[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"quot", 4} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"amp", 3} } }, {0, { {"#039", 4} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"lt", 2} } }, {0, { {NULL, 0} } }, {0, { {"gt", 2} } }, {0, { {NULL, 0} } },
};

/* {{{ Basic entities (no apos) hash table for entity -> codepoint */

static const entity_cp_map ht_bucket_be_noapos_000[] = { {"gt", 2, 0x0003E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_be_noapos_003[] = { {"amp", 3, 0x00026, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_be_noapos_004[] = { {"#039", 4, 0x00027, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_be_noapos_005[] = { {"lt", 2, 0x0003C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_be_noapos_00E[] = { {"quot", 4, 0x00022, 0}, {NULL, 0, 0, 0} };

static const entity_cp_map *const ht_buckets_be_noapos[] = {
	ht_bucket_be_noapos_000, ht_bucket_empty, ht_bucket_empty, ht_bucket_be_noapos_003,
	ht_bucket_be_noapos_004, ht_bucket_be_noapos_005, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_be_noapos_00E, ht_bucket_empty,
};

static const entity_ht ent_ht_be_noapos = {
	0x10,
	ht_buckets_be_noapos
};

/* end of Basic entities (no apos) hash table for entity -> codepoint }}} */

/* {{{ Start of Basic entities (with apos) table for codepoint -> entity */

static const entity_stage3_row stage3_table_be_apos_00000[] = {
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"quot", 4} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {"amp", 3} } }, {0, { {"apos", 4} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } }, {0, { {NULL, 0} } },
	{0, { {"lt", 2} } }, {0, { {NULL, 0} } }, {0, { {"gt", 2} } }, {0, { {NULL, 0} } },
};

/* {{{ Basic entities (with apos) hash table for entity -> codepoint */

static const entity_cp_map ht_bucket_be_apos_000[] = { {"gt", 2, 0x0003E, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_be_apos_003[] = { {"amp", 3, 0x00026, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_be_apos_005[] = { {"lt", 2, 0x0003C, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_be_apos_008[] = { {"apos", 4, 0x00027, 0}, {NULL, 0, 0, 0} };
static const entity_cp_map ht_bucket_be_apos_00E[] = { {"quot", 4, 0x00022, 0}, {NULL, 0, 0, 0} };

static const entity_cp_map *const ht_buckets_be_apos[] = {
	ht_bucket_be_apos_000, ht_bucket_empty, ht_bucket_empty, ht_bucket_be_apos_003,
	ht_bucket_empty, ht_bucket_be_apos_005, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_be_apos_008, ht_bucket_empty, ht_bucket_empty, ht_bucket_empty,
	ht_bucket_empty, ht_bucket_empty, ht_bucket_be_apos_00E, ht_bucket_empty,
};

static const entity_ht ent_ht_be_apos = {
	0x10,
	ht_buckets_be_apos
};

/* end of Basic entities (with apos) hash table for entity -> codepoint }}} */

#endif /* HTML_TABLES_H */
php/ext/standard/php_image.h000064400000004530151730541070012042 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Rasmus Lerdorf <rasmus@php.net>                             |
   |          Marcus Boerger <helly@php.net>                              |
   +----------------------------------------------------------------------+
*/

/* $Id: php_image.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_IMAGE_H
#define PHP_IMAGE_H

PHP_FUNCTION(getimagesize);

PHP_FUNCTION(image_type_to_mime_type);
PHP_FUNCTION(image_type_to_extension);

/* {{{ enum image_filetype
   This enum is used to have ext/standard/image.c and ext/exif/exif.c use
   the same constants for file types.
*/
typedef enum
{ IMAGE_FILETYPE_UNKNOWN=0,
  IMAGE_FILETYPE_GIF=1,
  IMAGE_FILETYPE_JPEG,
  IMAGE_FILETYPE_PNG,
  IMAGE_FILETYPE_SWF,
  IMAGE_FILETYPE_PSD,
  IMAGE_FILETYPE_BMP,
  IMAGE_FILETYPE_TIFF_II, /* intel */
  IMAGE_FILETYPE_TIFF_MM, /* motorola */
  IMAGE_FILETYPE_JPC,
  IMAGE_FILETYPE_JP2,
  IMAGE_FILETYPE_JPX,
  IMAGE_FILETYPE_JB2,
  IMAGE_FILETYPE_SWC,
  IMAGE_FILETYPE_IFF,
  IMAGE_FILETYPE_WBMP,
  /* IMAGE_FILETYPE_JPEG2000 is a userland alias for IMAGE_FILETYPE_JPC */
  IMAGE_FILETYPE_XBM
/* WHEN EXTENDING: PLEASE ALSO REGISTER IN image.c:PHP_MINIT_FUNCTION(imagetypes) */
} image_filetype;
/* }}} */

PHP_MINIT_FUNCTION(imagetypes);

PHPAPI int php_getimagetype(php_stream *stream, char *filetype TSRMLS_DC);

PHPAPI char * php_image_type_to_mime_type(int image_type);

#endif /* PHP_IMAGE_H */
php/ext/standard/head.h000064400000003157151730541070011016 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Rasmus Lerdorf <rasmus@lerdorf.on.ca>                        |
   +----------------------------------------------------------------------+
*/

/* $Id: head.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef HEAD_H
#define HEAD_H

extern PHP_RINIT_FUNCTION(head);
PHP_FUNCTION(header);
PHP_FUNCTION(setcookie);
PHP_FUNCTION(setrawcookie);
PHP_FUNCTION(headers_sent);
PHP_FUNCTION(headers_list);

PHPAPI int php_header(TSRMLS_D);
PHPAPI int php_setcookie(char *name, int name_len, char *value, int value_len, time_t expires, char *path, int path_len, char *domain, int domain_len, int secure, int url_encode, int httponly TSRMLS_DC);

#endif
php/ext/standard/php_ext_syslog.h000064400000003106151730541070013156 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Stig S�ther Bakken <ssb@php.net>                             |
   +----------------------------------------------------------------------+
*/

/* $Id: php_ext_syslog.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_EXT_SYSLOG_H
#define PHP_EXT_SYSLOG_H

#ifdef HAVE_SYSLOG_H

#include "php_syslog.h"

PHP_MINIT_FUNCTION(syslog);
PHP_RINIT_FUNCTION(syslog);
#ifdef PHP_WIN32
PHP_RSHUTDOWN_FUNCTION(syslog);
#endif
PHP_MSHUTDOWN_FUNCTION(syslog);

PHP_FUNCTION(openlog);
PHP_FUNCTION(syslog);
PHP_FUNCTION(closelog);
PHP_FUNCTION(define_syslog_variables);

#endif

#endif /* PHP_EXT_SYSLOG_H */
php/ext/standard/pageinfo.h000064400000002754151730541070011707 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Jim Winstead <jimw@php.net>                                  |
   +----------------------------------------------------------------------+
*/

/* $Id: pageinfo.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PAGEINFO_H
#define PAGEINFO_H

PHP_FUNCTION(getmyuid);
PHP_FUNCTION(getmygid);
PHP_FUNCTION(getmypid);
PHP_FUNCTION(getmyinode);
PHP_FUNCTION(getlastmod);

PHPAPI void php_statpage(TSRMLS_D);
PHPAPI long php_getlastmod(TSRMLS_D);
extern long php_getuid(void);
extern long php_getgid(void);

#endif
php/ext/standard/base64.h000064400000003175151730541070011201 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Jim Winstead <jimw@php.net>                                  |
   +----------------------------------------------------------------------+
*/

/* $Id: base64.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef BASE64_H
#define BASE64_H

PHP_FUNCTION(base64_decode);
PHP_FUNCTION(base64_encode);

PHPAPI extern unsigned char *php_base64_encode(const unsigned char *, int, int *);
PHPAPI extern unsigned char *php_base64_decode_ex(const unsigned char *, int, int *, zend_bool);
PHPAPI extern unsigned char *php_base64_decode(const unsigned char *, int, int *);

#endif /* BASE64_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 */
php/ext/standard/php_standard.h000064400000004411151730541100012550 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author:                                                              |
   +----------------------------------------------------------------------+
*/

/* $Id: php_standard.h 293036 2010-01-03 09:23:27Z sebastian $ */

#include "basic_functions.h"
#include "php_math.h"
#include "php_string.h"
#include "base64.h"
#include "php_dir.h"
#include "php_dns.h"
#include "reg.h"
#include "php_mail.h"
#include "md5.h"
#include "sha1.h"
#include "html.h"
#include "exec.h"
#include "file.h"
#include "php_ext_syslog.h"
#include "php_filestat.h"
#include "php_browscap.h"
#include "pack.h"
#include "datetime.h"
#include "microtime.h"
#include "url.h"
#include "pageinfo.h"
#include "cyr_convert.h"
#include "php_link.h"
#include "fsock.h"
#include "php_image.h"
#include "php_iptc.h"
#include "info.h"
#include "uniqid.h"
#include "php_var.h"
#include "quot_print.h"
#include "dl.h"
#include "php_crypt.h"
#include "head.h"
#include "php_lcg.h"
#include "php_metaphone.h"
#include "php_output.h"
#include "php_array.h"
#include "php_assert.h"
#include "php_versioning.h"
#include "php_ftok.h"
#include "php_type.h"

#define phpext_standard_ptr basic_functions_module_ptr
PHP_MINIT_FUNCTION(standard_filters);
PHP_MSHUTDOWN_FUNCTION(standard_filters);


/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 */
php/ext/standard/php_filestat.h000064400000006310151730541100012563 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author:  Jim Winstead <jimw@php.net>                                 |
   +----------------------------------------------------------------------+
*/

/* $Id: php_filestat.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_FILESTAT_H
#define PHP_FILESTAT_H

PHP_RINIT_FUNCTION(filestat);
PHP_RSHUTDOWN_FUNCTION(filestat);

PHP_FUNCTION(clearstatcache);
PHP_FUNCTION(fileatime);
PHP_FUNCTION(filectime);
PHP_FUNCTION(filegroup);
PHP_FUNCTION(fileinode);
PHP_FUNCTION(filemtime);
PHP_FUNCTION(fileowner);
PHP_FUNCTION(fileperms);
PHP_FUNCTION(filesize);
PHP_FUNCTION(filetype);
PHP_FUNCTION(is_writable);
PHP_FUNCTION(is_readable);
PHP_FUNCTION(is_executable);
PHP_FUNCTION(is_file);
PHP_FUNCTION(is_dir);
PHP_FUNCTION(is_link);
PHP_FUNCTION(file_exists);
PHP_NAMED_FUNCTION(php_if_stat);
PHP_NAMED_FUNCTION(php_if_lstat);
PHP_FUNCTION(disk_total_space);
PHP_FUNCTION(disk_free_space);
PHP_FUNCTION(chown);
PHP_FUNCTION(chgrp);
#if HAVE_LCHOWN
PHP_FUNCTION(lchown);
#endif
#if HAVE_LCHOWN
PHP_FUNCTION(lchgrp);
#endif
PHP_FUNCTION(chmod);
#if HAVE_UTIME
PHP_FUNCTION(touch);
#endif
PHP_FUNCTION(clearstatcache);

#define MAKE_LONG_ZVAL_INCREF(name, val)\
	MAKE_STD_ZVAL(name); \
	ZVAL_LONG(name, val); \
	name->refcount++; 

#ifdef PHP_WIN32
#define S_IRUSR S_IREAD
#define S_IWUSR S_IWRITE
#define S_IXUSR S_IEXEC
#define S_IRGRP S_IREAD
#define S_IWGRP S_IWRITE
#define S_IXGRP S_IEXEC
#define S_IROTH S_IREAD
#define S_IWOTH S_IWRITE
#define S_IXOTH S_IEXEC

#undef getgid
#define getgroups(a, b) 0
#define getgid() 1
#define getuid() 1
#endif

#ifdef PHP_WIN32
typedef unsigned int php_stat_len;
#else
typedef int php_stat_len;
#endif

PHPAPI void php_clear_stat_cache(TSRMLS_D);
PHPAPI void php_stat(const char *filename, php_stat_len filename_length, int type, zval *return_value TSRMLS_DC);

/* Switches for various filestat functions: */
#define FS_PERMS    0
#define FS_INODE    1
#define FS_SIZE     2
#define FS_OWNER    3
#define FS_GROUP    4
#define FS_ATIME    5
#define FS_MTIME    6
#define FS_CTIME    7
#define FS_TYPE     8
#define FS_IS_W     9
#define FS_IS_R    10
#define FS_IS_X    11
#define FS_IS_FILE 12
#define FS_IS_DIR  13
#define FS_IS_LINK 14
#define FS_EXISTS  15
#define FS_LSTAT   16
#define FS_STAT    17

#endif /* PHP_FILESTAT_H */
php/ext/standard/css.h000064400000002405151730541100010672 0ustar00/* 
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Colin Viebrock <colin@easydns.com>                          |
   +----------------------------------------------------------------------+
*/

/* $Id: css.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef CSS_H
#define CSS_H

PHPAPI void php_info_print_css(TSRMLS_D);

#endif
php/ext/standard/pack.h000064400000002456151730541100011026 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Rasmus Lerdorf <rasmus@lerdorf.on.ca>                        |
   +----------------------------------------------------------------------+
*/

/* $Id: pack.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PACK_H
#define PACK_H

PHP_MINIT_FUNCTION(pack);
PHP_FUNCTION(pack);
PHP_FUNCTION(unpack);

#endif /* PACK_H */
php/ext/standard/php_uuencode.h000064400000003020151730541100012552 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Ilia Alshanetsky <ilia@php.net>                              |
   +----------------------------------------------------------------------+
*/

/* $Id: php_uuencode.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_UUENCODE_H
#define PHP_UUENCODE_H

PHP_FUNCTION(convert_uudecode);
PHP_FUNCTION(convert_uuencode);

PHPAPI int php_uudecode(char *src, int src_len, char **dest);
PHPAPI int php_uuencode(char *src, int src_len, char **dest);

#endif /* PHP_UUENCODE_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 */
php/ext/standard/crypt_blowfish.h000064400000002030151730541110013133 0ustar00/* $Id$ */
/*
 * Written by Solar Designer <solar at openwall.com> in 2000-2011.
 * No copyright is claimed, and the software is hereby placed in the public
 * domain. In case this attempt to disclaim copyright and place the software
 * in the public domain is deemed null and void, then the software is
 * Copyright (c) 2000-2011 Solar Designer and it is hereby released to the
 * general public under the following terms:
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted.
 *
 * There's ABSOLUTELY NO WARRANTY, express or implied.
 *
 * See crypt_blowfish.c for more information.
 */

#ifndef _CRYPT_BLOWFISH_H
#define _CRYPT_BLOWFISH_H

#if 0
extern int _crypt_output_magic(const char *setting, char *output, int size);
#endif
extern char *php_crypt_blowfish_rn(const char *key, const char *setting,
	char *output, int size);
#if 0
extern char *_crypt_gensalt_blowfish_rn(const char *prefix,
	unsigned long count,
	const char *input, int size, char *output, int output_size);
#endif

#endif
php/ext/standard/dl.h000064400000003035151730541110010502 0ustar00/* 
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Brian Schaffner <brian@tool.net>                            |
   |          Shane Caraveo <shane@caraveo.com>                           |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: dl.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef DL_H
#define DL_H

PHPAPI void php_dl(zval *file,int type, zval *return_value, int start_now TSRMLS_DC);

/* dynamic loading functions */
PHP_FUNCTION(dl);

PHP_MINFO_FUNCTION(dl);

#endif /* DL_H */
php/ext/standard/php_ftok.h000064400000002443151730541110011717 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Andrew Sitnikov <sitnikov@infonet.ee>                        |
   +----------------------------------------------------------------------+
*/

/* $Id: php_ftok.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_FTOK_H
#define PHP_FTOK_H

#if HAVE_FTOK
PHP_FUNCTION(ftok);
#endif

#endif /* PHP_FTOK_H */
php/ext/standard/info.h000064400000007107151730541120011043 0ustar00/* 
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Rasmus Lerdorf <rasmus@php.net>                             |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: info.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef INFO_H
#define INFO_H

#define PHP_ENTRY_NAME_COLOR "#ccccff"
#define PHP_CONTENTS_COLOR "#cccccc"
#define PHP_HEADER_COLOR "#9999cc"

#define PHP_INFO_GENERAL			(1<<0)
#define PHP_INFO_CREDITS			(1<<1)
#define PHP_INFO_CONFIGURATION		(1<<2)
#define PHP_INFO_MODULES			(1<<3)
#define PHP_INFO_ENVIRONMENT		(1<<4)
#define PHP_INFO_VARIABLES			(1<<5)
#define PHP_INFO_LICENSE			(1<<6)
#define PHP_INFO_ALL				0xFFFFFFFF

#ifndef HAVE_CREDITS_DEFS
#define HAVE_CREDITS_DEFS

#define PHP_CREDITS_GROUP			(1<<0)
#define PHP_CREDITS_GENERAL			(1<<1)
#define PHP_CREDITS_SAPI			(1<<2)
#define PHP_CREDITS_MODULES			(1<<3)
#define PHP_CREDITS_DOCS			(1<<4)
#define PHP_CREDITS_FULLPAGE		(1<<5)
#define PHP_CREDITS_QA				(1<<6)
#define PHP_CREDITS_WEB             (1<<7)
#define PHP_CREDITS_ALL				0xFFFFFFFF

#endif /* HAVE_CREDITS_DEFS */

#define PHP_LOGO_GUID		  "PHPE9568F34-D428-11d2-A769-00AA001ACF42"
#define ZEND_LOGO_GUID		"PHPE9568F35-D428-11d2-A769-00AA001ACF42"
#define PHP_CREDITS_GUID  "PHPB8B5F2A0-3C92-11d3-A3A9-4C7B08C10000"

BEGIN_EXTERN_C()
PHP_FUNCTION(phpversion);
PHP_FUNCTION(phpinfo);
PHP_FUNCTION(phpcredits);
PHP_FUNCTION(php_logo_guid);
PHP_FUNCTION(php_real_logo_guid);
PHP_FUNCTION(zend_logo_guid);
PHP_FUNCTION(php_sapi_name);
PHP_FUNCTION(php_uname);
PHP_FUNCTION(php_ini_scanned_files);
PHP_FUNCTION(php_ini_loaded_file);
PHPAPI char *php_info_html_esc(char *string TSRMLS_DC);
PHPAPI void php_info_html_esc_write(char *string, int str_len TSRMLS_DC);
PHPAPI void php_print_info_htmlhead(TSRMLS_D);
PHPAPI void php_print_info(int flag TSRMLS_DC);
PHPAPI void php_print_style(void);
PHPAPI void php_info_print_style(TSRMLS_D);
PHPAPI void php_info_print_table_colspan_header(int num_cols, char *header);
PHPAPI void php_info_print_table_header(int num_cols, ...);
PHPAPI void php_info_print_table_row(int num_cols, ...);
PHPAPI void php_info_print_table_row_ex(int num_cols, const char *, ...);
PHPAPI void php_info_print_table_start(void);
PHPAPI void php_info_print_table_end(void);
PHPAPI void php_info_print_box_start(int bg);
PHPAPI void php_info_print_box_end(void);
PHPAPI void php_info_print_hr(void);
PHPAPI void php_info_print_module(zend_module_entry *module TSRMLS_DC);
PHPAPI char *php_logo_guid(void);
PHPAPI char *php_get_uname(char mode);

void register_phpinfo_constants(INIT_FUNC_ARGS);
END_EXTERN_C()

#endif /* INFO_H */
php/ext/standard/php_crypt.h000064400000003056151730541120012117 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Stig Bakken <ssb@php.net>                                   |
   |          Zeev Suraski <zeev@zend.com>                                |
   |          Rasmus Lerdorf <rasmus@php.net>                             |
   +----------------------------------------------------------------------+
*/

/* $Id: php_crypt.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_CRYPT_H
#define PHP_CRYPT_H

PHP_FUNCTION(crypt);
#if HAVE_CRYPT
PHP_MINIT_FUNCTION(crypt);
PHP_RINIT_FUNCTION(crypt);
#endif

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 */
php/ext/standard/php_browscap.h000064400000002547151730541120012602 0ustar00/* 
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Zeev Suraski <zeev@zend.com>                                 |
   +----------------------------------------------------------------------+
*/

/* $Id: php_browscap.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_BROWSCAP_H
#define PHP_BROWSCAP_H

PHP_MINIT_FUNCTION(browscap);
PHP_MSHUTDOWN_FUNCTION(browscap);

PHP_FUNCTION(get_browser);

#endif /* PHP_BROWSCAP_H */
php/ext/standard/php_crypt_r.h000064400000004004151730541130012433 0ustar00/* $Id$ */
/*
   +----------------------------------------------------------------------+
   | PHP Version 7                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2018 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Pierre Alain Joye  <pajoye@php.net                          |
   +----------------------------------------------------------------------+
 */

#ifndef _CRYPT_WIHN32_H_
#define _CRYPT_WIHN32_H_

#ifdef __cplusplus
extern "C"
{
#endif
#include "crypt_freesec.h"

#ifndef __const
#ifdef __GNUC__
#define __CONST __const
#else
#define __CONST
#endif
#else
#define __CONST __const
#endif

void php_init_crypt_r();
void php_shutdown_crypt_r();

extern void _crypt_extended_init_r(void);

/*PHPAPI char* crypt(const char *key, const char *salt);*/
PHPAPI char *php_crypt_r (const char *__key, const char *__salt, struct php_crypt_extended_data * __data);

#define MD5_HASH_MAX_LEN 120

#include "crypt_blowfish.h"

extern char * php_md5_crypt_r(const char *pw, const char *salt, char *out);
extern char * php_sha512_crypt_r (const char *key, const char *salt, char *buffer, int buflen);
extern char * php_sha256_crypt_r (const char *key, const char *salt, char *buffer, int buflen);

#ifdef __cplusplus
}
#endif

#endif /* _CRYPT_WIHN32_H_ */
php/ext/standard/php_lcg.h000064400000003062151730541130011521 0ustar00/* 
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Sascha Schumann <sascha@schumann.cx>                         |
   +----------------------------------------------------------------------+
*/

/* $Id: php_lcg.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_LCG_H
#define PHP_LCG_H

#include "ext/standard/basic_functions.h"

typedef struct {
	php_int32 s1;
	php_int32 s2;
	int seeded;
} php_lcg_globals;

PHPAPI double php_combined_lcg(TSRMLS_D);
PHP_FUNCTION(lcg_value);

PHP_MINIT_FUNCTION(lcg);

#ifdef ZTS
#define LCG(v) TSRMG(lcg_globals_id, php_lcg_globals *, v)
#else
#define LCG(v) (lcg_globals.v)
#endif

#endif
php/ext/standard/php_dns.h000064400000003710151730541130011540 0ustar00/* 
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: The typical suspects                                        |
   |          Marcus Boerger <helly@php.net>                              |
   |          Pollita <pollita@php.net>                                   |
   +----------------------------------------------------------------------+
*/

/* $Id: php_dns.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_DNS_H
#define PHP_DNS_H

#if HAVE_RES_NMKQUERY && HAVE_RES_NSEND && HAVE_DN_EXPAND && HAVE_DN_SKIPNAME
#define HAVE_DNS_FUNCS 1
#endif

PHP_FUNCTION(gethostbyaddr);
PHP_FUNCTION(gethostbyname);
PHP_FUNCTION(gethostbynamel);

#if HAVE_RES_SEARCH && !(defined(__BEOS__) || defined(PHP_WIN32) || defined(NETWARE))
PHP_FUNCTION(dns_check_record);
# if HAVE_DN_SKIPNAME && HAVE_DN_EXPAND
PHP_FUNCTION(dns_get_mx);
# endif

# if HAVE_DNS_FUNCS
PHP_FUNCTION(dns_get_record);
PHP_MINIT_FUNCTION(dns);
# endif
#endif

#ifndef INT16SZ
#define INT16SZ		2
#endif

#ifndef INT32SZ
#define INT32SZ		4
#endif

#endif /* PHP_DNS_H */
php/ext/standard/php_mail.h000064400000002662151730541140011704 0ustar00/* 
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Rasmus Lerdorf <rasmus@lerdorf.on.ca>                        |
   +----------------------------------------------------------------------+
*/

/* $Id: php_mail.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_MAIL_H
#define PHP_MAIL_H

PHP_FUNCTION(mail);
PHP_MINFO_FUNCTION(mail);

PHP_FUNCTION(ezmlm_hash);
PHPAPI extern int php_mail(char *to, char *subject, char *message, char *headers, char *extra_cmd TSRMLS_DC);

#endif /* PHP_MAIL_H */
php/ext/standard/php_http.h000064400000003463151730541140011741 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Sara Golemon <pollita@php.net>                              |
   +----------------------------------------------------------------------+
*/

/* $Id: php_http.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_HTTP_H
#define PHP_HTTP_H

#include "php.h"
#include "php_smart_str.h"

PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr,
				const char *num_prefix, int num_prefix_len,
				const char *key_prefix, int key_prefix_len,
				const char *key_suffix, int key_suffix_len, 
				zval *type, char *arg_sep TSRMLS_DC);
#define php_url_encode_hash(ht, formstr)	php_url_encode_hash_ex((ht), (formstr), NULL, 0, NULL, 0, NULL, 0, NULL TSRMLS_CC)

PHP_FUNCTION(http_build_query);

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */

php/ext/standard/php_versioning.h000064400000002667151730541150013153 0ustar00/* 
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Stig S�ther Bakken <ssb@php.net>                             |
   +----------------------------------------------------------------------+
*/

/* $Id: php_versioning.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_VERSIONING_H
#define PHP_VERSIONING_H

#include "ext/standard/basic_functions.h"

PHPAPI char *php_canonicalize_version(const char *);
PHPAPI int php_version_compare(const char *, const char *);
PHP_FUNCTION(version_compare);

#endif
php/ext/standard/exec.h000064400000003320151730541150011030 0ustar00/* 
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Rasmus Lerdorf <rasmus@lerdorf.on.ca>                        |
   +----------------------------------------------------------------------+
*/

/* $Id: exec.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef EXEC_H
#define EXEC_H

PHP_FUNCTION(system);
PHP_FUNCTION(exec);
PHP_FUNCTION(escapeshellcmd);
PHP_FUNCTION(escapeshellarg);
PHP_FUNCTION(passthru);
PHP_FUNCTION(shell_exec);
PHP_FUNCTION(proc_open);
PHP_FUNCTION(proc_get_status);
PHP_FUNCTION(proc_close);
PHP_FUNCTION(proc_terminate);
PHP_FUNCTION(proc_nice);
PHP_MINIT_FUNCTION(proc_open);

PHPAPI char *php_escape_shell_cmd(char *);
PHPAPI char *php_escape_shell_arg(char *);
int php_exec(int type, char *cmd, zval *array, zval *return_value TSRMLS_DC);

#endif /* EXEC_H */
php/ext/standard/php_dir.h000064400000003170151730541150011534 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Thies C. Arntzen <thies@thieso.net>                          |
   +----------------------------------------------------------------------+
 */

/* $Id: php_dir.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_DIR_H
#define PHP_DIR_H

/* directory functions */
PHP_MINIT_FUNCTION(dir);
PHP_RINIT_FUNCTION(dir);
PHP_FUNCTION(opendir);
PHP_FUNCTION(closedir);
PHP_FUNCTION(chdir);
#if defined(HAVE_CHROOT) && !defined(ZTS) && ENABLE_CHROOT_FUNC
PHP_FUNCTION(chroot);
#endif
PHP_FUNCTION(getcwd);
PHP_FUNCTION(rewinddir);
PHP_NAMED_FUNCTION(php_if_readdir);
PHP_FUNCTION(getdir);
PHP_FUNCTION(glob);
PHP_FUNCTION(scandir);

#endif /* PHP_DIR_H */
php/ext/standard/url.h000064400000004421151730541150010711 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Jim Winstead <jimw@php.net>                                  |
   +----------------------------------------------------------------------+
 */
/* $Id: url.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef URL_H
#define URL_H

typedef struct php_url {
	char *scheme;
	char *user;
	char *pass;
	char *host;
	unsigned short port;
	char *path;
	char *query;
	char *fragment;
} php_url;

PHPAPI void php_url_free(php_url *theurl);
PHPAPI php_url *php_url_parse(char const *str);
PHPAPI php_url *php_url_parse_ex(char const *str, int length);
PHPAPI int php_url_decode(char *str, int len); /* return value: length of decoded string */
PHPAPI int php_raw_url_decode(char *str, int len); /* return value: length of decoded string */
PHPAPI char *php_url_encode(char const *s, int len, int *new_length);
PHPAPI char *php_raw_url_encode(char const *s, int len, int *new_length);

PHP_FUNCTION(parse_url);
PHP_FUNCTION(urlencode);
PHP_FUNCTION(urldecode);
PHP_FUNCTION(rawurlencode);
PHP_FUNCTION(rawurldecode);
PHP_FUNCTION(get_headers);

#define PHP_URL_SCHEME 0
#define PHP_URL_HOST 1
#define PHP_URL_PORT 2
#define PHP_URL_USER 3
#define PHP_URL_PASS 4
#define PHP_URL_PATH 5
#define PHP_URL_QUERY 6
#define PHP_URL_FRAGMENT 7

#endif /* URL_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 */
php/ext/standard/proc_open.h000064400000003557151730541160012105 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Wez Furlong <wez@thebrainroom.com>                           |
   +----------------------------------------------------------------------+
 */
/* $Id: proc_open.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifdef PHP_WIN32
typedef HANDLE php_file_descriptor_t;
typedef DWORD php_process_id_t;
#else
typedef int php_file_descriptor_t;
typedef pid_t php_process_id_t;
#endif

#define PHP_PROC_OPEN_MAX_DESCRIPTORS	16

/* Environment block under win32 is a NUL terminated sequence of NUL terminated
 * name=value strings.
 * Under unix, it is an argv style array.
 * */
typedef struct _php_process_env {
	char *envp;
#ifndef PHP_WIN32
	char **envarray;
#endif
} php_process_env_t;

struct php_process_handle {
	php_process_id_t	child;
#ifdef PHP_WIN32
	HANDLE childHandle;
#endif
	int npipes;
	long pipes[PHP_PROC_OPEN_MAX_DESCRIPTORS];
	char *command;
	int is_persistent;
	php_process_env_t env;
};

php/ext/standard/php_password.h000064400000003566151730541170012633 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 7                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2018 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Anthony Ferrara <ircmaxell@php.net>                         |
   |          Charles R. Portwood II <charlesportwoodii@erianna.com>      |
   +----------------------------------------------------------------------+
*/

/* $Id$ */

#ifndef PHP_PASSWORD_H
#define PHP_PASSWORD_H

PHP_FUNCTION(password_hash);
PHP_FUNCTION(password_verify);
PHP_FUNCTION(password_needs_rehash);
PHP_FUNCTION(password_get_info);

PHP_MINIT_FUNCTION(password);

#define PHP_PASSWORD_DEFAULT    PHP_PASSWORD_BCRYPT
#define PHP_PASSWORD_BCRYPT_COST 10

#if HAVE_ARGON2LIB
#define PHP_PASSWORD_ARGON2_MEMORY_COST (64 << 10)
#define PHP_PASSWORD_ARGON2_TIME_COST 4
#define PHP_PASSWORD_ARGON2_THREADS 1
#endif

typedef enum {
    PHP_PASSWORD_UNKNOWN,
    PHP_PASSWORD_BCRYPT,
#if HAVE_ARGON2LIB
    PHP_PASSWORD_ARGON2I,
#endif
} php_password_algo;

#endif


/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 */
php/ext/standard/php_metaphone.h000064400000002423151730541170012740 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Thies C. Arntzen <thies@thieso.net>                          |
   +----------------------------------------------------------------------+
 */
 
/* $Id: php_metaphone.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_METAPHONE_H
#define PHP_METAPHONE_H

PHP_FUNCTION(metaphone);

#endif
php/ext/standard/php_var.h000064400000012722151730541170011553 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Jani Lehtim�ki <jkl@njet.net>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: php_var.h 301245 2010-07-13 18:53:12Z pajoye $ */

#ifndef PHP_VAR_H
#define PHP_VAR_H

#include "ext/standard/php_smart_str_public.h"

PHP_FUNCTION(var_dump);
PHP_FUNCTION(var_export);
PHP_FUNCTION(debug_zval_dump);
PHP_FUNCTION(serialize);
PHP_FUNCTION(unserialize);
PHP_FUNCTION(memory_get_usage);
PHP_FUNCTION(memory_get_peak_usage);

PHPAPI void php_var_dump(zval **struc, int level TSRMLS_DC);
PHPAPI void php_var_export(zval **struc, int level TSRMLS_DC);
PHPAPI void php_var_export_ex(zval **struc, int level, smart_str *buf TSRMLS_DC);

PHPAPI void php_debug_zval_dump(zval **struc, int level TSRMLS_DC);

/* typdef HashTable php_serialize_data_t; */
#define php_serialize_data_t HashTable

struct php_unserialize_data {
	void *first;
	void *first_dtor;
};

typedef struct php_unserialize_data php_unserialize_data_t;

PHPAPI void php_var_serialize(smart_str *buf, zval **struc, php_serialize_data_t *var_hash TSRMLS_DC);
PHPAPI int php_var_unserialize(zval **rval, const unsigned char **p, const unsigned char *max, php_unserialize_data_t *var_hash TSRMLS_DC);

#define PHP_VAR_SERIALIZE_INIT(var_hash) \
   zend_hash_init(&(var_hash), 10, NULL, NULL, 0)
#define PHP_VAR_SERIALIZE_DESTROY(var_hash) \
   zend_hash_destroy(&(var_hash))

#define PHP_VAR_UNSERIALIZE_INIT(var_hash) \
	(var_hash).first = 0; \
	(var_hash).first_dtor = 0
#define PHP_VAR_UNSERIALIZE_DESTROY(var_hash) \
	var_destroy(&(var_hash))

PHPAPI void var_replace(php_unserialize_data_t *var_hash, zval *ozval, zval **nzval);
PHPAPI void var_push_dtor(php_unserialize_data_t *var_hash, zval **val);
PHPAPI void var_push_dtor_no_addref(php_unserialize_data_t *var_hashx, zval **rval);
PHPAPI void var_destroy(php_unserialize_data_t *var_hash);

#define PHP_VAR_UNSERIALIZE_ZVAL_CHANGED(var_hash, ozval, nzval) \
	var_replace((var_hash), (ozval), &(nzval))

PHPAPI zend_class_entry *php_create_empty_class(char *class_name, int len);

static inline int php_varname_check(char *name, int name_len, zend_bool silent TSRMLS_DC) /* {{{ */
{
    if (name_len == sizeof("GLOBALS") && !memcmp(name, "GLOBALS", sizeof("GLOBALS"))) {
		if (!silent) {
			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attempted GLOBALS variable overwrite");
		}
        return FAILURE;
    } else if (name[0] == '_' &&
            (
             (name_len == sizeof("_GET") && !memcmp(name, "_GET", sizeof("_GET"))) ||
             (name_len == sizeof("_POST") && !memcmp(name, "_POST", sizeof("_POST"))) ||
             (name_len == sizeof("_COOKIE") && !memcmp(name, "_COOKIE", sizeof("_COOKIE"))) ||
             (name_len == sizeof("_ENV") && !memcmp(name, "_ENV", sizeof("_ENV"))) ||
             (name_len == sizeof("_SERVER") && !memcmp(name, "_SERVER", sizeof("_SERVER"))) ||
             (name_len == sizeof("_SESSION") && !memcmp(name, "_SESSION", sizeof("_SESSION"))) ||
             (name_len == sizeof("_FILES") && !memcmp(name, "_FILES", sizeof("_FILES"))) ||
             (name_len == sizeof("_REQUEST") && !memcmp(name, "_REQUEST", sizeof("_REQUEST")))
            )
            ) {
		if (!silent) {
			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attempted super-global (%s) variable overwrite", name);
		}
        return FAILURE;
    } else if (name[0] == 'H' &&
            (
             (name_len == sizeof("HTTP_POST_VARS") && !memcmp(name, "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"))) ||
             (name_len == sizeof("HTTP_GET_VARS") && !memcmp(name, "HTTP_GET_VARS", sizeof("HTTP_GET_VARS"))) ||
             (name_len == sizeof("HTTP_COOKIE_VARS") && !memcmp(name, "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS"))) ||
             (name_len == sizeof("HTTP_ENV_VARS") && !memcmp(name, "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS"))) ||
             (name_len == sizeof("HTTP_SERVER_VARS") && !memcmp(name, "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS"))) ||
             (name_len == sizeof("HTTP_SESSION_VARS") && !memcmp(name, "HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS"))) ||
             (name_len == sizeof("HTTP_RAW_POST_DATA") && !memcmp(name, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"))) ||
             (name_len == sizeof("HTTP_POST_FILES") && !memcmp(name, "HTTP_POST_FILES", sizeof("HTTP_POST_FILES")))
            )
            ) {
		if (!silent) {
			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attempted long input array (%s) overwrite", name);
		}
        return FAILURE;
    }
	return SUCCESS;
}
/* }}} */

#endif /* PHP_VAR_H */
php/ext/standard/flock_compat.h000064400000004063151730541200012546 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Sascha Schumann <sascha@schumann.cx>                         |
   +----------------------------------------------------------------------+
*/

/* $Id: flock_compat.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef FLOCK_COMPAT_H
#define FLOCK_COMPAT_H

/* php_flock internally uses fcntl whther or not flock is available
 * This way our php_flock even works on NFS files.
 * More info: /usr/src/linux/Documentation
 */
PHPAPI int php_flock(int fd, int operation);

#ifndef HAVE_FLOCK
#	define LOCK_SH 1
#	define LOCK_EX 2
#	define LOCK_NB 4
#	define LOCK_UN 8
PHPAPI int flock(int fd, int operation);
#endif

/* Userland LOCK_* constants */
#define PHP_LOCK_SH 1
#define PHP_LOCK_EX 2
#define PHP_LOCK_UN 3
#define PHP_LOCK_NB 4

#ifdef PHP_WIN32
#define EWOULDBLOCK WSAEWOULDBLOCK
#	define fsync _commit
#	define ftruncate(a, b) chsize(a, b)
#endif /* defined(PHP_WIN32) */

#if !HAVE_INET_ATON
#if HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#if HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif

extern int inet_aton(const char *, struct in_addr *);
#endif

#endif	/* FLOCK_COMPAT_H */
php/ext/standard/php_rand.h000064400000005136151730541210011703 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Rasmus Lerdorf <rasmus@php.net>                             |
   |          Zeev Suraski <zeev@zend.com>                                |
   |          Pedro Melo <melo@ip.pt>                                     |
   |          Sterling Hughes <sterling@php.net>                          |
   |                                                                      |
   | Based on code from: Shawn Cokus <Cokus@math.washington.edu>          |
   +----------------------------------------------------------------------+
 */
/* $Id: php_rand.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_RAND_H
#define	PHP_RAND_H

#include <stdlib.h>
#include "basic_functions.h"

/* System Rand functions */
#ifndef RAND_MAX
#define RAND_MAX (1<<15)
#endif

/* In ZTS mode we rely on rand_r() so we must use RAND_MAX. */
#if !defined(ZTS) && (defined(HAVE_LRAND48) || defined(HAVE_RANDOM))
#define PHP_RAND_MAX 2147483647
#else
#define PHP_RAND_MAX RAND_MAX
#endif

#define RAND_RANGE(__n, __min, __max, __tmax) \
    (__n) = (__min) + (long) ((double) ( (double) (__max) - (__min) + 1.0) * ((__n) / ((__tmax) + 1.0)))

/* MT Rand */
#define PHP_MT_RAND_MAX ((long) (0x7FFFFFFF)) /* (1<<31) - 1 */ 

#ifdef PHP_WIN32
#define GENERATE_SEED() (((long) (time(0) * GetCurrentProcessId())) ^ ((long) (1000000.0 * php_combined_lcg(TSRMLS_C))))
#else
#define GENERATE_SEED() (((long) (time(0) * getpid())) ^ ((long) (1000000.0 * php_combined_lcg(TSRMLS_C))))
#endif

PHPAPI void php_srand(long seed TSRMLS_DC);
PHPAPI long php_rand(TSRMLS_D);
PHPAPI void php_mt_srand(php_uint32 seed TSRMLS_DC);
PHPAPI php_uint32 php_mt_rand(TSRMLS_D);

#endif	/* PHP_RAND_H */
php/ext/standard/fsock.h000064400000003172151730541210011213 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Paul Panotzki - Bunyip Information Systems                  |
   |          Jim Winstead <jimw@php.net>                                 |
   |          Wez Furlong                                                 |
   +----------------------------------------------------------------------+
*/

/* $Id: fsock.h 293036 2010-01-03 09:23:27Z sebastian $ */

/* Synced with php 3.0 revision 1.24 1999-06-18 [ssb] */

#ifndef FSOCK_H
#define FSOCK_H

#include "file.h"

#include "php_network.h"

PHP_FUNCTION(fsockopen);
PHP_FUNCTION(pfsockopen);

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim: sw=4 ts=4
 */
#endif /* FSOCK_H */
php/ext/standard/php_incomplete_class.h000064400000005011151730541220014274 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author:  Sascha Schumann <sascha@schumann.cx>                        |
   +----------------------------------------------------------------------+
*/

/* $Id: php_incomplete_class.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_INCOMPLETE_CLASS_H
#define PHP_INCOMPLETE_CLASS_H

#include "ext/standard/basic_functions.h"

#define PHP_IC_ENTRY \
	BG(incomplete_class)

#define PHP_SET_CLASS_ATTRIBUTES(struc) \
	/* OBJECTS_FIXME: Fix for new object model */	\
	if (Z_OBJ_HT_P(struc)->get_class_entry && \
            Z_OBJCE_P(struc) == BG(incomplete_class)) {	\
		class_name = php_lookup_class_name(struc, &name_len); \
		if (!class_name) { \
			name_len = sizeof(INCOMPLETE_CLASS) - 1; \
			class_name = estrndup(INCOMPLETE_CLASS, name_len); \
		} \
		free_class_name = 1; \
		incomplete_class = 1; \
	} else { \
		free_class_name = !zend_get_object_classname(struc, &class_name, &name_len TSRMLS_CC);\
	}

#define PHP_CLEANUP_CLASS_ATTRIBUTES()	\
	if (free_class_name) efree(class_name)

#define PHP_CLASS_ATTRIBUTES											\
	char *class_name;													\
	zend_uint name_len;													\
	zend_bool free_class_name = 0;										\
	zend_bool incomplete_class = 0

#define INCOMPLETE_CLASS "__PHP_Incomplete_Class"
#define MAGIC_MEMBER "__PHP_Incomplete_Class_Name"

#ifdef __cplusplus
extern "C" {
#endif
	
zend_class_entry *php_create_incomplete_class(TSRMLS_D);

PHPAPI char *php_lookup_class_name(zval *object, zend_uint *nlen);
PHPAPI void  php_store_class_name(zval *object, const char *name, zend_uint len);

#ifdef __cplusplus
};
#endif

#endif
php/ext/standard/uniqid.h000064400000002451151730541220011377 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Stig S�ther Bakken <ssb@php.net>                             |
   +----------------------------------------------------------------------+
 */

/* $Id: uniqid.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef UNIQID_H
#define UNIQID_H

#ifdef HAVE_GETTIMEOFDAY
PHP_FUNCTION(uniqid);
#endif

#endif /* UNIQID_H */
php/ext/standard/php_mt_rand.h000064400000003736151730541220012410 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 7                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2018 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Rasmus Lerdorf <rasmus@php.net>                             |
   |          Zeev Suraski <zeev@zend.com>                                |
   |          Pedro Melo <melo@ip.pt>                                     |
   |          Sterling Hughes <sterling@php.net>                          |
   |                                                                      |
   | Based on code from: Shawn Cokus <Cokus@math.washington.edu>          |
   +----------------------------------------------------------------------+
 */
/* $Id$ */

#ifndef PHP_MT_RAND_H
#define PHP_MT_RAND_H

#include "php_lcg.h"
#include "php_rand.h"

#define PHP_MT_RAND_MAX ((zend_long) (0x7FFFFFFF)) /* (1<<31) - 1 */

#define MT_RAND_MT19937 0
#define MT_RAND_PHP 1

PHPAPI void php_mt_srand(uint32_t seed);
PHPAPI uint32_t php_mt_rand(void);
PHPAPI zend_long php_mt_rand_range(zend_long min, zend_long max);
PHPAPI zend_long php_mt_rand_common(zend_long min, zend_long max);

PHP_MINIT_FUNCTION(mt_rand);

#endif	/* PHP_MT_RAND_H */
php/ext/standard/datetime.h000064400000002651151730541230011705 0ustar00/* 
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: datetime.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef DATETIME_H
#define DATETIME_H

#if HAVE_STRPTIME
PHP_FUNCTION(strptime);
#endif 

PHPAPI char *php_std_date(time_t t TSRMLS_DC);

#endif /* DATETIME_H */
php/ext/standard/quot_print.h000064400000002652151730541230012316 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Kirill Maximov (kir@rus.net)                                 |
   +----------------------------------------------------------------------+
*/

/* $Id: quot_print.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef QUOT_PRINT_H
#define QUOT_PRINT_H

PHPAPI unsigned char *php_quot_print_decode(const unsigned char *str, size_t length, size_t *ret_length, int replace_us_by_ws);

PHP_FUNCTION(quoted_printable_decode);

#endif /* QUOT_PRINT_H */
php/ext/standard/php_array.h000064400000007703151730541230012101 0ustar00/* 
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   |          Rasmus Lerdorf <rasmus@php.net>                             |
   |          Andrei Zmievski <andrei@php.net>                            |
   +----------------------------------------------------------------------+
*/

/* $Id: php_array.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_ARRAY_H
#define PHP_ARRAY_H

PHP_MINIT_FUNCTION(array);
PHP_MSHUTDOWN_FUNCTION(array);

PHP_FUNCTION(ksort);
PHP_FUNCTION(krsort);
PHP_FUNCTION(natsort);
PHP_FUNCTION(natcasesort);
PHP_FUNCTION(asort);
PHP_FUNCTION(arsort);
PHP_FUNCTION(sort);
PHP_FUNCTION(rsort);
PHP_FUNCTION(usort);
PHP_FUNCTION(uasort);
PHP_FUNCTION(uksort);
PHP_FUNCTION(array_walk);
PHP_FUNCTION(array_walk_recursive);
PHP_FUNCTION(count);
PHP_FUNCTION(end);
PHP_FUNCTION(prev);
PHP_FUNCTION(next);
PHP_FUNCTION(reset);
PHP_FUNCTION(current);
PHP_FUNCTION(key);
PHP_FUNCTION(min);
PHP_FUNCTION(max);
PHP_FUNCTION(in_array);
PHP_FUNCTION(array_search);
PHP_FUNCTION(extract);
PHP_FUNCTION(compact);
PHP_FUNCTION(array_fill);
PHP_FUNCTION(array_fill_keys);
PHP_FUNCTION(range);
PHP_FUNCTION(shuffle);
PHP_FUNCTION(array_multisort);
PHP_FUNCTION(array_push);
PHP_FUNCTION(array_pop);
PHP_FUNCTION(array_shift);
PHP_FUNCTION(array_unshift);
PHP_FUNCTION(array_splice);
PHP_FUNCTION(array_slice);
PHP_FUNCTION(array_merge);
PHP_FUNCTION(array_merge_recursive);
PHP_FUNCTION(array_keys);
PHP_FUNCTION(array_values);
PHP_FUNCTION(array_count_values);
PHP_FUNCTION(array_reverse);
PHP_FUNCTION(array_reduce);
PHP_FUNCTION(array_pad);
PHP_FUNCTION(array_flip);
PHP_FUNCTION(array_change_key_case);
PHP_FUNCTION(array_rand);
PHP_FUNCTION(array_unique);
PHP_FUNCTION(array_intersect);
PHP_FUNCTION(array_intersect_key);
PHP_FUNCTION(array_intersect_ukey);
PHP_FUNCTION(array_uintersect);
PHP_FUNCTION(array_intersect_assoc);
PHP_FUNCTION(array_uintersect_assoc);
PHP_FUNCTION(array_intersect_uassoc);
PHP_FUNCTION(array_uintersect_uassoc);
PHP_FUNCTION(array_diff);
PHP_FUNCTION(array_diff_key);
PHP_FUNCTION(array_diff_ukey);
PHP_FUNCTION(array_udiff);
PHP_FUNCTION(array_diff_assoc);
PHP_FUNCTION(array_udiff_assoc);
PHP_FUNCTION(array_diff_uassoc);
PHP_FUNCTION(array_udiff_uassoc);
PHP_FUNCTION(array_sum);
PHP_FUNCTION(array_product);
PHP_FUNCTION(array_filter);
PHP_FUNCTION(array_map);
PHP_FUNCTION(array_key_exists);
PHP_FUNCTION(array_chunk);
PHP_FUNCTION(array_combine);

HashTable* php_splice(HashTable *, int, int, zval ***, int, HashTable **);
PHPAPI int php_array_merge(HashTable *dest, HashTable *src, int recursive TSRMLS_DC);
int multisort_compare(const void *a, const void *b TSRMLS_DC);

ZEND_BEGIN_MODULE_GLOBALS(array) 
	int *multisort_flags[2];
	int (*compare_func)(zval *result, zval *op1, zval *op2 TSRMLS_DC);
ZEND_END_MODULE_GLOBALS(array) 

#ifdef ZTS
#define ARRAYG(v) TSRMG(array_globals_id, zend_array_globals *, v)
#else
#define ARRAYG(v) (array_globals.v)
#endif

#endif /* PHP_ARRAY_H */
php/ext/standard/php_math.h000064400000010356151730541240011713 0ustar00/* 
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Jim Winstead <jimw@php.net>                                 |
   |          Stig S�ther Bakken <ssb@php.net>                            |
   +----------------------------------------------------------------------+
*/

/* $Id: php_math.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_MATH_H
#define PHP_MATH_H

PHPAPI char *_php_math_number_format(double, int, char , char);
PHPAPI char * _php_math_longtobase(zval *arg, int base);
PHPAPI long _php_math_basetolong(zval *arg, int base);
PHPAPI int _php_math_basetozval(zval *arg, int base, zval *ret);
PHPAPI char * _php_math_zvaltobase(zval *arg, int base TSRMLS_DC);

PHP_FUNCTION(sin);
PHP_FUNCTION(cos);
PHP_FUNCTION(tan);
PHP_FUNCTION(asin);
PHP_FUNCTION(acos);
PHP_FUNCTION(atan);
PHP_FUNCTION(atan2);
PHP_FUNCTION(pi);
PHP_FUNCTION(exp);
PHP_FUNCTION(log);
PHP_FUNCTION(log10);
PHP_FUNCTION(is_finite);
PHP_FUNCTION(is_infinite);
PHP_FUNCTION(is_nan);
PHP_FUNCTION(pow);
PHP_FUNCTION(sqrt);
PHP_FUNCTION(srand);
PHP_FUNCTION(rand);
PHP_FUNCTION(getrandmax);
PHP_FUNCTION(mt_srand);
PHP_FUNCTION(mt_rand);
PHP_FUNCTION(mt_getrandmax);
PHP_FUNCTION(abs);
PHP_FUNCTION(ceil);
PHP_FUNCTION(floor);
PHP_FUNCTION(round);
PHP_FUNCTION(decbin);
PHP_FUNCTION(dechex);
PHP_FUNCTION(decoct);
PHP_FUNCTION(bindec);
PHP_FUNCTION(hexdec);
PHP_FUNCTION(octdec);
PHP_FUNCTION(base_convert);
PHP_FUNCTION(number_format);
PHP_FUNCTION(fmod);
PHP_FUNCTION(deg2rad);
PHP_FUNCTION(rad2deg);

   /*
   WARNING: these functions are expermental: they could change their names or 
   disappear in the next version of PHP!
   */
PHP_FUNCTION(hypot);
PHP_FUNCTION(expm1);
#ifdef HAVE_LOG1P
PHP_FUNCTION(log1p);
#endif

PHP_FUNCTION(sinh);
PHP_FUNCTION(cosh);
PHP_FUNCTION(tanh);

#ifdef HAVE_ASINH
PHP_FUNCTION(asinh);
#endif
#ifdef HAVE_ACOSH
PHP_FUNCTION(acosh);
#endif
#ifdef HAVE_ATANH
PHP_FUNCTION(atanh);
#endif

#include <math.h>

#ifndef M_E
#define M_E            2.7182818284590452354   /* e */
#endif

#ifndef M_LOG2E
#define M_LOG2E        1.4426950408889634074   /* log_2 e */
#endif

#ifndef M_LOG10E
#define M_LOG10E       0.43429448190325182765  /* log_10 e */
#endif

#ifndef M_LN2
#define M_LN2          0.69314718055994530942  /* log_e 2 */
#endif

#ifndef M_LN10
#define M_LN10         2.30258509299404568402  /* log_e 10 */
#endif

#ifndef M_PI
#define M_PI           3.14159265358979323846  /* pi */
#endif

#ifndef M_PI_2
#define M_PI_2         1.57079632679489661923  /* pi/2 */
#endif

#ifndef M_PI_4
#define M_PI_4         0.78539816339744830962  /* pi/4 */
#endif

#ifndef M_1_PI
#define M_1_PI         0.31830988618379067154  /* 1/pi */
#endif

#ifndef M_2_PI
#define M_2_PI         0.63661977236758134308  /* 2/pi */
#endif

#ifndef M_SQRTPI
#define M_SQRTPI       1.77245385090551602729  /* sqrt(pi) */
#endif

#ifndef M_2_SQRTPI
#define M_2_SQRTPI     1.12837916709551257390  /* 2/sqrt(pi) */
#endif

#ifndef M_LNPI
#define M_LNPI         1.14472988584940017414  /* ln(pi) */
#endif

#ifndef M_EULER
#define M_EULER        0.57721566490153286061 /* Euler constant */
#endif

#ifndef M_SQRT2
#define M_SQRT2        1.41421356237309504880  /* sqrt(2) */
#endif

#ifndef M_SQRT1_2
#define M_SQRT1_2      0.70710678118654752440  /* 1/sqrt(2) */
#endif

#ifndef M_SQRT3
#define M_SQRT3	       1.73205080756887729352  /* sqrt(3) */
#endif

#endif /* PHP_MATH_H */
php/ext/igbinary/igbinary.h000064400000000447151730541240011723 0ustar00#ifndef PHPEXT_IGBINARY_BASE_IGBINARY_H
#define PHPEXT_IGBINARY_BASE_IGBINARY_H
#include "php_version.h"
#if PHP_MAJOR_VERSION == 5
#include "src/php5/igbinary.h"
#elif PHP_MAJOR_VERSION == 7
#include "src/php7/igbinary.h"
#else
#error "Unsupported php version for igbinary build"
#endif
#endif
php/ext/igbinary/src/php7/igbinary.h000064400000006465151730541250013377 0ustar00/*
  +----------------------------------------------------------------------+
  | See COPYING file for further copyright information                   |
  +----------------------------------------------------------------------+
  | Author: Oleg Grenrus <oleg.grenrus@dynamoid.com>                     |
  | See CREDITS for contributors                                         |
  +----------------------------------------------------------------------+
*/

#ifndef IGBINARY_H
#define IGBINARY_H
#include <stdint.h>

/* Forward declarations. */
struct zval;

/* Constants and constant macros */
/** Binary protocol version of igbinary. */
#define IGBINARY_FORMAT_VERSION 0x00000002

#define PHP_IGBINARY_VERSION "3.2.15"

/* Macros */

#ifdef PHP_WIN32
#	if defined(IGBINARY_EXPORTS) || (!defined(COMPILE_DL_IGBINARY))
#		define IGBINARY_API __declspec(dllexport)
#	elif defined(COMPILE_DL_IGBINARY)
#		define IGBINARY_API __declspec(dllimport)
#	else
#		define IGBINARY_API /* nothing special */
#	endif
#elif defined(__GNUC__) && __GNUC__ >= 4
#	define IGBINARY_API __attribute__ ((visibility("default")))
#else
#	define IGBINARY_API /* nothing special */
#endif

/** Struct that contains pointers to memory allocation and deallocation functions.
 * @see igbinary_serialize_data
 */
struct igbinary_memory_manager {
	void *(*alloc)(size_t size, void *context);
	void *(*realloc)(void *ptr, size_t new_size, void *context);
	void (*free)(void *ptr, void *context);
	void *context;
};

/** Serialize zval.
 * Return buffer is allocated by this function with emalloc.
 * @param[out] ret Return buffer
 * @param[out] ret_len Size of return buffer
 * @param[in] z Variable to be serialized
 * @return 0 on success, 1 elsewhere.
 */
IGBINARY_API int igbinary_serialize(uint8_t **ret, size_t *ret_len, zval *z);

/** Serialize zval.
 * Return buffer is allocated by this function with emalloc.
 * @param[out] ret Return buffer
 * @param[out] ret_len Size of return buffer
 * @param[in] z Variable to be serialized
 * @param[in] memory_manager Pointer to the structure that contains memory allocation functions.
 * @return 0 on success, 1 elsewhere.
 */
IGBINARY_API int igbinary_serialize_ex(uint8_t **ret, size_t *ret_len, zval *z, struct igbinary_memory_manager *memory_manager);

/** Unserialize to zval.
 * @param[in] buf Buffer with serialized data.
 * @param[in] buf_len Buffer length.
 * @param[out] z Unserialized zval
 * @return 0 on success, 1 elsewhere.
 */
IGBINARY_API int igbinary_unserialize(const uint8_t *buf, size_t buf_len, zval *z);

static zend_always_inline int _igbinary_has_valid_header(const uint8_t *buf, size_t buf_len) {
	if (buf_len < 5) {
		/* Must have 4 header bytes and at least one byte of data */
		return 0;
	}
	/* Unserialize 32bit value the same way on big-endian and little-endian architectures.
	 * This compiles to a load+optional bswap when compiler optimizations are enabled. */
	const uint32_t ret =
	    ((uint32_t)(buf[0]) << 24) |
	    ((uint32_t)(buf[1]) << 16) |
	    ((uint32_t)(buf[2]) << 8) |
	    ((uint32_t)(buf[3]));
	return ret == 1 || ret == 2;
}
/** This is defined as a macro and a static C function
 * to allow callers to use the macro from newer igbinary versions even with older igbinary installations. */
#define igbinary_has_valid_header(buf, buf_len) _igbinary_has_valid_header((buf), (buf_len))


#endif /* IGBINARY_H */
php/ext/igbinary/src/php7/php_igbinary.h000064400000003732151730541250014240 0ustar00/*
  +----------------------------------------------------------------------+
  | See COPYING file for further copyright information                   |
  +----------------------------------------------------------------------+
  | Author: Oleg Grenrus <oleg.grenrus@dynamoid.com>                     |
  | See CREDITS for contributors                                         |
  +----------------------------------------------------------------------+
*/

#ifndef PHP_IGBINARY_H
#define PHP_IGBINARY_H
// Note: php_igbinary.h should contain publicly exposed variables, functions, and macros of igbinary.
// If a macro is needed by *only* igbinary, put it in igbinary_macros.h

#include "php.h"

/** Module entry of igbinary. */
extern zend_module_entry igbinary_module_entry;
#define phpext_igbinary_ptr &igbinary_module_entry

#ifdef PHP_WIN32
#define PHP_IGBINARY_API __declspec(dllexport)
#else
#define PHP_IGBINARY_API
#endif

ZEND_BEGIN_MODULE_GLOBALS(igbinary)
	zend_bool compact_strings;
ZEND_END_MODULE_GLOBALS(igbinary)

#ifdef ZTS
#include "TSRM.h"
#endif

#include "ext/standard/php_smart_string.h"

/** Module init function. */
PHP_MINIT_FUNCTION(igbinary);

/** Module shutdown function. */
PHP_MSHUTDOWN_FUNCTION(igbinary);

/** Request init function. */
PHP_RINIT_FUNCTION(igbinary);

/** Request shutdown function. */
PHP_RSHUTDOWN_FUNCTION(igbinary);

/** Module info function for phpinfo(). */
PHP_MINFO_FUNCTION(igbinary);

/** string igbinary_serialize(mixed value).
 * Returns the binary serialized value.
 */
PHP_FUNCTION(igbinary_serialize);

/** mixed igbinary_unserialize(string data).
 * Unserializes the given inputstring (value).
 */
PHP_FUNCTION(igbinary_unserialize);

#ifdef ZTS
#define IGBINARY_G(v) TSRMG(igbinary_globals_id, zend_igbinary_globals *, v)
#else
#define IGBINARY_G(v) (igbinary_globals.v)
#endif

#endif /* PHP_IGBINARY_H */

/*
 * Local variables:
 * tab-width: 2
 * c-basic-offset: 0
 * End:
 * vim600: noet sw=2 ts=2 fdm=marker
 * vim<600: noet sw=2 ts=2
 */
php/ext/igbinary/php_igbinary.h000064400000001555151730541260012575 0ustar00#ifndef PHPEXT_IGBINARY_BASE_PHP_IGBINARY_H
#define PHPEXT_IGBINARY_BASE_PHP_IGBINARY_H
#include "php_version.h"
#if PHP_MAJOR_VERSION == 5
#include "ext/igbinary/src/php5/php_igbinary.h"
#elif PHP_MAJOR_VERSION == 7
#include "ext/igbinary/src/php7/php_igbinary.h"
#else
#error "Unsupported php version for igbinary build"
#endif

/**
 * The below line is redundant and identical to php5 and php7's line
 * (and just mentioning phpext_ in a comment is sufficient).
 * This block is only here to make php-src/build/print_include.awk include this file,
 * when igbinary is placed in php-src/ext/igbinary/ (instead of compiled separately with `phpize; ...`)
 */
#ifndef phpext_igbinary_ptr
extern zend_module_entry igbinary_module_entry;
#define phpext_igbinary_ptr &igbinary_module_entry
#endif
/** End line needed for putting igbinary in php-src/ext/igbinary to work */

#endif
php/main/snprintf.h000064400000015243151730541260010304 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Stig Sæther Bakken <ssb@php.net>                             |
   |         Marcus Boerger <helly@php.net>                               |
   +----------------------------------------------------------------------+
*/

/* $Id: snprintf.h 293036 2010-01-03 09:23:27Z sebastian $ */

/*

Comparing: sprintf, snprintf, slprintf, spprintf 

sprintf  offers the ability to make a lot of failures since it does not know
         the size of the buffer it uses. Therefore usage of sprintf often
         results in possible entries for buffer overrun attacks. So please
         use this version only if you are sure the call is safe. sprintf
         allways terminstes the buffer it writes to.

snprintf knows the buffers size and will not write behind it. But you will
         have to use either a static buffer or allocate a dynamic buffer
         before beeing able to call the function. In other words you must
         be sure that you really know the maximum size of the buffer required.
         A bad thing is having a big maximum while in most cases you would
         only need a small buffer. If the size of the resulting string is 
         longer or equal to the buffer size than the buffer is not terminated.
         The function also returns the number of chars not including the 
         terminating \0 that were needed to fully comply to the print request.

slprintf same as snprintf with the difference that it actually returns the 
         length printed not including the terminating \0.

spprintf is the dynamical version of snprintf. It allocates the buffer in size
         as needed and allows a maximum setting as snprintf (turn this feature
         off by setting max_len to 0). spprintf is a little bit slower than
         snprintf and offers possible memory leakes if you miss freeing the 
         buffer allocated by the function. Therfore this function should be 
         used where either no maximum is known or the maximum is much bigger
         than normal size required. spprintf allways terminates the buffer.

Example:

 #define MAX 1024              | #define MAX 1024               | #define MAX 1024
 char buffer[MAX]              | char buffer[MAX]               | char *buffer;
                               |                                |
                               |                                | // No need to initialize buffer:
                               |                                | // spprintf ignores value of buffer
 sprintf(buffer, "test");      | snprintf(buffer, MAX, "test"); | spprintf(&buffer, MAX, "text");
                               |                                | if (!buffer)
                               |                                |   return OUT_OF_MEMORY
 // sprintf allways terminates | // manual termination of       | // spprintf allays terminates buffer
 // buffer                     | // buffer *IS* required        |   
                               | buffer[MAX-1] = 0;             | 
 action_with_buffer(buffer);   | action_with_buffer(buffer);    | action_with_buffer(buffer);
                               |                                | efree(buffer);
*/

#ifndef SNPRINTF_H
#define SNPRINTF_H

typedef int bool_int;

typedef enum {
	NO = 0, YES = 1
} boolean_e;


BEGIN_EXTERN_C()
PHPAPI int ap_php_slprintf(char *buf, size_t len, const char *format,...);
PHPAPI int ap_php_vslprintf(char *buf, size_t len, const char *format, va_list ap);
PHPAPI int ap_php_snprintf(char *, size_t, const char *, ...);
PHPAPI int ap_php_vsnprintf(char *, size_t, const char *, va_list ap);
PHPAPI int php_sprintf (char* s, const char* format, ...) PHP_ATTRIBUTE_FORMAT(printf, 2, 3);
PHPAPI char * php_gcvt(double value, int ndigit, char dec_point, char exponent, char *buf);
PHPAPI char * php_conv_fp(register char format, register double num,
		 boolean_e add_dp, int precision, char dec_point, bool_int * is_negative, char *buf, int *len);

END_EXTERN_C()

#ifdef slprintf
#undef slprintf
#endif
#define slprintf ap_php_slprintf

#ifdef vslprintf
#undef vslprintf
#endif
#define vslprintf ap_php_vslprintf

#ifdef snprintf
#undef snprintf
#endif
#define snprintf ap_php_snprintf

#ifdef vsnprintf
#undef vsnprintf
#endif
#define vsnprintf ap_php_vsnprintf

#ifdef sprintf
#undef sprintf
#endif
#define sprintf php_sprintf

typedef enum {
	LM_STD = 0,
#if SIZEOF_INTMAX_T
	LM_INTMAX_T,
#endif
#if SIZEOF_PTRDIFF_T
	LM_PTRDIFF_T,
#endif
#if SIZEOF_LONG_LONG
	LM_LONG_LONG,
#endif
	LM_SIZE_T,
	LM_LONG,
	LM_LONG_DOUBLE
} length_modifier_e;

#ifdef PHP_WIN32
# define WIDE_INT		__int64
#elif SIZEOF_LONG_LONG_INT
# define WIDE_INT		long long int
#elif SIZEOF_LONG_LONG
# define WIDE_INT		long long
#else
# define WIDE_INT		long
#endif
typedef WIDE_INT wide_int;
typedef unsigned WIDE_INT u_wide_int;

extern char * ap_php_conv_10(register wide_int num, register bool_int is_unsigned,
	   register bool_int * is_negative, char *buf_end, register int *len);

extern char * ap_php_conv_p2(register u_wide_int num, register int nbits,
		 char format, char *buf_end, register int *len);

/* The maximum precision that's allowed for float conversion. Does not include
 * decimal separator, exponent, sign, terminator. Currently does not affect
 * the modes e/f, only g/k/H, as those have a different limit enforced at
 * another level (see NDIG in php_conv_fp()).
 * Applies to the formatting functions of both spprintf.c and snprintf.c, which
 * use equally sized buffers of MAX_BUF_SIZE = 512 to hold the result of the
 * call to php_gcvt().
 * This should be reasonably smaller than MAX_BUF_SIZE (I think MAX_BUF_SIZE - 9
 * should be enough, but let's give some more space) */
#define FORMAT_CONV_MAX_PRECISION 500

#endif /* SNPRINTF_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 */
php/main/php_main.h000064400000005320151730541270010230 0ustar00/* 
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
 */

/* $Id: php_main.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_MAIN_H
#define PHP_MAIN_H

#include "zend_globals.h"
#include "php_globals.h"
#include "SAPI.h"

BEGIN_EXTERN_C()
PHPAPI int php_request_startup(TSRMLS_D);
PHPAPI void php_request_shutdown(void *dummy);
PHPAPI void php_request_shutdown_for_exec(void *dummy);
PHPAPI int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_modules, uint num_additional_modules);
PHPAPI void php_module_shutdown(TSRMLS_D);
PHPAPI void php_module_shutdown_for_exec(void);
PHPAPI int php_module_shutdown_wrapper(sapi_module_struct *sapi_globals);
PHPAPI int php_request_startup_for_hook(TSRMLS_D);

PHPAPI int php_register_extensions(zend_module_entry **ptr, int count TSRMLS_DC);

PHPAPI int php_execute_script(zend_file_handle *primary_file TSRMLS_DC);
PHPAPI int php_execute_simple_script(zend_file_handle *primary_file, zval **ret TSRMLS_DC);
PHPAPI int php_handle_special_queries(TSRMLS_D);
PHPAPI int php_lint_script(zend_file_handle *file TSRMLS_DC);

PHPAPI void php_handle_aborted_connection(void);
PHPAPI int php_handle_auth_data(const char *auth TSRMLS_DC);

PHPAPI void php_html_puts(const char *str, uint siz TSRMLS_DC);
PHPAPI int php_stream_open_for_zend_ex(const char *filename, zend_file_handle *handle, int mode TSRMLS_DC);

extern void php_call_shutdown_functions(TSRMLS_D);
extern void php_free_shutdown_functions(TSRMLS_D);

/* environment module */
extern int php_init_environ(void);
extern int php_shutdown_environ(void);
END_EXTERN_C()

#endif
php/main/php_syslog.h000064400000003133151730541270010624 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 5                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2010 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author:                                                              |
  +----------------------------------------------------------------------+
*/

/* $Id: php_syslog.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_SYSLOG_H
#define PHP_SYSLOG_H

#ifdef PHP_WIN32
#include "win32/syslog.h"
#else
#include <php_config.h>
#ifdef HAVE_SYSLOG_H
#include <syslog.h>
#endif
#endif

/* 
 * The SCO OpenServer 5 Development System (not the UDK)
 * defines syslog to std_syslog.
 */

#ifdef syslog

#ifdef HAVE_STD_SYSLOG
#define php_syslog std_syslog
#endif

#undef syslog

#endif

#ifndef php_syslog
#define php_syslog syslog
#endif

#endif
php/main/php_reentrancy.h000064400000007244151730541270011465 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Sascha Schumann <sascha@schumann.cx>                         |
   +----------------------------------------------------------------------+
 */

/* $Id: php_reentrancy.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_REENTRANCY_H
#define PHP_REENTRANCY_H

#include "php.h"

#include <sys/types.h>
#ifdef HAVE_DIRENT_H
#include <dirent.h>
#endif
#include <time.h>

/* currently, PHP does not check for these functions, but assumes
   that they are available on all systems. */

#define HAVE_LOCALTIME 1
#define HAVE_GMTIME 1
#define HAVE_ASCTIME 1
#define HAVE_CTIME 1

#if defined(PHP_IRIX_TIME_R)
#undef HAVE_ASCTIME_R
#undef HAVE_CTIME_R
#endif

#if defined(PHP_HPUX_TIME_R)
#undef HAVE_LOCALTIME_R
#undef HAVE_ASCTIME_R
#undef HAVE_CTIME_R
#undef HAVE_GMTIME_R
#endif

BEGIN_EXTERN_C()

#if defined(HAVE_POSIX_READDIR_R)
#define php_readdir_r readdir_r
#else
PHPAPI int php_readdir_r(DIR *dirp, struct dirent *entry,
		struct dirent **result);
#endif

#if !defined(HAVE_LOCALTIME_R) && defined(HAVE_LOCALTIME)
#define PHP_NEED_REENTRANCY 1
PHPAPI struct tm *php_localtime_r(const time_t *const timep, struct tm *p_tm);
#else
#define php_localtime_r localtime_r
#ifdef MISSING_LOCALTIME_R_DECL
struct tm *localtime_r(const time_t *const timep, struct tm *p_tm);
#endif
#endif


#if !defined(HAVE_CTIME_R) && defined(HAVE_CTIME)
#define PHP_NEED_REENTRANCY 1
PHPAPI char *php_ctime_r(const time_t *clock, char *buf);
#else
#define php_ctime_r ctime_r
#ifdef MISSING_CTIME_R_DECL
char *ctime_r(const time_t *clock, char *buf);
#endif
#endif


#if !defined(HAVE_ASCTIME_R) && defined(HAVE_ASCTIME)
#define PHP_NEED_REENTRANCY 1
PHPAPI char *php_asctime_r(const struct tm *tm, char *buf);
#else
#define php_asctime_r asctime_r
#ifdef MISSING_ASCTIME_R_DECL
char *asctime_r(const struct tm *tm, char *buf);
#endif
#endif


#if !defined(HAVE_GMTIME_R) && defined(HAVE_GMTIME) || defined(__BEOS__)
#define PHP_NEED_REENTRANCY 1
PHPAPI struct tm *php_gmtime_r(const time_t *const timep, struct tm *p_tm);
#else
#define php_gmtime_r gmtime_r
#ifdef MISSING_GMTIME_R_DECL
struct tm *php_gmtime_r(const time_t *const timep, struct tm *p_tm);
#endif
#endif

#if !defined(HAVE_STRTOK_R)
PHPAPI char *php_strtok_r(char *s, const char *delim, char **last);
#else
#define php_strtok_r strtok_r
#ifdef MISSING_STRTOK_R_DECL
char *strtok_r(char *s, const char *delim, char **last);
#endif
#endif

#if !defined(HAVE_RAND_R)
PHPAPI int php_rand_r(unsigned int *seed);
#else
#define php_rand_r rand_r
#endif

END_EXTERN_C()

#if !defined(ZTS)
#undef PHP_NEED_REENTRANCY
#endif

#if defined(PHP_NEED_REENTRANCY)
void reentrancy_startup(void);
void reentrancy_shutdown(void);
#else
#define reentrancy_startup()
#define reentrancy_shutdown()
#endif

#endif	
php/main/php_content_types.h000064400000003040151730541300012171 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 5                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2010 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author:                                                              |
  +----------------------------------------------------------------------+
*/

/* $Id: php_content_types.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_CONTENT_TYPES_H
#define PHP_CONTENT_TYPES_H

#define DEFAULT_POST_CONTENT_TYPE "application/x-www-form-urlencoded"

SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader);
SAPI_API SAPI_POST_HANDLER_FUNC(php_std_post_handler);
int php_startup_sapi_content_types(TSRMLS_D);
int php_setup_sapi_content_types(TSRMLS_D);

#endif /* PHP_CONTENT_TYPES_H */
php/main/streams/php_stream_userspace.h000064400000003122151730541300014317 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Wez Furlong <wez@thebrainroom.com>                           |
   +----------------------------------------------------------------------+
 */

/* $Id: php_stream_userspace.h 293036 2010-01-03 09:23:27Z sebastian $ */


/* for user-space streams */
PHPAPI extern php_stream_ops php_stream_userspace_ops;
PHPAPI extern php_stream_ops php_stream_userspace_dir_ops;
#define PHP_STREAM_IS_USERSPACE	&php_stream_userspace_ops
#define PHP_STREAM_IS_USERSPACE_DIR	&php_stream_userspace_dir_ops

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/main/streams/php_streams_int.h000064400000005102151730541310013303 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 5                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2010 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: Wez Furlong <wez@thebrainroom.com>                           |
  +----------------------------------------------------------------------+
*/

/* $Id: php_streams_int.h 293036 2010-01-03 09:23:27Z sebastian $ */


#if ZEND_DEBUG

#define emalloc_rel_orig(size)	\
		( __php_stream_call_depth == 0 \
		? _emalloc((size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_RELAY_CC) \
		: _emalloc((size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_ORIG_RELAY_CC) )

#define erealloc_rel_orig(ptr, size)	\
		( __php_stream_call_depth == 0 \
		? _erealloc((ptr), (size), 0 ZEND_FILE_LINE_CC ZEND_FILE_LINE_RELAY_CC) \
		: _erealloc((ptr), (size), 0 ZEND_FILE_LINE_CC ZEND_FILE_LINE_ORIG_RELAY_CC) )

#define pemalloc_rel_orig(size, persistent)	((persistent) ? malloc((size)) : emalloc_rel_orig((size)))
#define perealloc_rel_orig(ptr, size, persistent)	((persistent) ? realloc((ptr), (size)) : erealloc_rel_orig((ptr), (size)))
#else
# define pemalloc_rel_orig(size, persistent)				pemalloc((size), (persistent))
# define perealloc_rel_orig(ptr, size, persistent)			perealloc((ptr), (size), (persistent))
# define emalloc_rel_orig(size)								emalloc((size))
#endif

#define STREAM_DEBUG 0
#define STREAM_WRAPPER_PLAIN_FILES	((php_stream_wrapper*)-1)

#ifndef MAP_FAILED
#define MAP_FAILED ((void *) -1)
#endif

#define CHUNK_SIZE	8192

#ifdef PHP_WIN32
#define EWOULDBLOCK WSAEWOULDBLOCK
#endif

#ifndef S_ISREG
#define S_ISREG(mode)	(((mode)&S_IFMT) == S_IFREG)
#endif

void php_stream_tidy_wrapper_error_log(php_stream_wrapper *wrapper TSRMLS_DC);
void php_stream_display_wrapper_errors(php_stream_wrapper *wrapper, const char *path, const char *caption TSRMLS_DC);

php/main/streams/php_stream_mmap.h000064400000006760151730541320013274 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 5                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2010 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: Wez Furlong <wez@thebrainroom.com>                           |
  +----------------------------------------------------------------------+
*/

/* $Id: php_stream_mmap.h 293036 2010-01-03 09:23:27Z sebastian $ */

/* Memory Mapping interface for streams.
 * The intention is to provide a uniform interface over the most common
 * operations that are used within PHP itself, rather than a complete
 * API for all memory mapping needs.
 *
 * ATM, we support only mmap(), but win32 memory mapping support will
 * follow soon.
 * */

typedef enum {
	/* Does the stream support mmap ? */
	PHP_STREAM_MMAP_SUPPORTED,
	/* Request a range and offset to be mapped;
	 * while mapped, you MUST NOT use any read/write functions
	 * on the stream (win9x compatibility) */
	PHP_STREAM_MMAP_MAP_RANGE,
	/* Unmap the last range that was mapped for the stream */
	PHP_STREAM_MMAP_UNMAP
} php_stream_mmap_operation_t;
	
typedef enum {
	PHP_STREAM_MAP_MODE_READONLY,
	PHP_STREAM_MAP_MODE_READWRITE,
	PHP_STREAM_MAP_MODE_SHARED_READONLY,
	PHP_STREAM_MAP_MODE_SHARED_READWRITE
} php_stream_mmap_access_t;

typedef struct {
	/* requested offset and length.
	 * If length is 0, the whole file is mapped */
	size_t offset;
	size_t length;
	
	php_stream_mmap_access_t mode;
	
	/* returned mapped address */
	char *mapped;

} php_stream_mmap_range;

#define PHP_STREAM_MMAP_ALL 0

#define php_stream_mmap_supported(stream)	(_php_stream_set_option((stream), PHP_STREAM_OPTION_MMAP_API, PHP_STREAM_MMAP_SUPPORTED, NULL TSRMLS_CC) == 0 ? 1 : 0)

/* Returns 1 if the stream in its current state can be memory mapped,
 * 0 otherwise */
#define php_stream_mmap_possible(stream)			(!php_stream_is_filtered((stream)) && php_stream_mmap_supported((stream)))

BEGIN_EXTERN_C()
PHPAPI char *_php_stream_mmap_range(php_stream *stream, size_t offset, size_t length, php_stream_mmap_operation_t mode, size_t *mapped_len TSRMLS_DC);
#define php_stream_mmap_range(stream, offset, length, mode, mapped_len)	_php_stream_mmap_range((stream), (offset), (length), (mode), (mapped_len) TSRMLS_CC)

/* un-maps the last mapped range */
PHPAPI int _php_stream_mmap_unmap(php_stream *stream TSRMLS_DC);
#define php_stream_mmap_unmap(stream)				_php_stream_mmap_unmap((stream) TSRMLS_CC)

PHPAPI int _php_stream_mmap_unmap_ex(php_stream *stream, off_t readden TSRMLS_DC);
#define php_stream_mmap_unmap_ex(stream, readden)			_php_stream_mmap_unmap_ex((stream), (readden) TSRMLS_CC)
END_EXTERN_C()

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/main/streams/php_stream_transport.h000064400000015064151730541320014373 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 5                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2010 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: Wez Furlong <wez@thebrainroom.com>                           |
  +----------------------------------------------------------------------+
*/

/* $Id: php_stream_transport.h 293036 2010-01-03 09:23:27Z sebastian $ */

#if HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif

typedef php_stream *(php_stream_transport_factory_func)(const char *proto, long protolen,
		char *resourcename, long resourcenamelen,
		const char *persistent_id, int options, int flags,
		struct timeval *timeout,
		php_stream_context *context STREAMS_DC TSRMLS_DC);
typedef php_stream_transport_factory_func *php_stream_transport_factory;

BEGIN_EXTERN_C()
PHPAPI int php_stream_xport_register(char *protocol, php_stream_transport_factory factory TSRMLS_DC);
PHPAPI int php_stream_xport_unregister(char *protocol TSRMLS_DC);

#define STREAM_XPORT_CLIENT			0
#define STREAM_XPORT_SERVER			1

#define STREAM_XPORT_CONNECT		2
#define STREAM_XPORT_BIND			4
#define STREAM_XPORT_LISTEN			8
#define STREAM_XPORT_CONNECT_ASYNC	16

/* Open a client or server socket connection */
PHPAPI php_stream *_php_stream_xport_create(const char *name, long namelen, int options,
		int flags, const char *persistent_id,
		struct timeval *timeout,
		php_stream_context *context,
		char **error_string,
		int *error_code
		STREAMS_DC TSRMLS_DC);

#define php_stream_xport_create(name, namelen, options, flags, persistent_id, timeout, context, estr, ecode) \
	_php_stream_xport_create(name, namelen, options, flags, persistent_id, timeout, context, estr, ecode STREAMS_CC TSRMLS_CC)

/* Bind the stream to a local address */
PHPAPI int php_stream_xport_bind(php_stream *stream,
		const char *name, long namelen,
		char **error_text
		TSRMLS_DC);

/* Connect to a remote address */
PHPAPI int php_stream_xport_connect(php_stream *stream,
		const char *name, long namelen,
		int asynchronous,
		struct timeval *timeout,
		char **error_text,
		int *error_code
		TSRMLS_DC);

/* Prepare to listen */
PHPAPI int php_stream_xport_listen(php_stream *stream,
		int backlog,
		char **error_text
		TSRMLS_DC);

/* Get the next client and their address as a string, or the underlying address
 * structure.  You must efree either of these if you request them */
PHPAPI int php_stream_xport_accept(php_stream *stream, php_stream **client,
		char **textaddr, int *textaddrlen,
		void **addr, socklen_t *addrlen,
		struct timeval *timeout,
		char **error_text
		TSRMLS_DC);

/* Get the name of either the socket or it's peer */
PHPAPI int php_stream_xport_get_name(php_stream *stream, int want_peer,
		char **textaddr, int *textaddrlen,
		void **addr, socklen_t *addrlen
		TSRMLS_DC);

enum php_stream_xport_send_recv_flags {
	STREAM_OOB = 1,
	STREAM_PEEK = 2
};

/* Similar to recv() system call; read data from the stream, optionally
 * peeking, optionally retrieving OOB data */
PHPAPI int php_stream_xport_recvfrom(php_stream *stream, char *buf, size_t buflen,
		long flags, void **addr, socklen_t *addrlen,
		char **textaddr, int *textaddrlen TSRMLS_DC);

/* Similar to send() system call; send data to the stream, optionally
 * sending it as OOB data */
PHPAPI int php_stream_xport_sendto(php_stream *stream, const char *buf, size_t buflen,
		long flags, void *addr, socklen_t addrlen TSRMLS_DC);

typedef enum {
	STREAM_SHUT_RD,
	STREAM_SHUT_WR,
	STREAM_SHUT_RDWR
} stream_shutdown_t;

/* Similar to shutdown() system call; shut down part of a full-duplex
 * connection */
PHPAPI int php_stream_xport_shutdown(php_stream *stream, stream_shutdown_t how TSRMLS_DC);
END_EXTERN_C()


/* Structure definition for the set_option interface that the above functions wrap */

typedef struct _php_stream_xport_param {
	enum {
		STREAM_XPORT_OP_BIND, STREAM_XPORT_OP_CONNECT,
		STREAM_XPORT_OP_LISTEN, STREAM_XPORT_OP_ACCEPT,
		STREAM_XPORT_OP_CONNECT_ASYNC,
		STREAM_XPORT_OP_GET_NAME,
		STREAM_XPORT_OP_GET_PEER_NAME,
		STREAM_XPORT_OP_RECV,
		STREAM_XPORT_OP_SEND,
		STREAM_XPORT_OP_SHUTDOWN
	} op;
	unsigned int want_addr:1;
	unsigned int want_textaddr:1;
	unsigned int want_errortext:1;
	unsigned int how:2;

	struct {
		char *name;
		long namelen;
		int backlog;
		struct timeval *timeout;
		struct sockaddr *addr;
		socklen_t addrlen;
		char *buf;
		size_t buflen;
		long flags;
	} inputs;
	struct {
		php_stream *client;
		int returncode;
		struct sockaddr *addr;
		socklen_t addrlen;
		char *textaddr;
		long textaddrlen;

		char *error_text;
		int error_code;
	} outputs;
} php_stream_xport_param;


/* These functions provide crypto support on the underlying transport */
typedef enum {
	STREAM_CRYPTO_METHOD_SSLv2_CLIENT,
	STREAM_CRYPTO_METHOD_SSLv3_CLIENT,
	STREAM_CRYPTO_METHOD_SSLv23_CLIENT,
	STREAM_CRYPTO_METHOD_TLS_CLIENT,
	STREAM_CRYPTO_METHOD_SSLv2_SERVER,
	STREAM_CRYPTO_METHOD_SSLv3_SERVER,
	STREAM_CRYPTO_METHOD_SSLv23_SERVER,
	STREAM_CRYPTO_METHOD_TLS_SERVER
} php_stream_xport_crypt_method_t;

BEGIN_EXTERN_C()
PHPAPI int php_stream_xport_crypto_setup(php_stream *stream, php_stream_xport_crypt_method_t crypto_method, php_stream *session_stream TSRMLS_DC);
PHPAPI int php_stream_xport_crypto_enable(php_stream *stream, int activate TSRMLS_DC);
END_EXTERN_C()

typedef struct _php_stream_xport_crypto_param {
	enum {
		STREAM_XPORT_CRYPTO_OP_SETUP,
		STREAM_XPORT_CRYPTO_OP_ENABLE
	} op;
	struct {
		int activate;
		php_stream_xport_crypt_method_t method;
		php_stream *session;
	} inputs;
	struct {
		int returncode;
	} outputs;
} php_stream_xport_crypto_param;

BEGIN_EXTERN_C()
PHPAPI HashTable *php_stream_xport_get_hash(void);
PHPAPI php_stream_transport_factory_func php_stream_generic_socket_factory;
END_EXTERN_C()

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/main/streams/php_stream_glob_wrapper.h000064400000004016151730541330015016 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 7                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2018 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Marcus Boerger <helly@php.net>                               |
   +----------------------------------------------------------------------+
 */

/* $Id$ */

PHPAPI extern php_stream_wrapper  php_glob_stream_wrapper;
PHPAPI extern php_stream_ops      php_glob_stream_ops;

BEGIN_EXTERN_C()

PHPAPI char* _php_glob_stream_get_path(php_stream *stream, int copy, size_t *plen STREAMS_DC);
#define php_glob_stream_get_path(stream, copy, plen)	_php_glob_stream_get_path((stream), (copy), (plen) STREAMS_CC)

PHPAPI char* _php_glob_stream_get_pattern(php_stream *stream, int copy, size_t *plen STREAMS_DC);
#define php_glob_stream_get_pattern(stream, copy, plen)	_php_glob_stream_get_pattern((stream), (copy), (plen) STREAMS_CC)

PHPAPI int   _php_glob_stream_get_count(php_stream *stream, int *pflags STREAMS_DC);
#define php_glob_stream_get_count(stream, pflags)	_php_glob_stream_get_count((stream), (pflags) STREAMS_CC)

END_EXTERN_C()

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/main/streams/php_stream_plain_wrapper.h000064400000007405151730541340015204 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Wez Furlong <wez@thebrainroom.com>                           |
   +----------------------------------------------------------------------+
 */

/* $Id: php_stream_plain_wrapper.h 293036 2010-01-03 09:23:27Z sebastian $ */

/* definitions for the plain files wrapper */

/* operations for a plain file; use the php_stream_fopen_XXX funcs below */
PHPAPI extern php_stream_ops php_stream_stdio_ops;
PHPAPI extern php_stream_wrapper php_plain_files_wrapper;

BEGIN_EXTERN_C()

/* like fopen, but returns a stream */
PHPAPI php_stream *_php_stream_fopen(const char *filename, const char *mode, char **opened_path, int options STREAMS_DC TSRMLS_DC);
#define php_stream_fopen(filename, mode, opened)	_php_stream_fopen((filename), (mode), (opened), 0 STREAMS_CC TSRMLS_CC)

PHPAPI php_stream *_php_stream_fopen_with_path(char *filename, char *mode, char *path, char **opened_path, int options STREAMS_DC TSRMLS_DC);
#define php_stream_fopen_with_path(filename, mode, path, opened)	_php_stream_fopen_with_path((filename), (mode), (path), (opened) STREAMS_CC TSRMLS_CC)

PHPAPI php_stream *_php_stream_fopen_from_file(FILE *file, const char *mode STREAMS_DC TSRMLS_DC);
#define php_stream_fopen_from_file(file, mode)	_php_stream_fopen_from_file((file), (mode) STREAMS_CC TSRMLS_CC)

PHPAPI php_stream *_php_stream_fopen_from_fd(int fd, const char *mode, const char *persistent_id STREAMS_DC TSRMLS_DC);
#define php_stream_fopen_from_fd(fd, mode, persistent_id)	_php_stream_fopen_from_fd((fd), (mode), (persistent_id) STREAMS_CC TSRMLS_CC)

PHPAPI php_stream *_php_stream_fopen_from_pipe(FILE *file, const char *mode STREAMS_DC TSRMLS_DC);
#define php_stream_fopen_from_pipe(file, mode)	_php_stream_fopen_from_pipe((file), (mode) STREAMS_CC TSRMLS_CC)

PHPAPI php_stream *_php_stream_fopen_tmpfile(int dummy STREAMS_DC TSRMLS_DC);
#define php_stream_fopen_tmpfile()	_php_stream_fopen_tmpfile(0 STREAMS_CC TSRMLS_CC)

PHPAPI php_stream *_php_stream_fopen_temporary_file(const char *dir, const char *pfx, char **opened_path STREAMS_DC TSRMLS_DC);
#define php_stream_fopen_temporary_file(dir, pfx, opened_path)	_php_stream_fopen_temporary_file((dir), (pfx), (opened_path) STREAMS_CC TSRMLS_CC)

/* This is a utility API for extensions that are opening a stream, converting it
 * to a FILE* and then closing it again.  Be warned that fileno() on the result
 * will most likely fail on systems with fopencookie. */
PHPAPI FILE * _php_stream_open_wrapper_as_file(char * path, char * mode, int options, char **opened_path STREAMS_DC TSRMLS_DC);
#define php_stream_open_wrapper_as_file(path, mode, options, opened_path) _php_stream_open_wrapper_as_file((path), (mode), (options), (opened_path) STREAMS_CC TSRMLS_CC)

END_EXTERN_C()

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/main/streams/php_stream_filter_api.h000064400000016154151730541350014461 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Wez Furlong <wez@thebrainroom.com>                           |
   | With suggestions from:                                               |
   |      Moriyoshi Koizumi <moriyoshi@at.wakwak.com>                     |
   |      Sara Golemon      <pollita@php.net>                             |
   +----------------------------------------------------------------------+
 */

/* $Id: php_stream_filter_api.h 293036 2010-01-03 09:23:27Z sebastian $ */

/* The filter API works on the principle of "Bucket-Brigades".  This is
 * partially inspired by the Apache 2 method of doing things, although
 * it is intentially a light-weight implementation.
 *
 * Each stream can have a chain of filters for reading and another for writing.
 * 
 * When data is written to the stream, is is placed into a bucket and placed at
 * the start of the input brigade.
 *
 * The first filter in the chain is invoked on the brigade and (depending on
 * it's return value), the next filter is invoked and so on.
 * */

#define PHP_STREAM_FILTER_READ	0x0001
#define PHP_STREAM_FILTER_WRITE	0x0002
#define PHP_STREAM_FILTER_ALL	(PHP_STREAM_FILTER_READ | PHP_STREAM_FILTER_WRITE)

typedef struct _php_stream_bucket			php_stream_bucket;
typedef struct _php_stream_bucket_brigade	php_stream_bucket_brigade;

struct _php_stream_bucket {
	php_stream_bucket *next, *prev;
	php_stream_bucket_brigade *brigade;

	char *buf;
	size_t buflen;
	/* if non-zero, buf should be pefreed when the bucket is destroyed */
	int own_buf;
	int is_persistent;
	
	/* destroy this struct when refcount falls to zero */
	int refcount;
};

struct _php_stream_bucket_brigade {
	php_stream_bucket *head, *tail;
};

typedef enum {
	PSFS_ERR_FATAL,	/* error in data stream */
	PSFS_FEED_ME,	/* filter needs more data; stop processing chain until more is available */
	PSFS_PASS_ON	/* filter generated output buckets; pass them on to next in chain */
} php_stream_filter_status_t;

/* Buckets API. */
BEGIN_EXTERN_C()
PHPAPI php_stream_bucket *php_stream_bucket_new(php_stream *stream, char *buf, size_t buflen, int own_buf, int buf_persistent TSRMLS_DC);
PHPAPI int php_stream_bucket_split(php_stream_bucket *in, php_stream_bucket **left, php_stream_bucket **right, size_t length TSRMLS_DC);
PHPAPI void php_stream_bucket_delref(php_stream_bucket *bucket TSRMLS_DC);
#define php_stream_bucket_addref(bucket)	(bucket)->refcount++
PHPAPI void php_stream_bucket_prepend(php_stream_bucket_brigade *brigade, php_stream_bucket *bucket TSRMLS_DC);
PHPAPI void php_stream_bucket_append(php_stream_bucket_brigade *brigade, php_stream_bucket *bucket TSRMLS_DC);
PHPAPI void php_stream_bucket_unlink(php_stream_bucket *bucket TSRMLS_DC);
PHPAPI php_stream_bucket *php_stream_bucket_make_writeable(php_stream_bucket *bucket TSRMLS_DC);
END_EXTERN_C()

#define PSFS_FLAG_NORMAL		0	/* regular read/write */
#define PSFS_FLAG_FLUSH_INC		1	/* an incremental flush */
#define PSFS_FLAG_FLUSH_CLOSE	2	/* final flush prior to closing */

typedef struct _php_stream_filter_ops {

	php_stream_filter_status_t (*filter)(
			php_stream *stream,
			php_stream_filter *thisfilter,
			php_stream_bucket_brigade *buckets_in,
			php_stream_bucket_brigade *buckets_out,
			size_t *bytes_consumed,
			int flags
			TSRMLS_DC);
	
	void (*dtor)(php_stream_filter *thisfilter TSRMLS_DC);
	
	const char *label;
	
} php_stream_filter_ops;

typedef struct _php_stream_filter_chain {
	php_stream_filter *head, *tail;

	/* Owning stream */
	php_stream *stream;
} php_stream_filter_chain;

struct _php_stream_filter {
	php_stream_filter_ops *fops;
	void *abstract; /* for use by filter implementation */
	php_stream_filter *next;
	php_stream_filter *prev;
	int is_persistent;

	/* link into stream and chain */
	php_stream_filter_chain *chain;

	/* buffered buckets */
	php_stream_bucket_brigade buffer;

	/* filters are auto_registered when they're applied */
	int rsrc_id;
};

/* stack filter onto a stream */
BEGIN_EXTERN_C()
PHPAPI void _php_stream_filter_prepend(php_stream_filter_chain *chain, php_stream_filter *filter TSRMLS_DC);
PHPAPI int php_stream_filter_prepend_ex(php_stream_filter_chain *chain, php_stream_filter *filter TSRMLS_DC);
PHPAPI void _php_stream_filter_append(php_stream_filter_chain *chain, php_stream_filter *filter TSRMLS_DC);
PHPAPI int php_stream_filter_append_ex(php_stream_filter_chain *chain, php_stream_filter *filter TSRMLS_DC);
PHPAPI int _php_stream_filter_flush(php_stream_filter *filter, int finish TSRMLS_DC);
PHPAPI php_stream_filter *php_stream_filter_remove(php_stream_filter *filter, int call_dtor TSRMLS_DC);
PHPAPI void php_stream_filter_free(php_stream_filter *filter TSRMLS_DC);
PHPAPI php_stream_filter *_php_stream_filter_alloc(php_stream_filter_ops *fops, void *abstract, int persistent STREAMS_DC TSRMLS_DC);
END_EXTERN_C()
#define php_stream_filter_alloc(fops, thisptr, persistent) _php_stream_filter_alloc((fops), (thisptr), (persistent) STREAMS_CC TSRMLS_CC)
#define php_stream_filter_alloc_rel(fops, thisptr, persistent) _php_stream_filter_alloc((fops), (thisptr), (persistent) STREAMS_REL_CC TSRMLS_CC)
#define php_stream_filter_prepend(chain, filter) _php_stream_filter_prepend((chain), (filter) TSRMLS_CC)
#define php_stream_filter_append(chain, filter) _php_stream_filter_append((chain), (filter) TSRMLS_CC)
#define php_stream_filter_flush(filter, finish) _php_stream_filter_flush((filter), (finish) TSRMLS_CC)

#define php_stream_is_filtered(stream)	((stream)->readfilters.head || (stream)->writefilters.head)

typedef struct _php_stream_filter_factory {
	php_stream_filter *(*create_filter)(const char *filtername, zval *filterparams, int persistent TSRMLS_DC);
} php_stream_filter_factory;

BEGIN_EXTERN_C()
PHPAPI int php_stream_filter_register_factory(const char *filterpattern, php_stream_filter_factory *factory TSRMLS_DC);
PHPAPI int php_stream_filter_unregister_factory(const char *filterpattern TSRMLS_DC);
PHPAPI int php_stream_filter_register_factory_volatile(const char *filterpattern, php_stream_filter_factory *factory TSRMLS_DC);
PHPAPI php_stream_filter *php_stream_filter_create(const char *filtername, zval *filterparams, int persistent TSRMLS_DC);
END_EXTERN_C()

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/main/streams/php_stream_context.h000064400000014376151730541350014033 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Wez Furlong <wez@thebrainroom.com>                           |
   +----------------------------------------------------------------------+
 */

/* $Id: php_stream_context.h 293036 2010-01-03 09:23:27Z sebastian $ */

/* Stream context and status notification related definitions */

/* callback for status notifications */
typedef void (*php_stream_notification_func)(php_stream_context *context,
		int notifycode, int severity,
		char *xmsg, int xcode,
		size_t bytes_sofar, size_t bytes_max,
		void * ptr TSRMLS_DC);

#define PHP_STREAM_NOTIFIER_PROGRESS	1

/* Attempt to fetch context from the zval passed,
   If no context was passed, use the default context
   The the default context has not yet been created, do it now. */
#define php_stream_context_from_zval(zcontext, nocontext) ( \
		(zcontext) ? zend_fetch_resource(&(zcontext) TSRMLS_CC, -1, "Stream-Context", NULL, 1, php_le_stream_context()) : \
		(nocontext) ? NULL : \
		FG(default_context) ? FG(default_context) : \
		(FG(default_context) = php_stream_context_alloc()) )

#define php_stream_context_to_zval(context, zval) { ZVAL_RESOURCE(zval, (context)->rsrc_id); zend_list_addref((context)->rsrc_id); }

typedef struct _php_stream_notifier php_stream_notifier;

struct _php_stream_notifier {
	php_stream_notification_func func;
	void (*dtor)(php_stream_notifier *notifier);
	void *ptr;
	int mask;
	size_t progress, progress_max; /* position for progress notification */
};

struct _php_stream_context {
	php_stream_notifier *notifier;
	zval *options;	/* hash keyed by wrapper family or specific wrapper */
	zval *links;	/* hash keyed by hostent for connection pooling */
	int rsrc_id;	/* used for auto-cleanup */
};

BEGIN_EXTERN_C()
PHPAPI void php_stream_context_free(php_stream_context *context);
PHPAPI php_stream_context *php_stream_context_alloc(void);
PHPAPI int php_stream_context_get_option(php_stream_context *context,
		const char *wrappername, const char *optionname, zval ***optionvalue);
PHPAPI int php_stream_context_set_option(php_stream_context *context,
		const char *wrappername, const char *optionname, zval *optionvalue);

PHPAPI int php_stream_context_get_link(php_stream_context *context,
		const char *hostent, php_stream **stream);
PHPAPI int php_stream_context_set_link(php_stream_context *context,
		const char *hostent, php_stream *stream);
PHPAPI int php_stream_context_del_link(php_stream_context *context,
		php_stream *stream);

PHPAPI php_stream_notifier *php_stream_notification_alloc(void);
PHPAPI void php_stream_notification_free(php_stream_notifier *notifier);
END_EXTERN_C()

/* not all notification codes are implemented */
#define PHP_STREAM_NOTIFY_RESOLVE		1
#define PHP_STREAM_NOTIFY_CONNECT		2
#define PHP_STREAM_NOTIFY_AUTH_REQUIRED		3
#define PHP_STREAM_NOTIFY_MIME_TYPE_IS	4
#define PHP_STREAM_NOTIFY_FILE_SIZE_IS	5
#define PHP_STREAM_NOTIFY_REDIRECTED	6
#define PHP_STREAM_NOTIFY_PROGRESS		7
#define PHP_STREAM_NOTIFY_COMPLETED		8
#define PHP_STREAM_NOTIFY_FAILURE		9
#define PHP_STREAM_NOTIFY_AUTH_RESULT	10

#define PHP_STREAM_NOTIFY_SEVERITY_INFO	0
#define PHP_STREAM_NOTIFY_SEVERITY_WARN	1
#define PHP_STREAM_NOTIFY_SEVERITY_ERR	2

BEGIN_EXTERN_C()
PHPAPI void php_stream_notification_notify(php_stream_context *context, int notifycode, int severity,
		char *xmsg, int xcode, size_t bytes_sofar, size_t bytes_max, void * ptr TSRMLS_DC);
PHPAPI php_stream_context *php_stream_context_set(php_stream *stream, php_stream_context *context);
END_EXTERN_C()

#define php_stream_notify_info(context, code, xmsg, xcode)	do { if ((context) && (context)->notifier) { \
	php_stream_notification_notify((context), (code), PHP_STREAM_NOTIFY_SEVERITY_INFO, \
				(xmsg), (xcode), 0, 0, NULL TSRMLS_CC); } } while (0)
			
#define php_stream_notify_progress(context, bsofar, bmax) do { if ((context) && (context)->notifier) { \
	php_stream_notification_notify((context), PHP_STREAM_NOTIFY_PROGRESS, PHP_STREAM_NOTIFY_SEVERITY_INFO, \
			NULL, 0, (bsofar), (bmax), NULL TSRMLS_CC); } } while(0)

#define php_stream_notify_progress_init(context, sofar, bmax) do { if ((context) && (context)->notifier) { \
	(context)->notifier->progress = (sofar); \
	(context)->notifier->progress_max = (bmax); \
	(context)->notifier->mask |= PHP_STREAM_NOTIFIER_PROGRESS; \
	php_stream_notify_progress((context), (sofar), (bmax)); } } while (0)

#define php_stream_notify_progress_increment(context, dsofar, dmax) do { if ((context) && (context)->notifier && (context)->notifier->mask & PHP_STREAM_NOTIFIER_PROGRESS) { \
	(context)->notifier->progress += (dsofar); \
	(context)->notifier->progress_max += (dmax); \
	php_stream_notify_progress((context), (context)->notifier->progress, (context)->notifier->progress_max); } } while (0)

#define php_stream_notify_file_size(context, file_size, xmsg, xcode) do { if ((context) && (context)->notifier) { \
	php_stream_notification_notify((context), PHP_STREAM_NOTIFY_FILE_SIZE_IS, PHP_STREAM_NOTIFY_SEVERITY_INFO, \
			(xmsg), (xcode), 0, (file_size), NULL TSRMLS_CC); } } while(0)
	
#define php_stream_notify_error(context, code, xmsg, xcode) do { if ((context) && (context)->notifier) {\
	php_stream_notification_notify((context), (code), PHP_STREAM_NOTIFY_SEVERITY_ERR, \
			(xmsg), (xcode), 0, 0, NULL TSRMLS_CC); } } while(0)
	

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/main/SAPI.h000064400000022332151730541360007173 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author:  Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: SAPI.h 296362 2010-03-18 22:37:25Z andrei $ */

#ifndef SAPI_H
#define SAPI_H

#include "zend.h"
#include "zend_llist.h"
#include "zend_operators.h"
#ifdef PHP_WIN32
#include "win95nt.h"
#endif
#include <sys/stat.h>

#define SAPI_OPTION_NO_CHDIR 1

#define SAPI_POST_BLOCK_SIZE 4000

#ifdef PHP_WIN32
#	ifdef SAPI_EXPORTS
#	define SAPI_API __declspec(dllexport) 
#	else
#	define SAPI_API __declspec(dllimport) 
#	endif
#else
#define SAPI_API
#endif

#undef shutdown

typedef struct {
	char *header;
	uint header_len;
	zend_bool replace;
} sapi_header_struct;


typedef struct {
	zend_llist headers;
	int http_response_code;
	unsigned char send_default_content_type;
	char *mimetype;
	char *http_status_line;
} sapi_headers_struct;


typedef struct _sapi_post_entry sapi_post_entry;
typedef struct _sapi_module_struct sapi_module_struct;

BEGIN_EXTERN_C()
extern SAPI_API sapi_module_struct sapi_module;  /* true global */
END_EXTERN_C()

/* Some values in this structure needs to be filled in before
 * calling sapi_activate(). We WILL change the `char *' entries,
 * so make sure that you allocate a separate buffer for them
 * and that you free them after sapi_deactivate().
 */

typedef struct {
	const char *request_method;
	char *query_string;
	char *post_data, *raw_post_data;
	char *cookie_data;
	long content_length;
	uint post_data_length, raw_post_data_length;

	char *path_translated;
	char *request_uri;

	const char *content_type;

	zend_bool headers_only;
	zend_bool no_headers;
	zend_bool headers_read;

	sapi_post_entry *post_entry;

	char *content_type_dup;

	/* for HTTP authentication */
	char *auth_user;
	char *auth_password;
	char *auth_digest;

	/* this is necessary for the CGI SAPI module */
	char *argv0;

	/* this is necessary for Safe Mode */
	char *current_user;
	int current_user_length;

	/* this is necessary for CLI module */
	int argc;
	char **argv;
	int proto_num;
} sapi_request_info;


typedef struct _sapi_globals_struct {
	void *server_context;
	sapi_request_info request_info;
	sapi_headers_struct sapi_headers;
	int read_post_bytes;
	unsigned char headers_sent;
	struct stat global_stat;
	char *default_mimetype;
	char *default_charset;
	HashTable *rfc1867_uploaded_files;
	long post_max_size;
	int options;
	zend_bool sapi_started;
	time_t global_request_time;
	HashTable known_post_content_types;
} sapi_globals_struct;


BEGIN_EXTERN_C()
#ifdef ZTS
# define SG(v) TSRMG(sapi_globals_id, sapi_globals_struct *, v)
SAPI_API extern int sapi_globals_id;
#else
# define SG(v) (sapi_globals.v)
extern SAPI_API sapi_globals_struct sapi_globals;
#endif

SAPI_API void sapi_startup(sapi_module_struct *sf);
SAPI_API void sapi_shutdown(void);
SAPI_API void sapi_activate(TSRMLS_D);
SAPI_API void sapi_deactivate(TSRMLS_D);
SAPI_API void sapi_initialize_empty_request(TSRMLS_D);
END_EXTERN_C()

/*
 * This is the preferred and maintained API for 
 * operating on HTTP headers.
 */

/*
 * Always specify a sapi_header_line this way:
 *
 *     sapi_header_line ctr = {0};
 */
 
typedef struct {
	char *line; /* If you allocated this, you need to free it yourself */
	uint line_len;
	long response_code; /* long due to zend_parse_parameters compatibility */
} sapi_header_line;

typedef enum {					/* Parameter: 			*/
	SAPI_HEADER_REPLACE,		/* sapi_header_line* 	*/
	SAPI_HEADER_ADD,			/* sapi_header_line* 	*/
	SAPI_HEADER_SET_STATUS		/* int 					*/
} sapi_header_op_enum;

BEGIN_EXTERN_C()
SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC);

/* Deprecated functions. Use sapi_header_op instead. */
SAPI_API int sapi_add_header_ex(char *header_line, uint header_line_len, zend_bool duplicate, zend_bool replace TSRMLS_DC);
#define sapi_add_header(a, b, c) sapi_add_header_ex((a),(b),(c),1 TSRMLS_CC)


SAPI_API int sapi_send_headers(TSRMLS_D);
SAPI_API void sapi_free_header(sapi_header_struct *sapi_header);
SAPI_API void sapi_handle_post(void *arg TSRMLS_DC);

SAPI_API int sapi_register_post_entries(sapi_post_entry *post_entry TSRMLS_DC);
SAPI_API int sapi_register_post_entry(sapi_post_entry *post_entry TSRMLS_DC);
SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry TSRMLS_DC);
SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D));
SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC));
SAPI_API int sapi_register_input_filter(unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC));

SAPI_API int sapi_flush(TSRMLS_D);
SAPI_API struct stat *sapi_get_stat(TSRMLS_D);
SAPI_API char *sapi_getenv(char *name, size_t name_len TSRMLS_DC);

SAPI_API char *sapi_get_default_content_type(TSRMLS_D);
SAPI_API void sapi_get_default_content_type_header(sapi_header_struct *default_header TSRMLS_DC);
SAPI_API size_t sapi_apply_default_charset(char **mimetype, size_t len TSRMLS_DC);
SAPI_API void sapi_activate_headers_only(TSRMLS_D);

SAPI_API int sapi_get_fd(int *fd TSRMLS_DC);
SAPI_API int sapi_force_http_10(TSRMLS_D);

SAPI_API int sapi_get_target_uid(uid_t * TSRMLS_DC);
SAPI_API int sapi_get_target_gid(gid_t * TSRMLS_DC);
SAPI_API time_t sapi_get_request_time(TSRMLS_D);
END_EXTERN_C()

struct _sapi_module_struct {
	char *name;
	char *pretty_name;

	int (*startup)(struct _sapi_module_struct *sapi_module);
	int (*shutdown)(struct _sapi_module_struct *sapi_module);

	int (*activate)(TSRMLS_D);
	int (*deactivate)(TSRMLS_D);

	int (*ub_write)(const char *str, unsigned int str_length TSRMLS_DC);
	void (*flush)(void *server_context);
	struct stat *(*get_stat)(TSRMLS_D);
	char *(*getenv)(char *name, size_t name_len TSRMLS_DC);

	void (*sapi_error)(int type, const char *error_msg, ...);

	int (*header_handler)(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC);
	int (*send_headers)(sapi_headers_struct *sapi_headers TSRMLS_DC);
	void (*send_header)(sapi_header_struct *sapi_header, void *server_context TSRMLS_DC);

	int (*read_post)(char *buffer, uint count_bytes TSRMLS_DC);
	char *(*read_cookies)(TSRMLS_D);

	void (*register_server_variables)(zval *track_vars_array TSRMLS_DC);
	void (*log_message)(char *message);
	time_t (*get_request_time)(TSRMLS_D);

	char *php_ini_path_override;

	void (*block_interruptions)(void);
	void (*unblock_interruptions)(void);

	void (*default_post_reader)(TSRMLS_D);
	void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC);
	char *executable_location;

	int php_ini_ignore;

	int (*get_fd)(int *fd TSRMLS_DC);

	int (*force_http_10)(TSRMLS_D);

	int (*get_target_uid)(uid_t * TSRMLS_DC);
	int (*get_target_gid)(gid_t * TSRMLS_DC);

	unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC);
	
	void (*ini_defaults)(HashTable *configuration_hash);
	int phpinfo_as_text;

	char *ini_entries;
};


struct _sapi_post_entry {
	char *content_type;
	uint content_type_len;
	void (*post_reader)(TSRMLS_D);
	void (*post_handler)(char *content_type_dup, void *arg TSRMLS_DC);
};

/* header_handler() constants */
#define SAPI_HEADER_ADD			(1<<0)
#define SAPI_HEADER_DELETE_ALL	(1<<1)
#define SAPI_HEADER_SEND_NOW	(1<<2)


#define SAPI_HEADER_SENT_SUCCESSFULLY	1
#define SAPI_HEADER_DO_SEND				2
#define SAPI_HEADER_SEND_FAILED			3

#define SAPI_DEFAULT_MIMETYPE		"text/html"
#define SAPI_DEFAULT_CHARSET		""
#define SAPI_PHP_VERSION_HEADER		"X-Powered-By: PHP/" PHP_VERSION

#define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D)
#define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC)

#define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC)
#define SAPI_INPUT_FILTER_FUNC(input_filter) unsigned int input_filter(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC)

BEGIN_EXTERN_C()
SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data);
SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader);
SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data);
SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter);
END_EXTERN_C()

#define STANDARD_SAPI_MODULE_PROPERTIES

#endif /* SAPI_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 */
php/main/php_config.h000064400000164161151730541360010562 0ustar00/* main/php_config.h.  Generated automatically by configure.  */
/* main/php_config.h.in.  Generated automatically from configure.in by autoheader.  */
/* Leave this file alone */
/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: acconfig.h 293155 2010-01-05 20:46:53Z sebastian $ */

#define ZEND_API
#define ZEND_DLEXPORT
#define ZEND_DLIMPORT


/* Define if on AIX 3.
   System headers sometimes define this.
   We just want to avoid a redefinition error message.  */
#ifndef _ALL_SOURCE
/* #undef _ALL_SOURCE */
#endif

/* Define if using alloca.c.  */
/* #undef C_ALLOCA */

/* Define to empty if the keyword does not work.  */
/* #undef const */

/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
   This function is required for alloca.c support on those systems.  */
/* #undef CRAY_STACKSEG_END */

/* Define to `int' if <sys/types.h> doesn't define.  */
/* #undef gid_t */

/* Define if you have alloca, as a function or macro.  */
#define HAVE_ALLOCA 1

/* Define if you have <alloca.h> and it should be used (not on Ultrix).  */
#define HAVE_ALLOCA_H 1

/* Define if you don't have vprintf but do have _doprnt.  */
/* #undef HAVE_DOPRNT */

/* Define if your system has a working fnmatch function.  */
#define HAVE_FNMATCH 1

/* Define if your struct stat has st_blksize.  */
#define HAVE_ST_BLKSIZE 1

/* Define if your struct stat has st_blocks.  */
#define HAVE_ST_BLOCKS 1

/* Define if your struct stat has st_rdev.  */
#define HAVE_ST_RDEV 1

/* Define if your struct tm has tm_zone.  */
#define HAVE_TM_ZONE 1

/* Define if you don't have tm_zone but do have the external array
   tzname.  */
/* #undef HAVE_TZNAME */

/* Define if utime(file, NULL) sets file's timestamp to the present.  */
#define HAVE_UTIME_NULL 1

/* Define if you have the vprintf function.  */
#define HAVE_VPRINTF 1

/* Define as __inline if that's what the C compiler calls it.  */
/* #undef inline */

/* Define if your C compiler doesn't accept -c and -o together.  */
/* #undef NO_MINUS_C_MINUS_O */

/* Define as the return type of signal handlers (int or void).  */
#define RETSIGTYPE void

/* Define to `unsigned' if <sys/types.h> doesn't define.  */
/* #undef size_t */

/* If using the C implementation of alloca, define if you know the
   direction of stack growth for your system; otherwise it will be
   automatically deduced at run-time.
 STACK_DIRECTION > 0 => grows toward higher addresses
 STACK_DIRECTION < 0 => grows toward lower addresses
 STACK_DIRECTION = 0 => direction of growth unknown
 */
/* #undef STACK_DIRECTION */

/* Define if you have the ANSI C header files.  */
#define STDC_HEADERS 1

/* Define if you can safely include both <sys/time.h> and <time.h>.  */
#define TIME_WITH_SYS_TIME 1

/* Define if your <sys/time.h> declares struct tm.  */
/* #undef TM_IN_SYS_TIME */

/* Define to `int' if <sys/types.h> doesn't define.  */
/* #undef uid_t */

/* Define if lex declares yytext as a char * by default, not a char[].  */
/* #undef YYTEXT_POINTER */

/* #undef uint */
/* #undef ulong */

/* The number of bytes in a char.  */
#define SIZEOF_CHAR 1

/* The number of bytes in a char *.  */
#define SIZEOF_CHAR_P 8

/* The number of bytes in a int.  */
#define SIZEOF_INT 4

/* The number of bytes in a long.  */
#define SIZEOF_LONG 8

/* The number of bytes in a long int.  */
/* #undef SIZEOF_LONG_INT */

/* The number of bytes in a long long.  */
#define SIZEOF_LONG_LONG 8

/* The number of bytes in a long long int.  */
#define SIZEOF_LONG_LONG_INT 8

/* The number of bytes in a short.  */
#define SIZEOF_SHORT 2

/* The number of bytes in a size_t.  */
#define SIZEOF_SIZE_T 8

/* Define if you have the CreateProcess function.  */
/* #undef HAVE_CREATEPROCESS */

/* Define if you have the RAND_egd function.  */
/* #undef HAVE_RAND_EGD */

/* Define if you have the acosh function.  */
#define HAVE_ACOSH 1

/* Define if you have the alphasort function.  */
#define HAVE_ALPHASORT 1

/* Define if you have the asctime_r function.  */
#define HAVE_ASCTIME_R 1

/* Define if you have the asinh function.  */
#define HAVE_ASINH 1

/* Define if you have the atanh function.  */
#define HAVE_ATANH 1

/* Define if you have the atoll function.  */
#define HAVE_ATOLL 1

/* Define if you have the chroot function.  */
#define HAVE_CHROOT 1

/* Define if you have the crypt function.  */
#define HAVE_CRYPT 1

/* Define if you have the crypt_r function.  */
/* #undef HAVE_CRYPT_R */

/* Define if you have the ctermid function.  */
#define HAVE_CTERMID 1

/* Define if you have the ctime_r function.  */
#define HAVE_CTIME_R 1

/* Define if you have the cuserid function.  */
#define HAVE_CUSERID 1

/* Define if you have the fabsf function.  */
#define HAVE_FABSF 1

/* Define if you have the finite function.  */
#define HAVE_FINITE 1

/* Define if you have the flock function.  */
#define HAVE_FLOCK 1

/* Define if you have the floorf function.  */
#define HAVE_FLOORF 1

/* Define if you have the fork function.  */
#define HAVE_FORK 1

/* Define if you have the fpclass function.  */
/* #undef HAVE_FPCLASS */

/* Define if you have the ftok function.  */
#define HAVE_FTOK 1

/* Define if you have the funopen function.  */
/* #undef HAVE_FUNOPEN */

/* Define if you have the gai_strerror function.  */
#define HAVE_GAI_STRERROR 1

/* Define if you have the gcvt function.  */
#define HAVE_GCVT 1

/* Define if you have the getcwd function.  */
#define HAVE_GETCWD 1

/* Define if you have the getgrgid_r function.  */
#define HAVE_GETGRGID_R 1

/* Define if you have the getgrnam_r function.  */
#define HAVE_GETGRNAM_R 1

/* Define if you have the getgroups function.  */
#define HAVE_GETGROUPS 1

/* Define if you have the getloadavg function.  */
#define HAVE_GETLOADAVG 1

/* Define if you have the getlogin function.  */
#define HAVE_GETLOGIN 1

/* Define if you have the getopt function.  */
#define HAVE_GETOPT 1

/* Define if you have the getpgid function.  */
#define HAVE_GETPGID 1

/* Define if you have the getpid function.  */
#define HAVE_GETPID 1

/* Define if you have the getpriority function.  */
#define HAVE_GETPRIORITY 1

/* Define if you have the getprotobyname function.  */
#define HAVE_GETPROTOBYNAME 1

/* Define if you have the getprotobynumber function.  */
#define HAVE_GETPROTOBYNUMBER 1

/* Define if you have the getpwnam_r function.  */
#define HAVE_GETPWNAM_R 1

/* Define if you have the getpwuid_r function.  */
#define HAVE_GETPWUID_R 1

/* Define if you have the getrlimit function.  */
#define HAVE_GETRLIMIT 1

/* Define if you have the getrusage function.  */
#define HAVE_GETRUSAGE 1

/* Define if you have the getservbyname function.  */
#define HAVE_GETSERVBYNAME 1

/* Define if you have the getservbyport function.  */
#define HAVE_GETSERVBYPORT 1

/* Define if you have the getsid function.  */
#define HAVE_GETSID 1

/* Define if you have the gettimeofday function.  */
#define HAVE_GETTIMEOFDAY 1

/* Define if you have the getwd function.  */
#define HAVE_GETWD 1

/* Define if you have the glob function.  */
#define HAVE_GLOB 1

/* Define if you have the gmtime_r function.  */
#define HAVE_GMTIME_R 1

/* Define if you have the grantpt function.  */
#define HAVE_GRANTPT 1

/* Define if you have the hstrerror function.  */
#define HAVE_HSTRERROR 1

/* Define if you have the hypot function.  */
#define HAVE_HYPOT 1

/* Define if you have the inet_ntoa function.  */
#define HAVE_INET_NTOA 1

/* Define if you have the inet_ntop function.  */
#define HAVE_INET_NTOP 1

/* Define if you have the inet_pton function.  */
#define HAVE_INET_PTON 1

/* Define if you have the initgroups function.  */
#define HAVE_INITGROUPS 1

/* Define if you have the isascii function.  */
#define HAVE_ISASCII 1

/* Define if you have the isfinite function.  */
/* #undef HAVE_ISFINITE */

/* Define if you have the isinf function.  */
#define HAVE_ISINF 1

/* Define if you have the isnan function.  */
#define HAVE_ISNAN 1

/* Define if you have the kill function.  */
#define HAVE_KILL 1

/* Define if you have the lchown function.  */
#define HAVE_LCHOWN 1

/* Define if you have the ldap_parse_reference function.  */
#define HAVE_LDAP_PARSE_REFERENCE 1

/* Define if you have the ldap_parse_result function.  */
#define HAVE_LDAP_PARSE_RESULT 1

/* Define if you have the ldap_start_tls_s function.  */
#define HAVE_LDAP_START_TLS_S 1

/* Define if you have the link function.  */
#define HAVE_LINK 1

/* Define if you have the localeconv function.  */
#define HAVE_LOCALECONV 1

/* Define if you have the localtime_r function.  */
#define HAVE_LOCALTIME_R 1

/* Define if you have the lockf function.  */
#define HAVE_LOCKF 1

/* Define if you have the log1p function.  */
#define HAVE_LOG1P 1

/* Define if you have the lrand48 function.  */
#define HAVE_LRAND48 1

/* Define if you have the makedev function.  */
/* #undef HAVE_MAKEDEV */

/* Define if you have the mblen function.  */
#define HAVE_MBLEN 1

/* Define if you have the mbrlen function.  */
#define HAVE_MBRLEN 1

/* Define if you have the mbsinit function.  */
#define HAVE_MBSINIT 1

/* Define if you have the memcpy function.  */
#define HAVE_MEMCPY 1

/* Define if you have the memmove function.  */
#define HAVE_MEMMOVE 1

/* Define if you have the mkfifo function.  */
#define HAVE_MKFIFO 1

/* Define if you have the mknod function.  */
#define HAVE_MKNOD 1

/* Define if you have the mkstemp function.  */
#define HAVE_MKSTEMP 1

/* Define if you have the mmap function.  */
#define HAVE_MMAP 1

/* Define if you have the mremap function.  */
#define HAVE_MREMAP 1

/* Define if you have the mysql_commit function.  */
/* #undef HAVE_MYSQL_COMMIT */

/* Define if you have the mysql_next_result function.  */
/* #undef HAVE_MYSQL_NEXT_RESULT */

/* Define if you have the mysql_sqlstate function.  */
/* #undef HAVE_MYSQL_SQLSTATE */

/* Define if you have the mysql_stmt_prepare function.  */
/* #undef HAVE_MYSQL_STMT_PREPARE */

/* Define if you have the nanosleep function.  */
#define HAVE_NANOSLEEP 1

/* Define if you have the nice function.  */
#define HAVE_NICE 1

/* Define if you have the nl_langinfo function.  */
#define HAVE_NL_LANGINFO 1

/* Define if you have the perror function.  */
#define HAVE_PERROR 1

/* Define if you have the poll function.  */
#define HAVE_POLL 1

/* Define if you have the ptsname function.  */
#define HAVE_PTSNAME 1

/* Define if you have the putenv function.  */
#define HAVE_PUTENV 1

/* Define if you have the rand_r function.  */
#define HAVE_RAND_R 1

/* Define if you have the random function.  */
#define HAVE_RANDOM 1

/* Define if you have the realpath function.  */
#define HAVE_REALPATH 1

/* Define if you have the regcomp function.  */
#define HAVE_REGCOMP 1

/* Define if you have the res_search function.  */
#define HAVE_RES_SEARCH 1

/* Define if you have the rl_completion_matches function.  */
#define HAVE_RL_COMPLETION_MATCHES 1

/* Define if you have the scandir function.  */
#define HAVE_SCANDIR 1

/* Define if you have the setegid function.  */
#define HAVE_SETEGID 1

/* Define if you have the setenv function.  */
#define HAVE_SETENV 1

/* Define if you have the seteuid function.  */
#define HAVE_SETEUID 1

/* Define if you have the setitimer function.  */
#define HAVE_SETITIMER 1

/* Define if you have the setlocale function.  */
#define HAVE_SETLOCALE 1

/* Define if you have the setpgid function.  */
#define HAVE_SETPGID 1

/* Define if you have the setpriority function.  */
#define HAVE_SETPRIORITY 1

/* Define if you have the setsid function.  */
#define HAVE_SETSID 1

/* Define if you have the setsockopt function.  */
#define HAVE_SETSOCKOPT 1

/* Define if you have the setvbuf function.  */
#define HAVE_SETVBUF 1

/* Define if you have the shutdown function.  */
#define HAVE_SHUTDOWN 1

/* Define if you have the sigaction function.  */
#define HAVE_SIGACTION 1

/* Define if you have the sin function.  */
#define HAVE_SIN 1

/* Define if you have the snprintf function.  */
#define HAVE_SNPRINTF 1

/* Define if you have the socketpair function.  */
#define HAVE_SOCKETPAIR 1

/* Define if you have the srand48 function.  */
#define HAVE_SRAND48 1

/* Define if you have the srandom function.  */
#define HAVE_SRANDOM 1

/* Define if you have the statfs function.  */
#define HAVE_STATFS 1

/* Define if you have the statvfs function.  */
#define HAVE_STATVFS 1

/* Define if you have the std_syslog function.  */
/* #undef HAVE_STD_SYSLOG */

/* Define if you have the strcasecmp function.  */
#define HAVE_STRCASECMP 1

/* Define if you have the strcoll function.  */
#define HAVE_STRCOLL 1

/* Define if you have the strdup function.  */
#define HAVE_STRDUP 1

/* Define if you have the strerror function.  */
#define HAVE_STRERROR 1

/* Define if you have the strfmon function.  */
#define HAVE_STRFMON 1

/* Define if you have the strftime function.  */
#define HAVE_STRFTIME 1

/* Define if you have the strlcat function.  */
/* #undef HAVE_STRLCAT */

/* Define if you have the strlcpy function.  */
/* #undef HAVE_STRLCPY */

/* Define if you have the strnlen function.  */
#define HAVE_STRNLEN 1

/* Define if you have the strpbrk function.  */
#define HAVE_STRPBRK 1

/* Define if you have the strptime function.  */
#define HAVE_STRPTIME 1

/* Define if you have the strstr function.  */
#define HAVE_STRSTR 1

/* Define if you have the strtod function.  */
#define HAVE_STRTOD 1

/* Define if you have the strtok_r function.  */
#define HAVE_STRTOK_R 1

/* Define if you have the strtol function.  */
#define HAVE_STRTOL 1

/* Define if you have the strtoll function.  */
#define HAVE_STRTOLL 1

/* Define if you have the strtoul function.  */
#define HAVE_STRTOUL 1

/* Define if you have the strtoull function.  */
#define HAVE_STRTOULL 1

/* Define if you have the symlink function.  */
#define HAVE_SYMLINK 1

/* Define if you have the tempnam function.  */
#define HAVE_TEMPNAM 1

/* Define if you have the tzset function.  */
#define HAVE_TZSET 1

/* Define if you have the unlockpt function.  */
#define HAVE_UNLOCKPT 1

/* Define if you have the unsetenv function.  */
#define HAVE_UNSETENV 1

/* Define if you have the usleep function.  */
#define HAVE_USLEEP 1

/* Define if you have the utime function.  */
#define HAVE_UTIME 1

/* Define if you have the vsnprintf function.  */
#define HAVE_VSNPRINTF 1

/* Define if you have the wait3 function.  */
#define HAVE_WAIT3 1

/* Define if you have the waitpid function.  */
#define HAVE_WAITPID 1

/* Define if you have the </nsapi.h> header file.  */
/* #undef HAVE__NSAPI_H */

/* Define if you have the <ApplicationServices/ApplicationServices.h> header file.  */
/* #undef HAVE_APPLICATIONSERVICES_APPLICATIONSERVICES_H */

/* Define if you have the <alloca.h> header file.  */
#define HAVE_ALLOCA_H 1

/* Define if you have the <arpa/inet.h> header file.  */
#define HAVE_ARPA_INET_H 1

/* Define if you have the <arpa/nameser.h> header file.  */
#define HAVE_ARPA_NAMESER_H 1

/* Define if you have the <assert.h> header file.  */
#define HAVE_ASSERT_H 1

/* Define if you have the <crypt.h> header file.  */
#define HAVE_CRYPT_H 1

/* Define if you have the <default_store.h> header file.  */
/* #undef HAVE_DEFAULT_STORE_H */

/* Define if you have the <dirent.h> header file.  */
#define HAVE_DIRENT_H 1

/* Define if you have the <dlfcn.h> header file.  */
#define HAVE_DLFCN_H 1

/* Define if you have the <errno.h> header file.  */
#define HAVE_ERRNO_H 1

/* Define if you have the <fcntl.h> header file.  */
#define HAVE_FCNTL_H 1

/* Define if you have the <grp.h> header file.  */
#define HAVE_GRP_H 1

/* Define if you have the <ieeefp.h> header file.  */
/* #undef HAVE_IEEEFP_H */

/* Define if you have the <inttypes.h> header file.  */
#define HAVE_INTTYPES_H 1

/* Define if you have the <langinfo.h> header file.  */
#define HAVE_LANGINFO_H 1

/* Define if you have the <limits.h> header file.  */
#define HAVE_LIMITS_H 1

/* Define if you have the <locale.h> header file.  */
#define HAVE_LOCALE_H 1

/* Define if you have the <mach-o/dyld.h> header file.  */
/* #undef HAVE_MACH_O_DYLD_H */

/* Define if you have the <malloc.h> header file.  */
#define HAVE_MALLOC_H 1

/* Define if you have the <monetary.h> header file.  */
#define HAVE_MONETARY_H 1

/* Define if you have the <ndir.h> header file.  */
/* #undef HAVE_NDIR_H */

/* Define if you have the <netdb.h> header file.  */
#define HAVE_NETDB_H 1

/* Define if you have the <netinet/in.h> header file.  */
#define HAVE_NETINET_IN_H 1

/* Define if you have the <netinet/tcp.h> header file.  */
#define HAVE_NETINET_TCP_H 1

/* Define if you have the <openssl/crypto.h> header file.  */
/* #undef HAVE_OPENSSL_CRYPTO_H */

/* Define if you have the <pwd.h> header file.  */
#define HAVE_PWD_H 1

/* Define if you have the <resolv.h> header file.  */
#define HAVE_RESOLV_H 1

/* Define if you have the <signal.h> header file.  */
#define HAVE_SIGNAL_H 1

/* Define if you have the <st.h> header file.  */
/* #undef HAVE_ST_H */

/* Define if you have the <stdarg.h> header file.  */
#define HAVE_STDARG_H 1

/* Define if you have the <stdbool.h> header file.  */
#define HAVE_STDBOOL_H 1

/* Define if you have the <stdint.h> header file.  */
#define HAVE_STDINT_H 1

/* Define if you have the <stdlib.h> header file.  */
#define HAVE_STDLIB_H 1

/* Define if you have the <string.h> header file.  */
#define HAVE_STRING_H 1

/* Define if you have the <strings.h> header file.  */
#define HAVE_STRINGS_H 1

/* Define if you have the <sys/dir.h> header file.  */
/* #undef HAVE_SYS_DIR_H */

/* Define if you have the <sys/file.h> header file.  */
#define HAVE_SYS_FILE_H 1

/* Define if you have the <sys/ioctl.h> header file.  */
#define HAVE_SYS_IOCTL_H 1

/* Define if you have the <sys/ipc.h> header file.  */
#define HAVE_SYS_IPC_H 1

/* Define if you have the <sys/loadavg.h> header file.  */
/* #undef HAVE_SYS_LOADAVG_H */

/* Define if you have the <sys/mkdev.h> header file.  */
/* #undef HAVE_SYS_MKDEV_H */

/* Define if you have the <sys/mman.h> header file.  */
#define HAVE_SYS_MMAN_H 1

/* Define if you have the <sys/mount.h> header file.  */
#define HAVE_SYS_MOUNT_H 1

/* Define if you have the <sys/ndir.h> header file.  */
/* #undef HAVE_SYS_NDIR_H */

/* Define if you have the <sys/param.h> header file.  */
#define HAVE_SYS_PARAM_H 1

/* Define if you have the <sys/poll.h> header file.  */
#define HAVE_SYS_POLL_H 1

/* Define if you have the <sys/resource.h> header file.  */
#define HAVE_SYS_RESOURCE_H 1

/* Define if you have the <sys/select.h> header file.  */
#define HAVE_SYS_SELECT_H 1

/* Define if you have the <sys/socket.h> header file.  */
#define HAVE_SYS_SOCKET_H 1

/* Define if you have the <sys/stat.h> header file.  */
#define HAVE_SYS_STAT_H 1

/* Define if you have the <sys/statfs.h> header file.  */
#define HAVE_SYS_STATFS_H 1

/* Define if you have the <sys/statvfs.h> header file.  */
#define HAVE_SYS_STATVFS_H 1

/* Define if you have the <sys/sysexits.h> header file.  */
/* #undef HAVE_SYS_SYSEXITS_H */

/* Define if you have the <sys/time.h> header file.  */
#define HAVE_SYS_TIME_H 1

/* Define if you have the <sys/times.h> header file.  */
#define HAVE_SYS_TIMES_H 1

/* Define if you have the <sys/types.h> header file.  */
#define HAVE_SYS_TYPES_H 1

/* Define if you have the <sys/un.h> header file.  */
#define HAVE_SYS_UN_H 1

/* Define if you have the <sys/utsname.h> header file.  */
#define HAVE_SYS_UTSNAME_H 1

/* Define if you have the <sys/varargs.h> header file.  */
/* #undef HAVE_SYS_VARARGS_H */

/* Define if you have the <sys/vfs.h> header file.  */
#define HAVE_SYS_VFS_H 1

/* Define if you have the <sys/wait.h> header file.  */
#define HAVE_SYS_WAIT_H 1

/* Define if you have the <sysexits.h> header file.  */
#define HAVE_SYSEXITS_H 1

/* Define if you have the <syslog.h> header file.  */
#define HAVE_SYSLOG_H 1

/* Define if you have the <termios.h> header file.  */
#define HAVE_TERMIOS_H 1

/* Define if you have the <time.h> header file.  */
#define HAVE_TIME_H 1

/* Define if you have the <tuxmodule.h> header file.  */
/* #undef HAVE_TUXMODULE_H */

/* Define if you have the <unistd.h> header file.  */
#define HAVE_UNISTD_H 1

/* Define if you have the <unix.h> header file.  */
/* #undef HAVE_UNIX_H */

/* Define if you have the <utime.h> header file.  */
#define HAVE_UTIME_H 1

/* Define if you have the <wchar.h> header file.  */
#define HAVE_WCHAR_H 1

/* Define if you have the <xmlparse.h> header file.  */
/* #undef HAVE_XMLPARSE_H */

/* Define if you have the <xmltok.h> header file.  */
/* #undef HAVE_XMLTOK_H */

/* Define if you have the m library (-lm).  */
#define HAVE_LIBM 1

/* Define to enable GNU C Library extensions */
#define _GNU_SOURCE 1

/* Enabling BIND8 compatibility for Panther */
/* #undef BIND_8_COMPAT */

/* Define if the target system has /dev/urandom device */
#define HAVE_DEV_URANDOM 1

/* Whether you have AOLserver */
/* #undef HAVE_AOLSERVER */

/*   */
/* #undef HAVE_AP_CONFIG_H */

/*   */
/* #undef HAVE_AP_COMPAT_H */

/*   */
/* #undef HAVE_APACHE */

/*   */
/* #undef HAVE_APACHE */

/*   */
/* #undef HAVE_AP_CONFIG_H */

/*   */
/* #undef HAVE_AP_CONFIG_H */

/*   */
/* #undef HAVE_AP_COMPAT_H */

/*   */
/* #undef HAVE_OLD_COMPAT_H */

/*   */
/* #undef HAVE_AP_CONFIG_H */

/*   */
/* #undef HAVE_AP_COMPAT_H */

/*   */
/* #undef HAVE_OLD_COMPAT_H */

/*   */
/* #undef HAVE_AP_CONFIG_H */

/*   */
/* #undef HAVE_AP_COMPAT_H */

/*   */
/* #undef HAVE_OLD_COMPAT_H */

/*   */
/* #undef USE_TRANSFER_TABLES */

/*   */
/* #undef PHP_APACHE_HAVE_CLIENT_FD */

/*   */
/* #undef HAVE_AP_CONFIG_H */

/*   */
/* #undef HAVE_AP_COMPAT_H */

/*   */
/* #undef HAVE_APACHE_HOOKS */

/*   */
/* #undef HAVE_APACHE */

/*   */
/* #undef HAVE_AP_CONFIG_H */

/*   */
/* #undef HAVE_AP_CONFIG_H */

/*   */
/* #undef HAVE_AP_COMPAT_H */

/*   */
/* #undef HAVE_OLD_COMPAT_H */

/*   */
/* #undef HAVE_AP_CONFIG_H */

/*   */
/* #undef HAVE_AP_COMPAT_H */

/*   */
/* #undef HAVE_OLD_COMPAT_H */

/*   */
/* #undef HAVE_AP_CONFIG_H */

/*   */
/* #undef HAVE_AP_COMPAT_H */

/*   */
/* #undef HAVE_OLD_COMPAT_H */

/*   */
/* #undef USE_TRANSFER_TABLES */

/*   */
/* #undef PHP_APACHE_HAVE_CLIENT_FD */

/* Whether to compile with Caudium support */
/* #undef HAVE_CAUDIUM */

/* Whether you have a Continuity Server */
/* #undef HAVE_CONTINUITY */

/*   */
/* #undef WITH_ZEUS */

/* Whether you have a Netscape/iPlanet/Sun Webserver */
/* #undef HAVE_NSAPI */

/* Whether you have phttpd */
/* #undef HAVE_PHTTPD */

/* whether you want Pi3Web support */
/* #undef WITH_PI3WEB */

/* Whether you use Roxen */
/* #undef HAVE_ROXEN */

/* Whether to use Roxen in ZTS mode */
/* #undef ROXEN_USE_ZTS */

/*   */
#define PHP_FASTCGI 1

/*   */
#define FORCE_CGI_REDIRECT 1

/*   */
#define DISCARD_PATH 0

/*   */
#define ENABLE_PATHINFO_CHECK 1

/* Define if system uses EBCDIC */
/* #undef CHARSET_EBCDIC */

/* Define if processor uses big-endian word */
/* #undef WORDS_BIGENDIAN */

/* whether write(2) works */
#define PHP_WRITE_STDOUT 1

/*   */
#define HAVE_SOCKET 1

/*   */
#define HAVE_SOCKET 1

/*   */
/* #undef HAVE_LIBSOCKET */

/*   */
#define HAVE_SOCKETPAIR 1

/*   */
#define HAVE_SOCKETPAIR 1

/*   */
/* #undef HAVE_LIBSOCKET */

/*   */
#define HAVE_HTONL 1

/*   */
#define HAVE_HTONL 1

/*   */
/* #undef HAVE_LIBSOCKET */

/*   */
#define HAVE_GETHOSTNAME 1

/*   */
#define HAVE_GETHOSTNAME 1

/*   */
/* #undef HAVE_LIBNSL */

/*   */
#define HAVE_GETHOSTBYADDR 1

/*   */
#define HAVE_GETHOSTBYADDR 1

/*   */
/* #undef HAVE_LIBNSL */

/*   */
/* #undef HAVE_YP_GET_DEFAULT_DOMAIN */

/*   */
/* #undef HAVE_YP_GET_DEFAULT_DOMAIN */

/*   */
/* #undef HAVE_LIBNSL */

/*   */
#define HAVE_DLOPEN 1

/*   */
#define HAVE_DLOPEN 1

/*   */
#define HAVE_LIBDL 1

/*   */
#define HAVE_LIBDL 1

/*   */
#define HAVE_RES_SEARCH 1

/*   */
#define HAVE_RES_SEARCH 1

/*   */
#define HAVE_LIBRESOLV 1

/*   */
#define HAVE_RES_SEARCH 1

/*   */
/* #undef HAVE_LIBBIND */

/*   */
#define HAVE_RES_SEARCH 1

/*   */
/* #undef HAVE_LIBSOCKET */

/*   */
#define HAVE_INET_ATON 1

/*   */
#define HAVE_INET_ATON 1

/*   */
#define HAVE_LIBRESOLV 1

/*   */
#define HAVE_INET_ATON 1

/*   */
/* #undef HAVE_LIBBIND */

/*   */
#define HAVE_DN_SKIPNAME 1

/*   */
#define HAVE_DN_SKIPNAME 1

/*   */
#define HAVE_LIBRESOLV 1

/*   */
#define HAVE_DN_SKIPNAME 1

/*   */
/* #undef HAVE_LIBBIND */

/*   */
#define HAVE_FOPENCOOKIE 1

/*   */
#define COOKIE_IO_FUNCTIONS_T cookie_io_functions_t

/*   */
#define COOKIE_SEEKER_USES_OFF64_T 1

/* Define if system has broken getcwd */
/* #undef HAVE_BROKEN_GETCWD */

/* Define if your glibc borks on fopen with mode a+ */
#define HAVE_BROKEN_GLIBC_FOPEN_APPEND 1

/* Whether localtime_r is declared */
/* #undef MISSING_LOCALTIME_R_DECL */

/* Whether gmtime_r is declared */
/* #undef MISSING_GMTIME_R_DECL */

/* Whether asctime_r is declared */
/* #undef MISSING_ASCTIME_R_DECL */

/* Whether ctime_r is declared */
/* #undef MISSING_CTIME_R_DECL */

/* Whether strtok_r is declared */
/* #undef MISSING_STRTOK_R_DECL */

/*   */
#define MISSING_FCLOSE_DECL 0

/*   */
#define MISSING_FCLOSE_DECL 0

/* whether you have tm_gmtoff in struct tm */
#define HAVE_TM_GMTOFF 1

/* whether you have struct flock */
#define HAVE_STRUCT_FLOCK 1

/* Whether you have socklen_t */
#define HAVE_SOCKLEN_T 1

/* Size of intmax_t */
#define SIZEOF_INTMAX_T 8

/* Whether intmax_t is available */
#define HAVE_INTMAX_T 1

/* Size of ssize_t */
#define SIZEOF_SSIZE_T 8

/* Whether ssize_t is available */
#define HAVE_SSIZE_T 1

/* Size of ptrdiff_t */
#define SIZEOF_PTRDIFF_T 8

/* Whether ptrdiff_t is available */
#define HAVE_PTRDIFF_T 1

/* Whether you have struct sockaddr_storage */
#define HAVE_SOCKADDR_STORAGE 1

/* Whether struct sockaddr has field sa_len */
/* #undef HAVE_SOCKADDR_SA_LEN */

/*   */
#define HAVE_NANOSLEEP 1

/*   */
#define HAVE_LIBRT 1

/* Define if you have the getaddrinfo function */
#define HAVE_GETADDRINFO 1

/* Whether system headers declare timezone */
#define HAVE_DECLARED_TIMEZONE 1

/* Whether you have HP-UX 10.x */
/* #undef PHP_HPUX_TIME_R */

/* Whether you have IRIX-style functions */
/* #undef PHP_IRIX_TIME_R */

/* whether you have POSIX readdir_r */
#define HAVE_POSIX_READDIR_R 1

/* whether you have old-style readdir_r */
/* #undef HAVE_OLD_READDIR_R */

/*   */
/* #undef in_addr_t */

/* Define if crypt_r has uses CRYPTD */
/* #undef CRYPT_R_CRYPTD */

/* Define if crypt_r uses struct crypt_data */
/* #undef CRYPT_R_STRUCT_CRYPT_DATA */

/* Define if struct crypt_data requires _GNU_SOURCE */
/* #undef CRYPT_R_GNU_SOURCE */

/* Whether you have gcov */
/* #undef HAVE_GCOV */

/*   */
#define PHP_SAFE_MODE 0

/*   */
#define PHP_SAFE_MODE 0

/*   */
#define PHP_SAFE_MODE_EXEC_DIR "/usr/bin"

/*   */
#define PHP_SAFE_MODE_EXEC_DIR "/usr/bin"

/*   */
#define PHP_SIGCHILD 0

/*   */
#define PHP_SIGCHILD 0

/*   */
#define MAGIC_QUOTES 1

/*   */
#define MAGIC_QUOTES 1

/*   */
#define DEFAULT_SHORT_OPEN_TAG "1"

/*   */
#define DEFAULT_SHORT_OPEN_TAG "1"

/* Whether you have dmalloc */
/* #undef HAVE_DMALLOC */

/* Whether to enable IPv6 support */
#define HAVE_IPV6 1

/*  Define if int32_t type is present.  */
#define HAVE_INT32_T 1

/*  Define if uint32_t type is present.  */
#define HAVE_UINT32_T 1

/* Whether to build date as dynamic module */
/* #undef COMPILE_DL_DATE */

/*   */
#define HAVE_LIBXML 1

/*   */
#define HAVE_LIBXML 1

/* Whether to build libxml as dynamic module */
/* #undef COMPILE_DL_LIBXML */

/* Whether to build openssl as dynamic module */
/* #undef COMPILE_DL_OPENSSL */

/* OpenSSL 0.9.7 or later */
/* #undef HAVE_DSA_DEFAULT_METHOD */

/*   */
#define HAVE_OPENSSL_EXT 1

/* Whether to build pcre as dynamic module */
/* #undef COMPILE_DL_PCRE */

/*   */
/* #undef HAVE_BUNDLED_PCRE */

/*   */
#define HAVE_PCRE 1

/* Whether to build pcre as dynamic module */
/* #undef COMPILE_DL_PCRE */

/* Whether to build zlib as dynamic module */
/* #undef COMPILE_DL_ZLIB */

/*   */
#define HAVE_ZLIB 1

/* Whether to build bcmath as dynamic module */
#define COMPILE_DL_BCMATH 1

/* Whether you have bcmath */
#define HAVE_BCMATH 1

/*   */
#define HAVE_BZ2 1

/* Whether to build bz2 as dynamic module */
/* #undef COMPILE_DL_BZ2 */

/*   */
#define HAVE_CALENDAR 1

/* Whether to build calendar as dynamic module */
/* #undef COMPILE_DL_CALENDAR */

/*   */
#define HAVE_CTYPE 1

/* Whether to build ctype as dynamic module */
/* #undef COMPILE_DL_CTYPE */

/* Have cURL with  SSL support */
#define HAVE_CURL_SSL 1

/* Have cURL with OpenSSL support */
/* #undef HAVE_CURL_OPENSSL */

/* Fix for threadsafe using of MariaDB 10.2 */
#define PHP_CURL_MARIADB102_FIX 1

/* Have cURL with GnuTLS support */
/* #undef HAVE_CURL_GNUTLS */

/*   */
#define HAVE_CURL 1

/*   */
#define HAVE_CURL_VERSION_INFO 1

/*   */
#define HAVE_CURL_EASY_STRERROR 1

/*   */
#define HAVE_CURL_MULTI_STRERROR 1

/*   */
/* #undef PHP_CURL_URL_WRAPPERS */

/* Whether to build curl as dynamic module */
/* #undef COMPILE_DL_CURL */

/*   */
/* #undef QDBM_INCLUDE_FILE */

/*   */
/* #undef DBA_QDBM */

/*   */
/* #undef GDBM_INCLUDE_FILE */

/*   */
/* #undef DBA_GDBM */

/*   */
/* #undef NDBM_INCLUDE_FILE */

/*   */
/* #undef DBA_NDBM */

/*   */
/* #undef DBA_DB4 */

/*   */
/* #undef DB4_INCLUDE_FILE */

/*   */
/* #undef DBA_DB3 */

/*   */
/* #undef DB3_INCLUDE_FILE */

/*   */
/* #undef DBA_DB2 */

/*   */
/* #undef DB2_INCLUDE_FILE */

/*   */
/* #undef DB1_VERSION */

/*   */
/* #undef DB1_VERSION */

/*   */
/* #undef DB1_INCLUDE_FILE */

/*   */
/* #undef DBA_DB1 */

/*   */
/* #undef DBM_INCLUDE_FILE */

/*   */
/* #undef DBM_VERSION */

/*   */
/* #undef DBM_VERSION */

/*   */
/* #undef DBA_DBM */

/*   */
#define DBA_CDB_BUILTIN 1

/*   */
#define DBA_CDB_MAKE 1

/*   */
#define DBA_CDB 1

/*   */
/* #undef CDB_INCLUDE_FILE */

/*   */
#define DBA_CDB 1

/*   */
#define DBA_INIFILE 1

/*   */
#define DBA_FLATFILE 1

/*   */
#define HAVE_DBA 1

/* Whether to build dba as dynamic module */
#define COMPILE_DL_DBA 1

/*   */
#define DBASE 1

/* Whether to build dbase as dynamic module */
#define COMPILE_DL_DBASE 1

/* Whether to build dbx as dynamic module */
#define COMPILE_DL_DBX 1

/*   */
#define HAVE_LIBXML 1

/*   */
#define HAVE_DOM 1

/* Whether to build dom as dynamic module */
#define COMPILE_DL_DOM 1

/* Whether to build enchant as dynamic module */
#define COMPILE_DL_ENCHANT 1

/*   */
#define HAVE_ENCHANT 1

/*   */
#define HAVE_ENCHANT_BROKER_SET_PARAM 1

/*   */
#define ENCHANT_VERSION_STRING "1.5.x"

/* Whether you want EXIF (metadata from images) support */
#define HAVE_EXIF 1

/* Whether to build exif as dynamic module */
/* #undef COMPILE_DL_EXIF */

/* Whether you have FrontBase */
/* #undef HAVE_FBSQL */

/* Whether to build fbsql as dynamic module */
/* #undef COMPILE_DL_FBSQL */

/*   */
/* #undef HAVE_FDFTK_H_LOWER */

/*   */
/* #undef HAVE_FDFTK_5 */

/* Whether to build fdf as dynamic module */
/* #undef COMPILE_DL_FDF */

/*   */
/* #undef HAVE_FDFLIB */

/*   */
/* #undef HAVE_DL */

/*   */
/* #undef HAVE_DL */

/*   */
/* #undef HAVE_LIBDLOPEN */

/*   */
#define HAVE_GZGETS 1

/*   */
#define HAVE_GZGETS 1

/*   */
/* #undef HAVE_LIBZ */

/*   */
#define HAVE_ROUND 1

/*   */
#define HAVE_ROUND 1

/*   */
#define HAVE_LIBM 1

/*   */
#define HAVE_FILEINFOLIB 1

/* magic file path */
#define PHP_DEFAULT_MAGIC_FILE "/usr/share/misc/magic"

/* Whether to build fileinfo as dynamic module */
#define COMPILE_DL_FILEINFO 1

/* Whether to build filter as dynamic module */
/* #undef COMPILE_DL_FILTER */

/* Whether you want FTP support */
#define HAVE_FTP 1

/* Whether to build ftp as dynamic module */
/* #undef COMPILE_DL_FTP */

/*   */
#define USE_GD_IMGSTRTTF 1

/*   */
#define USE_GD_IMGSTRTTF 1

/*   */
#define HAVE_LIBFREETYPE 1

/*   */
/* #undef HAVE_LIBTTF */

/*   */
#define HAVE_LIBT1 1

/*   */
#define HAVE_LIBGD 1

/*   */
#define HAVE_LIBGD13 1

/*   */
#define HAVE_LIBGD15 1

/*   */
#define HAVE_LIBGD20 1

/*   */
#define HAVE_LIBGD204 1

/*   */
#define HAVE_GD_IMAGESETTILE 1

/*   */
#define HAVE_GD_IMAGESETBRUSH 1

/*   */
#define HAVE_GDIMAGECOLORRESOLVE 1

/*   */
#define HAVE_COLORCLOSESTHWB 1

/*   */
#define HAVE_GD_WBMP 1

/*   */
#define HAVE_GD_GD2 1

/*   */
#define HAVE_GD_PNG 1

/*   */
#define HAVE_GD_XBM 1

/*   */
#define HAVE_GD_BUNDLED 1

/*   */
#define HAVE_GD_GIF_READ 1

/*   */
#define HAVE_GD_GIF_CREATE 1

/*   */
#define HAVE_GD_IMAGEELLIPSE 1

/*   */
#define HAVE_GD_FONTCACHESHUTDOWN 1

/*   */
#define HAVE_GD_FONTMUTEX 1

/*   */
#define HAVE_GD_DYNAMIC_CTX_EX 1

/*   */
#define HAVE_GD_GIF_CTX 1

/*   */
#define HAVE_GD_JPG 1

/*   */
#define HAVE_GD_XPM 1

/*   */
#define HAVE_GD_STRINGFT 1

/*   */
#define HAVE_GD_STRINGFTEX 1

/*   */
/* #undef USE_GD_JISX0208 */

/*   */
#define USE_GD_IMGSTRTTF 1

/*   */
#define USE_GD_IMGSTRTTF 1

/*   */
#define HAVE_LIBFREETYPE 1

/*   */
/* #undef HAVE_LIBTTF */

/*   */
#define HAVE_LIBT1 1

/*   */
#define HAVE_LIBGD 1

/*   */
#define HAVE_LIBGD13 1

/*   */
#define HAVE_LIBGD15 1

/*   */
#define HAVE_GD_PNG 1

/*   */
#define HAVE_GD_GIF_READ 1

/*   */
#define HAVE_GD_GIF_CREATE 1

/*   */
#define HAVE_GD_WBMP 1

/*   */
#define HAVE_GD_JPG 1

/*   */
#define HAVE_GD_XPM 1

/*   */
#define HAVE_GD_GD2 1

/*   */
#define HAVE_LIBGD20 1

/*   */
#define HAVE_GD_IMAGESETTILE 1

/*   */
#define HAVE_GD_IMAGEELLIPSE 1

/*   */
#define HAVE_GD_IMAGESETBRUSH 1

/*   */
/* #undef HAVE_GD_STRINGTTF */

/*   */
#define HAVE_GD_STRINGFT 1

/*   */
#define HAVE_GD_STRINGFTEX 1

/*   */
#define HAVE_COLORCLOSESTHWB 1

/*   */
#define HAVE_GDIMAGECOLORRESOLVE 1

/*   */
#define HAVE_GD_GIF_CTX 1

/*   */
/* #undef HAVE_GD_CACHE_CREATE */

/*   */
#define HAVE_GD_FONTCACHESHUTDOWN 1

/*   */
/* #undef HAVE_GD_FREEFONTCACHE */

/*   */
#define HAVE_GD_FONTMUTEX 1

/*   */
#define HAVE_GD_DYNAMIC_CTX_EX 1

/*   */
#define HAVE_LIBGD204 1

/* Whether to build gd as dynamic module */
#define COMPILE_DL_GD 1

/*   */
#define HAVE_LIBINTL 1

/* Whether to build gettext as dynamic module */
/* #undef COMPILE_DL_GETTEXT */

/*   */
#define HAVE_NGETTEXT 1

/*   */
#define HAVE_DNGETTEXT 1

/*   */
#define HAVE_DCNGETTEXT 1

/*   */
#define HAVE_BIND_TEXTDOMAIN_CODESET 1

/* Whether to build gmp as dynamic module */
/* #undef COMPILE_DL_GMP */

/*   */
#define HAVE_GMP 1

/* Have HASH Extension */
#define HAVE_HASH_EXT 1

/* Define if processor uses big-endian word */
/* #undef WORDS_BIGENDIAN */

/* Whether to build hash as dynamic module */
/* #undef COMPILE_DL_HASH */

/*   */
/* #undef HAVE_LIBICONV */

/*   */
/* #undef HAVE_GICONV_H */

/*   */
/* #undef HAVE_LIBICONV */

/* iconv() is aliased to libiconv() in -liconv */
/* #undef ICONV_ALIASED_LIBICONV */

/*   */
#define HAVE_ICONV 1

/* Which iconv implementation to use */
#define PHP_ICONV_IMPL "glibc"

/* Konstantin Chuguev's iconv implementation */
/* #undef HAVE_BSD_ICONV */

/* Which iconv implementation to use */
#define PHP_ICONV_IMPL "glibc"

/* glibc's iconv implementation */
#define HAVE_GLIBC_ICONV 1

/* Which iconv implementation to use */
#define PHP_ICONV_IMPL "glibc"

/* Whether iconv supports error no or not */
#define ICONV_SUPPORTS_ERRNO 1

/* Whether iconv supports error no or not */
#define ICONV_SUPPORTS_ERRNO 1

/* Whether iconv supports error no or not */
#define ICONV_SUPPORTS_ERRNO 1

/* Path to iconv.h */
#define PHP_ICONV_H_PATH </usr/include/iconv.h>

/* Whether to build iconv as dynamic module */
/* #undef COMPILE_DL_ICONV */

/* Whether to build imap as dynamic module */
#define COMPILE_DL_IMAP 1

/*   */
#define HAVE_IMAP 1

/*   */
#define HAVE_IMAP2000 1

/*   */
#define HAVE_IMAP2000 1

/*   */
#define HAVE_IMAP2000 1

/*   */
#define HAVE_IMAP2000 1

/*   */
#define HAVE_IMAP2000 1

/*   */
#define HAVE_IMAP2000 1

/*   */
#define HAVE_IMAP2004 1

/* Whether utf8_mime2text() has new signature */
#define HAVE_NEW_MIME2TEXT 1

/*   */
/* #undef HAVE_IMAP2001 */

/*   */
#define HAVE_LIBPAM 1

/*   */
#define HAVE_LIBCRYPT 1

/*   */
#define HAVE_IMAP_KRB 1

/*   */
#define HAVE_IMAP_SSL 1

/*   */
#define HAVE_IMAP_AUTH_GSS 1

/*   */
#define HAVE_RFC822_OUTPUT_ADDRESS_LIST 1

/*   */
#define HAVE_IBASE 1

/* Whether to build interbase as dynamic module */
#define COMPILE_DL_INTERBASE 1

/* Whether to build intl as dynamic module */
#define COMPILE_DL_INTL 1

/* whether to enable JavaScript Object Serialization support */
#define HAVE_JSON 1 

/* Whether to build json as dynamic module */
#define COMPILE_DL_JSON 1

/* Whether to build ldap as dynamic module */
#define COMPILE_DL_LDAP 1

/*   */
/* #undef HAVE_NSLDAP */

/*   */
/* #undef HAVE_NSLDAP */

/*   */
/* #undef HAVE_NSLDAP */

/*   */
/* #undef HAVE_NSLDAP */

/*   */
/* #undef HAVE_ORALDAP */

/*   */
/* #undef HAVE_ORALDAP_10 */

/*   */
#define HAVE_LDAP 1

/* Whether 3 arg set_rebind_proc() */
#define HAVE_3ARG_SETREBINDPROC 1

/*   */
#define HAVE_LDAP_SASL_SASL_H 1

/*   */
/* #undef HAVE_LDAP_SASL_H */

/* LDAP SASL support */
#define HAVE_LDAP_SASL 1

/* whether to have multibyte string support */
#define HAVE_MBSTRING 1

/* whether to have multibyte regex support */
#define HAVE_MBREGEX 1

/* whether to check multibyte regex backtrack */
#define USE_COMBINATION_EXPLOSION_CHECK 1

/* Whether to build mbstring as dynamic module */
#define COMPILE_DL_MBSTRING 1

/*   */
#define HAVE_LIBMCRYPT 1

/*   */
#define HAVE_LIBMCRYPT 1

/* Whether to build mcrypt as dynamic module */
#define COMPILE_DL_MCRYPT 1

/* Whether to build mhash as dynamic module */
/* #undef COMPILE_DL_MHASH */

/*   */
#define HAVE_LIBMHASH 1

/* Whether to build mime_magic as dynamic module */
/* #undef COMPILE_DL_MIME_MAGIC */

/* magic file path */
/* #undef PHP_MIME_MAGIC_FILE_PATH */

/*   */
/* #undef HAVE_MING */

/*   */
/* #undef HAVE_SWFPREBUILTCLIP */

/*   */
/* #undef HAVE_SWFMOVIE_NAMEDANCHOR */

/*   */
/* #undef HAVE_MING_SETSWFCOMPRESSION */

/*   */
/* #undef HAVE_DESTROY_SWF_BLOCK */

/*   */
/* #undef HAVE_NEW_MING */

/*   */
/* #undef HAVE_MING_ZLIB */

/*   */
/* #undef HAVE_MING_MOVIE_LEVEL */

/* Whether to build ming as dynamic module */
/* #undef COMPILE_DL_MING */

/*   */
/* #undef HAVE_MSQL */

/* Whether to build msql as dynamic module */
/* #undef COMPILE_DL_MSQL */

/*   */
/* #undef MSQL1 */

/*   */
/* #undef MSQL1 */

/* Whether to build mssql as dynamic module */
#define COMPILE_DL_MSSQL 1

/*   */
/* #undef HAVE_LIBDNET_STUB */

/*   */
#define HAVE_MSSQL 1

/*   */
#define HAVE_FREETDS 1

/* Whether you have MySQL */
/* #undef HAVE_MYSQL */

/*   */
/* #undef MYSQL_UNIX_ADDR */

/*   */
/* #undef MYSQL_UNIX_ADDR */

/* Whether to build mysql as dynamic module */
/* #undef COMPILE_DL_MYSQL */

/* embedded MySQL support enabled */
/* #undef HAVE_EMBEDDED_MYSQLI */

/*   */
/* #undef HAVE_MYSQLILIB */

/* Whether to build mysqli as dynamic module */
/* #undef COMPILE_DL_MYSQLI */

/*   */
#define HAVE_NCURSES_H 1

/*   */
#define HAVE_NCURSESLIB 1

/*   */
#define HAVE_NCURSES_PANEL 1

/*   */
#define HAVE_NCURSES_COLOR_SET 1

/*   */
#define HAVE_NCURSES_SLK_COLOR 1

/*   */
#define HAVE_NCURSES_ASSUME_DEFAULT_COLORS 1

/*   */
#define HAVE_NCURSES_USE_EXTENDED_NAMES 1

/* Whether to build ncurses as dynamic module */
#define COMPILE_DL_NCURSES 1

/*   */
/* #undef HAVE_OCI_ENV_CREATE */

/*   */
/* #undef HAVE_OCI_STMT_PREPARE2 */

/*   */
/* #undef HAVE_OCI_ENV_CREATE */

/*   */
/* #undef HAVE_OCI_STMT_PREPARE2 */

/*   */
/* #undef HAVE_OCI8_ATTR_STATEMENT */

/*   */
/* #undef HAVE_OCI8_ATTR_STATEMENT */

/*   */
/* #undef HAVE_OCI_ENV_NLS_CREATE */

/*   */
/* #undef HAVE_OCI_ENV_CREATE */

/*   */
/* #undef HAVE_OCI_STMT_PREPARE2 */

/*   */
/* #undef HAVE_OCI_LOB_READ2 */

/*   */
/* #undef HAVE_OCI8_ATTR_STATEMENT */

/*   */
/* #undef HAVE_OCI_ENV_NLS_CREATE */

/*   */
/* #undef HAVE_OCI_ENV_CREATE */

/*   */
/* #undef HAVE_OCI_STMT_PREPARE2 */

/*   */
/* #undef HAVE_OCI_LOB_READ2 */

/*   */
/* #undef HAVE_OCI8_TEMP_LOB */

/*   */
/* #undef PHP_OCI8_HAVE_COLLECTIONS */

/*   */
/* #undef HAVE_OCI8_TEMP_LOB */

/*   */
/* #undef HAVE_OCI8_TEMP_LOB */

/*   */
/* #undef PHP_OCI8_HAVE_COLLECTIONS */

/* Whether to build oci8 as dynamic module */
/* #undef COMPILE_DL_OCI8 */

/* Whether to build oci8 as dynamic module */
/* #undef COMPILE_DL_OCI8 */

/*   */
/* #undef HAVE_OCI8 */

/*   */
/* #undef HAVE_OCI_INSTANT_CLIENT */

/*   */
/* #undef HAVE_OCI8_ATTR_STATEMENT */

/*   */
/* #undef HAVE_OCI_ENV_NLS_CREATE */

/*   */
/* #undef HAVE_OCI_ENV_CREATE */

/*   */
/* #undef HAVE_OCI_STMT_PREPARE2 */

/*   */
/* #undef HAVE_OCI_LOB_READ2 */

/*   */
/* #undef HAVE_OCI8_TEMP_LOB */

/*   */
/* #undef PHP_OCI8_HAVE_COLLECTIONS */

/* Whether to build oci8 as dynamic module */
/* #undef COMPILE_DL_OCI8 */

/*   */
/* #undef HAVE_OCI8 */

/*   */
/* #undef HAVE_ADABAS */

/*   */
/* #undef HAVE_SAPDB */

/*   */
/* #undef HAVE_SOLID_35 */

/*   */
/* #undef HAVE_SOLID_30 */

/*   */
/* #undef HAVE_SOLID */

/* Needed in sqlunix.h  */
/* #undef SS_LINUX */

/* Needed in sqlunix.h  */
/* #undef SS_LINUX */

/* Needed in sqlunix.h for wchar defs  */
/* #undef SS_FBX */

/* Needed in sqlunix.h for wchar defs  */
/* #undef SS_FBX */

/*   */
/* #undef HAVE_IBMDB2 */

/*   */
/* #undef HAVE_ODBC_ROUTER */

/*   */
/* #undef HAVE_EMPRESS */

/*   */
/* #undef HAVE_EMPRESS */

/*   */
/* #undef AIX */

/*   */
/* #undef HPUX */

/*   */
/* #undef LINUX */

/*   */
/* #undef NEUTRINO */

/*   */
/* #undef ISOLARIS */

/*   */
/* #undef SOLARIS */

/*   */
/* #undef UNIXWARE */

/*   */
/* #undef HAVE_BIRDSTEP */

/*   */
/* #undef HAVE_CODBC */

/*   */
/* #undef HAVE_IODBC */

/*   */
/* #undef HAVE_ODBC2 */

/*   */
/* #undef HAVE_ESOOB */

/*   */
#define HAVE_UNIXODBC 1

/* Whether you want DBMaker */
/* #undef HAVE_DBMAKER */

/*   */
#define HAVE_SQLDATASOURCES 1

/*   */
#define HAVE_UODBC 1

/* Whether to build odbc as dynamic module */
#define COMPILE_DL_ODBC 1

/*   */
#define HAVE_FORK 1

/*   */
#define HAVE_WAITPID 1

/*   */
#define HAVE_SIGACTION 1

/* Whether to build pcntl as dynamic module */
/* #undef COMPILE_DL_PCNTL */

/* Whether to build pdo as dynamic module */
#define COMPILE_DL_PDO 1

/* Whether to build pdo_dblib as dynamic module */
#define COMPILE_DL_PDO_DBLIB 1

/*   */
/* #undef HAVE_LIBDNET_STUB */

/*   */
#define HAVE_PDO_DBLIB 1

/*   */
#define HAVE_FREETDS 1

/*   */
#define HAVE_PDO_FIREBIRD 1

/* Whether to build pdo_firebird as dynamic module */
#define COMPILE_DL_PDO_FIREBIRD 1

/* Whether you have MySQL */
/* #undef HAVE_MYSQL */

/*   */
/* #undef PDO_MYSQL_UNIX_ADDR */

/* Whether to build pdo_mysql as dynamic module */
/* #undef COMPILE_DL_PDO_MYSQL */

/*   */
/* #undef HAVE_OCIENVCREATE */

/*   */
/* #undef HAVE_OCIENVNLSCREATE */

/*   */
/* #undef HAVE_OCILOBISTEMPORARY */

/*   */
/* #undef HAVE_OCILOBISTEMPORARY */

/*   */
/* #undef HAVE_OCICOLLASSIGN */

/*   */
/* #undef HAVE_OCISTMTFETCH2 */

/* Whether to build pdo_oci as dynamic module */
/* #undef COMPILE_DL_PDO_OCI */

/*   */
/* #undef PHP_PDO_OCI_CLIENT_VERSION */

/*   */
/* #undef HAVE_ODBC_H */

/*   */
/* #undef HAVE_ODBCSDK_H */

/*   */
/* #undef HAVE_IODBC_H */

/*   */
/* #undef HAVE_SQLUNIX_H */

/*   */
#define HAVE_SQLTYPES_H 1

/*   */
#define HAVE_SQLUCODE_H 1

/*   */
#define HAVE_SQL_H 1

/*   */
/* #undef HAVE_ISQL_H */

/*   */
#define HAVE_SQLEXT_H 1

/*   */
/* #undef HAVE_ISQLEXT_H */

/*   */
/* #undef HAVE_UDBCEXT_H */

/*   */
/* #undef HAVE_SQLCLI1_H */

/*   */
/* #undef HAVE_LIBRARYMANAGER_H */

/*   */
/* #undef HAVE_CLI0CORE_H */

/*   */
/* #undef HAVE_CLI0EXT_H */

/*   */
/* #undef HAVE_CLI0CLI_H */

/*   */
/* #undef HAVE_CLI0DEFS_H */

/*   */
/* #undef HAVE_CLI0ENV_H */

/* Whether to build pdo_odbc as dynamic module */
#define COMPILE_DL_PDO_ODBC 1

/* Whether to have pg_config.h */
#define HAVE_PG_CONFIG_H 1

/* Whether to have pg_config.h */
#define HAVE_PG_CONFIG_H 1

/* Whether to build PostgreSQL for PDO support or not */
#define HAVE_PDO_PGSQL 1

/* PostgreSQL 7.2.0 or later */
#define HAVE_PQESCAPE 1

/* PostgreSQL 8.1.4 or later */
#define HAVE_PQESCAPE_CONN 1

/* PostgreSQL 8.1.4 or later */
#define HAVE_PQESCAPE_BYTEA_CONN 1

/* PostgreSQL 7.0.x or later */
#define HAVE_PQSETNONBLOCKING 1

/* Broken libpq under windows */
#define HAVE_PQCMDTUPLES 1

/* Older PostgreSQL */
#define HAVE_PQOIDVALUE 1

/* PostgreSQL 7.0.x or later */
#define HAVE_PQCLIENTENCODING 1

/* PostgreSQL 7.4 or later */
#define HAVE_PQPARAMETERSTATUS 1

/* PostgreSQL 7.4 or later */
#define HAVE_PQPROTOCOLVERSION 1

/* PostgreSQL 7.4 or later */
#define HAVE_PGTRANSACTIONSTATUS 1

/* PostgreSQL 7.4 or later */
#define HAVE_PQUNESCAPEBYTEA 1

/* PostgreSQL 7.4 or later */
#define HAVE_PQEXECPARAMS 1

/* PostgreSQL 7.4 or later */
#define HAVE_PQFREEMEM 1

/* PostgreSQL 7.4 or later */
#define HAVE_PQRESULTERRORFIELD 1

/* Whether libpq is compiled with --enable-multibyte */
#define HAVE_PGSQL_WITH_MULTIBYTE_SUPPORT 1

/* prepared statements */
#define HAVE_PQPREPARE 1

/* Whether to build pdo_pgsql as dynamic module */
#define COMPILE_DL_PDO_PGSQL 1

/*   */
#define HAVE_PDO_SQLITELIB 1

/* have commercial sqlite3 with crypto support */
/* #undef HAVE_SQLITE3_KEY */

/* Whether to build pdo_sqlite as dynamic module */
#define COMPILE_DL_PDO_SQLITE 1

/* Whether to build pdo_sqlite as dynamic module */
#define COMPILE_DL_PDO_SQLITE 1

/* Size of a pointer */
#define SQLITE_PTR_SZ SIZEOF_CHAR_P

/* Whether to have pg_config.h */
#define HAVE_PG_CONFIG_H 1

/* Whether to have pg_config.h */
#define HAVE_PG_CONFIG_H 1

/* Whether to build PostgreSQL support or not */
#define HAVE_PGSQL 1

/* PostgreSQL 7.2.0 or later */
#define HAVE_PQESCAPE 1

/* PostgreSQL 7.3.0 or later */
#define HAVE_PQUNESCAPEBYTEA 1

/* PostgreSQL 7.0.x or later */
#define HAVE_PQSETNONBLOCKING 1

/* Broken libpq under windows */
#define HAVE_PQCMDTUPLES 1

/* Older PostgreSQL */
#define HAVE_PQOIDVALUE 1

/* PostgreSQL 7.0.x or later */
#define HAVE_PQCLIENTENCODING 1

/* PostgreSQL 7.4 or later */
#define HAVE_PQPARAMETERSTATUS 1

/* PostgreSQL 7.4 or later */
#define HAVE_PQPROTOCOLVERSION 1

/* PostgreSQL 7.4 or later */
#define HAVE_PGTRANSACTIONSTATUS 1

/* PostgreSQL 7.4 or later */
#define HAVE_PQEXECPARAMS 1

/* PostgreSQL 7.4 or later */
#define HAVE_PQPREPARE 1

/* PostgreSQL 7.4 or later */
#define HAVE_PQEXECPREPARED 1

/* PostgreSQL 7.4 or later */
#define HAVE_PQRESULTERRORFIELD 1

/* PostgreSQL 7.4 or later */
#define HAVE_PQSENDQUERYPARAMS 1

/* PostgreSQL 7.4 or later */
#define HAVE_PQSENDPREPARE 1

/* PostgreSQL 7.4 or later */
#define HAVE_PQSENDQUERYPREPARED 1

/* PostgreSQL 7.4 or later */
#define HAVE_PQPUTCOPYDATA 1

/* PostgreSQL 7.4 or later */
#define HAVE_PQPUTCOPYEND 1

/* PostgreSQL 7.4 or later */
#define HAVE_PQGETCOPYDATA 1

/* PostgreSQL 7.4 or later */
#define HAVE_PQFREEMEM 1

/* PostgreSQL 7.4 or later */
#define HAVE_PQSETERRORVERBOSITY 1

/* PostgreSQL 7.4 or later */
#define HAVE_PQFTABLE 1

/* PostgreSQL 8.1.4 or later */
#define HAVE_PQESCAPE_CONN 1

/* PostgreSQL 8.1.4 or later */
#define HAVE_PQESCAPE_BYTEA_CONN 1

/* Whether libpq is compiled with --enable-multibyte */
#define HAVE_PGSQL_WITH_MULTIBYTE_SUPPORT 1

/* Whether to build pgsql as dynamic module */
#define COMPILE_DL_PGSQL 1

/* Whether to build phar as dynamic module */
#define COMPILE_DL_PHAR 1

/*   */
#define PHAR_HASH_OK 1

/*   */
/* #undef PHAR_HAVE_OPENSSL */

/* whether to include POSIX-like functions */
#define HAVE_POSIX 1

/* Whether to build posix as dynamic module */
#define COMPILE_DL_POSIX 1

/* Whether you have a working ttyname_r */
/* #undef HAVE_TTYNAME_R */

/* Wether struct utsname has domainname */
#define HAVE_UTSNAME_DOMAINNAME 1

/* Whether to build pspell as dynamic module */
#define COMPILE_DL_PSPELL 1

/*   */
#define HAVE_PSPELL 1

/*   */
#define HAVE_RL_CALLBACK_READ_CHAR 1

/*   */
#define HAVE_LIBREADLINE 1

/*   */
/* #undef HAVE_LIBEDIT */

/* Whether to build readline as dynamic module */
/* #undef COMPILE_DL_READLINE */

/* Whether we have librecode 3.5 */
/* #undef HAVE_BROKEN_RECODE */

/* Whether we have librecode 3.5 or higher */
#define HAVE_LIBRECODE 1

/* Whether to build recode as dynamic module */
#define COMPILE_DL_RECODE 1

/* Whether Reflection is enabled */
#define HAVE_REFLECTION 1

/* Whether to build reflection as dynamic module */
/* #undef COMPILE_DL_REFLECTION */

/*   */
#define HAVE_PWRITE 1

/* whether pwrite64 is default */
/* #undef PHP_PWRITE_64 */

/*   */
#define HAVE_PREAD 1

/* whether pread64 is default */
/* #undef PHP_PREAD_64 */

/* Whether to build session as dynamic module */
/* #undef COMPILE_DL_SESSION */

/*   */
#define HAVE_PHP_SESSION 1

/* Whether you have libmm */
/* #undef HAVE_LIBMM */

/*   */
#define HAVE_SHMOP 1

/* Whether to build shmop as dynamic module */
/* #undef COMPILE_DL_SHMOP */

/*   */
#define HAVE_LIBXML 1

/*   */
#define HAVE_SIMPLEXML 1

/* Whether to build simplexml as dynamic module */
/* #undef COMPILE_DL_SIMPLEXML */

/*   */
#define HAVE_NET_SNMP 1

/*   */
#define HAVE_SNMP_PARSE_OID 1

/*   */
#define HAVE_SNMP 1

/*   */
#define UCD_SNMP_HACK 1

/* Whether to build snmp as dynamic module */
#define COMPILE_DL_SNMP 1

/*   */
#define HAVE_LIBXML 1

/*   */
#define HAVE_SOAP 1

/* Whether to build soap as dynamic module */
#define COMPILE_DL_SOAP 1

/* Whether you have struct cmsghdr */
#define HAVE_CMSGHDR 1

/*   */
/* #undef MISSING_MSGHDR_MSGFLAGS */

/*   */
#define HAVE_SOCKETS 1

/* Whether to build sockets as dynamic module */
#define COMPILE_DL_SOCKETS 1

/* Whether struct _zend_object_value is packed */
#define HAVE_PACKED_OBJECT_VALUE 0

/* Whether you want SPL (Standard PHP Library) support */
#define HAVE_SPL 1

/* Whether to build spl as dynamic module */
/* #undef COMPILE_DL_SPL */

/* Have PDO */
#define PHP_SQLITE2_HAVE_PDO 1

/* Whether to build sqlite as dynamic module */
#define COMPILE_DL_SQLITE 1

/* Size of a pointer */
#define SQLITE_PTR_SZ SIZEOF_CHAR_P

/*   */
#define SQLITE_UTF8 1

/* Define if flush should be called explicitly after a buffered io. */
/* #undef HAVE_FLUSHIO */

/*   */
#define HAVE_CRYPT 1

/* Whether the system supports standard DES salt */
#define PHP_STD_DES_CRYPT 1

/* Whether the system supports extended DES salt */
#define PHP_EXT_DES_CRYPT 1

/* Whether the system supports MD5 salt */
#define PHP_MD5_CRYPT 1

/* Whether the system supports BlowFish salt */
#define PHP_BLOWFISH_CRYPT 1

/*   */
#define HAVE_REGEX_T_RE_MAGIC 1

/*   */
#define HSREGEX 1

/*   */
#define REGEX 1

/*   */
#define REGEX 1

/* 1 */
#define HAVE_REGEX_T_RE_MAGIC 1

/*  see #24142  */
#define PHP_ROUND_FUZZ 0.5

/* Define if your system has fork/vfork/CreateProcess */
#define PHP_CAN_SUPPORT_PROC_OPEN 1

/* Whether to enable chroot() function */
#define ENABLE_CHROOT_FUNC 1

/*   */
#define HAVE_RES_NMKQUERY 1

/*   */
#define HAVE_RES_NMKQUERY 1

/*   */
#define HAVE_LIBRESOLV 1

/*   */
#define HAVE_RES_NMKQUERY 1

/*   */
/* #undef HAVE_LIBBIND */

/*   */
#define HAVE_RES_NMKQUERY 1

/*   */
/* #undef HAVE_LIBSOCKET */

/*   */
#define HAVE_RES_NSEND 1

/*   */
#define HAVE_RES_NSEND 1

/*   */
#define HAVE_LIBRESOLV 1

/*   */
#define HAVE_RES_NSEND 1

/*   */
/* #undef HAVE_LIBBIND */

/*   */
#define HAVE_RES_NSEND 1

/*   */
/* #undef HAVE_LIBSOCKET */

/*   */
#define HAVE_DN_EXPAND 1

/*   */
#define HAVE_DN_EXPAND 1

/*   */
#define HAVE_LIBRESOLV 1

/*   */
#define HAVE_DN_EXPAND 1

/*   */
/* #undef HAVE_LIBBIND */

/*   */
#define HAVE_DN_EXPAND 1

/*   */
/* #undef HAVE_LIBSOCKET */

/* whether atof() accepts NAN */
#define HAVE_ATOF_ACCEPTS_NAN 1

/* whether atof() accepts INF */
#define HAVE_ATOF_ACCEPTS_INF 1

/* whether HUGE_VAL == INF */
#define HAVE_HUGE_VAL_INF 1

/* whether HUGE_VAL + -HUGEVAL == NAN */
#define HAVE_HUGE_VAL_NAN 1

/* whether strptime() declaration fails */
#define HAVE_STRPTIME_DECL_FAILS 1

/* Define if your system has mbstate_t in wchar.h */
#define HAVE_MBSTATE_T 1

/* Whether to build standard as dynamic module */
/* #undef COMPILE_DL_STANDARD */

/* Whether to build sybase as dynamic module */
/* #undef COMPILE_DL_SYBASE */

/*   */
/* #undef HAVE_LIBDNET_STUB */

/*   */
/* #undef HAVE_SYBASE */

/*   */
/* #undef PHP_SYBASE_DBOPEN */

/*   */
/* #undef DBMFIX */

/*   */
/* #undef PHP_SYBASE_DBOPEN */

/*   */
#define HAVE_SYBASE_CT 1

/* Whether to build sybase_ct as dynamic module */
#define COMPILE_DL_SYBASE_CT 1

/*   */
#define HAVE_SYSVMSG 1

/* Whether to build sysvmsg as dynamic module */
#define COMPILE_DL_SYSVMSG 1

/* Whether to build sysvsem as dynamic module */
#define COMPILE_DL_SYSVSEM 1

/*   */
#define HAVE_SYSVSEM 1

/*   */
#define HAVE_SEMUN 0

/*   */
#define HAVE_SEMUN 0

/*   */
#define HAVE_SYSVSHM 1

/* Whether to build sysvshm as dynamic module */
#define COMPILE_DL_SYSVSHM 1

/*   */
#define HAVE_TIDYOPTGETDOC 1

/* Whether to build tidy as dynamic module */
#define COMPILE_DL_TIDY 1

/*   */
#define HAVE_TIDY 1

/* Whether to build tokenizer as dynamic module */
/* #undef COMPILE_DL_TOKENIZER */

/*   */
#define HAVE_LIBXML 1

/*   */
/* #undef HAVE_LIBEXPAT */

/*   */
#define HAVE_WDDX 1

/* Whether to build wddx as dynamic module */
#define COMPILE_DL_WDDX 1

/*   */
#define HAVE_LIBXML 1

/*   */
/* #undef HAVE_LIBEXPAT */

/* Whether to build xml as dynamic module */
/* #undef COMPILE_DL_XML */

/*   */
#define HAVE_XML 1

/*   */
#define HAVE_LIBXML 1

/*   */
#define HAVE_XMLREADER 1

/* Whether to build xmlreader as dynamic module */
#define COMPILE_DL_XMLREADER 1

/*   */
#define HAVE_XMLRPC 1

/*   */
#define HAVE_LIBXML 1

/*   */
/* #undef HAVE_LIBEXPAT */

/*   */
/* #undef HAVE_LIBICONV */

/*   */
/* #undef HAVE_GICONV_H */

/*   */
/* #undef HAVE_LIBICONV */

/* iconv() is aliased to libiconv() in -liconv */
/* #undef ICONV_ALIASED_LIBICONV */

/*   */
#define HAVE_ICONV 1

/*   */
#define UNDEF_THREADS_HACK 

/* Whether to build xmlrpc as dynamic module */
#define COMPILE_DL_XMLRPC 1

/* Whether to build xmlrpc as dynamic module */
#define COMPILE_DL_XMLRPC 1

/*   */
#define HAVE_LIBXML 1

/*   */
#define HAVE_XMLWRITER 1

/* Whether to build xmlwriter as dynamic module */
#define COMPILE_DL_XMLWRITER 1

/*   */
#define HAVE_XSL_EXSLT 1

/*   */
#define HAVE_XSL 1

/* Whether to build xsl as dynamic module */
#define COMPILE_DL_XSL 1

/*   */
#define HAVE_ZIP 1

/* Whether to build zip as dynamic module */
#define COMPILE_DL_ZIP 1

/* Define if int32_t type is present.  */
#define HAVE_INT32_T 1

/* Define if uint32_t type is present.  */
#define HAVE_UINT32_T 1

/* Whether sprintf is broken */
#define ZEND_BROKEN_SPRINTF 0

/* whether floatingpoint.h defines fp_except */
/* #undef HAVE_FP_EXCEPT */

/* Define if dlsym() requires a leading underscore in symbol names.  */
/* #undef DLSYM_NEEDS_UNDERSCORE */

/* virtual machine dispatch method */
#define ZEND_VM_KIND ZEND_VM_KIND_CALL

/* virtual machine dispatch method */
#define ZEND_VM_KIND ZEND_VM_KIND_CALL

/* virtual machine dispatch method */
#define ZEND_VM_KIND ZEND_VM_KIND_CALL

/*   */
#define ZEND_DEBUG 0

/*   */
#define ZEND_DEBUG 0

/*   */
/* #undef ZTS */

/*   */
/* #undef ZEND_MULTIBYTE */

/* Define if the target system is darwin */
/* #undef DARWIN */

/*   */
#define ZEND_MM_ALIGNMENT 8

/*   */
#define ZEND_MM_ALIGNMENT_LOG2 3

/* Define if the target system has support for memory allocation using mmap(MAP_ANON) */
#define HAVE_MEM_MMAP_ANON 1

/* Define if the target system has support for memory allocation using mmap(/dev/zero) */
#define HAVE_MEM_MMAP_ZERO 1

/*   */
/* #undef ZTS */

/* Whether you use GNU Pth */
/* #undef GNUPTH */

/*   */
/* #undef TSRM_ST */

/* Whether to use native BeOS threads */
/* #undef BETHREADS */

/* Whether to use Pthreads */
/* #undef PTHREADS */

/* PHP build date */
#define PHP_BUILD_DATE "2026-03-09"

/* hardcode for each of the cross compiler host */
#define PHP_OS "Linux"

/* hardcode for each of the cross compiler host */
#define PHP_UNAME "Linux buildfarm01-new.corp.cloudlinux.com 4.18.0-553.8.1.el8_10.x86_64 #1 SMP Tue Jul 2 07:26:33 EDT 2024 x86_64 x86_64 x86_64 GNU/Linux"

/* uname -a output */
#define PHP_UNAME "Linux buildfarm01-new.corp.cloudlinux.com 4.18.0-553.8.1.el8_10.x86_64 #1 SMP Tue Jul 2 07:26:33 EDT 2024 x86_64 x86_64 x86_64 GNU/Linux"

/* uname output */
#define PHP_OS "Linux"

/*   */
#define HAVE_BUILD_DEFS_H 1


#ifndef ZEND_ACCONFIG_H_NO_C_PROTOS

#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif

#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif

#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif

#ifdef HAVE_IEEEFP_H
# include <ieeefp.h>
#endif

#ifdef HAVE_STRING_H
# include <string.h>
#else
# include <strings.h>
#endif

#if ZEND_BROKEN_SPRINTF
int zend_sprintf(char *buffer, const char *format, ...);
#else
# define zend_sprintf sprintf
#endif

#include <math.h>

/* To enable the is_nan, is_infinite and is_finite PHP functions */
#ifdef NETWARE
	#define HAVE_ISNAN 1
	#define HAVE_ISINF 1
	#define HAVE_ISFINITE 1
#endif

#ifndef zend_isnan
#ifdef HAVE_ISNAN
#define zend_isnan(a) isnan(a)
#elif defined(HAVE_FPCLASS)
#define zend_isnan(a) ((fpclass(a) == FP_SNAN) || (fpclass(a) == FP_QNAN))
#else
#define zend_isnan(a) 0
#endif
#endif

#ifdef HAVE_ISINF
#define zend_isinf(a) isinf(a)
#elif defined(INFINITY)
/* Might not work, but is required by ISO C99 */
#define zend_isinf(a) (((a)==INFINITY)?1:0)
#elif defined(HAVE_FPCLASS)
#define zend_isinf(a) ((fpclass(a) == FP_PINF) || (fpclass(a) == FP_NINF))
#else
#define zend_isinf(a) 0
#endif

#ifdef HAVE_FINITE
#define zend_finite(a) finite(a)
#elif defined(HAVE_ISFINITE) || defined(isfinite)
#define zend_finite(a) isfinite(a)
#elif defined(fpclassify)
#define zend_finite(a) ((fpclassify((a))!=FP_INFINITE&&fpclassify((a))!=FP_NAN)?1:0)
#else
#define zend_finite(a) (zend_isnan(a) ? 0 : zend_isinf(a) ? 0 : 1)
#endif

#endif /* ifndef ZEND_ACCONFIG_H_NO_C_PROTOS */

#ifdef NETWARE
#ifdef USE_WINSOCK
#/*This detection against winsock is of no use*/ undef HAVE_SOCKLEN_T
#/*This detection against winsock is of no use*/ undef HAVE_SYS_SOCKET_H
#endif
#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
/* #undef PTHREADS */
php/main/php.h000064400000027043151730541360007232 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
 */

/* $Id: php.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_H
#define PHP_H

#ifdef HAVE_DMALLOC
#include <dmalloc.h>
#endif

#define PHP_API_VERSION 20041225
#define PHP_HAVE_STREAMS
#define YYDEBUG 0

#include "php_config.h"
#include "php_version.h"
#include "zend.h"
#include "zend_qsort.h"
#include "php_compat.h"

#include "zend_API.h"

#undef sprintf
#define sprintf php_sprintf

/* PHP's DEBUG value must match Zend's ZEND_DEBUG value */
#undef PHP_DEBUG
#define PHP_DEBUG ZEND_DEBUG

#ifdef PHP_WIN32
#include "tsrm_win32.h"
#include "win95nt.h"
#	ifdef PHP_EXPORTS
#	define PHPAPI __declspec(dllexport)
#	else
#	define PHPAPI __declspec(dllimport)
#	endif
#define PHP_DIR_SEPARATOR '\\'
#define PHP_EOL "\r\n"
#else
#define PHPAPI
#define THREAD_LS
#define PHP_DIR_SEPARATOR '/'
#if defined(__MacOSX__)
#define PHP_EOL "\r"
#else 
#define PHP_EOL "\n"
#endif
#endif

#ifdef NETWARE
/* For php_get_uname() function */
#define PHP_UNAME  "NetWare"
#define PHP_OS      PHP_UNAME
#endif

#include "php_regex.h"

#if HAVE_ASSERT_H
#if PHP_DEBUG
#undef NDEBUG
#else
#ifndef NDEBUG
#define NDEBUG
#endif
#endif
#include <assert.h>
#else /* HAVE_ASSERT_H */
#define assert(expr) ((void) (0))
#endif /* HAVE_ASSERT_H */

#define APACHE 0

#if HAVE_UNIX_H
#include <unix.h>
#endif

#if HAVE_ALLOCA_H
#include <alloca.h>
#endif

#if HAVE_BUILD_DEFS_H
#include <build-defs.h>
#endif

/*
 * This is a fast version of strlcpy which should be used, if you
 * know the size of the destination buffer and if you know
 * the length of the source string.
 *
 * size is the allocated number of bytes of dst
 * src_size is the number of bytes excluding the NUL of src
 */

#define PHP_STRLCPY(dst, src, size, src_size)	\
	{											\
		size_t php_str_len;						\
												\
		if (src_size >= size)					\
			php_str_len = size - 1;				\
		else									\
			php_str_len = src_size;				\
		memcpy(dst, src, php_str_len);			\
		dst[php_str_len] = '\0';				\
	}

#ifndef HAVE_STRLCPY
BEGIN_EXTERN_C()
PHPAPI size_t php_strlcpy(char *dst, const char *src, size_t siz);
END_EXTERN_C()
#undef strlcpy
#define strlcpy php_strlcpy
#endif

#ifndef HAVE_STRLCAT
BEGIN_EXTERN_C()
PHPAPI size_t php_strlcat(char *dst, const char *src, size_t siz);
END_EXTERN_C()
#undef strlcat
#define strlcat php_strlcat
#endif

#ifndef HAVE_STRTOK_R
BEGIN_EXTERN_C()
char *strtok_r(char *s, const char *delim, char **last);
END_EXTERN_C()
#endif

#ifndef HAVE_SOCKLEN_T
typedef unsigned int socklen_t;
#endif

#define CREATE_MUTEX(a, b)
#define SET_MUTEX(a)
#define FREE_MUTEX(a)

/*
 * Then the ODBC support can use both iodbc and Solid,
 * uncomment this.
 * #define HAVE_ODBC (HAVE_IODBC|HAVE_SOLID)
 */

#include <stdlib.h>
#include <ctype.h>
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#if HAVE_STDARG_H
#include <stdarg.h>
#else
# if HAVE_SYS_VARARGS_H
# include <sys/varargs.h>
# endif
#endif


#include "zend_hash.h"
#include "php3_compat.h"
#include "zend_alloc.h"
#include "zend_stack.h"

#if STDC_HEADERS
# include <string.h>
#else
# ifndef HAVE_MEMCPY
#  define memcpy(d, s, n)	bcopy((s), (d), (n))
# endif
# ifndef HAVE_MEMMOVE
#  define memmove(d, s, n)	bcopy ((s), (d), (n))
# endif
#endif

#include "safe_mode.h"

#ifndef HAVE_STRERROR
char *strerror(int);
#endif

#if (REGEX == 1 || REGEX == 0) && !defined(NO_REGEX_EXTRA_H)
#include "regex/regex_extra.h"
#endif

#if HAVE_PWD_H
# ifdef PHP_WIN32
#include "win32/param.h"
# else
#include <pwd.h>
#include <sys/param.h>
# endif
#endif

#if HAVE_LIMITS_H
#include <limits.h>
#endif

#ifndef LONG_MAX
#define LONG_MAX 2147483647L
#endif

#ifndef LONG_MIN
#define LONG_MIN (- LONG_MAX - 1)
#endif

#ifndef INT_MAX
#define INT_MAX 2147483647
#endif

#ifndef INT_MIN
#define INT_MIN (- INT_MAX - 1)
#endif

#define PHP_GCC_VERSION ZEND_GCC_VERSION
#define PHP_ATTRIBUTE_MALLOC ZEND_ATTRIBUTE_MALLOC
#define PHP_ATTRIBUTE_FORMAT ZEND_ATTRIBUTE_FORMAT

BEGIN_EXTERN_C()
#include "snprintf.h"
END_EXTERN_C()
#include "spprintf.h"

#define EXEC_INPUT_BUF 4096

#define PHP_MIME_TYPE "application/x-httpd-php"

/* macros */
#define STR_PRINT(str)	((str)?(str):"")

#ifndef MAXPATHLEN
# ifdef PATH_MAX
#  define MAXPATHLEN PATH_MAX
# elif defined(MAX_PATH)
#  define MAXPATHLEN MAX_PATH
# else
#  define MAXPATHLEN 256    /* Should be safe for any weird systems that do not define it */
# endif
#endif


/* global variables */
#if !defined(PHP_WIN32)
#define PHP_SLEEP_NON_VOID
#define php_sleep sleep
extern char **environ;
#endif	/* !defined(PHP_WIN32) */

#ifdef PHP_PWRITE_64
ssize_t pwrite(int, void *, size_t, off64_t);
#endif

#ifdef PHP_PREAD_64
ssize_t pread(int, void *, size_t, off64_t);
#endif

BEGIN_EXTERN_C()
void phperror(char *error);
PHPAPI int php_write(void *buf, uint size TSRMLS_DC);
PHPAPI int php_printf(const char *format, ...) PHP_ATTRIBUTE_FORMAT(printf, 1,
		2);
PHPAPI void php_log_err(char *log_message TSRMLS_DC);
int Debug(char *format, ...) PHP_ATTRIBUTE_FORMAT(printf, 1, 2);
int cfgparse(void);
END_EXTERN_C()

#define php_error zend_error

typedef enum {
	EH_NORMAL = 0,
	EH_SUPPRESS,
	EH_THROW
} error_handling_t;

BEGIN_EXTERN_C()
PHPAPI void php_set_error_handling(error_handling_t error_handling, zend_class_entry *exception_class TSRMLS_DC);
#define php_std_error_handling() php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC)

PHPAPI void php_verror(const char *docref, const char *params, int type, const char *format, va_list args TSRMLS_DC) PHP_ATTRIBUTE_FORMAT(printf, 4, 0);

#ifdef ZTS
#define PHP_ATTR_FMT_OFFSET 1
#else
#define PHP_ATTR_FMT_OFFSET 0
#endif

/* PHPAPI void php_error(int type, const char *format, ...); */
PHPAPI void php_error_docref0(const char *docref TSRMLS_DC, int type, const char *format, ...)
	PHP_ATTRIBUTE_FORMAT(printf, PHP_ATTR_FMT_OFFSET + 3, PHP_ATTR_FMT_OFFSET + 4);
PHPAPI void php_error_docref1(const char *docref TSRMLS_DC, const char *param1, int type, const char *format, ...)
	PHP_ATTRIBUTE_FORMAT(printf, PHP_ATTR_FMT_OFFSET + 4, PHP_ATTR_FMT_OFFSET + 5);
PHPAPI void php_error_docref2(const char *docref TSRMLS_DC, const char *param1, const char *param2, int type, const char *format, ...)
	PHP_ATTRIBUTE_FORMAT(printf, PHP_ATTR_FMT_OFFSET + 5, PHP_ATTR_FMT_OFFSET + 6);
END_EXTERN_C()

#define php_error_docref php_error_docref0

#define zenderror phperror
#define zendlex phplex

#define phpparse zendparse
#define phprestart zendrestart
#define phpin zendin

#define php_memnstr zend_memnstr

/* functions */
BEGIN_EXTERN_C()
int php_register_internal_extensions(TSRMLS_D);

int php_mergesort(void *base, size_t nmemb, register size_t size, int (*cmp)(const void *, const void * TSRMLS_DC) TSRMLS_DC);

PHPAPI void php_register_pre_request_shutdown(void (*func)(void *), void *userdata);

PHPAPI void php_com_initialize(TSRMLS_D);
END_EXTERN_C()

/* PHP-named Zend macro wrappers */
#define PHP_FN					ZEND_FN
#define PHP_MN					ZEND_MN
#define PHP_NAMED_FUNCTION		ZEND_NAMED_FUNCTION
#define PHP_FUNCTION			ZEND_FUNCTION
#define PHP_METHOD  			ZEND_METHOD

#define PHP_RAW_NAMED_FE ZEND_RAW_NAMED_FE
#define PHP_NAMED_FE	ZEND_NAMED_FE
#define PHP_FE			ZEND_FE
#define PHP_DEP_FE      ZEND_DEP_FE
#define PHP_FALIAS		ZEND_FALIAS
#define PHP_DEP_FALIAS	ZEND_DEP_FALIAS
#define PHP_ME          ZEND_ME
#define PHP_MALIAS      ZEND_MALIAS
#define PHP_ABSTRACT_ME ZEND_ABSTRACT_ME
#define PHP_ME_MAPPING  ZEND_ME_MAPPING

#define PHP_MODULE_STARTUP_N	ZEND_MODULE_STARTUP_N
#define PHP_MODULE_SHUTDOWN_N	ZEND_MODULE_SHUTDOWN_N
#define PHP_MODULE_ACTIVATE_N	ZEND_MODULE_ACTIVATE_N
#define PHP_MODULE_DEACTIVATE_N	ZEND_MODULE_DEACTIVATE_N
#define PHP_MODULE_INFO_N		ZEND_MODULE_INFO_N

#define PHP_MODULE_STARTUP_D	ZEND_MODULE_STARTUP_D
#define PHP_MODULE_SHUTDOWN_D	ZEND_MODULE_SHUTDOWN_D
#define PHP_MODULE_ACTIVATE_D	ZEND_MODULE_ACTIVATE_D
#define PHP_MODULE_DEACTIVATE_D	ZEND_MODULE_DEACTIVATE_D
#define PHP_MODULE_INFO_D		ZEND_MODULE_INFO_D

/* Compatibility macros */
#define PHP_MINIT		ZEND_MODULE_STARTUP_N
#define PHP_MSHUTDOWN	ZEND_MODULE_SHUTDOWN_N
#define PHP_RINIT		ZEND_MODULE_ACTIVATE_N
#define PHP_RSHUTDOWN	ZEND_MODULE_DEACTIVATE_N
#define PHP_MINFO		ZEND_MODULE_INFO_N
#define PHP_GINIT		ZEND_GINIT
#define PHP_GSHUTDOWN	ZEND_GSHUTDOWN

#define PHP_MINIT_FUNCTION		ZEND_MODULE_STARTUP_D
#define PHP_MSHUTDOWN_FUNCTION	ZEND_MODULE_SHUTDOWN_D
#define PHP_RINIT_FUNCTION		ZEND_MODULE_ACTIVATE_D
#define PHP_RSHUTDOWN_FUNCTION	ZEND_MODULE_DEACTIVATE_D
#define PHP_MINFO_FUNCTION		ZEND_MODULE_INFO_D
#define PHP_GINIT_FUNCTION		ZEND_GINIT_FUNCTION
#define PHP_GSHUTDOWN_FUNCTION	ZEND_GSHUTDOWN_FUNCTION
 
#define PHP_MODULE_GLOBALS		ZEND_MODULE_GLOBALS


/* Output support */
#include "main/php_output.h"
#define PHPWRITE(str, str_len)		php_body_write((str), (str_len) TSRMLS_CC)
#define PUTS(str)					do {			\
	const char *__str = (str);						\
	php_body_write(__str, strlen(__str) TSRMLS_CC);	\
} while (0)

#define PUTC(c)						(php_body_write(&(c), 1 TSRMLS_CC), (c))
#define PHPWRITE_H(str, str_len)	php_header_write((str), (str_len) TSRMLS_CC)
#define PUTS_H(str)					do {				\
	const char *__str = (str);							\
	php_header_write(__str, strlen(__str) TSRMLS_CC);	\
} while (0)

#define PUTC_H(c)					(php_header_write(&(c), 1 TSRMLS_CC), (c))

#include "php_streams.h"
#include "php_memory_streams.h"
#include "fopen_wrappers.h"


/* Virtual current working directory support */
#include "tsrm_virtual_cwd.h"

#include "zend_constants.h"

/* connection status states */
#define PHP_CONNECTION_NORMAL  0
#define PHP_CONNECTION_ABORTED 1
#define PHP_CONNECTION_TIMEOUT 2

#include "php_reentrancy.h"

/* Finding offsets of elements within structures.
 * Taken from the Apache code, which in turn, was taken from X code...
 */

#ifndef XtOffset
#if defined(CRAY) || (defined(__arm) && !(defined(LINUX) || defined(__riscos__)))
#ifdef __STDC__
#define XtOffset(p_type, field) _Offsetof(p_type, field)
#else
#ifdef CRAY2
#define XtOffset(p_type, field) \
    (sizeof(int)*((unsigned int)&(((p_type)NULL)->field)))

#else /* !CRAY2 */

#define XtOffset(p_type, field) ((unsigned int)&(((p_type)NULL)->field))

#endif /* !CRAY2 */
#endif /* __STDC__ */
#else /* ! (CRAY || __arm) */

#define XtOffset(p_type, field) \
    ((long) (((char *) (&(((p_type)NULL)->field))) - ((char *) NULL)))

#endif /* !CRAY */
#endif /* ! XtOffset */

#ifndef XtOffsetOf
#ifdef offsetof
#define XtOffsetOf(s_type, field) offsetof(s_type, field)
#else
#define XtOffsetOf(s_type, field) XtOffset(s_type*, field)
#endif
#endif /* !XtOffsetOf */

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/main/fopen_wrappers.h000064400000004173151730541360011474 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Jim Winstead <jimw@php.net>                                  |
   +----------------------------------------------------------------------+
 */

/* $Id: fopen_wrappers.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef FOPEN_WRAPPERS_H
#define FOPEN_WRAPPERS_H

BEGIN_EXTERN_C()
#include "php_globals.h"

PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle TSRMLS_DC);
PHPAPI char *expand_filepath(const char *filepath, char *real_path TSRMLS_DC);
PHPAPI char *expand_filepath_ex(const char *filepath, char *real_path, const char *relative_to, size_t relative_to_len TSRMLS_DC);

PHPAPI int php_check_open_basedir(const char *path TSRMLS_DC);
PHPAPI int php_check_open_basedir_ex(const char *path, int warn TSRMLS_DC);
PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path TSRMLS_DC);

PHPAPI int php_check_safe_mode_include_dir(const char *path TSRMLS_DC);

PHPAPI FILE *php_fopen_with_path(const char *filename, const char *mode, const char *path, char **opened_path TSRMLS_DC);

PHPAPI char *php_strip_url_passwd(char *path);
END_EXTERN_C()

#endif
/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 */
php/main/php_compat.h000064400000043304151730541370010574 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 5                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2010 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author:                                                              |
  +----------------------------------------------------------------------+
*/

/* $Id: php_compat.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_COMPAT_H
#define PHP_COMPAT_H

#ifdef PHP_WIN32
#include "config.w32.h"
#else
#include <php_config.h>
#endif

#if defined(HAVE_BUNDLED_PCRE) || !defined(PHP_VERSION)
#define pcre_compile			php_pcre_compile
#define pcre_compile2			php_pcre_compile2
#define pcre_copy_substring		php_pcre_copy_substring
#define pcre_exec			php_pcre_exec
#define pcre_get_substring		php_pcre_get_substring
#define pcre_get_substring_list		php_pcre_get_substring_list
#define pcre_info			php_pcre_info
#define pcre_maketables			php_pcre_maketables
#define pcre_study			php_pcre_study
#define pcre_version			php_pcre_version
#define pcre_fullinfo			php_pcre_fullinfo
#define pcre_free			php_pcre_free
#define pcre_malloc			php_pcre_malloc
#define pcre_config			php_pcre_config
#define pcre_copy_named_substring	php_pcre_copy_named_substring
#define pcre_free_substring		php_pcre_free_substring
#define pcre_free_substring_list	php_pcre_free_substring_list
#define pcre_get_named_substring	php_pcre_get_named_substring
#define pcre_get_stringnumber		php_pcre_get_stringnumber
#define pcre_refcount			php_pcre_refcount
#define _pcre_ord2utf8			php__pcre_ord2utf8
#define _pcre_try_flipped		php__pcre_try_flipped
#define _pcre_valid_utf8		php__pcre_valid_utf8
#define _pcre_xclass			php__pcre_xclass
#define pcre_callout			php_pcre_callout
#define _pcre_OP_lengths		php__pcre_OP_lengths
#define _pcre_utt_names			php__pcre_utt_names
#define _pcre_default_tables		php__pcre_default_tables
#define pcre_get_stringtable_entries	php_pcre_get_stringtable_entries
#define _pcre_is_newline		php__pcre_is_newline
#define pcre_stack_free			php_pcre_stack_free
#define pcre_stack_malloc		php_pcre_stack_malloc
#define _pcre_utf8_table1		php__pcre_utf8_table1
#define _pcre_utf8_table1_size		php__pcre_utf8_table1_size
#define _pcre_utf8_table2		php__pcre_utf8_table2
#define _pcre_utf8_table3		php__pcre_utf8_table3
#define _pcre_utf8_table4		php__pcre_utf8_table4
#define _pcre_utt			php__pcre_utt
#define _pcre_utt_size			php__pcre_utt_size
#define _pcre_was_newline		php__pcre_was_newline
#define _pcre_ucd_records		php__pcre_ucd_records
#define _pcre_ucd_stage1		php__pcre_ucd_stage1
#define _pcre_ucd_stage2		php__pcre_ucd_stage2
#define _pcre_ucp_gentype		php__pcre_ucp_gentype
#endif

#define lookup				php_lookup
#define hashTableInit		php_hashTableInit
#define hashTableDestroy	php_hashTableDestroy
#define hashTableIterInit	php_hashTableIterInit
#define hashTableIterNext	php_hashTableIterNext

#if defined(HAVE_LIBXML) && (defined(HAVE_XML) || defined(HAVE_XMLRPC)) && !defined(HAVE_LIBEXPAT)
#define XML_DefaultCurrent php_XML_DefaultCurrent
#define XML_ErrorString php_XML_ErrorString
#define XML_ExpatVersion php_XML_ExpatVersion
#define XML_ExpatVersionInfo php_XML_ExpatVersionInfo
#define XML_ExternalEntityParserCreate php_XML_ExternalEntityParserCreate
#define XML_GetBase php_XML_GetBase
#define XML_GetBuffer php_XML_GetBuffer
#define XML_GetCurrentByteCount php_XML_GetCurrentByteCount
#define XML_GetCurrentByteIndex php_XML_GetCurrentByteIndex
#define XML_GetCurrentColumnNumber php_XML_GetCurrentColumnNumber
#define XML_GetCurrentLineNumber php_XML_GetCurrentLineNumber
#define XML_GetErrorCode php_XML_GetErrorCode
#define XML_GetIdAttributeIndex php_XML_GetIdAttributeIndex
#define XML_GetInputContext php_XML_GetInputContext
#define XML_GetSpecifiedAttributeCount php_XML_GetSpecifiedAttributeCount
#define XmlGetUtf16InternalEncodingNS php_XmlGetUtf16InternalEncodingNS
#define XmlGetUtf16InternalEncoding php_XmlGetUtf16InternalEncoding
#define XmlGetUtf8InternalEncodingNS php_XmlGetUtf8InternalEncodingNS
#define XmlGetUtf8InternalEncoding php_XmlGetUtf8InternalEncoding
#define XmlInitEncoding php_XmlInitEncoding
#define XmlInitEncodingNS php_XmlInitEncodingNS
#define XmlInitUnknownEncoding php_XmlInitUnknownEncoding
#define XmlInitUnknownEncodingNS php_XmlInitUnknownEncodingNS
#define XML_ParseBuffer php_XML_ParseBuffer
#define XML_Parse php_XML_Parse
#define XML_ParserCreate_MM php_XML_ParserCreate_MM
#define XML_ParserCreateNS php_XML_ParserCreateNS
#define XML_ParserCreate php_XML_ParserCreate
#define XML_ParserFree php_XML_ParserFree
#define XmlParseXmlDecl php_XmlParseXmlDecl
#define XmlParseXmlDeclNS php_XmlParseXmlDeclNS
#define XmlPrologStateInitExternalEntity php_XmlPrologStateInitExternalEntity
#define XmlPrologStateInit php_XmlPrologStateInit
#define XML_SetAttlistDeclHandler php_XML_SetAttlistDeclHandler
#define XML_SetBase php_XML_SetBase
#define XML_SetCdataSectionHandler php_XML_SetCdataSectionHandler
#define XML_SetCharacterDataHandler php_XML_SetCharacterDataHandler
#define XML_SetCommentHandler php_XML_SetCommentHandler
#define XML_SetDefaultHandlerExpand php_XML_SetDefaultHandlerExpand
#define XML_SetDefaultHandler php_XML_SetDefaultHandler
#define XML_SetDoctypeDeclHandler php_XML_SetDoctypeDeclHandler
#define XML_SetElementDeclHandler php_XML_SetElementDeclHandler
#define XML_SetElementHandler php_XML_SetElementHandler
#define XML_SetEncoding php_XML_SetEncoding
#define XML_SetEndCdataSectionHandler php_XML_SetEndCdataSectionHandler
#define XML_SetEndDoctypeDeclHandler php_XML_SetEndDoctypeDeclHandler
#define XML_SetEndElementHandler php_XML_SetEndElementHandler
#define XML_SetEndNamespaceDeclHandler php_XML_SetEndNamespaceDeclHandler
#define XML_SetEntityDeclHandler php_XML_SetEntityDeclHandler
#define XML_SetExternalEntityRefHandlerArg php_XML_SetExternalEntityRefHandlerArg
#define XML_SetExternalEntityRefHandler php_XML_SetExternalEntityRefHandler
#define XML_SetNamespaceDeclHandler php_XML_SetNamespaceDeclHandler
#define XML_SetNotationDeclHandler php_XML_SetNotationDeclHandler
#define XML_SetNotStandaloneHandler php_XML_SetNotStandaloneHandler
#define XML_SetParamEntityParsing php_XML_SetParamEntityParsing
#define XML_SetProcessingInstructionHandler php_XML_SetProcessingInstructionHandler
#define XML_SetReturnNSTriplet php_XML_SetReturnNSTriplet
#define XML_SetStartCdataSectionHandler php_XML_SetStartCdataSectionHandler
#define XML_SetStartDoctypeDeclHandler php_XML_SetStartDoctypeDeclHandler
#define XML_SetStartElementHandler php_XML_SetStartElementHandler
#define XML_SetStartNamespaceDeclHandler php_XML_SetStartNamespaceDeclHandler
#define XML_SetUnknownEncodingHandler php_XML_SetUnknownEncodingHandler
#define XML_SetUnparsedEntityDeclHandler php_XML_SetUnparsedEntityDeclHandler
#define XML_SetUserData php_XML_SetUserData
#define XML_SetXmlDeclHandler php_XML_SetXmlDeclHandler
#define XmlSizeOfUnknownEncoding php_XmlSizeOfUnknownEncoding
#define XML_UseParserAsHandlerArg php_XML_UseParserAsHandlerArg
#define XmlUtf16Encode php_XmlUtf16Encode
#define XmlUtf8Encode php_XmlUtf8Encode
#define XML_FreeContentModel php_XML_FreeContentModel
#define XML_MemMalloc php_XML_MemMalloc
#define XML_MemRealloc php_XML_MemRealloc
#define XML_MemFree php_XML_MemFree
#define XML_UseForeignDTD php_XML_UseForeignDTD
#define XML_GetFeatureList php_XML_GetFeatureList
#define XML_ParserReset php_XML_ParserReset

#ifdef HAVE_GD_BUNDLED
#define any2eucjp php_gd_any2eucjp
#define createwbmp php_gd_createwbmp
#define empty_output_buffer php_gd_empty_output_buffer
#define fill_input_buffer php_gd_fill_input_buffer
#define freewbmp php_gd_freewbmp
#define gdAlphaBlend php_gd_gdAlphaBlend
#define gdCompareInt php_gd_gdCompareInt
#define gdCosT php_gd_gdCosT
#define gdCtxPrintf php_gd_gdCtxPrintf
#define gdDPExtractData php_gd_gdDPExtractData
#define gdFontGetGiant php_gd_gdFontGetGiant
#define gdFontGetLarge php_gd_gdFontGetLarge
#define gdFontGetMediumBold php_gd_gdFontGetMediumBold
#define gdFontGetSmall php_gd_gdFontGetSmall
#define gdFontGetTiny php_gd_gdFontGetTiny
#define gdFontGiant php_gd_gdFontGiant
#define gdFontGiantData php_gd_gdFontGiantData
#define gdFontGiantRep php_gd_gdFontGiantRep
#define gdFontLarge php_gd_gdFontLarge
#define gdFontLargeData php_gd_gdFontLargeData
#define gdFontLargeRep php_gd_gdFontLargeRep
#define gdFontMediumBold php_gd_gdFontMediumBold
#define gdFontMediumBoldData php_gd_gdFontMediumBoldData
#define gdFontMediumBoldRep php_gd_gdFontMediumBoldRep
#define gdFontSmall php_gd_gdFontSmall
#define gdFontSmallData php_gd_gdFontSmallData
#define gdFontSmallRep php_gd_gdFontSmallRep
#define gdFontTiny php_gd_gdFontTiny
#define gdFontTinyData php_gd_gdFontTinyData
#define gdFontTinyRep php_gd_gdFontTinyRep
#define gdGetBuf php_gd_gdGetBuf
#define gdGetByte php_gd_gdGetByte
#define gdGetC php_gd_gdGetC
#define _gdGetColors php_gd__gdGetColors
#define gd_getin php_gd_gd_getin
#define gdGetInt php_gd_gdGetInt
#define gdGetWord php_gd_gdGetWord
#define gdImageAABlend php_gd_gdImageAABlend
#define gdImageAALine php_gd_gdImageAALine
#define gdImageAlphaBlending php_gd_gdImageAlphaBlending
#define gdImageAntialias php_gd_gdImageAntialias
#define gdImageArc php_gd_gdImageArc
#define gdImageBrightness php_gd_gdImageBrightness
#define gdImageChar php_gd_gdImageChar
#define gdImageCharUp php_gd_gdImageCharUp
#define gdImageColor php_gd_gdImageColor
#define gdImageColorAllocate php_gd_gdImageColorAllocate
#define gdImageColorAllocateAlpha php_gd_gdImageColorAllocateAlpha
#define gdImageColorClosest php_gd_gdImageColorClosest
#define gdImageColorClosestAlpha php_gd_gdImageColorClosestAlpha
#define gdImageColorClosestHWB php_gd_gdImageColorClosestHWB
#define gdImageColorDeallocate php_gd_gdImageColorDeallocate
#define gdImageColorExact php_gd_gdImageColorExact
#define gdImageColorExactAlpha php_gd_gdImageColorExactAlpha
#define gdImageColorMatch php_gd_gdImageColorMatch
#define gdImageColorResolve php_gd_gdImageColorResolve
#define gdImageColorResolveAlpha php_gd_gdImageColorResolveAlpha
#define gdImageColorTransparent php_gd_gdImageColorTransparent
#define gdImageCompare php_gd_gdImageCompare
#define gdImageContrast php_gd_gdImageContrast
#define gdImageConvolution php_gd_gdImageConvolution
#define gdImageCopy php_gd_gdImageCopy
#define gdImageCopyMerge php_gd_gdImageCopyMerge
#define gdImageCopyMergeGray php_gd_gdImageCopyMergeGray
#define gdImageCopyResampled php_gd_gdImageCopyResampled
#define gdImageCopyResized php_gd_gdImageCopyResized
#define gdImageCreate php_gd_gdImageCreate
#define gdImageCreateFromGd php_gd_gdImageCreateFromGd
#define gdImageCreateFromGd2 php_gd_gdImageCreateFromGd2
#define gdImageCreateFromGd2Ctx php_gd_gdImageCreateFromGd2Ctx
#define gdImageCreateFromGd2Part php_gd_gdImageCreateFromGd2Part
#define gdImageCreateFromGd2PartCtx php_gd_gdImageCreateFromGd2PartCtx
#define gdImageCreateFromGd2PartPtr php_gd_gdImageCreateFromGd2PartPtr
#define gdImageCreateFromGd2Ptr php_gd_gdImageCreateFromGd2Ptr
#define gdImageCreateFromGdCtx php_gd_gdImageCreateFromGdCtx
#define gdImageCreateFromGdPtr php_gd_gdImageCreateFromGdPtr
#define gdImageCreateFromGif php_gd_gdImageCreateFromGif
#define gdImageCreateFromGifCtx php_gd_gdImageCreateFromGifCtx
#define gdImageCreateFromGifSource php_gd_gdImageCreateFromGifSource
#define gdImageCreateFromJpeg php_gd_gdImageCreateFromJpeg
#define gdImageCreateFromJpegCtx php_gd_gdImageCreateFromJpegCtx
#define gdImageCreateFromJpegPtr php_gd_gdImageCreateFromJpegPtr
#define gdImageCreateFromPng php_gd_gdImageCreateFromPng
#define gdImageCreateFromPngCtx php_gd_gdImageCreateFromPngCtx
#define gdImageCreateFromPngPtr php_gd_gdImageCreateFromPngPtr
#define gdImageCreateFromPngSource php_gd_gdImageCreateFromPngSource
#define gdImageCreateFromWBMP php_gd_gdImageCreateFromWBMP
#define gdImageCreateFromWBMPCtx php_gd_gdImageCreateFromWBMPCtx
#define gdImageCreateFromWBMPPtr php_gd_gdImageCreateFromWBMPPtr
#define gdImageCreateFromXbm php_gd_gdImageCreateFromXbm
#define gdImageCreatePaletteFromTrueColor php_gd_gdImageCreatePaletteFromTrueColor
#define gdImageCreateTrueColor php_gd_gdImageCreateTrueColor
#define gdImageDashedLine php_gd_gdImageDashedLine
#define gdImageDestroy php_gd_gdImageDestroy
#define gdImageEdgeDetectQuick php_gd_gdImageEdgeDetectQuick
#define gdImageEllipse php_gd_gdImageEllipse
#define gdImageEmboss php_gd_gdImageEmboss
#define gdImageFill php_gd_gdImageFill
#define gdImageFilledArc php_gd_gdImageFilledArc
#define gdImageFilledEllipse php_gd_gdImageFilledEllipse
#define gdImageFilledPolygon php_gd_gdImageFilledPolygon
#define gdImageFilledRectangle php_gd_gdImageFilledRectangle
#define _gdImageFillTiled php_gd__gdImageFillTiled
#define gdImageFillToBorder php_gd_gdImageFillToBorder
#define gdImageGaussianBlur php_gd_gdImageGaussianBlur
#define gdImageGd php_gd_gdImageGd
#define gdImageGd2 php_gd_gdImageGd2
#define gdImageGd2Ptr php_gd_gdImageGd2Ptr
#define gdImageGdPtr php_gd_gdImageGdPtr
#define gdImageGetClip php_gd_gdImageGetClip
#define gdImageGetPixel php_gd_gdImageGetPixel
#define gdImageGetTrueColorPixel php_gd_gdImageGetTrueColorPixel
#define gdImageGif php_gd_gdImageGif
#define gdImageGifCtx php_gd_gdImageGifCtx
#define gdImageGifPtr php_gd_gdImageGifPtr
#define gdImageGrayScale php_gd_gdImageGrayScale
#define gdImageInterlace php_gd_gdImageInterlace
#define gdImageJpeg php_gd_gdImageJpeg
#define gdImageJpegCtx php_gd_gdImageJpegCtx
#define gdImageJpegPtr php_gd_gdImageJpegPtr
#define gdImageLine php_gd_gdImageLine
#define gdImageMeanRemoval php_gd_gdImageMeanRemoval
#define gdImageNegate php_gd_gdImageNegate
#define gdImagePaletteCopy php_gd_gdImagePaletteCopy
#define gdImagePng php_gd_gdImagePng
#define gdImagePngCtx php_gd_gdImagePngCtx
#define gdImagePngCtxEx php_gd_gdImagePngCtxEx
#define gdImagePngEx php_gd_gdImagePngEx
#define gdImagePngPtr php_gd_gdImagePngPtr
#define gdImagePngPtrEx php_gd_gdImagePngPtrEx
#define gdImagePngToSink php_gd_gdImagePngToSink
#define gdImagePolygon php_gd_gdImagePolygon
#define gdImageRectangle php_gd_gdImageRectangle
#define gdImageRotate php_gd_gdImageRotate
#define gdImageRotate180 php_gd_gdImageRotate180
#define gdImageRotate270 php_gd_gdImageRotate270
#define gdImageRotate45 php_gd_gdImageRotate45
#define gdImageRotate90 php_gd_gdImageRotate90
#define gdImageSaveAlpha php_gd_gdImageSaveAlpha
#define gdImageSelectiveBlur php_gd_gdImageSelectiveBlur
#define gdImageSetAntiAliased php_gd_gdImageSetAntiAliased
#define gdImageSetAntiAliasedDontBlend php_gd_gdImageSetAntiAliasedDontBlend
#define gdImageSetBrush php_gd_gdImageSetBrush
#define gdImageSetClip php_gd_gdImageSetClip
#define gdImageSetPixel php_gd_gdImageSetPixel
#define gdImageSetStyle php_gd_gdImageSetStyle
#define gdImageSetThickness php_gd_gdImageSetThickness
#define gdImageSetTile php_gd_gdImageSetTile
#define gdImageSkewX php_gd_gdImageSkewX
#define gdImageSkewY php_gd_gdImageSkewY
#define gdImageSmooth php_gd_gdImageSmooth
#define gdImageString php_gd_gdImageString
#define gdImageString16 php_gd_gdImageString16
#define gdImageStringFT php_gd_gdImageStringFT
#define gdImageStringFTEx php_gd_gdImageStringFTEx
#define gdImageStringTTF php_gd_gdImageStringTTF
#define gdImageStringUp php_gd_gdImageStringUp
#define gdImageStringUp16 php_gd_gdImageStringUp16
#define gdImageTrueColorToPalette php_gd_gdImageTrueColorToPalette
#define gdImageWBMP php_gd_gdImageWBMP
#define gdImageWBMPCtx php_gd_gdImageWBMPCtx
#define gdImageWBMPPtr php_gd_gdImageWBMPPtr
#define gdImageXbmCtx php_gd_gdImageXbmCtx
#define gdNewDynamicCtx php_gd_gdNewDynamicCtx
#define gdNewDynamicCtxEx php_gd_gdNewDynamicCtxEx
#define gdNewFileCtx php_gd_gdNewFileCtx
#define gdNewSSCtx php_gd_gdNewSSCtx
#define gdPutBuf php_gd_gdPutBuf
#define gdPutC php_gd_gdPutC
#define _gdPutColors php_gd__gdPutColors
#define gdPutInt php_gd_gdPutInt
#define gd_putout php_gd_gd_putout
#define gdPutWord php_gd_gdPutWord
#define gdSeek php_gd_gdSeek
#define gdSinT php_gd_gdSinT
#define gd_strtok_r php_gd_gd_strtok_r
#define gdTell php_gd_gdTell
#define getmbi php_gd_getmbi
#define init_destination php_gd_init_destination
#define init_source php_gd_init_source
#define jpeg_gdIOCtx_dest php_gd_jpeg_gdIOCtx_dest
#define jpeg_gdIOCtx_src php_gd_jpeg_gdIOCtx_src
#define lsqrt php_gd_lsqrt
#define printwbmp php_gd_printwbmp
#define Putchar php_gd_Putchar
#define putmbi php_gd_putmbi
#define Putword php_gd_Putword
#define readwbmp php_gd_readwbmp
#define skipheader php_gd_skipheader
#define skip_input_data php_gd_skip_input_data
#define term_destination php_gd_term_destination
#define term_source php_gd_term_source
#define writewbmp php_gd_writewbmp
#define ZeroDataBlock php_gd_ZeroDataBlock
#define gdCacheCreate php_gd_gdCacheCreate
#define gdCacheDelete php_gd_gdCacheDelete
#define gdCacheGet php_gd_gdCacheGet
#define gdFontCacheSetup php_gd_gdFontCacheSetup
#define gdFontCacheShutdown php_gd_gdFontCacheShutdown
#define gdFreeFontCache php_gd_gdFreeFontCache
#endif /* HAVE_GD_BUNDLED */

/* Define to specify how much context to retain around the current parse
   point. */
#define XML_CONTEXT_BYTES 1024

/* Define to make parameter entity parsing functionality available. */
#define XML_DTD 1

/* Define to make XML Namespaces functionality available. */
#define XML_NS 1
#endif

#ifdef PHP_EXPORTS
#define PCRE_STATIC
#endif

#endif
php/main/build-defs.h000064400000016357151730541370010470 0ustar00/*                                                                -*- C -*-
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2007 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Stig S�ther Bakken <ssb@php.net>                             |
   +----------------------------------------------------------------------+
*/

/* $Id: build-defs.h.in 292156 2009-12-15 11:17:47Z jani $ */

#define CONFIGURE_COMMAND " './configure'  '--build=x86_64-redhat-linux-gnu' '--host=x86_64-redhat-linux-gnu' '--program-prefix=' '--disable-dependency-tracking' '--prefix=/usr' '--exec-prefix=/usr' '--bindir=/usr/bin' '--sbindir=/usr/sbin' '--sysconfdir=/etc' '--datadir=/usr/share' '--includedir=/usr/include' '--libdir=/usr/lib64' '--libexecdir=/usr/libexec' '--localstatedir=/var' '--sharedstatedir=/var/lib' '--mandir=/usr/share/man' '--infodir=/usr/share/info' '--build=x86_64-redhat-linux-gnu' '--host=x86_64-redhat-linux-gnu' '--target=x86_64-redhat-linux-gnu' '--program-prefix=' '--prefix=/opt/alt/php52' '--exec-prefix=/opt/alt/php52' '--bindir=/opt/alt/php52/usr/bin' '--sbindir=/opt/alt/php52/usr/sbin' '--sysconfdir=/opt/alt/php52/etc' '--datadir=/opt/alt/php52/usr/share' '--includedir=/opt/alt/php52/usr/include' '--libdir=/opt/alt/php52/usr/lib64' '--libexecdir=/opt/alt/php52/usr/libexec' '--localstatedir=/var' '--sharedstatedir=/usr/com' '--mandir=/opt/alt/php52/usr/share/man' '--infodir=/opt/alt/php52/usr/share/info' '--cache-file=../config.cache' '--with-libdir=lib64' '--with-config-file-path=/opt/alt/php52/etc' '--with-config-file-scan-dir=/opt/alt/php52/link/conf' '--with-exec-dir=/usr/bin' '--with-layout=GNU' '--disable-debug' '--without-pear' '--without-gdbm' '--with-pic' '--with-bz2' '--with-zlib' '--with-gettext' '--with-gmp' '--with-iconv' '--with-kerberos=/opt/alt/krb5/usr' '--with-mhash' '--with-readline' '--with-webp=/opt/alt/libwebp' '--with-pcre-regex=/opt/alt/pcre802/usr' '--with-libxml-dir=/opt/alt/libxml2/usr' '--with-curl=/opt/alt/curlssl11/usr' '--with-openssl=/opt/alt/openssl11' '--with-openssl-dir=/opt/alt/openssl11' '--enable-exif' '--enable-ftp' '--enable-magic-quotes' '--enable-shmop' '--enable-calendar' '--enable-xml' '--enable-force-cgi-redirect' '--enable-bcmath=shared' '--enable-dba=shared' '--enable-dbase=shared' '--enable-dbx=shared,/usr' '--enable-dom=shared' '--enable-fastcgi' '--enable-intl=shared' '--enable-json=shared' '--enable-mbstring=shared' '--enable-mbregex' '--enable-pcntl' '--enable-pdo=shared' '--enable-phar=shared' '--enable-posix=shared' '--enable-soap=shared' '--enable-sockets=shared' '--enable-sysvsem=shared' '--enable-sysvshm=shared' '--enable-sysvmsg=shared' '--enable-ucd-snmp-hack' '--enable-wddx=shared' '--enable-xmlreader=shared' '--enable-xmlwriter=shared' '--enable-zip=shared' '--with-enchant=shared,/usr' '--with-fileinfo=shared' '--with-freetype-dir=/usr' '--with-gd=shared' '--enable-gd-native-ttf' '--with-icu-dir=/opt/alt/libicu57/usr' '--with-imap=shared,/opt/alt/libc-client11' '--with-imap-ssl=/opt/alt/openssl11' '--with-jpeg-dir=/usr' '--with-ldap=shared,/opt/alt/openldap11' '--with-ldap-sasl' '--with-mcrypt=shared,/usr' '--with-ncurses=shared' '--with-pdo-odbc=shared,unixODBC,/usr' '--with-pdo-sqlite=shared,/usr' '--with-png-dir=/usr' '--with-pspell=shared' '--with-snmp=shared,/opt/alt/net-snmp11/usr' '--with-sqlite=shared' '--enable-sqlite-utf8' '--with-tidy=shared,/usr' '--with-unixODBC=shared,/usr' '--with-xmlrpc=shared' '--with-xpm-dir=/usr' '--with-pdo-pgsql=shared,/usr' '--with-pgsql=shared,/usr' '--with-mssql=shared,/opt/alt/freetds11/usr' '--with-pdo-dblib=shared,/opt/alt/freetds11/usr' '--with-sybase-ct=shared,/opt/alt/freetds11/usr' '--with-t1lib=/opt/alt/t1lib/usr' '--with-interbase=shared,/usr' '--with-pdo-firebird=shared,/usr' '--with-recode=shared,/usr' '--with-unixODBC=shared,/usr' '--with-xsl=shared,/usr'"
#define PHP_ADA_INCLUDE		""
#define PHP_ADA_LFLAGS		""
#define PHP_ADA_LIBS		""
#define PHP_APACHE_INCLUDE	""
#define PHP_APACHE_TARGET	""
#define PHP_FHTTPD_INCLUDE      ""
#define PHP_FHTTPD_LIB          ""
#define PHP_FHTTPD_TARGET       ""
#define PHP_CFLAGS		"$(CFLAGS_CLEAN) -prefer-non-pic -static"
#define PHP_DBASE_LIB		""
#define PHP_BUILD_DEBUG		""
#define PHP_GDBM_INCLUDE	""
#define PHP_IBASE_INCLUDE	""
#define PHP_IBASE_LFLAGS	""
#define PHP_IBASE_LIBS		""
#define PHP_IFX_INCLUDE		""
#define PHP_IFX_LFLAGS		""
#define PHP_IFX_LIBS		""
#define PHP_INSTALL_IT		"@echo "Installing PHP CGI binary: $(INSTALL_ROOT)$(bindir)/"; $(INSTALL) -m 0755 $(SAPI_CGI_PATH) $(INSTALL_ROOT)$(bindir)/$(program_prefix)php-cgi$(program_suffix)$(EXEEXT)"
#define PHP_IODBC_INCLUDE	""
#define PHP_IODBC_LFLAGS	""
#define PHP_IODBC_LIBS		""
#define PHP_MSQL_INCLUDE	""
#define PHP_MSQL_LFLAGS		""
#define PHP_MSQL_LIBS		""
#define PHP_MYSQL_INCLUDE	""
#define PHP_MYSQL_LIBS		""
#define PHP_MYSQL_TYPE		""
#define PHP_ODBC_INCLUDE	"-I/usr/include"
#define PHP_ODBC_LFLAGS		"-L/usr/lib64"
#define PHP_ODBC_LIBS		"-lodbc"
#define PHP_ODBC_TYPE		"unixODBC"
#define PHP_OCI8_SHARED_LIBADD 	""
#define PHP_OCI8_DIR			""
#define PHP_OCI8_VERSION		""
#define PHP_ORACLE_SHARED_LIBADD 	"@ORACLE_SHARED_LIBADD@"
#define PHP_ORACLE_DIR				"@ORACLE_DIR@"
#define PHP_ORACLE_VERSION			"@ORACLE_VERSION@"
#define PHP_PGSQL_INCLUDE	""
#define PHP_PGSQL_LFLAGS	""
#define PHP_PGSQL_LIBS		""
#define PHP_PROG_SENDMAIL	"/usr/sbin/sendmail"
#define PHP_SOLID_INCLUDE	""
#define PHP_SOLID_LIBS		""
#define PHP_EMPRESS_INCLUDE	""
#define PHP_EMPRESS_LIBS	""
#define PHP_SYBASE_INCLUDE	""
#define PHP_SYBASE_LFLAGS	""
#define PHP_SYBASE_LIBS		""
#define PHP_DBM_TYPE		""
#define PHP_DBM_LIB		""
#define PHP_LDAP_LFLAGS		""
#define PHP_LDAP_INCLUDE	""
#define PHP_LDAP_LIBS		""
#define PHP_BIRDSTEP_INCLUDE     ""
#define PHP_BIRDSTEP_LIBS        ""
#define PEAR_INSTALLDIR         "/opt/alt/php52/usr/share/pear"
#define PHP_INCLUDE_PATH	".:/opt/alt/php52/usr/share/pear:/opt/alt/php52/usr/share/php"
#define PHP_EXTENSION_DIR       "/opt/alt/php52/usr/lib64/php/modules"
#define PHP_PREFIX              "/opt/alt/php52"
#define PHP_BINDIR              "/opt/alt/php52/usr/bin"
#define PHP_SBINDIR             "/opt/alt/php52/usr/sbin"
#define PHP_LIBDIR              "/opt/alt/php52/usr/lib64"
#define PHP_DATADIR             "/opt/alt/php52/usr/share"
#define PHP_SYSCONFDIR          "/opt/alt/php52/etc"
#define PHP_LOCALSTATEDIR       "/var"
#define PHP_CONFIG_FILE_PATH    "/opt/alt/php52/etc"
#define PHP_CONFIG_FILE_SCAN_DIR    "/opt/alt/php52/link/conf"
#define PHP_SHLIB_SUFFIX        "so"
php/main/php_ticks.h000064400000003115151730541400010414 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Stig Bakken <ssb@php.net>                                    |
   +----------------------------------------------------------------------+
*/

/* $Id: php_ticks.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_TICKS_H
#define PHP_TICKS_H

int php_startup_ticks(TSRMLS_D);
void php_deactivate_ticks(TSRMLS_D);
void php_shutdown_ticks(TSRMLS_D);
void php_run_ticks(int count);

BEGIN_EXTERN_C()
PHPAPI void php_add_tick_function(void (*func)(int));
PHPAPI void php_remove_tick_function(void (*func)(int));
END_EXTERN_C()

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 */
php/main/spprintf.h000064400000004113151730541400010274 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Marcus Boerger <helly@php.net>                               |
   +----------------------------------------------------------------------+
 */

/* $Id: spprintf.h 293036 2010-01-03 09:23:27Z sebastian $ */

/* 

The pbuf parameter of all spprintf version receives a pointer to the allocated
buffer. This buffer must be freed manually after usage using efree() function.
The buffer will allways be terminated by a zero character. When pbuf is NULL
the function can be used to calculate the required size of the buffer but for
that purpose snprintf is faster. When both pbuf and the return value are 0
than you are out of memory.

There is also snprintf: See difference explained in snprintf.h

*/

#ifndef SPPRINTF_H
#define SPPRINTF_H

#include "snprintf.h"

BEGIN_EXTERN_C()
PHPAPI int spprintf( char **pbuf, size_t max_len, const char *format, ...) PHP_ATTRIBUTE_FORMAT(printf, 3, 4);

PHPAPI int vspprintf(char **pbuf, size_t max_len, const char *format, va_list ap) PHP_ATTRIBUTE_FORMAT(printf, 3, 0);
END_EXTERN_C()

#endif /* SNPRINTF_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 */
php/main/php_output.h000064400000011236151730541400010642 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Zeev Suraski <zeev@zend.com>                                 |
   +----------------------------------------------------------------------+
*/

/* $Id: php_output.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_OUTPUT_H
#define PHP_OUTPUT_H

typedef void (*php_output_handler_func_t)(char *output, uint output_len, char **handled_output, uint *handled_output_len, int mode TSRMLS_DC);

BEGIN_EXTERN_C()
PHPAPI void php_output_startup(void);
PHPAPI void php_output_activate(TSRMLS_D);
PHPAPI void php_output_set_status(zend_bool status TSRMLS_DC);
PHPAPI void php_output_register_constants(TSRMLS_D);
PHPAPI int  php_default_output_func(const char *str, uint str_len TSRMLS_DC);
PHPAPI int  php_ub_body_write(const char *str, uint str_length TSRMLS_DC);
PHPAPI int  php_ub_body_write_no_header(const char *str, uint str_length TSRMLS_DC);
PHPAPI int  php_body_write(const char *str, uint str_length TSRMLS_DC);
PHPAPI int  php_header_write(const char *str, uint str_length TSRMLS_DC);
PHPAPI int php_start_ob_buffer(zval *output_handler, uint chunk_size, zend_bool erase TSRMLS_DC);
PHPAPI int php_start_ob_buffer_named(const char *output_handler_name, uint chunk_size, zend_bool erase TSRMLS_DC);
PHPAPI void php_end_ob_buffer(zend_bool send_buffer, zend_bool just_flush TSRMLS_DC);
PHPAPI void php_end_ob_buffers(zend_bool send_buffer TSRMLS_DC);
PHPAPI int php_ob_get_buffer(zval *p TSRMLS_DC);
PHPAPI int php_ob_get_length(zval *p TSRMLS_DC);
PHPAPI void php_start_implicit_flush(TSRMLS_D);
PHPAPI void php_end_implicit_flush(TSRMLS_D);
PHPAPI char *php_get_output_start_filename(TSRMLS_D);
PHPAPI int php_get_output_start_lineno(TSRMLS_D);
PHPAPI void php_ob_set_internal_handler(php_output_handler_func_t internal_output_handler, uint buffer_size, char *handler_name, zend_bool erase TSRMLS_DC);
PHPAPI int php_ob_handler_used(char *handler_name TSRMLS_DC);
PHPAPI int php_ob_init_conflict(char *handler_new, char *handler_set TSRMLS_DC);
PHPAPI int php_ob_get_buffer(zval *p TSRMLS_DC);
PHPAPI int php_ob_get_length(zval *p TSRMLS_DC);
END_EXTERN_C()

PHP_FUNCTION(ob_start);
PHP_FUNCTION(ob_flush);
PHP_FUNCTION(ob_clean);
PHP_FUNCTION(ob_end_flush);
PHP_FUNCTION(ob_end_clean);
PHP_FUNCTION(ob_get_flush);
PHP_FUNCTION(ob_get_clean);
PHP_FUNCTION(ob_get_contents);
PHP_FUNCTION(ob_get_length);
PHP_FUNCTION(ob_get_level);
PHP_FUNCTION(ob_get_status);
PHP_FUNCTION(ob_implicit_flush);
PHP_FUNCTION(ob_list_handlers);

typedef struct _php_ob_buffer {
	char *buffer;
	uint size;
	uint text_length;
	int block_size;
	uint chunk_size;
	int status;
	zval *output_handler;
	php_output_handler_func_t internal_output_handler;
	char *internal_output_handler_buffer;
	uint internal_output_handler_buffer_size;
	char *handler_name;
	zend_bool erase;
} php_ob_buffer;

typedef struct _php_output_globals {
	int (*php_body_write)(const char *str, uint str_length TSRMLS_DC);		/* string output */
	int (*php_header_write)(const char *str, uint str_length TSRMLS_DC);	/* unbuffer string output */
	php_ob_buffer active_ob_buffer;
	unsigned char implicit_flush;
	char *output_start_filename;
	int output_start_lineno;
	zend_stack ob_buffers;
	int ob_nesting_level;
	zend_bool ob_lock;
	zend_bool disable_output;
} php_output_globals;

#ifdef ZTS
#define OG(v) TSRMG(output_globals_id, php_output_globals *, v)
ZEND_API extern int output_globals_id;
#else
#define OG(v) (output_globals.v)
ZEND_API extern php_output_globals output_globals;
#endif

#define PHP_OUTPUT_HANDLER_START		(1<<0)
#define PHP_OUTPUT_HANDLER_CONT			(1<<1)
#define PHP_OUTPUT_HANDLER_END			(1<<2)

#define PHP_OUTPUT_HANDLER_INTERNAL     0
#define PHP_OUTPUT_HANDLER_USER        1

PHP_FUNCTION(output_add_rewrite_var);
PHP_FUNCTION(output_reset_rewrite_vars);


#endif /* PHP_OUTPUT_H */
php/main/php_scandir.h000064400000003701151730541410010724 0ustar00/* 
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Shane Caraveo <shane@caraveo.com>                           |
   |          Ilia Alshanetsky  <ilia@prohost.org>                        |
   +----------------------------------------------------------------------+
*/

/* $Id: php_scandir.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_SCANDIR_H
#define PHP_SCANDIR_H

#include <sys/types.h>

#ifdef HAVE_SYS_DIR_H
#include <sys/dir.h>
#endif

#ifdef PHP_WIN32
#include "config.w32.h"
#include "win32/readdir.h"
#else
#include <php_config.h>
#endif

#ifdef HAVE_DIRENT_H
#include <dirent.h>
#endif

#ifdef HAVE_SCANDIR
#define php_scandir		scandir
#else
PHPAPI int php_scandir(const char *dirname, struct dirent **namelist[], int (*selector) (const struct dirent *entry), int (*compare) (const struct dirent **a, const struct dirent **b));
#endif

#ifdef HAVE_ALPHASORT
#define php_alphasort	alphasort
#else
PHPAPI int php_alphasort(const struct dirent **a, const struct dirent **b);
#endif

#endif /* PHP_SCANDIR_H */
php/main/fastcgi.h000064400000012051151730541410010050 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 7                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2018 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Dmitry Stogov <dmitry@zend.com>                             |
   +----------------------------------------------------------------------+
*/

/* $Id$ */

/* FastCGI protocol */

#define FCGI_VERSION_1 1

#define FCGI_MAX_LENGTH 0xffff

#define FCGI_KEEP_CONN  1

/* this is near the perfect hash function for most useful FastCGI variables
 * which combines efficiency and minimal hash collisions
 */

#define FCGI_HASH_FUNC(var, var_len) \
	(UNEXPECTED(var_len < 3) ? (unsigned int)var_len : \
		(((unsigned int)var[3]) << 2) + \
		(((unsigned int)var[var_len-2]) << 4) + \
		(((unsigned int)var[var_len-1]) << 2) + \
		var_len)

#define FCGI_GETENV(request, name) \
	fcgi_quick_getenv(request, name, sizeof(name)-1, FCGI_HASH_FUNC(name, sizeof(name)-1))

#define FCGI_PUTENV(request, name, value) \
	fcgi_quick_putenv(request, name, sizeof(name)-1, FCGI_HASH_FUNC(name, sizeof(name)-1), value)

typedef enum _fcgi_role {
	FCGI_RESPONDER	= 1,
	FCGI_AUTHORIZER	= 2,
	FCGI_FILTER		= 3
} fcgi_role;

enum {
	FCGI_DEBUG		= 1,
	FCGI_NOTICE		= 2,
	FCGI_WARNING	= 3,
	FCGI_ERROR		= 4,
	FCGI_ALERT		= 5,
};

typedef enum _fcgi_request_type {
	FCGI_BEGIN_REQUEST		=  1, /* [in]                              */
	FCGI_ABORT_REQUEST		=  2, /* [in]  (not supported)             */
	FCGI_END_REQUEST		=  3, /* [out]                             */
	FCGI_PARAMS				=  4, /* [in]  environment variables       */
	FCGI_STDIN				=  5, /* [in]  post data                   */
	FCGI_STDOUT				=  6, /* [out] response                    */
	FCGI_STDERR				=  7, /* [out] errors                      */
	FCGI_DATA				=  8, /* [in]  filter data (not supported) */
	FCGI_GET_VALUES			=  9, /* [in]                              */
	FCGI_GET_VALUES_RESULT	= 10  /* [out]                             */
} fcgi_request_type;

typedef enum _fcgi_protocol_status {
	FCGI_REQUEST_COMPLETE	= 0,
	FCGI_CANT_MPX_CONN		= 1,
	FCGI_OVERLOADED			= 2,
	FCGI_UNKNOWN_ROLE		= 3
} dcgi_protocol_status;

/* FastCGI client API */

typedef void (*fcgi_apply_func)(char *var, unsigned int var_len, char *val, unsigned int val_len, void *arg);

#define FCGI_HASH_TABLE_SIZE 128
#define FCGI_HASH_TABLE_MASK (FCGI_HASH_TABLE_SIZE - 1)
#define FCGI_HASH_SEG_SIZE   4096

typedef struct _fcgi_request fcgi_request;

int fcgi_init(void);
void fcgi_shutdown(void);
int fcgi_is_fastcgi(void);
int fcgi_is_closed(fcgi_request *req);
void fcgi_close(fcgi_request *req, int force, int destroy);
int fcgi_in_shutdown(void);
void fcgi_terminate(void);
int fcgi_listen(const char *path, int backlog);
fcgi_request* fcgi_init_request(int listen_socket, void(*on_accept)(), void(*on_read)(), void(*on_close)());
void fcgi_destroy_request(fcgi_request *req);
void fcgi_set_allowed_clients(char *ip);
int fcgi_accept_request(fcgi_request *req);
int fcgi_finish_request(fcgi_request *req, int force_close);
const char *fcgi_get_last_client_ip();
void fcgi_set_in_shutdown(int new_value);
void fcgi_request_set_keep(fcgi_request *req, int new_value);

#ifndef HAVE_ATTRIBUTE_WEAK
typedef void (*fcgi_logger)(int type, const char *fmt, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
void fcgi_set_logger(fcgi_logger lg);
#endif

int   fcgi_has_env(fcgi_request *req);
char* fcgi_getenv(fcgi_request *req, const char* var, int var_len);
char* fcgi_putenv(fcgi_request *req, char* var, int var_len, char* val);
char* fcgi_quick_getenv(fcgi_request *req, const char* var, int var_len, unsigned int hash_value);
char* fcgi_quick_putenv(fcgi_request *req, char* var, int var_len, unsigned int hash_value, char* val);
void  fcgi_loadenv(fcgi_request *req, fcgi_apply_func load_func, zval *array);

int fcgi_read(fcgi_request *req, char *str, int len);

int fcgi_write(fcgi_request *req, fcgi_request_type type, const char *str, int len);
int fcgi_flush(fcgi_request *req, int end);
int fcgi_end(fcgi_request *req);

#ifdef PHP_WIN32
void fcgi_impersonate(void);
#endif

void fcgi_set_mgmt_var(const char * name, size_t name_len, const char * value, size_t value_len);
void fcgi_free_mgmt_var_cb(zval *zv);

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/main/php_version.h000064400000000412151730541420010763 0ustar00/* automatically generated by configure */
/* edit configure.in to change version number */
#define PHP_MAJOR_VERSION 5
#define PHP_MINOR_VERSION 2
#define PHP_RELEASE_VERSION 17
#define PHP_EXTRA_VERSION ""
#define PHP_VERSION "5.2.17"
#define PHP_VERSION_ID 50217
php/main/php_globals.h000064400000010350151730541420010723 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Zeev Suraski <zeev@zend.com>                                 |
   +----------------------------------------------------------------------+
*/

/* $Id: php_globals.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_GLOBALS_H
#define PHP_GLOBALS_H

#include "zend_globals.h"

typedef struct _php_core_globals php_core_globals;

#ifdef ZTS
# define PG(v) TSRMG(core_globals_id, php_core_globals *, v)
extern PHPAPI int core_globals_id;
#else
# define PG(v) (core_globals.v)
extern ZEND_API struct _php_core_globals core_globals;
#endif

/* Error display modes */
#define PHP_DISPLAY_ERRORS_STDOUT	1
#define PHP_DISPLAY_ERRORS_STDERR	2

/* Track vars */
#define TRACK_VARS_POST		0
#define TRACK_VARS_GET		1
#define TRACK_VARS_COOKIE	2
#define TRACK_VARS_SERVER	3
#define TRACK_VARS_ENV		4
#define TRACK_VARS_FILES	5
#define TRACK_VARS_REQUEST	6

struct _php_tick_function_entry;

typedef struct _arg_separators {
	char *output;
	char *input;
} arg_separators;

struct _php_core_globals {
	zend_bool magic_quotes_gpc;
	zend_bool magic_quotes_runtime;
	zend_bool magic_quotes_sybase;

	zend_bool safe_mode;

	zend_bool allow_call_time_pass_reference;
	zend_bool implicit_flush;

	long output_buffering;

	char *safe_mode_include_dir;
	zend_bool safe_mode_gid;
	zend_bool sql_safe_mode;
	zend_bool enable_dl;

	char *output_handler;

	char *unserialize_callback_func;
	long serialize_precision;

	char *safe_mode_exec_dir;

	long memory_limit;
	long max_input_time;

	zend_bool track_errors;
	zend_bool display_errors;
	zend_bool display_startup_errors;
	zend_bool log_errors;
	long      log_errors_max_len;
	zend_bool ignore_repeated_errors;
	zend_bool ignore_repeated_source;
	zend_bool report_memleaks;
	char *error_log;

	char *doc_root;
	char *user_dir;
	char *include_path;
	char *open_basedir;
	char *extension_dir;

	char *upload_tmp_dir;
	long upload_max_filesize;
	
	char *error_append_string;
	char *error_prepend_string;

	char *auto_prepend_file;
	char *auto_append_file;

	arg_separators arg_separator;

	char *variables_order;

	HashTable rfc1867_protected_variables;

	short connection_status;
	short ignore_user_abort;

	unsigned char header_is_being_sent;

	zend_llist tick_functions;

	zval *http_globals[6];

	zend_bool expose_php;

	zend_bool register_globals;
	zend_bool register_long_arrays;
	zend_bool register_argc_argv;
	zend_bool auto_globals_jit;

	zend_bool y2k_compliance;

	char *docref_root;
	char *docref_ext;

	zend_bool html_errors;
	zend_bool xmlrpc_errors;

	long xmlrpc_error_number;

	zend_bool activated_auto_globals[8];

	zend_bool modules_activated;
	zend_bool file_uploads;
	zend_bool during_request_startup;
	zend_bool allow_url_fopen;
	zend_bool always_populate_raw_post_data;
	zend_bool report_zend_debug;

	int last_error_type;
	char *last_error_message;
	char *last_error_file;
	int  last_error_lineno;
	error_handling_t  error_handling;
	zend_class_entry *exception_class;

	char *disable_functions;
	char *disable_classes;
	zend_bool allow_url_include;
#ifdef PHP_WIN32
	zend_bool com_initialized;
#endif
	long max_input_nesting_level;
	long max_input_vars;
	zend_bool in_user_include;
        zend_bool mail_x_header;
        char *mail_log;

	zend_bool in_error_log;
};


#endif /* PHP_GLOBALS_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 */
php/main/php_open_temporary_file.h000064400000003421151730541420013343 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Zeev Suraski <zeev@zend.com>                                 |
   +----------------------------------------------------------------------+
*/

/* $Id: php_open_temporary_file.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_OPEN_TEMPORARY_FILE_H
#define PHP_OPEN_TEMPORARY_FILE_H

BEGIN_EXTERN_C()
PHPAPI FILE *php_open_temporary_file(const char *dir, const char *pfx, char **opened_path_p TSRMLS_DC);
PHPAPI int php_open_temporary_fd_ex(const char *dir, const char *pfx, char **opened_path_p, zend_bool open_basedir_check TSRMLS_DC);
PHPAPI int php_open_temporary_fd(const char *dir, const char *pfx, char **opened_path_p TSRMLS_DC);
PHPAPI const char *php_get_temporary_directory(void);
PHPAPI void php_shutdown_temporary_directory(void);
END_EXTERN_C()

#endif /* PHP_OPEN_TEMPORARY_FILE_H */
php/main/php_ini.h000064400000006214151730541430010064 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Zeev Suraski <zeev@zend.com>                                 |
   +----------------------------------------------------------------------+
*/

/* $Id: php_ini.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_INI_H
#define PHP_INI_H

#include "zend_ini.h"

BEGIN_EXTERN_C()
int php_init_config(TSRMLS_D);
int php_shutdown_config(void);
void php_ini_register_extensions(TSRMLS_D);
PHPAPI zval *cfg_get_entry(char *name, uint name_length);
PHPAPI int cfg_get_long(char *varname, long *result);
PHPAPI int cfg_get_double(char *varname, double *result);
PHPAPI int cfg_get_string(char *varname, char **result);
END_EXTERN_C()

#define PHP_INI_USER	ZEND_INI_USER
#define PHP_INI_PERDIR	ZEND_INI_PERDIR
#define PHP_INI_SYSTEM	ZEND_INI_SYSTEM

#define PHP_INI_ALL 	ZEND_INI_ALL

#define php_ini_entry	zend_ini_entry

#define PHP_INI_MH		ZEND_INI_MH
#define PHP_INI_DISP	ZEND_INI_DISP

#define PHP_INI_BEGIN		ZEND_INI_BEGIN
#define PHP_INI_END			ZEND_INI_END

#define PHP_INI_ENTRY3_EX	ZEND_INI_ENTRY3_EX
#define PHP_INI_ENTRY3		ZEND_INI_ENTRY3
#define PHP_INI_ENTRY2_EX	ZEND_INI_ENTRY2_EX
#define PHP_INI_ENTRY2		ZEND_INI_ENTRY2
#define PHP_INI_ENTRY1_EX	ZEND_INI_ENTRY1_EX
#define PHP_INI_ENTRY1		ZEND_INI_ENTRY1
#define PHP_INI_ENTRY_EX	ZEND_INI_ENTRY_EX
#define PHP_INI_ENTRY		ZEND_INI_ENTRY

#define STD_PHP_INI_ENTRY		STD_ZEND_INI_ENTRY
#define STD_PHP_INI_ENTRY_EX	STD_ZEND_INI_ENTRY_EX
#define STD_PHP_INI_BOOLEAN		STD_ZEND_INI_BOOLEAN

#define PHP_INI_DISPLAY_ORIG	ZEND_INI_DISPLAY_ORIG
#define PHP_INI_DISPLAY_ACTIVE	ZEND_INI_DISPLAY_ACTIVE

#define PHP_INI_STAGE_STARTUP		ZEND_INI_STAGE_STARTUP
#define PHP_INI_STAGE_SHUTDOWN		ZEND_INI_STAGE_SHUTDOWN
#define PHP_INI_STAGE_ACTIVATE		ZEND_INI_STAGE_ACTIVATE
#define PHP_INI_STAGE_DEACTIVATE	ZEND_INI_STAGE_DEACTIVATE
#define PHP_INI_STAGE_RUNTIME		ZEND_INI_STAGE_RUNTIME
#define PHP_INI_STAGE_HTACCESS		ZEND_INI_STAGE_HTACCESS

#define php_ini_boolean_displayer_cb	zend_ini_boolean_displayer_cb
#define php_ini_color_displayer_cb		zend_ini_color_displayer_cb

#define php_alter_ini_entry		zend_alter_ini_entry

#define php_ini_long	zend_ini_long
#define php_ini_double	zend_ini_double
#define php_ini_string	zend_ini_string

#endif /* PHP_INI_H */
php/main/php_variables.h000064400000004064151730541430011256 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca>                       |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: php_variables.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_VARIABLES_H
#define PHP_VARIABLES_H

#include "php.h"
#include "SAPI.h"

#define PARSE_POST 0
#define PARSE_GET 1
#define PARSE_COOKIE 2
#define PARSE_STRING 3
#define PARSE_ENV 4
#define PARSE_SERVER 5
#define PARSE_SESSION 6

BEGIN_EXTERN_C()
void php_startup_auto_globals(TSRMLS_D);
extern PHPAPI void (*php_import_environment_variables)(zval *array_ptr TSRMLS_DC);
PHPAPI void php_register_variable(char *var, char *val, zval *track_vars_array TSRMLS_DC);
/* binary-safe version */
PHPAPI void php_register_variable_safe(char *var, char *val, int val_len, zval *track_vars_array TSRMLS_DC);
PHPAPI void php_register_variable_ex(char *var, zval *val, zval *track_vars_array TSRMLS_DC);

int php_hash_environment(TSRMLS_D);
END_EXTERN_C()

#define NUM_TRACK_VARS	6

#endif /* PHP_VARIABLES_H */
php/main/php_stdint.h000064400000012323151730541430010610 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 7                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2018 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Michael Wallner <mike@php.net>                               |
   +----------------------------------------------------------------------+
*/

#ifndef PHP_STDINT_H
#define PHP_STDINT_H

/* C99 requires these for C++ to get the definitions
 * of INT64_MAX and other macros used by Zend/zend_long.h
 * C11 drops this requirement, so these effectively
 * just backport that piece of behavior.
 *
 * These defines are placed here instead of
 * with the include below, because sys/types
 * and inttypes may include stdint themselves.
 * And these definitions MUST come first.
 */
#ifdef __cplusplus
# ifndef __STDC_LIMIT_MACROS
#  define __STDC_LIMIT_MACROS
# endif
# ifndef __STDC_CONSTANT_MACROS
#  define __STDC_CONSTANT_MACROS
# endif
#endif

#if defined(_MSC_VER)
/* Make sure the regular stdint.h wasn't included already and prevent it to be
   included afterwards. Though if some other library needs some stuff from
   stdint.h included afterwards and misses it, we'd have to extend ours. On
   the other hand, if stdint.h was included before, some conflicts might
   happen so we'd likewise have to fix ours. */
# if !defined(_STDINT)
#  define _STDINT
#  include "win32/php_stdint.h"
#  include "win32/php_inttypes.h"
# endif
# define HAVE_INT8_T   1
# define HAVE_UINT8_T  1
# define HAVE_INT16_T  1
# define HAVE_UINT16_T 1
# define HAVE_INT32_T  1
# define HAVE_UINT32_T 1
# define HAVE_INT64_T  1
# define HAVE_UINT64_T 1
#else

#include "php_config.h"

#if HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif

#if HAVE_INTTYPES_H
# include <inttypes.h>
#endif

#if HAVE_STDINT_H
# include <stdint.h>
#endif

#ifndef HAVE_INT8_T
# ifdef HAVE_INT8
typedef int8 int8_t;
# else
typedef signed char int8_t;
# endif
#endif

#ifndef INT8_C
# define INT8_C(c) c
#endif

#ifndef HAVE_UINT8_T
# ifdef HAVE_UINT8
typedef uint8 uint8_t
# elif HAVE_U_INT8_T
typedef u_int8_t uint8_t;
# else
typedef unsigned char uint8_t;
# endif
#endif

#ifndef UINT8_C
# define UINT8_C(c) c
#endif

#ifndef HAVE_INT16_T
# ifdef HAVE_INT16
typedef int16 int16_t;
# elif SIZEOF_SHORT >= 2
typedef signed short int16_t;
# else
#  error "No suitable 16bit integer type found"
# endif
#endif

#ifndef INT16_C
# define INT16_C(c) c
#endif

#ifndef HAVE_UINT16_T
# ifdef HAVE_UINT16
typedef uint16 uint16_t
# elif HAVE_U_INT16_T
typedef u_int16_t uint16_t;
# elif SIZEOF_SHORT >= 2
typedef unsigned short uint16_t;
# else
#  error "No suitable 16bit integer type found"
# endif
#endif

#ifndef UINT16_C
# define UINT16_C(c) c
#endif

#ifndef HAVE_INT32_T
# ifdef HAVE_INT32
typedef int32 int32_t;
# elif SIZEOF_INT >= 4
typedef int int32_t;
# elif SIZEOF_LONG >= 4
typedef long int32_t;
# else
#  error "No suitable 32bit integer type found"
# endif
#endif

#ifndef INT32_C
# define INT32_C(c) c
#endif

#ifndef HAVE_UINT32_T
# ifdef HAVE_UINT32
typedef uint32 uint32_t
# elif HAVE_U_INT32_T
typedef u_int32_t uint32_t;
# elif SIZEOF_INT >= 4
typedef unsigned int uint32_t;
# elif SIZEOF_LONG >= 4
typedef unsigned long uint32_t;
# else
#  error "No suitable 32bit integer type found"
# endif
#endif

#ifndef UINT32_C
# define UINT32_C(c) c ## U
#endif

#ifndef HAVE_INT64_T
# ifdef HAVE_INT64
typedef int64 int64_t;
# elif SIZEOF_INT >= 8
typedef int int64_t;
# elif SIZEOF_LONG >= 8
typedef long int64_t;
# elif SIZEOF_LONG_LONG >= 8
typedef long long int64_t;
# else
#  error "No suitable 64bit integer type found"
# endif
#endif

#ifndef INT64_C
# if SIZEOF_INT >= 8
#  define INT64_C(c) c
# elif SIZEOF_LONG >= 8
#  define INT64_C(c) c ## L
# elif SIZEOF_LONG_LONG >= 8
#  define INT64_C(c) c ## LL
# endif
#endif

#ifndef HAVE_UINT64_T
# ifdef HAVE_UINT64
typedef uint64 uint64_t
# elif HAVE_U_INT64_T
typedef u_int64_t uint64_t;
# elif SIZEOF_INT >= 8
typedef unsigned int uint64_t;
# elif SIZEOF_LONG >= 8
typedef unsigned long uint64_t;
# elif SIZEOF_LONG_LONG >= 8
typedef unsigned long long uint64_t;
# else
#  error "No suitable 64bit integer type found"
# endif
#endif

#ifndef UINT64_C
# if SIZEOF_INT >= 8
#  define UINT64_C(c) c ## U
# elif SIZEOF_LONG >= 8
#  define UINT64_C(c) c ## UL
# elif SIZEOF_LONG_LONG >= 8
#  define UINT64_C(c) c ## ULL
# endif
#endif

#endif /* !PHP_WIN32 */
#endif /* PHP_STDINT_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/main/php_network.h000064400000022722151730541440011001 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Stig Venaas <venaas@uninett.no>                              |
   +----------------------------------------------------------------------+
 */

/* $Id: php_network.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef _PHP_NETWORK_H
#define _PHP_NETWORK_H

#ifdef PHP_WIN32
# ifndef WINNT
#  define WINNT 1
# endif
# undef FD_SETSIZE
# include "arpa/inet.h"
  /* Apache folks decided that strtoul was evil and redefined
   * it to something that breaks the windows headers */
# undef strtoul
/* defines socklen_t and some IPV6 stuff */
# include <ws2tcpip.h>
# if HAVE_WSPIAPI_H
   /* getaddrinfo */
#  include <wspiapi.h>
# endif
#else
# undef closesocket
# define closesocket close
#endif

#ifndef HAVE_SHUTDOWN
#undef shutdown
#define shutdown(s,n)	/* nothing */
#endif

#ifdef PHP_WIN32
#define EWOULDBLOCK WSAEWOULDBLOCK
#define EINPROGRESS	WSAEWOULDBLOCK
#	define fsync _commit
#	define ftruncate(a, b) chsize(a, b)
#endif /* defined(PHP_WIN32) */

#ifndef EWOULDBLOCK
# define EWOULDBLOCK EAGAIN
#endif

#ifdef PHP_WIN32
#define php_socket_errno() WSAGetLastError()
#else
#define php_socket_errno() errno
#endif

/* like strerror, but caller must efree the returned string,
 * unless buf is not NULL.
 * Also works sensibly for win32 */
BEGIN_EXTERN_C()
PHPAPI char *php_socket_strerror(long err, char *buf, size_t bufsize);
END_EXTERN_C()

#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif

#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif

/* These are here, rather than with the win32 counterparts above,
 * since <sys/socket.h> defines them. */
#ifndef SHUT_RD
# define SHUT_RD 0
# define SHUT_WR 1
# define SHUT_RDWR 2
#endif

#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif

#ifdef HAVE_STDDEF_H
#include <stddef.h>
#endif

#ifdef PHP_WIN32
typedef SOCKET php_socket_t;
#else
typedef int php_socket_t;
#endif

#ifdef PHP_WIN32
# define SOCK_ERR INVALID_SOCKET
# define SOCK_CONN_ERR SOCKET_ERROR
# define SOCK_RECV_ERR SOCKET_ERROR
#else
# define SOCK_ERR -1
# define SOCK_CONN_ERR -1
# define SOCK_RECV_ERR -1
#endif

/* uncomment this to debug poll(2) emulation on systems that have poll(2) */
/* #define PHP_USE_POLL_2_EMULATION 1 */

#if defined(HAVE_SYS_POLL_H) && defined(HAVE_POLL)
# include <sys/poll.h>
typedef struct pollfd php_pollfd;
#else
typedef struct _php_pollfd {
	php_socket_t fd;
	short events;
	short revents;
} php_pollfd;

PHPAPI int php_poll2(php_pollfd *ufds, unsigned int nfds, int timeout);

# define POLLIN      0x0001    /* There is data to read */
# define POLLPRI     0x0002    /* There is urgent data to read */
# define POLLOUT     0x0004    /* Writing now will not block */
# define POLLERR     0x0008    /* Error condition */
# define POLLHUP     0x0010    /* Hung up */
# define POLLNVAL    0x0020    /* Invalid request: fd not open */

# ifndef PHP_USE_POLL_2_EMULATION
#  define PHP_USE_POLL_2_EMULATION 1
# endif
#endif

#define PHP_POLLREADABLE	(POLLIN|POLLERR|POLLHUP)

#ifndef PHP_USE_POLL_2_EMULATION
# define php_poll2(ufds, nfds, timeout)		poll(ufds, nfds, timeout)
#endif

/* timeval-to-timeout (for poll(2)) */
static inline int php_tvtoto(struct timeval *timeouttv)
{
	if (timeouttv) {
		return (timeouttv->tv_sec * 1000) + (timeouttv->tv_usec / 1000);
	}
	return -1;
}

/* hybrid select(2)/poll(2) for a single descriptor.
 * timeouttv follows same rules as select(2), but is reduced to millisecond accuracy.
 * Returns 0 on timeout, -1 on error, or the event mask (ala poll(2)).
 */
static inline int php_pollfd_for(php_socket_t fd, int events, struct timeval *timeouttv)
{
	php_pollfd p;
	int n;

	p.fd = fd;
	p.events = events;
	p.revents = 0;

	n = php_poll2(&p, 1, php_tvtoto(timeouttv));

	if (n > 0) {
		return p.revents;
	}

	return n;
}

static inline int php_pollfd_for_ms(php_socket_t fd, int events, int timeout)
{
	php_pollfd p;
	int n;

	p.fd = fd;
	p.events = events;
	p.revents = 0;

	n = php_poll2(&p, 1, timeout);

	if (n > 0) {
		return p.revents;
	}

	return n;
}

/* emit warning and suggestion for unsafe select(2) usage */
PHPAPI void _php_emit_fd_setsize_warning(int max_fd);

#ifdef PHP_WIN32
/* it is safe to FD_SET too many fd's under win32; the macro will simply ignore
 * descriptors that go beyond the default FD_SETSIZE */
# define PHP_SAFE_FD_SET(fd, set)	FD_SET(fd, set)
# define PHP_SAFE_FD_ISSET(fd, set)	FD_ISSET(fd, set)
# define PHP_SAFE_MAX_FD(m, n)		do { if (n + 1 >= FD_SETSIZE) { _php_emit_fd_setsize_warning(n); }} while(0)
#else
# define PHP_SAFE_FD_SET(fd, set)	do { if (fd < FD_SETSIZE) FD_SET(fd, set); } while(0)
# define PHP_SAFE_FD_ISSET(fd, set)	((fd < FD_SETSIZE) && FD_ISSET(fd, set))
# define PHP_SAFE_MAX_FD(m, n)		do { if (m >= FD_SETSIZE) { _php_emit_fd_setsize_warning(m); m = FD_SETSIZE - 1; }} while(0)
#endif


#define PHP_SOCK_CHUNK_SIZE	8192

#ifdef HAVE_SOCKADDR_STORAGE
typedef struct sockaddr_storage php_sockaddr_storage;
#else
typedef struct {
#ifdef HAVE_SOCKADDR_SA_LEN
		unsigned char ss_len;
		unsigned char ss_family;
#else
        unsigned short ss_family;
#endif
        char info[126];
} php_sockaddr_storage;
#endif

BEGIN_EXTERN_C()
PHPAPI php_socket_t php_network_connect_socket_to_host(const char *host, unsigned short port,
		int socktype, int asynchronous, struct timeval *timeout, char **error_string,
		int *error_code, char *bindto, unsigned short bindport 
		TSRMLS_DC);

PHPAPI int php_network_connect_socket(php_socket_t sockfd,
		const struct sockaddr *addr,
		socklen_t addrlen,
		int asynchronous,
		struct timeval *timeout,
		char **error_string,
		int *error_code);

#define php_connect_nonb(sock, addr, addrlen, timeout) \
	php_network_connect_socket((sock), (addr), (addrlen), 0, (timeout), NULL, NULL)

PHPAPI php_socket_t php_network_bind_socket_to_local_addr(const char *host, unsigned port,
		int socktype, char **error_string, int *error_code
		TSRMLS_DC);

PHPAPI php_socket_t php_network_accept_incoming(php_socket_t srvsock,
		char **textaddr, long *textaddrlen,
		struct sockaddr **addr,
		socklen_t *addrlen,
		struct timeval *timeout,
		char **error_string,
		int *error_code
		TSRMLS_DC);

PHPAPI int php_network_get_sock_name(php_socket_t sock, 
		char **textaddr, long *textaddrlen,
		struct sockaddr **addr,
		socklen_t *addrlen
		TSRMLS_DC);
	
PHPAPI int php_network_get_peer_name(php_socket_t sock, 
		char **textaddr, long *textaddrlen,
		struct sockaddr **addr,
		socklen_t *addrlen
		TSRMLS_DC);

PHPAPI void php_any_addr(int family, php_sockaddr_storage *addr, unsigned short port);
PHPAPI int php_sockaddr_size(php_sockaddr_storage *addr);
END_EXTERN_C()

struct _php_netstream_data_t	{
	php_socket_t socket;
	char is_blocked;
	struct timeval timeout;
	char timeout_event;
	size_t ownsize;
};
typedef struct _php_netstream_data_t php_netstream_data_t;
PHPAPI extern php_stream_ops php_stream_socket_ops;
extern php_stream_ops php_stream_generic_socket_ops;
#define PHP_STREAM_IS_SOCKET	(&php_stream_socket_ops)

BEGIN_EXTERN_C()
PHPAPI php_stream *_php_stream_sock_open_from_socket(php_socket_t socket, const char *persistent_id STREAMS_DC TSRMLS_DC );
/* open a connection to a host using php_hostconnect and return a stream */
PHPAPI php_stream *_php_stream_sock_open_host(const char *host, unsigned short port,
		int socktype, struct timeval *timeout, const char *persistent_id STREAMS_DC TSRMLS_DC);
PHPAPI void php_network_populate_name_from_sockaddr(
		/* input address */
		struct sockaddr *sa, socklen_t sl,
		/* output readable address */
		char **textaddr, long *textaddrlen,
		/* output address */
		struct sockaddr **addr,
		socklen_t *addrlen
		TSRMLS_DC);

PHPAPI int php_network_parse_network_address_with_port(const char *addr,
		long addrlen, struct sockaddr *sa, socklen_t *sl TSRMLS_DC);
END_EXTERN_C()

#define php_stream_sock_open_from_socket(socket, persistent)	_php_stream_sock_open_from_socket((socket), (persistent) STREAMS_CC TSRMLS_CC)
#define php_stream_sock_open_host(host, port, socktype, timeout, persistent)	_php_stream_sock_open_host((host), (port), (socktype), (timeout), (persistent) STREAMS_CC TSRMLS_CC)

/* {{{ memory debug */
#define php_stream_sock_open_from_socket_rel(socket, persistent)	_php_stream_sock_open_from_socket((socket), (persistent) STREAMS_REL_CC TSRMLS_CC)
#define php_stream_sock_open_host_rel(host, port, socktype, timeout, persistent)	_php_stream_sock_open_host((host), (port), (socktype), (timeout), (persistent) STREAMS_REL_CC TSRMLS_CC)
#define php_stream_sock_open_unix_rel(path, pathlen, persistent, timeval)	_php_stream_sock_open_unix((path), (pathlen), (persistent), (timeval) STREAMS_REL_CC TSRMLS_CC)

/* }}} */

#endif /* _PHP_NETWORK_H */

/*
 * Local variables:
 * tab-width: 8
 * c-basic-offset: 8
 * End:
 */
php/main/php_streams.h000064400000067136151730541440010776 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Wez Furlong (wez@thebrainroom.com)                           |
   +----------------------------------------------------------------------+
 */

/* $Id: php_streams.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_STREAMS_H
#define PHP_STREAMS_H

#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>

BEGIN_EXTERN_C()
PHPAPI int php_file_le_stream(void);
PHPAPI int php_file_le_pstream(void);
PHPAPI int php_file_le_stream_filter(void);
END_EXTERN_C()

/* {{{ Streams memory debugging stuff */

#if ZEND_DEBUG
/* these have more of a dependency on the definitions of the zend macros than
 * I would prefer, but doing it this way saves loads of idefs :-/ */
# define STREAMS_D			int __php_stream_call_depth ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC 
# define STREAMS_C			0 ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC 
# define STREAMS_REL_C		__php_stream_call_depth + 1 ZEND_FILE_LINE_CC, \
	__php_stream_call_depth ? __zend_orig_filename : __zend_filename, \
	__php_stream_call_depth ? __zend_orig_lineno : __zend_lineno 

# define STREAMS_DC		, STREAMS_D
# define STREAMS_CC		, STREAMS_C
# define STREAMS_REL_CC	, STREAMS_REL_C

#else
# define STREAMS_D
# define STREAMS_C
# define STREAMS_REL_C
# define STREAMS_DC
# define STREAMS_CC
# define STREAMS_REL_CC
#endif

/* these functions relay the file/line number information. They are depth aware, so they will pass
 * the ultimate ancestor, which is useful, because there can be several layers of calls */
#define php_stream_alloc_rel(ops, thisptr, persistent, mode) _php_stream_alloc((ops), (thisptr), (persistent), (mode) STREAMS_REL_CC TSRMLS_CC)

#define php_stream_copy_to_mem_rel(src, buf, maxlen, persistent) _php_stream_copy_to_mem((src), (buf), (maxlen), (persistent) STREAMS_REL_CC TSRMLS_CC)
	
#define php_stream_fopen_rel(filename, mode, opened, options) _php_stream_fopen((filename), (mode), (opened), (options) STREAMS_REL_CC TSRMLS_CC)

#define php_stream_fopen_with_path_rel(filename, mode, path, opened, options) _php_stream_fopen_with_path((filename), (mode), (path), (opened), (options) STREAMS_REL_CC TSRMLS_CC)

#define php_stream_fopen_from_fd_rel(fd, mode, persistent_id)	 _php_stream_fopen_from_fd((fd), (mode), (persistent_id) STREAMS_REL_CC TSRMLS_CC)
#define php_stream_fopen_from_file_rel(file, mode)	 _php_stream_fopen_from_file((file), (mode) STREAMS_REL_CC TSRMLS_CC)
	
#define php_stream_fopen_from_pipe_rel(file, mode)	 _php_stream_fopen_from_pipe((file), (mode) STREAMS_REL_CC TSRMLS_CC)
	
#define php_stream_fopen_tmpfile_rel()	_php_stream_fopen_tmpfile(0 STREAMS_REL_CC TSRMLS_CC)

#define php_stream_fopen_temporary_file_rel(dir, pfx, opened_path)	_php_stream_fopen_temporary_file((dir), (pfx), (opened_path) STREAMS_REL_CC TSRMLS_CC)
	
#define php_stream_open_wrapper_rel(path, mode, options, opened) _php_stream_open_wrapper_ex((path), (mode), (options), (opened), NULL STREAMS_REL_CC TSRMLS_CC)
#define php_stream_open_wrapper_ex_rel(path, mode, options, opened, context) _php_stream_open_wrapper_ex((path), (mode), (options), (opened), (context) STREAMS_REL_CC TSRMLS_CC)

#define php_stream_make_seekable_rel(origstream, newstream, flags) _php_stream_make_seekable((origstream), (newstream), (flags) STREAMS_REL_CC TSRMLS_CC)

/* }}} */
	
/* The contents of the php_stream_ops and php_stream should only be accessed
 * using the functions/macros in this header.
 * If you need to get at something that doesn't have an API,
 * drop me a line <wez@thebrainroom.com> and we can sort out a way to do
 * it properly.
 * 
 * The only exceptions to this rule are that stream implementations can use
 * the php_stream->abstract pointer to hold their context, and streams
 * opened via stream_open_wrappers can use the zval ptr in
 * php_stream->wrapperdata to hold meta data for php scripts to
 * retrieve using file_get_wrapper_data(). */

typedef struct _php_stream php_stream;
typedef struct _php_stream_wrapper php_stream_wrapper;
typedef struct _php_stream_context php_stream_context;
typedef struct _php_stream_filter php_stream_filter;

#include "streams/php_stream_context.h"
#include "streams/php_stream_filter_api.h"

typedef struct _php_stream_statbuf {
	struct stat sb; /* regular info */
	/* extended info to go here some day: content-type etc. etc. */
} php_stream_statbuf;

typedef struct _php_stream_dirent {
	char d_name[MAXPATHLEN];
} php_stream_dirent;

/* operations on streams that are file-handles */
typedef struct _php_stream_ops  {
	/* stdio like functions - these are mandatory! */
	size_t (*write)(php_stream *stream, const char *buf, size_t count TSRMLS_DC);
	size_t (*read)(php_stream *stream, char *buf, size_t count TSRMLS_DC);
	int    (*close)(php_stream *stream, int close_handle TSRMLS_DC);
	int    (*flush)(php_stream *stream TSRMLS_DC);
	
	const char *label; /* label for this ops structure */
	
	/* these are optional */
	int (*seek)(php_stream *stream, off_t offset, int whence, off_t *newoffset TSRMLS_DC);
	int (*cast)(php_stream *stream, int castas, void **ret TSRMLS_DC);
	int (*stat)(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC);
	int (*set_option)(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC);
} php_stream_ops;

typedef struct _php_stream_wrapper_ops {
	/* open/create a wrapped stream */
	php_stream *(*stream_opener)(php_stream_wrapper *wrapper, char *filename, char *mode,
			int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC);
	/* close/destroy a wrapped stream */
	int (*stream_closer)(php_stream_wrapper *wrapper, php_stream *stream TSRMLS_DC);
	/* stat a wrapped stream */
	int (*stream_stat)(php_stream_wrapper *wrapper, php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC);
	/* stat a URL */
	int (*url_stat)(php_stream_wrapper *wrapper, char *url, int flags, php_stream_statbuf *ssb, php_stream_context *context TSRMLS_DC);
	/* open a "directory" stream */
	php_stream *(*dir_opener)(php_stream_wrapper *wrapper, char *filename, char *mode,
			int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC);
	
	const char *label;

	/* delete a file */
	int (*unlink)(php_stream_wrapper *wrapper, char *url, int options, php_stream_context *context TSRMLS_DC);

	/* rename a file */
	int (*rename)(php_stream_wrapper *wrapper, char *url_from, char *url_to, int options, php_stream_context *context TSRMLS_DC);

	/* Create/Remove directory */
	int (*stream_mkdir)(php_stream_wrapper *wrapper, char *url, int mode, int options, php_stream_context *context TSRMLS_DC);
	int (*stream_rmdir)(php_stream_wrapper *wrapper, char *url, int options, php_stream_context *context TSRMLS_DC);
} php_stream_wrapper_ops;

struct _php_stream_wrapper	{
	php_stream_wrapper_ops *wops;	/* operations the wrapper can perform */
	void *abstract;					/* context for the wrapper */
	int is_url;						/* so that PG(allow_url_fopen) can be respected */

	/* support for wrappers to return (multiple) error messages to the stream opener */
	int err_count;
	char **err_stack;
};

#define PHP_STREAM_FLAG_NO_SEEK						1
#define PHP_STREAM_FLAG_NO_BUFFER					2

#define PHP_STREAM_FLAG_EOL_UNIX					0 /* also includes DOS */
#define PHP_STREAM_FLAG_DETECT_EOL					4
#define PHP_STREAM_FLAG_EOL_MAC						8

/* set this when the stream might represent "interactive" data.
 * When set, the read buffer will avoid certain operations that
 * might otherwise cause the read to block for much longer than
 * is strictly required. */
#define PHP_STREAM_FLAG_AVOID_BLOCKING				16

#define PHP_STREAM_FLAG_NO_CLOSE					32
	
#define PHP_STREAM_FLAG_IS_DIR						64

#define PHP_STREAM_FLAG_NO_FCLOSE					128

struct _php_stream  {
	php_stream_ops *ops;
	void *abstract;  		/* convenience pointer for abstraction */

	php_stream_filter_chain readfilters, writefilters;

	php_stream_wrapper *wrapper; /* which wrapper was used to open the stream */
	void *wrapperthis;		/* convenience pointer for a instance of a wrapper */
	zval *wrapperdata;		/* fgetwrapperdata retrieves this */

	int fgetss_state;		/* for fgetss to handle multiline tags */
	int is_persistent;
	char mode[16];			/* "rwb" etc. ala stdio */
	int rsrc_id;			/* used for auto-cleanup */
	int in_free;			/* to prevent recursion during free */
	/* so we know how to clean it up correctly.  This should be set to
	 * PHP_STREAM_FCLOSE_XXX as appropriate */
	int fclose_stdiocast;
	FILE *stdiocast;    /* cache this, otherwise we might leak! */
#if ZEND_DEBUG
	int __exposed;	/* non-zero if exposed as a zval somewhere */
#endif
	char *orig_path;

	php_stream_context *context;
	int flags;	/* PHP_STREAM_FLAG_XXX */

	/* buffer */
	off_t position; /* of underlying stream */
	unsigned char *readbuf;
	size_t readbuflen;
	off_t readpos;
	off_t writepos;
	
	/* how much data to read when filling buffer */
	size_t chunk_size;

	int eof;

}; /* php_stream */
/* state definitions when closing down; these are private to streams.c */
#define PHP_STREAM_FCLOSE_NONE 0
#define PHP_STREAM_FCLOSE_FDOPEN	1
#define PHP_STREAM_FCLOSE_FOPENCOOKIE 2

/* allocate a new stream for a particular ops */
BEGIN_EXTERN_C()
PHPAPI php_stream *_php_stream_alloc(php_stream_ops *ops, void *abstract,
		const char *persistent_id, const char *mode STREAMS_DC TSRMLS_DC);
END_EXTERN_C()
#define php_stream_alloc(ops, thisptr, persistent_id, mode)	_php_stream_alloc((ops), (thisptr), (persistent_id), (mode) STREAMS_CC TSRMLS_CC)


#define php_stream_get_resource_id(stream)		(stream)->rsrc_id
#if ZEND_DEBUG
/* use this to tell the stream that it is OK if we don't explicitly close it */
# define php_stream_auto_cleanup(stream)	{ (stream)->__exposed++; }
/* use this to assign the stream to a zval and tell the stream that is
 * has been exported to the engine; it will expect to be closed automatically
 * when the resources are auto-destructed */
# define php_stream_to_zval(stream, zval)	{ ZVAL_RESOURCE(zval, (stream)->rsrc_id); (stream)->__exposed++; }
#else
# define php_stream_auto_cleanup(stream)	/* nothing */
# define php_stream_to_zval(stream, zval)	{ ZVAL_RESOURCE(zval, (stream)->rsrc_id); }
#endif

#define php_stream_from_zval(xstr, ppzval)	ZEND_FETCH_RESOURCE2((xstr), php_stream *, (ppzval), -1, "stream", php_file_le_stream(), php_file_le_pstream())
#define php_stream_from_zval_no_verify(xstr, ppzval)	(xstr) = (php_stream*)zend_fetch_resource((ppzval) TSRMLS_CC, -1, "stream", NULL, 2, php_file_le_stream(), php_file_le_pstream())

BEGIN_EXTERN_C()
PHPAPI int php_stream_from_persistent_id(const char *persistent_id, php_stream **stream TSRMLS_DC);
#define PHP_STREAM_PERSISTENT_SUCCESS	0 /* id exists */
#define PHP_STREAM_PERSISTENT_FAILURE	1 /* id exists but is not a stream! */
#define PHP_STREAM_PERSISTENT_NOT_EXIST	2 /* id does not exist */

#define PHP_STREAM_FREE_CALL_DTOR			1 /* call ops->close */
#define PHP_STREAM_FREE_RELEASE_STREAM		2 /* pefree(stream) */
#define PHP_STREAM_FREE_PRESERVE_HANDLE		4 /* tell ops->close to not close it's underlying handle */
#define PHP_STREAM_FREE_RSRC_DTOR			8 /* called from the resource list dtor */
#define PHP_STREAM_FREE_PERSISTENT			16 /* manually freeing a persistent connection */
#define PHP_STREAM_FREE_CLOSE				(PHP_STREAM_FREE_CALL_DTOR | PHP_STREAM_FREE_RELEASE_STREAM)
#define PHP_STREAM_FREE_CLOSE_CASTED		(PHP_STREAM_FREE_CLOSE | PHP_STREAM_FREE_PRESERVE_HANDLE)
#define PHP_STREAM_FREE_CLOSE_PERSISTENT	(PHP_STREAM_FREE_CLOSE | PHP_STREAM_FREE_PERSISTENT)

PHPAPI int _php_stream_free(php_stream *stream, int close_options TSRMLS_DC);
#define php_stream_free(stream, close_options)	_php_stream_free((stream), (close_options) TSRMLS_CC)
#define php_stream_close(stream)	_php_stream_free((stream), PHP_STREAM_FREE_CLOSE TSRMLS_CC)
#define php_stream_pclose(stream)	_php_stream_free((stream), PHP_STREAM_FREE_CLOSE_PERSISTENT TSRMLS_CC)

PHPAPI int _php_stream_seek(php_stream *stream, off_t offset, int whence TSRMLS_DC);
#define php_stream_rewind(stream)	_php_stream_seek((stream), 0L, SEEK_SET TSRMLS_CC)
#define php_stream_seek(stream, offset, whence)	_php_stream_seek((stream), (offset), (whence) TSRMLS_CC)

PHPAPI off_t _php_stream_tell(php_stream *stream TSRMLS_DC);
#define php_stream_tell(stream)	_php_stream_tell((stream) TSRMLS_CC)

PHPAPI size_t _php_stream_read(php_stream *stream, char *buf, size_t count TSRMLS_DC);
#define php_stream_read(stream, buf, count)		_php_stream_read((stream), (buf), (count) TSRMLS_CC)

PHPAPI size_t _php_stream_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC);
#define php_stream_write_string(stream, str)	_php_stream_write(stream, str, strlen(str) TSRMLS_CC)
#define php_stream_write(stream, buf, count)	_php_stream_write(stream, (buf), (count) TSRMLS_CC)

PHPAPI size_t _php_stream_printf(php_stream *stream TSRMLS_DC, const char *fmt, ...);
/* php_stream_printf macro & function require TSRMLS_CC */
#define php_stream_printf _php_stream_printf

PHPAPI int _php_stream_eof(php_stream *stream TSRMLS_DC);
#define php_stream_eof(stream)	_php_stream_eof((stream) TSRMLS_CC)

PHPAPI int _php_stream_getc(php_stream *stream TSRMLS_DC);
#define php_stream_getc(stream)	_php_stream_getc((stream) TSRMLS_CC)

PHPAPI int _php_stream_putc(php_stream *stream, int c TSRMLS_DC);
#define php_stream_putc(stream, c)	_php_stream_putc((stream), (c) TSRMLS_CC)

PHPAPI int _php_stream_flush(php_stream *stream, int closing TSRMLS_DC);
#define php_stream_flush(stream)	_php_stream_flush((stream), 0 TSRMLS_CC)

PHPAPI char *_php_stream_get_line(php_stream *stream, char *buf, size_t maxlen, size_t *returned_len TSRMLS_DC);
#define php_stream_gets(stream, buf, maxlen)	_php_stream_get_line((stream), (buf), (maxlen), NULL TSRMLS_CC)

#define php_stream_get_line(stream, buf, maxlen, retlen) _php_stream_get_line((stream), (buf), (maxlen), (retlen) TSRMLS_CC)
PHPAPI char *php_stream_get_record(php_stream *stream, size_t maxlen, size_t *returned_len, char *delim, size_t delim_len TSRMLS_DC);

/* CAREFUL! this is equivalent to puts NOT fputs! */
PHPAPI int _php_stream_puts(php_stream *stream, char *buf TSRMLS_DC);
#define php_stream_puts(stream, buf)	_php_stream_puts((stream), (buf) TSRMLS_CC)

PHPAPI int _php_stream_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC);
#define php_stream_stat(stream, ssb)	_php_stream_stat((stream), (ssb) TSRMLS_CC)

PHPAPI int _php_stream_stat_path(char *path, int flags, php_stream_statbuf *ssb, php_stream_context *context TSRMLS_DC);
#define php_stream_stat_path(path, ssb)	_php_stream_stat_path((path), 0, (ssb), NULL TSRMLS_CC)
#define php_stream_stat_path_ex(path, flags, ssb, context)	_php_stream_stat_path((path), (flags), (ssb), (context) TSRMLS_CC)

PHPAPI int _php_stream_mkdir(char *path, int mode, int options, php_stream_context *context TSRMLS_DC);
#define php_stream_mkdir(path, mode, options, context)	_php_stream_mkdir(path, mode, options, context TSRMLS_CC)

PHPAPI int _php_stream_rmdir(char *path, int options, php_stream_context *context TSRMLS_DC);
#define php_stream_rmdir(path, options, context)	_php_stream_rmdir(path, options, context TSRMLS_CC)

PHPAPI php_stream *_php_stream_opendir(char *path, int options, php_stream_context *context STREAMS_DC TSRMLS_DC);
#define php_stream_opendir(path, options, context)	_php_stream_opendir((path), (options), (context) STREAMS_CC TSRMLS_CC)
PHPAPI php_stream_dirent *_php_stream_readdir(php_stream *dirstream, php_stream_dirent *ent TSRMLS_DC);
#define php_stream_readdir(dirstream, dirent)	_php_stream_readdir((dirstream), (dirent) TSRMLS_CC)
#define php_stream_closedir(dirstream)	php_stream_close((dirstream))
#define php_stream_rewinddir(dirstream)	php_stream_rewind((dirstream))

PHPAPI int php_stream_dirent_alphasort(const char **a, const char **b);
PHPAPI int php_stream_dirent_alphasortr(const char **a, const char **b);

PHPAPI int _php_stream_scandir(char *dirname, char **namelist[], int flags, php_stream_context *context,
			int (*compare) (const char **a, const char **b) TSRMLS_DC);
#define php_stream_scandir(dirname, namelist, context, compare) _php_stream_scandir((dirname), (namelist), 0, (context), (compare) TSRMLS_CC)

PHPAPI int _php_stream_set_option(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC);
#define php_stream_set_option(stream, option, value, ptrvalue)	_php_stream_set_option((stream), (option), (value), (ptrvalue) TSRMLS_CC)

#define php_stream_set_chunk_size(stream, size) _php_stream_set_option((stream), PHP_STREAM_OPTION_SET_CHUNK_SIZE, (size), NULL TSRMLS_CC)

END_EXTERN_C()


/* Flags for mkdir method in wrapper ops */
#define PHP_STREAM_MKDIR_RECURSIVE	1
/* define REPORT ERRORS 8 (below) */

/* Flags for rmdir method in wrapper ops */
/* define REPORT_ERRORS 8 (below) */

/* Flags for url_stat method in wrapper ops */
#define PHP_STREAM_URL_STAT_LINK	1
#define PHP_STREAM_URL_STAT_QUIET	2

/* change the blocking mode of stream: value == 1 => blocking, value == 0 => non-blocking. */
#define PHP_STREAM_OPTION_BLOCKING	1

/* change the buffering mode of stream. value is a PHP_STREAM_BUFFER_XXXX value, ptrparam is a ptr to a size_t holding
 * the required buffer size */
#define PHP_STREAM_OPTION_READ_BUFFER	2
#define PHP_STREAM_OPTION_WRITE_BUFFER	3

#define PHP_STREAM_BUFFER_NONE	0	/* unbuffered */
#define PHP_STREAM_BUFFER_LINE	1	/* line buffered */
#define PHP_STREAM_BUFFER_FULL	2	/* fully buffered */

/* set the timeout duration for reads on the stream. ptrparam is a pointer to a struct timeval * */
#define PHP_STREAM_OPTION_READ_TIMEOUT	4
#define PHP_STREAM_OPTION_SET_CHUNK_SIZE	5

/* set or release lock on a stream */
#define PHP_STREAM_OPTION_LOCKING		6

/* whether or not locking is supported */
#define PHP_STREAM_LOCK_SUPPORTED		1	

#define php_stream_supports_lock(stream)	_php_stream_set_option((stream), PHP_STREAM_OPTION_LOCKING, 0, (void *) PHP_STREAM_LOCK_SUPPORTED TSRMLS_CC) == 0 ? 1 : 0
#define php_stream_lock(stream, mode)		_php_stream_set_option((stream), PHP_STREAM_OPTION_LOCKING, (mode), (void *) NULL TSRMLS_CC)

/* option code used by the php_stream_xport_XXX api */
#define PHP_STREAM_OPTION_XPORT_API			7 /* see php_stream_transport.h */
#define PHP_STREAM_OPTION_CRYPTO_API		8 /* see php_stream_transport.h */
#define PHP_STREAM_OPTION_MMAP_API			9 /* see php_stream_mmap.h */
#define PHP_STREAM_OPTION_TRUNCATE_API		10

#define PHP_STREAM_TRUNCATE_SUPPORTED	0
#define PHP_STREAM_TRUNCATE_SET_SIZE	1	/* ptrparam is a pointer to a size_t */

#define php_stream_truncate_supported(stream)	(_php_stream_set_option((stream), PHP_STREAM_OPTION_TRUNCATE_API, PHP_STREAM_TRUNCATE_SUPPORTED, NULL TSRMLS_CC) == PHP_STREAM_OPTION_RETURN_OK ? 1 : 0)

BEGIN_EXTERN_C()
PHPAPI int _php_stream_truncate_set_size(php_stream *stream, size_t newsize TSRMLS_DC);
#define php_stream_truncate_set_size(stream, size)	_php_stream_truncate_set_size((stream), (size) TSRMLS_CC)
END_EXTERN_C()

#define PHP_STREAM_OPTION_META_DATA_API		11 /* ptrparam is a zval* to which to add meta data information */
#define php_stream_populate_meta_data(stream, zv)	(_php_stream_set_option((stream), PHP_STREAM_OPTION_META_DATA_API, 0, zv TSRMLS_CC) == PHP_STREAM_OPTION_RETURN_OK ? 1 : 0)

/* Check if the stream is still "live"; for sockets/pipes this means the socket
 * is still connected; for files, this does not really have meaning */
#define PHP_STREAM_OPTION_CHECK_LIVENESS	12 /* no parameters */

#define PHP_STREAM_OPTION_RETURN_OK			 0 /* option set OK */
#define PHP_STREAM_OPTION_RETURN_ERR 		-1 /* problem setting option */
#define PHP_STREAM_OPTION_RETURN_NOTIMPL	-2 /* underlying stream does not implement; streams can handle it instead */

/* copy up to maxlen bytes from src to dest.  If maxlen is PHP_STREAM_COPY_ALL, copy until eof(src).
 * Uses mmap if the src is a plain file and at offset 0 */
#define PHP_STREAM_COPY_ALL		((size_t)-1)

BEGIN_EXTERN_C()
PHPAPI size_t _php_stream_copy_to_stream(php_stream *src, php_stream *dest, size_t maxlen STREAMS_DC TSRMLS_DC);
#define php_stream_copy_to_stream(src, dest, maxlen)	_php_stream_copy_to_stream((src), (dest), (maxlen) STREAMS_CC TSRMLS_CC)
PHPAPI size_t _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, size_t maxlen, size_t *len STREAMS_DC TSRMLS_DC);
#define php_stream_copy_to_stream_ex(src, dest, maxlen, len)	_php_stream_copy_to_stream_ex((src), (dest), (maxlen), (len) STREAMS_CC TSRMLS_CC)


/* read all data from stream and put into a buffer. Caller must free buffer when done.
 * The copy will use mmap if available. */
PHPAPI size_t _php_stream_copy_to_mem(php_stream *src, char **buf, size_t maxlen,
		int persistent STREAMS_DC TSRMLS_DC);
#define php_stream_copy_to_mem(src, buf, maxlen, persistent) _php_stream_copy_to_mem((src), (buf), (maxlen), (persistent) STREAMS_CC TSRMLS_CC)

/* output all data from a stream */
PHPAPI size_t _php_stream_passthru(php_stream * src STREAMS_DC TSRMLS_DC);
#define php_stream_passthru(stream)	_php_stream_passthru((stream) STREAMS_CC TSRMLS_CC)
END_EXTERN_C()

#include "streams/php_stream_transport.h"
#include "streams/php_stream_plain_wrapper.h"
#include "streams/php_stream_userspace.h"
#include "streams/php_stream_mmap.h"

/* coerce the stream into some other form */
/* cast as a stdio FILE * */
#define PHP_STREAM_AS_STDIO     0
/* cast as a POSIX fd or socketd */
#define PHP_STREAM_AS_FD		1
/* cast as a socketd */
#define PHP_STREAM_AS_SOCKETD	2
/* cast as fd/socket for select purposes */
#define PHP_STREAM_AS_FD_FOR_SELECT 3

/* try really, really hard to make sure the cast happens (avoid using this flag if possible) */
#define PHP_STREAM_CAST_TRY_HARD	0x80000000
#define PHP_STREAM_CAST_RELEASE		0x40000000	/* stream becomes invalid on success */
#define PHP_STREAM_CAST_INTERNAL	0x20000000	/* stream cast for internal use */
#define PHP_STREAM_CAST_MASK		(PHP_STREAM_CAST_TRY_HARD | PHP_STREAM_CAST_RELEASE | PHP_STREAM_CAST_INTERNAL)
BEGIN_EXTERN_C()
PHPAPI int _php_stream_cast(php_stream *stream, int castas, void **ret, int show_err TSRMLS_DC);
END_EXTERN_C()
/* use this to check if a stream can be cast into another form */
#define php_stream_can_cast(stream, as)	_php_stream_cast((stream), (as), NULL, 0 TSRMLS_CC)
#define php_stream_cast(stream, as, ret, show_err)	_php_stream_cast((stream), (as), (ret), (show_err) TSRMLS_CC)

/* use this to check if a stream is of a particular type:
 * PHPAPI int php_stream_is(php_stream *stream, php_stream_ops *ops); */
#define php_stream_is(stream, anops)		((stream)->ops == anops)
#define PHP_STREAM_IS_STDIO &php_stream_stdio_ops

#define php_stream_is_persistent(stream)	(stream)->is_persistent

/* Wrappers support */

#define IGNORE_PATH			0
#define USE_PATH			1
#define IGNORE_URL			2
#define ENFORCE_SAFE_MODE 	4
#define REPORT_ERRORS		8
/* If you don't need to write to the stream, but really need to
 * be able to seek, use this flag in your options. */
#define STREAM_MUST_SEEK	16
/* If you are going to end up casting the stream into a FILE* or
 * a socket, pass this flag and the streams/wrappers will not use
 * buffering mechanisms while reading the headers, so that HTTP
 * wrapped streams will work consistently.
 * If you omit this flag, streams will use buffering and should end 
 * up working more optimally.
 * */
#define STREAM_WILL_CAST	32

/* this flag applies to php_stream_locate_url_wrapper */
#define STREAM_LOCATE_WRAPPERS_ONLY	64

/* this flag is only used by include/require functions */
#define STREAM_OPEN_FOR_INCLUDE		128

/* this flag tells streams to ONLY open urls */
#define STREAM_USE_URL			256

/* this flag is used when only the headers from HTTP request are to be fetched */
#define STREAM_ONLY_GET_HEADERS		512

/* don't apply open_basedir checks */
#define STREAM_DISABLE_OPEN_BASEDIR	1024

/* get (or create) a persistent version of the stream */
#define STREAM_OPEN_PERSISTENT	2048

/* don't check allow_url_fopen and allow_url_include */
#define STREAM_DISABLE_URL_PROTECTION   0x00002000

/* Antique - no longer has meaning */
#define IGNORE_URL_WIN 0

int php_init_stream_wrappers(int module_number TSRMLS_DC);
int php_shutdown_stream_wrappers(int module_number TSRMLS_DC);
void php_shutdown_stream_hashes(TSRMLS_D);
PHP_RSHUTDOWN_FUNCTION(streams);

BEGIN_EXTERN_C()
PHPAPI int php_register_url_stream_wrapper(char *protocol, php_stream_wrapper *wrapper TSRMLS_DC);
PHPAPI int php_unregister_url_stream_wrapper(char *protocol TSRMLS_DC);
PHPAPI int php_register_url_stream_wrapper_volatile(char *protocol, php_stream_wrapper *wrapper TSRMLS_DC);
PHPAPI int php_unregister_url_stream_wrapper_volatile(char *protocol TSRMLS_DC);
PHPAPI php_stream *_php_stream_open_wrapper_ex(char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC);
PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, char **path_for_open, int options TSRMLS_DC);
PHPAPI char *php_stream_locate_eol(php_stream *stream, char *buf, size_t buf_len TSRMLS_DC);

#define php_stream_open_wrapper(path, mode, options, opened)	_php_stream_open_wrapper_ex((path), (mode), (options), (opened), NULL STREAMS_CC TSRMLS_CC)
#define php_stream_open_wrapper_ex(path, mode, options, opened, context)	_php_stream_open_wrapper_ex((path), (mode), (options), (opened), (context) STREAMS_CC TSRMLS_CC)

#define php_stream_get_from_zval(stream, zstream, mode, options, opened, context) \
		if (Z_TYPE_PP((zstream)) == IS_RESOURCE) { \
			php_stream_from_zval((stream), (zstream)); \
		} else (stream) = Z_TYPE_PP((zstream)) == IS_STRING ?  \
			php_stream_open_wrapper_ex(Z_STRVAL_PP((zstream)), (mode), (options), (opened), (context)) : NULL

/* pushes an error message onto the stack for a wrapper instance */
PHPAPI void php_stream_wrapper_log_error(php_stream_wrapper *wrapper, int options TSRMLS_DC, const char *fmt, ...);


#define PHP_STREAM_UNCHANGED	0 /* orig stream was seekable anyway */
#define PHP_STREAM_RELEASED		1 /* newstream should be used; origstream is no longer valid */
#define PHP_STREAM_FAILED		2 /* an error occurred while attempting conversion */
#define PHP_STREAM_CRITICAL		3 /* an error occurred; origstream is in an unknown state; you should close origstream */
#define PHP_STREAM_NO_PREFERENCE	0
#define PHP_STREAM_PREFER_STDIO		1
#define PHP_STREAM_FORCE_CONVERSION	2
/* DO NOT call this on streams that are referenced by resources! */
PHPAPI int _php_stream_make_seekable(php_stream *origstream, php_stream **newstream, int flags STREAMS_DC TSRMLS_DC);
#define php_stream_make_seekable(origstream, newstream, flags)	_php_stream_make_seekable((origstream), (newstream), (flags) STREAMS_CC TSRMLS_CC)

/* Give other modules access to the url_stream_wrappers_hash and stream_filters_hash */
PHPAPI HashTable *_php_stream_get_url_stream_wrappers_hash(TSRMLS_D);
#define php_stream_get_url_stream_wrappers_hash()	_php_stream_get_url_stream_wrappers_hash(TSRMLS_C)
PHPAPI HashTable *php_stream_get_url_stream_wrappers_hash_global(void);
PHPAPI HashTable *_php_get_stream_filters_hash(TSRMLS_D);
#define php_get_stream_filters_hash()	_php_get_stream_filters_hash(TSRMLS_C)
PHPAPI HashTable *php_get_stream_filters_hash_global(void);
END_EXTERN_C()
#endif

/* Definitions for user streams */
#define PHP_STREAM_IS_URL		1

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/main/http_status_codes.h000064400000006160151730541440012176 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 7                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2018 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Andrea Faulds     <ajf@ajf.me>                               |
   +----------------------------------------------------------------------+
*/

/* $Id: $ */

#ifndef HTTP_STATUS_CODES_H
#define HTTP_STATUS_CODES_H

typedef struct _http_response_status_code_pair {
	const int code;
	const char *str;
} http_response_status_code_pair;

static http_response_status_code_pair http_status_map[] = {
	{ 100, "Continue" },
	{ 101, "Switching Protocols" },
	{ 200, "OK" },
	{ 201, "Created" },
	{ 202, "Accepted" },
	{ 203, "Non-Authoritative Information" },
	{ 204, "No Content" },
	{ 205, "Reset Content" },
	{ 206, "Partial Content" },
	{ 300, "Multiple Choices" },
	{ 301, "Moved Permanently" },
	{ 302, "Found" },
	{ 303, "See Other" },
	{ 304, "Not Modified" },
	{ 305, "Use Proxy" },
	{ 307, "Temporary Redirect" },
	{ 308, "Permanent Redirect" },
	{ 400, "Bad Request" },
	{ 401, "Unauthorized" },
	{ 402, "Payment Required" },
	{ 403, "Forbidden" },
	{ 404, "Not Found" },
	{ 405, "Method Not Allowed" },
	{ 406, "Not Acceptable" },
	{ 407, "Proxy Authentication Required" },
	{ 408, "Request Timeout" },
	{ 409, "Conflict" },
	{ 410, "Gone" },
	{ 411, "Length Required" },
	{ 412, "Precondition Failed" },
	{ 413, "Request Entity Too Large" },
	{ 414, "Request-URI Too Long" },
	{ 415, "Unsupported Media Type" },
	{ 416, "Requested Range Not Satisfiable" },
	{ 417, "Expectation Failed" },
	{ 426, "Upgrade Required" },
	{ 428, "Precondition Required" },
	{ 429, "Too Many Requests" },
	{ 431, "Request Header Fields Too Large" },
	{ 451, "Unavailable For Legal Reasons"},
	{ 500, "Internal Server Error" },
	{ 501, "Not Implemented" },
	{ 502, "Bad Gateway" },
	{ 503, "Service Unavailable" },
	{ 504, "Gateway Timeout" },
	{ 505, "HTTP Version Not Supported" },
	{ 506, "Variant Also Negotiates" },
	{ 511, "Network Authentication Required" },
	/* to allow search with while() loop */
	{ 0, NULL }
};

static const size_t http_status_map_len = (sizeof(http_status_map) / sizeof(http_response_status_code_pair)) - 1;

#endif /* HTTP_STATUS_CODES_H */
/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/main/php_getopt.h000064400000003505151730541440010610 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 7                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2018 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Marcus Boerger <helly@php.net>                               |
   +----------------------------------------------------------------------+
*/

/* $Id$ */

#ifndef PHP_GETOPT_H
#define PHP_GETOPT_H

#include "php.h"

/* Define structure for one recognized option (both single char and long name).
 * If short_open is '-' this is the last option. */
typedef struct _opt_struct {
	char opt_char;
	int  need_param;
	char * opt_name;
} opt_struct;

BEGIN_EXTERN_C()
/* holds the index of the latest fetched element from the opts array */
extern PHPAPI int php_optidx;
PHPAPI int php_getopt(int argc, char* const *argv, const opt_struct opts[], char **optarg, int *optind, int show_err, int arg_start);
END_EXTERN_C()

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
php/main/rfc1867.h000064400000005031151730541440007533 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 5                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2010 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author:                                                              |
  +----------------------------------------------------------------------+
*/

/* $Id: rfc1867.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef RFC1867_H
#define RFC1867_H

#include "SAPI.h"

#define MULTIPART_CONTENT_TYPE "multipart/form-data"
#define MULTIPART_EVENT_START		0
#define MULTIPART_EVENT_FORMDATA	1
#define MULTIPART_EVENT_FILE_START	2
#define MULTIPART_EVENT_FILE_DATA	3
#define MULTIPART_EVENT_FILE_END	4
#define MULTIPART_EVENT_END		5

typedef struct _multipart_event_start {
	size_t	content_length;
} multipart_event_start;

typedef struct _multipart_event_formdata {
	size_t	post_bytes_processed;
	char	*name;
	char	**value;
	size_t	length;
	size_t	*newlength;
} multipart_event_formdata;

typedef struct _multipart_event_file_start {
	size_t	post_bytes_processed;
	char	*name;
	char	**filename;
} multipart_event_file_start;

typedef struct _multipart_event_file_data {
	size_t	post_bytes_processed;
	off_t	offset;
	char	*data;
	size_t	length;
	size_t	*newlength;	
} multipart_event_file_data;

typedef struct _multipart_event_file_end {
	size_t	post_bytes_processed;
	char	*temp_filename;
	int	cancel_upload;
} multipart_event_file_end;

typedef struct _multipart_event_end {
	size_t	post_bytes_processed;
} multipart_event_end;

SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler);

void destroy_uploaded_files_hash(TSRMLS_D);
void php_rfc1867_register_constants(TSRMLS_D);
extern PHPAPI int (*php_rfc1867_callback)(unsigned int event, void *event_data, void **extra TSRMLS_DC);

#endif /* RFC1867_H */
php/main/php_memory_streams.h000064400000006476151730541440012366 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Marcus Boerger <helly@php.net>                               |
   +----------------------------------------------------------------------+
 */

/* $Id: php_memory_streams.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_MEMORY_STREAM_H
#define PHP_MEMORY_STREAM_H

#include "php_streams.h"

#define PHP_STREAM_MAX_MEM	2 * 1024 * 1024

#define TEMP_STREAM_DEFAULT  0
#define TEMP_STREAM_READONLY 1
#define TEMP_STREAM_TAKE_BUFFER 2

#define php_stream_memory_create(mode) _php_stream_memory_create((mode) STREAMS_CC TSRMLS_CC)
#define php_stream_memory_create_rel(mode) _php_stream_memory_create((mode) STREAMS_REL_CC TSRMLS_CC)
#define php_stream_memory_open(mode, buf, length) _php_stream_memory_open((mode), (buf), (length) STREAMS_CC TSRMLS_CC)
#define php_stream_memory_get_buffer(stream, length) _php_stream_memory_get_buffer((stream), (length) STREAMS_CC TSRMLS_CC)

#define php_stream_temp_new() php_stream_temp_create(TEMP_STREAM_DEFAULT, PHP_STREAM_MAX_MEM)
#define php_stream_temp_create(mode, max_memory_usage) _php_stream_temp_create((mode), (max_memory_usage) STREAMS_CC TSRMLS_CC)
#define php_stream_temp_create_rel(mode, max_memory_usage) _php_stream_temp_create((mode), (max_memory_usage) STREAMS_REL_CC TSRMLS_CC)
#define php_stream_temp_open(mode, max_memory_usage, buf, length) _php_stream_temp_open((mode), (max_memory_usage), (buf), (length) STREAMS_CC TSRMLS_CC)

BEGIN_EXTERN_C()
PHPAPI php_stream *_php_stream_memory_create(int mode STREAMS_DC TSRMLS_DC);
PHPAPI php_stream *_php_stream_memory_open(int mode, char *buf, size_t length STREAMS_DC TSRMLS_DC);
PHPAPI char *_php_stream_memory_get_buffer(php_stream *stream, size_t *length STREAMS_DC TSRMLS_DC);

PHPAPI php_stream *_php_stream_temp_create(int mode, size_t max_memory_usage STREAMS_DC TSRMLS_DC);
PHPAPI php_stream *_php_stream_temp_open(int mode, size_t max_memory_usage, char *buf, size_t length STREAMS_DC TSRMLS_DC);
END_EXTERN_C()

extern PHPAPI php_stream_ops php_stream_memory_ops;
extern PHPAPI php_stream_ops php_stream_temp_ops;
extern PHPAPI php_stream_ops php_stream_rfc2397_ops;
extern PHPAPI php_stream_wrapper php_stream_rfc2397_wrapper;

#define PHP_STREAM_IS_MEMORY &php_stream_memory_ops
#define PHP_STREAM_IS_TEMP   &php_stream_temp_ops

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/TSRM/tsrm_config.w32.h000064400000000447151730541440011226 0ustar00#ifndef TSRM_CONFIG_W32_H
#define TSRM_CONFIG_W32_H

#define HAVE_UTIME 1
#define HAVE_ALLOCA 1
#define HAVE_REALPATH 1

#include <malloc.h>
#include <stdlib.h>
#include <crtdbg.h>

#undef inline
#ifdef ZEND_WIN32_FORCE_INLINE
# define inline __forceinline
#else
# define inline
#endif


#endif
php/TSRM/readdir.h000064400000002153151730541440007710 0ustar00#ifndef READDIR_H
#define READDIR_H


/*
 * Structures and types used to implement opendir/readdir/closedir
 * on Windows 95/NT.
 */

#define _WIN32_WINNT 0x0400

#include <windows.h>

#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <direct.h>

/* struct dirent - same as Unix */

struct dirent {
	long d_ino;					/* inode (always 1 in WIN32) */
	off_t d_off;				/* offset to this dirent */
	unsigned short d_reclen;	/* length of d_name */
	char d_name[_MAX_FNAME + 1];	/* filename (null terminated) */
};


/* typedef DIR - not the same as Unix */
typedef struct {
	HANDLE handle;				/* _findfirst/_findnext handle */
	short offset;				/* offset into directory */
	short finished;				/* 1 if there are not more files */
	WIN32_FIND_DATA fileinfo;	/* from _findfirst/_findnext */
	char *dir;					/* the dir we are reading */
	struct dirent dent;			/* the dirent to return */
} DIR;

/* Function prototypes */
DIR *opendir(const char *);
struct dirent *readdir(DIR *);
int readdir_r(DIR *, struct dirent *, struct dirent **);
int closedir(DIR *);
int rewinddir(DIR *);

#endif /* READDIR_H */
php/TSRM/tsrm_config_common.h000064400000002114151730541450012156 0ustar00#ifndef TSRM_CONFIG_COMMON_H
#define TSRM_CONFIG_COMMON_H

#ifndef __CYGWIN__
# if WINNT|WIN32
#  define TSRM_WIN32
# endif
#endif

#ifdef TSRM_WIN32
# include "tsrm_config.w32.h"
#else
# include <tsrm_config.h>
# include <sys/param.h>
#endif

#if HAVE_ALLOCA_H && !defined(_ALLOCA_H)
#  include <alloca.h>
#endif

/* AIX requires this to be the first thing in the file.  */
#ifndef __GNUC__
# ifndef HAVE_ALLOCA_H
#  ifdef _AIX
#pragma alloca
#  else
#   ifndef alloca /* predefined by HP cc +Olibcalls */
#    ifndef NETWARE
char *alloca ();
#    endif
#   endif
#  endif
# endif
#endif

#if HAVE_UNISTD_H
#include <unistd.h>
#endif

#if HAVE_LIMITS_H
#include <limits.h>
#endif

#ifndef MAXPATHLEN
# ifdef PATH_MAX
#  define MAXPATHLEN PATH_MAX
# elif defined(MAX_PATH)
#  define MAXPATHLEN MAX_PATH
# else
#  define MAXPATHLEN 256
# endif
#endif

#if (HAVE_ALLOCA || (defined (__GNUC__) && __GNUC__ >= 2))
# define tsrm_do_alloca(p) alloca(p)
# define tsrm_free_alloca(p)
#else
# define tsrm_do_alloca(p)   malloc(p)
# define tsrm_free_alloca(p) free(p)
#endif

#endif /* TSRM_CONFIG_COMMON_H */
php/TSRM/tsrm_config.h000064400000000040151730541450010602 0ustar00#include <../main/php_config.h>
php/TSRM/tsrm_strtok_r.h000064400000000163151730541450011212 0ustar00#ifndef TSRM_STRTOK_R
#define TSRM_STRTOK_R

char *tsrm_strtok_r(char *s, const char *delim, char **last);

#endif
php/TSRM/tsrm_win32.h000064400000005752151730541460010317 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Daniel Beulshausen <daniel@php4win.de>                      |
   +----------------------------------------------------------------------+
*/

/* $Id: tsrm_win32.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef TSRM_WIN32_H
#define TSRM_WIN32_H

#include "TSRM.h"
#include <windows.h>

struct ipc_perm {
	int			key;
	unsigned short	uid;
	unsigned short	gid;
	unsigned short	cuid;
	unsigned short	cgid;
	unsigned short	mode;
	unsigned short	seq;
};

struct shmid_ds {
	struct	ipc_perm	shm_perm;
	int				shm_segsz;
	time_t			shm_atime;
	time_t			shm_dtime;
	time_t			shm_ctime;
	unsigned short	shm_cpid;
	unsigned short	shm_lpid;
	short			shm_nattch;
};

typedef struct {
	FILE	*stream;
	HANDLE	prochnd;
} process_pair;

typedef struct {
	void	*addr;
	HANDLE	info;
	HANDLE	segment;
	struct	shmid_ds	*descriptor;
} shm_pair;

typedef struct {
	process_pair	*process;
	shm_pair		*shm;
	int				process_size;
	int				shm_size;
	char			*comspec;
} tsrm_win32_globals;

#ifdef ZTS
# define TWG(v) TSRMG(win32_globals_id, tsrm_win32_globals *, v)
#else
# define TWG(v) (win32_globals.v)
#endif

#define IPC_PRIVATE	0
#define IPC_CREAT	00001000
#define IPC_EXCL	00002000
#define IPC_NOWAIT	00004000

#define IPC_RMID	0
#define IPC_SET		1
#define IPC_STAT	2
#define IPC_INFO	3

#define SHM_R		PAGE_READONLY
#define SHM_W		PAGE_READWRITE

#define	SHM_RDONLY	FILE_MAP_READ
#define	SHM_RND		FILE_MAP_WRITE
#define	SHM_REMAP	FILE_MAP_COPY


TSRM_API void tsrm_win32_startup(void);
TSRM_API void tsrm_win32_shutdown(void);

TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd, char *env);
TSRM_API FILE *popen(const char *command, const char *type);
TSRM_API int pclose(FILE *stream);
TSRM_API int tsrm_win32_access(const char *pathname, int mode);

TSRM_API int shmget(int key, int size, int flags);
TSRM_API void *shmat(int key, const void *shmaddr, int flags);
TSRM_API int shmdt(const void *shmaddr);
TSRM_API int shmctl(int key, int cmd, struct shmid_ds *buf);

TSRM_API char *realpath(char *orig_path, char *buffer);
#endif
php/TSRM/TSRM.h000064400000012164151730541470007071 0ustar00/*
   +----------------------------------------------------------------------+
   | Thread Safe Resource Manager                                         |
   +----------------------------------------------------------------------+
   | Copyright (c) 1999-2009, Andi Gutmans, Sascha Schumann, Zeev Suraski |
   | This source file is subject to the TSRM license, that is bundled     |
   | with this package in the file LICENSE                                |
   +----------------------------------------------------------------------+
   | Authors:  Zeev Suraski <zeev@zend.com>                               |
   +----------------------------------------------------------------------+
*/

#ifndef TSRM_H
#define TSRM_H

#if !defined(__CYGWIN__) && defined(WIN32)
# define TSRM_WIN32
# include "tsrm_config.w32.h"
#else
# include <tsrm_config.h>
#endif

#ifdef TSRM_WIN32
#	ifdef TSRM_EXPORTS
#	define TSRM_API __declspec(dllexport)
#	else
#	define TSRM_API __declspec(dllimport)
#	endif
#else
#	define TSRM_API
#endif

#ifdef _WIN64
typedef __int64 tsrm_intptr_t;
typedef unsigned __int64 tsrm_uintptr_t;
#else
typedef long tsrm_intptr_t;
typedef unsigned long tsrm_uintptr_t;
#endif

/* Only compile multi-threading functions if we're in ZTS mode */
#ifdef ZTS

#ifdef TSRM_WIN32
# ifndef TSRM_INCLUDE_FULL_WINDOWS_HEADERS
#  define WIN32_LEAN_AND_MEAN
# endif
# include <windows.h>
# include <shellapi.h>
#elif defined(GNUPTH)
# include <pth.h>
#elif defined(PTHREADS)
# include <pthread.h>
#elif defined(TSRM_ST)
# include <st.h>
#elif defined(BETHREADS)
#include <kernel/OS.h> 
#include <TLS.h>
#endif

typedef int ts_rsrc_id;

/* Define THREAD_T and MUTEX_T */
#ifdef TSRM_WIN32
# define THREAD_T DWORD
# define MUTEX_T CRITICAL_SECTION *
#elif defined(GNUPTH)
# define THREAD_T pth_t
# define MUTEX_T pth_mutex_t *
#elif defined(PTHREADS)
# define THREAD_T pthread_t
# define MUTEX_T pthread_mutex_t *
#elif defined(NSAPI)
# define THREAD_T SYS_THREAD
# define MUTEX_T CRITICAL
#elif defined(PI3WEB)
# define THREAD_T PIThread *
# define MUTEX_T PISync *
#elif defined(TSRM_ST)
# define THREAD_T st_thread_t
# define MUTEX_T st_mutex_t
#elif defined(BETHREADS)
# define THREAD_T thread_id
typedef struct {
  sem_id sem;
  int32 ben;
} beos_ben;
# define MUTEX_T beos_ben * 
#endif

typedef void (*ts_allocate_ctor)(void *, void ***);
typedef void (*ts_allocate_dtor)(void *, void ***);

#define THREAD_HASH_OF(thr,ts)  (unsigned long)thr%(unsigned long)ts

#ifdef __cplusplus
extern "C" {
#endif

/* startup/shutdown */
TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debug_level, char *debug_filename);
TSRM_API void tsrm_shutdown(void);

/* allocates a new thread-safe-resource id */
TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor);

/* fetches the requested resource for the current thread */
TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id);
#define ts_resource(id)			ts_resource_ex(id, NULL)

/* frees all resources allocated for the current thread */
TSRM_API void ts_free_thread(void);

/* frees all resources allocated for all threads except current */
void ts_free_worker_threads(void);

/* deallocates all occurrences of a given id */
TSRM_API void ts_free_id(ts_rsrc_id id);


/* Debug support */
#define TSRM_ERROR_LEVEL_ERROR	1
#define TSRM_ERROR_LEVEL_CORE	2
#define TSRM_ERROR_LEVEL_INFO	3

typedef void (*tsrm_thread_begin_func_t)(THREAD_T thread_id, void ***tsrm_ls);
typedef void (*tsrm_thread_end_func_t)(THREAD_T thread_id, void ***tsrm_ls);


TSRM_API int tsrm_error(int level, const char *format, ...);
TSRM_API void tsrm_error_set(int level, char *debug_filename);

/* utility functions */
TSRM_API THREAD_T tsrm_thread_id(void);
TSRM_API MUTEX_T tsrm_mutex_alloc(void);
TSRM_API void tsrm_mutex_free(MUTEX_T mutexp);
TSRM_API int tsrm_mutex_lock(MUTEX_T mutexp);
TSRM_API int tsrm_mutex_unlock(MUTEX_T mutexp);

TSRM_API void *tsrm_set_new_thread_begin_handler(tsrm_thread_begin_func_t new_thread_begin_handler);
TSRM_API void *tsrm_set_new_thread_end_handler(tsrm_thread_end_func_t new_thread_end_handler);

/* these 3 APIs should only be used by people that fully understand the threading model
 * used by PHP/Zend and the selected SAPI. */
TSRM_API void *tsrm_new_interpreter_context(void);
TSRM_API void *tsrm_set_interpreter_context(void *new_ctx);
TSRM_API void tsrm_free_interpreter_context(void *context);

#define TSRM_SHUFFLE_RSRC_ID(rsrc_id)		((rsrc_id)+1)
#define TSRM_UNSHUFFLE_RSRC_ID(rsrc_id)		((rsrc_id)-1)

#define TSRMLS_FETCH()			void ***tsrm_ls = (void ***) ts_resource_ex(0, NULL)
#define TSRMLS_FETCH_FROM_CTX(ctx)	void ***tsrm_ls = (void ***) ctx
#define TSRMLS_SET_CTX(ctx)		ctx = (void ***) tsrm_ls
#define TSRMG(id, type, element)	(((type) (*((void ***) tsrm_ls))[TSRM_UNSHUFFLE_RSRC_ID(id)])->element)
#define TSRMLS_D	void ***tsrm_ls
#define TSRMLS_DC	, TSRMLS_D
#define TSRMLS_C	tsrm_ls
#define TSRMLS_CC	, TSRMLS_C

#ifdef __cplusplus
}
#endif

#else /* non ZTS */

#define TSRMLS_FETCH()
#define TSRMLS_FETCH_FROM_CTX(ctx)
#define TSRMLS_SET_CTX(ctx)
#define TSRMLS_D	void
#define TSRMLS_DC
#define TSRMLS_C
#define TSRMLS_CC

#endif /* ZTS */

#endif /* TSRM_H */
php/Zend/zend_API.h000064400000104037151730541470010051 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        | 
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   |          Andrei Zmievski <andrei@php.net>                            |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_API.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef ZEND_API_H
#define ZEND_API_H

#include "zend_modules.h"
#include "zend_list.h"
#include "zend_operators.h"
#include "zend_variables.h"
#include "zend_execute.h"


BEGIN_EXTERN_C()

typedef struct _zend_function_entry {
	char *fname;
	void (*handler)(INTERNAL_FUNCTION_PARAMETERS);
	struct _zend_arg_info *arg_info;
	zend_uint num_args;
	zend_uint flags;
} zend_function_entry;

#define ZEND_FN(name) zif_##name
#define ZEND_MN(name) zim_##name
#define ZEND_NAMED_FUNCTION(name)		void name(INTERNAL_FUNCTION_PARAMETERS)
#define ZEND_FUNCTION(name)				ZEND_NAMED_FUNCTION(ZEND_FN(name))
#define ZEND_METHOD(classname, name)	ZEND_NAMED_FUNCTION(ZEND_MN(classname##_##name))

#define ZEND_FENTRY(zend_name, name, arg_info, flags)	{ #zend_name, name, arg_info, (zend_uint) (sizeof(arg_info)/sizeof(struct _zend_arg_info)-1), flags },

#define ZEND_RAW_FENTRY(zend_name, name, arg_info, flags)   { zend_name, name, arg_info, (zend_uint) (sizeof(arg_info)/sizeof(struct _zend_arg_info)-1), flags },
#define ZEND_RAW_NAMED_FE(zend_name, name, arg_info) ZEND_RAW_FENTRY(#zend_name, name, arg_info, 0)

#define ZEND_NAMED_FE(zend_name, name, arg_info)	ZEND_FENTRY(zend_name, name, arg_info, 0)
#define ZEND_FE(name, arg_info)						ZEND_FENTRY(name, ZEND_FN(name), arg_info, 0)
#define ZEND_DEP_FE(name, arg_info)                 ZEND_FENTRY(name, ZEND_FN(name), arg_info, ZEND_ACC_DEPRECATED)
#define ZEND_FALIAS(name, alias, arg_info)			ZEND_FENTRY(name, ZEND_FN(alias), arg_info, 0)
#define ZEND_DEP_FALIAS(name, alias, arg_info)		ZEND_FENTRY(name, ZEND_FN(alias), arg_info, ZEND_ACC_DEPRECATED)
#define ZEND_NAMED_ME(zend_name, name, arg_info, flags)	ZEND_FENTRY(zend_name, name, arg_info, flags)
#define ZEND_ME(classname, name, arg_info, flags)	ZEND_FENTRY(name, ZEND_MN(classname##_##name), arg_info, flags)
#define ZEND_ABSTRACT_ME(classname, name, arg_info)	ZEND_FENTRY(name, NULL, arg_info, ZEND_ACC_PUBLIC|ZEND_ACC_ABSTRACT)
#define ZEND_MALIAS(classname, name, alias, arg_info, flags) \
                                                    ZEND_FENTRY(name, ZEND_MN(classname##_##alias), arg_info, flags)
#define ZEND_ME_MAPPING(name, func_name, arg_types, flags) ZEND_NAMED_ME(name, ZEND_FN(func_name), arg_types, flags)

#define ZEND_ARG_INFO(pass_by_ref, name)							{ #name, sizeof(#name)-1, NULL, 0, 0, 0, pass_by_ref, 0, 0 },
#define ZEND_ARG_PASS_INFO(pass_by_ref)								{ NULL, 0, NULL, 0, 0, 0, pass_by_ref, 0, 0 },
#define ZEND_ARG_OBJ_INFO(pass_by_ref, name, classname, allow_null) { #name, sizeof(#name)-1, #classname, sizeof(#classname)-1, 0, allow_null, pass_by_ref, 0, 0 },
#define ZEND_ARG_ARRAY_INFO(pass_by_ref, name, allow_null) { #name, sizeof(#name)-1, NULL, 0, 1, allow_null, pass_by_ref, 0, 0 },
#define ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, return_reference, required_num_args)	\
	zend_arg_info name[] = {																		\
		{ NULL, 0, NULL, 0, 0, 0, pass_rest_by_reference, return_reference, required_num_args },
#define ZEND_BEGIN_ARG_INFO(name, pass_rest_by_reference)	\
	ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, ZEND_RETURN_VALUE, -1)
#define ZEND_END_ARG_INFO()		};

/* Name macros */
#define ZEND_MODULE_STARTUP_N(module)       zm_startup_##module
#define ZEND_MODULE_SHUTDOWN_N(module)		zm_shutdown_##module
#define ZEND_MODULE_ACTIVATE_N(module)		zm_activate_##module
#define ZEND_MODULE_DEACTIVATE_N(module)	zm_deactivate_##module
#define ZEND_MODULE_POST_ZEND_DEACTIVATE_N(module)	zm_post_zend_deactivate_##module
#define ZEND_MODULE_INFO_N(module)			zm_info_##module
#define ZEND_MODULE_GLOBALS_CTOR_N(module)  zm_globals_ctor_##module
#define ZEND_MODULE_GLOBALS_DTOR_N(module)  zm_globals_dtor_##module

/* Declaration macros */
#define ZEND_MODULE_STARTUP_D(module)		int ZEND_MODULE_STARTUP_N(module)(INIT_FUNC_ARGS)
#define ZEND_MODULE_SHUTDOWN_D(module)		int ZEND_MODULE_SHUTDOWN_N(module)(SHUTDOWN_FUNC_ARGS)
#define ZEND_MODULE_ACTIVATE_D(module)		int ZEND_MODULE_ACTIVATE_N(module)(INIT_FUNC_ARGS)
#define ZEND_MODULE_DEACTIVATE_D(module)	int ZEND_MODULE_DEACTIVATE_N(module)(SHUTDOWN_FUNC_ARGS)
#define ZEND_MODULE_POST_ZEND_DEACTIVATE_D(module)	int ZEND_MODULE_POST_ZEND_DEACTIVATE_N(module)(void)
#define ZEND_MODULE_INFO_D(module)			void ZEND_MODULE_INFO_N(module)(ZEND_MODULE_INFO_FUNC_ARGS)
#define ZEND_MODULE_GLOBALS_CTOR_D(module)  void ZEND_MODULE_GLOBALS_CTOR_N(module)(zend_##module##_globals *module##_globals TSRMLS_DC)
#define ZEND_MODULE_GLOBALS_DTOR_D(module)  void ZEND_MODULE_GLOBALS_DTOR_N(module)(zend_##module##_globals *module##_globals TSRMLS_DC)

#define ZEND_GET_MODULE(name) \
    BEGIN_EXTERN_C()\
	ZEND_DLEXPORT zend_module_entry *get_module(void) { return &name##_module_entry; }\
    END_EXTERN_C()

#define ZEND_BEGIN_MODULE_GLOBALS(module_name)		\
	typedef struct _zend_##module_name##_globals {
#define ZEND_END_MODULE_GLOBALS(module_name)		\
	} zend_##module_name##_globals;

#ifdef ZTS

#define ZEND_DECLARE_MODULE_GLOBALS(module_name)							\
	ts_rsrc_id module_name##_globals_id;
#define ZEND_EXTERN_MODULE_GLOBALS(module_name)								\
	extern ts_rsrc_id module_name##_globals_id;
#define ZEND_INIT_MODULE_GLOBALS(module_name, globals_ctor, globals_dtor)	\
	ts_allocate_id(&module_name##_globals_id, sizeof(zend_##module_name##_globals), (ts_allocate_ctor) globals_ctor, (ts_allocate_dtor) globals_dtor);

#else

#define ZEND_DECLARE_MODULE_GLOBALS(module_name)							\
	zend_##module_name##_globals module_name##_globals;
#define ZEND_EXTERN_MODULE_GLOBALS(module_name)								\
	extern zend_##module_name##_globals module_name##_globals;
#define ZEND_INIT_MODULE_GLOBALS(module_name, globals_ctor, globals_dtor)	\
	globals_ctor(&module_name##_globals);

#endif

#define INIT_CLASS_ENTRY(class_container, class_name, functions) INIT_OVERLOADED_CLASS_ENTRY(class_container, class_name, functions, NULL, NULL, NULL)

#define INIT_OVERLOADED_CLASS_ENTRY_EX(class_container, class_name, functions, handle_fcall, handle_propget, handle_propset, handle_propunset, handle_propisset) \
	{															\
		class_container.name = strdup(class_name);				\
		class_container.name_length = sizeof(class_name) - 1;	\
		class_container.builtin_functions = functions;			\
		class_container.constructor = NULL;						\
		class_container.destructor = NULL;						\
		class_container.clone = NULL;							\
		class_container.serialize = NULL;						\
		class_container.unserialize = NULL;						\
		class_container.create_object = NULL;					\
		class_container.interface_gets_implemented = NULL;		\
		class_container.__call = handle_fcall;					\
		class_container.__tostring = NULL;						\
		class_container.__get = handle_propget;					\
		class_container.__set = handle_propset;					\
		class_container.__unset = handle_propunset;				\
		class_container.__isset = handle_propisset;				\
		class_container.serialize_func = NULL;					\
		class_container.unserialize_func = NULL;				\
		class_container.serialize = NULL;						\
		class_container.unserialize = NULL;						\
		class_container.parent = NULL;							\
		class_container.num_interfaces = 0;						\
		class_container.interfaces = NULL;						\
		class_container.get_iterator = NULL;					\
		class_container.iterator_funcs.funcs = NULL;			\
		class_container.module = NULL;							\
	}

#define INIT_OVERLOADED_CLASS_ENTRY(class_container, class_name, functions, handle_fcall, handle_propget, handle_propset) \
	INIT_OVERLOADED_CLASS_ENTRY_EX(class_container, class_name, functions, handle_fcall, handle_propget, handle_propset, NULL, NULL)

#ifdef ZTS
#	define CE_STATIC_MEMBERS(ce) (((ce)->type==ZEND_USER_CLASS)?(ce)->static_members:CG(static_members)[(zend_intptr_t)(ce)->static_members])
#else
#	define CE_STATIC_MEMBERS(ce) ((ce)->static_members)
#endif

int zend_next_free_module(void);

BEGIN_EXTERN_C()
ZEND_API int zend_get_parameters(int ht, int param_count, ...);
ZEND_API int _zend_get_parameters_array(int ht, int param_count, zval **argument_array TSRMLS_DC);
ZEND_API int zend_get_parameters_ex(int param_count, ...);
ZEND_API int _zend_get_parameters_array_ex(int param_count, zval ***argument_array TSRMLS_DC);

/* internal function to efficiently copy parameters when executing __call() */
ZEND_API int zend_copy_parameters_array(int param_count, zval *argument_array TSRMLS_DC);

#define zend_get_parameters_array(ht, param_count, argument_array)			\
	_zend_get_parameters_array(ht, param_count, argument_array TSRMLS_CC)
#define zend_get_parameters_array_ex(param_count, argument_array)			\
	_zend_get_parameters_array_ex(param_count, argument_array TSRMLS_CC)


/* Parameter parsing API -- andrei */

#define ZEND_PARSE_PARAMS_QUIET 1<<1
ZEND_API int zend_parse_parameters(int num_args TSRMLS_DC, char *type_spec, ...);
ZEND_API int zend_parse_parameters_ex(int flags, int num_args TSRMLS_DC, char *type_spec, ...);
ZEND_API char *zend_zval_type_name(zval *arg);

ZEND_API int zend_parse_method_parameters(int num_args TSRMLS_DC, zval *this_ptr, char *type_spec, ...);
ZEND_API int zend_parse_method_parameters_ex(int flags, int num_args TSRMLS_DC, zval *this_ptr, char *type_spec, ...);

/* End of parameter parsing API -- andrei */

ZEND_API int zend_register_functions(zend_class_entry *scope, zend_function_entry *functions, HashTable *function_table, int type TSRMLS_DC);
ZEND_API void zend_unregister_functions(zend_function_entry *functions, int count, HashTable *function_table TSRMLS_DC);
ZEND_API int zend_startup_module(zend_module_entry *module_entry);
ZEND_API zend_module_entry* zend_register_internal_module(zend_module_entry *module_entry TSRMLS_DC);
ZEND_API zend_module_entry* zend_register_module_ex(zend_module_entry *module TSRMLS_DC);
ZEND_API int zend_startup_module_ex(zend_module_entry *module TSRMLS_DC);
ZEND_API int zend_startup_modules(TSRMLS_D);
ZEND_API void zend_check_magic_method_implementation(zend_class_entry *ce, zend_function *fptr, int error_type TSRMLS_DC);

ZEND_API zend_class_entry *zend_register_internal_class(zend_class_entry *class_entry TSRMLS_DC);
ZEND_API zend_class_entry *zend_register_internal_class_ex(zend_class_entry *class_entry, zend_class_entry *parent_ce, char *parent_name TSRMLS_DC);
ZEND_API zend_class_entry *zend_register_internal_interface(zend_class_entry *orig_class_entry TSRMLS_DC);
ZEND_API void zend_class_implements(zend_class_entry *class_entry TSRMLS_DC, int num_interfaces, ...);

ZEND_API int zend_disable_function(char *function_name, uint function_name_length TSRMLS_DC);
ZEND_API int zend_disable_class(char *class_name, uint class_name_length TSRMLS_DC);

ZEND_API void zend_wrong_param_count(TSRMLS_D);

#define IS_CALLABLE_CHECK_SYNTAX_ONLY (1<<0)
#define IS_CALLABLE_CHECK_NO_ACCESS   (1<<1)
#define IS_CALLABLE_CHECK_IS_STATIC   (1<<2)

#define IS_CALLABLE_STRICT  (IS_CALLABLE_CHECK_IS_STATIC)

ZEND_API zend_bool zend_is_callable_ex(zval *callable, uint check_flags, char **callable_name, int *callable_name_len, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zval ***zobj_ptr_ptr TSRMLS_DC);
ZEND_API zend_bool zend_is_callable(zval *callable, uint check_flags, char **callable_name);
ZEND_API zend_bool zend_make_callable(zval *callable, char **callable_name TSRMLS_DC);
ZEND_API char *zend_get_module_version(char *module_name);
ZEND_API int zend_get_module_started(char *module_name);
ZEND_API int zend_declare_property(zend_class_entry *ce, char *name, int name_length, zval *property, int access_type TSRMLS_DC);
ZEND_API int zend_declare_property_ex(zend_class_entry *ce, char *name, int name_length, zval *property, int access_type, char *doc_comment, int doc_comment_len TSRMLS_DC);
ZEND_API int zend_declare_property_null(zend_class_entry *ce, char *name, int name_length, int access_type TSRMLS_DC);
ZEND_API int zend_declare_property_bool(zend_class_entry *ce, char *name, int name_length, long value, int access_type TSRMLS_DC);
ZEND_API int zend_declare_property_long(zend_class_entry *ce, char *name, int name_length, long value, int access_type TSRMLS_DC);
ZEND_API int zend_declare_property_double(zend_class_entry *ce, char *name, int name_length, double value, int access_type TSRMLS_DC);
ZEND_API int zend_declare_property_string(zend_class_entry *ce, char *name, int name_length, char *value, int access_type TSRMLS_DC);
ZEND_API int zend_declare_property_stringl(zend_class_entry *ce, char *name, int name_length, char *value, int value_len, int access_type TSRMLS_DC);

ZEND_API int zend_declare_class_constant(zend_class_entry *ce, char *name, size_t name_length, zval *value TSRMLS_DC);
ZEND_API int zend_declare_class_constant_null(zend_class_entry *ce, char *name, size_t name_length TSRMLS_DC);
ZEND_API int zend_declare_class_constant_long(zend_class_entry *ce, char *name, size_t name_length, long value TSRMLS_DC);
ZEND_API int zend_declare_class_constant_bool(zend_class_entry *ce, char *name, size_t name_length, zend_bool value TSRMLS_DC);
ZEND_API int zend_declare_class_constant_double(zend_class_entry *ce, char *name, size_t name_length, double value TSRMLS_DC);
ZEND_API int zend_declare_class_constant_stringl(zend_class_entry *ce, char *name, size_t name_length, char *value, size_t value_length TSRMLS_DC);
ZEND_API int zend_declare_class_constant_string(zend_class_entry *ce, char *name, size_t name_length, char *value TSRMLS_DC);

ZEND_API void zend_update_class_constants(zend_class_entry *class_type TSRMLS_DC);
ZEND_API void zend_update_property(zend_class_entry *scope, zval *object, char *name, int name_length, zval *value TSRMLS_DC);
ZEND_API void zend_update_property_null(zend_class_entry *scope, zval *object, char *name, int name_length TSRMLS_DC);
ZEND_API void zend_update_property_bool(zend_class_entry *scope, zval *object, char *name, int name_length, long value TSRMLS_DC);
ZEND_API void zend_update_property_long(zend_class_entry *scope, zval *object, char *name, int name_length, long value TSRMLS_DC);
ZEND_API void zend_update_property_double(zend_class_entry *scope, zval *object, char *name, int name_length, double value TSRMLS_DC);
ZEND_API void zend_update_property_string(zend_class_entry *scope, zval *object, char *name, int name_length, char *value TSRMLS_DC);
ZEND_API void zend_update_property_stringl(zend_class_entry *scope, zval *object, char *name, int name_length, char *value, int value_length TSRMLS_DC);

ZEND_API int zend_update_static_property(zend_class_entry *scope, char *name, int name_length, zval *value TSRMLS_DC);
ZEND_API int zend_update_static_property_null(zend_class_entry *scope, char *name, int name_length TSRMLS_DC);
ZEND_API int zend_update_static_property_bool(zend_class_entry *scope, char *name, int name_length, long value TSRMLS_DC);
ZEND_API int zend_update_static_property_long(zend_class_entry *scope, char *name, int name_length, long value TSRMLS_DC);
ZEND_API int zend_update_static_property_double(zend_class_entry *scope, char *name, int name_length, double value TSRMLS_DC);
ZEND_API int zend_update_static_property_string(zend_class_entry *scope, char *name, int name_length, char *value TSRMLS_DC);
ZEND_API int zend_update_static_property_stringl(zend_class_entry *scope, char *name, int name_length, char *value, int value_length TSRMLS_DC);

ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, char *name, int name_length, zend_bool silent TSRMLS_DC);

ZEND_API zval *zend_read_static_property(zend_class_entry *scope, char *name, int name_length, zend_bool silent TSRMLS_DC);

ZEND_API zend_class_entry *zend_get_class_entry(zval *zobject TSRMLS_DC);
ZEND_API int zend_get_object_classname(zval *object, char **class_name, zend_uint *class_name_len TSRMLS_DC);
ZEND_API char *zend_get_type_by_const(int type);

#define getThis() (this_ptr)

#define WRONG_PARAM_COUNT					ZEND_WRONG_PARAM_COUNT()
#define WRONG_PARAM_COUNT_WITH_RETVAL(ret)	ZEND_WRONG_PARAM_COUNT_WITH_RETVAL(ret)
#define ARG_COUNT(dummy)	(ht)
#define ZEND_NUM_ARGS()		(ht)
#define ZEND_WRONG_PARAM_COUNT()					{ zend_wrong_param_count(TSRMLS_C); return; }
#define ZEND_WRONG_PARAM_COUNT_WITH_RETVAL(ret)		{ zend_wrong_param_count(TSRMLS_C); return ret; }

#ifndef ZEND_WIN32
#define DLEXPORT
#endif

#define array_init(arg)			_array_init((arg) ZEND_FILE_LINE_CC)
#define object_init(arg)		_object_init((arg) ZEND_FILE_LINE_CC TSRMLS_CC)
#define object_init_ex(arg, ce)	_object_init_ex((arg), (ce) ZEND_FILE_LINE_CC TSRMLS_CC)
#define object_and_properties_init(arg, ce, properties)	_object_and_properties_init((arg), (ce), (properties) ZEND_FILE_LINE_CC TSRMLS_CC)
ZEND_API int _array_init(zval *arg ZEND_FILE_LINE_DC);
ZEND_API int _object_init(zval *arg ZEND_FILE_LINE_DC TSRMLS_DC);
ZEND_API int _object_init_ex(zval *arg, zend_class_entry *ce ZEND_FILE_LINE_DC TSRMLS_DC);
ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *ce, HashTable *properties ZEND_FILE_LINE_DC TSRMLS_DC);

ZEND_API void zend_merge_properties(zval *obj, HashTable *properties, int destroy_ht TSRMLS_DC);

/* no longer supported */
ZEND_API int add_assoc_function(zval *arg, char *key, void (*function_ptr)(INTERNAL_FUNCTION_PARAMETERS));

ZEND_API int add_assoc_long_ex(zval *arg, char *key, uint key_len, long n);
ZEND_API int add_assoc_null_ex(zval *arg, char *key, uint key_len);
ZEND_API int add_assoc_bool_ex(zval *arg, char *key, uint key_len, int b);
ZEND_API int add_assoc_resource_ex(zval *arg, char *key, uint key_len, int r);
ZEND_API int add_assoc_double_ex(zval *arg, char *key, uint key_len, double d);
ZEND_API int add_assoc_string_ex(zval *arg, char *key, uint key_len, char *str, int duplicate);
ZEND_API int add_assoc_stringl_ex(zval *arg, char *key, uint key_len, char *str, uint length, int duplicate);
ZEND_API int add_assoc_zval_ex(zval *arg, char *key, uint key_len, zval *value);

#define add_assoc_long(__arg, __key, __n) add_assoc_long_ex(__arg, __key, strlen(__key)+1, __n)
#define add_assoc_null(__arg, __key) add_assoc_null_ex(__arg, __key, strlen(__key) + 1)
#define add_assoc_bool(__arg, __key, __b) add_assoc_bool_ex(__arg, __key, strlen(__key)+1, __b)
#define add_assoc_resource(__arg, __key, __r) add_assoc_resource_ex(__arg, __key, strlen(__key)+1, __r)
#define add_assoc_double(__arg, __key, __d) add_assoc_double_ex(__arg, __key, strlen(__key)+1, __d)
#define add_assoc_string(__arg, __key, __str, __duplicate) add_assoc_string_ex(__arg, __key, strlen(__key)+1, __str, __duplicate)
#define add_assoc_stringl(__arg, __key, __str, __length, __duplicate) add_assoc_stringl_ex(__arg, __key, strlen(__key)+1, __str, __length, __duplicate)
#define add_assoc_zval(__arg, __key, __value) add_assoc_zval_ex(__arg, __key, strlen(__key)+1, __value)

/* unset() functions are only suported for legacy modules and null() functions should be used */
#define add_assoc_unset(__arg, __key) add_assoc_null_ex(__arg, __key, strlen(__key) + 1)
#define add_index_unset(__arg, __key) add_index_null(__arg, __key)
#define add_next_index_unset(__arg) add_next_index_null(__arg)
#define add_property_unset(__arg, __key) add_property_null(__arg, __key)

ZEND_API int add_index_long(zval *arg, ulong idx, long n);
ZEND_API int add_index_null(zval *arg, ulong idx);
ZEND_API int add_index_bool(zval *arg, ulong idx, int b);
ZEND_API int add_index_resource(zval *arg, ulong idx, int r);
ZEND_API int add_index_double(zval *arg, ulong idx, double d);
ZEND_API int add_index_string(zval *arg, ulong idx, char *str, int duplicate);
ZEND_API int add_index_stringl(zval *arg, ulong idx, char *str, uint length, int duplicate);
ZEND_API int add_index_zval(zval *arg, ulong index, zval *value);

ZEND_API int add_next_index_long(zval *arg, long n);
ZEND_API int add_next_index_null(zval *arg);
ZEND_API int add_next_index_bool(zval *arg, int b);
ZEND_API int add_next_index_resource(zval *arg, int r);
ZEND_API int add_next_index_double(zval *arg, double d);
ZEND_API int add_next_index_string(zval *arg, char *str, int duplicate);
ZEND_API int add_next_index_stringl(zval *arg, char *str, uint length, int duplicate);
ZEND_API int add_next_index_zval(zval *arg, zval *value);

ZEND_API int add_get_assoc_string_ex(zval *arg, char *key, uint key_len, char *str, void **dest, int duplicate);
ZEND_API int add_get_assoc_stringl_ex(zval *arg, char *key, uint key_len, char *str, uint length, void **dest, int duplicate);

#define add_get_assoc_string(__arg, __key, __str, __dest, __duplicate) add_get_assoc_string_ex(__arg, __key, strlen(__key)+1, __str, __dest, __duplicate)
#define add_get_assoc_stringl(__arg, __key, __str, __length, __dest, __duplicate) add_get_assoc_stringl_ex(__arg, __key, strlen(__key)+1, __str, __length, __dest, __duplicate)

ZEND_API int add_get_index_long(zval *arg, ulong idx, long l, void **dest);
ZEND_API int add_get_index_double(zval *arg, ulong idx, double d, void **dest);
ZEND_API int add_get_index_string(zval *arg, ulong idx, char *str, void **dest, int duplicate);
ZEND_API int add_get_index_stringl(zval *arg, ulong idx, char *str, uint length, void **dest, int duplicate);

ZEND_API int add_property_long_ex(zval *arg, char *key, uint key_len, long l TSRMLS_DC);
ZEND_API int add_property_null_ex(zval *arg, char *key, uint key_len TSRMLS_DC);
ZEND_API int add_property_bool_ex(zval *arg, char *key, uint key_len, int b TSRMLS_DC);
ZEND_API int add_property_resource_ex(zval *arg, char *key, uint key_len, long r TSRMLS_DC);
ZEND_API int add_property_double_ex(zval *arg, char *key, uint key_len, double d TSRMLS_DC);
ZEND_API int add_property_string_ex(zval *arg, char *key, uint key_len, char *str, int duplicate TSRMLS_DC);
ZEND_API int add_property_stringl_ex(zval *arg, char *key, uint key_len,  char *str, uint length, int duplicate TSRMLS_DC);
ZEND_API int add_property_zval_ex(zval *arg, char *key, uint key_len, zval *value TSRMLS_DC);

#define add_property_long(__arg, __key, __n) add_property_long_ex(__arg, __key, strlen(__key)+1, __n TSRMLS_CC)
#define add_property_null(__arg, __key) add_property_null_ex(__arg, __key, strlen(__key) + 1 TSRMLS_CC)
#define add_property_bool(__arg, __key, __b) add_property_bool_ex(__arg, __key, strlen(__key)+1, __b TSRMLS_CC)
#define add_property_resource(__arg, __key, __r) add_property_resource_ex(__arg, __key, strlen(__key)+1, __r TSRMLS_CC)
#define add_property_double(__arg, __key, __d) add_property_double_ex(__arg, __key, strlen(__key)+1, __d TSRMLS_CC)
#define add_property_string(__arg, __key, __str, __duplicate) add_property_string_ex(__arg, __key, strlen(__key)+1, __str, __duplicate TSRMLS_CC)
#define add_property_stringl(__arg, __key, __str, __length, __duplicate) add_property_stringl_ex(__arg, __key, strlen(__key)+1, __str, __length, __duplicate TSRMLS_CC)
#define add_property_zval(__arg, __key, __value) add_property_zval_ex(__arg, __key, strlen(__key)+1, __value TSRMLS_CC)       


ZEND_API int call_user_function(HashTable *function_table, zval **object_pp, zval *function_name, zval *retval_ptr, zend_uint param_count, zval *params[] TSRMLS_DC);
ZEND_API int call_user_function_ex(HashTable *function_table, zval **object_pp, zval *function_name, zval **retval_ptr_ptr, zend_uint param_count, zval **params[], int no_separation, HashTable *symbol_table TSRMLS_DC);
END_EXTERN_C()

typedef struct _zend_fcall_info {
	size_t size;
	HashTable *function_table;
	zval *function_name;
	HashTable *symbol_table;
	zval **retval_ptr_ptr;
	zend_uint param_count;
	zval ***params;
	zval **object_pp;
	zend_bool no_separation;
} zend_fcall_info;

typedef struct _zend_fcall_info_cache {
	zend_bool initialized;
	zend_function *function_handler;
	zend_class_entry *calling_scope;
	zval **object_pp;
} zend_fcall_info_cache;

BEGIN_EXTERN_C()
ZEND_API extern zend_fcall_info_cache empty_fcall_info_cache;

/** Build zend_call_info/cache from a zval*
 *
 * Caller is responsible to provide a return value, otherwise the we will crash. 
 * fci->retval_ptr_ptr = NULL;
 * In order to pass parameters the following members need to be set:
 * fci->param_count = 0;
 * fci->params = NULL;
 */
ZEND_API int zend_fcall_info_init(zval *callable, zend_fcall_info *fci, zend_fcall_info_cache *fcc TSRMLS_DC);

/** Set or clear the arguments in the zend_call_info struct taking care of
 * refcount. If args is NULL and arguments are set then those are cleared.
 */
ZEND_API int zend_fcall_info_args(zend_fcall_info *fci, zval *args TSRMLS_DC);

/** Call a function using information created by zend_fcall_info_init()/args().
 * If args is given then those replace the arguement info in fci is temporarily.
 */
ZEND_API int zend_fcall_info_call(zend_fcall_info *fci, zend_fcall_info_cache *fcc, zval **retval, zval *args TSRMLS_DC);

ZEND_API int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TSRMLS_DC);


ZEND_API int zend_set_hash_symbol(zval *symbol, char *name, int name_length,
                                  zend_bool is_ref, int num_symbol_tables, ...);

ZEND_API int zend_delete_global_variable(char *name, int name_len TSRMLS_DC);

ZEND_API void zend_reset_all_cv(HashTable *symbol_table TSRMLS_DC);

#define add_method(arg, key, method)	add_assoc_function((arg), (key), (method))

ZEND_API ZEND_FUNCTION(display_disabled_function);
ZEND_API ZEND_FUNCTION(display_disabled_class);
END_EXTERN_C()

#if ZEND_DEBUG
#define CHECK_ZVAL_STRING(z) \
	if ((z)->value.str.val[ (z)->value.str.len ] != '\0') { zend_error(E_WARNING, "String is not zero-terminated (%s)", (z)->value.str.val); }
#define CHECK_ZVAL_STRING_REL(z) \
	if ((z)->value.str.val[ (z)->value.str.len ] != '\0') { zend_error(E_WARNING, "String is not zero-terminated (%s) (source: %s:%d)", (z)->value.str.val ZEND_FILE_LINE_RELAY_CC); }
#else
#define CHECK_ZVAL_STRING(z)
#define CHECK_ZVAL_STRING_REL(z)
#endif

#define CHECK_ZVAL_NULL_PATH(p) (Z_STRLEN_P(p) != strlen(Z_STRVAL_P(p)))
#define CHECK_NULL_PATH(p, l) (strlen(p) != l)

#define ZVAL_RESOURCE(z, l) {		\
		Z_TYPE_P(z) = IS_RESOURCE;	\
		Z_LVAL_P(z) = l;			\
	}

#define ZVAL_BOOL(z, b) {			\
		Z_TYPE_P(z) = IS_BOOL;		\
		Z_LVAL_P(z) = ((b) != 0);   \
	}

#define ZVAL_NULL(z) {				\
		Z_TYPE_P(z) = IS_NULL;		\
	}

#define ZVAL_LONG(z, l) {			\
		Z_TYPE_P(z) = IS_LONG;		\
		Z_LVAL_P(z) = l;			\
	}

#define ZVAL_DOUBLE(z, d) {			\
		Z_TYPE_P(z) = IS_DOUBLE;	\
		Z_DVAL_P(z) = d;			\
	}

#define ZVAL_STRING(z, s, duplicate) {	\
		char *__s=(s);					\
		(z)->value.str.len = strlen(__s);	\
		if (UNEXPECTED(Z_STRLEN_P(z) < 0)) { \
			zend_error(E_ERROR, "String size overflow"); \
		} \
		(z)->value.str.val = (duplicate?estrndup(__s, (z)->value.str.len):__s);	\
		(z)->type = IS_STRING;	        \
	}

#define ZVAL_STRINGL(z, s, l, duplicate) {	\
		char *__s=(s); int __l=l;		\
		(z)->value.str.len = __l;	    \
		(z)->value.str.val = (duplicate?estrndup(__s, __l):__s);	\
		(z)->type = IS_STRING;		    \
	}

#define ZVAL_EMPTY_STRING(z) {	        \
		(z)->value.str.len = 0;  	    \
		(z)->value.str.val = STR_EMPTY_ALLOC(); \
		(z)->type = IS_STRING;		    \
	}

#define ZVAL_ZVAL(z, zv, copy, dtor) {  \
		int is_ref, refcount;           \
		is_ref = (z)->is_ref;           \
		refcount = (z)->refcount;       \
		*(z) = *(zv);                   \
		if (copy) {                     \
			zval_copy_ctor(z);          \
	    }                               \
		if (dtor) {                     \
			if (!copy) {                \
				ZVAL_NULL(zv);          \
			}                           \
			zval_ptr_dtor(&zv);         \
	    }                               \
		(z)->is_ref = is_ref;           \
		(z)->refcount = refcount;       \
	}

#define ZVAL_FALSE(z)  					ZVAL_BOOL(z, 0)
#define ZVAL_TRUE(z)  					ZVAL_BOOL(z, 1)

#define RETVAL_RESOURCE(l)				ZVAL_RESOURCE(return_value, l)
#define RETVAL_BOOL(b)					ZVAL_BOOL(return_value, b)
#define RETVAL_NULL() 					ZVAL_NULL(return_value)
#define RETVAL_LONG(l) 					ZVAL_LONG(return_value, l)
#define RETVAL_DOUBLE(d) 				ZVAL_DOUBLE(return_value, d)
#define RETVAL_STRING(s, duplicate) 		ZVAL_STRING(return_value, s, duplicate)
#define RETVAL_STRINGL(s, l, duplicate) 	ZVAL_STRINGL(return_value, s, l, duplicate)
#define RETVAL_EMPTY_STRING() 			ZVAL_EMPTY_STRING(return_value)
#define RETVAL_ZVAL(zv, copy, dtor)		ZVAL_ZVAL(return_value, zv, copy, dtor)
#define RETVAL_FALSE  					ZVAL_BOOL(return_value, 0)
#define RETVAL_TRUE   					ZVAL_BOOL(return_value, 1)

#define RETURN_RESOURCE(l) 				{ RETVAL_RESOURCE(l); return; }
#define RETURN_BOOL(b) 					{ RETVAL_BOOL(b); return; }
#define RETURN_NULL() 					{ RETVAL_NULL(); return;}
#define RETURN_LONG(l) 					{ RETVAL_LONG(l); return; }
#define RETURN_DOUBLE(d) 				{ RETVAL_DOUBLE(d); return; }
#define RETURN_STRING(s, duplicate) 	{ RETVAL_STRING(s, duplicate); return; }
#define RETURN_STRINGL(s, l, duplicate) { RETVAL_STRINGL(s, l, duplicate); return; }
#define RETURN_EMPTY_STRING() 			{ RETVAL_EMPTY_STRING(); return; }
#define RETURN_ZVAL(zv, copy, dtor)		{ RETVAL_ZVAL(zv, copy, dtor); return; }
#define RETURN_FALSE  					{ RETVAL_FALSE; return; }
#define RETURN_TRUE   					{ RETVAL_TRUE; return; }

/* Check that returned string length fits int */
#define RETVAL_STRINGL_CHECK(s, len, dup) do {  \
	size_t __len = (len);                   \
	if (UNEXPECTED(__len > INT_MAX)) {      \
		php_error_docref(NULL TSRMLS_CC, E_WARNING, "String too long, max is %d", INT_MAX); \
		if(!(dup)) {                        \
			efree((s));                     \
		}                                   \
		RETURN_FALSE;                       \
	}                                       \
	RETVAL_STRINGL((s), (int)__len, (dup)); \
} while (0)
#define RETURN_STRINGL_CHECK(s, len, dup) { RETVAL_STRINGL_CHECK(s, len, dup); return; }

#define SET_VAR_STRING(n, v) {																				\
								{																			\
									zval *var;																\
									ALLOC_ZVAL(var);														\
									ZVAL_STRING(var, v, 0);													\
									ZEND_SET_GLOBAL_VAR(n, var);											\
								}																			\
							}

#define SET_VAR_STRINGL(n, v, l) {														\
									{													\
										zval *var;										\
										ALLOC_ZVAL(var);								\
										ZVAL_STRINGL(var, v, l, 0);						\
										ZEND_SET_GLOBAL_VAR(n, var);					\
									}													\
								}

#define SET_VAR_LONG(n, v)	{															\
								{														\
									zval *var;											\
									ALLOC_ZVAL(var);									\
									ZVAL_LONG(var, v);									\
									ZEND_SET_GLOBAL_VAR(n, var);						\
								}														\
							}

#define SET_VAR_DOUBLE(n, v) {															\
								{														\
									zval *var;											\
									ALLOC_ZVAL(var);									\
									ZVAL_DOUBLE(var, v);								\
									ZEND_SET_GLOBAL_VAR(n, var);						\
								}														\
							}


#define ZEND_SET_SYMBOL(symtable, name, var)										\
	{																				\
		char *_name = (name);														\
																					\
		ZEND_SET_SYMBOL_WITH_LENGTH(symtable, _name, strlen(_name)+1, var, 1, 0);	\
	}

#define ZEND_SET_SYMBOL_WITH_LENGTH(symtable, name, name_length, var, _refcount, _is_ref)				\
	{																									\
		zval **orig_var;																				\
																										\
		if (zend_hash_find(symtable, (name), (name_length), (void **) &orig_var)==SUCCESS				\
			&& PZVAL_IS_REF(*orig_var)) {																\
			(var)->refcount = (*orig_var)->refcount;													\
			(var)->is_ref = 1;																			\
																										\
			if (_refcount) {																			\
				(var)->refcount += _refcount-1;															\
			}																							\
			zval_dtor(*orig_var);																		\
			**orig_var = *(var);																		\
			FREE_ZVAL(var);																					\
		} else {																						\
			(var)->is_ref = _is_ref;																	\
			if (_refcount) {																			\
				(var)->refcount = _refcount;															\
			}																							\
			zend_hash_update(symtable, (name), (name_length), &(var), sizeof(zval *), NULL);			\
		}																								\
	}


#define ZEND_SET_GLOBAL_VAR(name, var)				\
	ZEND_SET_SYMBOL(&EG(symbol_table), name, var)

#define ZEND_SET_GLOBAL_VAR_WITH_LENGTH(name, name_length, var, _refcount, _is_ref)		\
	ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), name, name_length, var, _refcount, _is_ref)

#define ZEND_DEFINE_PROPERTY(class_ptr, name, value, mask)								\
{																					\
	char *_name = (name);															\
	int namelen = strlen(_name);													\
	zend_declare_property(class_ptr, _name, namelen, value, mask TSRMLS_CC);		\
}

#define HASH_OF(p) (Z_TYPE_P(p)==IS_ARRAY ? Z_ARRVAL_P(p) : ((Z_TYPE_P(p)==IS_OBJECT ? Z_OBJ_HT_P(p)->get_properties((p) TSRMLS_CC) : NULL)))
#define ZVAL_IS_NULL(z) (Z_TYPE_P(z)==IS_NULL)

/* For compatibility */
#define ZEND_MINIT			ZEND_MODULE_STARTUP_N
#define ZEND_MSHUTDOWN		ZEND_MODULE_SHUTDOWN_N
#define ZEND_RINIT			ZEND_MODULE_ACTIVATE_N
#define ZEND_RSHUTDOWN		ZEND_MODULE_DEACTIVATE_N
#define ZEND_MINFO			ZEND_MODULE_INFO_N
#define ZEND_GINIT(module)		((void (*)(void* TSRMLS_DC))(ZEND_MODULE_GLOBALS_CTOR_N(module)))
#define ZEND_GSHUTDOWN(module)	((void (*)(void* TSRMLS_DC))(ZEND_MODULE_GLOBALS_DTOR_N(module)))

#define ZEND_MINIT_FUNCTION			ZEND_MODULE_STARTUP_D
#define ZEND_MSHUTDOWN_FUNCTION		ZEND_MODULE_SHUTDOWN_D
#define ZEND_RINIT_FUNCTION			ZEND_MODULE_ACTIVATE_D
#define ZEND_RSHUTDOWN_FUNCTION		ZEND_MODULE_DEACTIVATE_D
#define ZEND_MINFO_FUNCTION			ZEND_MODULE_INFO_D
#define ZEND_GINIT_FUNCTION			ZEND_MODULE_GLOBALS_CTOR_D
#define ZEND_GSHUTDOWN_FUNCTION		ZEND_MODULE_GLOBALS_DTOR_D

END_EXTERN_C()

#endif /* ZEND_API_H */


/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_variables.h000064400000010037151730541500011376 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        | 
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_variables.h 302150 2010-08-12 17:27:16Z sas $ */

#ifndef ZEND_VARIABLES_H
#define ZEND_VARIABLES_H


BEGIN_EXTERN_C()

ZEND_API void _zval_dtor_func(zval *zvalue ZEND_FILE_LINE_DC);

static inline void _zval_dtor(zval *zvalue ZEND_FILE_LINE_DC)
{
	if (zvalue->type <= IS_BOOL) {
		return;
	}
	_zval_dtor_func(zvalue ZEND_FILE_LINE_RELAY_CC);
}

ZEND_API void _zval_copy_ctor_func(zval *zvalue ZEND_FILE_LINE_DC);

static inline void _zval_copy_ctor(zval *zvalue ZEND_FILE_LINE_DC)
{
	if (zvalue->type <= IS_BOOL) {
		return;
	}
	_zval_copy_ctor_func(zvalue ZEND_FILE_LINE_RELAY_CC);
}


ZEND_API int zend_print_variable(zval *var);
ZEND_API void _zval_ptr_dtor(zval **zval_ptr ZEND_FILE_LINE_DC);
ZEND_API void _zval_internal_dtor(zval *zvalue ZEND_FILE_LINE_DC);
ZEND_API void _zval_internal_ptr_dtor(zval **zvalue ZEND_FILE_LINE_DC);
#define zval_copy_ctor(zvalue) _zval_copy_ctor((zvalue) ZEND_FILE_LINE_CC)
#define zval_dtor(zvalue) _zval_dtor((zvalue) ZEND_FILE_LINE_CC)
#define zval_ptr_dtor(zval_ptr) _zval_ptr_dtor((zval_ptr) ZEND_FILE_LINE_CC)
#define zval_internal_dtor(zvalue) _zval_internal_dtor((zvalue) ZEND_FILE_LINE_CC)
#define zval_internal_ptr_dtor(zvalue) _zval_internal_ptr_dtor((zvalue) ZEND_FILE_LINE_CC)

#if ZEND_DEBUG
ZEND_API void _zval_copy_ctor_wrapper(zval *zvalue);
ZEND_API void _zval_dtor_wrapper(zval *zvalue);
ZEND_API void _zval_ptr_dtor_wrapper(zval **zval_ptr);
ZEND_API void _zval_internal_dtor_wrapper(zval *zvalue);
ZEND_API void _zval_internal_ptr_dtor_wrapper(zval **zvalue);
#define zval_copy_ctor_wrapper _zval_copy_ctor_wrapper
#define zval_dtor_wrapper _zval_dtor_wrapper
#define zval_ptr_dtor_wrapper _zval_ptr_dtor_wrapper
#define zval_internal_dtor_wrapper _zval_internal_dtor_wrapper
#define zval_internal_ptr_dtor_wrapper _zval_internal_ptr_dtor_wrapper
#else
#define zval_copy_ctor_wrapper _zval_copy_ctor_func
#define zval_dtor_wrapper _zval_dtor_func
#define zval_ptr_dtor_wrapper _zval_ptr_dtor
#define zval_internal_dtor_wrapper _zval_internal_dtor
#define zval_internal_ptr_dtor_wrapper _zval_internal_ptr_dtor
#endif

ZEND_API void zval_add_ref(zval **p);

ZEND_API void zval_property_ctor(zval **);

#ifdef ZTS
# define zval_shared_property_ctor zval_property_ctor
#else
# define zval_shared_property_ctor zval_add_ref
#endif

#define zval_copy_property_ctor(ce) ((copy_ctor_func_t) (((ce)->type == ZEND_INTERNAL_CLASS) ? zval_shared_property_ctor : zval_add_ref))


END_EXTERN_C()

#define ZVAL_DESTRUCTOR (void (*)(void *)) zval_dtor_wrapper
#define ZVAL_PTR_DTOR (void (*)(void *)) zval_ptr_dtor_wrapper
#define ZVAL_INTERNAL_DTOR (void (*)(void *)) zval_internal_dtor_wrapper
#define ZVAL_INTERNAL_PTR_DTOR (void (*)(void *)) zval_internal_ptr_dtor_wrapper
#define ZVAL_COPY_CTOR (void (*)(void *)) zval_copy_ctor_wrapper

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_string.h000064400000036073151730541510010745 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2018 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Dmitry Stogov <dmitry@zend.com>                             |
   +----------------------------------------------------------------------+
*/

/* $Id: $ */

#ifndef ZEND_STRING_H
#define ZEND_STRING_H

#include "zend.h"

BEGIN_EXTERN_C()

typedef void (*zend_string_copy_storage_func_t)(void);
typedef zend_string *(*zend_new_interned_string_func_t)(zend_string *str);

ZEND_API extern zend_new_interned_string_func_t zend_new_interned_string;

ZEND_API zend_ulong zend_hash_func(const char *str, size_t len);
ZEND_API void zend_interned_strings_init(void);
ZEND_API void zend_interned_strings_dtor(void);
ZEND_API void zend_interned_strings_activate(void);
ZEND_API void zend_interned_strings_deactivate(void);
ZEND_API zend_string *zend_interned_string_find_permanent(zend_string *str);
ZEND_API void zend_interned_strings_set_request_storage_handler(zend_new_interned_string_func_t handler);
ZEND_API void zend_interned_strings_set_permanent_storage_copy_handler(zend_string_copy_storage_func_t handler);
ZEND_API void zend_interned_strings_switch_storage(void);

ZEND_API zend_string *zend_string_concat3(
		const char *str1, size_t str1_len,
		const char *str2, size_t str2_len,
		const char *str3, size_t str3_len);

ZEND_API extern zend_string  *zend_empty_string;
ZEND_API extern zend_string  *zend_one_char_string[256];
ZEND_API extern zend_string **zend_known_strings;

END_EXTERN_C()

/* Shortcuts */

#define ZSTR_VAL(zstr)  (zstr)->val
#define ZSTR_LEN(zstr)  (zstr)->len
#define ZSTR_MAX_OVERHEAD (ZEND_MM_ALIGNED_SIZE(_ZSTR_HEADER_SIZE + 1))
#define ZSTR_MAX_LEN (SIZE_MAX - ZSTR_MAX_OVERHEAD)
#define ZSTR_H(zstr)    (zstr)->h
#define ZSTR_HASH(zstr) zend_string_hash_val(zstr)

/* Compatibility macros */

#define IS_INTERNED(s)	ZSTR_IS_INTERNED(s)
#define STR_EMPTY_ALLOC()	ZSTR_EMPTY_ALLOC()
#define _STR_HEADER_SIZE _ZSTR_HEADER_SIZE
#define STR_ALLOCA_ALLOC(str, _len, use_heap) ZSTR_ALLOCA_ALLOC(str, _len, use_heap)
#define STR_ALLOCA_INIT(str, s, len, use_heap) ZSTR_ALLOCA_INIT(str, s, len, use_heap)
#define STR_ALLOCA_FREE(str, use_heap) ZSTR_ALLOCA_FREE(str, use_heap)

/*---*/

#define ZSTR_IS_INTERNED(s)					(GC_FLAGS(s) & IS_STR_INTERNED)

#define ZSTR_EMPTY_ALLOC() zend_empty_string
#define ZSTR_CHAR(c) zend_one_char_string[c]
#define ZSTR_KNOWN(idx) zend_known_strings[idx]

#define _ZSTR_HEADER_SIZE XtOffsetOf(zend_string, val)

#define _ZSTR_STRUCT_SIZE(len) (_ZSTR_HEADER_SIZE + len + 1)

#define ZSTR_ALLOCA_ALLOC(str, _len, use_heap) do { \
	(str) = (zend_string *)do_alloca(ZEND_MM_ALIGNED_SIZE_EX(_ZSTR_STRUCT_SIZE(_len), 8), (use_heap)); \
	GC_REFCOUNT(str) = 1; \
	GC_TYPE_INFO(str) = IS_STRING; \
	zend_string_forget_hash_val(str); \
	ZSTR_LEN(str) = _len; \
} while (0)

#define ZSTR_ALLOCA_INIT(str, s, len, use_heap) do { \
	ZSTR_ALLOCA_ALLOC(str, len, use_heap); \
	memcpy(ZSTR_VAL(str), (s), (len)); \
	ZSTR_VAL(str)[(len)] = '\0'; \
} while (0)

#define ZSTR_ALLOCA_FREE(str, use_heap) free_alloca(str, use_heap)

#define ZSTR_INIT_LITERAL(s, persistent) (zend_string_init((s), strlen(s), (persistent)))

/*---*/

static zend_always_inline zend_ulong zend_string_hash_val(zend_string *s)
{
	if (!ZSTR_H(s)) {
		ZSTR_H(s) = zend_hash_func(ZSTR_VAL(s), ZSTR_LEN(s));
	}
	return ZSTR_H(s);
}

static zend_always_inline void zend_string_forget_hash_val(zend_string *s)
{
	ZSTR_H(s) = 0;
}

static zend_always_inline uint32_t zend_string_refcount(const zend_string *s)
{
	if (!ZSTR_IS_INTERNED(s)) {
		return GC_REFCOUNT(s);
	}
	return 1;
}

static zend_always_inline uint32_t zend_string_addref(zend_string *s)
{
	if (!ZSTR_IS_INTERNED(s)) {
		return ++GC_REFCOUNT(s);
	}
	return 1;
}

static zend_always_inline uint32_t zend_string_delref(zend_string *s)
{
	if (!ZSTR_IS_INTERNED(s)) {
		return --GC_REFCOUNT(s);
	}
	return 1;
}

static zend_always_inline zend_string *zend_string_alloc(size_t len, int persistent)
{
	zend_string *ret = (zend_string *)pemalloc(ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(len)), persistent);

	GC_REFCOUNT(ret) = 1;
#if 1
	/* optimized single assignment */
	GC_TYPE_INFO(ret) = IS_STRING | ((persistent ? IS_STR_PERSISTENT : 0) << 8);
#else
	GC_TYPE(ret) = IS_STRING;
	GC_FLAGS(ret) = (persistent ? IS_STR_PERSISTENT : 0);
	GC_INFO(ret) = 0;
#endif
	zend_string_forget_hash_val(ret);
	ZSTR_LEN(ret) = len;
	return ret;
}

static zend_always_inline zend_string *zend_string_safe_alloc(size_t n, size_t m, size_t l, int persistent)
{
	zend_string *ret = (zend_string *)safe_pemalloc(n, m, ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(l)), persistent);

	GC_REFCOUNT(ret) = 1;
#if 1
	/* optimized single assignment */
	GC_TYPE_INFO(ret) = IS_STRING | ((persistent ? IS_STR_PERSISTENT : 0) << 8);
#else
	GC_TYPE(ret) = IS_STRING;
	GC_FLAGS(ret) = (persistent ? IS_STR_PERSISTENT : 0);
	GC_INFO(ret) = 0;
#endif
	zend_string_forget_hash_val(ret);
	ZSTR_LEN(ret) = (n * m) + l;
	return ret;
}

static zend_always_inline zend_string *zend_string_init(const char *str, size_t len, int persistent)
{
	zend_string *ret = zend_string_alloc(len, persistent);

	memcpy(ZSTR_VAL(ret), str, len);
	ZSTR_VAL(ret)[len] = '\0';
	return ret;
}

static zend_always_inline zend_string *zend_string_init_interned(const char *str, size_t len, int persistent)
{
	zend_string *ret = zend_string_init(str, len, persistent);

	return zend_new_interned_string(ret);
}

static zend_always_inline zend_string *zend_string_copy(zend_string *s)
{
	if (!ZSTR_IS_INTERNED(s)) {
		GC_REFCOUNT(s)++;
	}
	return s;
}

static zend_always_inline zend_string *zend_string_dup(zend_string *s, int persistent)
{
	if (ZSTR_IS_INTERNED(s)) {
		return s;
	} else {
		return zend_string_init(ZSTR_VAL(s), ZSTR_LEN(s), persistent);
	}
}

static zend_always_inline zend_string *zend_string_realloc(zend_string *s, size_t len, int persistent)
{
	zend_string *ret;

	if (!ZSTR_IS_INTERNED(s)) {
		if (EXPECTED(GC_REFCOUNT(s) == 1)) {
			ret = (zend_string *)perealloc(s, ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(len)), persistent);
			ZSTR_LEN(ret) = len;
			zend_string_forget_hash_val(ret);
			return ret;
		}
	}
	ret = zend_string_alloc(len, persistent);
	memcpy(ZSTR_VAL(ret), ZSTR_VAL(s), MIN(len, ZSTR_LEN(s)) + 1);
	if (!ZSTR_IS_INTERNED(s)) {
		GC_REFCOUNT(s)--;
	}
	return ret;
}

static zend_always_inline zend_string *zend_string_extend(zend_string *s, size_t len, int persistent)
{
	zend_string *ret;

	ZEND_ASSERT(len >= ZSTR_LEN(s));
	if (!ZSTR_IS_INTERNED(s)) {
		if (EXPECTED(GC_REFCOUNT(s) == 1)) {
			ret = (zend_string *)perealloc(s, ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(len)), persistent);
			ZSTR_LEN(ret) = len;
			zend_string_forget_hash_val(ret);
			return ret;
		}
	}
	ret = zend_string_alloc(len, persistent);
	memcpy(ZSTR_VAL(ret), ZSTR_VAL(s), ZSTR_LEN(s) + 1);
	if (!ZSTR_IS_INTERNED(s)) {
		GC_REFCOUNT(s)--;
	}
	return ret;
}

static zend_always_inline zend_string *zend_string_truncate(zend_string *s, size_t len, int persistent)
{
	zend_string *ret;

	ZEND_ASSERT(len <= ZSTR_LEN(s));
	if (!ZSTR_IS_INTERNED(s)) {
		if (EXPECTED(GC_REFCOUNT(s) == 1)) {
			ret = (zend_string *)perealloc(s, ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(len)), persistent);
			ZSTR_LEN(ret) = len;
			zend_string_forget_hash_val(ret);
			return ret;
		}
	}
	ret = zend_string_alloc(len, persistent);
	memcpy(ZSTR_VAL(ret), ZSTR_VAL(s), len + 1);
	if (!ZSTR_IS_INTERNED(s)) {
		GC_REFCOUNT(s)--;
	}
	return ret;
}

static zend_always_inline zend_string *zend_string_safe_realloc(zend_string *s, size_t n, size_t m, size_t l, int persistent)
{
	zend_string *ret;

	if (!ZSTR_IS_INTERNED(s)) {
		if (GC_REFCOUNT(s) == 1) {
			ret = (zend_string *)safe_perealloc(s, n, m, ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(l)), persistent);
			ZSTR_LEN(ret) = (n * m) + l;
			zend_string_forget_hash_val(ret);
			return ret;
		}
	}
	ret = zend_string_safe_alloc(n, m, l, persistent);
	memcpy(ZSTR_VAL(ret), ZSTR_VAL(s), MIN((n * m) + l, ZSTR_LEN(s)) + 1);
	if (!ZSTR_IS_INTERNED(s)) {
		GC_REFCOUNT(s)--;
	}
	return ret;
}

static zend_always_inline void zend_string_free(zend_string *s)
{
	if (!ZSTR_IS_INTERNED(s)) {
		ZEND_ASSERT(GC_REFCOUNT(s) <= 1);
		pefree(s, GC_FLAGS(s) & IS_STR_PERSISTENT);
	}
}

static zend_always_inline void zend_string_release(zend_string *s)
{
	if (!ZSTR_IS_INTERNED(s)) {
		if (--GC_REFCOUNT(s) == 0) {
			pefree(s, GC_FLAGS(s) & IS_STR_PERSISTENT);
		}
	}
}


static zend_always_inline zend_bool zend_string_equals(zend_string *s1, zend_string *s2)
{
	return s1 == s2 || (ZSTR_LEN(s1) == ZSTR_LEN(s2) && !memcmp(ZSTR_VAL(s1), ZSTR_VAL(s2), ZSTR_LEN(s1)));
}

#define zend_string_equals_ci(s1, s2) \
	(ZSTR_LEN(s1) == ZSTR_LEN(s2) && !zend_binary_strcasecmp(ZSTR_VAL(s1), ZSTR_LEN(s1), ZSTR_VAL(s2), ZSTR_LEN(s2)))

#define zend_string_equals_literal_ci(str, c) \
	(ZSTR_LEN(str) == sizeof(c) - 1 && !zend_binary_strcasecmp(ZSTR_VAL(str), ZSTR_LEN(str), (c), sizeof(c) - 1))

#define zend_string_equals_literal(str, literal) \
	(ZSTR_LEN(str) == sizeof(literal)-1 && !memcmp(ZSTR_VAL(str), literal, sizeof(literal) - 1))

/*
 * DJBX33A (Daniel J. Bernstein, Times 33 with Addition)
 *
 * This is Daniel J. Bernstein's popular `times 33' hash function as
 * posted by him years ago on comp.lang.c. It basically uses a function
 * like ``hash(i) = hash(i-1) * 33 + str[i]''. This is one of the best
 * known hash functions for strings. Because it is both computed very
 * fast and distributes very well.
 *
 * The magic of number 33, i.e. why it works better than many other
 * constants, prime or not, has never been adequately explained by
 * anyone. So I try an explanation: if one experimentally tests all
 * multipliers between 1 and 256 (as RSE did now) one detects that even
 * numbers are not useable at all. The remaining 128 odd numbers
 * (except for the number 1) work more or less all equally well. They
 * all distribute in an acceptable way and this way fill a hash table
 * with an average percent of approx. 86%.
 *
 * If one compares the Chi^2 values of the variants, the number 33 not
 * even has the best value. But the number 33 and a few other equally
 * good numbers like 17, 31, 63, 127 and 129 have nevertheless a great
 * advantage to the remaining numbers in the large set of possible
 * multipliers: their multiply operation can be replaced by a faster
 * operation based on just one shift plus either a single addition
 * or subtraction operation. And because a hash function has to both
 * distribute good _and_ has to be very fast to compute, those few
 * numbers should be preferred and seems to be the reason why Daniel J.
 * Bernstein also preferred it.
 *
 *
 *                  -- Ralf S. Engelschall <rse@engelschall.com>
 */

static zend_always_inline zend_ulong zend_inline_hash_func(const char *str, size_t len)
{
	zend_ulong hash = Z_UL(5381);

	/* variant with the hash unrolled eight times */
	for (; len >= 8; len -= 8) {
		hash = ((hash << 5) + hash) + *str++;
		hash = ((hash << 5) + hash) + *str++;
		hash = ((hash << 5) + hash) + *str++;
		hash = ((hash << 5) + hash) + *str++;
		hash = ((hash << 5) + hash) + *str++;
		hash = ((hash << 5) + hash) + *str++;
		hash = ((hash << 5) + hash) + *str++;
		hash = ((hash << 5) + hash) + *str++;
	}
	switch (len) {
		case 7: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
		case 6: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
		case 5: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
		case 4: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
		case 3: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
		case 2: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
		case 1: hash = ((hash << 5) + hash) + *str++; break;
		case 0: break;
EMPTY_SWITCH_DEFAULT_CASE()
	}

	/* Hash value can't be zero, so we always set the high bit */
#if SIZEOF_ZEND_LONG == 8
	return hash | Z_UL(0x8000000000000000);
#elif SIZEOF_ZEND_LONG == 4
	return hash | Z_UL(0x80000000);
#else
# error "Unknown SIZEOF_ZEND_LONG"
#endif
}

#define ZEND_KNOWN_STRINGS(_) \
	_(ZEND_STR_FILE,                   "file") \
	_(ZEND_STR_LINE,                   "line") \
	_(ZEND_STR_FUNCTION,               "function") \
	_(ZEND_STR_CLASS,                  "class") \
	_(ZEND_STR_OBJECT,                 "object") \
	_(ZEND_STR_TYPE,                   "type") \
	_(ZEND_STR_OBJECT_OPERATOR,        "->") \
	_(ZEND_STR_PAAMAYIM_NEKUDOTAYIM,   "::") \
	_(ZEND_STR_ARGS,                   "args") \
	_(ZEND_STR_UNKNOWN,                "unknown") \
	_(ZEND_STR_EVAL,                   "eval") \
	_(ZEND_STR_INCLUDE,                "include") \
	_(ZEND_STR_REQUIRE,                "require") \
	_(ZEND_STR_INCLUDE_ONCE,           "include_once") \
	_(ZEND_STR_REQUIRE_ONCE,           "require_once") \
	_(ZEND_STR_SCALAR,                 "scalar") \
	_(ZEND_STR_ERROR_REPORTING,        "error_reporting") \
	_(ZEND_STR_STATIC,                 "static") \
	_(ZEND_STR_THIS,                   "this") \
	_(ZEND_STR_VALUE,                  "value") \
	_(ZEND_STR_KEY,                    "key") \
	_(ZEND_STR_MAGIC_AUTOLOAD,         "__autoload") \
	_(ZEND_STR_MAGIC_INVOKE,           "__invoke") \
	_(ZEND_STR_PREVIOUS,               "previous") \
	_(ZEND_STR_CODE,                   "code") \
	_(ZEND_STR_MESSAGE,                "message") \
	_(ZEND_STR_SEVERITY,               "severity") \
	_(ZEND_STR_STRING,                 "string") \
	_(ZEND_STR_TRACE,                  "trace") \
	_(ZEND_STR_SCHEME,                 "scheme") \
	_(ZEND_STR_HOST,                   "host") \
	_(ZEND_STR_PORT,                   "port") \
	_(ZEND_STR_USER,                   "user") \
	_(ZEND_STR_PASS,                   "pass") \
	_(ZEND_STR_PATH,                   "path") \
	_(ZEND_STR_QUERY,                  "query") \
	_(ZEND_STR_FRAGMENT,               "fragment") \
	_(ZEND_STR_NULL,                   "NULL") \
	_(ZEND_STR_BOOLEAN,                "boolean") \
	_(ZEND_STR_INTEGER,                "integer") \
	_(ZEND_STR_DOUBLE,                 "double") \
	_(ZEND_STR_ARRAY,                  "array") \
	_(ZEND_STR_RESOURCE,               "resource") \
	_(ZEND_STR_CLOSED_RESOURCE,        "resource (closed)") \


typedef enum _zend_known_string_id {
#define _ZEND_STR_ID(id, str) id,
ZEND_KNOWN_STRINGS(_ZEND_STR_ID)
#undef _ZEND_STR_ID
	ZEND_STR_LAST_KNOWN
} zend_known_string_id;

#endif /* ZEND_STRING_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/Zend/zend_stream.h000064400000004757151730541510010736 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        | 
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Wez Furlong <wez@thebrainroom.com>                          |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_stream.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef ZEND_STREAM_H
#define ZEND_STREAM_H

/* Lightweight stream implementation for the ZE scanners.
 * These functions are private to the engine.
 * */

typedef size_t (*zend_stream_reader_t)(void *handle, char *buf, size_t len TSRMLS_DC);
typedef void (*zend_stream_closer_t)(void *handle TSRMLS_DC);
typedef long (*zend_stream_fteller_t)(void *handle TSRMLS_DC);

typedef struct _zend_stream {
	void *handle;
	zend_stream_reader_t reader;
	zend_stream_closer_t closer;
	zend_stream_fteller_t fteller;
	int interactive;
} zend_stream;

typedef struct _zend_file_handle {
	zend_uchar type;
	char *filename;
	char *opened_path;
	union {
		int fd;
		FILE *fp;
		zend_stream stream;
	} handle;
	zend_bool free_filename;
} zend_file_handle;

BEGIN_EXTERN_C()
ZEND_API int zend_stream_open(const char *filename, zend_file_handle *handle TSRMLS_DC);
ZEND_API int zend_stream_ferror(zend_file_handle *file_handle TSRMLS_DC);
ZEND_API int zend_stream_getc(zend_file_handle *file_handle TSRMLS_DC);
ZEND_API size_t zend_stream_read(zend_file_handle *file_handle, char *buf, size_t len TSRMLS_DC);
ZEND_API long zend_stream_ftell(zend_file_handle *file_handle TSRMLS_DC);
ZEND_API int zend_stream_fixup(zend_file_handle *file_handle TSRMLS_DC);
END_EXTERN_C()

#define zend_stream_close(handle)	zend_file_handle_dtor((handle))

#endif

php/Zend/zend_smart_str.h000064400000012207151730541520011447 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 7                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2018 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Sascha Schumann <sascha@schumann.cx>                         |
   +----------------------------------------------------------------------+
 */

#ifndef ZEND_SMART_STR_H
#define ZEND_SMART_STR_H

#include <zend.h>
#include "zend_globals.h"
#include "zend_smart_str_public.h"

#define smart_str_appends_ex(dest, src, what) \
	smart_str_appendl_ex((dest), (src), strlen(src), (what))
#define smart_str_appends(dest, src) \
	smart_str_appendl((dest), (src), strlen(src))
#define smart_str_appendc(dest, c) \
	smart_str_appendc_ex((dest), (c), 0)
#define smart_str_appendl(dest, src, len) \
	smart_str_appendl_ex((dest), (src), (len), 0)
#define smart_str_append(dest, src) \
	smart_str_append_ex((dest), (src), 0)
#define smart_str_append_smart_str(dest, src) \
	smart_str_append_smart_str_ex((dest), (src), 0)
#define smart_str_sets(dest, src) \
	smart_str_setl((dest), (src), strlen(src));
#define smart_str_append_long(dest, val) \
	smart_str_append_long_ex((dest), (val), 0)
#define smart_str_append_unsigned(dest, val) \
	smart_str_append_unsigned_ex((dest), (val), 0)

BEGIN_EXTERN_C()

ZEND_API void ZEND_FASTCALL smart_str_erealloc(smart_str *str, size_t len);
ZEND_API void ZEND_FASTCALL smart_str_realloc(smart_str *str, size_t len);
ZEND_API void ZEND_FASTCALL smart_str_append_escaped(smart_str *str, const char *s, size_t l);
ZEND_API void ZEND_FASTCALL smart_str_append_printf(smart_str *dest, const char *format, ...)
	ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);

END_EXTERN_C()

static zend_always_inline size_t smart_str_alloc(smart_str *str, size_t len, zend_bool persistent) {
	if (UNEXPECTED(!str->s)) {
		goto do_smart_str_realloc;
	} else {
		len += ZSTR_LEN(str->s);
		if (UNEXPECTED(len >= str->a)) {
do_smart_str_realloc:
			if (persistent) {
				smart_str_realloc(str, len);
			} else {
				smart_str_erealloc(str, len);
			}
		}
	}
	return len;
}

static zend_always_inline void smart_str_free(smart_str *str) {
	if (str->s) {
		zend_string_release(str->s);
		str->s = NULL;
	}
	str->a = 0;
}

static zend_always_inline void smart_str_0(smart_str *str) {
	if (str->s) {
		ZSTR_VAL(str->s)[ZSTR_LEN(str->s)] = '\0';
	}
}

static zend_always_inline size_t smart_str_get_len(smart_str *str) {
	return str->s ? ZSTR_LEN(str->s) : 0;
}

static zend_always_inline zend_string *smart_str_extract(smart_str *str) {
	if (str->s) {
		zend_string *res;
		smart_str_0(str);
		res = str->s;
		str->s = NULL;
		return res;
	} else {
		return ZSTR_EMPTY_ALLOC();
	}
}

static zend_always_inline void smart_str_appendc_ex(smart_str *dest, char ch, zend_bool persistent) {
	size_t new_len = smart_str_alloc(dest, 1, persistent);
	ZSTR_VAL(dest->s)[new_len - 1] = ch;
	ZSTR_LEN(dest->s) = new_len;
}

static zend_always_inline void smart_str_appendl_ex(smart_str *dest, const char *str, size_t len, zend_bool persistent) {
	size_t new_len = smart_str_alloc(dest, len, persistent);
	memcpy(ZSTR_VAL(dest->s) + ZSTR_LEN(dest->s), str, len);
	ZSTR_LEN(dest->s) = new_len;
}

static zend_always_inline void smart_str_append_ex(smart_str *dest, const zend_string *src, zend_bool persistent) {
	smart_str_appendl_ex(dest, ZSTR_VAL(src), ZSTR_LEN(src), persistent);
}

static zend_always_inline void smart_str_append_smart_str_ex(smart_str *dest, const smart_str *src, zend_bool persistent) {
	if (src->s && ZSTR_LEN(src->s)) {
		smart_str_append_ex(dest, src->s, persistent);
	}
}

static zend_always_inline void smart_str_append_long_ex(smart_str *dest, zend_long num, zend_bool persistent) {
	char buf[32];
	char *result = zend_print_long_to_buf(buf + sizeof(buf) - 1, num);
	smart_str_appendl_ex(dest, result, buf + sizeof(buf) - 1 - result, persistent);
}

static zend_always_inline void smart_str_append_unsigned_ex(smart_str *dest, zend_ulong num, zend_bool persistent) {
	char buf[32];
	char *result = zend_print_ulong_to_buf(buf + sizeof(buf) - 1, num);
	smart_str_appendl_ex(dest, result, buf + sizeof(buf) - 1 - result, persistent);
}

static zend_always_inline void smart_str_setl(smart_str *dest, const char *src, size_t len) {
	smart_str_free(dest);
	smart_str_appendl(dest, src, len);
}

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/Zend/zend_language_scanner.h000064400000004471151730541530012732 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        | 
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_language_scanner.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef ZEND_SCANNER_H
#define ZEND_SCANNER_H

typedef struct _zend_lex_state {
	YY_BUFFER_STATE buffer_state;
	int state;
	zend_file_handle *in;
	uint lineno;
	char *filename;

#ifdef ZEND_MULTIBYTE
	/* original (unfiltered) script */
	char *script_org;
	int script_org_size;

	/* filtered script */
	char *script_filtered;
	int script_filtered_size;

	/* input/ouput filters */
	zend_encoding_filter input_filter;
	zend_encoding_filter output_filter;
	zend_encoding *script_encoding;
	zend_encoding *internal_encoding;
#endif /* ZEND_MULTIBYTE */
} zend_lex_state;


void zend_fatal_scanner_error(char *);
BEGIN_EXTERN_C()
int zend_compare_file_handles(zend_file_handle *fh1, zend_file_handle *fh2);
ZEND_API void zend_save_lexical_state(zend_lex_state *lex_state TSRMLS_DC);
ZEND_API void zend_restore_lexical_state(zend_lex_state *lex_state TSRMLS_DC);
ZEND_API int zend_prepare_string_for_scanning(zval *str, char *filename TSRMLS_DC);

END_EXTERN_C()

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_inheritance.h000064400000003730151730541530011724 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2018 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

#ifndef ZEND_INHERITANCE_H
#define ZEND_INHERITANCE_H

#include "zend.h"

BEGIN_EXTERN_C()

ZEND_API void zend_do_inherit_interfaces(zend_class_entry *ce, const zend_class_entry *iface);
ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry *iface);

ZEND_API void zend_do_implement_trait(zend_class_entry *ce, zend_class_entry *trait);
ZEND_API void zend_do_bind_traits(zend_class_entry *ce);

ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent_ce);
void zend_do_early_binding(void);

void zend_check_deprecated_constructor(const zend_class_entry *ce);

END_EXTERN_C()

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/Zend/zend_portability.h000064400000035744151730541540012010 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2018 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   |          Dmitry Stogov <zeev@zend.com>                               |
   +----------------------------------------------------------------------+
*/

/* $Id$ */

#ifndef ZEND_PORTABILITY_H
#define ZEND_PORTABILITY_H

#ifdef __cplusplus
#define BEGIN_EXTERN_C() extern "C" {
#define END_EXTERN_C() }
#else
#define BEGIN_EXTERN_C()
#define END_EXTERN_C()
#endif

/*
 * general definitions
 */

#ifdef ZEND_WIN32
# include "zend_config.w32.h"
# define ZEND_PATHS_SEPARATOR		';'
#elif defined(__riscos__)
# include <zend_config.h>
# define ZEND_PATHS_SEPARATOR		';'
#else
# include <zend_config.h>
# define ZEND_PATHS_SEPARATOR		':'
#endif

#include "../TSRM/TSRM.h"

#include <stdio.h>
#include <assert.h>
#include <math.h>

#ifdef HAVE_UNIX_H
# include <unix.h>
#endif

#ifdef HAVE_STDARG_H
# include <stdarg.h>
#endif

#ifdef HAVE_DLFCN_H
# include <dlfcn.h>
#endif

#ifdef HAVE_LIMITS_H
# include <limits.h>
#endif

#if HAVE_ALLOCA_H && !defined(_ALLOCA_H)
# include <alloca.h>
#endif

#if defined(ZEND_WIN32)
#include <intrin.h>
#endif

#include "zend_range_check.h"

/* GCC x.y.z supplies __GNUC__ = x and __GNUC_MINOR__ = y */
#ifdef __GNUC__
# define ZEND_GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
#else
# define ZEND_GCC_VERSION 0
#endif

/* Compatibility with non-clang compilers */
#ifndef __has_attribute
# define __has_attribute(x) 0
#endif
#ifndef __has_builtin
# define __has_builtin(x) 0
#endif

#if defined(ZEND_WIN32) && !defined(__clang__)
# define ZEND_ASSUME(c)	__assume(c)
#elif ((defined(__GNUC__) && ZEND_GCC_VERSION >= 4005) || __has_builtin(__builtin_unreachable)) && PHP_HAVE_BUILTIN_EXPECT
# define ZEND_ASSUME(c)	do { \
		if (__builtin_expect(!(c), 0)) __builtin_unreachable(); \
	} while (0)
#else
# define ZEND_ASSUME(c)
#endif

#if ZEND_DEBUG
# define ZEND_ASSERT(c)	assert(c)
#else
# define ZEND_ASSERT(c) ZEND_ASSUME(c)
#endif

/* Only use this macro if you know for sure that all of the switches values
   are covered by its case statements */
#if ZEND_DEBUG
# define EMPTY_SWITCH_DEFAULT_CASE() default: ZEND_ASSERT(0); break;
#else
# define EMPTY_SWITCH_DEFAULT_CASE() default: ZEND_ASSUME(0); break;
#endif

#if defined(__GNUC__) && __GNUC__ >= 4
# define ZEND_IGNORE_VALUE(x) (({ __typeof__ (x) __x = (x); (void) __x; }))
#else
# define ZEND_IGNORE_VALUE(x) ((void) (x))
#endif

#define zend_quiet_write(...) ZEND_IGNORE_VALUE(write(__VA_ARGS__))

/* all HAVE_XXX test have to be after the include of zend_config above */

#if defined(HAVE_LIBDL) && !defined(ZEND_WIN32)

# if defined(__has_feature)
#  if __has_feature(address_sanitizer)
#   define __SANITIZE_ADDRESS__
#  endif
# endif

# ifndef RTLD_LAZY
#  define RTLD_LAZY 1    /* Solaris 1, FreeBSD's (2.1.7.1 and older) */
# endif

# ifndef RTLD_GLOBAL
#  define RTLD_GLOBAL 0
# endif

# if defined(RTLD_GROUP) && defined(RTLD_WORLD) && defined(RTLD_PARENT)
#  define DL_LOAD(libname)			dlopen(libname, RTLD_LAZY | RTLD_GLOBAL | RTLD_GROUP | RTLD_WORLD | RTLD_PARENT)
# elif defined(RTLD_DEEPBIND) && !defined(__SANITIZE_ADDRESS__)
#  define DL_LOAD(libname)			dlopen(libname, RTLD_LAZY | RTLD_GLOBAL | RTLD_DEEPBIND)
# else
#  define DL_LOAD(libname)			dlopen(libname, RTLD_LAZY | RTLD_GLOBAL)
# endif
# define DL_UNLOAD					dlclose
# if defined(DLSYM_NEEDS_UNDERSCORE)
#  define DL_FETCH_SYMBOL(h,s)		dlsym((h), "_" s)
# else
#  define DL_FETCH_SYMBOL			dlsym
# endif
# define DL_ERROR					dlerror
# define DL_HANDLE					void *
# define ZEND_EXTENSIONS_SUPPORT	1
#elif defined(ZEND_WIN32)
# define DL_LOAD(libname)			LoadLibrary(libname)
# define DL_FETCH_SYMBOL			GetProcAddress
# define DL_UNLOAD					FreeLibrary
# define DL_HANDLE					HMODULE
# define ZEND_EXTENSIONS_SUPPORT	1
#else
# define DL_HANDLE					void *
# define ZEND_EXTENSIONS_SUPPORT	0
#endif

/* AIX requires this to be the first thing in the file.  */
#ifndef __GNUC__
# ifndef HAVE_ALLOCA_H
#  ifdef _AIX
#   pragma alloca
#  else
#   ifndef alloca /* predefined by HP cc +Olibcalls */
char *alloca();
#   endif
#  endif
# endif
#endif

#if ZEND_GCC_VERSION >= 2096 || __has_attribute(__malloc__)
# define ZEND_ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
#else
# define ZEND_ATTRIBUTE_MALLOC
#endif

#if ZEND_GCC_VERSION >= 4003 || __has_attribute(alloc_size)
# define ZEND_ATTRIBUTE_ALLOC_SIZE(X) __attribute__ ((alloc_size(X)))
# define ZEND_ATTRIBUTE_ALLOC_SIZE2(X,Y) __attribute__ ((alloc_size(X,Y)))
#else
# define ZEND_ATTRIBUTE_ALLOC_SIZE(X)
# define ZEND_ATTRIBUTE_ALLOC_SIZE2(X,Y)
#endif

/* Format string checks are disabled by default, because we use custom format modifiers (like %p),
 * which cause a large amount of false positives. You can enable format checks by adding
 * -DZEND_CHECK_FORMAT_STRINGS to CFLAGS. */

#if defined(ZEND_CHECK_FORMAT_STRINGS) && (ZEND_GCC_VERSION >= 2007 || __has_attribute(format))
# define ZEND_ATTRIBUTE_FORMAT(type, idx, first) __attribute__ ((format(type, idx, first)))
#else
# define ZEND_ATTRIBUTE_FORMAT(type, idx, first)
#endif

#if defined(ZEND_CHECK_FORMAT_STRINGS) && ((ZEND_GCC_VERSION >= 3001 && !defined(__INTEL_COMPILER)) || __has_attribute(format))
# define ZEND_ATTRIBUTE_PTR_FORMAT(type, idx, first) __attribute__ ((format(type, idx, first)))
#else
# define ZEND_ATTRIBUTE_PTR_FORMAT(type, idx, first)
#endif

#if ZEND_GCC_VERSION >= 3001 || __has_attribute(deprecated)
# define ZEND_ATTRIBUTE_DEPRECATED  __attribute__((deprecated))
#elif defined(ZEND_WIN32)
# define ZEND_ATTRIBUTE_DEPRECATED  __declspec(deprecated)
#else
# define ZEND_ATTRIBUTE_DEPRECATED
#endif

#if defined(__GNUC__) && ZEND_GCC_VERSION >= 4003
# define ZEND_ATTRIBUTE_UNUSED __attribute__((unused))
# define ZEND_ATTRIBUTE_UNUSED_LABEL __attribute__((cold, unused));
# define ZEND_COLD __attribute__((cold))
# define ZEND_HOT __attribute__((hot))
#else
# define ZEND_ATTRIBUTE_UNUSED
# define ZEND_ATTRIBUTE_UNUSED_LABEL
# define ZEND_COLD
# define ZEND_HOT
#endif

#if defined(__GNUC__) && ZEND_GCC_VERSION >= 3004 && defined(__i386__)
# define ZEND_FASTCALL __attribute__((fastcall))
#elif defined(_MSC_VER) && defined(_M_IX86) && _MSC_VER == 1700
# define ZEND_FASTCALL __fastcall
#elif defined(_MSC_VER) && _MSC_VER >= 1800 && !defined(__clang__)
# define ZEND_FASTCALL __vectorcall
#else
# define ZEND_FASTCALL
#endif

#ifndef restrict
# if defined(__GNUC__) && ZEND_GCC_VERSION >= 3004
# else
#  define __restrict__
# endif
# define restrict __restrict__
#endif

#if (defined(__GNUC__) && __GNUC__ >= 3 && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX) && !defined(__osf__)) || __has_attribute(noreturn)
# define HAVE_NORETURN
# define ZEND_NORETURN __attribute__((noreturn))
#elif defined(ZEND_WIN32)
# define HAVE_NORETURN
# define ZEND_NORETURN __declspec(noreturn)
#else
# define ZEND_NORETURN
#endif

#if (defined(__GNUC__) && __GNUC__ >= 3 && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX) && !defined(__osf__))
# define HAVE_NORETURN_ALIAS
# define HAVE_ATTRIBUTE_WEAK
#endif

#if ZEND_GCC_VERSION >= 3001 || __has_builtin(__builtin_constant_p)
# define HAVE_BUILTIN_CONSTANT_P
#endif

#ifdef HAVE_BUILTIN_CONSTANT_P
# define ZEND_CONST_COND(_condition, _default) \
	(__builtin_constant_p(_condition) ? (_condition) : (_default))
#else
# define ZEND_CONST_COND(_condition, _default) \
	(_default)
#endif

#if ZEND_DEBUG
# define zend_always_inline inline
# define zend_never_inline
#else
# if defined(__GNUC__)
#  if __GNUC__ >= 3
#   define zend_always_inline inline __attribute__((always_inline))
#   define zend_never_inline __attribute__((noinline))
#  else
#   define zend_always_inline inline
#   define zend_never_inline
#  endif
# elif defined(_MSC_VER)
#  define zend_always_inline __forceinline
#  define zend_never_inline __declspec(noinline)
# else
#  if __has_attribute(always_inline)
#   define zend_always_inline inline __attribute__((always_inline))
#  else
#   define zend_always_inline inline
#  endif
#  if __has_attribute(noinline)
#   define zend_never_inline __attribute__((noinline))
#  else
#   define zend_never_inline
#  endif
# endif
#endif /* ZEND_DEBUG */

#if PHP_HAVE_BUILTIN_EXPECT
# define EXPECTED(condition)   __builtin_expect(!!(condition), 1)
# define UNEXPECTED(condition) __builtin_expect(!!(condition), 0)
#else
# define EXPECTED(condition)   (condition)
# define UNEXPECTED(condition) (condition)
#endif

#ifndef XtOffsetOf
# if defined(CRAY) || (defined(__ARMCC_VERSION) && !defined(LINUX))
# ifdef __STDC__
# define XtOffset(p_type, field) _Offsetof(p_type, field)
# else
# ifdef CRAY2
# define XtOffset(p_type, field) \
    (sizeof(int)*((unsigned int)&(((p_type)NULL)->field)))

# else /* !CRAY2 */

# define XtOffset(p_type, field) ((unsigned int)&(((p_type)NULL)->field))

# endif /* !CRAY2 */
# endif /* __STDC__ */
# else /* ! (CRAY || __arm) */

# define XtOffset(p_type, field) \
    ((zend_long) (((char *) (&(((p_type)NULL)->field))) - ((char *) NULL)))

# endif /* !CRAY */

# ifdef offsetof
# define XtOffsetOf(s_type, field) offsetof(s_type, field)
# else
# define XtOffsetOf(s_type, field) XtOffset(s_type*, field)
# endif

#endif

#if (HAVE_ALLOCA || (defined (__GNUC__) && __GNUC__ >= 2)) && !(defined(ZTS)) && !(defined(ZTS) && defined(HPUX)) && !defined(DARWIN)
# define ZEND_ALLOCA_MAX_SIZE (32 * 1024)
# define ALLOCA_FLAG(name) \
	zend_bool name;
# define SET_ALLOCA_FLAG(name) \
	name = 1
# define do_alloca_ex(size, limit, use_heap) \
	((use_heap = (UNEXPECTED((size) > (limit)))) ? emalloc(size) : alloca(size))
# define do_alloca(size, use_heap) \
	do_alloca_ex(size, ZEND_ALLOCA_MAX_SIZE, use_heap)
# define free_alloca(p, use_heap) \
	do { if (UNEXPECTED(use_heap)) efree(p); } while (0)
#else
# define ALLOCA_FLAG(name)
# define SET_ALLOCA_FLAG(name)
# define do_alloca(p, use_heap)		emalloc(p)
# define free_alloca(p, use_heap)	efree(p)
#endif

#ifdef HAVE_SIGSETJMP
# define SETJMP(a) sigsetjmp(a, 0)
# define LONGJMP(a,b) siglongjmp(a, b)
# define JMP_BUF sigjmp_buf
#else
# define SETJMP(a) setjmp(a)
# define LONGJMP(a,b) longjmp(a, b)
# define JMP_BUF jmp_buf
#endif

#if ZEND_DEBUG
# define ZEND_FILE_LINE_D				const char *__zend_filename, const uint32_t __zend_lineno
# define ZEND_FILE_LINE_DC				, ZEND_FILE_LINE_D
# define ZEND_FILE_LINE_ORIG_D			const char *__zend_orig_filename, const uint32_t __zend_orig_lineno
# define ZEND_FILE_LINE_ORIG_DC			, ZEND_FILE_LINE_ORIG_D
# define ZEND_FILE_LINE_RELAY_C			__zend_filename, __zend_lineno
# define ZEND_FILE_LINE_RELAY_CC		, ZEND_FILE_LINE_RELAY_C
# define ZEND_FILE_LINE_C				__FILE__, __LINE__
# define ZEND_FILE_LINE_CC				, ZEND_FILE_LINE_C
# define ZEND_FILE_LINE_EMPTY_C			NULL, 0
# define ZEND_FILE_LINE_EMPTY_CC		, ZEND_FILE_LINE_EMPTY_C
# define ZEND_FILE_LINE_ORIG_RELAY_C	__zend_orig_filename, __zend_orig_lineno
# define ZEND_FILE_LINE_ORIG_RELAY_CC	, ZEND_FILE_LINE_ORIG_RELAY_C
#else
# define ZEND_FILE_LINE_D
# define ZEND_FILE_LINE_DC
# define ZEND_FILE_LINE_ORIG_D
# define ZEND_FILE_LINE_ORIG_DC
# define ZEND_FILE_LINE_RELAY_C
# define ZEND_FILE_LINE_RELAY_CC
# define ZEND_FILE_LINE_C
# define ZEND_FILE_LINE_CC
# define ZEND_FILE_LINE_EMPTY_C
# define ZEND_FILE_LINE_EMPTY_CC
# define ZEND_FILE_LINE_ORIG_RELAY_C
# define ZEND_FILE_LINE_ORIG_RELAY_CC
#endif	/* ZEND_DEBUG */

#if ZEND_DEBUG
# define Z_DBG(expr)		(expr)
#else
# define Z_DBG(expr)
#endif

#ifdef ZTS
# define ZTS_V 1
#else
# define ZTS_V 0
#endif

#ifndef LONG_MAX
# define LONG_MAX 2147483647L
#endif

#ifndef LONG_MIN
# define LONG_MIN (- LONG_MAX - 1)
#endif

#define MAX_LENGTH_OF_DOUBLE 32

#undef MIN
#undef MAX
#define MAX(a, b)  (((a)>(b))?(a):(b))
#define MIN(a, b)  (((a)<(b))?(a):(b))

/* We always define a function, even if there's a macro or expression we could
 * alias, so that using it in contexts where we can't make function calls
 * won't fail to compile on some machines and not others.
 */
static zend_always_inline double _zend_get_inf(void) /* {{{ */
{
#ifdef INFINITY
	return INFINITY;
#elif HAVE_HUGE_VAL_INF
	return HUGE_VAL;
#elif defined(__i386__) || defined(_X86_) || defined(ALPHA) || defined(_ALPHA) || defined(__alpha)
# define _zend_DOUBLE_INFINITY_HIGH       0x7ff00000
	double val = 0.0;
	((uint32_t*)&val)[1] = _zend_DOUBLE_INFINITY_HIGH;
	((uint32_t*)&val)[0] = 0;
	return val;
#elif HAVE_ATOF_ACCEPTS_INF
	return atof("INF");
#else
	return 1.0/0.0;
#endif
} /* }}} */
#define ZEND_INFINITY (_zend_get_inf())

static zend_always_inline double _zend_get_nan(void) /* {{{ */
{
#ifdef NAN
	return NAN;
#elif HAVE_HUGE_VAL_NAN
	return HUGE_VAL + -HUGE_VAL;
#elif defined(__i386__) || defined(_X86_) || defined(ALPHA) || defined(_ALPHA) || defined(__alpha)
# define _zend_DOUBLE_QUIET_NAN_HIGH      0xfff80000
	double val = 0.0;
	((uint32_t*)&val)[1] = _zend_DOUBLE_QUIET_NAN_HIGH;
	((uint32_t*)&val)[0] = 0;
	return val;
#elif HAVE_ATOF_ACCEPTS_NAN
	return atof("NAN");
#else
	return 0.0/0.0;
#endif
} /* }}} */
#define ZEND_NAN (_zend_get_nan())

#define ZEND_STRL(str)		(str), (sizeof(str)-1)
#define ZEND_STRS(str)		(str), (sizeof(str))
#define ZEND_NORMALIZE_BOOL(n)			\
	((n) ? (((n)<0) ? -1 : 1) : 0)
#define ZEND_TRUTH(x)		((x) ? 1 : 0)
#define ZEND_LOG_XOR(a, b)		(ZEND_TRUTH(a) ^ ZEND_TRUTH(b))

#define ZEND_MAX_RESERVED_RESOURCES	6

/* excpt.h on Digital Unix 4.0 defines function_table */
#undef function_table

#ifdef ZEND_WIN32
#define ZEND_SECURE_ZERO(var, size) RtlSecureZeroMemory((var), (size))
#else
#define ZEND_SECURE_ZERO(var, size) explicit_bzero((var), (size))
#endif

/* This check should only be used on network socket, not file descriptors */
#ifdef ZEND_WIN32
#define ZEND_VALID_SOCKET(sock) (INVALID_SOCKET != (sock))
#else
#define ZEND_VALID_SOCKET(sock) ((sock) >= 0)
#endif

/* va_copy() is __va_copy() in old gcc versions.
 * According to the autoconf manual, using
 * memcpy(&dst, &src, sizeof(va_list))
 * gives maximum portability. */
#ifndef va_copy
# ifdef __va_copy
#  define va_copy(dest, src) __va_copy((dest), (src))
# else
#  define va_copy(dest, src) memcpy(&(dest), &(src), sizeof(va_list))
# endif
#endif

#endif /* ZEND_PORTABILITY_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/Zend/zend_globals_macros.h000064400000006175151730541550012432 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_globals_macros.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef ZEND_GLOBALS_MACROS_H
#define ZEND_GLOBALS_MACROS_H

typedef struct _zend_compiler_globals zend_compiler_globals;
typedef struct _zend_executor_globals zend_executor_globals;
typedef struct _zend_scanner_globals zend_scanner_globals;

BEGIN_EXTERN_C()

/* Compiler */
#ifdef ZTS
# define CG(v) TSRMG(compiler_globals_id, zend_compiler_globals *, v)
int zendparse(void *compiler_globals);
#else
# define CG(v) (compiler_globals.v)
extern ZEND_API struct _zend_compiler_globals compiler_globals;
int zendparse(void);
#endif


/* Executor */
#ifdef ZTS
# define EG(v) TSRMG(executor_globals_id, zend_executor_globals *, v)
#else
# define EG(v) (executor_globals.v)
extern ZEND_API zend_executor_globals executor_globals;
#endif

/* Language Scanner */
#ifdef ZTS
# define LANG_SCNG(v) TSRMG(language_scanner_globals_id, zend_scanner_globals *, v)
extern ZEND_API ts_rsrc_id language_scanner_globals_id;
#else
# define LANG_SCNG(v) (language_scanner_globals.v)
extern ZEND_API zend_scanner_globals language_scanner_globals;
#endif


/* INI Scanner */
#ifdef ZTS
# define INI_SCNG(v) TSRMG(ini_scanner_globals_id, zend_scanner_globals *, v)
extern ZEND_API ts_rsrc_id ini_scanner_globals_id;
#else
# define INI_SCNG(v) (ini_scanner_globals.v)
extern ZEND_API zend_scanner_globals ini_scanner_globals;
#endif

END_EXTERN_C()

/* For limited downwards source compatibility */
#define CLS_FETCH()
#define ELS_FETCH()
#define ALS_FETCH()
#define PLS_FETCH()
#define SLS_FETCH()
#define CLS_D
#define ELS_D
#define ALS_D
#define PLS_D
#define SLS_D
#define CLS_DC
#define ELS_DC
#define ALS_DC
#define PLS_DC
#define SLS_DC
#define CLS_C
#define ELS_C
#define ALS_C
#define PLS_C
#define SLS_C
#define CLS_CC
#define ELS_CC
#define ALS_CC
#define PLS_CC
#define SLS_CC


#endif /* ZEND_GLOBALS_MACROS_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_stack.h000064400000004536151730541550010547 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        | 
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_stack.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef ZEND_STACK_H
#define ZEND_STACK_H

typedef struct _zend_stack {
	int top, max;
	void **elements;
} zend_stack;


#define STACK_BLOCK_SIZE 64

BEGIN_EXTERN_C()
ZEND_API int zend_stack_init(zend_stack *stack);
ZEND_API int zend_stack_push(zend_stack *stack, void *element, int size);
ZEND_API int zend_stack_top(zend_stack *stack, void **element);
ZEND_API int zend_stack_del_top(zend_stack *stack);
ZEND_API int zend_stack_int_top(zend_stack *stack);
ZEND_API int zend_stack_is_empty(zend_stack *stack);
ZEND_API int zend_stack_destroy(zend_stack *stack);
ZEND_API void **zend_stack_base(zend_stack *stack);
ZEND_API int zend_stack_count(zend_stack *stack);
ZEND_API void zend_stack_apply(zend_stack *stack, int type, int (*apply_function)(void *element));
ZEND_API void zend_stack_apply_with_argument(zend_stack *stack, int type, int (*apply_function)(void *element, void *arg), void *arg);
END_EXTERN_C()

#define ZEND_STACK_APPLY_TOPDOWN	1
#define ZEND_STACK_APPLY_BOTTOMUP	2

#endif /* ZEND_STACK_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_config.nw.h000064400000004777151730541560011342 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        | 
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_config.nw.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef ZEND_CONFIG_NW_H
#define ZEND_CONFIG_NW_H


#include <string.h>
#include <float.h>

typedef unsigned long ulong;
typedef unsigned int uint;

#define HAVE_ALLOCA 1
#define HAVE_LIMITS_H 1
/* #include <malloc.h> */

#define HAVE_STRING_H 1
#define HAVE_SYS_SELECT_H 1
#define HAVE_STDLIB_H 1
#undef HAVE_KILL
#define HAVE_GETPID 1
/* #define HAVE_ALLOCA_H 1 */
#define HAVE_MEMCPY 1
#define HAVE_STRDUP 1
#define HAVE_SYS_TYPES_H 1
/* #define HAVE_STDIOSTR_H 1 */
#define HAVE_CLASS_ISTDIOSTREAM
#define istdiostream stdiostream
#define HAVE_STDARG_H	1
#define HAVE_DLFCN_H	1
/* #define HAVE_LIBDL 1 */
#define HAVE_SNPRINTF	1
#define HAVE_VSNPRINTF	1

/*
#define snprintf _snprintf
#define vsnprintf _vsnprintf
#define zend_isinf(a)	0
#define zend_finite(x)	_finite(x)
#define zend_isnan(x)	_isnan(x)
*/

#define zend_sprintf sprintf

/* This will cause the compilation process to be MUCH longer, but will generate
 * a much quicker PHP binary
 */
/* 
#undef inline
#ifdef ZEND_WIN32_FORCE_INLINE
# define inline __forceinline
#else
# define inline
#endif
*/

/*
#define zend_finite(A) _finite(A)
#define zend_isnan(A) _isnan(A)
*/

#endif /* ZEND_CONFIG_NW_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_generators.h000064400000016614151730541570011615 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2018 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Nikita Popov <nikic@php.net>                                |
   |          Bob Weinand <bobwei9@hotmail.com>                           |
   +----------------------------------------------------------------------+
*/

/* $Id$ */

#ifndef ZEND_GENERATORS_H
#define ZEND_GENERATORS_H

BEGIN_EXTERN_C()

extern ZEND_API zend_class_entry *zend_ce_generator;
extern ZEND_API zend_class_entry *zend_ce_ClosedGeneratorException;

typedef struct _zend_generator_node zend_generator_node;
typedef struct _zend_generator zend_generator;

/* The concept of `yield from` exposes problems when accessed at different levels of the chain of delegated generators. We need to be able to reference the currently executed Generator in all cases and still being able to access the return values of finished Generators.
 * The solution to this problem is a doubly-linked tree, which all Generators referenced in maintain a reference to. It should be impossible to avoid walking the tree in all cases. This way, we only need tree walks from leaf to root in case where some part of the `yield from` chain is passed to another `yield from`. (Update of leaf node pointer and list of multi-children nodes needed when leaf gets a child in direct path from leaf to root node.) But only in that case, which should be a fairly rare case (which is then possible, but not totally cheap).
 * The root of the tree is then the currently executed Generator. The subnodes of the tree (all except the root node) are all Generators which do `yield from`. Each node of the tree knows a pointer to one leaf descendant node. Each node with multiple children needs a list of all leaf descendant nodes paired with pointers to their respective child node. (The stack is determined by leaf node pointers) Nodes with only one child just don't need a list, there it is enough to just have a pointer to the child node. Further, leaf nodes store a pointer to the root node.
 * That way, when we advance any generator, we just need to look up a leaf node (which all have a reference to a root node). Then we can see at the root node whether current Generator is finished. If it isn't, all is fine and we can just continue. If the Generator finished, there will be two cases. Either it is a simple node with just one child, then go down to child node. Or it has multiple children and we now will remove the current leaf node from the list of nodes (unnecessary, is microoptimization) and go down to the child node whose reference was paired with current leaf node. Child node is then removed its parent reference and becomes new top node. Or the current node references the Generator we're currently executing, then we can continue from the YIELD_FROM opcode. When a node referenced as root node in a leaf node has a parent, then we go the way up until we find a root node without parent.
 * In case we go into a new `yield from` level, a node is created on top of current root and becomes the new root. Leaf node needs to be updated with new root node then.
 * When a Generator referenced by a node of the tree is added to `yield from`, that node now gets a list of children (we need to walk the descendants of that node and nodes of the tree of the other Generator down to the first multi-children node and copy all the leaf node pointers from there). In case there was no multi-children node (linear tree), we just add a pair (pointer to leaf node, pointer to child node), with the child node being in a direct path from leaf to this node.
 */

struct _zend_generator_node {
	zend_generator *parent; /* NULL for root */
	uint32_t children;
	union { /* HashTable / hard coded array for faster access */
		HashTable ht; /* if > 4 children */
		struct {
			zend_generator *leaf;
			zend_generator *child;
		} array[4]; /* if <= 4 children */
	} child;
	union {
		zend_generator *leaf; /* if > 0 children */
		zend_generator *root; /* if 0 children */
	} ptr;
};

struct _zend_generator {
	zend_object std;

	zend_object_iterator *iterator;

	/* The suspended execution context. */
	zend_execute_data *execute_data;

	/* Frozen call stack for "yield" used in context of other calls */
	zend_execute_data *frozen_call_stack;

	/* Current value */
	zval value;
	/* Current key */
	zval key;
	/* Return value */
	zval retval;
	/* Variable to put sent value into */
	zval *send_target;
	/* Largest used integer key for auto-incrementing keys */
	zend_long largest_used_integer_key;

	/* Values specified by "yield from" to yield from this generator.
	 * This is only used for arrays or non-generator Traversables.
	 * This zval also uses the u2 structure in the same way as
	 * by-value foreach. */
	zval values;

	/* Node of waiting generators when multiple "yield from" expressions
	 * are nested. */
	zend_generator_node node;

	/* Fake execute_data for stacktraces */
	zend_execute_data execute_fake;

	/* ZEND_GENERATOR_* flags */
	zend_uchar flags;

	zval *gc_buffer;
	uint32_t gc_buffer_size;
};

static const zend_uchar ZEND_GENERATOR_CURRENTLY_RUNNING = 0x1;
static const zend_uchar ZEND_GENERATOR_FORCED_CLOSE      = 0x2;
static const zend_uchar ZEND_GENERATOR_AT_FIRST_YIELD    = 0x4;
static const zend_uchar ZEND_GENERATOR_DO_INIT           = 0x8;

void zend_register_generator_ce(void);
ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished_execution);
ZEND_API void zend_generator_resume(zend_generator *generator);

ZEND_API void zend_generator_restore_call_stack(zend_generator *generator);
ZEND_API zend_execute_data* zend_generator_freeze_call_stack(zend_execute_data *execute_data);

void zend_generator_yield_from(zend_generator *generator, zend_generator *from);
ZEND_API zend_execute_data *zend_generator_check_placeholder_frame(zend_execute_data *ptr);

ZEND_API zend_generator *zend_generator_update_current(zend_generator *generator, zend_generator *leaf);
static zend_always_inline zend_generator *zend_generator_get_current(zend_generator *generator)
{
	zend_generator *leaf;
	zend_generator *root;

	if (EXPECTED(generator->node.parent == NULL)) {
		/* we're not in yield from mode */
		return generator;
	}

	leaf = generator->node.children ? generator->node.ptr.leaf : generator;
	root = leaf->node.ptr.root;

	if (EXPECTED(root->execute_data && root->node.parent == NULL)) {
		/* generator still running */
		return root;
	}

	return zend_generator_update_current(generator, leaf);
}

END_EXTERN_C()

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/Zend/zend_hash.h000064400000040374151730541570010367 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        | 
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_hash.h 304083 2010-10-05 11:28:56Z dmitry $ */

#ifndef ZEND_HASH_H
#define ZEND_HASH_H

#include <sys/types.h>
#include "zend.h"

#define HASH_KEY_IS_STRING 1
#define HASH_KEY_IS_LONG 2
#define HASH_KEY_NON_EXISTANT 3

#define HASH_UPDATE 		(1<<0)
#define HASH_ADD			(1<<1)
#define HASH_NEXT_INSERT	(1<<2)

#define HASH_DEL_KEY 0
#define HASH_DEL_INDEX 1

typedef ulong (*hash_func_t)(char *arKey, uint nKeyLength);
typedef int  (*compare_func_t)(const void *, const void * TSRMLS_DC);
typedef void (*sort_func_t)(void *, size_t, register size_t, compare_func_t TSRMLS_DC);
typedef void (*dtor_func_t)(void *pDest);
typedef void (*copy_ctor_func_t)(void *pElement);
typedef void (*copy_ctor_param_func_t)(void *pElement, void *pParam);

struct _hashtable;

typedef struct bucket {
	ulong h;						/* Used for numeric indexing */
	uint nKeyLength;
	void *pData;
	void *pDataPtr;
	struct bucket *pListNext;
	struct bucket *pListLast;
	struct bucket *pNext;
	struct bucket *pLast;
	char arKey[1]; /* Must be last element */
} Bucket;

typedef struct _hashtable {
	uint nTableSize;
	uint nTableMask;
	uint nNumOfElements;
	ulong nNextFreeElement;
	Bucket *pInternalPointer;	/* Used for element traversal */
	Bucket *pListHead;
	Bucket *pListTail;
	Bucket **arBuckets;
	dtor_func_t pDestructor;
	zend_bool persistent;
	unsigned char nApplyCount;
	zend_bool bApplyProtection;
#if ZEND_DEBUG
	int inconsistent;
#endif
} HashTable;


typedef struct _zend_hash_key {
	char *arKey;
	uint nKeyLength;
	ulong h;
} zend_hash_key;


typedef zend_bool (*merge_checker_func_t)(HashTable *target_ht, void *source_data, zend_hash_key *hash_key, void *pParam);

typedef Bucket* HashPosition;

BEGIN_EXTERN_C()

/* startup/shutdown */
ZEND_API int _zend_hash_init(HashTable *ht, uint nSize, hash_func_t pHashFunction, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC);
ZEND_API int _zend_hash_init_ex(HashTable *ht, uint nSize, hash_func_t pHashFunction, dtor_func_t pDestructor, zend_bool persistent, zend_bool bApplyProtection ZEND_FILE_LINE_DC);
ZEND_API void zend_hash_destroy(HashTable *ht);
ZEND_API void zend_hash_clean(HashTable *ht);
#define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent)						_zend_hash_init((ht), (nSize), (pHashFunction), (pDestructor), (persistent) ZEND_FILE_LINE_CC)
#define zend_hash_init_ex(ht, nSize, pHashFunction, pDestructor, persistent, bApplyProtection)		_zend_hash_init_ex((ht), (nSize), (pHashFunction), (pDestructor), (persistent), (bApplyProtection) ZEND_FILE_LINE_CC)

/* additions/updates/changes */
ZEND_API int _zend_hash_add_or_update(HashTable *ht, char *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC);
#define zend_hash_update(ht, arKey, nKeyLength, pData, nDataSize, pDest) \
		_zend_hash_add_or_update(ht, arKey, nKeyLength, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)
#define zend_hash_add(ht, arKey, nKeyLength, pData, nDataSize, pDest) \
		_zend_hash_add_or_update(ht, arKey, nKeyLength, pData, nDataSize, pDest, HASH_ADD ZEND_FILE_LINE_CC)

ZEND_API int _zend_hash_quick_add_or_update(HashTable *ht, char *arKey, uint nKeyLength, ulong h, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC);
#define zend_hash_quick_update(ht, arKey, nKeyLength, h, pData, nDataSize, pDest) \
		_zend_hash_quick_add_or_update(ht, arKey, nKeyLength, h, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)
#define zend_hash_quick_add(ht, arKey, nKeyLength, h, pData, nDataSize, pDest) \
		_zend_hash_quick_add_or_update(ht, arKey, nKeyLength, h, pData, nDataSize, pDest, HASH_ADD ZEND_FILE_LINE_CC)

ZEND_API int _zend_hash_index_update_or_next_insert(HashTable *ht, ulong h, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC);
#define zend_hash_index_update(ht, h, pData, nDataSize, pDest) \
		_zend_hash_index_update_or_next_insert(ht, h, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)
#define zend_hash_next_index_insert(ht, pData, nDataSize, pDest) \
		_zend_hash_index_update_or_next_insert(ht, 0, pData, nDataSize, pDest, HASH_NEXT_INSERT ZEND_FILE_LINE_CC)

ZEND_API int zend_hash_add_empty_element(HashTable *ht, char *arKey, uint nKeyLength);


#define ZEND_HASH_APPLY_KEEP				0
#define ZEND_HASH_APPLY_REMOVE				1<<0
#define ZEND_HASH_APPLY_STOP				1<<1


typedef int (*apply_func_t)(void *pDest TSRMLS_DC);
typedef int (*apply_func_arg_t)(void *pDest, void *argument TSRMLS_DC);
typedef int (*apply_func_args_t)(void *pDest, int num_args, va_list args, zend_hash_key *hash_key);

ZEND_API void zend_hash_graceful_destroy(HashTable *ht);
ZEND_API void zend_hash_graceful_reverse_destroy(HashTable *ht);
ZEND_API void zend_hash_apply(HashTable *ht, apply_func_t apply_func TSRMLS_DC);
ZEND_API void zend_hash_apply_with_argument(HashTable *ht, apply_func_arg_t apply_func, void * TSRMLS_DC);
ZEND_API void zend_hash_apply_with_arguments(HashTable *ht, apply_func_args_t apply_func, int, ...);

/* This function should be used with special care (in other words,
 * it should usually not be used).  When used with the ZEND_HASH_APPLY_STOP
 * return value, it assumes things about the order of the elements in the hash.
 * Also, it does not provide the same kind of reentrancy protection that
 * the standard apply functions do.
 */
ZEND_API void zend_hash_reverse_apply(HashTable *ht, apply_func_t apply_func TSRMLS_DC);


/* Deletes */
ZEND_API int zend_hash_del_key_or_index(HashTable *ht, char *arKey, uint nKeyLength, ulong h, int flag);
#define zend_hash_del(ht, arKey, nKeyLength) \
		zend_hash_del_key_or_index(ht, arKey, nKeyLength, 0, HASH_DEL_KEY)
#define zend_hash_index_del(ht, h) \
		zend_hash_del_key_or_index(ht, NULL, 0, h, HASH_DEL_INDEX)

ZEND_API ulong zend_get_hash_value(char *arKey, uint nKeyLength);

/* Data retreival */
ZEND_API int zend_hash_find(HashTable *ht, char *arKey, uint nKeyLength, void **pData);
ZEND_API int zend_hash_quick_find(HashTable *ht, char *arKey, uint nKeyLength, ulong h, void **pData);
ZEND_API int zend_hash_index_find(HashTable *ht, ulong h, void **pData);

/* Misc */
ZEND_API int zend_hash_exists(HashTable *ht, char *arKey, uint nKeyLength);
ZEND_API int zend_hash_quick_exists(HashTable *ht, char *arKey, uint nKeyLength, ulong h);
ZEND_API int zend_hash_index_exists(HashTable *ht, ulong h);
ZEND_API ulong zend_hash_next_free_element(HashTable *ht);


/* traversing */
#define zend_hash_has_more_elements_ex(ht, pos) \
	(zend_hash_get_current_key_type_ex(ht, pos) == HASH_KEY_NON_EXISTANT ? FAILURE : SUCCESS)
ZEND_API int zend_hash_move_forward_ex(HashTable *ht, HashPosition *pos);
ZEND_API int zend_hash_move_backwards_ex(HashTable *ht, HashPosition *pos);
ZEND_API int zend_hash_get_current_key_ex(HashTable *ht, char **str_index, uint *str_length, ulong *num_index, zend_bool duplicate, HashPosition *pos);
ZEND_API int zend_hash_get_current_key_type_ex(HashTable *ht, HashPosition *pos);
ZEND_API int zend_hash_get_current_data_ex(HashTable *ht, void **pData, HashPosition *pos);
ZEND_API void zend_hash_internal_pointer_reset_ex(HashTable *ht, HashPosition *pos);
ZEND_API void zend_hash_internal_pointer_end_ex(HashTable *ht, HashPosition *pos);
ZEND_API int zend_hash_update_current_key_ex(HashTable *ht, int key_type, char *str_index, uint str_length, ulong num_index, HashPosition *pos);

typedef struct _HashPointer {
	HashPosition pos;
	ulong h;
} HashPointer;

ZEND_API int zend_hash_get_pointer(HashTable *ht, HashPointer *ptr);
ZEND_API int zend_hash_set_pointer(HashTable *ht, const HashPointer *ptr);

#define zend_hash_has_more_elements(ht) \
	zend_hash_has_more_elements_ex(ht, NULL)
#define zend_hash_move_forward(ht) \
	zend_hash_move_forward_ex(ht, NULL)
#define zend_hash_move_backwards(ht) \
	zend_hash_move_backwards_ex(ht, NULL)
#define zend_hash_get_current_key(ht, str_index, num_index, duplicate) \
	zend_hash_get_current_key_ex(ht, str_index, NULL, num_index, duplicate, NULL)
#define zend_hash_get_current_key_type(ht) \
	zend_hash_get_current_key_type_ex(ht, NULL)
#define zend_hash_get_current_data(ht, pData) \
	zend_hash_get_current_data_ex(ht, pData, NULL)
#define zend_hash_internal_pointer_reset(ht) \
	zend_hash_internal_pointer_reset_ex(ht, NULL)
#define zend_hash_internal_pointer_end(ht) \
	zend_hash_internal_pointer_end_ex(ht, NULL)
#define zend_hash_update_current_key(ht, key_type, str_index, str_length, num_index) \
	zend_hash_update_current_key_ex(ht, key_type, str_index, str_length, num_index, NULL)

/* Copying, merging and sorting */
ZEND_API void zend_hash_copy(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size);
ZEND_API void _zend_hash_merge(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size, int overwrite ZEND_FILE_LINE_DC);
ZEND_API void zend_hash_merge_ex(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, uint size, merge_checker_func_t pMergeSource, void *pParam);
ZEND_API int zend_hash_sort(HashTable *ht, sort_func_t sort_func, compare_func_t compare_func, int renumber TSRMLS_DC);
ZEND_API int zend_hash_compare(HashTable *ht1, HashTable *ht2, compare_func_t compar, zend_bool ordered TSRMLS_DC);
ZEND_API int zend_hash_minmax(HashTable *ht, compare_func_t compar, int flag, void **pData TSRMLS_DC);

#define zend_hash_merge(target, source, pCopyConstructor, tmp, size, overwrite)					\
	_zend_hash_merge(target, source, pCopyConstructor, tmp, size, overwrite ZEND_FILE_LINE_CC)

ZEND_API int zend_hash_num_elements(HashTable *ht);

ZEND_API int zend_hash_rehash(HashTable *ht);

/*
 * DJBX33A (Daniel J. Bernstein, Times 33 with Addition)
 *
 * This is Daniel J. Bernstein's popular `times 33' hash function as
 * posted by him years ago on comp.lang.c. It basically uses a function
 * like ``hash(i) = hash(i-1) * 33 + str[i]''. This is one of the best
 * known hash functions for strings. Because it is both computed very
 * fast and distributes very well.
 *
 * The magic of number 33, i.e. why it works better than many other
 * constants, prime or not, has never been adequately explained by
 * anyone. So I try an explanation: if one experimentally tests all
 * multipliers between 1 and 256 (as RSE did now) one detects that even
 * numbers are not useable at all. The remaining 128 odd numbers
 * (except for the number 1) work more or less all equally well. They
 * all distribute in an acceptable way and this way fill a hash table
 * with an average percent of approx. 86%. 
 *
 * If one compares the Chi^2 values of the variants, the number 33 not
 * even has the best value. But the number 33 and a few other equally
 * good numbers like 17, 31, 63, 127 and 129 have nevertheless a great
 * advantage to the remaining numbers in the large set of possible
 * multipliers: their multiply operation can be replaced by a faster
 * operation based on just one shift plus either a single addition
 * or subtraction operation. And because a hash function has to both
 * distribute good _and_ has to be very fast to compute, those few
 * numbers should be preferred and seems to be the reason why Daniel J.
 * Bernstein also preferred it.
 *
 *
 *                  -- Ralf S. Engelschall <rse@engelschall.com>
 */

static inline ulong zend_inline_hash_func(char *arKey, uint nKeyLength)
{
	register ulong hash = 5381;

	/* variant with the hash unrolled eight times */
	for (; nKeyLength >= 8; nKeyLength -= 8) {
		hash = ((hash << 5) + hash) + *arKey++;
		hash = ((hash << 5) + hash) + *arKey++;
		hash = ((hash << 5) + hash) + *arKey++;
		hash = ((hash << 5) + hash) + *arKey++;
		hash = ((hash << 5) + hash) + *arKey++;
		hash = ((hash << 5) + hash) + *arKey++;
		hash = ((hash << 5) + hash) + *arKey++;
		hash = ((hash << 5) + hash) + *arKey++;
	}
	switch (nKeyLength) {
		case 7: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
		case 6: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
		case 5: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
		case 4: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
		case 3: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
		case 2: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
		case 1: hash = ((hash << 5) + hash) + *arKey++; break;
		case 0: break;
EMPTY_SWITCH_DEFAULT_CASE()
	}
	return hash;
}


ZEND_API ulong zend_hash_func(char *arKey, uint nKeyLength);

#if ZEND_DEBUG
/* debug */
void zend_hash_display_pListTail(HashTable *ht);
void zend_hash_display(HashTable *ht);
#endif

END_EXTERN_C()

#define ZEND_INIT_SYMTABLE(ht)								\
	ZEND_INIT_SYMTABLE_EX(ht, 2, 0)

#define ZEND_INIT_SYMTABLE_EX(ht, n, persistent)			\
	zend_hash_init(ht, n, NULL, ZVAL_PTR_DTOR, persistent)


#define HANDLE_NUMERIC(key, length, func) do {								\
	register const char *tmp = key;											\
																			\
	if (*tmp == '-') {														\
		tmp++;																\
	}																		\
	if (*tmp >= '0' && *tmp <= '9') { /* possibly a numeric index */		\
		const char *end = key + length - 1;									\
		ulong idx;															\
																			\
		if ((*end != '\0') /* not a null terminated string */				\
		 || (*tmp == '0' && length > 2) /* numbers with leading zeros */	\
		 || (end - tmp > MAX_LENGTH_OF_LONG - 1) /* number too long */		\
		 || (SIZEOF_LONG == 4 &&											\
		     end - tmp == MAX_LENGTH_OF_LONG - 1 &&							\
		     *tmp > '2')) { /* overflow */									\
			break;															\
		}																	\
		idx = (*tmp - '0');													\
		while (++tmp != end && *tmp >= '0' && *tmp <= '9') {				\
			idx = (idx * 10) + (*tmp - '0');								\
		}																	\
		if (tmp == end) {													\
			if (*key == '-') {												\
				if (idx-1 > LONG_MAX) { /* overflow */						\
					break;													\
				}															\
				idx = (ulong)(-(long)idx);									\
			} else if (idx > LONG_MAX) { /* overflow */						\
				break;														\
			}																\
			return func;													\
		}																	\
	}																		\
} while (0)


static inline int zend_symtable_update(HashTable *ht, char *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest)					\
{
	HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_update(ht, idx, pData, nDataSize, pDest));
	return zend_hash_update(ht, arKey, nKeyLength, pData, nDataSize, pDest);
}


static inline int zend_symtable_del(HashTable *ht, char *arKey, uint nKeyLength)
{
	HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_del(ht, idx));
	return zend_hash_del(ht, arKey, nKeyLength);
}


static inline int zend_symtable_find(HashTable *ht, char *arKey, uint nKeyLength, void **pData)
{
	HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_find(ht, idx, pData));
	return zend_hash_find(ht, arKey, nKeyLength, pData);
}


static inline int zend_symtable_exists(HashTable *ht, char *arKey, uint nKeyLength)
{
	HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_exists(ht, idx));
	return zend_hash_exists(ht, arKey, nKeyLength);
}

static inline int zend_symtable_update_current_key(HashTable *ht, char *arKey, uint nKeyLength)
{
	HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_update_current_key(ht, HASH_KEY_IS_LONG, NULL, 0, idx));
	return zend_hash_update_current_key(ht, HASH_KEY_IS_STRING, arKey, nKeyLength, 0);
}

#endif							/* ZEND_HASH_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_ini.h000064400000023030151730541600010203 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Author: Zeev Suraski <zeev@zend.com>                                 |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_ini.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef ZEND_INI_H
#define ZEND_INI_H

#define ZEND_INI_USER	(1<<0)
#define ZEND_INI_PERDIR	(1<<1)
#define ZEND_INI_SYSTEM	(1<<2)

#define ZEND_INI_ALL (ZEND_INI_USER|ZEND_INI_PERDIR|ZEND_INI_SYSTEM)

#ifndef XtOffsetOf
# if defined(CRAY) || (defined(__arm) && !defined(LINUX))
# ifdef __STDC__
# define XtOffset(p_type, field) _Offsetof(p_type, field)
# else
# ifdef CRAY2
# define XtOffset(p_type, field) \
    (sizeof(int)*((unsigned int)&(((p_type)NULL)->field)))

# else /* !CRAY2 */

# define XtOffset(p_type, field) ((unsigned int)&(((p_type)NULL)->field))

# endif /* !CRAY2 */
# endif /* __STDC__ */
# else /* ! (CRAY || __arm) */

# define XtOffset(p_type, field) \
    ((long) (((char *) (&(((p_type)NULL)->field))) - ((char *) NULL)))

# endif /* !CRAY */

# ifdef offsetof
# define XtOffsetOf(s_type, field) offsetof(s_type, field)
# else
# define XtOffsetOf(s_type, field) XtOffset(s_type*, field)
# endif

#endif

typedef struct _zend_ini_entry zend_ini_entry;

#define ZEND_INI_MH(name) int name(zend_ini_entry *entry, char *new_value, uint new_value_length, void *mh_arg1, void *mh_arg2, void *mh_arg3, int stage TSRMLS_DC)
#define ZEND_INI_DISP(name) void name(zend_ini_entry *ini_entry, int type)

struct _zend_ini_entry {
	int module_number;
	int modifiable;
	char *name;
	uint name_length;
	ZEND_INI_MH((*on_modify));
	void *mh_arg1;
	void *mh_arg2;
	void *mh_arg3;

	char *value;
	uint value_length;

	char *orig_value;
	uint orig_value_length;
	int modified;

	void (*displayer)(zend_ini_entry *ini_entry, int type);
};

BEGIN_EXTERN_C()
ZEND_API int zend_ini_startup(TSRMLS_D);
ZEND_API int zend_ini_shutdown(TSRMLS_D);
ZEND_API int zend_ini_global_shutdown(TSRMLS_D);
ZEND_API int zend_ini_deactivate(TSRMLS_D);

ZEND_API int zend_copy_ini_directives(TSRMLS_D);

ZEND_API void zend_ini_sort_entries(TSRMLS_D);

ZEND_API int zend_register_ini_entries(zend_ini_entry *ini_entry, int module_number TSRMLS_DC);
ZEND_API void zend_unregister_ini_entries(int module_number TSRMLS_DC);
ZEND_API void zend_ini_refresh_caches(int stage TSRMLS_DC);
ZEND_API int zend_alter_ini_entry(char *name, uint name_length, char *new_value, uint new_value_length, int modify_type, int stage);
ZEND_API int zend_alter_ini_entry_ex(char *name, uint name_length, char *new_value, uint new_value_length, int modify_type, int stage, int force_change);
ZEND_API int zend_restore_ini_entry(char *name, uint name_length, int stage);
ZEND_API void display_ini_entries(zend_module_entry *module);

ZEND_API long zend_ini_long(char *name, uint name_length, int orig);
ZEND_API double zend_ini_double(char *name, uint name_length, int orig);
ZEND_API char *zend_ini_string(char *name, uint name_length, int orig);

ZEND_API int zend_ini_register_displayer(char *name, uint name_length, void (*displayer)(zend_ini_entry *ini_entry, int type));

ZEND_API ZEND_INI_DISP(zend_ini_boolean_displayer_cb);
ZEND_API ZEND_INI_DISP(zend_ini_color_displayer_cb);
ZEND_API ZEND_INI_DISP(display_link_numbers);
END_EXTERN_C()

#define ZEND_INI_BEGIN()		static zend_ini_entry ini_entries[] = {
#define ZEND_INI_END()		{ 0, 0, NULL, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0, 0, NULL } };

#define ZEND_INI_ENTRY3_EX(name, default_value, modifiable, on_modify, arg1, arg2, arg3, displayer) \
	{ 0, modifiable, name, sizeof(name), on_modify, arg1, arg2, arg3, default_value, sizeof(default_value)-1, NULL, 0, 0, displayer },

#define ZEND_INI_ENTRY3(name, default_value, modifiable, on_modify, arg1, arg2, arg3) \
	ZEND_INI_ENTRY3_EX(name, default_value, modifiable, on_modify, arg1, arg2, arg3, NULL)

#define ZEND_INI_ENTRY2_EX(name, default_value, modifiable, on_modify, arg1, arg2, displayer) \
	ZEND_INI_ENTRY3_EX(name, default_value, modifiable, on_modify, arg1, arg2, NULL, displayer)

#define ZEND_INI_ENTRY2(name, default_value, modifiable, on_modify, arg1, arg2) \
	ZEND_INI_ENTRY2_EX(name, default_value, modifiable, on_modify, arg1, arg2, NULL)

#define ZEND_INI_ENTRY1_EX(name, default_value, modifiable, on_modify, arg1, displayer) \
	ZEND_INI_ENTRY3_EX(name, default_value, modifiable, on_modify, arg1, NULL, NULL, displayer)

#define ZEND_INI_ENTRY1(name, default_value, modifiable, on_modify, arg1) \
	ZEND_INI_ENTRY1_EX(name, default_value, modifiable, on_modify, arg1, NULL)
	
#define ZEND_INI_ENTRY_EX(name, default_value, modifiable, on_modify, displayer) \
	ZEND_INI_ENTRY3_EX(name, default_value, modifiable, on_modify, NULL, NULL, NULL, displayer)

#define ZEND_INI_ENTRY(name, default_value, modifiable, on_modify) \
	ZEND_INI_ENTRY_EX(name, default_value, modifiable, on_modify, NULL)

#ifdef ZTS
#define STD_ZEND_INI_ENTRY(name, default_value, modifiable, on_modify, property_name, struct_type, struct_ptr) \
	ZEND_INI_ENTRY2(name, default_value, modifiable, on_modify, (void *) XtOffsetOf(struct_type, property_name), (void *) &struct_ptr##_id)
#define STD_ZEND_INI_ENTRY_EX(name, default_value, modifiable, on_modify, property_name, struct_type, struct_ptr, displayer) \
	ZEND_INI_ENTRY2_EX(name, default_value, modifiable, on_modify, (void *) XtOffsetOf(struct_type, property_name), (void *) &struct_ptr##_id, displayer)
#define STD_ZEND_INI_BOOLEAN(name, default_value, modifiable, on_modify, property_name, struct_type, struct_ptr) \
	ZEND_INI_ENTRY3_EX(name, default_value, modifiable, on_modify, (void *) XtOffsetOf(struct_type, property_name), (void *) &struct_ptr##_id, NULL, zend_ini_boolean_displayer_cb)
#else
#define STD_ZEND_INI_ENTRY(name, default_value, modifiable, on_modify, property_name, struct_type, struct_ptr) \
	ZEND_INI_ENTRY2(name, default_value, modifiable, on_modify, (void *) XtOffsetOf(struct_type, property_name), (void *) &struct_ptr)
#define STD_ZEND_INI_ENTRY_EX(name, default_value, modifiable, on_modify, property_name, struct_type, struct_ptr, displayer) \
	ZEND_INI_ENTRY2_EX(name, default_value, modifiable, on_modify, (void *) XtOffsetOf(struct_type, property_name), (void *) &struct_ptr, displayer)
#define STD_ZEND_INI_BOOLEAN(name, default_value, modifiable, on_modify, property_name, struct_type, struct_ptr) \
	ZEND_INI_ENTRY3_EX(name, default_value, modifiable, on_modify, (void *) XtOffsetOf(struct_type, property_name), (void *) &struct_ptr, NULL, zend_ini_boolean_displayer_cb)
#endif

#define INI_INT(name) zend_ini_long((name), sizeof(name), 0)
#define INI_FLT(name) zend_ini_double((name), sizeof(name), 0)
#define INI_STR(name) zend_ini_string((name), sizeof(name), 0)
#define INI_BOOL(name) ((zend_bool) INI_INT(name))

#define INI_ORIG_INT(name)	zend_ini_long((name), sizeof(name), 1)
#define INI_ORIG_FLT(name)	zend_ini_double((name), sizeof(name), 1)
#define INI_ORIG_STR(name)	zend_ini_string((name), sizeof(name), 1)
#define INI_ORIG_BOOL(name) ((zend_bool) INI_ORIG_INT(name))


#define REGISTER_INI_ENTRIES() zend_register_ini_entries(ini_entries, module_number TSRMLS_CC)
#define UNREGISTER_INI_ENTRIES() zend_unregister_ini_entries(module_number TSRMLS_CC)
#define DISPLAY_INI_ENTRIES() display_ini_entries(zend_module)

#define REGISTER_INI_DISPLAYER(name, displayer) zend_ini_register_displayer((name), sizeof(name), displayer)
#define REGISTER_INI_BOOLEAN(name) REGISTER_INI_DISPLAYER(name, zend_ini_boolean_displayer_cb)

/* Standard message handlers */
BEGIN_EXTERN_C()
ZEND_API ZEND_INI_MH(OnUpdateBool);
ZEND_API ZEND_INI_MH(OnUpdateLong);
ZEND_API ZEND_INI_MH(OnUpdateLongGEZero);
ZEND_API ZEND_INI_MH(OnUpdateReal);
ZEND_API ZEND_INI_MH(OnUpdateString);
ZEND_API ZEND_INI_MH(OnUpdateStringUnempty);
END_EXTERN_C()

#define ZEND_INI_DISPLAY_ORIG	1
#define ZEND_INI_DISPLAY_ACTIVE	2

#define ZEND_INI_STAGE_STARTUP		(1<<0)
#define ZEND_INI_STAGE_SHUTDOWN		(1<<1)
#define ZEND_INI_STAGE_ACTIVATE		(1<<2)
#define ZEND_INI_STAGE_DEACTIVATE	(1<<3)
#define ZEND_INI_STAGE_RUNTIME		(1<<4)
#define ZEND_INI_STAGE_HTACCESS		(1<<5)

/* INI parsing engine */
typedef void (*zend_ini_parser_cb_t)(zval *arg1, zval *arg2, int callback_type, void *arg);
BEGIN_EXTERN_C()
ZEND_API int zend_parse_ini_file(zend_file_handle *fh, zend_bool unbuffered_errors, zend_ini_parser_cb_t ini_parser_cb, void *arg);
ZEND_API int zend_parse_ini_string(char *str, zend_bool unbuffered_errors, zend_ini_parser_cb_t ini_parser_cb, void *arg);
END_EXTERN_C()

#define ZEND_INI_PARSER_ENTRY	1
#define ZEND_INI_PARSER_SECTION	2
#define ZEND_INI_PARSER_POP_ENTRY	3

typedef struct _zend_ini_parser_param {
	zend_ini_parser_cb_t ini_parser_cb;
	void *arg;
} zend_ini_parser_param;

#endif /* ZEND_INI_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_ini_scanner_defs.h000064400000000340151730541600012714 0ustar00/* Generated by re2c 0.16 */
#line 3 "Zend/zend_ini_scanner_defs.h"

enum YYCONDTYPE {
	yycINITIAL,
	yycST_OFFSET,
	yycST_SECTION_VALUE,
	yycST_VALUE,
	yycST_SECTION_RAW,
	yycST_DOUBLE_QUOTES,
	yycST_VARNAME,
	yycST_RAW,
};
php/Zend/zend_dtrace.h000064400000004065151730541610010676 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2009 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: David Soria Parra <david.soriaparra@sun.com>                |
   +----------------------------------------------------------------------+
*/

/* $Id: $ */

#ifndef	_ZEND_DTRACE_H
#define	_ZEND_DTRACE_H

#ifndef ZEND_WIN32
# include <unistd.h>
#endif

#ifdef	__cplusplus
extern "C" {
#endif

#ifdef HAVE_DTRACE
ZEND_API extern zend_op_array *(*zend_dtrace_compile_file)(zend_file_handle *file_handle, int type);
ZEND_API extern void (*zend_dtrace_execute)(zend_op_array *op_array);
ZEND_API extern void (*zend_dtrace_execute_internal)(zend_execute_data *execute_data, zval *return_value);

ZEND_API zend_op_array *dtrace_compile_file(zend_file_handle *file_handle, int type);
ZEND_API void dtrace_execute_ex(zend_execute_data *execute_data);
ZEND_API void dtrace_execute_internal(zend_execute_data *execute_data, zval *return_value);
#include <zend_dtrace_gen.h>

#endif /* HAVE_DTRACE */

#ifdef	__cplusplus
}
#endif

#endif	/* _ZEND_DTRACE_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/Zend/zend_vm.h000064400000002636151730541620010061 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Dmitry Stogov <dmitry@zend.com>                             |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_vm.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef ZEND_VM_H
#define ZEND_VM_H

ZEND_API void zend_vm_use_old_executor(void);
ZEND_API void zend_vm_set_opcode_handler(zend_op* opcode);

#define ZEND_VM_SET_OPCODE_HANDLER(opline) zend_vm_set_opcode_handler(opline)

#endif
php/Zend/zend_multiply.h000064400000004117151730541620011312 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Sascha Schumann <sascha@schumann.cx>                        |
   |          Ard Biesheuvel <ard@ard.nu>                                 |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_multiply.h 293155 2010-01-05 20:46:53Z sebastian $ */

#if defined(__i386__) && defined(__GNUC__)

#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do {	\
	long __tmpvar; 													\
	__asm__ ("imul %3,%0\n"											\
		"adc $0,%1" 												\
			: "=r"(__tmpvar),"=r"(usedval) 							\
			: "0"(a), "r"(b), "1"(0));								\
	if (usedval) (dval) = (double) (a) * (double) (b);				\
	else (lval) = __tmpvar;											\
} while (0)

#else

#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do {		\
	long   __lres  = (a) * (b);											\
	long double __dres  = (long double)(a) * (long double)(b);							\
	long double __delta = (long double) __lres - __dres;							\
	if ( ((usedval) = (( __dres + __delta ) != __dres))) {				\
		(dval) = __dres;												\
	} else {															\
		(lval) = __lres;												\
	}																	\
} while (0)

#endif
php/Zend/zend_vm_def.h000064400000346200151730541620010675 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   |          Dmitry Stogov <dmitry@zend.com>                             |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_vm_def.h 300990 2010-07-05 09:08:35Z dmitry $ */

/* If you change this file, please regenerate the zend_vm_execute.h and
 * zend_vm_opcodes.h files by running:
 * php zend_vm_gen.php
 */

ZEND_VM_HANDLER(1, ZEND_ADD, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	add_function(&EX_T(opline->result.u.var).tmp_var,
		GET_OP1_ZVAL_PTR(BP_VAR_R),
		GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
	FREE_OP1();
	FREE_OP2();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(2, ZEND_SUB, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	sub_function(&EX_T(opline->result.u.var).tmp_var,
		GET_OP1_ZVAL_PTR(BP_VAR_R),
		GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
	FREE_OP1();
	FREE_OP2();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(3, ZEND_MUL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	mul_function(&EX_T(opline->result.u.var).tmp_var,
		GET_OP1_ZVAL_PTR(BP_VAR_R),
		GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
	FREE_OP1();
	FREE_OP2();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(4, ZEND_DIV, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	div_function(&EX_T(opline->result.u.var).tmp_var,
		GET_OP1_ZVAL_PTR(BP_VAR_R),
		GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
	FREE_OP1();
	FREE_OP2();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(5, ZEND_MOD, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	mod_function(&EX_T(opline->result.u.var).tmp_var,
		GET_OP1_ZVAL_PTR(BP_VAR_R),
		GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
	FREE_OP1();
	FREE_OP2();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(6, ZEND_SL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	shift_left_function(&EX_T(opline->result.u.var).tmp_var,
		GET_OP1_ZVAL_PTR(BP_VAR_R),
		GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
	FREE_OP1();
	FREE_OP2();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(7, ZEND_SR, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	shift_right_function(&EX_T(opline->result.u.var).tmp_var,
		GET_OP1_ZVAL_PTR(BP_VAR_R),
		GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
	FREE_OP1();
	FREE_OP2();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	concat_function(&EX_T(opline->result.u.var).tmp_var,
		GET_OP1_ZVAL_PTR(BP_VAR_R),
		GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
	FREE_OP1();
	FREE_OP2();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(15, ZEND_IS_IDENTICAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	is_identical_function(&EX_T(opline->result.u.var).tmp_var,
		GET_OP1_ZVAL_PTR(BP_VAR_R),
		GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
	FREE_OP1();
	FREE_OP2();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(16, ZEND_IS_NOT_IDENTICAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	is_not_identical_function(&EX_T(opline->result.u.var).tmp_var,
		GET_OP1_ZVAL_PTR(BP_VAR_R),
		GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
	FREE_OP1();
	FREE_OP2();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(17, ZEND_IS_EQUAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	is_equal_function(&EX_T(opline->result.u.var).tmp_var,
		GET_OP1_ZVAL_PTR(BP_VAR_R),
		GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
	FREE_OP1();
	FREE_OP2();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(18, ZEND_IS_NOT_EQUAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	is_not_equal_function(&EX_T(opline->result.u.var).tmp_var,
		GET_OP1_ZVAL_PTR(BP_VAR_R),
		GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
	FREE_OP1();
	FREE_OP2();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(19, ZEND_IS_SMALLER, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	is_smaller_function(&EX_T(opline->result.u.var).tmp_var,
		GET_OP1_ZVAL_PTR(BP_VAR_R),
		GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
	FREE_OP1();
	FREE_OP2();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(20, ZEND_IS_SMALLER_OR_EQUAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	is_smaller_or_equal_function(&EX_T(opline->result.u.var).tmp_var,
		GET_OP1_ZVAL_PTR(BP_VAR_R),
		GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
	FREE_OP1();
	FREE_OP2();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(9, ZEND_BW_OR, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	bitwise_or_function(&EX_T(opline->result.u.var).tmp_var,
		GET_OP1_ZVAL_PTR(BP_VAR_R),
		GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
	FREE_OP1();
	FREE_OP2();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(10, ZEND_BW_AND, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	bitwise_and_function(&EX_T(opline->result.u.var).tmp_var,
		GET_OP1_ZVAL_PTR(BP_VAR_R),
		GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
	FREE_OP1();
	FREE_OP2();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(11, ZEND_BW_XOR, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	bitwise_xor_function(&EX_T(opline->result.u.var).tmp_var,
		GET_OP1_ZVAL_PTR(BP_VAR_R),
		GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
	FREE_OP1();
	FREE_OP2();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(14, ZEND_BOOL_XOR, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	boolean_xor_function(&EX_T(opline->result.u.var).tmp_var,
		GET_OP1_ZVAL_PTR(BP_VAR_R),
		GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
	FREE_OP1();
	FREE_OP2();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(12, ZEND_BW_NOT, CONST|TMP|VAR|CV, ANY)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	bitwise_not_function(&EX_T(opline->result.u.var).tmp_var,
		GET_OP1_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
	FREE_OP1();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(13, ZEND_BOOL_NOT, CONST|TMP|VAR|CV, ANY)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	boolean_not_function(&EX_T(opline->result.u.var).tmp_var,
		GET_OP1_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
	FREE_OP1();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV, int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC))
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;
	zend_free_op free_op1, free_op2, free_op_data1;
	zval **object_ptr = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W);
	zval *object;
	zval *property = GET_OP2_ZVAL_PTR(BP_VAR_R);
	zval *value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
	znode *result = &opline->result;
	zval **retval = &EX_T(result->u.var).var.ptr;
	int have_get_ptr = 0;

	if (OP1_TYPE == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
	}

	EX_T(result->u.var).var.ptr_ptr = NULL;
	make_real_object(object_ptr TSRMLS_CC);
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to assign property of non-object");
		FREE_OP2();
		FREE_OP(free_op_data1);

		if (!RETURN_VALUE_UNUSED(result)) {
			*retval = EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*retval);
		}
	} else {
		/* here we are sure we are dealing with an object */
		if (IS_OP2_TMP_FREE()) {
			MAKE_REAL_ZVAL_PTR(property);
		}

		/* here property is a string */
		if (opline->extended_value == ZEND_ASSIGN_OBJ
			&& Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
			zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
			if (zptr != NULL) { 			/* NULL means no success in getting PTR */
				SEPARATE_ZVAL_IF_NOT_REF(zptr);

				have_get_ptr = 1;
				binary_op(*zptr, *zptr, value TSRMLS_CC);
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = *zptr;
					PZVAL_LOCK(*retval);
				}
			}
		}

		if (!have_get_ptr) {
			zval *z = NULL;

			switch (opline->extended_value) {
				case ZEND_ASSIGN_OBJ:
					if (Z_OBJ_HT_P(object)->read_property) {
						z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
					}
					break;
				case ZEND_ASSIGN_DIM:
					if (Z_OBJ_HT_P(object)->read_dimension) {
						z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
					}
					break;
			}
			if (z) {
				if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
					zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

					if (z->refcount == 0) {
						zval_dtor(z);
						FREE_ZVAL(z);
					}
					z = value;
				}
				z->refcount++;
				SEPARATE_ZVAL_IF_NOT_REF(&z);
				binary_op(z, z, value TSRMLS_CC);
				switch (opline->extended_value) {
					case ZEND_ASSIGN_OBJ:
						Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
						break;
					case ZEND_ASSIGN_DIM:
						Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
						break;
				}
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = z;
					PZVAL_LOCK(*retval);
				}
				zval_ptr_dtor(&z);
			} else {
				zend_error(E_WARNING, "Attempt to assign property of non-object");
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = EG(uninitialized_zval_ptr);
					PZVAL_LOCK(*retval);
				}
			}
		}

		if (IS_OP2_TMP_FREE()) {
			zval_ptr_dtor(&property);
		} else {
			FREE_OP2();
		}
		FREE_OP(free_op_data1);
	}

	FREE_OP1_VAR_PTR();
	/* assign_obj has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HELPER_EX(zend_binary_assign_op_helper, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV, int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC))
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2, free_op_data2, free_op_data1;
	zval **var_ptr;
	zval *value;
	zend_bool increment_opline = 0;

	switch (opline->extended_value) {
		case ZEND_ASSIGN_OBJ:
			ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, binary_op);
			break;
		case ZEND_ASSIGN_DIM: {
				zval **object_ptr = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W);

				if (object_ptr && OP1_TYPE != IS_CV && !OP1_FREE) {
					(*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
				}

				if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
					ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, binary_op);
				} else {
					zend_op *op_data = opline+1;
					zval *dim = GET_OP2_ZVAL_PTR(BP_VAR_R);

					zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW), dim, IS_OP2_TMP_FREE(), BP_VAR_RW TSRMLS_CC);
					value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
					var_ptr = get_zval_ptr_ptr(&op_data->op2, EX(Ts), &free_op_data2, BP_VAR_RW);
					increment_opline = 1;
				}
			}
			break;
		default:
			value = GET_OP2_ZVAL_PTR(BP_VAR_R);
			var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW);
			/* do nothing */
			break;
	}

	if (!var_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets");
	}

	if (*var_ptr == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}
		FREE_OP2();
		FREE_OP1_VAR_PTR();
		if (increment_opline) {
			ZEND_VM_INC_OPCODE();
		}
		ZEND_VM_NEXT_OPCODE();
	}

	SEPARATE_ZVAL_IF_NOT_REF(var_ptr);

	if(Z_TYPE_PP(var_ptr) == IS_OBJECT && Z_OBJ_HANDLER_PP(var_ptr, get)
	   && Z_OBJ_HANDLER_PP(var_ptr, set)) {
		/* proxy object */
		zval *objval = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
		objval->refcount++;
		binary_op(objval, objval, value TSRMLS_CC);
		Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, objval TSRMLS_CC);
		zval_ptr_dtor(&objval);
	} else {
		binary_op(*var_ptr, *var_ptr, value TSRMLS_CC);
	}

	if (!RETURN_VALUE_UNUSED(&opline->result)) {
		EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
		PZVAL_LOCK(*var_ptr);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
	}
	FREE_OP2();

	if (increment_opline) {
		ZEND_VM_INC_OPCODE();
		FREE_OP(free_op_data1);
		FREE_OP_VAR_PTR(free_op_data2);
	}
	FREE_OP1_VAR_PTR();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(23, ZEND_ASSIGN_ADD, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
{
	ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, add_function);
}

ZEND_VM_HANDLER(24, ZEND_ASSIGN_SUB, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
{
	ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, sub_function);
}

ZEND_VM_HANDLER(25, ZEND_ASSIGN_MUL, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
{
	ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, mul_function);
}

ZEND_VM_HANDLER(26, ZEND_ASSIGN_DIV, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
{
	ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, div_function);
}

ZEND_VM_HANDLER(27, ZEND_ASSIGN_MOD, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
{
	ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, mod_function);
}

ZEND_VM_HANDLER(28, ZEND_ASSIGN_SL, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
{
	ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, shift_left_function);
}

ZEND_VM_HANDLER(29, ZEND_ASSIGN_SR, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
{
	ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, shift_right_function);
}

ZEND_VM_HANDLER(30, ZEND_ASSIGN_CONCAT, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
{
	ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, concat_function);
}

ZEND_VM_HANDLER(31, ZEND_ASSIGN_BW_OR, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
{
	ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, bitwise_or_function);
}

ZEND_VM_HANDLER(32, ZEND_ASSIGN_BW_AND, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
{
	ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, bitwise_and_function);
}

ZEND_VM_HANDLER(33, ZEND_ASSIGN_BW_XOR, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
{
	ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, bitwise_xor_function);
}

ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR|CV, incdec_t incdec_op)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval **object_ptr = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W);
	zval *object;
	zval *property = GET_OP2_ZVAL_PTR(BP_VAR_R);
	zval **retval = &EX_T(opline->result.u.var).var.ptr;
	int have_get_ptr = 0;

	if (OP1_TYPE == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}

	make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
		FREE_OP2();
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			*retval = EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*retval);
		}
		FREE_OP1_VAR_PTR();
		ZEND_VM_NEXT_OPCODE();
	}

	/* here we are sure we are dealing with an object */

	if (IS_OP2_TMP_FREE()) {
		MAKE_REAL_ZVAL_PTR(property);
	}

	if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
		zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
		if (zptr != NULL) { 			/* NULL means no success in getting PTR */
			SEPARATE_ZVAL_IF_NOT_REF(zptr);

			have_get_ptr = 1;
			incdec_op(*zptr);
			if (!RETURN_VALUE_UNUSED(&opline->result)) {
				*retval = *zptr;
				PZVAL_LOCK(*retval);
			}
		}
	}

	if (!have_get_ptr) {
		if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
			zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);

			if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
				zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

				if (z->refcount == 0) {
					zval_dtor(z);
					FREE_ZVAL(z);
				}
				z = value;
			}
			z->refcount++;
			SEPARATE_ZVAL_IF_NOT_REF(&z);
			incdec_op(z);
			*retval = z;
			Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
			SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
			zval_ptr_dtor(&z);
		} else {
			zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
			if (!RETURN_VALUE_UNUSED(&opline->result)) {
				*retval = EG(uninitialized_zval_ptr);
				PZVAL_LOCK(*retval);
			}
		}
	}

	if (IS_OP2_TMP_FREE()) {
		zval_ptr_dtor(&property);
	} else {
		FREE_OP2();
	}
	FREE_OP1_VAR_PTR();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(132, ZEND_PRE_INC_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
{
	ZEND_VM_DISPATCH_TO_HELPER_EX(zend_pre_incdec_property_helper, incdec_op, increment_function);
}

ZEND_VM_HANDLER(133, ZEND_PRE_DEC_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
{
	ZEND_VM_DISPATCH_TO_HELPER_EX(zend_pre_incdec_property_helper, incdec_op, decrement_function);
}

ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR|CV, incdec_t incdec_op)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval **object_ptr = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W);
	zval *object;
	zval *property = GET_OP2_ZVAL_PTR(BP_VAR_R);
	zval *retval = &EX_T(opline->result.u.var).tmp_var;
	int have_get_ptr = 0;

	if (OP1_TYPE == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}

	make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
		FREE_OP2();
		*retval = *EG(uninitialized_zval_ptr);
		FREE_OP1_VAR_PTR();
		ZEND_VM_NEXT_OPCODE();
	}

	/* here we are sure we are dealing with an object */

	if (IS_OP2_TMP_FREE()) {
		MAKE_REAL_ZVAL_PTR(property);
	}

	if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
		zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
		if (zptr != NULL) { 			/* NULL means no success in getting PTR */
			have_get_ptr = 1;
			SEPARATE_ZVAL_IF_NOT_REF(zptr);

			*retval = **zptr;
			zendi_zval_copy_ctor(*retval);

			incdec_op(*zptr);

		}
	}

	if (!have_get_ptr) {
		if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
			zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
			zval *z_copy;

			if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
				zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

				if (z->refcount == 0) {
					zval_dtor(z);
					FREE_ZVAL(z);
				}
				z = value;
			}
			*retval = *z;
			zendi_zval_copy_ctor(*retval);
			ALLOC_ZVAL(z_copy);
			*z_copy = *z;
			zendi_zval_copy_ctor(*z_copy);
			INIT_PZVAL(z_copy);
			incdec_op(z_copy);
			z->refcount++;
			Z_OBJ_HT_P(object)->write_property(object, property, z_copy TSRMLS_CC);
			zval_ptr_dtor(&z_copy);
			zval_ptr_dtor(&z);
		} else {
			zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
			*retval = *EG(uninitialized_zval_ptr);
		}
	}

	if (IS_OP2_TMP_FREE()) {
		zval_ptr_dtor(&property);
	} else {
		FREE_OP2();
	}
	FREE_OP1_VAR_PTR();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(134, ZEND_POST_INC_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
{
	ZEND_VM_DISPATCH_TO_HELPER_EX(zend_post_incdec_property_helper, incdec_op, increment_function);
}

ZEND_VM_HANDLER(135, ZEND_POST_DEC_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
{
	ZEND_VM_DISPATCH_TO_HELPER_EX(zend_post_incdec_property_helper, incdec_op, decrement_function);
}

ZEND_VM_HANDLER(34, ZEND_PRE_INC, VAR|CV, ANY)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval **var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW);

	if (!var_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}
	if (*var_ptr == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}
		FREE_OP1_VAR_PTR();
		ZEND_VM_NEXT_OPCODE();
	}

	SEPARATE_ZVAL_IF_NOT_REF(var_ptr);

	if(Z_TYPE_PP(var_ptr) == IS_OBJECT && Z_OBJ_HANDLER_PP(var_ptr, get)
	   && Z_OBJ_HANDLER_PP(var_ptr, set)) {
		/* proxy object */
		zval *val = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
		val->refcount++;
		increment_function(val);
		Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, val TSRMLS_CC);
		zval_ptr_dtor(&val);
	} else {
		increment_function(*var_ptr);
	}

	if (!RETURN_VALUE_UNUSED(&opline->result)) {
		EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
		PZVAL_LOCK(*var_ptr);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
	}

	FREE_OP1_VAR_PTR();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(35, ZEND_PRE_DEC, VAR|CV, ANY)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval **var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW);

	if (!var_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}
	if (*var_ptr == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}
		FREE_OP1_VAR_PTR();
		ZEND_VM_NEXT_OPCODE();
	}

	SEPARATE_ZVAL_IF_NOT_REF(var_ptr);

	if(Z_TYPE_PP(var_ptr) == IS_OBJECT && Z_OBJ_HANDLER_PP(var_ptr, get)
	   && Z_OBJ_HANDLER_PP(var_ptr, set)) {
		/* proxy object */
		zval *val = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
		val->refcount++;
		decrement_function(val);
		Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, val TSRMLS_CC);
		zval_ptr_dtor(&val);
	} else {
		decrement_function(*var_ptr);
	}

	if (!RETURN_VALUE_UNUSED(&opline->result)) {
		EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
		PZVAL_LOCK(*var_ptr);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
	}

	FREE_OP1_VAR_PTR();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(36, ZEND_POST_INC, VAR|CV, ANY)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval **var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW);

	if (!var_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}
	if (*var_ptr == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			EX_T(opline->result.u.var).tmp_var = *EG(uninitialized_zval_ptr);
		}
		FREE_OP1_VAR_PTR();
		ZEND_VM_NEXT_OPCODE();
	}

	EX_T(opline->result.u.var).tmp_var = **var_ptr;
	zendi_zval_copy_ctor(EX_T(opline->result.u.var).tmp_var);

	SEPARATE_ZVAL_IF_NOT_REF(var_ptr);

	if(Z_TYPE_PP(var_ptr) == IS_OBJECT && Z_OBJ_HANDLER_PP(var_ptr, get)
	   && Z_OBJ_HANDLER_PP(var_ptr, set)) {
		/* proxy object */
		zval *val = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
		val->refcount++;
		increment_function(val);
		Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, val TSRMLS_CC);
		zval_ptr_dtor(&val);
	} else {
		increment_function(*var_ptr);
	}

	FREE_OP1_VAR_PTR();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(37, ZEND_POST_DEC, VAR|CV, ANY)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval **var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW);

	if (!var_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}
	if (*var_ptr == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			EX_T(opline->result.u.var).tmp_var = *EG(uninitialized_zval_ptr);
		}
		FREE_OP1_VAR_PTR();
		ZEND_VM_NEXT_OPCODE();
	}

	EX_T(opline->result.u.var).tmp_var = **var_ptr;
	zendi_zval_copy_ctor(EX_T(opline->result.u.var).tmp_var);

	SEPARATE_ZVAL_IF_NOT_REF(var_ptr);

	if(Z_TYPE_PP(var_ptr) == IS_OBJECT && Z_OBJ_HANDLER_PP(var_ptr, get)
	   && Z_OBJ_HANDLER_PP(var_ptr, set)) {
		/* proxy object */
		zval *val = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
		val->refcount++;
		decrement_function(val);
		Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, val TSRMLS_CC);
		zval_ptr_dtor(&val);
	} else {
		decrement_function(*var_ptr);
	}

	FREE_OP1_VAR_PTR();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(40, ZEND_ECHO, CONST|TMP|VAR|CV, ANY)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval z_copy;
	zval *z = GET_OP1_ZVAL_PTR(BP_VAR_R);

	if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL &&
		zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
		zend_print_variable(&z_copy);
		zval_dtor(&z_copy);
	} else {
		zend_print_variable(z);
	}

	FREE_OP1();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(41, ZEND_PRINT, CONST|TMP|VAR|CV, ANY)
{
	zend_op *opline = EX(opline);

	Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 1;
	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_LONG;

	ZEND_VM_DISPATCH_TO_HANDLER(ZEND_ECHO);
}

ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMP|VAR|CV, ANY, int type)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *varname = GET_OP1_ZVAL_PTR(BP_VAR_R);
	zval **retval;
	zval tmp_varname;
	HashTable *target_symbol_table;

 	if (Z_TYPE_P(varname) != IS_STRING) {
		tmp_varname = *varname;
		zval_copy_ctor(&tmp_varname);
		convert_to_string(&tmp_varname);
		varname = &tmp_varname;
	}

	if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
		retval = zend_std_get_static_property(EX_T(opline->op2.u.var).class_entry, Z_STRVAL_P(varname), Z_STRLEN_P(varname), 0 TSRMLS_CC);
		FREE_OP1();
	} else {
		target_symbol_table = zend_get_target_symbol_table(opline, EX(Ts), type, varname TSRMLS_CC);
/*
		if (!target_symbol_table) {
			ZEND_VM_NEXT_OPCODE();
		}
*/
		if (zend_hash_find(target_symbol_table, varname->value.str.val, varname->value.str.len+1, (void **) &retval) == FAILURE) {
			switch (type) {
				case BP_VAR_R:
				case BP_VAR_UNSET:
					zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
					/* break missing intentionally */
				case BP_VAR_IS:
					retval = &EG(uninitialized_zval_ptr);
					break;
				case BP_VAR_RW:
					zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
					/* break missing intentionally */
				case BP_VAR_W: {
						zval *new_zval = &EG(uninitialized_zval);

						new_zval->refcount++;
						zend_hash_update(target_symbol_table, varname->value.str.val, varname->value.str.len+1, &new_zval, sizeof(zval *), (void **) &retval);
					}
					break;
				EMPTY_SWITCH_DEFAULT_CASE()
			}
		}
		switch (opline->op2.u.EA.type) {
			case ZEND_FETCH_GLOBAL:
				if (OP1_TYPE != IS_TMP_VAR) {
					FREE_OP1();
				}
				break;
			case ZEND_FETCH_LOCAL:
				FREE_OP1();
				break;
			case ZEND_FETCH_STATIC:
				zval_update_constant(retval, (void*) 1 TSRMLS_CC);
				break;
			case ZEND_FETCH_GLOBAL_LOCK:
				if (OP1_TYPE == IS_VAR && !free_op1.var) {
					PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
				}
				break;
		}
	}


	if (varname == &tmp_varname) {
		zval_dtor(varname);
	}
	if (!RETURN_VALUE_UNUSED(&opline->result)) {
		EX_T(opline->result.u.var).var.ptr_ptr = retval;
		PZVAL_LOCK(*retval);
		switch (type) {
			case BP_VAR_R:
			case BP_VAR_IS:
				AI_USE_PTR(EX_T(opline->result.u.var).var);
				break;
			case BP_VAR_UNSET: {
				zend_free_op free_res;

				PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &free_res);
				if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
					SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
				}
				PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
				FREE_OP_VAR_PTR(free_res);
				break;
			}
		}
	}
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(80, ZEND_FETCH_R, CONST|TMP|VAR|CV, ANY)
{
	ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_R);
}

ZEND_VM_HANDLER(83, ZEND_FETCH_W, CONST|TMP|VAR|CV, ANY)
{
	ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_W);
}

ZEND_VM_HANDLER(86, ZEND_FETCH_RW, CONST|TMP|VAR|CV, ANY)
{
	ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_RW);
}

ZEND_VM_HANDLER(92, ZEND_FETCH_FUNC_ARG, CONST|TMP|VAR|CV, ANY)
{
	ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type,
		ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), EX(opline)->extended_value)?BP_VAR_W:BP_VAR_R);
}

ZEND_VM_HANDLER(95, ZEND_FETCH_UNSET, CONST|TMP|VAR|CV, ANY)
{
	ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_UNSET);
}

ZEND_VM_HANDLER(89, ZEND_FETCH_IS, CONST|TMP|VAR|CV, ANY)
{
	ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_IS);
}

ZEND_VM_HANDLER(81, ZEND_FETCH_DIM_R, VAR|CV, CONST|TMP|VAR|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *dim = GET_OP2_ZVAL_PTR(BP_VAR_R);

	if (opline->extended_value == ZEND_FETCH_ADD_LOCK &&
	    OP1_TYPE != IS_CV &&
	    EX_T(opline->op1.u.var).var.ptr_ptr) {
		PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
	}
	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), GET_OP1_ZVAL_PTR_PTR(BP_VAR_R), dim, IS_OP2_TMP_FREE(), BP_VAR_R TSRMLS_CC);
	FREE_OP2();
	FREE_OP1_VAR_PTR();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *dim = GET_OP2_ZVAL_PTR(BP_VAR_R);

	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), GET_OP1_ZVAL_PTR_PTR(BP_VAR_W), dim, IS_OP2_TMP_FREE(), BP_VAR_W TSRMLS_CC);
	FREE_OP2();
	if (OP1_TYPE == IS_VAR && OP1_FREE &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	FREE_OP1_VAR_PTR();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(87, ZEND_FETCH_DIM_RW, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *dim = GET_OP2_ZVAL_PTR(BP_VAR_R);

	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW), dim, IS_OP2_TMP_FREE(), BP_VAR_RW TSRMLS_CC);
	FREE_OP2();
	if (OP1_TYPE == IS_VAR && OP1_FREE &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	FREE_OP1_VAR_PTR();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(90, ZEND_FETCH_DIM_IS, VAR|CV, CONST|TMP|VAR|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *dim = GET_OP2_ZVAL_PTR(BP_VAR_R);

	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), GET_OP1_ZVAL_PTR_PTR(BP_VAR_IS), dim, IS_OP2_TMP_FREE(), BP_VAR_IS TSRMLS_CC);
	FREE_OP2();
	FREE_OP1_VAR_PTR();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
	zval *dim;

	if (OP2_TYPE == IS_UNUSED && type == BP_VAR_R) {
		zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
	}
	dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), GET_OP1_ZVAL_PTR_PTR(type), dim, IS_OP2_TMP_FREE(), type TSRMLS_CC);
	FREE_OP2();
	if (OP1_TYPE == IS_VAR && type == BP_VAR_W && OP1_FREE &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	FREE_OP1_VAR_PTR();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(96, ZEND_FETCH_DIM_UNSET, VAR|CV, CONST|TMP|VAR|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval **container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_UNSET);
	zval *dim = GET_OP2_ZVAL_PTR(BP_VAR_R);

	/* Not needed in DIM_UNSET
	if (opline->extended_value == ZEND_FETCH_ADD_LOCK) {
		PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
	}
	*/
	if (OP1_TYPE == IS_CV) {
		if (container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
	}
	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, dim, IS_OP2_TMP_FREE(), BP_VAR_UNSET TSRMLS_CC);
	FREE_OP2();
	if (OP1_TYPE == IS_VAR && OP1_FREE &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	FREE_OP1_VAR_PTR();
	if (EX_T(opline->result.u.var).var.ptr_ptr == NULL) {
		zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
	} else {
		zend_free_op free_res;

		PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &free_res);
		if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
		}
		PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
		FREE_OP_VAR_PTR(free_res);
	}
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HELPER_EX(zend_fetch_property_address_read_helper, VAR|UNUSED|CV, CONST|TMP|VAR|CV, int type)
{
	zend_op *opline = EX(opline);
	zval *container;
	zval **retval;
	zend_free_op free_op1;
	zend_free_op free_op2;
	zval *offset  = GET_OP2_ZVAL_PTR(BP_VAR_R);

	retval = &EX_T(opline->result.u.var).var.ptr;
	EX_T(opline->result.u.var).var.ptr_ptr = retval;

	container = GET_OP1_OBJ_ZVAL_PTR(type);

	if (container == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			*retval = EG(error_zval_ptr);
			PZVAL_LOCK(*retval);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}
		FREE_OP2();
		FREE_OP1();
		ZEND_VM_NEXT_OPCODE();
	}


	if (Z_TYPE_P(container) != IS_OBJECT || !Z_OBJ_HT_P(container)->read_property) {
		if (type != BP_VAR_IS) {
			zend_error(E_NOTICE, "Trying to get property of non-object");
		}
		*retval = EG(uninitialized_zval_ptr);
		SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		FREE_OP2();
	} else {
		if (IS_OP2_TMP_FREE()) {
			MAKE_REAL_ZVAL_PTR(offset);
		}

		/* here we are sure we are dealing with an object */
		*retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);

		if (RETURN_VALUE_UNUSED(&opline->result) && ((*retval)->refcount == 0)) {
			zval_dtor(*retval);
			FREE_ZVAL(*retval);
		} else {
			SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}

		if (IS_OP2_TMP_FREE()) {
			zval_ptr_dtor(&offset);
		} else {
			FREE_OP2();
		}
	}

	FREE_OP1();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(82, ZEND_FETCH_OBJ_R, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
{
	ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_property_address_read_helper, type, BP_VAR_R);
}

ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *property = GET_OP2_ZVAL_PTR(BP_VAR_R);

	if (opline->extended_value == ZEND_FETCH_ADD_LOCK && OP1_TYPE != IS_CV) {
		PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
		EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr;
	}

	if (IS_OP2_TMP_FREE()) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W), property, BP_VAR_W TSRMLS_CC);
	if (IS_OP2_TMP_FREE()) {
		zval_ptr_dtor(&property);
	} else {
		FREE_OP2();
	}
	if (OP1_TYPE == IS_VAR && OP1_FREE &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	FREE_OP1_VAR_PTR();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *property = GET_OP2_ZVAL_PTR(BP_VAR_R);

	if (IS_OP2_TMP_FREE()) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW), property, BP_VAR_RW TSRMLS_CC);
	if (IS_OP2_TMP_FREE()) {
		zval_ptr_dtor(&property);
	} else {
		FREE_OP2();
	}
	if (OP1_TYPE == IS_VAR && OP1_FREE &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	FREE_OP1_VAR_PTR();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
{
	ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_property_address_read_helper, type, BP_VAR_IS);
}

ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
{
	zend_op *opline = EX(opline);

	if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) {
		/* Behave like FETCH_OBJ_W */
		zend_free_op free_op1, free_op2;
		zval *property = GET_OP2_ZVAL_PTR(BP_VAR_R);

		if (IS_OP2_TMP_FREE()) {
			MAKE_REAL_ZVAL_PTR(property);
		}
		zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W), property, BP_VAR_W TSRMLS_CC);
		if (IS_OP2_TMP_FREE()) {
			zval_ptr_dtor(&property);
		} else {
			FREE_OP2();
		}
		if (OP1_TYPE == IS_VAR && OP1_FREE &&
		    READY_TO_DESTROY(free_op1.var) &&
		    !RETURN_VALUE_UNUSED(&opline->result)) {
			AI_USE_PTR(EX_T(opline->result.u.var).var);
			if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
			    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
				SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
			}
		}
		FREE_OP1_VAR_PTR();
		ZEND_VM_NEXT_OPCODE();
	} else {
		ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_property_address_read_helper, type, BP_VAR_R);
	}
}

ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2, free_res;
	zval **container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_R);
	zval *property = GET_OP2_ZVAL_PTR(BP_VAR_R);

	if (OP1_TYPE == IS_CV) {
		if (container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
	}
	if (IS_OP2_TMP_FREE()) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC);
	if (IS_OP2_TMP_FREE()) {
		zval_ptr_dtor(&property);
	} else {
		FREE_OP2();
	}
	if (OP1_TYPE == IS_VAR && OP1_FREE &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	FREE_OP1_VAR_PTR();

	PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &free_res);
	if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
		SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
	}
	PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
	FREE_OP_VAR_PTR(free_res);
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(98, ZEND_FETCH_DIM_TMP_VAR, CONST|TMP, CONST)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *container = GET_OP1_ZVAL_PTR(BP_VAR_R);

	if (Z_TYPE_P(container) != IS_ARRAY) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
		}
	} else {
		zend_free_op free_op2;
		zval *dim = GET_OP2_ZVAL_PTR(BP_VAR_R);

		EX_T(opline->result.u.var).var.ptr_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, BP_VAR_R TSRMLS_CC);
		SELECTIVE_PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &opline->result);
		FREE_OP2();
	}
	AI_USE_PTR(EX_T(opline->result.u.var).var);
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(136, ZEND_ASSIGN_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;
	zend_free_op free_op1;
	zval **object_ptr = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W);

	zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);
	FREE_OP1_VAR_PTR();
	/* assign_obj has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;
	zend_free_op free_op1;
	zval **object_ptr;

	if (OP1_TYPE == IS_CV || EX_T(opline->op1.u.var).var.ptr_ptr) {
		/* not an array offset */
		object_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
	} else {
		object_ptr = NULL;
	}

	if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
		zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC);
	} else {
		zend_free_op free_op2, free_op_data1;
		zval *value;
		zval *dim = GET_OP2_ZVAL_PTR(BP_VAR_R);

		zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, IS_OP2_TMP_FREE(), BP_VAR_W TSRMLS_CC);
		FREE_OP2();

		value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
	 	zend_assign_to_variable(&opline->result, &op_data->op2, &op_data->op1, value, (IS_TMP_FREE(free_op_data1)?IS_TMP_VAR:op_data->op1.op_type), EX(Ts) TSRMLS_CC);
	 	FREE_OP_IF_VAR(free_op_data1);
	}
 	FREE_OP1_VAR_PTR();
	/* assign_dim has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(38, ZEND_ASSIGN, VAR|CV, CONST|TMP|VAR|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zval *value = GET_OP2_ZVAL_PTR(BP_VAR_R);

 	zend_assign_to_variable(&opline->result, &opline->op1, &opline->op2, value, (IS_OP2_TMP_FREE()?IS_TMP_VAR:OP2_TYPE), EX(Ts) TSRMLS_CC);
	/* zend_assign_to_variable() always takes care of op2, never free it! */
 	FREE_OP2_IF_VAR();

	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval **variable_ptr_ptr;
	zval **value_ptr_ptr = GET_OP2_ZVAL_PTR_PTR(BP_VAR_W);

	if (OP2_TYPE == IS_VAR &&
	    value_ptr_ptr &&
	    !(*value_ptr_ptr)->is_ref &&
	    opline->extended_value == ZEND_RETURNS_FUNCTION &&
	    !EX_T(opline->op2.u.var).var.fcall_returned_reference) {
		if (free_op2.var == NULL) {
			PZVAL_LOCK(*value_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
		}
		zend_error(E_STRICT, "Only variables should be assigned by reference");
		if (EG(exception)) {
			FREE_OP2_VAR_PTR();
			ZEND_VM_NEXT_OPCODE();
		}
		ZEND_VM_DISPATCH_TO_HANDLER(ZEND_ASSIGN);
	} else if (OP2_TYPE == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
		PZVAL_LOCK(*value_ptr_ptr);
	}
	if (OP1_TYPE == IS_VAR && EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
		zend_error(E_ERROR, "Cannot assign by reference to overloaded object");
	}

	variable_ptr_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
	zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);

	if (OP2_TYPE == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
		(*variable_ptr_ptr)->refcount--;
	}

	if (!RETURN_VALUE_UNUSED(&opline->result)) {
		EX_T(opline->result.u.var).var.ptr_ptr = variable_ptr_ptr;
		PZVAL_LOCK(*variable_ptr_ptr);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
	}

	FREE_OP1_VAR_PTR();
	FREE_OP2_VAR_PTR();

	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(42, ZEND_JMP, ANY, ANY)
{
#if DEBUG_ZEND>=2
	printf("Jumping to %d\n", EX(opline)->op1.u.opline_num);
#endif
	ZEND_VM_SET_OPCODE(EX(opline)->op1.u.jmp_addr);
	ZEND_VM_CONTINUE(); /* CHECK_ME */
}

ZEND_VM_HANDLER(43, ZEND_JMPZ, CONST|TMP|VAR|CV, ANY)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	int ret = i_zend_is_true(GET_OP1_ZVAL_PTR(BP_VAR_R));

	FREE_OP1();
	if (!ret) {
#if DEBUG_ZEND>=2
		printf("Conditional jmp to %d\n", opline->op2.u.opline_num);
#endif
		ZEND_VM_JMP(opline->op2.u.jmp_addr);
	}

	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(44, ZEND_JMPNZ, CONST|TMP|VAR|CV, ANY)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	int ret = i_zend_is_true(GET_OP1_ZVAL_PTR(BP_VAR_R));

	FREE_OP1();
	if (ret) {
#if DEBUG_ZEND>=2
		printf("Conditional jmp to %d\n", opline->op2.u.opline_num);
#endif
		ZEND_VM_JMP(opline->op2.u.jmp_addr);
	}

	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(45, ZEND_JMPZNZ, CONST|TMP|VAR|CV, ANY)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	int retval = i_zend_is_true(GET_OP1_ZVAL_PTR(BP_VAR_R));

	FREE_OP1();
	if (retval) {
#if DEBUG_ZEND>=2
		printf("Conditional jmp on true to %d\n", opline->extended_value);
#endif
		ZEND_VM_JMP(&EX(op_array)->opcodes[opline->extended_value]);
	} else {
#if DEBUG_ZEND>=2
		printf("Conditional jmp on false to %d\n", opline->op2.u.opline_num);
#endif
		ZEND_VM_JMP(&EX(op_array)->opcodes[opline->op2.u.opline_num]);
	}
}

ZEND_VM_HANDLER(46, ZEND_JMPZ_EX, CONST|TMP|VAR|CV, ANY)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	int retval = i_zend_is_true(GET_OP1_ZVAL_PTR(BP_VAR_R));

	FREE_OP1();
	Z_LVAL(EX_T(opline->result.u.var).tmp_var) = retval;
	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
	if (!retval) {
#if DEBUG_ZEND>=2
		printf("Conditional jmp to %d\n", opline->op2.u.opline_num);
#endif
		ZEND_VM_JMP(opline->op2.u.jmp_addr);
	}
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(47, ZEND_JMPNZ_EX, CONST|TMP|VAR|CV, ANY)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	int retval = i_zend_is_true(GET_OP1_ZVAL_PTR(BP_VAR_R));

	FREE_OP1();
	Z_LVAL(EX_T(opline->result.u.var).tmp_var) = retval;
	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
	if (retval) {
#if DEBUG_ZEND>=2
		printf("Conditional jmp to %d\n", opline->op2.u.opline_num);
#endif
		ZEND_VM_JMP(opline->op2.u.jmp_addr);
	}
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(70, ZEND_FREE, TMP, ANY)
{
	zendi_zval_dtor(EX_T(EX(opline)->op1.u.var).tmp_var);
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(53, ZEND_INIT_STRING, ANY, ANY)
{
	zval *tmp = &EX_T(EX(opline)->result.u.var).tmp_var;

	tmp->value.str.val = emalloc(1);
	tmp->value.str.val[0] = 0;
	tmp->value.str.len = 0;
	tmp->refcount = 1;
	tmp->type = IS_STRING;
	tmp->is_ref = 0;
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(54, ZEND_ADD_CHAR, TMP, CONST)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	add_char_to_string(&EX_T(opline->result.u.var).tmp_var,
		GET_OP1_ZVAL_PTR(BP_VAR_NA),
		&opline->op2.u.constant);
	/* FREE_OP is missing intentionally here - we're always working on the same temporary variable */
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(55, ZEND_ADD_STRING, TMP, CONST)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	add_string_to_string(&EX_T(opline->result.u.var).tmp_var,
		GET_OP1_ZVAL_PTR(BP_VAR_NA),
		&opline->op2.u.constant);
	/* FREE_OP is missing intentionally here - we're always working on the same temporary variable */
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(56, ZEND_ADD_VAR, TMP, TMP|VAR|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *var = GET_OP2_ZVAL_PTR(BP_VAR_R);
	zval var_copy;
	int use_copy = 0;

	if (Z_TYPE_P(var) != IS_STRING) {
		zend_make_printable_zval(var, &var_copy, &use_copy);

		if (use_copy) {
			var = &var_copy;
		}
	}
	add_string_to_string(	&EX_T(opline->result.u.var).tmp_var,
							GET_OP1_ZVAL_PTR(BP_VAR_NA),
							var);
	if (use_copy) {
		zval_dtor(var);
	}
	/* original comment, possibly problematic:
	 * FREE_OP is missing intentionally here - we're always working on the same temporary variable
	 * (Zeev):  I don't think it's problematic, we only use variables
	 * which aren't affected by FREE_OP(Ts, )'s anyway, unless they're
	 * string offsets or overloaded objects
	 */
	FREE_OP2();

	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(109, ZEND_FETCH_CLASS, ANY, CONST|TMP|VAR|UNUSED|CV)
{
	zend_op *opline = EX(opline);
	zval *class_name;
	zend_free_op free_op2;


	if (OP2_TYPE == IS_UNUSED) {
		EX_T(opline->result.u.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC);
		ZEND_VM_NEXT_OPCODE();
	}

	class_name = GET_OP2_ZVAL_PTR(BP_VAR_R);

	switch (Z_TYPE_P(class_name)) {
		case IS_OBJECT:
			EX_T(opline->result.u.var).class_entry = Z_OBJCE_P(class_name);
			break;
		case IS_STRING:
			EX_T(opline->result.u.var).class_entry = zend_fetch_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), opline->extended_value TSRMLS_CC);
			break;
		default:
			zend_error_noreturn(E_ERROR, "Class name must be a valid object or a string");
			break;
	}

	FREE_OP2();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV)
{
	zend_op *opline = EX(opline);
	zval *function_name;
	char *function_name_strval;
	int function_name_strlen;
	zend_free_op free_op1, free_op2;

	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), NULL);

	function_name = GET_OP2_ZVAL_PTR(BP_VAR_R);

	if (Z_TYPE_P(function_name)!=IS_STRING) {
		zend_error_noreturn(E_ERROR, "Method name must be a string");
	}

	function_name_strval = Z_STRVAL_P(function_name);
	function_name_strlen = Z_STRLEN_P(function_name);

	EX(object) = GET_OP1_OBJ_ZVAL_PTR(BP_VAR_R);

	if (EX(object) && Z_TYPE_P(EX(object)) == IS_OBJECT) {
		if (Z_OBJ_HT_P(EX(object))->get_method == NULL) {
			zend_error_noreturn(E_ERROR, "Object does not support method calls");
		}

		/* First, locate the function. */
		EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen TSRMLS_CC);
		if (!EX(fbc)) {
			zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
		}
	} else {
		zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
	}

	if (!EX(object) || (EX(fbc) && (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
		EX(object) = NULL;
	} else {
		if (!PZVAL_IS_REF(EX(object))) {
			EX(object)->refcount++; /* For $this pointer */
		} else {
			zval *this_ptr;
			ALLOC_ZVAL(this_ptr);
			INIT_PZVAL_COPY(this_ptr, EX(object));
			zval_copy_ctor(this_ptr);
			EX(object) = this_ptr;
		}
	}

	FREE_OP2();
	FREE_OP1_IF_VAR();

	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, ANY, CONST|TMP|VAR|UNUSED|CV)
{
	zend_op *opline = EX(opline);
	zval *function_name;
	zend_class_entry *ce;

	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), NULL);

	ce = EX_T(opline->op1.u.var).class_entry;
	if(OP2_TYPE != IS_UNUSED) {
		char *function_name_strval = NULL;
		int function_name_strlen;
		zend_bool is_const = (OP2_TYPE == IS_CONST);
		zend_free_op free_op2;

		if (is_const) {
			function_name_strval = Z_STRVAL(opline->op2.u.constant);
			function_name_strlen = Z_STRLEN(opline->op2.u.constant);
		} else {
			function_name = GET_OP2_ZVAL_PTR(BP_VAR_R);

			if (Z_TYPE_P(function_name) != IS_STRING) {
				zend_error_noreturn(E_ERROR, "Function name must be a string");
			} else {
				function_name_strval = Z_STRVAL_P(function_name);
				function_name_strlen = Z_STRLEN_P(function_name);
			}
		}

		if (function_name_strval) {
			EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
		}

		if (!is_const) {
			FREE_OP2();
		}
	} else {
		if(!ce->constructor) {
			zend_error_noreturn(E_ERROR, "Can not call constructor");
		}
		if (EG(This) && Z_OBJCE_P(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
			zend_error(E_COMPILE_ERROR, "Cannot call private %s::__construct()", ce->name);
		}
		EX(fbc) = ce->constructor;
	}

	if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
		EX(object) = NULL;
	} else {
		if (OP2_TYPE != IS_UNUSED &&
		    EG(This) &&
		    Z_OBJ_HT_P(EG(This))->get_class_entry &&
		    !instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
		    /* We are calling method of the other (incompatible) class,
		       but passing $this. This is done for compatibility with php-4. */
			int severity;
			char *verb;
			if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
				severity = E_STRICT;
				verb = "should not";
			} else {
				/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
				severity = E_ERROR;
				verb = "cannot";
			}
			zend_error(severity, "Non-static method %s::%s() %s be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name, verb);

		}
		if ((EX(object) = EG(This))) {
			EX(object)->refcount++;
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV)
{
	zend_op *opline = EX(opline);
	zval *function_name;
	zend_function *function;
	char *function_name_strval, *lcname;
	int function_name_strlen;
	zend_free_op free_op2;

	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), NULL);

	if (OP2_TYPE == IS_CONST) {
		function_name_strval = opline->op2.u.constant.value.str.val;
		function_name_strlen = opline->op2.u.constant.value.str.len;
	} else {
		function_name = GET_OP2_ZVAL_PTR(BP_VAR_R);

		if (Z_TYPE_P(function_name) != IS_STRING) {
			zend_error_noreturn(E_ERROR, "Function name must be a string");
		}
		function_name_strval = function_name->value.str.val;
		function_name_strlen = function_name->value.str.len;
	}

	lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen);
	if (zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &function)==FAILURE) {
		efree(lcname);
		zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
	}

	efree(lcname);
	if (OP2_TYPE != IS_CONST) {
		FREE_OP2();
	}

	EX(object) = NULL;

	EX(fbc) = function;

	ZEND_VM_NEXT_OPCODE();
}


ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
{
	zend_op *opline = EX(opline);
	zval **original_return_value;
	zend_class_entry *current_scope = NULL;
	zval *current_this = NULL;
	int return_value_used = RETURN_VALUE_USED(opline);
	zend_bool should_change_scope;
	zend_op *ctor_opline;

	if (EX(function_state).function->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) {
		if (EX(function_state).function->common.fn_flags & ZEND_ACC_ABSTRACT) {
			zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", EX(function_state).function->common.scope->name, EX(function_state).function->common.function_name);
			ZEND_VM_NEXT_OPCODE(); /* Never reached */
		}
		if (EX(function_state).function->common.fn_flags & ZEND_ACC_DEPRECATED) {
			zend_error(E_STRICT, "Function %s%s%s() is deprecated", 
				EX(function_state).function->common.scope ? EX(function_state).function->common.scope->name : "",
				EX(function_state).function->common.scope ? "::" : "",
				EX(function_state).function->common.function_name);
		}
	}

	zend_ptr_stack_2_push(&EG(argument_stack), (void *)(zend_uintptr_t)opline->extended_value, NULL);

	EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;

	if (EX(function_state).function->type == ZEND_USER_FUNCTION
		|| EX(function_state).function->common.scope) {
		should_change_scope = 1;
		current_this = EG(This);
		EG(This) = EX(object);
		current_scope = EG(scope);
		EG(scope) = (EX(function_state).function->type == ZEND_USER_FUNCTION || !EX(object)) ? EX(function_state).function->common.scope : NULL;
	} else {
		should_change_scope = 0;
	}

	EX_T(opline->result.u.var).var.fcall_returned_reference = 0;

	if (EX(function_state).function->common.scope) {
		if (!EG(This) && !(EX(function_state).function->common.fn_flags & ZEND_ACC_STATIC)) {
			int severity;
			char *severity_word;
			if (EX(function_state).function->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
				severity = E_STRICT;
				severity_word = "should not";
			} else {
				severity = E_ERROR;
				severity_word = "cannot";
			}
			zend_error(severity, "Non-static method %s::%s() %s be called statically", EX(function_state).function->common.scope->name, EX(function_state).function->common.function_name, severity_word);
		}
	}
	if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) {
		unsigned char return_reference = EX(function_state).function->common.return_reference;

		ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
		INIT_ZVAL(*(EX_T(opline->result.u.var).var.ptr));

		if (EX(function_state).function->common.arg_info) {
			zend_uint i=0;
			zval **p;
			ulong arg_count;

			p = (zval **) EG(argument_stack).top_element-2;
			arg_count = (ulong)(zend_uintptr_t) *p;

			while (arg_count>0) {
				zend_verify_arg_type(EX(function_state).function, ++i, *(p-arg_count) TSRMLS_CC);
				arg_count--;
			}
		}
		if (!zend_execute_internal) {
			/* saves one function call if zend_execute_internal is not used */
			((zend_internal_function *) EX(function_state).function)->handler(opline->extended_value, EX_T(opline->result.u.var).var.ptr, EX(function_state).function->common.return_reference?&EX_T(opline->result.u.var).var.ptr:NULL, EX(object), return_value_used TSRMLS_CC);
		} else {
			zend_execute_internal(EXECUTE_DATA, return_value_used TSRMLS_CC);
		}

		EG(current_execute_data) = EXECUTE_DATA;

/*	We shouldn't fix bad extensions here,
    because it can break proper ones (Bug #34045)
		if (!EX(function_state).function->common.return_reference) {
			EX_T(opline->result.u.var).var.ptr->is_ref = 0;
			EX_T(opline->result.u.var).var.ptr->refcount = 1;
		}
*/
		if (!return_value_used) {
			zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
		} else {
			EX_T(opline->result.u.var).var.fcall_returned_reference = return_reference;
		}
	} else if (EX(function_state).function->type == ZEND_USER_FUNCTION) {
		EX_T(opline->result.u.var).var.ptr = NULL;
		if (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
			/*printf("Cache hit!  Reusing %x\n", symtable_cache[symtable_cache_ptr]);*/
			EX(function_state).function_symbol_table = *(EG(symtable_cache_ptr)--);
		} else {
			ALLOC_HASHTABLE(EX(function_state).function_symbol_table);
			zend_hash_init(EX(function_state).function_symbol_table, 0, NULL, ZVAL_PTR_DTOR, 0);
			/*printf("Cache miss!  Initialized %x\n", function_state.function_symbol_table);*/
		}
		EG(active_symbol_table) = EX(function_state).function_symbol_table;
		original_return_value = EG(return_value_ptr_ptr);
		EG(return_value_ptr_ptr) = EX_T(opline->result.u.var).var.ptr_ptr;
		EG(active_op_array) = (zend_op_array *) EX(function_state).function;

		zend_execute(EG(active_op_array) TSRMLS_CC);
		EX_T(opline->result.u.var).var.fcall_returned_reference = EG(active_op_array)->return_reference;

		if (return_value_used && !EX_T(opline->result.u.var).var.ptr) {
			if (!EG(exception)) {
				ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
				INIT_ZVAL(*EX_T(opline->result.u.var).var.ptr);
			}
		} else if (!return_value_used && EX_T(opline->result.u.var).var.ptr) {
			zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
		}

		EG(opline_ptr) = &EX(opline);
		EG(active_op_array) = EX(op_array);
		EG(return_value_ptr_ptr)=original_return_value;
		if (EG(symtable_cache_ptr)>=EG(symtable_cache_limit)) {
			zend_hash_destroy(EX(function_state).function_symbol_table);
			FREE_HASHTABLE(EX(function_state).function_symbol_table);
		} else {
			/* clean before putting into the cache, since clean
			   could call dtors, which could use cached hash */
			zend_hash_clean(EX(function_state).function_symbol_table);
			*(++EG(symtable_cache_ptr)) = EX(function_state).function_symbol_table;
		}
		EG(active_symbol_table) = EX(symbol_table);
	} else { /* ZEND_OVERLOADED_FUNCTION */
		ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
		INIT_ZVAL(*(EX_T(opline->result.u.var).var.ptr));

			/* Not sure what should be done here if it's a static method */
		if (EX(object)) {
			Z_OBJ_HT_P(EX(object))->call_method(EX(fbc)->common.function_name, opline->extended_value, EX_T(opline->result.u.var).var.ptr, &EX_T(opline->result.u.var).var.ptr, EX(object), return_value_used TSRMLS_CC);
		} else {
			zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
		}

		if (EX(function_state).function->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
			efree(EX(function_state).function->common.function_name);
		}
		efree(EX(fbc));

		if (!return_value_used) {
			zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
		} else {
			EX_T(opline->result.u.var).var.ptr->is_ref = 0;
			EX_T(opline->result.u.var).var.ptr->refcount = 1;
		}
	}

	EX(function_state).function = (zend_function *) EX(op_array);
	EG(function_state_ptr) = &EX(function_state);
	ctor_opline = (zend_op*)zend_ptr_stack_pop(&EG(arg_types_stack));

	if (EG(This)) {
		if (EG(exception) && ctor_opline) {
			if (RETURN_VALUE_USED(ctor_opline)) {
				EG(This)->refcount--;
			}
			if (EG(This)->refcount == 1) {
				zend_object_store_ctor_failed(EG(This) TSRMLS_CC);
			}
		}
		if (should_change_scope) {
			zval_ptr_dtor(&EG(This));
		}
	}

	if (should_change_scope) {
		EG(This) = current_this;
		EG(scope) = current_scope;
	}
	zend_arg_types_stack_2_pop(&EG(arg_types_stack), &EX(object), &EX(fbc));

	zend_ptr_stack_clear_multiple(TSRMLS_C);

	if (EG(exception)) {
		zend_throw_exception_internal(NULL TSRMLS_CC);
		if (return_value_used && EX_T(opline->result.u.var).var.ptr) {
			zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(61, ZEND_DO_FCALL_BY_NAME, ANY, ANY)
{
	EX(function_state).function = EX(fbc);
	ZEND_VM_DISPATCH_TO_HELPER(zend_do_fcall_common_helper);
}

ZEND_VM_HANDLER(60, ZEND_DO_FCALL, CONST, ANY)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *fname = GET_OP1_ZVAL_PTR(BP_VAR_R);

	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), NULL);

	if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) {
		zend_error_noreturn(E_ERROR, "Call to undefined function %s()", fname->value.str.val);
	}
	EX(object) = NULL;

	FREE_OP1();

	ZEND_VM_DISPATCH_TO_HELPER(zend_do_fcall_common_helper);
}

ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY)
{
	zend_op *opline = EX(opline);
	zval *retval_ptr;
	zval **retval_ptr_ptr;
	zend_free_op free_op1;

	if (EG(active_op_array)->return_reference == ZEND_RETURN_REF) {

		if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_TMP_VAR) {
			/* Not supposed to happen, but we'll allow it */
			zend_error(E_NOTICE, "Only variable references should be returned by reference");
			ZEND_VM_C_GOTO(return_by_value);
		}

		retval_ptr_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);

		if (!retval_ptr_ptr) {
			zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
		}

		if (OP1_TYPE == IS_VAR && !(*retval_ptr_ptr)->is_ref) {
			if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
			    EX_T(opline->op1.u.var).var.fcall_returned_reference) {
			} else if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
				if (OP1_TYPE == IS_VAR && !OP1_FREE) {
					PZVAL_LOCK(*retval_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
				}
				zend_error(E_NOTICE, "Only variable references should be returned by reference");
				ZEND_VM_C_GOTO(return_by_value);
			}
		}

		SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr_ptr);
		(*retval_ptr_ptr)->refcount++;

		(*EG(return_value_ptr_ptr)) = (*retval_ptr_ptr);
	} else {
ZEND_VM_C_LABEL(return_by_value):

		retval_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);

		if (EG(ze1_compatibility_mode) && Z_TYPE_P(retval_ptr) == IS_OBJECT) {
			zval *ret;
			char *class_name;
			zend_uint class_name_len;
			int dup;

			ALLOC_ZVAL(ret);
			INIT_PZVAL_COPY(ret, retval_ptr);
			dup = zend_get_object_classname(retval_ptr, &class_name, &class_name_len TSRMLS_CC);
			if (Z_OBJ_HT_P(retval_ptr)->clone_obj == NULL) {
				zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s",  class_name);
			}
			zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name);
			ret->value.obj = Z_OBJ_HT_P(retval_ptr)->clone_obj(retval_ptr TSRMLS_CC);
			*EG(return_value_ptr_ptr) = ret;
			if (!dup) {
				efree(class_name);
			}
		} else if (!IS_OP1_TMP_FREE()) { /* Not a temp var */
			if (EG(active_op_array)->return_reference == ZEND_RETURN_REF ||
			    (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0)) {
				zval *ret;

				ALLOC_ZVAL(ret);
				INIT_PZVAL_COPY(ret, retval_ptr);
				zval_copy_ctor(ret);
				*EG(return_value_ptr_ptr) = ret;
			} else if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) &&
			           retval_ptr == &EG(uninitialized_zval)) {
				zval *ret;

				ALLOC_INIT_ZVAL(ret);
				*EG(return_value_ptr_ptr) = ret;
			} else {
				*EG(return_value_ptr_ptr) = retval_ptr;
				retval_ptr->refcount++;
			}
		} else {
			zval *ret;

			ALLOC_ZVAL(ret);
			INIT_PZVAL_COPY(ret, retval_ptr);
			*EG(return_value_ptr_ptr) = ret;
		}
	}
	FREE_OP1_IF_VAR();
	ZEND_VM_RETURN_FROM_EXECUTE_LOOP();
}

ZEND_VM_HANDLER(108, ZEND_THROW, CONST|TMP|VAR|CV, ANY)
{
	zend_op *opline = EX(opline);
	zval *value;
	zval *exception;
	zend_free_op free_op1;

	value = GET_OP1_ZVAL_PTR(BP_VAR_R);

	if (Z_TYPE_P(value) != IS_OBJECT) {
		zend_error_noreturn(E_ERROR, "Can only throw objects");
	}
	/* Not sure if a complete copy is what we want here */
	ALLOC_ZVAL(exception);
	INIT_PZVAL_COPY(exception, value);
	if (!IS_OP1_TMP_FREE()) {
		zval_copy_ctor(exception);
	}

	zend_throw_exception_object(exception TSRMLS_CC);
	FREE_OP1_IF_VAR();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(107, ZEND_CATCH, ANY, ANY)
{
	zend_op *opline = EX(opline);
	zend_class_entry *ce;

	/* Check whether an exception has been thrown, if not, jump over code */
	if (EG(exception) == NULL) {
		ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->extended_value]);
		ZEND_VM_CONTINUE(); /* CHECK_ME */
	}
	ce = Z_OBJCE_P(EG(exception));
	if (ce != EX_T(opline->op1.u.var).class_entry) {
		if (!instanceof_function(ce, EX_T(opline->op1.u.var).class_entry TSRMLS_CC)) {
			if (opline->op1.u.EA.type) {
				zend_throw_exception_internal(NULL TSRMLS_CC);
				ZEND_VM_NEXT_OPCODE();
			}
			ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->extended_value]);
			ZEND_VM_CONTINUE(); /* CHECK_ME */
		}
	}

	zend_hash_update(EG(active_symbol_table), opline->op2.u.constant.value.str.val,
		opline->op2.u.constant.value.str.len+1, &EG(exception), sizeof(zval *), (void **) NULL);
	EG(exception) = NULL;
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(65, ZEND_SEND_VAL, CONST|TMP|VAR|CV, ANY)
{
	zend_op *opline = EX(opline);
	if (opline->extended_value==ZEND_DO_FCALL_BY_NAME
		&& ARG_MUST_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
			zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.u.opline_num);
	}
	{
		zval *valptr;
		zval *value;
		zend_free_op free_op1;

		value = GET_OP1_ZVAL_PTR(BP_VAR_R);

		ALLOC_ZVAL(valptr);
		INIT_PZVAL_COPY(valptr, value);
		if (!IS_OP1_TMP_FREE()) {
			zval_copy_ctor(valptr);
		}
		zend_ptr_stack_push(&EG(argument_stack), valptr);
		FREE_OP1_IF_VAR();
	}
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HELPER(zend_send_by_var_helper, VAR|CV, ANY)
{
	zend_op *opline = EX(opline);
	zval *varptr;
	zend_free_op free_op1;
	varptr = GET_OP1_ZVAL_PTR(BP_VAR_R);

	if (varptr == &EG(uninitialized_zval)) {
		ALLOC_ZVAL(varptr);
		INIT_ZVAL(*varptr);
		varptr->refcount = 0;
	} else if (PZVAL_IS_REF(varptr)) {
		zval *original_var = varptr;

		ALLOC_ZVAL(varptr);
		*varptr = *original_var;
		varptr->is_ref = 0;
		varptr->refcount = 0;
		zval_copy_ctor(varptr);
	}
	varptr->refcount++;
	zend_ptr_stack_push(&EG(argument_stack), varptr);
	FREE_OP1();  /* for string offsets */

	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR|CV, ANY)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *varptr;

	if (opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) { /* Had function_ptr at compile_time */
		if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF)) {
			ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper);
		}
	} else if (!ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
		ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper);
	}

	if (OP1_TYPE == IS_VAR &&
		(opline->extended_value & ZEND_ARG_SEND_FUNCTION) &&
		EX_T(opline->op1.u.var).var.fcall_returned_reference &&
		EX_T(opline->op1.u.var).var.ptr) {
		varptr = EX_T(opline->op1.u.var).var.ptr;
		PZVAL_UNLOCK_EX(varptr, &free_op1, 0);
	} else {
		varptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
	}
	if ((!(opline->extended_value & ZEND_ARG_SEND_FUNCTION) ||
	     EX_T(opline->op1.u.var).var.fcall_returned_reference) &&
	    varptr != &EG(uninitialized_zval) &&
	    (PZVAL_IS_REF(varptr) ||
	     (varptr->refcount == 1 && (OP1_TYPE == IS_CV || free_op1.var)))) {
		varptr->is_ref = 1;
		varptr->refcount++;
		zend_ptr_stack_push(&EG(argument_stack), varptr);
	} else {
		zval *valptr;

		if (!(opline->extended_value & ZEND_ARG_SEND_SILENT)) {
			zend_error(E_STRICT, "Only variables should be passed by reference");
		}
		ALLOC_ZVAL(valptr);
		INIT_PZVAL_COPY(valptr, varptr);
		if (!IS_OP1_TMP_FREE()) {
			zval_copy_ctor(valptr);
		}
		zend_ptr_stack_push(&EG(argument_stack), valptr);
	}
	FREE_OP1_IF_VAR();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, ANY)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval **varptr_ptr;
	zval *varptr;
	varptr_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);

	if (!varptr_ptr) {
		zend_error_noreturn(E_ERROR, "Only variables can be passed by reference");
	}

	if (OP1_TYPE == IS_VAR && *varptr_ptr == EG(error_zval_ptr)) {
		(*varptr_ptr)->refcount--;
		ALLOC_ZVAL(*varptr_ptr);
		INIT_ZVAL(**varptr_ptr);
		(*varptr_ptr)->refcount = 0;
	}

	if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION && !ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
		ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper);
	}

	SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr_ptr);
	varptr = *varptr_ptr;
	varptr->refcount++;
	zend_ptr_stack_push(&EG(argument_stack), varptr);

	FREE_OP1_VAR_PTR();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(66, ZEND_SEND_VAR, VAR|CV, ANY)
{
	zend_op *opline = EX(opline);

	if ((opline->extended_value == ZEND_DO_FCALL_BY_NAME)
		&& ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
		ZEND_VM_DISPATCH_TO_HANDLER(ZEND_SEND_REF);
	}
	ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper);
}

ZEND_VM_HANDLER(63, ZEND_RECV, ANY, ANY)
{
	zend_op *opline = EX(opline);
	zval **param;
	zend_uint arg_num = Z_LVAL(opline->op1.u.constant);

	if (zend_ptr_stack_get_arg(arg_num, (void **) &param TSRMLS_CC)==FAILURE) {
		char *space;
		char *class_name = get_active_class_name(&space TSRMLS_CC);
		zend_execute_data *ptr = EX(prev_execute_data);

		zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, NULL TSRMLS_CC);
		if(ptr && ptr->op_array) {
			zend_error(E_WARNING, "Missing argument %ld for %s%s%s(), called in %s on line %d and defined", opline->op1.u.constant.value.lval, class_name, space, get_active_function_name(TSRMLS_C), ptr->op_array->filename, ptr->opline->lineno);
		} else {
			zend_error(E_WARNING, "Missing argument %ld for %s%s%s()", opline->op1.u.constant.value.lval, class_name, space, get_active_function_name(TSRMLS_C));
		}
		if (opline->result.op_type == IS_VAR) {
			PZVAL_UNLOCK_FREE(*EX_T(opline->result.u.var).var.ptr_ptr);
		}
	} else {
		zend_free_op free_res;
		zval **var_ptr;

		zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param TSRMLS_CC);
		var_ptr = get_zval_ptr_ptr(&opline->result, EX(Ts), &free_res, BP_VAR_W);
		if (PZVAL_IS_REF(*param)) {
			zend_assign_to_variable_reference(var_ptr, param TSRMLS_CC);
		} else {
			zend_receive(var_ptr, *param TSRMLS_CC);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST)
{
	zend_op *opline = EX(opline);
	zval **param, *assignment_value;
	zend_uint arg_num = Z_LVAL(opline->op1.u.constant);
	zend_free_op free_res;

	if (zend_ptr_stack_get_arg(arg_num, (void **) &param TSRMLS_CC)==FAILURE) {
		if (Z_TYPE(opline->op2.u.constant) == IS_CONSTANT || Z_TYPE(opline->op2.u.constant)==IS_CONSTANT_ARRAY) {
			zval *default_value;

			ALLOC_ZVAL(default_value);
			*default_value = opline->op2.u.constant;
			default_value->refcount=1;
			zval_update_constant(&default_value, 0 TSRMLS_CC);
			default_value->refcount=0;
			default_value->is_ref=0;
			param = &default_value;
			assignment_value = default_value;
		} else {
			param = NULL;
			assignment_value = &opline->op2.u.constant;
		}
		zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value TSRMLS_CC);
		zend_assign_to_variable(NULL, &opline->result, NULL, assignment_value, IS_VAR, EX(Ts) TSRMLS_CC);
	} else {
		zval **var_ptr = get_zval_ptr_ptr(&opline->result, EX(Ts), &free_res, BP_VAR_W);

		assignment_value = *param;
		zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value TSRMLS_CC);
		if (PZVAL_IS_REF(assignment_value)) {
			zend_assign_to_variable_reference(var_ptr, param TSRMLS_CC);
		} else {
			zend_receive(var_ptr, assignment_value TSRMLS_CC);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(52, ZEND_BOOL, CONST|TMP|VAR|CV, ANY)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	/* PHP 3.0 returned "" for false and 1 for true, here we use 0 and 1 for now */
	Z_LVAL(EX_T(opline->result.u.var).tmp_var) = i_zend_is_true(GET_OP1_ZVAL_PTR(BP_VAR_R));
	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
	FREE_OP1();

	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(50, ZEND_BRK, ANY, CONST|TMP|VAR|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zend_brk_cont_element *el;

	el = zend_brk_cont(GET_OP2_ZVAL_PTR(BP_VAR_R), opline->op1.u.opline_num,
	                   EX(op_array), EX(Ts) TSRMLS_CC);
	FREE_OP2();
	ZEND_VM_JMP(EX(op_array)->opcodes + el->brk);
}

ZEND_VM_HANDLER(51, ZEND_CONT, ANY, CONST|TMP|VAR|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zend_brk_cont_element *el;

	el = zend_brk_cont(GET_OP2_ZVAL_PTR(BP_VAR_R), opline->op1.u.opline_num,
	                   EX(op_array), EX(Ts) TSRMLS_CC);
	FREE_OP2();
	ZEND_VM_JMP(EX(op_array)->opcodes + el->cont);
}

ZEND_VM_HANDLER(48, ZEND_CASE, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
{
	zend_op *opline = EX(opline);
	int switch_expr_is_overloaded=0;
	zend_free_op free_op1, free_op2;

	if (OP1_TYPE==IS_VAR) {
		if (EX_T(opline->op1.u.var).var.ptr_ptr) {
			PZVAL_LOCK(EX_T(opline->op1.u.var).var.ptr);
		} else {
			switch_expr_is_overloaded = 1;
			EX_T(opline->op1.u.var).str_offset.str->refcount++;
		}
	}
	is_equal_function(&EX_T(opline->result.u.var).tmp_var,
				 GET_OP1_ZVAL_PTR(BP_VAR_R),
				 GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);

	FREE_OP2();
	if (switch_expr_is_overloaded) {
		/* We only free op1 if this is a string offset,
		 * Since if it is a TMP_VAR, it'll be reused by
		 * other CASE opcodes (whereas string offsets
		 * are allocated at each get_zval_ptr())
		 */
		FREE_OP1();
		EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
		AI_USE_PTR(EX_T(opline->op1.u.var).var);
	}
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(49, ZEND_SWITCH_FREE, TMP|VAR, ANY)
{
	zend_switch_free(EX(opline), EX(Ts) TSRMLS_CC);
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(68, ZEND_NEW, ANY, ANY)
{
	zend_op *opline = EX(opline);
	zval *object_zval;
	zend_function *constructor;

	if (EX_T(opline->op1.u.var).class_entry->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
		char *class_type;

		if (EX_T(opline->op1.u.var).class_entry->ce_flags & ZEND_ACC_INTERFACE) {
			class_type = "interface";
		} else {
			class_type = "abstract class";
		}
		zend_error_noreturn(E_ERROR, "Cannot instantiate %s %s", class_type,  EX_T(opline->op1.u.var).class_entry->name);
	}
	ALLOC_ZVAL(object_zval);
	object_init_ex(object_zval, EX_T(opline->op1.u.var).class_entry);
	INIT_PZVAL(object_zval);

	constructor = Z_OBJ_HT_P(object_zval)->get_constructor(object_zval TSRMLS_CC);

	if (constructor == NULL) {
		if (RETURN_VALUE_USED(opline)) {
			EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
			EX_T(opline->result.u.var).var.ptr = object_zval;
		} else {
			zval_ptr_dtor(&object_zval);
		}
		ZEND_VM_JMP(EX(op_array)->opcodes + opline->op2.u.opline_num);
	} else {
		SELECTIVE_PZVAL_LOCK(object_zval, &opline->result);
		EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
		EX_T(opline->result.u.var).var.ptr = object_zval;

		zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), opline);

		/* We are not handling overloaded classes right now */
		EX(object) = object_zval;
		EX(fbc) = constructor;

		ZEND_VM_NEXT_OPCODE();
	}
}

ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMP|VAR|UNUSED|CV, ANY)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *obj = GET_OP1_OBJ_ZVAL_PTR(BP_VAR_R);
	zend_class_entry *ce;
	zend_function *clone;
	zend_object_clone_obj_t clone_call;

	if (!obj || Z_TYPE_P(obj) != IS_OBJECT) {
		zend_error_noreturn(E_ERROR, "__clone method called on non-object");
		EX_T(opline->result.u.var).var.ptr = EG(error_zval_ptr);
		EX_T(opline->result.u.var).var.ptr->refcount++;
		FREE_OP1_IF_VAR();
		ZEND_VM_NEXT_OPCODE();
	}

	ce = Z_OBJCE_P(obj);
	clone = ce ? ce->clone : NULL;
	clone_call =  Z_OBJ_HT_P(obj)->clone_obj;
	if (!clone_call) {
		if (ce) {
			zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", ce->name);
		} else {
			zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object");
		}
		EX_T(opline->result.u.var).var.ptr = EG(error_zval_ptr);
		EX_T(opline->result.u.var).var.ptr->refcount++;
	}

	if (ce && clone) {
		if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) {
			/* Ensure that if we're calling a private function, we're allowed to do so.
			 */
			if (ce != EG(scope)) {
				zend_error_noreturn(E_ERROR, "Call to private %s::__clone() from context '%s'", ce->name, EG(scope) ? EG(scope)->name : "");
			}
		} else if ((clone->common.fn_flags & ZEND_ACC_PROTECTED)) {
			/* Ensure that if we're calling a protected function, we're allowed to do so.
			 */
			if (!zend_check_protected(clone->common.scope, EG(scope))) {
				zend_error_noreturn(E_ERROR, "Call to protected %s::__clone() from context '%s'", ce->name, EG(scope) ? EG(scope)->name : "");
			}
		}
	}

	EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
	if (!EG(exception)) {
		ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
		Z_OBJVAL_P(EX_T(opline->result.u.var).var.ptr) = clone_call(obj TSRMLS_CC);
		Z_TYPE_P(EX_T(opline->result.u.var).var.ptr) = IS_OBJECT;
		EX_T(opline->result.u.var).var.ptr->refcount=1;
		EX_T(opline->result.u.var).var.ptr->is_ref=1;
		if (!RETURN_VALUE_USED(opline) || EG(exception)) {
			zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
		}
	}
	FREE_OP1_IF_VAR();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, CONST|UNUSED, CONST)
{
	zend_op *opline = EX(opline);
	zend_class_entry *ce = NULL;
	zval **value;

	if (OP1_TYPE == IS_UNUSED) {
/* This seems to be a reminant of namespaces
		if (EG(scope)) {
			ce = EG(scope);
			if (zend_hash_find(&ce->constants_table, Z_STRVAL(opline->op2.u.constant), Z_STRLEN(opline->op2.u.constant)+1, (void **) &value) == SUCCESS) {
				zval_update_constant(value, (void *) 1 TSRMLS_CC);
				EX_T(opline->result.u.var).tmp_var = **value;
				zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var);
				ZEND_VM_NEXT_OPCODE();
			}
		}
*/
		if (!zend_get_constant(opline->op2.u.constant.value.str.val, opline->op2.u.constant.value.str.len, &EX_T(opline->result.u.var).tmp_var TSRMLS_CC)) {
			zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'",
						opline->op2.u.constant.value.str.val,
						opline->op2.u.constant.value.str.val);
			EX_T(opline->result.u.var).tmp_var = opline->op2.u.constant;
			zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var);
		}
		ZEND_VM_NEXT_OPCODE();
	}

	ce = EX_T(opline->op1.u.var).class_entry;

	if (zend_hash_find(&ce->constants_table, opline->op2.u.constant.value.str.val, opline->op2.u.constant.value.str.len+1, (void **) &value) == SUCCESS) {
		zend_class_entry *old_scope = EG(scope);

		EG(scope) = ce;
		zval_update_constant(value, (void *) 1 TSRMLS_CC);
		EG(scope) = old_scope;
		EX_T(opline->result.u.var).tmp_var = **value;
		zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var);
	} else {
		zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", opline->op2.u.constant.value.str.val);
	}

	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMP|VAR|UNUSED|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *array_ptr = &EX_T(opline->result.u.var).tmp_var;
	zval *expr_ptr;
	zval *offset=GET_OP2_ZVAL_PTR(BP_VAR_R);

#if !defined(ZEND_VM_SPEC) || OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV
	zval **expr_ptr_ptr = NULL;

	if (opline->extended_value) {
		expr_ptr_ptr=GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
		expr_ptr = *expr_ptr_ptr;
	} else {
		expr_ptr=GET_OP1_ZVAL_PTR(BP_VAR_R);
	}
#else
	expr_ptr=GET_OP1_ZVAL_PTR(BP_VAR_R);
#endif

	if (IS_OP1_TMP_FREE()) { /* temporary variable */
		zval *new_expr;

		ALLOC_ZVAL(new_expr);
		INIT_PZVAL_COPY(new_expr, expr_ptr);
		expr_ptr = new_expr;
	} else {
#if !defined(ZEND_VM_SPEC) || OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV
		if (opline->extended_value) {
			SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr_ptr);
			expr_ptr = *expr_ptr_ptr;
			expr_ptr->refcount++;
		} else 
#endif
		if (PZVAL_IS_REF(expr_ptr)) {
			zval *new_expr;

			ALLOC_ZVAL(new_expr);
			INIT_PZVAL_COPY(new_expr, expr_ptr);
			expr_ptr = new_expr;
			zendi_zval_copy_ctor(*expr_ptr);
		} else {
			expr_ptr->refcount++;
		}
	}
	if (offset) {
		switch (Z_TYPE_P(offset)) {
			case IS_DOUBLE:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_LONG:
			case IS_BOOL:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), Z_LVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_STRING:
				zend_symtable_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_NULL:
				zend_hash_update(Z_ARRVAL_P(array_ptr), "", sizeof(""), &expr_ptr, sizeof(zval *), NULL);
				break;
			default:
				zend_error(E_WARNING, "Illegal offset type");
				zval_ptr_dtor(&expr_ptr);
				/* do nothing */
				break;
		}
		FREE_OP2();
	} else {
		zend_hash_next_index_insert(Z_ARRVAL_P(array_ptr), &expr_ptr, sizeof(zval *), NULL);
	}
	if (opline->extended_value) {
		FREE_OP1_VAR_PTR();
	} else {
		FREE_OP1_IF_VAR();
	}
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(71, ZEND_INIT_ARRAY, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
{
	zend_op *opline = EX(opline);

	array_init(&EX_T(opline->result.u.var).tmp_var);
	if (OP1_TYPE == IS_UNUSED) {
		ZEND_VM_NEXT_OPCODE();
#if !defined(ZEND_VM_SPEC) || OP1_TYPE != IS_UNUSED
	} else {
		ZEND_VM_DISPATCH_TO_HANDLER(ZEND_ADD_ARRAY_ELEMENT);
#endif
	}
}

ZEND_VM_HANDLER(21, ZEND_CAST, CONST|TMP|VAR|CV, ANY)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *expr = GET_OP1_ZVAL_PTR(BP_VAR_R);
	zval *result = &EX_T(opline->result.u.var).tmp_var;

	if (opline->extended_value != IS_STRING) {
		*result = *expr;
		if (!IS_OP1_TMP_FREE()) {
			zendi_zval_copy_ctor(*result);
		}
	}
	switch (opline->extended_value) {
		case IS_NULL:
			convert_to_null(result);
			break;
		case IS_BOOL:
			convert_to_boolean(result);
			break;
		case IS_LONG:
			convert_to_long(result);
			break;
		case IS_DOUBLE:
			convert_to_double(result);
			break;
		case IS_STRING: {
			zval var_copy;
			int use_copy;

			zend_make_printable_zval(expr, &var_copy, &use_copy);
			if (use_copy) {
				*result = var_copy;
				if (IS_OP1_TMP_FREE()) {
					FREE_OP1();
				}
			} else {
				*result = *expr;
				if (!IS_OP1_TMP_FREE()) {
					zendi_zval_copy_ctor(*result);
				}
			}
			break;
		}
		case IS_ARRAY:
			convert_to_array(result);
			break;
		case IS_OBJECT:
			convert_to_object(result);
			break;
	}
	FREE_OP1_IF_VAR();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMP|VAR|CV, ANY)
{
	zend_op *opline = EX(opline);
	zend_op_array *new_op_array=NULL;
	zval **original_return_value = EG(return_value_ptr_ptr);
	int return_value_used;
	zend_free_op free_op1;
	zval *inc_filename = GET_OP1_ZVAL_PTR(BP_VAR_R);
	zval tmp_inc_filename;
	zend_bool failure_retval=0;

	if (inc_filename->type!=IS_STRING) {
		tmp_inc_filename = *inc_filename;
		zval_copy_ctor(&tmp_inc_filename);
		convert_to_string(&tmp_inc_filename);
		inc_filename = &tmp_inc_filename;
	}

	return_value_used = RETURN_VALUE_USED(opline);

	switch (Z_LVAL(opline->op2.u.constant)) {
		case ZEND_INCLUDE_ONCE:
		case ZEND_REQUIRE_ONCE: {
				zend_file_handle file_handle;

				if (IS_ABSOLUTE_PATH(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename))) {
					cwd_state state;
	
					state.cwd_length = 0;
					state.cwd = malloc(1);
					state.cwd[0] = 0;

					failure_retval = (!virtual_file_ex(&state, Z_STRVAL_P(inc_filename), NULL, 1) &&
						zend_hash_exists(&EG(included_files), state.cwd, state.cwd_length+1));

					free(state.cwd);
				}

				if (failure_retval) {
					/* do nothing */
				} else if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) {

					if (!file_handle.opened_path) {
						file_handle.opened_path = estrndup(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename));
					}

					if (zend_hash_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1)==SUCCESS) {
						new_op_array = zend_compile_file(&file_handle, (Z_LVAL(opline->op2.u.constant)==ZEND_INCLUDE_ONCE?ZEND_INCLUDE:ZEND_REQUIRE) TSRMLS_CC);
						zend_destroy_file_handle(&file_handle TSRMLS_CC);
					} else {
						zend_file_handle_dtor(&file_handle);
						failure_retval=1;
					}
				} else {
					if (Z_LVAL(opline->op2.u.constant)==ZEND_INCLUDE_ONCE) {
						zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, Z_STRVAL_P(inc_filename));
					} else {
						zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename));
					}
				}
			}
			break;
		case ZEND_INCLUDE:
		case ZEND_REQUIRE:
			new_op_array = compile_filename(Z_LVAL(opline->op2.u.constant), inc_filename TSRMLS_CC);
			break;
		case ZEND_EVAL: {
				char *eval_desc = zend_make_compiled_string_description("eval()'d code" TSRMLS_CC);

				new_op_array = zend_compile_string(inc_filename, eval_desc TSRMLS_CC);
				efree(eval_desc);
			}
			break;
		EMPTY_SWITCH_DEFAULT_CASE()
	}
	if (inc_filename==&tmp_inc_filename) {
		zval_dtor(&tmp_inc_filename);
	}
	EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
	if (new_op_array) {
		zval *saved_object;
		zend_function *saved_function;

		EG(return_value_ptr_ptr) = EX_T(opline->result.u.var).var.ptr_ptr;
		EG(active_op_array) = new_op_array;
		EX_T(opline->result.u.var).var.ptr = NULL;

		saved_object = EX(object);
		saved_function = EX(function_state).function;

		EX(function_state).function = (zend_function *) new_op_array;
		EX(object) = NULL;

		zend_execute(new_op_array TSRMLS_CC);

		EX(function_state).function = saved_function;
		EX(object) = saved_object;

		if (!return_value_used) {
			if (EX_T(opline->result.u.var).var.ptr) {
				zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
			}
		} else { /* return value is used */
			if (!EX_T(opline->result.u.var).var.ptr) { /* there was no return statement */
				ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
				INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);
				Z_LVAL_P(EX_T(opline->result.u.var).var.ptr) = 1;
				Z_TYPE_P(EX_T(opline->result.u.var).var.ptr) = IS_BOOL;
			}
		}

		EG(opline_ptr) = &EX(opline);
		EG(active_op_array) = EX(op_array);
		EG(function_state_ptr) = &EX(function_state);
		destroy_op_array(new_op_array TSRMLS_CC);
		efree(new_op_array);
		if (EG(exception)) {
			zend_throw_exception_internal(NULL TSRMLS_CC);
		}
	} else {
		if (return_value_used) {
			ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
			INIT_ZVAL(*EX_T(opline->result.u.var).var.ptr);
			Z_LVAL_P(EX_T(opline->result.u.var).var.ptr) = failure_retval;
			Z_TYPE_P(EX_T(opline->result.u.var).var.ptr) = IS_BOOL;
		}
	}
	FREE_OP1();
	EG(return_value_ptr_ptr) = original_return_value;
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMP|VAR|CV, ANY)
{
	zend_op *opline = EX(opline);
	zval tmp, *varname;
	HashTable *target_symbol_table;
	zend_free_op free_op1;

	varname = GET_OP1_ZVAL_PTR(BP_VAR_R);

	if (Z_TYPE_P(varname) != IS_STRING) {
		tmp = *varname;
		zval_copy_ctor(&tmp);
		convert_to_string(&tmp);
		varname = &tmp;
	} else if (OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) {
		varname->refcount++;
	}

	if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
		zend_std_unset_static_property(EX_T(opline->op2.u.var).class_entry, Z_STRVAL_P(varname), Z_STRLEN_P(varname) TSRMLS_CC);
	} else {
		target_symbol_table = zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
		if (zend_hash_del(target_symbol_table, varname->value.str.val, varname->value.str.len+1) == SUCCESS) {		
			zend_execute_data *ex = EXECUTE_DATA; 
			ulong hash_value = zend_inline_hash_func(varname->value.str.val, varname->value.str.len+1);

			do {
				int i;

				if (ex->op_array) {
					for (i = 0; i < ex->op_array->last_var; i++) {
						if (ex->op_array->vars[i].hash_value == hash_value &&
							ex->op_array->vars[i].name_len == varname->value.str.len &&
							!memcmp(ex->op_array->vars[i].name, varname->value.str.val, varname->value.str.len)) {
							ex->CVs[i] = NULL;
							break;
						}
					}
				}
				ex = ex->prev_execute_data;
			} while (ex && ex->symbol_table == target_symbol_table);
		}
	}

	if (varname == &tmp) {
		zval_dtor(&tmp);
	} else if (OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) {
		zval_ptr_dtor(&varname);
	}
	FREE_OP1();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(75, ZEND_UNSET_DIM, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval **container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_UNSET);
	zval *offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
	long index;

	if (container) {
		if (OP1_TYPE == IS_CV && container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
		switch (Z_TYPE_PP(container)) {
			case IS_ARRAY: {
				HashTable *ht = Z_ARRVAL_PP(container);

				switch (Z_TYPE_P(offset)) {
					case IS_DOUBLE:
						index = (long) Z_DVAL_P(offset);
						zend_hash_index_del(ht, index);
						break;
					case IS_RESOURCE:
					case IS_BOOL:
					case IS_LONG:
						index = Z_LVAL_P(offset);
						zend_hash_index_del(ht, index);
						break;
					case IS_STRING:
						if (OP2_TYPE == IS_CV || OP2_TYPE == IS_VAR) {
							offset->refcount++;
						}
						if (zend_symtable_del(ht, offset->value.str.val, offset->value.str.len+1) == SUCCESS &&
					    ht == &EG(symbol_table)) {
							zend_execute_data *ex;
							ulong hash_value = zend_inline_hash_func(offset->value.str.val, offset->value.str.len+1);

							for (ex = EXECUTE_DATA; ex; ex = ex->prev_execute_data) {
								if (ex->op_array && ex->symbol_table == ht) {
									int i;

									for (i = 0; i < ex->op_array->last_var; i++) {
										if (ex->op_array->vars[i].hash_value == hash_value &&
										    ex->op_array->vars[i].name_len == offset->value.str.len &&
										    !memcmp(ex->op_array->vars[i].name, offset->value.str.val, offset->value.str.len)) {
											ex->CVs[i] = NULL;
											break;
										}
									}
								}
							}
						}
						if (OP2_TYPE == IS_CV || OP2_TYPE == IS_VAR) {
							zval_ptr_dtor(&offset);
						}
						break;
					case IS_NULL:
						zend_hash_del(ht, "", sizeof(""));
						break;
					default:
						zend_error(E_WARNING, "Illegal offset type in unset");
						break;
				}
				FREE_OP2();
				break;
			}
			case IS_OBJECT:
				if (!Z_OBJ_HT_P(*container)->unset_dimension) {
					zend_error_noreturn(E_ERROR, "Cannot use object as array");
				}
				if (IS_OP2_TMP_FREE()) {
					MAKE_REAL_ZVAL_PTR(offset);
				}
				Z_OBJ_HT_P(*container)->unset_dimension(*container, offset TSRMLS_CC);
				if (IS_OP2_TMP_FREE()) {
					zval_ptr_dtor(&offset);
				} else {
					FREE_OP2();
				}
				break;
			case IS_STRING:
				zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
				ZEND_VM_CONTINUE(); /* bailed out before */
			default:
				FREE_OP2();
				break;
		}
	} else {
		FREE_OP2();
	}
	FREE_OP1_VAR_PTR();

	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval **container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_UNSET);
	zval *offset = GET_OP2_ZVAL_PTR(BP_VAR_R);

	if (container) {
		if (OP1_TYPE == IS_CV && container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
		if (Z_TYPE_PP(container) == IS_OBJECT) {
			if (IS_OP2_TMP_FREE()) {
				MAKE_REAL_ZVAL_PTR(offset);
			}
			Z_OBJ_HT_P(*container)->unset_property(*container, offset TSRMLS_CC);
			if (IS_OP2_TMP_FREE()) {
				zval_ptr_dtor(&offset);
			} else {
				FREE_OP2();
			}
		} else {
			FREE_OP2();
		}
	} else {
		FREE_OP2();
	}
	FREE_OP1_VAR_PTR();

	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *array_ptr, **array_ptr_ptr;
	HashTable *fe_ht;
	zend_object_iterator *iter = NULL;
	zend_class_entry *ce = NULL;
	zend_bool is_empty = 0;

	if (opline->extended_value & ZEND_FE_RESET_VARIABLE) {
		array_ptr_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_R);
		if (array_ptr_ptr == NULL || array_ptr_ptr == &EG(uninitialized_zval_ptr)) {
			ALLOC_INIT_ZVAL(array_ptr);
		} else if (Z_TYPE_PP(array_ptr_ptr) == IS_OBJECT) {
			if(Z_OBJ_HT_PP(array_ptr_ptr)->get_class_entry == NULL) {
				zend_error(E_WARNING, "foreach() can not iterate over objects without PHP class");
				ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.u.opline_num);
			}

			ce = Z_OBJCE_PP(array_ptr_ptr);
			if (!ce || ce->get_iterator == NULL) {
				SEPARATE_ZVAL_IF_NOT_REF(array_ptr_ptr);
				(*array_ptr_ptr)->refcount++;
			}
			array_ptr = *array_ptr_ptr;
		} else {
			if (Z_TYPE_PP(array_ptr_ptr) == IS_ARRAY) {
				SEPARATE_ZVAL_IF_NOT_REF(array_ptr_ptr);
				if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
					(*array_ptr_ptr)->is_ref = 1;
				}
			}
			array_ptr = *array_ptr_ptr;
			array_ptr->refcount++;
		}
	} else {
		array_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
		if (IS_OP1_TMP_FREE()) { /* IS_TMP_VAR */
			zval *tmp;

			ALLOC_ZVAL(tmp);
			INIT_PZVAL_COPY(tmp, array_ptr);
			array_ptr = tmp;
			if (Z_TYPE_P(array_ptr) == IS_OBJECT) {
				ce = Z_OBJCE_P(array_ptr);
				if (ce && ce->get_iterator) {
					array_ptr->refcount--;
				}
			}
		} else if (Z_TYPE_P(array_ptr) == IS_OBJECT) {
			ce = Z_OBJCE_P(array_ptr);
			if (!ce || !ce->get_iterator) {
				array_ptr->refcount++;
			}
		} else {
			if (OP1_TYPE == IS_CONST ||
			    ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) &&
			    !array_ptr->is_ref &&
			    array_ptr->refcount > 1)) {
				zval *tmp;

				ALLOC_ZVAL(tmp);
				INIT_PZVAL_COPY(tmp, array_ptr);
				zval_copy_ctor(tmp);
				array_ptr = tmp;
			} else {
				array_ptr->refcount++;
			}
		}
	}

	if (ce && ce->get_iterator) {
		iter = ce->get_iterator(ce, array_ptr, opline->extended_value & ZEND_FE_RESET_REFERENCE TSRMLS_CC);

		if (iter && !EG(exception)) {
			array_ptr = zend_iterator_wrap(iter TSRMLS_CC);
		} else {
			if (opline->extended_value & ZEND_FE_RESET_VARIABLE) {
				FREE_OP1_VAR_PTR();
			} else {
				FREE_OP1_IF_VAR();
			}
			if (!EG(exception)) {
				zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Object of type %s did not create an Iterator", ce->name);
			}
			zend_throw_exception_internal(NULL TSRMLS_CC);
			ZEND_VM_NEXT_OPCODE();
		}
	}

	PZVAL_LOCK(array_ptr);
	EX_T(opline->result.u.var).var.ptr = array_ptr;
	EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;

	if (iter) {
		iter->index = 0;
		if (iter->funcs->rewind) {
			iter->funcs->rewind(iter TSRMLS_CC);
			if (EG(exception)) {
				array_ptr->refcount--;
				zval_ptr_dtor(&array_ptr);
				if (opline->extended_value & ZEND_FE_RESET_VARIABLE) {
					FREE_OP1_VAR_PTR();
				} else {
					FREE_OP1_IF_VAR();
				}
				ZEND_VM_NEXT_OPCODE();
			}
		}
		is_empty = iter->funcs->valid(iter TSRMLS_CC) != SUCCESS;
		if (EG(exception)) {
			array_ptr->refcount--;
			zval_ptr_dtor(&array_ptr);
			if (opline->extended_value & ZEND_FE_RESET_VARIABLE) {
				FREE_OP1_VAR_PTR();
			} else {
				FREE_OP1_IF_VAR();
			}
			ZEND_VM_NEXT_OPCODE();
		}
		iter->index = -1; /* will be set to 0 before using next handler */
	} else if ((fe_ht = HASH_OF(array_ptr)) != NULL) {
		zend_hash_internal_pointer_reset(fe_ht);
		if (ce) {
			zend_object *zobj = zend_objects_get_address(array_ptr TSRMLS_CC);
			while (zend_hash_has_more_elements(fe_ht) == SUCCESS) {
				char *str_key;
				uint str_key_len;
				ulong int_key;
				zend_uchar key_type;

				key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 0, NULL);
				if (key_type != HASH_KEY_NON_EXISTANT &&
					(key_type == HASH_KEY_IS_LONG ||
				     zend_check_property_access(zobj, str_key, str_key_len-1 TSRMLS_CC) == SUCCESS)) {
					break;
				}
				zend_hash_move_forward(fe_ht);
			}
		}
		is_empty = zend_hash_has_more_elements(fe_ht) != SUCCESS;
		zend_hash_get_pointer(fe_ht, &EX_T(opline->result.u.var).fe.fe_pos);
	} else {
		zend_error(E_WARNING, "Invalid argument supplied for foreach()");
		is_empty = 1;
	}

	if (opline->extended_value & ZEND_FE_RESET_VARIABLE) {
		FREE_OP1_VAR_PTR();
	} else {
		FREE_OP1_IF_VAR();
	}
	if (is_empty) {
		ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.u.opline_num);
	} else {
		ZEND_VM_NEXT_OPCODE();
	}
}

ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *array = GET_OP1_ZVAL_PTR(BP_VAR_R);
	zval **value;
	char *str_key;
	uint str_key_len;
	ulong int_key;
	HashTable *fe_ht;
	zend_object_iterator *iter = NULL;
	int key_type = 0;
	zend_bool use_key = (zend_bool)(opline->extended_value & ZEND_FE_FETCH_WITH_KEY);

	PZVAL_LOCK(array);

	switch (zend_iterator_unwrap(array, &iter TSRMLS_CC)) {
		default:
		case ZEND_ITER_INVALID:
			zend_error(E_WARNING, "Invalid argument supplied for foreach()");
			ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.u.opline_num);

		case ZEND_ITER_PLAIN_OBJECT: {
			char *class_name, *prop_name;
			zend_object *zobj = zend_objects_get_address(array TSRMLS_CC);

			fe_ht = HASH_OF(array);
			zend_hash_set_pointer(fe_ht, &EX_T(opline->op1.u.var).fe.fe_pos);
			do {
				if (zend_hash_get_current_data(fe_ht, (void **) &value)==FAILURE) {
					/* reached end of iteration */
					ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.u.opline_num);
				}
				key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 0, NULL);

				zend_hash_move_forward(fe_ht);
			} while (key_type == HASH_KEY_NON_EXISTANT ||
			         (key_type != HASH_KEY_IS_LONG &&
			          zend_check_property_access(zobj, str_key, str_key_len-1 TSRMLS_CC) != SUCCESS));
			zend_hash_get_pointer(fe_ht, &EX_T(opline->op1.u.var).fe.fe_pos);
			if (use_key && key_type != HASH_KEY_IS_LONG) {
				zend_unmangle_property_name(str_key, str_key_len-1, &class_name, &prop_name);
				str_key_len = strlen(prop_name);
				str_key = estrndup(prop_name, str_key_len);
				str_key_len++;
			}
			break;
		}

		case ZEND_ITER_PLAIN_ARRAY:
			fe_ht = HASH_OF(array);
			zend_hash_set_pointer(fe_ht, &EX_T(opline->op1.u.var).fe.fe_pos);
			if (zend_hash_get_current_data(fe_ht, (void **) &value)==FAILURE) {
				/* reached end of iteration */
				ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.u.opline_num);
			}
			if (use_key) {
				key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 1, NULL);
			}
			zend_hash_move_forward(fe_ht);
			zend_hash_get_pointer(fe_ht, &EX_T(opline->op1.u.var).fe.fe_pos);
			break;

		case ZEND_ITER_OBJECT:
			/* !iter happens from exception */
			if (iter && ++iter->index > 0) {
				/* This could cause an endless loop if index becomes zero again.
				 * In case that ever happens we need an additional flag. */
				iter->funcs->move_forward(iter TSRMLS_CC);
				if (EG(exception)) {
					array->refcount--;
					zval_ptr_dtor(&array);
					ZEND_VM_NEXT_OPCODE();
				}
			}
			/* If index is zero we come from FE_RESET and checked valid() already. */
			if (!iter || (iter->index > 0 && iter->funcs->valid(iter TSRMLS_CC) == FAILURE)) {
				/* reached end of iteration */
				if (EG(exception)) {
					array->refcount--;
					zval_ptr_dtor(&array);
					ZEND_VM_NEXT_OPCODE();
				}
				ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.u.opline_num);
			}
			iter->funcs->get_current_data(iter, &value TSRMLS_CC);
			if (EG(exception)) {
				array->refcount--;
				zval_ptr_dtor(&array);
				ZEND_VM_NEXT_OPCODE();
			}
			if (!value) {
				/* failure in get_current_data */
				ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.u.opline_num);
			}
			if (use_key) {
				if (iter->funcs->get_current_key) {
					key_type = iter->funcs->get_current_key(iter, &str_key, &str_key_len, &int_key TSRMLS_CC);
					if (EG(exception)) {
						array->refcount--;
						zval_ptr_dtor(&array);
						ZEND_VM_NEXT_OPCODE();
					}
				} else {
					key_type = HASH_KEY_IS_LONG;
					int_key = iter->index;
				}
			}
			break;
	}

	if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
		SEPARATE_ZVAL_IF_NOT_REF(value);
		(*value)->is_ref = 1;
		EX_T(opline->result.u.var).var.ptr_ptr = value;
		(*value)->refcount++;
	} else {
		EX_T(opline->result.u.var).var.ptr_ptr = value;
		PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
	}

	if (use_key) {
		zend_op *op_data = opline+1;
		zval *key = &EX_T(op_data->result.u.var).tmp_var;

		switch (key_type) {
			case HASH_KEY_IS_STRING:
				Z_STRVAL_P(key) = str_key;
				Z_STRLEN_P(key) = str_key_len-1;
				Z_TYPE_P(key) = IS_STRING;
				break;
			case HASH_KEY_IS_LONG:
				Z_LVAL_P(key) = int_key;
				Z_TYPE_P(key) = IS_LONG;
				break;
			default:
			case HASH_KEY_NON_EXISTANT:
				ZVAL_NULL(key);
				break;
		}
	}

	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMP|VAR|CV, ANY)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval tmp, *varname = GET_OP1_ZVAL_PTR(BP_VAR_IS);
	zval **value;
	zend_bool isset = 1;
	HashTable *target_symbol_table;

	if (Z_TYPE_P(varname) != IS_STRING) {
		tmp = *varname;
		zval_copy_ctor(&tmp);
		convert_to_string(&tmp);
		varname = &tmp;
	}

	if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
		value = zend_std_get_static_property(EX_T(opline->op2.u.var).class_entry, Z_STRVAL_P(varname), Z_STRLEN_P(varname), 1 TSRMLS_CC);
		if (!value) {
			isset = 0;
		}
	} else {
		target_symbol_table = zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
		if (zend_hash_find(target_symbol_table, varname->value.str.val, varname->value.str.len+1, (void **) &value) == FAILURE) {
			isset = 0;
		}
	}

	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;

	switch (opline->extended_value) {
		case ZEND_ISSET:
			if (isset && Z_TYPE_PP(value) == IS_NULL) {
				Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 0;
			} else {
				Z_LVAL(EX_T(opline->result.u.var).tmp_var) = isset;
			}
			break;
		case ZEND_ISEMPTY:
			if (!isset || !i_zend_is_true(*value)) {
				Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 1;
			} else {
				Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 0;
			}
			break;
	}

	if (varname == &tmp) {
		zval_dtor(&tmp);
	}
	FREE_OP1();

	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HELPER_EX(zend_isset_isempty_dim_prop_obj_handler, VAR|UNUSED|CV, CONST|TMP|VAR|CV, int prop_dim)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval **container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_IS);
	zval **value = NULL;
	int result = 0;
	long index;

	if (container) {
		zend_free_op free_op2;
		zval *offset = GET_OP2_ZVAL_PTR(BP_VAR_R);

		if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
			HashTable *ht;
			int isset = 0;

			ht = Z_ARRVAL_PP(container);

			switch (Z_TYPE_P(offset)) {
				case IS_DOUBLE:
					index = (long) Z_DVAL_P(offset);
					if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_RESOURCE:
				case IS_BOOL:
				case IS_LONG:
					index = Z_LVAL_P(offset);
					if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_STRING:
					if (zend_symtable_find(ht, offset->value.str.val, offset->value.str.len+1, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_NULL:
					if (zend_hash_find(ht, "", sizeof(""), (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				default:
					zend_error(E_WARNING, "Illegal offset type in isset or empty");

					break;
			}

			switch (opline->extended_value) {
				case ZEND_ISSET:
					if (isset && Z_TYPE_PP(value) == IS_NULL) {
						result = 0;
					} else {
						result = isset;
					}
					break;
				case ZEND_ISEMPTY:
					if (!isset || !i_zend_is_true(*value)) {
						result = 0;
					} else {
						result = 1;
					}
					break;
			}
			FREE_OP2();
		} else if (Z_TYPE_PP(container) == IS_OBJECT) {
			if (IS_OP2_TMP_FREE()) {
				MAKE_REAL_ZVAL_PTR(offset);
			}
			if (prop_dim) {
				result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value == ZEND_ISEMPTY) TSRMLS_CC);
			} else {
				result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value == ZEND_ISEMPTY) TSRMLS_CC);
			}
			if (IS_OP2_TMP_FREE()) {
				zval_ptr_dtor(&offset);
			} else {
				FREE_OP2();
			}
		} else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
			zval tmp;

			if (Z_TYPE_P(offset) != IS_LONG) {
				tmp = *offset;
				zval_copy_ctor(&tmp);
				convert_to_long(&tmp);
				offset = &tmp;
			}
			if (Z_TYPE_P(offset) == IS_LONG) {
				switch (opline->extended_value) {
					case ZEND_ISSET:
						if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
							result = 1;
						}
						break;
					case ZEND_ISEMPTY:
						if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
							result = 1;
						}
						break;
				}
			}
			FREE_OP2();
		} else {
			FREE_OP2();
		}
	}

	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;

	switch (opline->extended_value) {
		case ZEND_ISSET:
			Z_LVAL(EX_T(opline->result.u.var).tmp_var) = result;
			break;
		case ZEND_ISEMPTY:
			Z_LVAL(EX_T(opline->result.u.var).tmp_var) = !result;
			break;
	}

	FREE_OP1_VAR_PTR();

	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(115, ZEND_ISSET_ISEMPTY_DIM_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
{
	ZEND_VM_DISPATCH_TO_HELPER_EX(zend_isset_isempty_dim_prop_obj_handler, prop_dim, 0);
}

ZEND_VM_HANDLER(148, ZEND_ISSET_ISEMPTY_PROP_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
{
	ZEND_VM_DISPATCH_TO_HELPER_EX(zend_isset_isempty_dim_prop_obj_handler, prop_dim, 1);
}

ZEND_VM_HANDLER(79, ZEND_EXIT, CONST|TMP|VAR|UNUSED|CV, ANY)
{
#if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
	zend_op *opline = EX(opline);
	if (OP1_TYPE != IS_UNUSED) {
		zend_free_op free_op1;
		zval *ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);

		if (Z_TYPE_P(ptr) == IS_LONG) {
			EG(exit_status) = Z_LVAL_P(ptr);
		} else {
			zend_print_variable(ptr);
		}
		FREE_OP1();
	}
#endif
	zend_bailout();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(57, ZEND_BEGIN_SILENCE, ANY, ANY)
{
	zend_op *opline = EX(opline);

	Z_LVAL(EX_T(opline->result.u.var).tmp_var) = EG(error_reporting);
	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_LONG;  /* shouldn't be necessary */
	if (EX(old_error_reporting) == NULL) {
		EX(old_error_reporting) = &EX_T(opline->result.u.var).tmp_var;
	}

	if (EG(error_reporting)) {
		zend_alter_ini_entry_ex("error_reporting", sizeof("error_reporting"), "0", 1, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME, 1);
	}
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(142, ZEND_RAISE_ABSTRACT_ERROR, ANY, ANY)
{
	zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", EG(scope)->name, EX(op_array)->function_name);
	ZEND_VM_NEXT_OPCODE(); /* Never reached */
}

ZEND_VM_HANDLER(58, ZEND_END_SILENCE, TMP, ANY)
{
	zend_op *opline = EX(opline);
	zval restored_error_reporting;

	if (!EG(error_reporting) && Z_LVAL(EX_T(opline->op1.u.var).tmp_var) != 0) {
		Z_TYPE(restored_error_reporting) = IS_LONG;
		Z_LVAL(restored_error_reporting) = Z_LVAL(EX_T(opline->op1.u.var).tmp_var);
		convert_to_string(&restored_error_reporting);
		zend_alter_ini_entry_ex("error_reporting", sizeof("error_reporting"), Z_STRVAL(restored_error_reporting), Z_STRLEN(restored_error_reporting), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME, 1);
		zendi_zval_dtor(restored_error_reporting);
	}
	if (EX(old_error_reporting) == &EX_T(opline->op1.u.var).tmp_var) {
		EX(old_error_reporting) = NULL;
	}
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(22, ZEND_QM_ASSIGN, CONST|TMP|VAR|CV, ANY)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *value = GET_OP1_ZVAL_PTR(BP_VAR_R);

	EX_T(opline->result.u.var).tmp_var = *value;
	if (!IS_OP1_TMP_FREE()) {
		zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var);
	}
	FREE_OP1_IF_VAR();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(101, ZEND_EXT_STMT, ANY, ANY)
{
	if (!EG(no_extensions)) {
		zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_statement_handler, EX(op_array) TSRMLS_CC);
	}
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(102, ZEND_EXT_FCALL_BEGIN, ANY, ANY)
{
	if (!EG(no_extensions)) {
		zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_fcall_begin_handler, EX(op_array) TSRMLS_CC);
	}
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(103, ZEND_EXT_FCALL_END, ANY, ANY)
{
	if (!EG(no_extensions)) {
		zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_fcall_end_handler, EX(op_array) TSRMLS_CC);
	}
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(139, ZEND_DECLARE_CLASS, ANY, ANY)
{
	zend_op *opline = EX(opline);

	EX_T(opline->result.u.var).class_entry = do_bind_class(opline, EG(class_table), 0 TSRMLS_CC);
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(140, ZEND_DECLARE_INHERITED_CLASS, ANY, ANY)
{
	zend_op *opline = EX(opline);

	EX_T(opline->result.u.var).class_entry = do_bind_inherited_class(opline, EG(class_table), EX_T(opline->extended_value).class_entry, 0 TSRMLS_CC);
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(141, ZEND_DECLARE_FUNCTION, ANY, ANY)
{
	do_bind_function(EX(opline), EG(function_table), 0);
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(105, ZEND_TICKS, CONST, ANY)
{
	zend_op *opline = EX(opline);

	if (++EG(ticks_count)>=Z_LVAL(opline->op1.u.constant)) {
		EG(ticks_count)=0;
		if (zend_ticks_function) {
			zend_ticks_function(Z_LVAL(opline->op1.u.constant));
		}
	}
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(138, ZEND_INSTANCEOF, TMP|VAR|CV, ANY)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *expr = GET_OP1_ZVAL_PTR(BP_VAR_R);
	zend_bool result;

	if (Z_TYPE_P(expr) == IS_OBJECT && Z_OBJ_HT_P(expr)->get_class_entry) {
		result = instanceof_function(Z_OBJCE_P(expr), EX_T(opline->op2.u.var).class_entry TSRMLS_CC);
	} else {
		result = 0;
	}
	ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, result);
	FREE_OP1();
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(104, ZEND_EXT_NOP, ANY, ANY)
{
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(0, ZEND_NOP, ANY, ANY)
{
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(144, ZEND_ADD_INTERFACE, ANY, ANY)
{
	zend_op *opline = EX(opline);
	zend_class_entry *ce = EX_T(opline->op1.u.var).class_entry;
	zend_class_entry *iface = EX_T(opline->op2.u.var).class_entry;

	if (!(iface->ce_flags & ZEND_ACC_INTERFACE)) {
		zend_error_noreturn(E_ERROR, "%s cannot implement %s - it is not an interface", ce->name, iface->name);
	}

	zend_do_implement_interface(ce, iface TSRMLS_CC);

	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
{
	zend_uint op_num = EG(opline_before_exception)-EG(active_op_array)->opcodes;
	int i;
	zend_uint catch_op_num;
	int catched = 0;
	zval **stack_zval_pp;
	zval restored_error_reporting;

	stack_zval_pp = (zval **) EG(argument_stack).top_element - 1;
	while (*stack_zval_pp != NULL) {
		zval_ptr_dtor(stack_zval_pp);
		EG(argument_stack).top_element--;
		EG(argument_stack).top--;
		stack_zval_pp--;
	}

	for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
		if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
			/* further blocks will not be relevant... */
			break;
		}
		if (op_num >= EG(active_op_array)->try_catch_array[i].try_op
			&& op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
			catch_op_num = EX(op_array)->try_catch_array[i].catch_op;
			catched = 1;
		}
	}

	while (EX(fbc)) {
		zend_op *ctor_opline = (zend_op*)zend_ptr_stack_pop(&EG(arg_types_stack));

		if (EX(object)) {
			if (ctor_opline && RETURN_VALUE_USED(ctor_opline)) {
				EX(object)->refcount--;
			}
			zval_ptr_dtor(&EX(object));
		}
		zend_arg_types_stack_2_pop(&EG(arg_types_stack), &EX(object), &EX(fbc));
	}

	for (i=0; i<EX(op_array)->last_brk_cont; i++) {
		if (EX(op_array)->brk_cont_array[i].start < 0) {
			continue;
		} else if (EX(op_array)->brk_cont_array[i].start > op_num) {
			/* further blocks will not be relevant... */
			break;
		} else if (op_num < EX(op_array)->brk_cont_array[i].brk) {
			if (!catched ||
			    catch_op_num >= EX(op_array)->brk_cont_array[i].brk) {
				zend_op *brk_opline = &EX(op_array)->opcodes[EX(op_array)->brk_cont_array[i].brk];

				switch (brk_opline->opcode) {
					case ZEND_SWITCH_FREE:
						zend_switch_free(brk_opline, EX(Ts) TSRMLS_CC);
						break;
					case ZEND_FREE:
						zendi_zval_dtor(EX_T(brk_opline->op1.u.var).tmp_var);
						break;
				}
			}
		}
	}

	/* restore previous error_reporting value */
	if (!EG(error_reporting) && EX(old_error_reporting) != NULL && Z_LVAL_P(EX(old_error_reporting)) != 0) {
		Z_TYPE(restored_error_reporting) = IS_LONG;
		Z_LVAL(restored_error_reporting) = Z_LVAL_P(EX(old_error_reporting));
		convert_to_string(&restored_error_reporting);
		zend_alter_ini_entry_ex("error_reporting", sizeof("error_reporting"), Z_STRVAL(restored_error_reporting), Z_STRLEN(restored_error_reporting), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME, 1);
		zendi_zval_dtor(restored_error_reporting);
	}
	EX(old_error_reporting) = NULL;

	if (!catched) {
 		ZEND_VM_RETURN_FROM_EXECUTE_LOOP();
 	} else {
		ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
 		ZEND_VM_CONTINUE();
 	}
}

ZEND_VM_HANDLER(146, ZEND_VERIFY_ABSTRACT_CLASS, ANY, ANY)
{
	zend_verify_abstract_class(EX_T(EX(opline)->op1.u.var).class_entry TSRMLS_CC);
	ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(150, ZEND_USER_OPCODE, ANY, ANY)
{
	int ret = zend_user_opcode_handlers[EX(opline)->opcode](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL);

	switch (ret) {
		case ZEND_USER_OPCODE_CONTINUE:
			ZEND_VM_CONTINUE();
		case ZEND_USER_OPCODE_RETURN:
			ZEND_VM_RETURN();
		case ZEND_USER_OPCODE_DISPATCH:
			ZEND_VM_DISPATCH(EX(opline)->opcode, EX(opline));
		default:
			ZEND_VM_DISPATCH(ret & 0xff, EX(opline));
	}
}

ZEND_VM_EXPORT_HELPER(zend_do_fcall, zend_do_fcall_common_helper)
php/Zend/zend_arena.h000064400000007324151730541630010525 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2018 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Dmitry Stogov <dmitry@zend.com>                             |
   +----------------------------------------------------------------------+
*/

/* $Id:$ */

#ifndef _ZEND_ARENA_H_
#define _ZEND_ARENA_H_

#include "zend.h"

typedef struct _zend_arena zend_arena;

struct _zend_arena {
	char		*ptr;
	char		*end;
	zend_arena  *prev;
};

static zend_always_inline zend_arena* zend_arena_create(size_t size)
{
	zend_arena *arena = (zend_arena*)emalloc(size);

	arena->ptr = (char*) arena + ZEND_MM_ALIGNED_SIZE(sizeof(zend_arena));
	arena->end = (char*) arena + size;
	arena->prev = NULL;
	return arena;
}

static zend_always_inline void zend_arena_destroy(zend_arena *arena)
{
	do {
		zend_arena *prev = arena->prev;
		efree(arena);
		arena = prev;
	} while (arena);
}

#define ZEND_ARENA_ALIGNMENT 8U

static zend_always_inline void* zend_arena_alloc(zend_arena **arena_ptr, size_t size)
{
	zend_arena *arena = *arena_ptr;
	char *ptr = arena->ptr;

	size = ZEND_MM_ALIGNED_SIZE(size);

	if (EXPECTED(size <= (size_t)(arena->end - ptr))) {
		arena->ptr = ptr + size;
	} else {
		size_t arena_size =
			UNEXPECTED((size + ZEND_MM_ALIGNED_SIZE(sizeof(zend_arena))) > (size_t)(arena->end - (char*) arena)) ?
				(size + ZEND_MM_ALIGNED_SIZE(sizeof(zend_arena))) :
				(size_t)(arena->end - (char*) arena);
		zend_arena *new_arena = (zend_arena*)emalloc(arena_size);

		ptr = (char*) new_arena + ZEND_MM_ALIGNED_SIZE(sizeof(zend_arena));
		new_arena->ptr = (char*) new_arena + ZEND_MM_ALIGNED_SIZE(sizeof(zend_arena)) + size;
		new_arena->end = (char*) new_arena + arena_size;
		new_arena->prev = arena;
		*arena_ptr = new_arena;
	}

	return (void*) ptr;
}

static zend_always_inline void* zend_arena_calloc(zend_arena **arena_ptr, size_t count, size_t unit_size)
{
	int overflow;
	size_t size;
	void *ret;

	size = zend_safe_address(unit_size, count, 0, &overflow);
	if (UNEXPECTED(overflow)) {
		zend_error(E_ERROR, "Possible integer overflow in zend_arena_calloc() (%zu * %zu)", unit_size, count);
	}
	ret = zend_arena_alloc(arena_ptr, size);
	memset(ret, 0, size);
	return ret;
}

static zend_always_inline void* zend_arena_checkpoint(zend_arena *arena)
{
	return arena->ptr;
}

static zend_always_inline void zend_arena_release(zend_arena **arena_ptr, void *checkpoint)
{
	zend_arena *arena = *arena_ptr;

	while (UNEXPECTED((char*)checkpoint > arena->end) ||
	       UNEXPECTED((char*)checkpoint <= (char*)arena)) {
		zend_arena *prev = arena->prev;
		efree(arena);
		*arena_ptr = arena = prev;
	}
	ZEND_ASSERT((char*)checkpoint > (char*)arena && (char*)checkpoint <= arena->end);
	arena->ptr = (char*)checkpoint;
}

#endif /* _ZEND_ARENA_H_ */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/Zend/zend_iterators.h000064400000007246151730541630011456 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Author: Wez Furlong <wez@thebrainroom.com>                           |
   |         Marcus Boerger <helly@php.net>                               |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_iterators.h 293155 2010-01-05 20:46:53Z sebastian $ */

/* These iterators were designed to operate within the foreach()
 * structures provided by the engine, but could be extended for use
 * with other iterative engine opcodes.
 * These methods have similar semantics to the zend_hash API functions
 * with similar names.
 * */

typedef struct _zend_object_iterator zend_object_iterator;

typedef struct _zend_object_iterator_funcs {
	/* release all resources associated with this iterator instance */
	void (*dtor)(zend_object_iterator *iter TSRMLS_DC);

	/* check for end of iteration (FAILURE or SUCCESS if data is valid) */
	int (*valid)(zend_object_iterator *iter TSRMLS_DC);

	/* fetch the item data for the current element */
	void (*get_current_data)(zend_object_iterator *iter, zval ***data TSRMLS_DC);

	/* fetch the key for the current element (return HASH_KEY_IS_STRING or HASH_KEY_IS_LONG) (optional, may be NULL) */
	int (*get_current_key)(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC);

	/* step forwards to next element */
	void (*move_forward)(zend_object_iterator *iter TSRMLS_DC);

	/* rewind to start of data (optional, may be NULL) */
	void (*rewind)(zend_object_iterator *iter TSRMLS_DC);

	/* invalidate current value/key (optional, may be NULL) */
	void (*invalidate_current)(zend_object_iterator *iter TSRMLS_DC);
} zend_object_iterator_funcs;

struct _zend_object_iterator {
	void *data;
	zend_object_iterator_funcs *funcs;
	ulong index; /* private to fe_reset/fe_fetch opcodes */
};

typedef struct _zend_class_iterator_funcs {
	zend_object_iterator_funcs  *funcs;
	union _zend_function *zf_new_iterator;
	union _zend_function *zf_valid;
	union _zend_function *zf_current;
	union _zend_function *zf_key;
	union _zend_function *zf_next;
	union _zend_function *zf_rewind;
} zend_class_iterator_funcs;

enum zend_object_iterator_kind {
	ZEND_ITER_INVALID,
	ZEND_ITER_PLAIN_ARRAY,
	ZEND_ITER_PLAIN_OBJECT,
	ZEND_ITER_OBJECT
};

BEGIN_EXTERN_C()
/* given a zval, returns stuff that can be used to iterate it. */
ZEND_API enum zend_object_iterator_kind zend_iterator_unwrap(zval *array_ptr, zend_object_iterator **iter TSRMLS_DC);

/* given an iterator, wrap it up as a zval for use by the engine opcodes */
ZEND_API zval *zend_iterator_wrap(zend_object_iterator *iter TSRMLS_DC);

ZEND_API void zend_register_iterator_wrapper(TSRMLS_D);
END_EXTERN_C()

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_type_info.h000064400000006265151730541640011437 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2018 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Dmitry Stogov <dmitry@zend.com>                             |
   +----------------------------------------------------------------------+
*/

/* $Id$ */

#ifndef ZEND_TYPE_INFO_H
#define ZEND_TYPE_INFO_H

#include "zend_types.h"

#define MAY_BE_UNDEF                (1 << IS_UNDEF)
#define MAY_BE_NULL		            (1 << IS_NULL)
#define MAY_BE_FALSE	            (1 << IS_FALSE)
#define MAY_BE_TRUE		            (1 << IS_TRUE)
#define MAY_BE_LONG		            (1 << IS_LONG)
#define MAY_BE_DOUBLE	            (1 << IS_DOUBLE)
#define MAY_BE_STRING	            (1 << IS_STRING)
#define MAY_BE_ARRAY	            (1 << IS_ARRAY)
#define MAY_BE_OBJECT	            (1 << IS_OBJECT)
#define MAY_BE_RESOURCE	            (1 << IS_RESOURCE)
#define MAY_BE_ANY                  (MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)
#define MAY_BE_REF                  (1 << IS_REFERENCE) /* may be reference */

#define MAY_BE_ARRAY_SHIFT          (IS_REFERENCE)

#define MAY_BE_ARRAY_OF_NULL		(MAY_BE_NULL     << MAY_BE_ARRAY_SHIFT)
#define MAY_BE_ARRAY_OF_FALSE		(MAY_BE_FALSE    << MAY_BE_ARRAY_SHIFT)
#define MAY_BE_ARRAY_OF_TRUE		(MAY_BE_TRUE     << MAY_BE_ARRAY_SHIFT)
#define MAY_BE_ARRAY_OF_LONG		(MAY_BE_LONG     << MAY_BE_ARRAY_SHIFT)
#define MAY_BE_ARRAY_OF_DOUBLE		(MAY_BE_DOUBLE   << MAY_BE_ARRAY_SHIFT)
#define MAY_BE_ARRAY_OF_STRING		(MAY_BE_STRING   << MAY_BE_ARRAY_SHIFT)
#define MAY_BE_ARRAY_OF_ARRAY		(MAY_BE_ARRAY    << MAY_BE_ARRAY_SHIFT)
#define MAY_BE_ARRAY_OF_OBJECT		(MAY_BE_OBJECT   << MAY_BE_ARRAY_SHIFT)
#define MAY_BE_ARRAY_OF_RESOURCE	(MAY_BE_RESOURCE << MAY_BE_ARRAY_SHIFT)
#define MAY_BE_ARRAY_OF_ANY			(MAY_BE_ANY      << MAY_BE_ARRAY_SHIFT)
#define MAY_BE_ARRAY_OF_REF			(MAY_BE_REF      << MAY_BE_ARRAY_SHIFT)

#define MAY_BE_ARRAY_KEY_LONG       (1<<21)
#define MAY_BE_ARRAY_KEY_STRING     (1<<22)
#define MAY_BE_ARRAY_KEY_ANY        (MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_KEY_STRING)

#define MAY_BE_ERROR                (1<<23)
#define MAY_BE_CLASS                (1<<24)

#endif /* ZEND_TYPE_INFO_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/Zend/zend_errors.h000064400000004065151730541640010753 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        | 
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_errors.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef ZEND_ERRORS_H
#define ZEND_ERRORS_H

#define E_ERROR				(1<<0L)
#define E_WARNING			(1<<1L)
#define E_PARSE				(1<<2L)
#define E_NOTICE			(1<<3L)
#define E_CORE_ERROR		(1<<4L)
#define E_CORE_WARNING		(1<<5L)
#define E_COMPILE_ERROR		(1<<6L)
#define E_COMPILE_WARNING	(1<<7L)
#define E_USER_ERROR		(1<<8L)
#define E_USER_WARNING		(1<<9L)
#define E_USER_NOTICE		(1<<10L)
#define E_STRICT			(1<<11L)
#define E_RECOVERABLE_ERROR	(1<<12L)

#define E_ALL (E_ERROR | E_WARNING | E_PARSE | E_NOTICE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING | E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE | E_RECOVERABLE_ERROR)
#define E_CORE (E_CORE_ERROR | E_CORE_WARNING)

#endif /* ZEND_ERRORS_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_ast.h000064400000020417151730541650010226 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2018 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Bob Weinand <bwoebi@php.net>                                |
   |          Dmitry Stogov <dmitry@zend.com>                             |
   |          Nikita Popov <nikic@php.net>                                |
   +----------------------------------------------------------------------+
*/

/* $Id$ */

#ifndef ZEND_AST_H
#define ZEND_AST_H

#include "zend.h"

#define ZEND_AST_SPECIAL_SHIFT      6
#define ZEND_AST_IS_LIST_SHIFT      7
#define ZEND_AST_NUM_CHILDREN_SHIFT 8

enum _zend_ast_kind {
	/* special nodes */
	ZEND_AST_ZVAL = 1 << ZEND_AST_SPECIAL_SHIFT,
	ZEND_AST_ZNODE,

	/* declaration nodes */
	ZEND_AST_FUNC_DECL,
	ZEND_AST_CLOSURE,
	ZEND_AST_METHOD,
	ZEND_AST_CLASS,

	/* list nodes */
	ZEND_AST_ARG_LIST = 1 << ZEND_AST_IS_LIST_SHIFT,
	ZEND_AST_ARRAY,
	ZEND_AST_ENCAPS_LIST,
	ZEND_AST_EXPR_LIST,
	ZEND_AST_STMT_LIST,
	ZEND_AST_IF,
	ZEND_AST_SWITCH_LIST,
	ZEND_AST_CATCH_LIST,
	ZEND_AST_PARAM_LIST,
	ZEND_AST_CLOSURE_USES,
	ZEND_AST_PROP_DECL,
	ZEND_AST_CONST_DECL,
	ZEND_AST_CLASS_CONST_DECL,
	ZEND_AST_NAME_LIST,
	ZEND_AST_TRAIT_ADAPTATIONS,
	ZEND_AST_USE,

	/* 0 child nodes */
	ZEND_AST_MAGIC_CONST = 0 << ZEND_AST_NUM_CHILDREN_SHIFT,
	ZEND_AST_TYPE,

	/* 1 child node */
	ZEND_AST_VAR = 1 << ZEND_AST_NUM_CHILDREN_SHIFT,
	ZEND_AST_CONST,
	ZEND_AST_UNPACK,
	ZEND_AST_UNARY_PLUS,
	ZEND_AST_UNARY_MINUS,
	ZEND_AST_CAST,
	ZEND_AST_EMPTY,
	ZEND_AST_ISSET,
	ZEND_AST_SILENCE,
	ZEND_AST_SHELL_EXEC,
	ZEND_AST_CLONE,
	ZEND_AST_EXIT,
	ZEND_AST_PRINT,
	ZEND_AST_INCLUDE_OR_EVAL,
	ZEND_AST_UNARY_OP,
	ZEND_AST_PRE_INC,
	ZEND_AST_PRE_DEC,
	ZEND_AST_POST_INC,
	ZEND_AST_POST_DEC,
	ZEND_AST_YIELD_FROM,

	ZEND_AST_GLOBAL,
	ZEND_AST_UNSET,
	ZEND_AST_RETURN,
	ZEND_AST_LABEL,
	ZEND_AST_REF,
	ZEND_AST_HALT_COMPILER,
	ZEND_AST_ECHO,
	ZEND_AST_THROW,
	ZEND_AST_GOTO,
	ZEND_AST_BREAK,
	ZEND_AST_CONTINUE,

	/* 2 child nodes */
	ZEND_AST_DIM = 2 << ZEND_AST_NUM_CHILDREN_SHIFT,
	ZEND_AST_PROP,
	ZEND_AST_STATIC_PROP,
	ZEND_AST_CALL,
	ZEND_AST_CLASS_CONST,
	ZEND_AST_ASSIGN,
	ZEND_AST_ASSIGN_REF,
	ZEND_AST_ASSIGN_OP,
	ZEND_AST_BINARY_OP,
	ZEND_AST_GREATER,
	ZEND_AST_GREATER_EQUAL,
	ZEND_AST_AND,
	ZEND_AST_OR,
	ZEND_AST_ARRAY_ELEM,
	ZEND_AST_NEW,
	ZEND_AST_INSTANCEOF,
	ZEND_AST_YIELD,
	ZEND_AST_COALESCE,

	ZEND_AST_STATIC,
	ZEND_AST_WHILE,
	ZEND_AST_DO_WHILE,
	ZEND_AST_IF_ELEM,
	ZEND_AST_SWITCH,
	ZEND_AST_SWITCH_CASE,
	ZEND_AST_DECLARE,
	ZEND_AST_USE_TRAIT,
	ZEND_AST_TRAIT_PRECEDENCE,
	ZEND_AST_METHOD_REFERENCE,
	ZEND_AST_NAMESPACE,
	ZEND_AST_USE_ELEM,
	ZEND_AST_TRAIT_ALIAS,
	ZEND_AST_GROUP_USE,

	/* 3 child nodes */
	ZEND_AST_METHOD_CALL = 3 << ZEND_AST_NUM_CHILDREN_SHIFT,
	ZEND_AST_STATIC_CALL,
	ZEND_AST_CONDITIONAL,

	ZEND_AST_TRY,
	ZEND_AST_CATCH,
	ZEND_AST_PARAM,
	ZEND_AST_PROP_ELEM,
	ZEND_AST_CONST_ELEM,

	/* 4 child nodes */
	ZEND_AST_FOR = 4 << ZEND_AST_NUM_CHILDREN_SHIFT,
	ZEND_AST_FOREACH,
};

typedef uint16_t zend_ast_kind;
typedef uint16_t zend_ast_attr;

struct _zend_ast {
	zend_ast_kind kind; /* Type of the node (ZEND_AST_* enum constant) */
	zend_ast_attr attr; /* Additional attribute, use depending on node type */
	uint32_t lineno;    /* Line number */
	zend_ast *child[1]; /* Array of children (using struct hack) */
};

/* Same as zend_ast, but with children count, which is updated dynamically */
typedef struct _zend_ast_list {
	zend_ast_kind kind;
	zend_ast_attr attr;
	uint32_t lineno;
	uint32_t children;
	zend_ast *child[1];
} zend_ast_list;

/* Lineno is stored in val.u2.lineno */
typedef struct _zend_ast_zval {
	zend_ast_kind kind;
	zend_ast_attr attr;
	zval val;
} zend_ast_zval;

/* Separate structure for function and class declaration, as they need extra information. */
typedef struct _zend_ast_decl {
	zend_ast_kind kind;
	zend_ast_attr attr; /* Unused - for structure compatibility */
	uint32_t start_lineno;
	uint32_t end_lineno;
	uint32_t flags;
	unsigned char *lex_pos;
	zend_string *doc_comment;
	zend_string *name;
	zend_ast *child[4];
} zend_ast_decl;

typedef void (*zend_ast_process_t)(zend_ast *ast);
extern ZEND_API zend_ast_process_t zend_ast_process;

ZEND_API zend_ast *zend_ast_create_zval_with_lineno(zval *zv, zend_ast_attr attr, uint32_t lineno);
ZEND_API zend_ast *zend_ast_create_zval_ex(zval *zv, zend_ast_attr attr);

ZEND_API zend_ast *zend_ast_create_ex(zend_ast_kind kind, zend_ast_attr attr, ...);
ZEND_API zend_ast *zend_ast_create(zend_ast_kind kind, ...);

ZEND_API zend_ast *zend_ast_create_decl(
	zend_ast_kind kind, uint32_t flags, uint32_t start_lineno, zend_string *doc_comment,
	zend_string *name, zend_ast *child0, zend_ast *child1, zend_ast *child2, zend_ast *child3
);

ZEND_API zend_ast *zend_ast_create_list(uint32_t init_children, zend_ast_kind kind, ...);
ZEND_API zend_ast *zend_ast_list_add(zend_ast *list, zend_ast *op);

ZEND_API int zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *scope);
ZEND_API zend_string *zend_ast_export(const char *prefix, zend_ast *ast, const char *suffix);

ZEND_API zend_ast *zend_ast_copy(zend_ast *ast);
ZEND_API void zend_ast_destroy(zend_ast *ast);
ZEND_API void zend_ast_destroy_and_free(zend_ast *ast);

typedef void (*zend_ast_apply_func)(zend_ast **ast_ptr);
ZEND_API void zend_ast_apply(zend_ast *ast, zend_ast_apply_func fn);

static zend_always_inline zend_bool zend_ast_is_list(zend_ast *ast) {
	return (ast->kind >> ZEND_AST_IS_LIST_SHIFT) & 1;
}
static zend_always_inline zend_ast_list *zend_ast_get_list(zend_ast *ast) {
	ZEND_ASSERT(zend_ast_is_list(ast));
	return (zend_ast_list *) ast;
}

static zend_always_inline zval *zend_ast_get_zval(zend_ast *ast) {
	ZEND_ASSERT(ast->kind == ZEND_AST_ZVAL);
	return &((zend_ast_zval *) ast)->val;
}
static zend_always_inline zend_string *zend_ast_get_str(zend_ast *ast) {
	zval *zv = zend_ast_get_zval(ast);
	ZEND_ASSERT(Z_TYPE_P(zv) == IS_STRING);
	return Z_STR_P(zv);
}

static zend_always_inline uint32_t zend_ast_get_num_children(zend_ast *ast) {
	ZEND_ASSERT(!zend_ast_is_list(ast));
	return ast->kind >> ZEND_AST_NUM_CHILDREN_SHIFT;
}
static zend_always_inline uint32_t zend_ast_get_lineno(zend_ast *ast) {
	if (ast->kind == ZEND_AST_ZVAL) {
		zval *zv = zend_ast_get_zval(ast);
		return zv->u2.lineno;
	} else {
		return ast->lineno;
	}
}

static zend_always_inline zend_ast *zend_ast_create_zval(zval *zv) {
	return zend_ast_create_zval_ex(zv, 0);
}
static zend_always_inline zend_ast *zend_ast_create_zval_from_str(zend_string *str) {
	zval zv;
	ZVAL_STR(&zv, str);
	return zend_ast_create_zval(&zv);
}
static zend_always_inline zend_ast *zend_ast_create_zval_from_long(zend_long lval) {
	zval zv;
	ZVAL_LONG(&zv, lval);
	return zend_ast_create_zval(&zv);
}

static zend_always_inline zend_ast *zend_ast_create_binary_op(uint32_t opcode, zend_ast *op0, zend_ast *op1) {
	return zend_ast_create_ex(ZEND_AST_BINARY_OP, opcode, op0, op1);
}
static zend_always_inline zend_ast *zend_ast_create_assign_op(uint32_t opcode, zend_ast *op0, zend_ast *op1) {
	return zend_ast_create_ex(ZEND_AST_ASSIGN_OP, opcode, op0, op1);
}
static zend_always_inline zend_ast *zend_ast_create_cast(uint32_t type, zend_ast *op0) {
	return zend_ast_create_ex(ZEND_AST_CAST, type, op0);
}
static zend_always_inline zend_ast *zend_ast_list_rtrim(zend_ast *ast) {
	zend_ast_list *list = zend_ast_get_list(ast);
	if (list->children && list->child[list->children - 1] == NULL) {
		list->children--;
	}
	return ast;
}
#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/Zend/zend_multibyte.h000064400000007162151730541650011457 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        | 
   | available through the world-wide-web at                              |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Masaki Fujimoto <fujimoto@php.net>                          |
   |          Rui Hirokawa <hirokawa@php.net>                             |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_multibyte.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef ZEND_MULTIBYTE_H
#define ZEND_MULTIBYTE_H

#ifdef ZEND_MULTIBYTE

#define BOM_UTF32_BE	"\x00\x00\xfe\xff"
#define	BOM_UTF32_LE	"\xff\xfe\x00\x00"
#define	BOM_UTF16_BE	"\xfe\xff"
#define	BOM_UTF16_LE	"\xff\xfe"
#define	BOM_UTF8		"\xef\xbb\xbf"

typedef int (*zend_encoding_filter)(char **str, int *str_length, const char *buf, int length TSRMLS_DC);

typedef char* (*zend_encoding_detector)(const char *string, int length, char *list TSRMLS_DC);

typedef int (*zend_encoding_converter)(char **to, int *to_length, const char *from, int from_length, const char *encoding_to, const char *encoding_from TSRMLS_DC);

typedef int (*zend_encoding_oddlen)(const char *string, int length, const char *encoding TSRMLS_DC);

typedef struct _zend_encoding {
	zend_encoding_filter input_filter;		/* escape input filter */
	zend_encoding_filter output_filter;		/* escape output filter */
	const char *name;					/* encoding name */
	const char *(*aliases)[];			/* encoding name aliases */
	int compatible;						/* flex compatible or not */
} zend_encoding;


/*
 * zend multibyte APIs
 */
BEGIN_EXTERN_C()
ZEND_API int zend_multibyte_set_script_encoding(char *encoding_list, int encoding_list_size TSRMLS_DC);
ZEND_API int zend_multibyte_set_internal_encoding(char *encoding_name, int encoding_name_size TSRMLS_DC);
ZEND_API int zend_multibyte_set_functions(zend_encoding_detector encoding_detector, zend_encoding_converter encoding_converter, zend_encoding_oddlen encoding_oddlen TSRMLS_DC);
ZEND_API int zend_multibyte_set_filter(zend_encoding *onetime_encoding TSRMLS_DC);
ZEND_API zend_encoding* zend_multibyte_fetch_encoding(char *encoding_name);
ZEND_API int zend_multibyte_script_encoding_filter(char **to, int *to_length, const char *from, int from_length TSRMLS_DC);
ZEND_API int zend_multibyte_internal_encoding_filter(char **to, int *to_length, const char *from, int from_length TSRMLS_DC);

/* in zend_language_scanner.l */
ZEND_API void zend_multibyte_yyinput_again(zend_encoding_filter old_input_filter, zend_encoding *old_encoding TSRMLS_DC);
ZEND_API int zend_multibyte_yyinput(zend_file_handle *file_handle, char *buf, size_t len TSRMLS_DC);
ZEND_API int zend_multibyte_read_script(TSRMLS_D);
END_EXTERN_C()

#endif /* ZEND_MULTIBYTE */

#endif /* ZEND_MULTIBYTE_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: sw=4 ts=4 tw=78
 * vim<600: sw=4 ts=4 tw=78
 */
php/Zend/zend_llist.h000064400000007676151730541650010602 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        | 
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_llist.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef ZEND_LLIST_H
#define ZEND_LLIST_H

typedef struct _zend_llist_element {
	struct _zend_llist_element *next;
	struct _zend_llist_element *prev;
	char data[1]; /* Needs to always be last in the struct */
} zend_llist_element;

typedef void (*llist_dtor_func_t)(void *);
typedef int (*llist_compare_func_t)(const zend_llist_element **, const zend_llist_element ** TSRMLS_DC);
typedef void (*llist_apply_with_args_func_t)(void *data, int num_args, va_list args TSRMLS_DC);
typedef void (*llist_apply_with_arg_func_t)(void *data, void *arg TSRMLS_DC);
typedef void (*llist_apply_func_t)(void * TSRMLS_DC);

typedef struct _zend_llist {
	zend_llist_element *head;
	zend_llist_element *tail;
	size_t count;
	size_t size;
	llist_dtor_func_t dtor;
	unsigned char persistent;
	zend_llist_element *traverse_ptr;
} zend_llist;

typedef zend_llist_element* zend_llist_position;

BEGIN_EXTERN_C()
ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent);
ZEND_API void zend_llist_add_element(zend_llist *l, void *element);
ZEND_API void zend_llist_prepend_element(zend_llist *l, void *element);
ZEND_API void zend_llist_del_element(zend_llist *l, void *element, int (*compare)(void *element1, void *element2));
ZEND_API void zend_llist_destroy(zend_llist *l);
ZEND_API void zend_llist_clean(zend_llist *l);
ZEND_API void *zend_llist_remove_tail(zend_llist *l);
ZEND_API void zend_llist_copy(zend_llist *dst, zend_llist *src);
ZEND_API void zend_llist_apply(zend_llist *l, llist_apply_func_t func TSRMLS_DC);
ZEND_API void zend_llist_apply_with_del(zend_llist *l, int (*func)(void *data));
ZEND_API void zend_llist_apply_with_argument(zend_llist *l, llist_apply_with_arg_func_t func, void *arg TSRMLS_DC);
ZEND_API void zend_llist_apply_with_arguments(zend_llist *l, llist_apply_with_args_func_t func TSRMLS_DC, int num_args, ...);
ZEND_API int zend_llist_count(zend_llist *l);
ZEND_API void zend_llist_sort(zend_llist *l, llist_compare_func_t comp_func TSRMLS_DC);

/* traversal */
ZEND_API void *zend_llist_get_first_ex(zend_llist *l, zend_llist_position *pos);
ZEND_API void *zend_llist_get_last_ex(zend_llist *l, zend_llist_position *pos);
ZEND_API void *zend_llist_get_next_ex(zend_llist *l, zend_llist_position *pos);
ZEND_API void *zend_llist_get_prev_ex(zend_llist *l, zend_llist_position *pos);

#define zend_llist_get_first(l) zend_llist_get_first_ex(l, NULL)
#define zend_llist_get_last(l) zend_llist_get_last_ex(l, NULL)
#define zend_llist_get_next(l) zend_llist_get_next_ex(l, NULL)
#define zend_llist_get_prev(l) zend_llist_get_prev_ex(l, NULL)

END_EXTERN_C()

#endif /* ZEND_LLIST_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_build.h000064400000003360151730541660010535 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2018 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Stanislav Malyshev <stas@zend.com>                          |
   +----------------------------------------------------------------------+
*/

#ifndef ZEND_BUILD_H
#define ZEND_BUILD_H

#define ZEND_TOSTR_(x) #x
#define ZEND_TOSTR(x) ZEND_TOSTR_(x)

#ifdef ZTS
#define ZEND_BUILD_TS ",TS"
#else
#define ZEND_BUILD_TS ",NTS"
#endif

#if ZEND_DEBUG
#define ZEND_BUILD_DEBUG ",debug"
#else
#define ZEND_BUILD_DEBUG
#endif

#if defined(ZEND_WIN32) && defined(PHP_COMPILER_ID)
#define ZEND_BUILD_SYSTEM "," PHP_COMPILER_ID
#else
#define ZEND_BUILD_SYSTEM
#endif

/* for private applications */
#define ZEND_BUILD_EXTRA

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/Zend/zend_modules.h000064400000012056151730541660011110 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_modules.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef MODULES_H
#define MODULES_H

#include "zend.h"
#include "zend_compile.h"

#define INIT_FUNC_ARGS		int type, int module_number TSRMLS_DC
#define INIT_FUNC_ARGS_PASSTHRU	type, module_number TSRMLS_CC
#define SHUTDOWN_FUNC_ARGS	int type, int module_number TSRMLS_DC
#define SHUTDOWN_FUNC_ARGS_PASSTHRU type, module_number TSRMLS_CC
#define ZEND_MODULE_INFO_FUNC_ARGS zend_module_entry *zend_module TSRMLS_DC
#define ZEND_MODULE_INFO_FUNC_ARGS_PASSTHRU zend_module TSRMLS_CC

extern struct _zend_arg_info first_arg_force_ref[2];
extern struct _zend_arg_info second_arg_force_ref[3];
extern struct _zend_arg_info third_arg_force_ref[4];
extern struct _zend_arg_info fourth_arg_force_ref[5];
extern struct _zend_arg_info fifth_arg_force_ref[6];
extern struct _zend_arg_info all_args_by_ref[1];

#define ZEND_MODULE_API_NO 20060613
#ifdef ZTS
#define USING_ZTS 1
#else
#define USING_ZTS 0
#endif

#define STANDARD_MODULE_HEADER_EX sizeof(zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS
#define STANDARD_MODULE_HEADER \
	STANDARD_MODULE_HEADER_EX, NULL, NULL
#define ZE2_STANDARD_MODULE_HEADER \
	STANDARD_MODULE_HEADER_EX, ini_entries, NULL

#define STANDARD_MODULE_PROPERTIES_EX 0, 0, NULL, 0

#define NO_MODULE_GLOBALS 0, NULL, NULL, NULL

#ifdef ZTS
# define ZEND_MODULE_GLOBALS(module_name) sizeof(zend_##module_name##_globals), &module_name##_globals_id
#else
# define ZEND_MODULE_GLOBALS(module_name) sizeof(zend_##module_name##_globals), &module_name##_globals
#endif

#define STANDARD_MODULE_PROPERTIES \
	NO_MODULE_GLOBALS, NULL, STANDARD_MODULE_PROPERTIES_EX

#define NO_VERSION_YET NULL

#define MODULE_PERSISTENT 1
#define MODULE_TEMPORARY 2

struct _zend_ini_entry;
typedef struct _zend_module_entry zend_module_entry;
typedef struct _zend_module_dep zend_module_dep;

struct _zend_module_entry {
	unsigned short size;
	unsigned int zend_api;
	unsigned char zend_debug;
	unsigned char zts;
	struct _zend_ini_entry *ini_entry;
	struct _zend_module_dep *deps;
	char *name;
	struct _zend_function_entry *functions;
	int (*module_startup_func)(INIT_FUNC_ARGS);
	int (*module_shutdown_func)(SHUTDOWN_FUNC_ARGS);
	int (*request_startup_func)(INIT_FUNC_ARGS);
	int (*request_shutdown_func)(SHUTDOWN_FUNC_ARGS);
	void (*info_func)(ZEND_MODULE_INFO_FUNC_ARGS);
	char *version;
	size_t globals_size;
#ifdef ZTS
	ts_rsrc_id* globals_id_ptr;
#else
	void* globals_ptr;
#endif
	void (*globals_ctor)(void *global TSRMLS_DC);
	void (*globals_dtor)(void *global TSRMLS_DC);
	int (*post_deactivate_func)(void);
	int module_started;
	unsigned char type;
	void *handle;
	int module_number;
};

#define MODULE_DEP_REQUIRED		1
#define MODULE_DEP_CONFLICTS	2
#define MODULE_DEP_OPTIONAL		3

#define ZEND_MOD_REQUIRED_EX(name, rel, ver)	{ name, rel, ver, MODULE_DEP_REQUIRED  },
#define ZEND_MOD_CONFLICTS_EX(name, rel, ver)	{ name, rel, ver, MODULE_DEP_CONFLICTS },
#define ZEND_MOD_OPTIONAL_EX(name, rel, ver)	{ name, rel, ver, MODULE_DEP_OPTIONAL  },

#define ZEND_MOD_REQUIRED(name)		ZEND_MOD_REQUIRED_EX(name, NULL, NULL)
#define ZEND_MOD_CONFLICTS(name)	ZEND_MOD_CONFLICTS_EX(name, NULL, NULL)
#define ZEND_MOD_OPTIONAL(name)		ZEND_MOD_OPTIONAL_EX(name, NULL, NULL)

struct _zend_module_dep {
	char *name;			/* module name */
	char *rel;			/* version relationship: NULL (exists), lt|le|eq|ge|gt (to given version) */
	char *version;		/* version */
	unsigned char type;	/* dependency type */
};

extern ZEND_API HashTable module_registry;

void module_destructor(zend_module_entry *module);
int module_registry_cleanup(zend_module_entry *module TSRMLS_DC);
int module_registry_request_startup(zend_module_entry *module TSRMLS_DC);
int module_registry_unload_temp(zend_module_entry *module TSRMLS_DC);

#define ZEND_MODULE_DTOR (void (*)(void *)) module_destructor
#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_exceptions.h000064400000005444151730541670011625 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        | 
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Marcus Boerger <helly@php.net>                              |
   |          Sterling Hughes <sterling@php.net>                          |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_exceptions.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef ZEND_EXCEPTIONS_H
#define ZEND_EXCEPTIONS_H

BEGIN_EXTERN_C()

void zend_throw_exception_internal(zval *exception TSRMLS_DC);

void zend_register_default_exception(TSRMLS_D);

ZEND_API zend_class_entry *zend_exception_get_default(TSRMLS_D);
ZEND_API zend_class_entry *zend_get_error_exception(TSRMLS_D);
ZEND_API void zend_register_default_classes(TSRMLS_D);

/* exception_ce   NULL or zend_exception_get_default() or a derived class
 * message        NULL or the message of the exception */
ZEND_API zval * zend_throw_exception(zend_class_entry *exception_ce, char *message, long code TSRMLS_DC);
ZEND_API zval * zend_throw_exception_ex(zend_class_entry *exception_ce, long code TSRMLS_DC, char *format, ...);
ZEND_API void zend_throw_exception_object(zval *exception TSRMLS_DC);
ZEND_API void zend_clear_exception(TSRMLS_D);

ZEND_API zval * zend_throw_error_exception(zend_class_entry *exception_ce, char *message, long code, int severity TSRMLS_DC);

extern ZEND_API void (*zend_throw_exception_hook)(zval *ex TSRMLS_DC);

/* show an exception using zend_error(E_ERROR,...) */
ZEND_API void zend_exception_error(zval *exception TSRMLS_DC);

/* do not export, in php it's available thru spprintf directly */
int zend_spprintf(char **message, int max_len, char *format, ...);

END_EXTERN_C()

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_signal.h000064400000010070151730541670010710 0ustar00/*
  +----------------------------------------------------------------------+
  | Zend Signal Handling                                                 |
  +----------------------------------------------------------------------+
  | Copyright (c) 2008-2018 The PHP Group                                     |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Lucas Nealan <lucas@php.net>                                |
  |          Arnaud Le Blanc <lbarnaud@php.net>                          |
  +----------------------------------------------------------------------+

 */

/* $Id$ */

#ifndef ZEND_SIGNAL_H
#define ZEND_SIGNAL_H

#ifdef ZEND_SIGNALS

# ifdef HAVE_SIGNAL_H
#  include <signal.h>
# endif

#ifndef NSIG
#define NSIG 65
#endif

#ifndef ZEND_SIGNAL_QUEUE_SIZE
#define ZEND_SIGNAL_QUEUE_SIZE 64
#endif

/* Signal structs */
typedef struct _zend_signal_entry_t {
	int   flags;          /* sigaction style flags */
	void* handler;      /* signal handler or context */
} zend_signal_entry_t;

typedef struct _zend_signal_t {
	int signo;
	siginfo_t *siginfo;
	void* context;
} zend_signal_t;

typedef struct _zend_signal_queue_t {
	zend_signal_t zend_signal;
	struct _zend_signal_queue_t *next;
} zend_signal_queue_t;

/* Signal Globals */
typedef struct _zend_signal_globals_t {
	int depth;
	int blocked;            /* 1==TRUE, 0==FALSE */
	int running;            /* in signal handler execution */
	int active;             /* internal signal handling is enabled */
	zend_bool check;        /* check for replaced handlers on shutdown */
	zend_signal_entry_t handlers[NSIG];
	zend_signal_queue_t pstorage[ZEND_SIGNAL_QUEUE_SIZE], *phead, *ptail, *pavail; /* pending queue */
} zend_signal_globals_t;

# ifdef ZTS
#  define SIGG(v) ZEND_TSRMG(zend_signal_globals_id, zend_signal_globals_t *, v)
BEGIN_EXTERN_C()
ZEND_API extern int zend_signal_globals_id;
END_EXTERN_C()
# else
#  define SIGG(v) (zend_signal_globals.v)
BEGIN_EXTERN_C()
ZEND_API extern zend_signal_globals_t zend_signal_globals;
END_EXTERN_C()
# endif /* not ZTS */

# ifdef ZTS
#  define ZEND_SIGNAL_BLOCK_INTERRUPTIONS() if (EXPECTED(zend_signal_globals_id)) { SIGG(depth)++; }
#  define ZEND_SIGNAL_UNBLOCK_INTERRUPTIONS() if (EXPECTED(zend_signal_globals_id) && UNEXPECTED(((SIGG(depth)--) == SIGG(blocked)))) { zend_signal_handler_unblock(); }
# else /* ZTS */
#  define ZEND_SIGNAL_BLOCK_INTERRUPTIONS()  SIGG(depth)++;
#  define ZEND_SIGNAL_UNBLOCK_INTERRUPTIONS() if (((SIGG(depth)--) == SIGG(blocked))) { zend_signal_handler_unblock(); }
# endif /* not ZTS */

ZEND_API void zend_signal_handler_unblock(void);
void zend_signal_activate(void);
void zend_signal_deactivate(void);
BEGIN_EXTERN_C()
ZEND_API void zend_signal_startup(void);
END_EXTERN_C()
void zend_signal_init(void);

ZEND_API int zend_signal(int signo, void (*handler)(int));
ZEND_API int zend_sigaction(int signo, const struct sigaction *act, struct sigaction *oldact);

#else /* ZEND_SIGNALS */

# define ZEND_SIGNAL_BLOCK_INTERRUPTIONS()
# define ZEND_SIGNAL_UNBLOCK_INTERRUPTIONS()

# define zend_signal_activate()
# define zend_signal_deactivate()
# define zend_signal_startup()
# define zend_signal_init()

# define zend_signal(signo, handler)           signal(signo, handler)
# define zend_sigaction(signo, act, oldact)    sigaction(signo, act, oldact)

#endif /* ZEND_SIGNALS */

#endif /* ZEND_SIGNAL_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/Zend/zend_ts_hash.h000064400000015424151730541700011066 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        | 
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Harald Radi <harald.radi@nme.at>                            |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_ts_hash.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef ZEND_TS_HASH_H
#define ZEND_TS_HASH_H

#include "zend.h"

typedef struct _zend_ts_hashtable {
	HashTable hash;
	zend_uint reader;
#ifdef ZTS
	MUTEX_T mx_reader;
	MUTEX_T mx_writer;
#endif
} TsHashTable;

BEGIN_EXTERN_C()

#define TS_HASH(table) (&(table->hash))

/* startup/shutdown */
ZEND_API int _zend_ts_hash_init(TsHashTable *ht, uint nSize, hash_func_t pHashFunction, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC);
ZEND_API int _zend_ts_hash_init_ex(TsHashTable *ht, uint nSize, hash_func_t pHashFunction, dtor_func_t pDestructor, zend_bool persistent, zend_bool bApplyProtection ZEND_FILE_LINE_DC);
ZEND_API void zend_ts_hash_destroy(TsHashTable *ht);
ZEND_API void zend_ts_hash_clean(TsHashTable *ht);

#define zend_ts_hash_init(ht, nSize, pHashFunction, pDestructor, persistent)	\
	_zend_ts_hash_init(ht, nSize, pHashFunction, pDestructor, persistent ZEND_FILE_LINE_CC)
#define zend_ts_hash_init_ex(ht, nSize, pHashFunction, pDestructor, persistent, bApplyProtection)	\
	_zend_ts_hash_init_ex(ht, nSize, pHashFunction, pDestructor, persistent, bApplyProtection ZEND_FILE_LINE_CC)


/* additions/updates/changes */
ZEND_API int _zend_ts_hash_add_or_update(TsHashTable *ht, char *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC);
#define zend_ts_hash_update(ht, arKey, nKeyLength, pData, nDataSize, pDest) \
		_zend_ts_hash_add_or_update(ht, arKey, nKeyLength, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)
#define zend_ts_hash_add(ht, arKey, nKeyLength, pData, nDataSize, pDest) \
		_zend_ts_hash_add_or_update(ht, arKey, nKeyLength, pData, nDataSize, pDest, HASH_ADD ZEND_FILE_LINE_CC)

ZEND_API int _zend_ts_hash_quick_add_or_update(TsHashTable *ht, char *arKey, uint nKeyLength, ulong h, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC);
#define zend_ts_hash_quick_update(ht, arKey, nKeyLength, h, pData, nDataSize, pDest) \
		_zend_ts_hash_quick_add_or_update(ht, arKey, nKeyLength, h, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)
#define zend_ts_hash_quick_add(ht, arKey, nKeyLength, h, pData, nDataSize, pDest) \
		_zend_ts_hash_quick_add_or_update(ht, arKey, nKeyLength, h, pData, nDataSize, pDest, HASH_ADD ZEND_FILE_LINE_CC)

ZEND_API int _zend_ts_hash_index_update_or_next_insert(TsHashTable *ht, ulong h, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC);
#define zend_ts_hash_index_update(ht, h, pData, nDataSize, pDest) \
		_zend_ts_hash_index_update_or_next_insert(ht, h, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)
#define zend_ts_hash_next_index_insert(ht, pData, nDataSize, pDest) \
		_zend_ts_hash_index_update_or_next_insert(ht, 0, pData, nDataSize, pDest, HASH_NEXT_INSERT ZEND_FILE_LINE_CC)

ZEND_API int zend_ts_hash_add_empty_element(TsHashTable *ht, char *arKey, uint nKeyLength);

ZEND_API void zend_ts_hash_graceful_destroy(TsHashTable *ht);
ZEND_API void zend_ts_hash_apply(TsHashTable *ht, apply_func_t apply_func TSRMLS_DC);
ZEND_API void zend_ts_hash_apply_with_argument(TsHashTable *ht, apply_func_arg_t apply_func, void * TSRMLS_DC);
ZEND_API void zend_ts_hash_apply_with_arguments(TsHashTable *ht, apply_func_args_t apply_func, int, ...);

ZEND_API void zend_ts_hash_reverse_apply(TsHashTable *ht, apply_func_t apply_func TSRMLS_DC);


/* Deletes */
ZEND_API int zend_ts_hash_del_key_or_index(TsHashTable *ht, char *arKey, uint nKeyLength, ulong h, int flag);
#define zend_ts_hash_del(ht, arKey, nKeyLength) \
		zend_ts_hash_del_key_or_index(ht, arKey, nKeyLength, 0, HASH_DEL_KEY)
#define zend_ts_hash_index_del(ht, h) \
		zend_ts_hash_del_key_or_index(ht, NULL, 0, h, HASH_DEL_INDEX)

ZEND_API ulong zend_ts_get_hash_value(TsHashTable *ht, char *arKey, uint nKeyLength);

/* Data retreival */
ZEND_API int zend_ts_hash_find(TsHashTable *ht, char *arKey, uint nKeyLength, void **pData);
ZEND_API int zend_ts_hash_quick_find(TsHashTable *ht, char *arKey, uint nKeyLength, ulong h, void **pData);
ZEND_API int zend_ts_hash_index_find(TsHashTable *ht, ulong h, void **pData);

/* Misc */
ZEND_API int zend_ts_hash_exists(TsHashTable *ht, char *arKey, uint nKeyLength);
ZEND_API int zend_ts_hash_index_exists(TsHashTable *ht, ulong h);

/* Copying, merging and sorting */
ZEND_API void zend_ts_hash_copy(TsHashTable *target, TsHashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size);
ZEND_API void zend_ts_hash_merge(TsHashTable *target, TsHashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size, int overwrite);
ZEND_API void zend_ts_hash_merge_ex(TsHashTable *target, TsHashTable *source, copy_ctor_func_t pCopyConstructor, uint size, merge_checker_func_t pMergeSource, void *pParam);
ZEND_API int zend_ts_hash_sort(TsHashTable *ht, sort_func_t sort_func, compare_func_t compare_func, int renumber TSRMLS_DC);
ZEND_API int zend_ts_hash_compare(TsHashTable *ht1, TsHashTable *ht2, compare_func_t compar, zend_bool ordered TSRMLS_DC);
ZEND_API int zend_ts_hash_minmax(TsHashTable *ht, compare_func_t compar, int flag, void **pData TSRMLS_DC);

ZEND_API int zend_ts_hash_num_elements(TsHashTable *ht);

ZEND_API int zend_ts_hash_rehash(TsHashTable *ht);

ZEND_API ulong zend_ts_hash_func(char *arKey, uint nKeyLength);

#if ZEND_DEBUG
/* debug */
void zend_ts_hash_display_pListTail(TsHashTable *ht);
void zend_ts_hash_display(TsHashTable *ht);
#endif

END_EXTERN_C()

#define ZEND_TS_INIT_SYMTABLE(ht)								\
	ZEND_TS_INIT_SYMTABLE_EX(ht, 2, 0)

#define ZEND_TS_INIT_SYMTABLE_EX(ht, n, persistent)			\
	zend_ts_hash_init(ht, n, NULL, ZVAL_PTR_DTOR, persistent)

#endif							/* ZEND_HASH_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_extensions.h000064400000010507151730541700011631 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_extensions.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef ZEND_EXTENSIONS_H
#define ZEND_EXTENSIONS_H

#include "zend_compile.h"

/* The first number is the engine version and the rest is the date.
 * This way engine 2/3 API no. is always greater than engine 1 API no..
 */
#define ZEND_EXTENSION_API_NO	220060519

typedef struct _zend_extension_version_info {
	int zend_extension_api_no;
	char *required_zend_version;
	unsigned char thread_safe;
	unsigned char debug;
} zend_extension_version_info;


typedef struct _zend_extension zend_extension;

/* Typedef's for zend_extension function pointers */
typedef int (*startup_func_t)(zend_extension *extension);
typedef void (*shutdown_func_t)(zend_extension *extension);
typedef void (*activate_func_t)(void);
typedef void (*deactivate_func_t)(void);

typedef void (*message_handler_func_t)(int message, void *arg);

typedef void (*op_array_handler_func_t)(zend_op_array *op_array);

typedef void (*statement_handler_func_t)(zend_op_array *op_array);
typedef void (*fcall_begin_handler_func_t)(zend_op_array *op_array);
typedef void (*fcall_end_handler_func_t)(zend_op_array *op_array);

typedef void (*op_array_ctor_func_t)(zend_op_array *op_array);
typedef void (*op_array_dtor_func_t)(zend_op_array *op_array);

struct _zend_extension {
	char *name;
	char *version;
	char *author;
	char *URL;
	char *copyright;

	startup_func_t startup;
	shutdown_func_t shutdown;
	activate_func_t activate;
	deactivate_func_t deactivate;

	message_handler_func_t message_handler;

	op_array_handler_func_t op_array_handler;

	statement_handler_func_t statement_handler;
	fcall_begin_handler_func_t fcall_begin_handler;
	fcall_end_handler_func_t fcall_end_handler;

	op_array_ctor_func_t op_array_ctor;
	op_array_dtor_func_t op_array_dtor;

	int (*api_no_check)(int api_no);
	void *reserved2;
	void *reserved3;
	void *reserved4;
	void *reserved5;
	void *reserved6;
	void *reserved7;
	void *reserved8;

	DL_HANDLE handle;
	int resource_number;
};

BEGIN_EXTERN_C()
ZEND_API int zend_get_resource_handle(zend_extension *extension);
ZEND_API void zend_extension_dispatch_message(int message, void *arg);
END_EXTERN_C()

#define ZEND_EXTMSG_NEW_EXTENSION		1


#define ZEND_EXTENSION()	\
	ZEND_EXT_API zend_extension_version_info extension_version_info = { ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG }

#define STANDARD_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
#define COMPAT_ZEND_EXTENSION_PROPERTIES   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1


ZEND_API extern zend_llist zend_extensions;

void zend_extension_dtor(zend_extension *extension);
void zend_append_version_info(zend_extension *extension);
int zend_startup_extensions_mechanism(void);
int zend_startup_extensions(void);
void zend_shutdown_extensions(TSRMLS_D);

BEGIN_EXTERN_C()
ZEND_API int zend_load_extension(char *path);
ZEND_API int zend_register_extension(zend_extension *new_extension, DL_HANDLE handle);
ZEND_API zend_extension *zend_get_extension(char *extension_name);
END_EXTERN_C()

#endif /* ZEND_EXTENSIONS_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_language_parser.h000064400000016613151730541700012575 0ustar00/* A Bison parser, made by GNU Bison 2.3.  */

/* Skeleton interface for Bison's Yacc-like parsers in C

   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
   Free Software Foundation, Inc.

   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, 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., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.  */

/* As a special exception, you may create a larger work that contains
   part or all of the Bison parser skeleton and distribute that work
   under terms of your choice, so long as that work isn't itself a
   parser generator using the skeleton or a modified version thereof
   as a parser skeleton.  Alternatively, if you modify or redistribute
   the parser skeleton itself, you may (at your option) remove this
   special exception, which will cause the skeleton and the resulting
   Bison output files to be licensed under the GNU General Public
   License without this special exception.

   This special exception was added by the Free Software Foundation in
   version 2.2 of Bison.  */

/* Tokens.  */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
   /* Put the tokens into the symbol table, so that GDB and other debuggers
      know about them.  */
   enum yytokentype {
     T_REQUIRE_ONCE = 258,
     T_REQUIRE = 259,
     T_EVAL = 260,
     T_INCLUDE_ONCE = 261,
     T_INCLUDE = 262,
     T_LOGICAL_OR = 263,
     T_LOGICAL_XOR = 264,
     T_LOGICAL_AND = 265,
     T_PRINT = 266,
     T_SR_EQUAL = 267,
     T_SL_EQUAL = 268,
     T_XOR_EQUAL = 269,
     T_OR_EQUAL = 270,
     T_AND_EQUAL = 271,
     T_MOD_EQUAL = 272,
     T_CONCAT_EQUAL = 273,
     T_DIV_EQUAL = 274,
     T_MUL_EQUAL = 275,
     T_MINUS_EQUAL = 276,
     T_PLUS_EQUAL = 277,
     T_BOOLEAN_OR = 278,
     T_BOOLEAN_AND = 279,
     T_IS_NOT_IDENTICAL = 280,
     T_IS_IDENTICAL = 281,
     T_IS_NOT_EQUAL = 282,
     T_IS_EQUAL = 283,
     T_IS_GREATER_OR_EQUAL = 284,
     T_IS_SMALLER_OR_EQUAL = 285,
     T_SR = 286,
     T_SL = 287,
     T_INSTANCEOF = 288,
     T_UNSET_CAST = 289,
     T_BOOL_CAST = 290,
     T_OBJECT_CAST = 291,
     T_ARRAY_CAST = 292,
     T_STRING_CAST = 293,
     T_DOUBLE_CAST = 294,
     T_INT_CAST = 295,
     T_DEC = 296,
     T_INC = 297,
     T_CLONE = 298,
     T_NEW = 299,
     T_EXIT = 300,
     T_IF = 301,
     T_ELSEIF = 302,
     T_ELSE = 303,
     T_ENDIF = 304,
     T_LNUMBER = 305,
     T_DNUMBER = 306,
     T_STRING = 307,
     T_STRING_VARNAME = 308,
     T_VARIABLE = 309,
     T_NUM_STRING = 310,
     T_INLINE_HTML = 311,
     T_CHARACTER = 312,
     T_BAD_CHARACTER = 313,
     T_ENCAPSED_AND_WHITESPACE = 314,
     T_CONSTANT_ENCAPSED_STRING = 315,
     T_ECHO = 316,
     T_DO = 317,
     T_WHILE = 318,
     T_ENDWHILE = 319,
     T_FOR = 320,
     T_ENDFOR = 321,
     T_FOREACH = 322,
     T_ENDFOREACH = 323,
     T_DECLARE = 324,
     T_ENDDECLARE = 325,
     T_AS = 326,
     T_SWITCH = 327,
     T_ENDSWITCH = 328,
     T_CASE = 329,
     T_DEFAULT = 330,
     T_BREAK = 331,
     T_CONTINUE = 332,
     T_FUNCTION = 333,
     T_CONST = 334,
     T_RETURN = 335,
     T_TRY = 336,
     T_CATCH = 337,
     T_THROW = 338,
     T_USE = 339,
     T_GLOBAL = 340,
     T_PUBLIC = 341,
     T_PROTECTED = 342,
     T_PRIVATE = 343,
     T_FINAL = 344,
     T_ABSTRACT = 345,
     T_STATIC = 346,
     T_VAR = 347,
     T_UNSET = 348,
     T_ISSET = 349,
     T_EMPTY = 350,
     T_HALT_COMPILER = 351,
     T_CLASS = 352,
     T_INTERFACE = 353,
     T_EXTENDS = 354,
     T_IMPLEMENTS = 355,
     T_OBJECT_OPERATOR = 356,
     T_DOUBLE_ARROW = 357,
     T_LIST = 358,
     T_ARRAY = 359,
     T_CLASS_C = 360,
     T_METHOD_C = 361,
     T_FUNC_C = 362,
     T_LINE = 363,
     T_FILE = 364,
     T_COMMENT = 365,
     T_DOC_COMMENT = 366,
     T_OPEN_TAG = 367,
     T_OPEN_TAG_WITH_ECHO = 368,
     T_CLOSE_TAG = 369,
     T_WHITESPACE = 370,
     T_START_HEREDOC = 371,
     T_END_HEREDOC = 372,
     T_DOLLAR_OPEN_CURLY_BRACES = 373,
     T_CURLY_OPEN = 374,
     T_PAAMAYIM_NEKUDOTAYIM = 375
   };
#endif
/* Tokens.  */
#define T_REQUIRE_ONCE 258
#define T_REQUIRE 259
#define T_EVAL 260
#define T_INCLUDE_ONCE 261
#define T_INCLUDE 262
#define T_LOGICAL_OR 263
#define T_LOGICAL_XOR 264
#define T_LOGICAL_AND 265
#define T_PRINT 266
#define T_SR_EQUAL 267
#define T_SL_EQUAL 268
#define T_XOR_EQUAL 269
#define T_OR_EQUAL 270
#define T_AND_EQUAL 271
#define T_MOD_EQUAL 272
#define T_CONCAT_EQUAL 273
#define T_DIV_EQUAL 274
#define T_MUL_EQUAL 275
#define T_MINUS_EQUAL 276
#define T_PLUS_EQUAL 277
#define T_BOOLEAN_OR 278
#define T_BOOLEAN_AND 279
#define T_IS_NOT_IDENTICAL 280
#define T_IS_IDENTICAL 281
#define T_IS_NOT_EQUAL 282
#define T_IS_EQUAL 283
#define T_IS_GREATER_OR_EQUAL 284
#define T_IS_SMALLER_OR_EQUAL 285
#define T_SR 286
#define T_SL 287
#define T_INSTANCEOF 288
#define T_UNSET_CAST 289
#define T_BOOL_CAST 290
#define T_OBJECT_CAST 291
#define T_ARRAY_CAST 292
#define T_STRING_CAST 293
#define T_DOUBLE_CAST 294
#define T_INT_CAST 295
#define T_DEC 296
#define T_INC 297
#define T_CLONE 298
#define T_NEW 299
#define T_EXIT 300
#define T_IF 301
#define T_ELSEIF 302
#define T_ELSE 303
#define T_ENDIF 304
#define T_LNUMBER 305
#define T_DNUMBER 306
#define T_STRING 307
#define T_STRING_VARNAME 308
#define T_VARIABLE 309
#define T_NUM_STRING 310
#define T_INLINE_HTML 311
#define T_CHARACTER 312
#define T_BAD_CHARACTER 313
#define T_ENCAPSED_AND_WHITESPACE 314
#define T_CONSTANT_ENCAPSED_STRING 315
#define T_ECHO 316
#define T_DO 317
#define T_WHILE 318
#define T_ENDWHILE 319
#define T_FOR 320
#define T_ENDFOR 321
#define T_FOREACH 322
#define T_ENDFOREACH 323
#define T_DECLARE 324
#define T_ENDDECLARE 325
#define T_AS 326
#define T_SWITCH 327
#define T_ENDSWITCH 328
#define T_CASE 329
#define T_DEFAULT 330
#define T_BREAK 331
#define T_CONTINUE 332
#define T_FUNCTION 333
#define T_CONST 334
#define T_RETURN 335
#define T_TRY 336
#define T_CATCH 337
#define T_THROW 338
#define T_USE 339
#define T_GLOBAL 340
#define T_PUBLIC 341
#define T_PROTECTED 342
#define T_PRIVATE 343
#define T_FINAL 344
#define T_ABSTRACT 345
#define T_STATIC 346
#define T_VAR 347
#define T_UNSET 348
#define T_ISSET 349
#define T_EMPTY 350
#define T_HALT_COMPILER 351
#define T_CLASS 352
#define T_INTERFACE 353
#define T_EXTENDS 354
#define T_IMPLEMENTS 355
#define T_OBJECT_OPERATOR 356
#define T_DOUBLE_ARROW 357
#define T_LIST 358
#define T_ARRAY 359
#define T_CLASS_C 360
#define T_METHOD_C 361
#define T_FUNC_C 362
#define T_LINE 363
#define T_FILE 364
#define T_COMMENT 365
#define T_DOC_COMMENT 366
#define T_OPEN_TAG 367
#define T_OPEN_TAG_WITH_ECHO 368
#define T_CLOSE_TAG 369
#define T_WHITESPACE 370
#define T_START_HEREDOC 371
#define T_END_HEREDOC 372
#define T_DOLLAR_OPEN_CURLY_BRACES 373
#define T_CURLY_OPEN 374
#define T_PAAMAYIM_NEKUDOTAYIM 375




#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef int YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#endif



php/Zend/zend_config.w32.h000064400000006035151730541710011313 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_config.w32.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef ZEND_CONFIG_W32_H
#define ZEND_CONFIG_W32_H

#include <../main/config.w32.h>

#define _CRTDBG_MAP_ALLOC

#include <malloc.h>
#include <stdlib.h>
#include <crtdbg.h>

#include <string.h>

#ifndef ZEND_INCLUDE_FULL_WINDOWS_HEADERS
#define WIN32_LEAN_AND_MEAN
#endif
#include <winsock2.h>
#include <windows.h>

#include <float.h>

typedef unsigned long ulong;
typedef unsigned int uint;

#define HAVE_STDIOSTR_H 1
#define HAVE_CLASS_ISTDIOSTREAM
#define istdiostream stdiostream

#define snprintf _snprintf
#define vsnprintf _vsnprintf
#define strcasecmp(s1, s2) stricmp(s1, s2)
#define strncasecmp(s1, s2, n) strnicmp(s1, s2, n)
#define zend_isinf(a)	((_fpclass(a) == _FPCLASS_PINF) || (_fpclass(a) == _FPCLASS_NINF))
#define zend_finite(x)	_finite(x)
#define zend_isnan(x)	_isnan(x)

#define zend_sprintf sprintf

/* This will cause the compilation process to be MUCH longer, but will generate
 * a much quicker PHP binary
 */
#undef inline
#ifdef ZEND_WIN32_FORCE_INLINE
# define inline __forceinline
#else
# define inline
#endif

#ifdef LIBZEND_EXPORTS
#	define ZEND_API __declspec(dllexport)
#else
#	define ZEND_API __declspec(dllimport)
#endif

#define ZEND_DLEXPORT		__declspec(dllexport)
#define ZEND_DLIMPORT		__declspec(dllimport)

/* 0x00200000L is MB_SERVICE_NOTIFICATION, which is only supported under Windows NT
 * (and requires _WIN32_WINNT to be defined, which prevents the resulting executable
 * from running under Windows 9x
 * Windows 9x should silently ignore it, so it's being used here directly
 */
#ifndef MB_SERVICE_NOTIFICATION
#define	MB_SERVICE_NOTIFICATION		0x00200000L
#endif

#define ZEND_SERVICE_MB_STYLE		(MB_TOPMOST|MB_SERVICE_NOTIFICATION)

#endif /* ZEND_CONFIG_W32_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_operators.h000064400000035240151730541710011452 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        | 
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_operators.h 300606 2010-06-19 20:47:24Z felipe $ */

#ifndef ZEND_OPERATORS_H
#define ZEND_OPERATORS_H

#include <errno.h>
#include <math.h>
#include <assert.h>

#ifdef HAVE_IEEEFP_H
#include <ieeefp.h>
#endif

#include "zend_strtod.h"

#if 0&&HAVE_BCMATH
#include "ext/bcmath/libbcmath/src/bcmath.h"
#endif

BEGIN_EXTERN_C()
ZEND_API int add_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
ZEND_API int sub_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
ZEND_API int mul_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
ZEND_API int div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
ZEND_API int mod_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
ZEND_API int boolean_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
ZEND_API int boolean_not_function(zval *result, zval *op1 TSRMLS_DC);
ZEND_API int bitwise_not_function(zval *result, zval *op1 TSRMLS_DC);
ZEND_API int bitwise_or_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
ZEND_API int bitwise_and_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
ZEND_API int bitwise_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
ZEND_API int shift_left_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
ZEND_API int shift_right_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
ZEND_API int concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);

ZEND_API int is_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
ZEND_API int is_identical_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
ZEND_API int is_not_identical_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
ZEND_API int is_not_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
ZEND_API int is_smaller_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
ZEND_API int is_smaller_or_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);

ZEND_API zend_bool instanceof_function_ex(zend_class_entry *instance_ce, zend_class_entry *ce, zend_bool interfaces_only TSRMLS_DC);
ZEND_API zend_bool instanceof_function(zend_class_entry *instance_ce, zend_class_entry *ce TSRMLS_DC);
END_EXTERN_C()

#define ZEND_IS_DIGIT(c) ((c) >= '0' && (c) <= '9')
#define ZEND_IS_XDIGIT(c) (((c) >= 'A' && (c) <= 'F') || ((c) >= 'a'  && (c) <= 'f'))

/**
 * Checks whether the string "str" with length "length" is numeric. The value
 * of allow_errors determines whether it's required to be entirely numeric, or
 * just its prefix. Leading whitespace is allowed.
 *
 * The function returns 0 if the string did not contain a valid number; IS_LONG
 * if it contained a number that fits within the range of a long; or IS_DOUBLE
 * if the number was out of long range or contained a decimal point/exponent.
 * The number's value is returned into the respective pointer, *lval or *dval,
 * if that pointer is not NULL.
 */

static inline zend_uchar is_numeric_string(const char *str, int length, long *lval, double *dval, int allow_errors)
{
	const char *ptr;
	int base = 10, digits = 0, dp_or_e = 0;
	double local_dval;
	zend_uchar type;

	if (!length) {
		return 0;
	}

	/* Skip any whitespace
	 * This is much faster than the isspace() function */
	while (*str == ' ' || *str == '\t' || *str == '\n' || *str == '\r' || *str == '\v' || *str == '\f') {
		str++;
		length--;
	}
	ptr = str;

	if (*ptr == '-' || *ptr == '+') {
		ptr++;
	}

	if (ZEND_IS_DIGIT(*ptr)) {
		/* Handle hex numbers
		 * str is used instead of ptr to disallow signs and keep old behavior */
		if (length > 2 && *str == '0' && (str[1] == 'x' || str[1] == 'X')) {
			base = 16;
			ptr += 2;
		}

		/* Skip any leading 0s */
		while (*ptr == '0') {
			ptr++;
		}

		/* Count the number of digits. If a decimal point/exponent is found,
		 * it's a double. Otherwise, if there's a dval or no need to check for
		 * a full match, stop when there are too many digits for a long */
		for (type = IS_LONG; !(digits >= MAX_LENGTH_OF_LONG && (dval || allow_errors == 1)); digits++, ptr++) {
check_digits:
			if (ZEND_IS_DIGIT(*ptr) || (base == 16 && ZEND_IS_XDIGIT(*ptr))) {
				continue;
			} else if (base == 10) {
				if (*ptr == '.' && dp_or_e < 1) {
					goto process_double;
				} else if ((*ptr == 'e' || *ptr == 'E') && dp_or_e < 2) {
					const char *e = ptr + 1;

					if (*e == '-' || *e == '+') {
						ptr = e++;
					}
					if (ZEND_IS_DIGIT(*e)) {
						goto process_double;
					}
				}
			}

			break;
		}

		if (base == 10) {
			if (digits >= MAX_LENGTH_OF_LONG) {
				dp_or_e = -1;
				goto process_double;
			}
		} else if (!(digits < SIZEOF_LONG * 2 || (digits == SIZEOF_LONG * 2 && ptr[-digits] <= '7'))) {
			if (dval) {
				local_dval = zend_hex_strtod(str, (char **)&ptr);
			}
			type = IS_DOUBLE;
		}
	} else if (*ptr == '.' && ZEND_IS_DIGIT(ptr[1])) {
process_double:
		type = IS_DOUBLE;

		/* If there's a dval, do the conversion; else continue checking
		 * the digits if we need to check for a full match */
		if (dval) {
			local_dval = zend_strtod(str, (char **)&ptr);
		} else if (allow_errors != 1 && dp_or_e != -1) {
			dp_or_e = (*ptr++ == '.') ? 1 : 2;
			goto check_digits;
		}
	} else {
		return 0;
	}

	if (ptr != str + length) {
		if (!allow_errors) {
			return 0;
		}
		if (allow_errors == -1) {
			zend_error(E_NOTICE, "A non well formed numeric value encountered");
		}
	}

	if (type == IS_LONG) {
		if (digits == MAX_LENGTH_OF_LONG - 1) {
			int cmp = strcmp(&ptr[-digits], long_min_digits);

			if (!(cmp < 0 || (cmp == 0 && *str == '-'))) {
				if (dval) {
					*dval = zend_strtod(str, NULL);
				}

				return IS_DOUBLE;
			}
		}

		if (lval) {
			*lval = strtol(str, NULL, base);
		}

		return IS_LONG;
	} else {
		if (dval) {
			*dval = local_dval;
		}

		return IS_DOUBLE;
	}
}

static inline char *
zend_memnstr(char *haystack, char *needle, int needle_len, char *end)
{
	char *p = haystack;
	char ne = needle[needle_len-1];

	if(needle_len > end-haystack) {
		return NULL;
	}
	end -= needle_len;

	while (p <= end) {
		if ((p = (char *)memchr(p, *needle, (end-p+1))) && ne == p[needle_len-1]) {
			if (!memcmp(needle, p, needle_len-1)) {
				return p;
			}
		}

		if (p == NULL) {
			return NULL;
		}

		p++;
	}

	return NULL;
}

static inline void *zend_memrchr(const void *s, int c, size_t n)
{
	register unsigned char *e;

	if (n <= 0) {
		return NULL;
	}

	for (e = (unsigned char *)s + n - 1; e >= (unsigned char *)s; e--) {
		if (*e == (unsigned char)c) {
			return (void *)e;
		}
	}

	return NULL;
}

BEGIN_EXTERN_C()
ZEND_API int increment_function(zval *op1);
ZEND_API int decrement_function(zval *op2);

ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC);
ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC);
ZEND_API void convert_to_long(zval *op);
ZEND_API void convert_to_double(zval *op);
ZEND_API void convert_to_long_base(zval *op, int base);
ZEND_API void convert_to_null(zval *op);
ZEND_API void convert_to_boolean(zval *op);
ZEND_API void convert_to_array(zval *op);
ZEND_API void convert_to_object(zval *op);
ZEND_API void multi_convert_to_long_ex(int argc, ...);
ZEND_API void multi_convert_to_double_ex(int argc, ...);
ZEND_API void multi_convert_to_string_ex(int argc, ...);
ZEND_API int add_char_to_string(zval *result, zval *op1, zval *op2);
ZEND_API int add_string_to_string(zval *result, zval *op1, zval *op2);
#define convert_to_string(op) if ((op)->type != IS_STRING) { _convert_to_string((op) ZEND_FILE_LINE_CC); }

ZEND_API double zend_string_to_double(const char *number, zend_uint length);

ZEND_API int zval_is_true(zval *op);
ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
ZEND_API int numeric_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
ZEND_API int string_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
#if HAVE_STRCOLL
ZEND_API int string_locale_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
#endif

ZEND_API void zend_str_tolower(char *str, unsigned int length);
ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length);
END_EXTERN_C()

static inline char *
zend_str_tolower_dup(const char *source, unsigned int length)
{
	return zend_str_tolower_copy((char *)emalloc(length+1), source, length);
}

BEGIN_EXTERN_C()
ZEND_API int zend_binary_zval_strcmp(zval *s1, zval *s2);
ZEND_API int zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3);
ZEND_API int zend_binary_zval_strcasecmp(zval *s1, zval *s2);
ZEND_API int zend_binary_zval_strncasecmp(zval *s1, zval *s2, zval *s3);
ZEND_API int zend_binary_strcmp(char *s1, uint len1, char *s2, uint len2);
ZEND_API int zend_binary_strncmp(char *s1, uint len1, char *s2, uint len2, uint length);
ZEND_API int zend_binary_strcasecmp(char *s1, uint len1, char *s2, uint len2);
ZEND_API int zend_binary_strncasecmp(char *s1, uint len1, char *s2, uint len2, uint length);

ZEND_API void zendi_smart_strcmp(zval *result, zval *s1, zval *s2);
ZEND_API void zend_compare_symbol_tables(zval *result, HashTable *ht1, HashTable *ht2 TSRMLS_DC);
ZEND_API void zend_compare_arrays(zval *result, zval *a1, zval *a2 TSRMLS_DC);
ZEND_API void zend_compare_objects(zval *result, zval *o1, zval *o2 TSRMLS_DC);

ZEND_API int zend_atoi(const char *str, int str_len);
ZEND_API long zend_atol(const char *str, int str_len);

ZEND_API void zend_locale_sprintf_double(zval *op ZEND_FILE_LINE_DC);
END_EXTERN_C()
#define convert_to_ex_master(ppzv, lower_type, upper_type)	\
	if ((*ppzv)->type!=IS_##upper_type) {					\
		SEPARATE_ZVAL_IF_NOT_REF(ppzv);						\
		convert_to_##lower_type(*ppzv);						\
	}

#define convert_to_explicit_type(pzv, type)		\
    do {										\
		switch (type) {							\
			case IS_NULL:						\
				convert_to_null(pzv);			\
				break;							\
			case IS_LONG:						\
				convert_to_long(pzv);			\
				break;							\
			case IS_DOUBLE: 					\
				convert_to_double(pzv); 		\
				break; 							\
			case IS_BOOL: 						\
				convert_to_boolean(pzv); 		\
				break; 							\
			case IS_ARRAY: 						\
				convert_to_array(pzv); 			\
				break; 							\
			case IS_OBJECT: 					\
				convert_to_object(pzv); 		\
				break; 							\
			case IS_STRING: 					\
				convert_to_string(pzv); 		\
				break; 							\
			default: 							\
				assert(0); 						\
				break; 							\
		}										\
	} while (0);								\

#define convert_to_explicit_type_ex(ppzv, str_type)	\
	if (Z_TYPE_PP(ppzv) != str_type) {				\
		SEPARATE_ZVAL_IF_NOT_REF(ppzv);				\
		convert_to_explicit_type(*ppzv, str_type);	\
	}

#define convert_to_boolean_ex(ppzv)	convert_to_ex_master(ppzv, boolean, BOOL)
#define convert_to_long_ex(ppzv)	convert_to_ex_master(ppzv, long, LONG)
#define convert_to_double_ex(ppzv)	convert_to_ex_master(ppzv, double, DOUBLE)
#define convert_to_string_ex(ppzv)	convert_to_ex_master(ppzv, string, STRING)
#define convert_to_array_ex(ppzv)	convert_to_ex_master(ppzv, array, ARRAY)
#define convert_to_object_ex(ppzv)	convert_to_ex_master(ppzv, object, OBJECT)
#define convert_to_null_ex(ppzv)	convert_to_ex_master(ppzv, null, NULL)

#define convert_scalar_to_number_ex(ppzv)							\
	if (Z_TYPE_PP(ppzv)!=IS_LONG && Z_TYPE_PP(ppzv)!=IS_DOUBLE) {		\
		if (!(*ppzv)->is_ref) {										\
			SEPARATE_ZVAL(ppzv);									\
		}															\
		convert_scalar_to_number(*ppzv TSRMLS_CC);					\
	}


#define Z_LVAL(zval)			(zval).value.lval
#define Z_BVAL(zval)			((zend_bool)(zval).value.lval)
#define Z_DVAL(zval)			(zval).value.dval
#define Z_STRVAL(zval)			(zval).value.str.val
#define Z_STRLEN(zval)			(zval).value.str.len
#define Z_ARRVAL(zval)			(zval).value.ht
#define Z_OBJVAL(zval)			(zval).value.obj
#define Z_OBJ_HANDLE(zval)		Z_OBJVAL(zval).handle
#define Z_OBJ_HT(zval)			Z_OBJVAL(zval).handlers
#define Z_OBJCE(zval)			zend_get_class_entry(&(zval) TSRMLS_CC)
#define Z_OBJPROP(zval)			Z_OBJ_HT((zval))->get_properties(&(zval) TSRMLS_CC)
#define Z_OBJ_HANDLER(zval, hf) Z_OBJ_HT((zval))->hf
#define Z_RESVAL(zval)			(zval).value.lval

#define Z_LVAL_P(zval_p)		Z_LVAL(*zval_p)
#define Z_BVAL_P(zval_p)		Z_BVAL(*zval_p)
#define Z_DVAL_P(zval_p)		Z_DVAL(*zval_p)
#define Z_STRVAL_P(zval_p)		Z_STRVAL(*zval_p)
#define Z_STRLEN_P(zval_p)		Z_STRLEN(*zval_p)
#define Z_ARRVAL_P(zval_p)		Z_ARRVAL(*zval_p)
#define Z_OBJPROP_P(zval_p)		Z_OBJPROP(*zval_p)
#define Z_OBJCE_P(zval_p)		Z_OBJCE(*zval_p)
#define Z_RESVAL_P(zval_p)		Z_RESVAL(*zval_p)
#define Z_OBJVAL_P(zval_p)      Z_OBJVAL(*zval_p)
#define Z_OBJ_HANDLE_P(zval_p)  Z_OBJ_HANDLE(*zval_p)
#define Z_OBJ_HT_P(zval_p)      Z_OBJ_HT(*zval_p)
#define Z_OBJ_HANDLER_P(zval_p, h) Z_OBJ_HANDLER(*zval_p, h)

#define Z_LVAL_PP(zval_pp)		Z_LVAL(**zval_pp)
#define Z_BVAL_PP(zval_pp)		Z_BVAL(**zval_pp)
#define Z_DVAL_PP(zval_pp)		Z_DVAL(**zval_pp)
#define Z_STRVAL_PP(zval_pp)	Z_STRVAL(**zval_pp)
#define Z_STRLEN_PP(zval_pp)	Z_STRLEN(**zval_pp)
#define Z_ARRVAL_PP(zval_pp)	Z_ARRVAL(**zval_pp)
#define Z_OBJPROP_PP(zval_pp)	Z_OBJPROP(**zval_pp)
#define Z_OBJCE_PP(zval_pp)		Z_OBJCE(**zval_pp)
#define Z_RESVAL_PP(zval_pp)	Z_RESVAL(**zval_pp)
#define Z_OBJVAL_PP(zval_pp)    Z_OBJVAL(**zval_pp)
#define Z_OBJ_HANDLE_PP(zval_p) Z_OBJ_HANDLE(**zval_p)
#define Z_OBJ_HT_PP(zval_p)     Z_OBJ_HT(**zval_p)
#define Z_OBJ_HANDLER_PP(zval_p, h) Z_OBJ_HANDLER(**zval_p, h)

#define Z_TYPE(zval)		(zval).type
#define Z_TYPE_P(zval_p)	Z_TYPE(*zval_p)
#define Z_TYPE_PP(zval_pp)	Z_TYPE(**zval_pp)

#if HAVE_SETLOCALE && defined(ZEND_WIN32) && !defined(ZTS) && defined(_MSC_VER) && (_MSC_VER >= 1400)
/* This is performance improvement of tolower() on Windows and VC2005
 * GIves 10-18% on bench.php
 */
#define ZEND_USE_TOLOWER_L 1
#endif

#ifdef ZEND_USE_TOLOWER_L
ZEND_API void zend_update_current_locale(void);
#else
#define zend_update_current_locale()
#endif

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_bitset.h000064400000015671151730541720010735 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend OPcache JIT                                                     |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2018 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Dmitry Stogov <dmitry@zend.com>                             |
   +----------------------------------------------------------------------+
*/

/* $Id:$ */

#ifndef _ZEND_BITSET_H_
#define _ZEND_BITSET_H_

typedef zend_ulong *zend_bitset;

#define ZEND_BITSET_ELM_SIZE sizeof(zend_ulong)

#if SIZEOF_ZEND_LONG == 4
# define ZEND_BITSET_ELM_NUM(n)		((n) >> 5)
# define ZEND_BITSET_BIT_NUM(n)		((zend_ulong)(n) & Z_UL(0x1f))
#elif SIZEOF_ZEND_LONG == 8
# define ZEND_BITSET_ELM_NUM(n)		((n) >> 6)
# define ZEND_BITSET_BIT_NUM(n)		((zend_ulong)(n) & Z_UL(0x3f))
#else
# define ZEND_BITSET_ELM_NUM(n)		((n) / (sizeof(zend_long) * 8))
# define ZEND_BITSET_BIT_NUM(n)		((n) % (sizeof(zend_long) * 8))
#endif

#define ZEND_BITSET_ALLOCA(n, use_heap) \
	(zend_bitset)do_alloca((n) * ZEND_BITSET_ELM_SIZE, use_heap)

/* Number of trailing zero bits (0x01 -> 0; 0x40 -> 6; 0x00 -> LEN) */
static zend_always_inline int zend_ulong_ntz(zend_ulong num)
{
#if (defined(__GNUC__) || __has_builtin(__builtin_ctzl)) \
	&& SIZEOF_ZEND_LONG == SIZEOF_LONG && defined(PHP_HAVE_BUILTIN_CTZL)
	return __builtin_ctzl(num);
#elif (defined(__GNUC__) || __has_builtin(__builtin_ctzll)) && defined(PHP_HAVE_BUILTIN_CTZLL)
	return __builtin_ctzll(num);
#elif defined(_WIN32)
	unsigned long index;

#if defined(_WIN64)
	if (!BitScanForward64(&index, num)) {
#else
	if (!BitScanForward(&index, num)) {
#endif
		/* undefined behavior */
		return SIZEOF_ZEND_LONG * 8;
	}

	return (int) index;
#else
	int n;

	if (num == Z_UL(0)) return SIZEOF_ZEND_LONG * 8;

	n = 1;
#if SIZEOF_ZEND_LONG == 8
	if ((num & 0xffffffff) == 0) {n += 32; num = num >> Z_UL(32);}
#endif
	if ((num & 0x0000ffff) == 0) {n += 16; num = num >> 16;}
	if ((num & 0x000000ff) == 0) {n +=  8; num = num >>  8;}
	if ((num & 0x0000000f) == 0) {n +=  4; num = num >>  4;}
	if ((num & 0x00000003) == 0) {n +=  2; num = num >>  2;}
	return n - (num & 1);
#endif
}

/* Returns the number of zend_ulong words needed to store a bitset that is N
   bits long.  */
static inline uint32_t zend_bitset_len(uint32_t n)
{
	return (n + ((sizeof(zend_long) * 8) - 1)) / (sizeof(zend_long) * 8);
}

static inline zend_bool zend_bitset_in(zend_bitset set, uint32_t n)
{
	return (set[ZEND_BITSET_ELM_NUM(n)] & (Z_UL(1) << ZEND_BITSET_BIT_NUM(n))) != Z_UL(0);
}

static inline void zend_bitset_incl(zend_bitset set, uint32_t n)
{
	set[ZEND_BITSET_ELM_NUM(n)] |= Z_UL(1) << ZEND_BITSET_BIT_NUM(n);
}

static inline void zend_bitset_excl(zend_bitset set, uint32_t n)
{
	set[ZEND_BITSET_ELM_NUM(n)] &= ~(Z_UL(1) << ZEND_BITSET_BIT_NUM(n));
}

static inline void zend_bitset_clear(zend_bitset set, uint32_t len)
{
	memset(set, 0, len * ZEND_BITSET_ELM_SIZE);
}

static inline int zend_bitset_empty(zend_bitset set, uint32_t len)
{
	uint32_t i;
	for (i = 0; i < len; i++) {
		if (set[i]) {
			return 0;
		}
	}
	return 1;
}

static inline void zend_bitset_fill(zend_bitset set, uint32_t len)
{
	memset(set, 0xff, len * ZEND_BITSET_ELM_SIZE);
}

static inline zend_bool zend_bitset_equal(zend_bitset set1, zend_bitset set2, uint32_t len)
{
    return memcmp(set1, set2, len * ZEND_BITSET_ELM_SIZE) == 0;
}

static inline void zend_bitset_copy(zend_bitset set1, zend_bitset set2, uint32_t len)
{
    memcpy(set1, set2, len * ZEND_BITSET_ELM_SIZE);
}

static inline void zend_bitset_intersection(zend_bitset set1, zend_bitset set2, uint32_t len)
{
    uint32_t i;

    for (i = 0; i < len; i++) {
		set1[i] &= set2[i];
	}
}

static inline void zend_bitset_union(zend_bitset set1, zend_bitset set2, uint32_t len)
{
	uint32_t i;

	for (i = 0; i < len; i++) {
		set1[i] |= set2[i];
	}
}

static inline void zend_bitset_difference(zend_bitset set1, zend_bitset set2, uint32_t len)
{
	uint32_t i;

	for (i = 0; i < len; i++) {
		set1[i] = set1[i] & ~set2[i];
	}
}

static inline void zend_bitset_union_with_intersection(zend_bitset set1, zend_bitset set2, zend_bitset set3, zend_bitset set4, uint32_t len)
{
	uint32_t i;

	for (i = 0; i < len; i++) {
		set1[i] = set2[i] | (set3[i] & set4[i]);
	}
}

static inline void zend_bitset_union_with_difference(zend_bitset set1, zend_bitset set2, zend_bitset set3, zend_bitset set4, uint32_t len)
{
	uint32_t i;

	for (i = 0; i < len; i++) {
		set1[i] = set2[i] | (set3[i] & ~set4[i]);
	}
}

static inline zend_bool zend_bitset_subset(zend_bitset set1, zend_bitset set2, uint32_t len)
{
	uint32_t i;

	for (i = 0; i < len; i++) {
		if (set1[i] & ~set2[i]) {
			return 0;
		}
	}
	return 1;
}

static inline int zend_bitset_first(zend_bitset set, uint32_t len)
{
	uint32_t i;

	for (i = 0; i < len; i++) {
		if (set[i]) {
			return ZEND_BITSET_ELM_SIZE * 8 * i + zend_ulong_ntz(set[i]);
		}
	}
	return -1; /* empty set */
}

static inline int zend_bitset_last(zend_bitset set, uint32_t len)
{
	uint32_t i = len;

	while (i > 0) {
		i--;
		if (set[i]) {
			int j = ZEND_BITSET_ELM_SIZE * 8 * i - 1;
			zend_ulong x = set[i];
			while (x != Z_UL(0)) {
				x = x >> Z_UL(1);
				j++;
			}
			return j;
		}
	}
	return -1; /* empty set */
}

#define ZEND_BITSET_FOREACH(set, len, bit) do { \
	zend_bitset _set = (set); \
	uint32_t _i, _len = (len); \
	for (_i = 0; _i < _len; _i++) { \
		zend_ulong _x = _set[_i]; \
		if (_x) { \
			(bit) = ZEND_BITSET_ELM_SIZE * 8 * _i; \
			for (; _x != 0; _x >>= Z_UL(1), (bit)++) { \
				if (!(_x & Z_UL(1))) continue;

#define ZEND_BITSET_REVERSE_FOREACH(set, len, bit) do { \
	zend_bitset _set = (set); \
	uint32_t _i = (len); \
	zend_ulong _test = Z_UL(1) << (ZEND_BITSET_ELM_SIZE * 8 - 1); \
	while (_i-- > 0) { \
		zend_ulong _x = _set[_i]; \
		if (_x) { \
			(bit) = ZEND_BITSET_ELM_SIZE * 8 * (_i + 1) - 1; \
			for (; _x != 0; _x <<= Z_UL(1), (bit)--) { \
				if (!(_x & _test)) continue; \

#define ZEND_BITSET_FOREACH_END() \
			} \
		} \
	} \
} while (0)

static inline int zend_bitset_pop_first(zend_bitset set, uint32_t len) {
	int i = zend_bitset_first(set, len);
	if (i >= 0) {
		zend_bitset_excl(set, i);
	}
	return i;
}

#endif /* _ZEND_BITSET_H_ */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/Zend/zend_ini_parser.h000064400000004503151730541720011566 0ustar00/* A Bison parser, made by GNU Bison 2.3.  */

/* Skeleton interface for Bison's Yacc-like parsers in C

   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
   Free Software Foundation, Inc.

   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, 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., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.  */

/* As a special exception, you may create a larger work that contains
   part or all of the Bison parser skeleton and distribute that work
   under terms of your choice, so long as that work isn't itself a
   parser generator using the skeleton or a modified version thereof
   as a parser skeleton.  Alternatively, if you modify or redistribute
   the parser skeleton itself, you may (at your option) remove this
   special exception, which will cause the skeleton and the resulting
   Bison output files to be licensed under the GNU General Public
   License without this special exception.

   This special exception was added by the Free Software Foundation in
   version 2.2 of Bison.  */

/* Tokens.  */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
   /* Put the tokens into the symbol table, so that GDB and other debuggers
      know about them.  */
   enum yytokentype {
     TC_STRING = 258,
     TC_ENCAPSULATED_STRING = 259,
     BRACK = 260,
     SECTION = 261,
     CFG_TRUE = 262,
     CFG_FALSE = 263,
     TC_DOLLAR_CURLY = 264
   };
#endif
/* Tokens.  */
#define TC_STRING 258
#define TC_ENCAPSULATED_STRING 259
#define BRACK 260
#define SECTION 261
#define CFG_TRUE 262
#define CFG_FALSE 263
#define TC_DOLLAR_CURLY 264




#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef int YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#endif



php/Zend/zend_sort.h000064400000003406151730541730010424 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2018 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Xinchen Hui <laruence@php.net>                              |
   |          Sterling Hughes <sterling@php.net>                          |
   +----------------------------------------------------------------------+
*/

/* $Id$ */

#ifndef ZEND_SORT_H
#define ZEND_SORT_H

BEGIN_EXTERN_C()
ZEND_API void zend_qsort(void *base, size_t nmemb, size_t siz, compare_func_t cmp, swap_func_t swp);
ZEND_API void zend_sort(void *base, size_t nmemb, size_t siz, compare_func_t cmp, swap_func_t swp);
ZEND_API void zend_insert_sort(void *base, size_t nmemb, size_t siz, compare_func_t cmp, swap_func_t swp);
END_EXTERN_C()

#endif       /* ZEND_SORT_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/Zend/zend_config.h000064400000000153151730541730010676 0ustar00#include <../main/php_config.h>
#if defined(APACHE) && defined(PHP_API_VERSION)
#undef HAVE_DLFCN_H
#endif
php/Zend/zend_strtod_int.h000064400000007101151730541740011623 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2018 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Anatol Belski <ab@php.net>                                  |
   +----------------------------------------------------------------------+
*/

#ifndef ZEND_STRTOD_INT_H
#define ZEND_STRTOD_INT_H

#ifdef ZTS
#include <TSRM.h>
#endif

#include <stddef.h>
#include <stdio.h>
#include <ctype.h>
#include <stdarg.h>
#include <math.h>

#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif

/* TODO check to undef this option, this might
	make more perf. destroy_freelist()
	should be adapted then. */
#define Omit_Private_Memory 1

/* HEX strings aren't supported as per
	https://wiki.php.net/rfc/remove_hex_support_in_numeric_strings */
#define NO_HEX_FP 1

#if defined(HAVE_INTTYPES_H)
#include <inttypes.h>
#elif defined(HAVE_STDINT_H)
#include <stdint.h>
#endif

#ifndef HAVE_INT32_T
# if SIZEOF_INT == 4
typedef int int32_t;
# elif SIZEOF_LONG == 4
typedef long int int32_t;
# endif
#endif

#ifndef HAVE_UINT32_T
# if SIZEOF_INT == 4
typedef unsigned int uint32_t;
# elif SIZEOF_LONG == 4
typedef unsigned long int uint32_t;
# endif
#endif

#ifdef USE_LOCALE
#undef USE_LOCALE
#endif

#ifndef NO_INFNAN_CHECK
#define NO_INFNAN_CHECK
#endif

#ifndef NO_ERRNO
#define NO_ERRNO
#endif

#ifdef WORDS_BIGENDIAN
#define IEEE_BIG_ENDIAN 1
#else
#define IEEE_LITTLE_ENDIAN 1
#endif

#if (defined(__APPLE__) || defined(__APPLE_CC__)) && (defined(__BIG_ENDIAN__) || defined(__LITTLE_ENDIAN__))
# if defined(__LITTLE_ENDIAN__)
#  undef WORDS_BIGENDIAN
# else
#  if defined(__BIG_ENDIAN__)
#   define WORDS_BIGENDIAN
#  endif
# endif
#endif

#if defined(__arm__) && !defined(__VFP_FP__)
/*
 *  * Although the CPU is little endian the FP has different
 *   * byte and word endianness. The byte order is still little endian
 *    * but the word order is big endian.
 *     */
#define IEEE_BIG_ENDIAN
#undef IEEE_LITTLE_ENDIAN
#endif

#ifdef __vax__
#define VAX
#undef IEEE_LITTLE_ENDIAN
#endif

#ifdef IEEE_LITTLE_ENDIAN
#define IEEE_8087 1
#endif

#ifdef IEEE_BIG_ENDIAN
#define IEEE_MC68k 1
#endif

#if defined(_MSC_VER)
#ifndef int32_t
#define int32_t __int32
#endif
#ifndef uint32_t
#define uint32_t unsigned __int32
#endif
#endif

#ifdef ZTS
#define MULTIPLE_THREADS 1

#define  ACQUIRE_DTOA_LOCK(x) \
	if (0 == x) { \
		tsrm_mutex_lock(dtoa_mutex); \
	} else if (1 == x) { \
		tsrm_mutex_lock(pow5mult_mutex); \
	}

#define FREE_DTOA_LOCK(x) \
	if (0 == x) { \
		tsrm_mutex_unlock(dtoa_mutex); \
	} else if (1 == x) { \
		tsrm_mutex_unlock(pow5mult_mutex); \
	}


#endif

#endif /* ZEND_STRTOD_INT_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/Zend/zend.h000064400000052113151730541740007355 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        | 
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: zend.h 293590 2010-01-15 18:26:53Z rasmus $ */

#ifndef ZEND_H
#define ZEND_H

#define ZEND_VERSION "2.2.0"

#define ZEND_ENGINE_2

#ifdef __cplusplus
#define BEGIN_EXTERN_C() extern "C" {
#define END_EXTERN_C() }
#else
#define BEGIN_EXTERN_C()
#define END_EXTERN_C()
#endif

#include <stdio.h>

/*
 * general definitions
 */

#ifdef ZEND_WIN32
# include "zend_config.w32.h"
# define ZEND_PATHS_SEPARATOR		';'
#elif defined(NETWARE)
# include <zend_config.h>
# define ZEND_PATHS_SEPARATOR		';'
#elif defined(__riscos__)
# include <zend_config.h>
# define ZEND_PATHS_SEPARATOR		';'
#else
# include <zend_config.h>
# define ZEND_PATHS_SEPARATOR		':'
#endif


#ifdef ZEND_WIN32
/* Only use this macro if you know for sure that all of the switches values
   are covered by its case statements */
#define EMPTY_SWITCH_DEFAULT_CASE() \
			default:				\
				__assume(0);		\
				break;
#else
#define EMPTY_SWITCH_DEFAULT_CASE()
#endif

/* all HAVE_XXX test have to be after the include of zend_config above */

#ifdef HAVE_UNIX_H
# include <unix.h>
#endif

#ifdef HAVE_STDARG_H
# include <stdarg.h>
#endif

#ifdef HAVE_DLFCN_H
# include <dlfcn.h>
#endif

#if HAVE_MACH_O_DYLD_H
#include <mach-o/dyld.h>

/* MH_BUNDLE loading functions for Mac OS X / Darwin */
void *zend_mh_bundle_load (char* bundle_path);
int zend_mh_bundle_unload (void *bundle_handle);
void *zend_mh_bundle_symbol(void *bundle_handle, const char *symbol_name);
const char *zend_mh_bundle_error(void);

#endif /* HAVE_MACH_O_DYLD_H */

#if defined(HAVE_LIBDL) && !defined(HAVE_MACH_O_DYLD_H) && !defined(ZEND_WIN32)

# ifndef RTLD_LAZY
#  define RTLD_LAZY 1    /* Solaris 1, FreeBSD's (2.1.7.1 and older) */
# endif

# ifndef RTLD_GLOBAL
#  define RTLD_GLOBAL 0
# endif

# if defined(RTLD_GROUP) && defined(RTLD_WORLD) && defined(RTLD_PARENT)
#  define DL_LOAD(libname)			dlopen(libname, RTLD_NOW | RTLD_GLOBAL | RTLD_GROUP | RTLD_WORLD | RTLD_PARENT)
# elif defined(RTLD_DEEPBIND)
#  define DL_LOAD(libname)			dlopen(libname, RTLD_NOW | RTLD_GLOBAL | RTLD_DEEPBIND)
# else
#  define DL_LOAD(libname)			dlopen(libname, RTLD_NOW | RTLD_GLOBAL)
# endif
# define DL_UNLOAD					dlclose
# if defined(DLSYM_NEEDS_UNDERSCORE)
#  define DL_FETCH_SYMBOL(h,s)		dlsym((h), "_" s)
# else
#  define DL_FETCH_SYMBOL			dlsym
# endif
# define DL_ERROR					dlerror
# define DL_HANDLE					void *
# define ZEND_EXTENSIONS_SUPPORT	1
#elif defined(HAVE_MACH_O_DYLD_H)
# define DL_LOAD(libname)			zend_mh_bundle_load(libname)
# define DL_UNLOAD			zend_mh_bundle_unload
# define DL_FETCH_SYMBOL(h,s)		zend_mh_bundle_symbol(h,s)
# define DL_ERROR					zend_mh_bundle_error
# define DL_HANDLE					void *
# define ZEND_EXTENSIONS_SUPPORT	1
#elif defined(ZEND_WIN32)
# define DL_LOAD(libname)			LoadLibrary(libname)
# define DL_FETCH_SYMBOL			GetProcAddress
# define DL_UNLOAD					FreeLibrary
# define DL_HANDLE					HMODULE
# define ZEND_EXTENSIONS_SUPPORT	1
#else
# define DL_HANDLE					void *
# define ZEND_EXTENSIONS_SUPPORT	0
#endif

#if HAVE_ALLOCA_H && !defined(_ALLOCA_H)
#  include <alloca.h>
#endif

/* AIX requires this to be the first thing in the file.  */
#ifndef __GNUC__
# ifndef HAVE_ALLOCA_H
#  ifdef _AIX
#pragma alloca
#  else
#   ifndef alloca /* predefined by HP cc +Olibcalls */
char *alloca ();
#   endif
#  endif
# endif
#endif

/* GCC x.y.z supplies __GNUC__ = x and __GNUC_MINOR__ = y */
#ifdef __GNUC__
# define ZEND_GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
#else
# define ZEND_GCC_VERSION 0
#endif

#if ZEND_GCC_VERSION >= 2096
# define ZEND_ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
#else
# define ZEND_ATTRIBUTE_MALLOC
#endif

#if ZEND_GCC_VERSION >= 2007
# define ZEND_ATTRIBUTE_FORMAT(type, idx, first) __attribute__ ((format(type, idx, first)))
#else
# define ZEND_ATTRIBUTE_FORMAT(type, idx, first)
#endif

#if ZEND_GCC_VERSION >= 3001 && !defined(__INTEL_COMPILER)
# define ZEND_ATTRIBUTE_PTR_FORMAT(type, idx, first) __attribute__ ((format(type, idx, first)))
#else
# define ZEND_ATTRIBUTE_PTR_FORMAT(type, idx, first)
#endif


#if defined(__GNUC__) && ZEND_GCC_VERSION >= 3004
#else
# define __restrict__
#endif
#define restrict __restrict__

#if (HAVE_ALLOCA || (defined (__GNUC__) && __GNUC__ >= 2)) && !(defined(ZTS) && defined(ZEND_WIN32)) && !(defined(ZTS) && defined(NETWARE)) && !(defined(ZTS) && defined(HPUX)) && !defined(DARWIN)
# define do_alloca(p) alloca(p)
# define free_alloca(p)
# define ZEND_ALLOCA_MAX_SIZE (32 * 1024)
# define ALLOCA_FLAG(name) \
	zend_bool name;
# define do_alloca_with_limit_ex(size, limit, use_heap) \
	((use_heap = ((size) > (limit))) ? emalloc(size) : alloca(size))
# define do_alloca_with_limit(size, use_heap) \
	do_alloca_with_limit_ex(size, ZEND_ALLOCA_MAX_SIZE, use_heap)
# define free_alloca_with_limit(p, use_heap) \
	do { if (use_heap) efree(p); } while (0)
#else
# define do_alloca(p)		emalloc(p)
# define free_alloca(p)	efree(p)
# define ALLOCA_FLAG(name)
# define do_alloca_with_limit(p, use_heap)		emalloc(p)
# define free_alloca_with_limit(p, use_heap)	efree(p)
#endif

#if ZEND_DEBUG
#define ZEND_FILE_LINE_D				char *__zend_filename, uint __zend_lineno
#define ZEND_FILE_LINE_DC				, ZEND_FILE_LINE_D
#define ZEND_FILE_LINE_ORIG_D			char *__zend_orig_filename, uint __zend_orig_lineno
#define ZEND_FILE_LINE_ORIG_DC			, ZEND_FILE_LINE_ORIG_D
#define ZEND_FILE_LINE_RELAY_C			__zend_filename, __zend_lineno
#define ZEND_FILE_LINE_RELAY_CC			, ZEND_FILE_LINE_RELAY_C
#define ZEND_FILE_LINE_C				__FILE__, __LINE__
#define ZEND_FILE_LINE_CC				, ZEND_FILE_LINE_C
#define ZEND_FILE_LINE_EMPTY_C			NULL, 0
#define ZEND_FILE_LINE_EMPTY_CC			, ZEND_FILE_LINE_EMPTY_C
#define ZEND_FILE_LINE_ORIG_RELAY_C		__zend_orig_filename, __zend_orig_lineno
#define ZEND_FILE_LINE_ORIG_RELAY_CC	, ZEND_FILE_LINE_ORIG_RELAY_C
#else
#define ZEND_FILE_LINE_D
#define ZEND_FILE_LINE_DC
#define ZEND_FILE_LINE_ORIG_D
#define ZEND_FILE_LINE_ORIG_DC
#define ZEND_FILE_LINE_RELAY_C
#define ZEND_FILE_LINE_RELAY_CC
#define ZEND_FILE_LINE_C
#define ZEND_FILE_LINE_CC
#define ZEND_FILE_LINE_EMPTY_C
#define ZEND_FILE_LINE_EMPTY_CC
#define ZEND_FILE_LINE_ORIG_RELAY_C
#define ZEND_FILE_LINE_ORIG_RELAY_CC
#endif	/* ZEND_DEBUG */

#ifdef ZTS
#define ZTS_V 1
#else
#define ZTS_V 0
#endif

#include "zend_errors.h"
#include "zend_alloc.h"

#include "zend_types.h"

#ifdef HAVE_LIMITS_H
# include <limits.h>
#endif

#ifndef LONG_MAX
#define LONG_MAX 2147483647L
#endif

#ifndef LONG_MIN
#define LONG_MIN (- LONG_MAX - 1)
#endif

#if SIZEOF_LONG == 4
#define MAX_LENGTH_OF_LONG 11
static const char long_min_digits[] = "2147483648";
#elif SIZEOF_LONG == 8
#define MAX_LENGTH_OF_LONG 20
static const char long_min_digits[] = "9223372036854775808";
#else
#error "Unknown SIZEOF_LONG"
#endif

#define MAX_LENGTH_OF_DOUBLE 32

#undef SUCCESS
#undef FAILURE
#define SUCCESS 0
#define FAILURE -1				/* this MUST stay a negative number, or it may affect functions! */


#include "zend_hash.h"
#include "zend_ts_hash.h"
#include "zend_llist.h"

#define INTERNAL_FUNCTION_PARAMETERS int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_value_used TSRMLS_DC
#define INTERNAL_FUNCTION_PARAM_PASSTHRU ht, return_value, return_value_ptr, this_ptr, return_value_used TSRMLS_CC

#if defined(__GNUC__) && __GNUC__ >= 3 && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX) && !defined(__osf__) && __GNUC__ >= 3
#  define ZEND_VM_ALWAYS_INLINE  __attribute__ ((always_inline))
void zend_error_noreturn(int type, const char *format, ...) __attribute__ ((noreturn));
#else
#  define ZEND_VM_ALWAYS_INLINE
#  define zend_error_noreturn zend_error
#endif

/*
 * zval
 */
typedef struct _zval_struct zval;
typedef struct _zend_class_entry zend_class_entry;

typedef struct _zend_guard {
	zend_bool in_get;
	zend_bool in_set;
	zend_bool in_unset;
	zend_bool in_isset;
	zend_bool dummy; /* sizeof(zend_guard) must not be equal to sizeof(void*) */
} zend_guard;

typedef struct _zend_object {
	zend_class_entry *ce;
	HashTable *properties;
	HashTable *guards; /* protects from __get/__set ... recursion */
} zend_object;

#include "zend_object_handlers.h"

typedef union _zvalue_value {
	long lval;					/* long value */
	double dval;				/* double value */
	struct {
		char *val;
		int len;
	} str;
	HashTable *ht;				/* hash table value */
	zend_object_value obj;
} zvalue_value;


struct _zval_struct {
	/* Variable information */
	zvalue_value value;		/* value */
	zend_uint refcount;
	zend_uchar type;	/* active type */
	zend_uchar is_ref;
};


#if (defined (__GNUC__) && __GNUC__ > 2 ) && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX)
# define EXPECTED(condition)   __builtin_expect(condition, 1)
# define UNEXPECTED(condition) __builtin_expect(condition, 0)
#else
# define EXPECTED(condition)   (condition)
# define UNEXPECTED(condition) (condition)
#endif

/* excpt.h on Digital Unix 4.0 defines function_table */
#undef function_table

/* A lot of stuff needs shifiting around in order to include zend_compile.h here */
union _zend_function;

#include "zend_iterators.h"

struct _zend_serialize_data;
struct _zend_unserialize_data;

typedef struct _zend_serialize_data zend_serialize_data;
typedef struct _zend_unserialize_data zend_unserialize_data;

struct _zend_class_entry {
	char type;
	char *name;
	zend_uint name_length;
	struct _zend_class_entry *parent;
	int refcount;
	zend_bool constants_updated;
	zend_uint ce_flags;

	HashTable function_table;
	HashTable default_properties;
	HashTable properties_info;
	HashTable default_static_members;
	HashTable *static_members;
	HashTable constants_table;
	struct _zend_function_entry *builtin_functions;

	union _zend_function *constructor;
	union _zend_function *destructor;
	union _zend_function *clone;
	union _zend_function *__get;
	union _zend_function *__set;
	union _zend_function *__unset;
	union _zend_function *__isset;
	union _zend_function *__call;
	union _zend_function *__tostring;
	union _zend_function *serialize_func;
	union _zend_function *unserialize_func;

	zend_class_iterator_funcs iterator_funcs;

	/* handlers */
	zend_object_value (*create_object)(zend_class_entry *class_type TSRMLS_DC);
	zend_object_iterator *(*get_iterator)(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC);
	int (*interface_gets_implemented)(zend_class_entry *iface, zend_class_entry *class_type TSRMLS_DC); /* a class implements this interface */

	/* serializer callbacks */
	int (*serialize)(zval *object, unsigned char **buffer, zend_uint *buf_len, zend_serialize_data *data TSRMLS_DC);
	int (*unserialize)(zval **object, zend_class_entry *ce, const unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC);

	zend_class_entry **interfaces;
	zend_uint num_interfaces;

	char *filename;
	zend_uint line_start;
	zend_uint line_end;
	char *doc_comment;
	zend_uint doc_comment_len;

	struct _zend_module_entry *module;
};

#include "zend_stream.h"
typedef struct _zend_utility_functions {
	void (*error_function)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 4, 0);
	int (*printf_function)(const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 1, 2);
	int (*write_function)(const char *str, uint str_length);
	FILE *(*fopen_function)(const char *filename, char **opened_path);
	void (*message_handler)(long message, void *data);
	void (*block_interruptions)(void);
	void (*unblock_interruptions)(void);
	int (*get_configuration_directive)(char *name, uint name_length, zval *contents);
	void (*ticks_function)(int ticks);
	void (*on_timeout)(int seconds TSRMLS_DC);
	int (*stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC);
	int (*vspprintf_function)(char **pbuf, size_t max_len, const char *format, va_list ap);
	char *(*getenv_function)(char *name, size_t name_len TSRMLS_DC);
} zend_utility_functions;


typedef struct _zend_utility_values {
	char *import_use_extension;
	uint import_use_extension_length;
	zend_bool html_errors;
} zend_utility_values;


typedef int (*zend_write_func_t)(const char *str, uint str_length);


#undef MIN
#undef MAX
#define MAX(a, b)  (((a)>(b))?(a):(b))
#define MIN(a, b)  (((a)<(b))?(a):(b))
#define ZEND_STRL(str)		(str), (sizeof(str)-1)
#define ZEND_STRS(str)		(str), (sizeof(str))
#define ZEND_NORMALIZE_BOOL(n)			\
	((n) ? (((n)>0) ? 1 : -1) : 0)
#define ZEND_TRUTH(x)		((x) ? 1 : 0)
#define ZEND_LOG_XOR(a, b)		(ZEND_TRUTH(a) ^ ZEND_TRUTH(b))



/* data types */
/* All data types <= IS_BOOL have their constructor/destructors skipped */
#define IS_NULL		0
#define IS_LONG		1
#define IS_DOUBLE	2
#define IS_BOOL		3
#define IS_ARRAY	4
#define IS_OBJECT	5
#define IS_STRING	6
#define IS_RESOURCE	7
#define IS_CONSTANT	8
#define IS_CONSTANT_ARRAY	9

/* Ugly hack to support constants as static array indices */
#define IS_CONSTANT_INDEX	0x80


/* overloaded elements data types */
#define OE_IS_ARRAY	(1<<0)
#define OE_IS_OBJECT	(1<<1)
#define OE_IS_METHOD	(1<<2)

int zend_startup(zend_utility_functions *utility_functions, char **extensions, int start_builtin_functions);
void zend_shutdown(TSRMLS_D);
void zend_register_standard_ini_entries(TSRMLS_D);

#ifdef ZTS
void zend_post_startup(TSRMLS_D);
#endif

void zend_set_utility_values(zend_utility_values *utility_values);

BEGIN_EXTERN_C()
ZEND_API void _zend_bailout(char *filename, uint lineno);
END_EXTERN_C()

#define zend_bailout()		_zend_bailout(__FILE__, __LINE__)

#define zend_try												\
	{															\
		jmp_buf *__orig_bailout = EG(bailout);					\
		jmp_buf __bailout;										\
																\
		EG(bailout) = &__bailout;								\
		if (setjmp(__bailout)==0) {
#define zend_catch												\
		} else {												\
			EG(bailout) = __orig_bailout;
#define zend_end_try()											\
		}														\
		EG(bailout) = __orig_bailout;							\
	}
#define zend_first_try		EG(bailout)=NULL; zend_try

BEGIN_EXTERN_C()
ZEND_API char *get_zend_version(void);
ZEND_API void zend_make_printable_zval(zval *expr, zval *expr_copy, int *use_copy);
ZEND_API int zend_print_zval(zval *expr, int indent);
ZEND_API int zend_print_zval_ex(zend_write_func_t write_func, zval *expr, int indent);
ZEND_API void zend_print_zval_r(zval *expr, int indent TSRMLS_DC);
ZEND_API void zend_print_flat_zval_r(zval *expr TSRMLS_DC);
ZEND_API void zend_print_zval_r_ex(zend_write_func_t write_func, zval *expr, int indent TSRMLS_DC);
ZEND_API void zend_output_debug_string(zend_bool trigger_break, char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
END_EXTERN_C()

void zend_activate(TSRMLS_D);
void zend_deactivate(TSRMLS_D);
void zend_call_destructors(TSRMLS_D);
void zend_activate_modules(TSRMLS_D);
void zend_deactivate_modules(TSRMLS_D);
void zend_post_deactivate_modules(TSRMLS_D);

#if ZEND_DEBUG
#define Z_DBG(expr)		(expr)
#else
#define	Z_DBG(expr)
#endif

BEGIN_EXTERN_C()
ZEND_API void free_estring(char **str_p);
END_EXTERN_C()

/* FIXME: Check if we can save if (ptr) too */

#define STR_FREE(ptr) if (ptr) { efree(ptr); }
#define STR_FREE_REL(ptr) if (ptr) { efree_rel(ptr); }

#define STR_EMPTY_ALLOC() estrndup("", sizeof("")-1)

#define STR_REALLOC(ptr, size) \
			ptr = (char *) erealloc(ptr, size);

/* output support */
#define ZEND_WRITE(str, str_len)		zend_write((str), (str_len))
#define ZEND_WRITE_EX(str, str_len)		write_func((str), (str_len))
#define ZEND_PUTS(str)					zend_write((str), strlen((str)))
#define ZEND_PUTS_EX(str)				write_func((str), strlen((str)))
#define ZEND_PUTC(c)					zend_write(&(c), 1), (c)


BEGIN_EXTERN_C()
extern ZEND_API int (*zend_printf)(const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 1, 2);
extern ZEND_API zend_write_func_t zend_write;
extern ZEND_API FILE *(*zend_fopen)(const char *filename, char **opened_path);
extern ZEND_API void (*zend_block_interruptions)(void);
extern ZEND_API void (*zend_unblock_interruptions)(void);
extern ZEND_API void (*zend_ticks_function)(int ticks);
extern ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 4, 0);
extern void (*zend_on_timeout)(int seconds TSRMLS_DC);
extern ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC);
extern int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
extern ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC);


ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);

void zenderror(char *error);

/* The following #define is used for code duality in PHP for Engine 1 & 2 */
#define ZEND_STANDARD_CLASS_DEF_PTR zend_standard_class_def
extern ZEND_API zend_class_entry *zend_standard_class_def;
extern ZEND_API zend_utility_values zend_uv;
extern ZEND_API zval zval_used_for_init;

END_EXTERN_C()

#define ZEND_UV(name) (zend_uv.name)


#define HANDLE_BLOCK_INTERRUPTIONS()		if (zend_block_interruptions) { zend_block_interruptions(); }
#define HANDLE_UNBLOCK_INTERRUPTIONS()		if (zend_unblock_interruptions) { zend_unblock_interruptions(); }

BEGIN_EXTERN_C()
ZEND_API void zend_message_dispatcher(long message, void *data);

ZEND_API int zend_get_configuration_directive(char *name, uint name_length, zval *contents);
END_EXTERN_C()


/* Messages for applications of Zend */
#define ZMSG_FAILED_INCLUDE_FOPEN		1L
#define ZMSG_FAILED_REQUIRE_FOPEN		2L
#define ZMSG_FAILED_HIGHLIGHT_FOPEN		3L
#define ZMSG_MEMORY_LEAK_DETECTED		4L
#define ZMSG_MEMORY_LEAK_REPEATED		5L
#define ZMSG_LOG_SCRIPT_NAME			6L
#define ZMSG_MEMORY_LEAKS_GRAND_TOTAL	7L


#define ZVAL_ADDREF(pz)		(++(pz)->refcount)
#define ZVAL_DELREF(pz)		(--(pz)->refcount)
#define ZVAL_REFCOUNT(pz)	((pz)->refcount)

#define INIT_PZVAL(z)		\
	(z)->refcount = 1;		\
	(z)->is_ref = 0;

#ifndef INIT_PZVAL_COPY
#define INIT_PZVAL_COPY(z,v) \
	(z)->value = (v)->value; \
	(z)->type = (v)->type; \
	(z)->refcount = 1; \
	(z)->is_ref = 0;
#endif

#ifndef MAKE_COPY_ZVAL
#define MAKE_COPY_ZVAL(ppzv, pzv) \
	INIT_PZVAL_COPY(pzv, *(ppzv));\
	zval_copy_ctor((pzv));
#endif

#define INIT_ZVAL(z) z = zval_used_for_init;

#define ALLOC_INIT_ZVAL(zp)						\
	ALLOC_ZVAL(zp);		\
	INIT_ZVAL(*zp);

#define MAKE_STD_ZVAL(zv)				 \
	ALLOC_ZVAL(zv); \
	INIT_PZVAL(zv);

#define PZVAL_IS_REF(z)		((z)->is_ref)

#define SEPARATE_ZVAL(ppzv)									\
	{														\
		zval *orig_ptr = *(ppzv);							\
															\
		if (orig_ptr->refcount>1) {							\
			orig_ptr->refcount--;							\
			ALLOC_ZVAL(*(ppzv));							\
			**(ppzv) = *orig_ptr;							\
			zval_copy_ctor(*(ppzv));						\
			(*(ppzv))->refcount=1;							\
			(*(ppzv))->is_ref = 0;							\
		}													\
	}

#define SEPARATE_ZVAL_IF_NOT_REF(ppzv)		\
	if (!PZVAL_IS_REF(*ppzv)) {				\
		SEPARATE_ZVAL(ppzv);				\
	}

#define SEPARATE_ZVAL_TO_MAKE_IS_REF(ppzv)	\
	if (!PZVAL_IS_REF(*ppzv)) {				\
		SEPARATE_ZVAL(ppzv);				\
		(*(ppzv))->is_ref = 1;				\
	}

#define COPY_PZVAL_TO_ZVAL(zv, pzv)			\
	(zv) = *(pzv);							\
	if ((pzv)->refcount>1) {				\
		zval_copy_ctor(&(zv));				\
		(pzv)->refcount--;					\
	} else {								\
		FREE_ZVAL(pzv);						\
	}										\
	INIT_PZVAL(&(zv));

#define REPLACE_ZVAL_VALUE(ppzv_dest, pzv_src, copy) {	\
	int is_ref, refcount;						\
												\
	SEPARATE_ZVAL_IF_NOT_REF(ppzv_dest);		\
	is_ref = (*ppzv_dest)->is_ref;				\
	refcount = (*ppzv_dest)->refcount;			\
	zval_dtor(*ppzv_dest);						\
	**ppzv_dest = *pzv_src;						\
	if (copy) {                                 \
		zval_copy_ctor(*ppzv_dest);				\
    }		                                    \
	(*ppzv_dest)->is_ref = is_ref;				\
	(*ppzv_dest)->refcount = refcount;			\
}

#define SEPARATE_ARG_IF_REF(varptr) \
	if (PZVAL_IS_REF(varptr)) { \
		zval *original_var = varptr; \
		ALLOC_ZVAL(varptr); \
		varptr->value = original_var->value; \
		varptr->type = original_var->type; \
		varptr->is_ref = 0; \
		varptr->refcount = 1; \
		zval_copy_ctor(varptr); \
	} else { \
		varptr->refcount++; \
	}

#define READY_TO_DESTROY(zv) \
	((zv)->refcount == 1 && \
	 (Z_TYPE_P(zv) != IS_OBJECT || \
	  zend_objects_store_get_refcount(zv TSRMLS_CC) == 1))


#define ZEND_MAX_RESERVED_RESOURCES	4

#include "zend_operators.h"
#include "zend_variables.h"

#endif /* ZEND_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_float.h000064400000036526151730541750010555 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2018 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Christian Seiler <chris_se@gmx.net>                         |
   +----------------------------------------------------------------------+
*/

/* $Id$ */

#ifndef ZEND_FLOAT_H
#define ZEND_FLOAT_H

BEGIN_EXTERN_C()

/*
  Define functions for FP initialization and de-initialization.
*/
extern ZEND_API void zend_init_fpu(void);
extern ZEND_API void zend_shutdown_fpu(void);
extern ZEND_API void zend_ensure_fpu_mode(void);

END_EXTERN_C()

/* Copy of the contents of xpfpa.h (which is under public domain)
   See http://wiki.php.net/rfc/rounding for details.

   Cross Platform Floating Point Arithmetics

   This header file defines several platform-dependent macros that ensure
   equal and deterministic floating point behaviour across several platforms,
   compilers and architectures.

   The current macros are currently only used on x86 and x86_64 architectures,
   on every other architecture, these macros expand to NOPs. This assumes that
   other architectures do not have an internal precision and the operhand types
   define the computational precision of floating point operations. This
   assumption may be false, in that case, the author is interested in further
   details on the other platform.

   For further details, please visit:
   http://www.christian-seiler.de/projekte/fpmath/

   Version: 20090317 */

/*
 Implementation notes:

 x86_64:
  - Since all x86_64 compilers use SSE by default, it is probably unnecessary
    to use these macros there. We define them anyway since we are too lazy
    to differentiate the architecture. Also, the compiler option -mfpmath=i387
    justifies this decision.

 General:
  - It would be nice if one could detect whether SSE if used for math via some
    funky compiler defines and if so, make the macros go to NOPs. Any ideas
    on how to do that?

 MS Visual C:
  - Since MSVC users tipically don't use autoconf or CMake, we will detect
    MSVC via compile time define. Floating point precision change isn't
    supported on 64 bit platforms, so it's NOP. See
    http://msdn.microsoft.com/en-us/library/c9676k6h(v=vs.110).aspx
*/

/* MSVC detection (MSVC people usually don't use autoconf) */
#if defined(_MSC_VER) && !defined(_WIN64)
#  define HAVE__CONTROLFP_S
#endif /* _MSC_VER */

#ifdef HAVE__CONTROLFP_S

/* float.h defines _controlfp_s */
# include <float.h>

# define XPFPA_HAVE_CW 1
# define XPFPA_CW_DATATYPE \
            unsigned int

# define XPFPA_STORE_CW(vptr) do { \
            _controlfp_s((unsigned int *)(vptr), 0, 0); \
        } while (0)

# define XPFPA_RESTORE_CW(vptr) do { \
            unsigned int _xpfpa_fpu_cw; \
            _controlfp_s(&_xpfpa_fpu_cw, *((unsigned int *)(vptr)), _MCW_PC); \
        } while (0)

# define XPFPA_DECLARE \
            unsigned int _xpfpa_fpu_oldcw, _xpfpa_fpu_cw;

# define XPFPA_SWITCH_DOUBLE() do { \
            _controlfp_s(&_xpfpa_fpu_cw, 0, 0); \
            _xpfpa_fpu_oldcw = _xpfpa_fpu_cw; \
            _controlfp_s(&_xpfpa_fpu_cw, _PC_53, _MCW_PC); \
        } while (0)
# define XPFPA_SWITCH_SINGLE() do { \
            _controlfp_s(&_xpfpa_fpu_cw, 0, 0); \
            _xpfpa_fpu_oldcw = _xpfpa_fpu_cw; \
            _controlfp_s(&_xpfpa_fpu_cw, _PC_24, _MCW_PC); \
        } while (0)
/* NOTE: This only sets internal precision. MSVC does NOT support double-
   extended precision! */
# define XPFPA_SWITCH_DOUBLE_EXTENDED() do { \
            _controlfp_s(&_xpfpa_fpu_cw, 0, 0); \
            _xpfpa_fpu_oldcw = _xpfpa_fpu_cw; \
            _controlfp_s(&_xpfpa_fpu_cw, _PC_64, _MCW_PC); \
        } while (0)
# define XPFPA_RESTORE() \
            _controlfp_s(&_xpfpa_fpu_cw, _xpfpa_fpu_oldcw, _MCW_PC)
/* We do NOT use the volatile return trick since _controlfp_s is a function
   call and thus FP registers are saved in memory anyway. However, we do use
   a variable to ensure that the expression passed into val will be evaluated
   *before* switching back contexts. */
# define XPFPA_RETURN_DOUBLE(val) \
            do { \
                double _xpfpa_result = (val); \
                XPFPA_RESTORE(); \
                return _xpfpa_result; \
            } while (0)
# define XPFPA_RETURN_SINGLE(val) \
            do { \
                float _xpfpa_result = (val); \
                XPFPA_RESTORE(); \
                return _xpfpa_result; \
            } while (0)
/* This won't work, but we add a macro for it anyway. */
# define XPFPA_RETURN_DOUBLE_EXTENDED(val) \
            do { \
                long double _xpfpa_result = (val); \
                XPFPA_RESTORE(); \
                return _xpfpa_result; \
            } while (0)

#elif defined(HAVE__CONTROLFP)

/* float.h defines _controlfp */
# include <float.h>

# define XPFPA_DECLARE \
            unsigned int _xpfpa_fpu_oldcw;

# define XPFPA_HAVE_CW 1
# define XPFPA_CW_DATATYPE \
            unsigned int

# define XPFPA_STORE_CW(vptr) do { \
            *((unsigned int *)(vptr)) = _controlfp(0, 0); \
        } while (0)

# define XPFPA_RESTORE_CW(vptr) do { \
            _controlfp(*((unsigned int *)(vptr)), _MCW_PC); \
        } while (0)

# define XPFPA_SWITCH_DOUBLE() do { \
            _xpfpa_fpu_oldcw = _controlfp(0, 0); \
            _controlfp(_PC_53, _MCW_PC); \
        } while (0)
# define XPFPA_SWITCH_SINGLE() do { \
            _xpfpa_fpu_oldcw = _controlfp(0, 0); \
            _controlfp(_PC_24, _MCW_PC); \
        } while (0)
/* NOTE: This will only work as expected on MinGW. */
# define XPFPA_SWITCH_DOUBLE_EXTENDED() do { \
            _xpfpa_fpu_oldcw = _controlfp(0, 0); \
            _controlfp(_PC_64, _MCW_PC); \
        } while (0)
# define XPFPA_RESTORE() \
            _controlfp(_xpfpa_fpu_oldcw, _MCW_PC)
/* We do NOT use the volatile return trick since _controlfp is a function
   call and thus FP registers are saved in memory anyway. However, we do use
   a variable to ensure that the expression passed into val will be evaluated
   *before* switching back contexts. */
# define XPFPA_RETURN_DOUBLE(val) \
            do { \
                double _xpfpa_result = (val); \
                XPFPA_RESTORE(); \
                return _xpfpa_result; \
            } while (0)
# define XPFPA_RETURN_SINGLE(val) \
            do { \
                float _xpfpa_result = (val); \
                XPFPA_RESTORE(); \
                return _xpfpa_result; \
            } while (0)
/* This will only work on MinGW */
# define XPFPA_RETURN_DOUBLE_EXTENDED(val) \
            do { \
                long double _xpfpa_result = (val); \
                XPFPA_RESTORE(); \
                return _xpfpa_result; \
            } while (0)

#elif defined(HAVE__FPU_SETCW) /* glibc systems */

/* fpu_control.h defines _FPU_[GS]ETCW */
# include <fpu_control.h>

# define XPFPA_DECLARE \
            fpu_control_t _xpfpa_fpu_oldcw, _xpfpa_fpu_cw;

# define XPFPA_HAVE_CW 1
# define XPFPA_CW_DATATYPE \
            fpu_control_t

# define XPFPA_STORE_CW(vptr) do { \
            _FPU_GETCW((*((fpu_control_t *)(vptr)))); \
        } while (0)

# define XPFPA_RESTORE_CW(vptr) do { \
            _FPU_SETCW((*((fpu_control_t *)(vptr)))); \
        } while (0)

# define XPFPA_SWITCH_DOUBLE() do { \
            _FPU_GETCW(_xpfpa_fpu_oldcw); \
            _xpfpa_fpu_cw = (_xpfpa_fpu_oldcw & ~_FPU_EXTENDED & ~_FPU_SINGLE) | _FPU_DOUBLE; \
            _FPU_SETCW(_xpfpa_fpu_cw); \
        } while (0)
# define XPFPA_SWITCH_SINGLE() do { \
            _FPU_GETCW(_xpfpa_fpu_oldcw); \
            _xpfpa_fpu_cw = (_xpfpa_fpu_oldcw & ~_FPU_EXTENDED & ~_FPU_DOUBLE) | _FPU_SINGLE; \
            _FPU_SETCW(_xpfpa_fpu_cw); \
        } while (0)
# define XPFPA_SWITCH_DOUBLE_EXTENDED()  do { \
            _FPU_GETCW(_xpfpa_fpu_oldcw); \
            _xpfpa_fpu_cw = (_xpfpa_fpu_oldcw & ~_FPU_SINGLE & ~_FPU_DOUBLE) | _FPU_EXTENDED; \
            _FPU_SETCW(_xpfpa_fpu_cw); \
        } while (0)
# define XPFPA_RESTORE() \
            _FPU_SETCW(_xpfpa_fpu_oldcw)
/* We use a temporary volatile variable (in a new block) in order to ensure
   that the optimizer does not mis-optimize the instructions. Also, a volatile
   variable ensures truncation to correct precision. */
# define XPFPA_RETURN_DOUBLE(val) \
            do { \
                volatile double _xpfpa_result = (val); \
                XPFPA_RESTORE(); \
                return _xpfpa_result; \
            } while (0)
# define XPFPA_RETURN_SINGLE(val) \
            do { \
                volatile float _xpfpa_result = (val); \
                XPFPA_RESTORE(); \
                return _xpfpa_result; \
            } while (0)
# define XPFPA_RETURN_DOUBLE_EXTENDED(val) \
            do { \
                volatile long double _xpfpa_result = (val); \
                XPFPA_RESTORE(); \
                return _xpfpa_result; \
            } while (0)

#elif defined(HAVE_FPSETPREC) /* FreeBSD */

/* fpu_control.h defines _FPU_[GS]ETCW */
# include <machine/ieeefp.h>

# define XPFPA_DECLARE \
            fp_prec_t _xpfpa_fpu_oldprec;

# define XPFPA_HAVE_CW 1
# define XPFPA_CW_DATATYPE \
            fp_prec_t

# define XPFPA_STORE_CW(vptr) do { \
            *((fp_prec_t *)(vptr)) = fpgetprec(); \
        } while (0)

# define XPFPA_RESTORE_CW(vptr) do { \
            fpsetprec(*((fp_prec_t *)(vptr))); \
        } while (0)

# define XPFPA_SWITCH_DOUBLE() do { \
            _xpfpa_fpu_oldprec = fpgetprec(); \
            fpsetprec(FP_PD); \
        } while (0)
# define XPFPA_SWITCH_SINGLE() do { \
            _xpfpa_fpu_oldprec = fpgetprec(); \
            fpsetprec(FP_PS); \
        } while (0)
# define XPFPA_SWITCH_DOUBLE_EXTENDED() do { \
            _xpfpa_fpu_oldprec = fpgetprec(); \
            fpsetprec(FP_PE); \
        } while (0)
# define XPFPA_RESTORE() \
            fpsetprec(_xpfpa_fpu_oldprec)
/* We use a temporary volatile variable (in a new block) in order to ensure
   that the optimizer does not mis-optimize the instructions. Also, a volatile
   variable ensures truncation to correct precision. */
# define XPFPA_RETURN_DOUBLE(val) \
            do { \
                volatile double _xpfpa_result = (val); \
                XPFPA_RESTORE(); \
                return _xpfpa_result; \
            } while (0)
# define XPFPA_RETURN_SINGLE(val) \
            do { \
                volatile float _xpfpa_result = (val); \
                XPFPA_RESTORE(); \
                return _xpfpa_result; \
            } while (0)
# define XPFPA_RETURN_DOUBLE_EXTENDED(val) \
            do { \
                volatile long double _xpfpa_result = (val); \
                XPFPA_RESTORE(); \
                return _xpfpa_result; \
            } while (0)

#elif defined(HAVE_FPU_INLINE_ASM_X86)

/*
  Custom x86 inline assembler implementation.

  This implementation does not use predefined wrappers of the OS / compiler
  but rather uses x86/x87 inline assembler directly. Basic instructions:

  fnstcw - Store the FPU control word in a variable
  fldcw  - Load the FPU control word from a variable

  Bits (only bits 8 and 9 are relevant, bits 0 to 7 are for other things):
     0x0yy: Single precision
     0x1yy: Reserved
     0x2yy: Double precision
     0x3yy: Double-extended precision

  We use an unsigned int for the datatype. glibc sources add __mode__ (__HI__)
  attribute to it (HI stands for half-integer according to docs). It is unclear
  what the does exactly and how portable it is.

  The assembly syntax works with GNU CC, Intel CC and Sun CC.
*/

# define XPFPA_DECLARE \
            unsigned int _xpfpa_fpu_oldcw, _xpfpa_fpu_cw;

# define XPFPA_HAVE_CW 1
# define XPFPA_CW_DATATYPE \
            unsigned int

# define XPFPA_STORE_CW(vptr) do { \
            __asm__ __volatile__ ("fnstcw %0" : "=m" (*((unsigned int *)(vptr)))); \
        } while (0)

# define XPFPA_RESTORE_CW(vptr) do { \
            __asm__ __volatile__ ("fldcw %0" : : "m" (*((unsigned int *)(vptr)))); \
        } while (0)

# define XPFPA_SWITCH_DOUBLE() do { \
            __asm__ __volatile__ ("fnstcw %0" : "=m" (*&_xpfpa_fpu_oldcw)); \
            _xpfpa_fpu_cw = (_xpfpa_fpu_oldcw & ~0x100) | 0x200; \
            __asm__ __volatile__ ("fldcw %0" : : "m" (*&_xpfpa_fpu_cw)); \
        } while (0)
# define XPFPA_SWITCH_SINGLE() do { \
            __asm__ __volatile__ ("fnstcw %0" : "=m" (*&_xpfpa_fpu_oldcw)); \
            _xpfpa_fpu_cw = (_xpfpa_fpu_oldcw & ~0x300); \
            __asm__ __volatile__ ("fldcw %0" : : "m" (*&_xpfpa_fpu_cw)); \
        } while (0)
# define XPFPA_SWITCH_DOUBLE_EXTENDED() do { \
            __asm__ __volatile__ ("fnstcw %0" : "=m" (*&_xpfpa_fpu_oldcw)); \
            _xpfpa_fpu_cw = _xpfpa_fpu_oldcw | 0x300; \
            __asm__ __volatile__ ("fldcw %0" : : "m" (*&_xpfpa_fpu_cw)); \
        } while (0)
# define XPFPA_RESTORE() \
            __asm__ __volatile__ ("fldcw %0" : : "m" (*&_xpfpa_fpu_oldcw))
/* We use a temporary volatile variable (in a new block) in order to ensure
   that the optimizer does not mis-optimize the instructions. Also, a volatile
   variable ensures truncation to correct precision. */
# define XPFPA_RETURN_DOUBLE(val) \
            do { \
                volatile double _xpfpa_result = (val); \
                XPFPA_RESTORE(); \
                return _xpfpa_result; \
            } while (0)
# define XPFPA_RETURN_SINGLE(val) \
            do { \
                volatile float _xpfpa_result = (val); \
                XPFPA_RESTORE(); \
                return _xpfpa_result; \
            } while (0)
# define XPFPA_RETURN_DOUBLE_EXTENDED(val) \
            do { \
                volatile long double _xpfpa_result = (val); \
                XPFPA_RESTORE(); \
                return _xpfpa_result; \
            } while (0)

#else /* FPU CONTROL */

/*
  This is either not an x87 FPU or the inline assembly syntax was not
  recognized. In any case, default to NOPs for the macros and hope the
  generated code will behave as planned.
*/
# define XPFPA_DECLARE                      /* NOP */
# define XPFPA_HAVE_CW                      0
# define XPFPA_CW_DATATYPE                  unsigned int
# define XPFPA_STORE_CW(variable)           /* NOP */
# define XPFPA_RESTORE_CW(variable)         /* NOP */
# define XPFPA_SWITCH_DOUBLE()              /* NOP */
# define XPFPA_SWITCH_SINGLE()              /* NOP */
# define XPFPA_SWITCH_DOUBLE_EXTENDED()     /* NOP */
# define XPFPA_RESTORE()                    /* NOP */
# define XPFPA_RETURN_DOUBLE(val)           return (val)
# define XPFPA_RETURN_SINGLE(val)           return (val)
# define XPFPA_RETURN_DOUBLE_EXTENDED(val)  return (val)

#endif /* FPU CONTROL */

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/Zend/zend_closures.h000064400000004130151730541760011272 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2018 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Christian Seiler <chris_se@gmx.net>                         |
   |          Dmitry Stogov <dmitry@zend.com>                             |
   +----------------------------------------------------------------------+
*/

/* $Id$ */

#ifndef ZEND_CLOSURES_H
#define ZEND_CLOSURES_H

BEGIN_EXTERN_C()

void zend_register_closure_ce(void);
void zend_closure_bind_var(zval *closure_zv, zend_string *var_name, zval *var);

extern ZEND_API zend_class_entry *zend_ce_closure;

ZEND_API void zend_create_closure(zval *res, zend_function *op_array, zend_class_entry *scope, zend_class_entry *called_scope, zval *this_ptr);
ZEND_API void zend_create_fake_closure(zval *res, zend_function *op_array, zend_class_entry *scope, zend_class_entry *called_scope, zval *this_ptr);
ZEND_API zend_function *zend_get_closure_invoke_method(zend_object *obj);
ZEND_API const zend_function *zend_get_closure_method_def(zval *obj);
ZEND_API zval* zend_get_closure_this_ptr(zval *obj);

END_EXTERN_C()

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/Zend/zend_smart_string.h000064400000011621151730541760012152 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 7                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2018 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Sascha Schumann <sascha@schumann.cx>                         |
   |         Xinchen Hui <laruence@php.net>                               |
   +----------------------------------------------------------------------+
 */

/* $Id$ */

#ifndef PHP_SMART_STRING_H
#define PHP_SMART_STRING_H

#include "zend_smart_string_public.h"

#include <stdlib.h>
#ifndef SMART_STR_USE_REALLOC
#include <zend.h>
#endif

#ifndef SMART_STRING_PREALLOC
#define SMART_STRING_PREALLOC 128
#endif

#ifndef SMART_STRING_START_SIZE
#define SMART_STRING_START_SIZE 78
#endif

#ifdef SMART_STRING_USE_REALLOC
#define SMART_STRING_REALLOC(a,b,c) realloc((a),(b))
#else
#define SMART_STRING_REALLOC(a,b,c) perealloc((a),(b),(c))
#endif

#define SMART_STRING_DO_REALLOC(d, what) \
	(d)->c = (char *) SMART_STRING_REALLOC((d)->c, (d)->a + 1, (what))

/* wrapper */

#define smart_string_appends_ex(str, src, what) \
	smart_string_appendl_ex((str), (src), strlen(src), (what))
#define smart_string_appends(str, src) \
	smart_string_appendl((str), (src), strlen(src))
#define smart_string_append_ex(str, src, what) \
	smart_string_appendl_ex((str), ((smart_string *)(src))->c, \
		((smart_string *)(src))->len, (what));
#define smart_string_sets(str, src) \
	smart_string_setl((str), (src), strlen(src));

#define smart_string_appendc(str, c) \
	smart_string_appendc_ex((str), (c), 0)
#define smart_string_free(s) \
	smart_string_free_ex((s), 0)
#define smart_string_appendl(str, src, len) \
	smart_string_appendl_ex((str), (src), (len), 0)
#define smart_string_append(str, src) \
	smart_string_append_ex((str), (src), 0)
#define smart_string_append_long(str, val) \
	smart_string_append_long_ex((str), (val), 0)
#define smart_string_append_unsigned(str, val) \
	smart_string_append_unsigned_ex((str), (val), 0)

static zend_always_inline size_t smart_string_alloc(smart_string *str, size_t len, zend_bool persistent) {
	if (!str->c) {
		str->len = 0;
		str->a = len < SMART_STRING_START_SIZE
				? SMART_STRING_START_SIZE
				: len + SMART_STRING_PREALLOC;
		SMART_STRING_DO_REALLOC(str, persistent);
		return len;
	} else {
		if (UNEXPECTED((size_t) len > SIZE_MAX - str->len)) {
			zend_error(E_ERROR, "String size overflow");
		}
		len += str->len;
		if (UNEXPECTED(len >= str->a)) {
			str->a = len + SMART_STRING_PREALLOC;
			SMART_STRING_DO_REALLOC(str, persistent);
		}
	}
	return len;
}

static zend_always_inline void smart_string_free_ex(smart_string *str, zend_bool persistent) {
	if (str->c) {
		pefree(str->c, persistent);
		str->c = NULL;
	}
	str->a = str->len = 0;
}

static zend_always_inline void smart_string_0(smart_string *str) {
	if (str->c) {
		str->c[str->len] = '\0';
	}
}

static zend_always_inline void smart_string_appendc_ex(smart_string *dest, char ch, zend_bool persistent) {
	dest->len = smart_string_alloc(dest, 1, persistent);
	dest->c[dest->len - 1] = ch;
}

static zend_always_inline void smart_string_appendl_ex(smart_string *dest, const char *str, size_t len, zend_bool persistent) {
	size_t new_len = smart_string_alloc(dest, len, persistent);
	memcpy(dest->c + dest->len, str, len);
	dest->len = new_len;

}

static zend_always_inline void smart_string_append_long_ex(smart_string *dest, zend_long num, zend_bool persistent) {
	char buf[32];
	char *result = zend_print_long_to_buf(buf + sizeof(buf) - 1, num);
	smart_string_appendl_ex(dest, result, buf + sizeof(buf) - 1 - result, persistent);
}

static zend_always_inline void smart_string_append_unsigned_ex(smart_string *dest, zend_ulong num, zend_bool persistent) {
	char buf[32];
	char *result = zend_print_ulong_to_buf(buf + sizeof(buf) - 1, num);
	smart_string_appendl_ex(dest, result, buf + sizeof(buf) - 1 - result, persistent);
}

static zend_always_inline void smart_string_setl(smart_string *dest, char *src, size_t len) {
	dest->len = len;
	dest->a = len + 1;
	dest->c = src;
}

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/Zend/zend_builtin_functions.h000064400000003230151730541770013172 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_builtin_functions.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef ZEND_BUILTIN_FUNCTIONS_H
#define ZEND_BUILTIN_FUNCTIONS_H

int zend_startup_builtin_functions(TSRMLS_D);

BEGIN_EXTERN_C()
ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int provide_object TSRMLS_DC);
END_EXTERN_C()

#endif /* ZEND_BUILTIN_FUNCTIONS_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_ini_scanner.h000064400000003450151730542000011713 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_ini_scanner.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef _ZEND_INI_SCANNER_H
#define _ZEND_INI_SCANNER_H

BEGIN_EXTERN_C()
int zend_ini_scanner_get_lineno(TSRMLS_D);
char *zend_ini_scanner_get_filename(TSRMLS_D);
int zend_ini_open_file_for_scanning(zend_file_handle *fh TSRMLS_DC);
int zend_ini_prepare_string_for_scanning(char *str TSRMLS_DC);
void zend_ini_close_file(zend_file_handle *fh TSRMLS_DC);
int ini_lex(zval *ini_lval TSRMLS_DC);
END_EXTERN_C()

#endif /* _ZEND_INI_SCANNER_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_long.h000064400000010555151730542000010366 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2018 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Anatol Belski <ab@php.net>                                  |
   +----------------------------------------------------------------------+
*/

/* $Id$ */


#ifndef ZEND_LONG_H
#define ZEND_LONG_H

#include "main/php_stdint.h"

/* This is the heart of the whole int64 enablement in zval. */
#if defined(__x86_64__) || defined(__LP64__) || defined(_LP64) || defined(_WIN64)
# define ZEND_ENABLE_ZVAL_LONG64 1
#endif

/* Integer types. */
#ifdef ZEND_ENABLE_ZVAL_LONG64
typedef int64_t zend_long;
typedef uint64_t zend_ulong;
typedef int64_t zend_off_t;
# define ZEND_LONG_MAX INT64_MAX
# define ZEND_LONG_MIN INT64_MIN
# define ZEND_ULONG_MAX UINT64_MAX
# define Z_L(i) INT64_C(i)
# define Z_UL(i) UINT64_C(i)
# define SIZEOF_ZEND_LONG 8
#else
typedef int32_t zend_long;
typedef uint32_t zend_ulong;
typedef int32_t zend_off_t;
# define ZEND_LONG_MAX INT32_MAX
# define ZEND_LONG_MIN INT32_MIN
# define ZEND_ULONG_MAX UINT32_MAX
# define Z_L(i) INT32_C(i)
# define Z_UL(i) UINT32_C(i)
# define SIZEOF_ZEND_LONG 4
#endif


/* Conversion macros. */
#define ZEND_LTOA_BUF_LEN 65

#ifdef ZEND_ENABLE_ZVAL_LONG64
# define ZEND_LONG_FMT "%" PRId64
# define ZEND_ULONG_FMT "%" PRIu64
# define ZEND_XLONG_FMT "%" PRIx64
# define ZEND_LONG_FMT_SPEC PRId64
# define ZEND_ULONG_FMT_SPEC PRIu64
# ifdef ZEND_WIN32
#  define ZEND_LTOA(i, s, len) _i64toa_s((i), (s), (len), 10)
#  define ZEND_ATOL(i, s) i = _atoi64((s))
#  define ZEND_STRTOL(s0, s1, base) _strtoi64((s0), (s1), (base))
#  define ZEND_STRTOUL(s0, s1, base) _strtoui64((s0), (s1), (base))
#  define ZEND_STRTOL_PTR _strtoi64
#  define ZEND_STRTOUL_PTR _strtoui64
#  define ZEND_ABS _abs64
# else
#  define ZEND_LTOA(i, s, len) \
	do { \
		int st = snprintf((s), (len), ZEND_LONG_FMT, (i)); \
		(s)[st] = '\0'; \
 	} while (0)
#  define ZEND_ATOL(i, s) (i) = atoll((s))
#  define ZEND_STRTOL(s0, s1, base) strtoll((s0), (s1), (base))
#  define ZEND_STRTOUL(s0, s1, base) strtoull((s0), (s1), (base))
#  define ZEND_STRTOL_PTR strtoll
#  define ZEND_STRTOUL_PTR strtoull
#  define ZEND_ABS imaxabs
# endif
#else
# define ZEND_STRTOL(s0, s1, base) strtol((s0), (s1), (base))
# define ZEND_STRTOUL(s0, s1, base) strtoul((s0), (s1), (base))
# define ZEND_LONG_FMT "%" PRId32
# define ZEND_ULONG_FMT "%" PRIu32
# define ZEND_XLONG_FMT "%" PRIx32
# define ZEND_LONG_FMT_SPEC PRId32
# define ZEND_ULONG_FMT_SPEC PRIu32
# ifdef ZEND_WIN32
#  define ZEND_LTOA(i, s, len) _ltoa_s((i), (s), (len), 10)
#  define ZEND_ATOL(i, s) i = atol((s))
# else
#  define ZEND_LTOA(i, s, len) \
	do { \
		int st = snprintf((s), (len), ZEND_LONG_FMT, (i)); \
		(s)[st] = '\0'; \
 	} while (0)
#  define ZEND_ATOL(i, s) (i) = atol((s))
# endif
# define ZEND_STRTOL_PTR strtol
# define ZEND_STRTOUL_PTR strtoul
# define ZEND_ABS abs
#endif

#if SIZEOF_ZEND_LONG == 4
# define MAX_LENGTH_OF_LONG 11
# define LONG_MIN_DIGITS "2147483648"
#elif SIZEOF_ZEND_LONG == 8
# define MAX_LENGTH_OF_LONG 20
# define LONG_MIN_DIGITS "9223372036854775808"
#else
# error "Unknown SIZEOF_ZEND_LONG"
#endif

static const char long_min_digits[] = LONG_MIN_DIGITS;

#ifdef _WIN64
# define ZEND_ADDR_FMT "0x%016I64x"
#elif SIZEOF_SIZE_T == 4
# define ZEND_ADDR_FMT "0x%08zx"
#elif SIZEOF_SIZE_T == 8
# define ZEND_ADDR_FMT "0x%016zx"
#else
# error "Unknown SIZEOF_SIZE_T"
#endif

#endif /* ZEND_LONG_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/Zend/zend_vm_opcodes.h000064400000014674151730542010011574 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   |          Dmitry Stogov <dmitry@zend.com>                             |
   +----------------------------------------------------------------------+
*/

#define ZEND_NOP                       0
#define ZEND_ADD                       1
#define ZEND_SUB                       2
#define ZEND_MUL                       3
#define ZEND_DIV                       4
#define ZEND_MOD                       5
#define ZEND_SL                        6
#define ZEND_SR                        7
#define ZEND_CONCAT                    8
#define ZEND_BW_OR                     9
#define ZEND_BW_AND                   10
#define ZEND_BW_XOR                   11
#define ZEND_BW_NOT                   12
#define ZEND_BOOL_NOT                 13
#define ZEND_BOOL_XOR                 14
#define ZEND_IS_IDENTICAL             15
#define ZEND_IS_NOT_IDENTICAL         16
#define ZEND_IS_EQUAL                 17
#define ZEND_IS_NOT_EQUAL             18
#define ZEND_IS_SMALLER               19
#define ZEND_IS_SMALLER_OR_EQUAL      20
#define ZEND_CAST                     21
#define ZEND_QM_ASSIGN                22
#define ZEND_ASSIGN_ADD               23
#define ZEND_ASSIGN_SUB               24
#define ZEND_ASSIGN_MUL               25
#define ZEND_ASSIGN_DIV               26
#define ZEND_ASSIGN_MOD               27
#define ZEND_ASSIGN_SL                28
#define ZEND_ASSIGN_SR                29
#define ZEND_ASSIGN_CONCAT            30
#define ZEND_ASSIGN_BW_OR             31
#define ZEND_ASSIGN_BW_AND            32
#define ZEND_ASSIGN_BW_XOR            33
#define ZEND_PRE_INC                  34
#define ZEND_PRE_DEC                  35
#define ZEND_POST_INC                 36
#define ZEND_POST_DEC                 37
#define ZEND_ASSIGN                   38
#define ZEND_ASSIGN_REF               39
#define ZEND_ECHO                     40
#define ZEND_PRINT                    41
#define ZEND_JMP                      42
#define ZEND_JMPZ                     43
#define ZEND_JMPNZ                    44
#define ZEND_JMPZNZ                   45
#define ZEND_JMPZ_EX                  46
#define ZEND_JMPNZ_EX                 47
#define ZEND_CASE                     48
#define ZEND_SWITCH_FREE              49
#define ZEND_BRK                      50
#define ZEND_CONT                     51
#define ZEND_BOOL                     52
#define ZEND_INIT_STRING              53
#define ZEND_ADD_CHAR                 54
#define ZEND_ADD_STRING               55
#define ZEND_ADD_VAR                  56
#define ZEND_BEGIN_SILENCE            57
#define ZEND_END_SILENCE              58
#define ZEND_INIT_FCALL_BY_NAME       59
#define ZEND_DO_FCALL                 60
#define ZEND_DO_FCALL_BY_NAME         61
#define ZEND_RETURN                   62
#define ZEND_RECV                     63
#define ZEND_RECV_INIT                64
#define ZEND_SEND_VAL                 65
#define ZEND_SEND_VAR                 66
#define ZEND_SEND_REF                 67
#define ZEND_NEW                      68
#define ZEND_FREE                     70
#define ZEND_INIT_ARRAY               71
#define ZEND_ADD_ARRAY_ELEMENT        72
#define ZEND_INCLUDE_OR_EVAL          73
#define ZEND_UNSET_VAR                74
#define ZEND_UNSET_DIM                75
#define ZEND_UNSET_OBJ                76
#define ZEND_FE_RESET                 77
#define ZEND_FE_FETCH                 78
#define ZEND_EXIT                     79
#define ZEND_FETCH_R                  80
#define ZEND_FETCH_DIM_R              81
#define ZEND_FETCH_OBJ_R              82
#define ZEND_FETCH_W                  83
#define ZEND_FETCH_DIM_W              84
#define ZEND_FETCH_OBJ_W              85
#define ZEND_FETCH_RW                 86
#define ZEND_FETCH_DIM_RW             87
#define ZEND_FETCH_OBJ_RW             88
#define ZEND_FETCH_IS                 89
#define ZEND_FETCH_DIM_IS             90
#define ZEND_FETCH_OBJ_IS             91
#define ZEND_FETCH_FUNC_ARG           92
#define ZEND_FETCH_DIM_FUNC_ARG       93
#define ZEND_FETCH_OBJ_FUNC_ARG       94
#define ZEND_FETCH_UNSET              95
#define ZEND_FETCH_DIM_UNSET          96
#define ZEND_FETCH_OBJ_UNSET          97
#define ZEND_FETCH_DIM_TMP_VAR        98
#define ZEND_FETCH_CONSTANT           99
#define ZEND_EXT_STMT                101
#define ZEND_EXT_FCALL_BEGIN         102
#define ZEND_EXT_FCALL_END           103
#define ZEND_EXT_NOP                 104
#define ZEND_TICKS                   105
#define ZEND_SEND_VAR_NO_REF         106
#define ZEND_CATCH                   107
#define ZEND_THROW                   108
#define ZEND_FETCH_CLASS             109
#define ZEND_CLONE                   110
#define ZEND_INIT_METHOD_CALL        112
#define ZEND_INIT_STATIC_METHOD_CALL 113
#define ZEND_ISSET_ISEMPTY_VAR       114
#define ZEND_ISSET_ISEMPTY_DIM_OBJ   115
#define ZEND_PRE_INC_OBJ             132
#define ZEND_PRE_DEC_OBJ             133
#define ZEND_POST_INC_OBJ            134
#define ZEND_POST_DEC_OBJ            135
#define ZEND_ASSIGN_OBJ              136
#define ZEND_INSTANCEOF              138
#define ZEND_DECLARE_CLASS           139
#define ZEND_DECLARE_INHERITED_CLASS 140
#define ZEND_DECLARE_FUNCTION        141
#define ZEND_RAISE_ABSTRACT_ERROR    142
#define ZEND_ADD_INTERFACE           144
#define ZEND_VERIFY_ABSTRACT_CLASS   146
#define ZEND_ASSIGN_DIM              147
#define ZEND_ISSET_ISEMPTY_PROP_OBJ  148
#define ZEND_HANDLE_EXCEPTION        149
#define ZEND_USER_OPCODE             150
php/Zend/zend_vm_execute.h000064400003461405151730542010011603 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   |          Dmitry Stogov <dmitry@zend.com>                             |
   +----------------------------------------------------------------------+
*/

static opcode_handler_t zend_user_opcode_handlers[256] = {(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL,(opcode_handler_t)NULL};

static zend_uchar zend_user_opcodes[256] = {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,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,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255};

static opcode_handler_t zend_vm_get_opcode_handler(zend_uchar opcode, zend_op* op);


#define ZEND_VM_CONTINUE()   return 0
#define ZEND_VM_RETURN()     return 1
#define ZEND_VM_DISPATCH(opcode, opline) return zend_vm_get_opcode_handler(opcode, opline)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);

#define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL execute_data TSRMLS_CC

ZEND_API void execute(zend_op_array *op_array TSRMLS_DC)
{
	zend_execute_data execute_data;


	if (EG(exception)) {
		return;
	}

	/* Initialize execute_data */
	EX(fbc) = NULL;
	EX(object) = NULL;
	EX(old_error_reporting) = NULL;
	if (op_array->T < TEMP_VAR_STACK_LIMIT) {
		EX(Ts) = (temp_variable *) do_alloca(sizeof(temp_variable) * op_array->T);
	} else {
		EX(Ts) = (temp_variable *) safe_emalloc(sizeof(temp_variable), op_array->T, 0);
	}
	EX(CVs) = (zval***)do_alloca(sizeof(zval**) * op_array->last_var);
	memset(EX(CVs), 0, sizeof(zval**) * op_array->last_var);
	EX(op_array) = op_array;
	EX(original_in_execution) = EG(in_execution);
	EX(symbol_table) = EG(active_symbol_table);
	EX(prev_execute_data) = EG(current_execute_data);
	EG(current_execute_data) = &execute_data;

	EG(in_execution) = 1;
	if (op_array->start_op) {
		ZEND_VM_SET_OPCODE(op_array->start_op);
	} else {
		ZEND_VM_SET_OPCODE(op_array->opcodes);
	}

	if (op_array->uses_this && EG(This)) {
		EG(This)->refcount++; /* For $this pointer */
		if (zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), NULL)==FAILURE) {
			EG(This)->refcount--;
		}
	}

	EG(opline_ptr) = &EX(opline);

	EX(function_state).function = (zend_function *) op_array;
	EG(function_state_ptr) = &EX(function_state);
#if ZEND_DEBUG
	/* function_state.function_symbol_table is saved as-is to a stack,
	 * which is an intentional UMR.  Shut it up if we're in DEBUG.
	 */
	EX(function_state).function_symbol_table = NULL;
#endif
	
	while (1) {
#ifdef ZEND_WIN32
		if (EG(timed_out)) {
			zend_timeout(0);
		}
#endif

		if (EX(opline)->handler(&execute_data TSRMLS_CC) > 0) {
      return;
		}

	}
	zend_error_noreturn(E_ERROR, "Arrived at end of main loop which shouldn't happen");
}

#undef EX
#define EX(element) execute_data->element

static int ZEND_JMP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
#if DEBUG_ZEND>=2
	printf("Jumping to %d\n", EX(opline)->op1.u.opline_num);
#endif
	ZEND_VM_SET_OPCODE(EX(opline)->op1.u.jmp_addr);
	ZEND_VM_CONTINUE(); /* CHECK_ME */
}

static int ZEND_INIT_STRING_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zval *tmp = &EX_T(EX(opline)->result.u.var).tmp_var;

	tmp->value.str.val = emalloc(1);
	tmp->value.str.val[0] = 0;
	tmp->value.str.len = 0;
	tmp->refcount = 1;
	tmp->type = IS_STRING;
	tmp->is_ref = 0;
	ZEND_VM_NEXT_OPCODE();
}

static int zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval **original_return_value;
	zend_class_entry *current_scope = NULL;
	zval *current_this = NULL;
	int return_value_used = RETURN_VALUE_USED(opline);
	zend_bool should_change_scope;
	zend_op *ctor_opline;

	if (EX(function_state).function->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) {
		if (EX(function_state).function->common.fn_flags & ZEND_ACC_ABSTRACT) {
			zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", EX(function_state).function->common.scope->name, EX(function_state).function->common.function_name);
			ZEND_VM_NEXT_OPCODE(); /* Never reached */
		}
		if (EX(function_state).function->common.fn_flags & ZEND_ACC_DEPRECATED) {
			zend_error(E_STRICT, "Function %s%s%s() is deprecated",
				EX(function_state).function->common.scope ? EX(function_state).function->common.scope->name : "",
				EX(function_state).function->common.scope ? "::" : "",
				EX(function_state).function->common.function_name);
		}
	}

	zend_ptr_stack_2_push(&EG(argument_stack), (void *)(zend_uintptr_t)opline->extended_value, NULL);

	EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;

	if (EX(function_state).function->type == ZEND_USER_FUNCTION
		|| EX(function_state).function->common.scope) {
		should_change_scope = 1;
		current_this = EG(This);
		EG(This) = EX(object);
		current_scope = EG(scope);
		EG(scope) = (EX(function_state).function->type == ZEND_USER_FUNCTION || !EX(object)) ? EX(function_state).function->common.scope : NULL;
	} else {
		should_change_scope = 0;
	}

	EX_T(opline->result.u.var).var.fcall_returned_reference = 0;

	if (EX(function_state).function->common.scope) {
		if (!EG(This) && !(EX(function_state).function->common.fn_flags & ZEND_ACC_STATIC)) {
			int severity;
			char *severity_word;
			if (EX(function_state).function->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
				severity = E_STRICT;
				severity_word = "should not";
			} else {
				severity = E_ERROR;
				severity_word = "cannot";
			}
			zend_error(severity, "Non-static method %s::%s() %s be called statically", EX(function_state).function->common.scope->name, EX(function_state).function->common.function_name, severity_word);
		}
	}
	if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) {
		unsigned char return_reference = EX(function_state).function->common.return_reference;

		ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
		INIT_ZVAL(*(EX_T(opline->result.u.var).var.ptr));

		if (EX(function_state).function->common.arg_info) {
			zend_uint i=0;
			zval **p;
			ulong arg_count;

			p = (zval **) EG(argument_stack).top_element-2;
			arg_count = (ulong)(zend_uintptr_t) *p;

			while (arg_count>0) {
				zend_verify_arg_type(EX(function_state).function, ++i, *(p-arg_count) TSRMLS_CC);
				arg_count--;
			}
		}
		if (!zend_execute_internal) {
			/* saves one function call if zend_execute_internal is not used */
			((zend_internal_function *) EX(function_state).function)->handler(opline->extended_value, EX_T(opline->result.u.var).var.ptr, EX(function_state).function->common.return_reference?&EX_T(opline->result.u.var).var.ptr:NULL, EX(object), return_value_used TSRMLS_CC);
		} else {
			zend_execute_internal(execute_data, return_value_used TSRMLS_CC);
		}

		EG(current_execute_data) = execute_data;

/*	We shouldn't fix bad extensions here,
    because it can break proper ones (Bug #34045)
		if (!EX(function_state).function->common.return_reference) {
			EX_T(opline->result.u.var).var.ptr->is_ref = 0;
			EX_T(opline->result.u.var).var.ptr->refcount = 1;
		}
*/
		if (!return_value_used) {
			zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
		} else {
			EX_T(opline->result.u.var).var.fcall_returned_reference = return_reference;
		}
	} else if (EX(function_state).function->type == ZEND_USER_FUNCTION) {
		EX_T(opline->result.u.var).var.ptr = NULL;
		if (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
			/*printf("Cache hit!  Reusing %x\n", symtable_cache[symtable_cache_ptr]);*/
			EX(function_state).function_symbol_table = *(EG(symtable_cache_ptr)--);
		} else {
			ALLOC_HASHTABLE(EX(function_state).function_symbol_table);
			zend_hash_init(EX(function_state).function_symbol_table, 0, NULL, ZVAL_PTR_DTOR, 0);
			/*printf("Cache miss!  Initialized %x\n", function_state.function_symbol_table);*/
		}
		EG(active_symbol_table) = EX(function_state).function_symbol_table;
		original_return_value = EG(return_value_ptr_ptr);
		EG(return_value_ptr_ptr) = EX_T(opline->result.u.var).var.ptr_ptr;
		EG(active_op_array) = (zend_op_array *) EX(function_state).function;

		zend_execute(EG(active_op_array) TSRMLS_CC);
		EX_T(opline->result.u.var).var.fcall_returned_reference = EG(active_op_array)->return_reference;

		if (return_value_used && !EX_T(opline->result.u.var).var.ptr) {
			if (!EG(exception)) {
				ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
				INIT_ZVAL(*EX_T(opline->result.u.var).var.ptr);
			}
		} else if (!return_value_used && EX_T(opline->result.u.var).var.ptr) {
			zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
		}

		EG(opline_ptr) = &EX(opline);
		EG(active_op_array) = EX(op_array);
		EG(return_value_ptr_ptr)=original_return_value;
		if (EG(symtable_cache_ptr)>=EG(symtable_cache_limit)) {
			zend_hash_destroy(EX(function_state).function_symbol_table);
			FREE_HASHTABLE(EX(function_state).function_symbol_table);
		} else {
			/* clean before putting into the cache, since clean
			   could call dtors, which could use cached hash */
			zend_hash_clean(EX(function_state).function_symbol_table);
			*(++EG(symtable_cache_ptr)) = EX(function_state).function_symbol_table;
		}
		EG(active_symbol_table) = EX(symbol_table);
	} else { /* ZEND_OVERLOADED_FUNCTION */
		ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
		INIT_ZVAL(*(EX_T(opline->result.u.var).var.ptr));

			/* Not sure what should be done here if it's a static method */
		if (EX(object)) {
			Z_OBJ_HT_P(EX(object))->call_method(EX(fbc)->common.function_name, opline->extended_value, EX_T(opline->result.u.var).var.ptr, &EX_T(opline->result.u.var).var.ptr, EX(object), return_value_used TSRMLS_CC);
		} else {
			zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
		}

		if (EX(function_state).function->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
			efree(EX(function_state).function->common.function_name);
		}
		efree(EX(fbc));

		if (!return_value_used) {
			zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
		} else {
			EX_T(opline->result.u.var).var.ptr->is_ref = 0;
			EX_T(opline->result.u.var).var.ptr->refcount = 1;
		}
	}

	EX(function_state).function = (zend_function *) EX(op_array);
	EG(function_state_ptr) = &EX(function_state);
	ctor_opline = (zend_op*)zend_ptr_stack_pop(&EG(arg_types_stack));

	if (EG(This)) {
		if (EG(exception) && ctor_opline) {
			if (RETURN_VALUE_USED(ctor_opline)) {
				EG(This)->refcount--;
			}
			if (EG(This)->refcount == 1) {
				zend_object_store_ctor_failed(EG(This) TSRMLS_CC);
			}
		}
		if (should_change_scope) {
			zval_ptr_dtor(&EG(This));
		}
	}

	if (should_change_scope) {
		EG(This) = current_this;
		EG(scope) = current_scope;
	}
	zend_arg_types_stack_2_pop(&EG(arg_types_stack), &EX(object), &EX(fbc));

	zend_ptr_stack_clear_multiple(TSRMLS_C);

	if (EG(exception)) {
		zend_throw_exception_internal(NULL TSRMLS_CC);
		if (return_value_used && EX_T(opline->result.u.var).var.ptr) {
			zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	EX(function_state).function = EX(fbc);
	return zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_CATCH_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_class_entry *ce;

	/* Check whether an exception has been thrown, if not, jump over code */
	if (EG(exception) == NULL) {
		ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->extended_value]);
		ZEND_VM_CONTINUE(); /* CHECK_ME */
	}
	ce = Z_OBJCE_P(EG(exception));
	if (ce != EX_T(opline->op1.u.var).class_entry) {
		if (!instanceof_function(ce, EX_T(opline->op1.u.var).class_entry TSRMLS_CC)) {
			if (opline->op1.u.EA.type) {
				zend_throw_exception_internal(NULL TSRMLS_CC);
				ZEND_VM_NEXT_OPCODE();
			}
			ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->extended_value]);
			ZEND_VM_CONTINUE(); /* CHECK_ME */
		}
	}

	zend_hash_update(EG(active_symbol_table), opline->op2.u.constant.value.str.val,
		opline->op2.u.constant.value.str.len+1, &EG(exception), sizeof(zval *), (void **) NULL);
	EG(exception) = NULL;
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_RECV_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval **param;
	zend_uint arg_num = Z_LVAL(opline->op1.u.constant);

	if (zend_ptr_stack_get_arg(arg_num, (void **) &param TSRMLS_CC)==FAILURE) {
		char *space;
		char *class_name = get_active_class_name(&space TSRMLS_CC);
		zend_execute_data *ptr = EX(prev_execute_data);

		zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, NULL TSRMLS_CC);
		if(ptr && ptr->op_array) {
			zend_error(E_WARNING, "Missing argument %ld for %s%s%s(), called in %s on line %d and defined", opline->op1.u.constant.value.lval, class_name, space, get_active_function_name(TSRMLS_C), ptr->op_array->filename, ptr->opline->lineno);
		} else {
			zend_error(E_WARNING, "Missing argument %ld for %s%s%s()", opline->op1.u.constant.value.lval, class_name, space, get_active_function_name(TSRMLS_C));
		}
		if (opline->result.op_type == IS_VAR) {
			PZVAL_UNLOCK_FREE(*EX_T(opline->result.u.var).var.ptr_ptr);
		}
	} else {
		zend_free_op free_res;
		zval **var_ptr;

		zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param TSRMLS_CC);
		var_ptr = get_zval_ptr_ptr(&opline->result, EX(Ts), &free_res, BP_VAR_W);
		if (PZVAL_IS_REF(*param)) {
			zend_assign_to_variable_reference(var_ptr, param TSRMLS_CC);
		} else {
			zend_receive(var_ptr, *param TSRMLS_CC);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_NEW_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *object_zval;
	zend_function *constructor;

	if (EX_T(opline->op1.u.var).class_entry->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
		char *class_type;

		if (EX_T(opline->op1.u.var).class_entry->ce_flags & ZEND_ACC_INTERFACE) {
			class_type = "interface";
		} else {
			class_type = "abstract class";
		}
		zend_error_noreturn(E_ERROR, "Cannot instantiate %s %s", class_type,  EX_T(opline->op1.u.var).class_entry->name);
	}
	ALLOC_ZVAL(object_zval);
	object_init_ex(object_zval, EX_T(opline->op1.u.var).class_entry);
	INIT_PZVAL(object_zval);

	constructor = Z_OBJ_HT_P(object_zval)->get_constructor(object_zval TSRMLS_CC);

	if (constructor == NULL) {
		if (RETURN_VALUE_USED(opline)) {
			EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
			EX_T(opline->result.u.var).var.ptr = object_zval;
		} else {
			zval_ptr_dtor(&object_zval);
		}
		ZEND_VM_JMP(EX(op_array)->opcodes + opline->op2.u.opline_num);
	} else {
		SELECTIVE_PZVAL_LOCK(object_zval, &opline->result);
		EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
		EX_T(opline->result.u.var).var.ptr = object_zval;

		zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), opline);

		/* We are not handling overloaded classes right now */
		EX(object) = object_zval;
		EX(fbc) = constructor;

		ZEND_VM_NEXT_OPCODE();
	}
}

static int ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	Z_LVAL(EX_T(opline->result.u.var).tmp_var) = EG(error_reporting);
	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_LONG;  /* shouldn't be necessary */
	if (EX(old_error_reporting) == NULL) {
		EX(old_error_reporting) = &EX_T(opline->result.u.var).tmp_var;
	}

	if (EG(error_reporting)) {
		zend_alter_ini_entry_ex("error_reporting", sizeof("error_reporting"), "0", 1, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME, 1);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", EG(scope)->name, EX(op_array)->function_name);
	ZEND_VM_NEXT_OPCODE(); /* Never reached */
}

static int ZEND_EXT_STMT_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	if (!EG(no_extensions)) {
		zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_statement_handler, EX(op_array) TSRMLS_CC);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	if (!EG(no_extensions)) {
		zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_fcall_begin_handler, EX(op_array) TSRMLS_CC);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_EXT_FCALL_END_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	if (!EG(no_extensions)) {
		zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_fcall_end_handler, EX(op_array) TSRMLS_CC);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_DECLARE_CLASS_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	EX_T(opline->result.u.var).class_entry = do_bind_class(opline, EG(class_table), 0 TSRMLS_CC);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	EX_T(opline->result.u.var).class_entry = do_bind_inherited_class(opline, EG(class_table), EX_T(opline->extended_value).class_entry, 0 TSRMLS_CC);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_DECLARE_FUNCTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	do_bind_function(EX(opline), EG(function_table), 0);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_EXT_NOP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_NOP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ADD_INTERFACE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_class_entry *ce = EX_T(opline->op1.u.var).class_entry;
	zend_class_entry *iface = EX_T(opline->op2.u.var).class_entry;

	if (!(iface->ce_flags & ZEND_ACC_INTERFACE)) {
		zend_error_noreturn(E_ERROR, "%s cannot implement %s - it is not an interface", ce->name, iface->name);
	}

	zend_do_implement_interface(ce, iface TSRMLS_CC);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_uint op_num = EG(opline_before_exception)-EG(active_op_array)->opcodes;
	int i;
	zend_uint catch_op_num;
	int catched = 0;
	zval **stack_zval_pp;
	zval restored_error_reporting;

	stack_zval_pp = (zval **) EG(argument_stack).top_element - 1;
	while (*stack_zval_pp != NULL) {
		zval_ptr_dtor(stack_zval_pp);
		EG(argument_stack).top_element--;
		EG(argument_stack).top--;
		stack_zval_pp--;
	}

	for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
		if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
			/* further blocks will not be relevant... */
			break;
		}
		if (op_num >= EG(active_op_array)->try_catch_array[i].try_op
			&& op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
			catch_op_num = EX(op_array)->try_catch_array[i].catch_op;
			catched = 1;
		}
	}

	while (EX(fbc)) {
		zend_op *ctor_opline = (zend_op*)zend_ptr_stack_pop(&EG(arg_types_stack));

		if (EX(object)) {
			if (ctor_opline && RETURN_VALUE_USED(ctor_opline)) {
				EX(object)->refcount--;
			}
			zval_ptr_dtor(&EX(object));
		}
		zend_arg_types_stack_2_pop(&EG(arg_types_stack), &EX(object), &EX(fbc));
	}

	for (i=0; i<EX(op_array)->last_brk_cont; i++) {
		if (EX(op_array)->brk_cont_array[i].start < 0) {
			continue;
		} else if (EX(op_array)->brk_cont_array[i].start > op_num) {
			/* further blocks will not be relevant... */
			break;
		} else if (op_num < EX(op_array)->brk_cont_array[i].brk) {
			if (!catched ||
			    catch_op_num >= EX(op_array)->brk_cont_array[i].brk) {
				zend_op *brk_opline = &EX(op_array)->opcodes[EX(op_array)->brk_cont_array[i].brk];

				switch (brk_opline->opcode) {
					case ZEND_SWITCH_FREE:
						zend_switch_free(brk_opline, EX(Ts) TSRMLS_CC);
						break;
					case ZEND_FREE:
						zendi_zval_dtor(EX_T(brk_opline->op1.u.var).tmp_var);
						break;
				}
			}
		}
	}

	/* restore previous error_reporting value */
	if (!EG(error_reporting) && EX(old_error_reporting) != NULL && Z_LVAL_P(EX(old_error_reporting)) != 0) {
		Z_TYPE(restored_error_reporting) = IS_LONG;
		Z_LVAL(restored_error_reporting) = Z_LVAL_P(EX(old_error_reporting));
		convert_to_string(&restored_error_reporting);
		zend_alter_ini_entry_ex("error_reporting", sizeof("error_reporting"), Z_STRVAL(restored_error_reporting), Z_STRLEN(restored_error_reporting), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME, 1);
		zendi_zval_dtor(restored_error_reporting);
	}
	EX(old_error_reporting) = NULL;

	if (!catched) {
 		ZEND_VM_RETURN_FROM_EXECUTE_LOOP();
 	} else {
		ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
 		ZEND_VM_CONTINUE();
 	}
}

static int ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_verify_abstract_class(EX_T(EX(opline)->op1.u.var).class_entry TSRMLS_CC);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_USER_OPCODE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	int ret = zend_user_opcode_handlers[EX(opline)->opcode](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL);

	switch (ret) {
		case ZEND_USER_OPCODE_CONTINUE:
			ZEND_VM_CONTINUE();
		case ZEND_USER_OPCODE_RETURN:
			ZEND_VM_RETURN();
		case ZEND_USER_OPCODE_DISPATCH:
			ZEND_VM_DISPATCH(EX(opline)->opcode, EX(opline));
		default:
			ZEND_VM_DISPATCH(ret & 0xff, EX(opline));
	}
}

static int ZEND_FETCH_CLASS_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *class_name;



	if (IS_CONST == IS_UNUSED) {
		EX_T(opline->result.u.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC);
		ZEND_VM_NEXT_OPCODE();
	}

	class_name = &opline->op2.u.constant;

	switch (Z_TYPE_P(class_name)) {
		case IS_OBJECT:
			EX_T(opline->result.u.var).class_entry = Z_OBJCE_P(class_name);
			break;
		case IS_STRING:
			EX_T(opline->result.u.var).class_entry = zend_fetch_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), opline->extended_value TSRMLS_CC);
			break;
		default:
			zend_error_noreturn(E_ERROR, "Class name must be a valid object or a string");
			break;
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *function_name;
	zend_class_entry *ce;

	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), NULL);

	ce = EX_T(opline->op1.u.var).class_entry;
	if(IS_CONST != IS_UNUSED) {
		char *function_name_strval = NULL;
		int function_name_strlen;
		zend_bool is_const = (IS_CONST == IS_CONST);


		if (is_const) {
			function_name_strval = Z_STRVAL(opline->op2.u.constant);
			function_name_strlen = Z_STRLEN(opline->op2.u.constant);
		} else {
			function_name = &opline->op2.u.constant;

			if (Z_TYPE_P(function_name) != IS_STRING) {
				zend_error_noreturn(E_ERROR, "Function name must be a string");
			} else {
				function_name_strval = Z_STRVAL_P(function_name);
				function_name_strlen = Z_STRLEN_P(function_name);
			}
		}

		if (function_name_strval) {
			EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
		}

		if (!is_const) {

		}
	} else {
		if(!ce->constructor) {
			zend_error_noreturn(E_ERROR, "Can not call constructor");
		}
		if (EG(This) && Z_OBJCE_P(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
			zend_error(E_COMPILE_ERROR, "Cannot call private %s::__construct()", ce->name);
		}
		EX(fbc) = ce->constructor;
	}

	if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
		EX(object) = NULL;
	} else {
		if (IS_CONST != IS_UNUSED &&
		    EG(This) &&
		    Z_OBJ_HT_P(EG(This))->get_class_entry &&
		    !instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
		    /* We are calling method of the other (incompatible) class,
		       but passing $this. This is done for compatibility with php-4. */
			int severity;
			char *verb;
			if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
				severity = E_STRICT;
				verb = "should not";
			} else {
				/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
				severity = E_ERROR;
				verb = "cannot";
			}
			zend_error(severity, "Non-static method %s::%s() %s be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name, verb);

		}
		if ((EX(object) = EG(This))) {
			EX(object)->refcount++;
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *function_name;
	zend_function *function;
	char *function_name_strval, *lcname;
	int function_name_strlen;


	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), NULL);

	if (IS_CONST == IS_CONST) {
		function_name_strval = opline->op2.u.constant.value.str.val;
		function_name_strlen = opline->op2.u.constant.value.str.len;
	} else {
		function_name = &opline->op2.u.constant;

		if (Z_TYPE_P(function_name) != IS_STRING) {
			zend_error_noreturn(E_ERROR, "Function name must be a string");
		}
		function_name_strval = function_name->value.str.val;
		function_name_strlen = function_name->value.str.len;
	}

	lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen);
	if (zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &function)==FAILURE) {
		efree(lcname);
		zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
	}

	efree(lcname);
	if (IS_CONST != IS_CONST) {

	}

	EX(object) = NULL;

	EX(fbc) = function;

	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_RECV_INIT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval **param, *assignment_value;
	zend_uint arg_num = Z_LVAL(opline->op1.u.constant);
	zend_free_op free_res;

	if (zend_ptr_stack_get_arg(arg_num, (void **) &param TSRMLS_CC)==FAILURE) {
		if (Z_TYPE(opline->op2.u.constant) == IS_CONSTANT || Z_TYPE(opline->op2.u.constant)==IS_CONSTANT_ARRAY) {
			zval *default_value;

			ALLOC_ZVAL(default_value);
			*default_value = opline->op2.u.constant;
			default_value->refcount=1;
			zval_update_constant(&default_value, 0 TSRMLS_CC);
			default_value->refcount=0;
			default_value->is_ref=0;
			param = &default_value;
			assignment_value = default_value;
		} else {
			param = NULL;
			assignment_value = &opline->op2.u.constant;
		}
		zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value TSRMLS_CC);
		zend_assign_to_variable(NULL, &opline->result, NULL, assignment_value, IS_VAR, EX(Ts) TSRMLS_CC);
	} else {
		zval **var_ptr = get_zval_ptr_ptr(&opline->result, EX(Ts), &free_res, BP_VAR_W);

		assignment_value = *param;
		zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value TSRMLS_CC);
		if (PZVAL_IS_REF(assignment_value)) {
			zend_assign_to_variable_reference(var_ptr, param TSRMLS_CC);
		} else {
			zend_receive(var_ptr, assignment_value TSRMLS_CC);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BRK_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zend_brk_cont_element *el;

	el = zend_brk_cont(&opline->op2.u.constant, opline->op1.u.opline_num,
	                   EX(op_array), EX(Ts) TSRMLS_CC);

	ZEND_VM_JMP(EX(op_array)->opcodes + el->brk);
}

static int ZEND_CONT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zend_brk_cont_element *el;

	el = zend_brk_cont(&opline->op2.u.constant, opline->op1.u.opline_num,
	                   EX(op_array), EX(Ts) TSRMLS_CC);

	ZEND_VM_JMP(EX(op_array)->opcodes + el->cont);
}

static int ZEND_FETCH_CLASS_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *class_name;
	zend_free_op free_op2;


	if (IS_TMP_VAR == IS_UNUSED) {
		EX_T(opline->result.u.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC);
		ZEND_VM_NEXT_OPCODE();
	}

	class_name = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	switch (Z_TYPE_P(class_name)) {
		case IS_OBJECT:
			EX_T(opline->result.u.var).class_entry = Z_OBJCE_P(class_name);
			break;
		case IS_STRING:
			EX_T(opline->result.u.var).class_entry = zend_fetch_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), opline->extended_value TSRMLS_CC);
			break;
		default:
			zend_error_noreturn(E_ERROR, "Class name must be a valid object or a string");
			break;
	}

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *function_name;
	zend_class_entry *ce;

	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), NULL);

	ce = EX_T(opline->op1.u.var).class_entry;
	if(IS_TMP_VAR != IS_UNUSED) {
		char *function_name_strval = NULL;
		int function_name_strlen;
		zend_bool is_const = (IS_TMP_VAR == IS_CONST);
		zend_free_op free_op2;

		if (is_const) {
			function_name_strval = Z_STRVAL(opline->op2.u.constant);
			function_name_strlen = Z_STRLEN(opline->op2.u.constant);
		} else {
			function_name = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

			if (Z_TYPE_P(function_name) != IS_STRING) {
				zend_error_noreturn(E_ERROR, "Function name must be a string");
			} else {
				function_name_strval = Z_STRVAL_P(function_name);
				function_name_strlen = Z_STRLEN_P(function_name);
			}
		}

		if (function_name_strval) {
			EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
		}

		if (!is_const) {
			zval_dtor(free_op2.var);
		}
	} else {
		if(!ce->constructor) {
			zend_error_noreturn(E_ERROR, "Can not call constructor");
		}
		if (EG(This) && Z_OBJCE_P(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
			zend_error(E_COMPILE_ERROR, "Cannot call private %s::__construct()", ce->name);
		}
		EX(fbc) = ce->constructor;
	}

	if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
		EX(object) = NULL;
	} else {
		if (IS_TMP_VAR != IS_UNUSED &&
		    EG(This) &&
		    Z_OBJ_HT_P(EG(This))->get_class_entry &&
		    !instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
		    /* We are calling method of the other (incompatible) class,
		       but passing $this. This is done for compatibility with php-4. */
			int severity;
			char *verb;
			if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
				severity = E_STRICT;
				verb = "should not";
			} else {
				/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
				severity = E_ERROR;
				verb = "cannot";
			}
			zend_error(severity, "Non-static method %s::%s() %s be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name, verb);

		}
		if ((EX(object) = EG(This))) {
			EX(object)->refcount++;
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *function_name;
	zend_function *function;
	char *function_name_strval, *lcname;
	int function_name_strlen;
	zend_free_op free_op2;

	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), NULL);

	if (IS_TMP_VAR == IS_CONST) {
		function_name_strval = opline->op2.u.constant.value.str.val;
		function_name_strlen = opline->op2.u.constant.value.str.len;
	} else {
		function_name = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

		if (Z_TYPE_P(function_name) != IS_STRING) {
			zend_error_noreturn(E_ERROR, "Function name must be a string");
		}
		function_name_strval = function_name->value.str.val;
		function_name_strlen = function_name->value.str.len;
	}

	lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen);
	if (zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &function)==FAILURE) {
		efree(lcname);
		zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
	}

	efree(lcname);
	if (IS_TMP_VAR != IS_CONST) {
		zval_dtor(free_op2.var);
	}

	EX(object) = NULL;

	EX(fbc) = function;

	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_BRK_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zend_brk_cont_element *el;

	el = zend_brk_cont(_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC), opline->op1.u.opline_num,
	                   EX(op_array), EX(Ts) TSRMLS_CC);
	zval_dtor(free_op2.var);
	ZEND_VM_JMP(EX(op_array)->opcodes + el->brk);
}

static int ZEND_CONT_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zend_brk_cont_element *el;

	el = zend_brk_cont(_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC), opline->op1.u.opline_num,
	                   EX(op_array), EX(Ts) TSRMLS_CC);
	zval_dtor(free_op2.var);
	ZEND_VM_JMP(EX(op_array)->opcodes + el->cont);
}

static int ZEND_FETCH_CLASS_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *class_name;
	zend_free_op free_op2;


	if (IS_VAR == IS_UNUSED) {
		EX_T(opline->result.u.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC);
		ZEND_VM_NEXT_OPCODE();
	}

	class_name = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	switch (Z_TYPE_P(class_name)) {
		case IS_OBJECT:
			EX_T(opline->result.u.var).class_entry = Z_OBJCE_P(class_name);
			break;
		case IS_STRING:
			EX_T(opline->result.u.var).class_entry = zend_fetch_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), opline->extended_value TSRMLS_CC);
			break;
		default:
			zend_error_noreturn(E_ERROR, "Class name must be a valid object or a string");
			break;
	}

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *function_name;
	zend_class_entry *ce;

	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), NULL);

	ce = EX_T(opline->op1.u.var).class_entry;
	if(IS_VAR != IS_UNUSED) {
		char *function_name_strval = NULL;
		int function_name_strlen;
		zend_bool is_const = (IS_VAR == IS_CONST);
		zend_free_op free_op2;

		if (is_const) {
			function_name_strval = Z_STRVAL(opline->op2.u.constant);
			function_name_strlen = Z_STRLEN(opline->op2.u.constant);
		} else {
			function_name = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

			if (Z_TYPE_P(function_name) != IS_STRING) {
				zend_error_noreturn(E_ERROR, "Function name must be a string");
			} else {
				function_name_strval = Z_STRVAL_P(function_name);
				function_name_strlen = Z_STRLEN_P(function_name);
			}
		}

		if (function_name_strval) {
			EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
		}

		if (!is_const) {
			if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
		}
	} else {
		if(!ce->constructor) {
			zend_error_noreturn(E_ERROR, "Can not call constructor");
		}
		if (EG(This) && Z_OBJCE_P(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
			zend_error(E_COMPILE_ERROR, "Cannot call private %s::__construct()", ce->name);
		}
		EX(fbc) = ce->constructor;
	}

	if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
		EX(object) = NULL;
	} else {
		if (IS_VAR != IS_UNUSED &&
		    EG(This) &&
		    Z_OBJ_HT_P(EG(This))->get_class_entry &&
		    !instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
		    /* We are calling method of the other (incompatible) class,
		       but passing $this. This is done for compatibility with php-4. */
			int severity;
			char *verb;
			if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
				severity = E_STRICT;
				verb = "should not";
			} else {
				/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
				severity = E_ERROR;
				verb = "cannot";
			}
			zend_error(severity, "Non-static method %s::%s() %s be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name, verb);

		}
		if ((EX(object) = EG(This))) {
			EX(object)->refcount++;
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *function_name;
	zend_function *function;
	char *function_name_strval, *lcname;
	int function_name_strlen;
	zend_free_op free_op2;

	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), NULL);

	if (IS_VAR == IS_CONST) {
		function_name_strval = opline->op2.u.constant.value.str.val;
		function_name_strlen = opline->op2.u.constant.value.str.len;
	} else {
		function_name = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

		if (Z_TYPE_P(function_name) != IS_STRING) {
			zend_error_noreturn(E_ERROR, "Function name must be a string");
		}
		function_name_strval = function_name->value.str.val;
		function_name_strlen = function_name->value.str.len;
	}

	lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen);
	if (zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &function)==FAILURE) {
		efree(lcname);
		zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
	}

	efree(lcname);
	if (IS_VAR != IS_CONST) {
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	}

	EX(object) = NULL;

	EX(fbc) = function;

	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_BRK_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zend_brk_cont_element *el;

	el = zend_brk_cont(_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC), opline->op1.u.opline_num,
	                   EX(op_array), EX(Ts) TSRMLS_CC);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_JMP(EX(op_array)->opcodes + el->brk);
}

static int ZEND_CONT_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zend_brk_cont_element *el;

	el = zend_brk_cont(_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC), opline->op1.u.opline_num,
	                   EX(op_array), EX(Ts) TSRMLS_CC);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_JMP(EX(op_array)->opcodes + el->cont);
}

static int ZEND_FETCH_CLASS_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *class_name;



	if (IS_UNUSED == IS_UNUSED) {
		EX_T(opline->result.u.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC);
		ZEND_VM_NEXT_OPCODE();
	}

	class_name = NULL;

	switch (Z_TYPE_P(class_name)) {
		case IS_OBJECT:
			EX_T(opline->result.u.var).class_entry = Z_OBJCE_P(class_name);
			break;
		case IS_STRING:
			EX_T(opline->result.u.var).class_entry = zend_fetch_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), opline->extended_value TSRMLS_CC);
			break;
		default:
			zend_error_noreturn(E_ERROR, "Class name must be a valid object or a string");
			break;
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *function_name;
	zend_class_entry *ce;

	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), NULL);

	ce = EX_T(opline->op1.u.var).class_entry;
	if(IS_UNUSED != IS_UNUSED) {
		char *function_name_strval = NULL;
		int function_name_strlen;
		zend_bool is_const = (IS_UNUSED == IS_CONST);


		if (is_const) {
			function_name_strval = Z_STRVAL(opline->op2.u.constant);
			function_name_strlen = Z_STRLEN(opline->op2.u.constant);
		} else {
			function_name = NULL;

			if (Z_TYPE_P(function_name) != IS_STRING) {
				zend_error_noreturn(E_ERROR, "Function name must be a string");
			} else {
				function_name_strval = Z_STRVAL_P(function_name);
				function_name_strlen = Z_STRLEN_P(function_name);
			}
		}

		if (function_name_strval) {
			EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
		}

		if (!is_const) {

		}
	} else {
		if(!ce->constructor) {
			zend_error_noreturn(E_ERROR, "Can not call constructor");
		}
		if (EG(This) && Z_OBJCE_P(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
			zend_error(E_COMPILE_ERROR, "Cannot call private %s::__construct()", ce->name);
		}
		EX(fbc) = ce->constructor;
	}

	if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
		EX(object) = NULL;
	} else {
		if (IS_UNUSED != IS_UNUSED &&
		    EG(This) &&
		    Z_OBJ_HT_P(EG(This))->get_class_entry &&
		    !instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
		    /* We are calling method of the other (incompatible) class,
		       but passing $this. This is done for compatibility with php-4. */
			int severity;
			char *verb;
			if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
				severity = E_STRICT;
				verb = "should not";
			} else {
				/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
				severity = E_ERROR;
				verb = "cannot";
			}
			zend_error(severity, "Non-static method %s::%s() %s be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name, verb);

		}
		if ((EX(object) = EG(This))) {
			EX(object)->refcount++;
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_CLASS_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *class_name;



	if (IS_CV == IS_UNUSED) {
		EX_T(opline->result.u.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC);
		ZEND_VM_NEXT_OPCODE();
	}

	class_name = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

	switch (Z_TYPE_P(class_name)) {
		case IS_OBJECT:
			EX_T(opline->result.u.var).class_entry = Z_OBJCE_P(class_name);
			break;
		case IS_STRING:
			EX_T(opline->result.u.var).class_entry = zend_fetch_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), opline->extended_value TSRMLS_CC);
			break;
		default:
			zend_error_noreturn(E_ERROR, "Class name must be a valid object or a string");
			break;
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *function_name;
	zend_class_entry *ce;

	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), NULL);

	ce = EX_T(opline->op1.u.var).class_entry;
	if(IS_CV != IS_UNUSED) {
		char *function_name_strval = NULL;
		int function_name_strlen;
		zend_bool is_const = (IS_CV == IS_CONST);


		if (is_const) {
			function_name_strval = Z_STRVAL(opline->op2.u.constant);
			function_name_strlen = Z_STRLEN(opline->op2.u.constant);
		} else {
			function_name = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

			if (Z_TYPE_P(function_name) != IS_STRING) {
				zend_error_noreturn(E_ERROR, "Function name must be a string");
			} else {
				function_name_strval = Z_STRVAL_P(function_name);
				function_name_strlen = Z_STRLEN_P(function_name);
			}
		}

		if (function_name_strval) {
			EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
		}

		if (!is_const) {

		}
	} else {
		if(!ce->constructor) {
			zend_error_noreturn(E_ERROR, "Can not call constructor");
		}
		if (EG(This) && Z_OBJCE_P(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
			zend_error(E_COMPILE_ERROR, "Cannot call private %s::__construct()", ce->name);
		}
		EX(fbc) = ce->constructor;
	}

	if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
		EX(object) = NULL;
	} else {
		if (IS_CV != IS_UNUSED &&
		    EG(This) &&
		    Z_OBJ_HT_P(EG(This))->get_class_entry &&
		    !instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
		    /* We are calling method of the other (incompatible) class,
		       but passing $this. This is done for compatibility with php-4. */
			int severity;
			char *verb;
			if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
				severity = E_STRICT;
				verb = "should not";
			} else {
				/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
				severity = E_ERROR;
				verb = "cannot";
			}
			zend_error(severity, "Non-static method %s::%s() %s be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name, verb);

		}
		if ((EX(object) = EG(This))) {
			EX(object)->refcount++;
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *function_name;
	zend_function *function;
	char *function_name_strval, *lcname;
	int function_name_strlen;


	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), NULL);

	if (IS_CV == IS_CONST) {
		function_name_strval = opline->op2.u.constant.value.str.val;
		function_name_strlen = opline->op2.u.constant.value.str.len;
	} else {
		function_name = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

		if (Z_TYPE_P(function_name) != IS_STRING) {
			zend_error_noreturn(E_ERROR, "Function name must be a string");
		}
		function_name_strval = function_name->value.str.val;
		function_name_strlen = function_name->value.str.len;
	}

	lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen);
	if (zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &function)==FAILURE) {
		efree(lcname);
		zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
	}

	efree(lcname);
	if (IS_CV != IS_CONST) {

	}

	EX(object) = NULL;

	EX(fbc) = function;

	ZEND_VM_NEXT_OPCODE();
}


static int ZEND_BRK_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zend_brk_cont_element *el;

	el = zend_brk_cont(_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC), opline->op1.u.opline_num,
	                   EX(op_array), EX(Ts) TSRMLS_CC);

	ZEND_VM_JMP(EX(op_array)->opcodes + el->brk);
}

static int ZEND_CONT_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zend_brk_cont_element *el;

	el = zend_brk_cont(_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC), opline->op1.u.opline_num,
	                   EX(op_array), EX(Ts) TSRMLS_CC);

	ZEND_VM_JMP(EX(op_array)->opcodes + el->cont);
}

static int ZEND_BW_NOT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	bitwise_not_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant TSRMLS_CC);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BOOL_NOT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	boolean_not_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant TSRMLS_CC);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ECHO_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval z_copy;
	zval *z = &opline->op1.u.constant;

	if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL &&
		zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
		zend_print_variable(&z_copy);
		zval_dtor(&z_copy);
	} else {
		zend_print_variable(z);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_PRINT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 1;
	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_LONG;

	return ZEND_ECHO_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_fetch_var_address_helper_SPEC_CONST(int type, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *varname = &opline->op1.u.constant;
	zval **retval;
	zval tmp_varname;
	HashTable *target_symbol_table;

 	if (Z_TYPE_P(varname) != IS_STRING) {
		tmp_varname = *varname;
		zval_copy_ctor(&tmp_varname);
		convert_to_string(&tmp_varname);
		varname = &tmp_varname;
	}

	if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
		retval = zend_std_get_static_property(EX_T(opline->op2.u.var).class_entry, Z_STRVAL_P(varname), Z_STRLEN_P(varname), 0 TSRMLS_CC);

	} else {
		target_symbol_table = zend_get_target_symbol_table(opline, EX(Ts), type, varname TSRMLS_CC);
/*
		if (!target_symbol_table) {
			ZEND_VM_NEXT_OPCODE();
		}
*/
		if (zend_hash_find(target_symbol_table, varname->value.str.val, varname->value.str.len+1, (void **) &retval) == FAILURE) {
			switch (type) {
				case BP_VAR_R:
				case BP_VAR_UNSET:
					zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
					/* break missing intentionally */
				case BP_VAR_IS:
					retval = &EG(uninitialized_zval_ptr);
					break;
				case BP_VAR_RW:
					zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
					/* break missing intentionally */
				case BP_VAR_W: {
						zval *new_zval = &EG(uninitialized_zval);

						new_zval->refcount++;
						zend_hash_update(target_symbol_table, varname->value.str.val, varname->value.str.len+1, &new_zval, sizeof(zval *), (void **) &retval);
					}
					break;
				EMPTY_SWITCH_DEFAULT_CASE()
			}
		}
		switch (opline->op2.u.EA.type) {
			case ZEND_FETCH_GLOBAL:
				if (IS_CONST != IS_TMP_VAR) {

				}
				break;
			case ZEND_FETCH_LOCAL:

				break;
			case ZEND_FETCH_STATIC:
				zval_update_constant(retval, (void*) 1 TSRMLS_CC);
				break;
			case ZEND_FETCH_GLOBAL_LOCK:
				if (IS_CONST == IS_VAR && !free_op1.var) {
					PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
				}
				break;
		}
	}


	if (varname == &tmp_varname) {
		zval_dtor(varname);
	}
	if (!RETURN_VALUE_UNUSED(&opline->result)) {
		EX_T(opline->result.u.var).var.ptr_ptr = retval;
		PZVAL_LOCK(*retval);
		switch (type) {
			case BP_VAR_R:
			case BP_VAR_IS:
				AI_USE_PTR(EX_T(opline->result.u.var).var);
				break;
			case BP_VAR_UNSET: {
				zend_free_op free_res;

				PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &free_res);
				if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
					SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
				}
				PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
				FREE_OP_VAR_PTR(free_res);
				break;
			}
		}
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_R_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_var_address_helper_SPEC_CONST(BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_W_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_var_address_helper_SPEC_CONST(BP_VAR_W, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_RW_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_var_address_helper_SPEC_CONST(BP_VAR_RW, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_FUNC_ARG_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_var_address_helper_SPEC_CONST(ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), EX(opline)->extended_value)?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_UNSET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_var_address_helper_SPEC_CONST(BP_VAR_UNSET, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_IS_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_var_address_helper_SPEC_CONST(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_JMPZ_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	int ret = i_zend_is_true(&opline->op1.u.constant);

	if (!ret) {
#if DEBUG_ZEND>=2
		printf("Conditional jmp to %d\n", opline->op2.u.opline_num);
#endif
		ZEND_VM_JMP(opline->op2.u.jmp_addr);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_JMPNZ_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	int ret = i_zend_is_true(&opline->op1.u.constant);

	if (ret) {
#if DEBUG_ZEND>=2
		printf("Conditional jmp to %d\n", opline->op2.u.opline_num);
#endif
		ZEND_VM_JMP(opline->op2.u.jmp_addr);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_JMPZNZ_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	int retval = i_zend_is_true(&opline->op1.u.constant);

	if (retval) {
#if DEBUG_ZEND>=2
		printf("Conditional jmp on true to %d\n", opline->extended_value);
#endif
		ZEND_VM_JMP(&EX(op_array)->opcodes[opline->extended_value]);
	} else {
#if DEBUG_ZEND>=2
		printf("Conditional jmp on false to %d\n", opline->op2.u.opline_num);
#endif
		ZEND_VM_JMP(&EX(op_array)->opcodes[opline->op2.u.opline_num]);
	}
}

static int ZEND_JMPZ_EX_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	int retval = i_zend_is_true(&opline->op1.u.constant);

	Z_LVAL(EX_T(opline->result.u.var).tmp_var) = retval;
	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
	if (!retval) {
#if DEBUG_ZEND>=2
		printf("Conditional jmp to %d\n", opline->op2.u.opline_num);
#endif
		ZEND_VM_JMP(opline->op2.u.jmp_addr);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_JMPNZ_EX_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	int retval = i_zend_is_true(&opline->op1.u.constant);

	Z_LVAL(EX_T(opline->result.u.var).tmp_var) = retval;
	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
	if (retval) {
#if DEBUG_ZEND>=2
		printf("Conditional jmp to %d\n", opline->op2.u.opline_num);
#endif
		ZEND_VM_JMP(opline->op2.u.jmp_addr);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_DO_FCALL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval *fname = &opline->op1.u.constant;

	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), NULL);

	if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) {
		zend_error_noreturn(E_ERROR, "Call to undefined function %s()", fname->value.str.val);
	}
	EX(object) = NULL;

	return zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_RETURN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *retval_ptr;
	zval **retval_ptr_ptr;


	if (EG(active_op_array)->return_reference == ZEND_RETURN_REF) {

		if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) {
			/* Not supposed to happen, but we'll allow it */
			zend_error(E_NOTICE, "Only variable references should be returned by reference");
			goto return_by_value;
		}

		retval_ptr_ptr = NULL;

		if (!retval_ptr_ptr) {
			zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
		}

		if (IS_CONST == IS_VAR && !(*retval_ptr_ptr)->is_ref) {
			if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
			    EX_T(opline->op1.u.var).var.fcall_returned_reference) {
			} else if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
				if (IS_CONST == IS_VAR && !0) {
					PZVAL_LOCK(*retval_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
				}
				zend_error(E_NOTICE, "Only variable references should be returned by reference");
				goto return_by_value;
			}
		}

		SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr_ptr);
		(*retval_ptr_ptr)->refcount++;

		(*EG(return_value_ptr_ptr)) = (*retval_ptr_ptr);
	} else {
return_by_value:

		retval_ptr = &opline->op1.u.constant;

		if (EG(ze1_compatibility_mode) && Z_TYPE_P(retval_ptr) == IS_OBJECT) {
			zval *ret;
			char *class_name;
			zend_uint class_name_len;
			int dup;

			ALLOC_ZVAL(ret);
			INIT_PZVAL_COPY(ret, retval_ptr);
			dup = zend_get_object_classname(retval_ptr, &class_name, &class_name_len TSRMLS_CC);
			if (Z_OBJ_HT_P(retval_ptr)->clone_obj == NULL) {
				zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s",  class_name);
			}
			zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name);
			ret->value.obj = Z_OBJ_HT_P(retval_ptr)->clone_obj(retval_ptr TSRMLS_CC);
			*EG(return_value_ptr_ptr) = ret;
			if (!dup) {
				efree(class_name);
			}
		} else if (!0) { /* Not a temp var */
			if (EG(active_op_array)->return_reference == ZEND_RETURN_REF ||
			    (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0)) {
				zval *ret;

				ALLOC_ZVAL(ret);
				INIT_PZVAL_COPY(ret, retval_ptr);
				zval_copy_ctor(ret);
				*EG(return_value_ptr_ptr) = ret;
			} else if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) &&
			           retval_ptr == &EG(uninitialized_zval)) {
				zval *ret;

				ALLOC_INIT_ZVAL(ret);
				*EG(return_value_ptr_ptr) = ret;
			} else {
				*EG(return_value_ptr_ptr) = retval_ptr;
				retval_ptr->refcount++;
			}
		} else {
			zval *ret;

			ALLOC_ZVAL(ret);
			INIT_PZVAL_COPY(ret, retval_ptr);
			*EG(return_value_ptr_ptr) = ret;
		}
	}

	ZEND_VM_RETURN_FROM_EXECUTE_LOOP();
}

static int ZEND_THROW_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *value;
	zval *exception;


	value = &opline->op1.u.constant;

	if (Z_TYPE_P(value) != IS_OBJECT) {
		zend_error_noreturn(E_ERROR, "Can only throw objects");
	}
	/* Not sure if a complete copy is what we want here */
	ALLOC_ZVAL(exception);
	INIT_PZVAL_COPY(exception, value);
	if (!0) {
		zval_copy_ctor(exception);
	}

	zend_throw_exception_object(exception TSRMLS_CC);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SEND_VAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	if (opline->extended_value==ZEND_DO_FCALL_BY_NAME
		&& ARG_MUST_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
			zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.u.opline_num);
	}
	{
		zval *valptr;
		zval *value;


		value = &opline->op1.u.constant;

		ALLOC_ZVAL(valptr);
		INIT_PZVAL_COPY(valptr, value);
		if (!0) {
			zval_copy_ctor(valptr);
		}
		zend_ptr_stack_push(&EG(argument_stack), valptr);

	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BOOL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	/* PHP 3.0 returned "" for false and 1 for true, here we use 0 and 1 for now */
	Z_LVAL(EX_T(opline->result.u.var).tmp_var) = i_zend_is_true(&opline->op1.u.constant);
	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CLONE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval *obj = &opline->op1.u.constant;
	zend_class_entry *ce;
	zend_function *clone;
	zend_object_clone_obj_t clone_call;

	if (!obj || Z_TYPE_P(obj) != IS_OBJECT) {
		zend_error_noreturn(E_ERROR, "__clone method called on non-object");
		EX_T(opline->result.u.var).var.ptr = EG(error_zval_ptr);
		EX_T(opline->result.u.var).var.ptr->refcount++;

		ZEND_VM_NEXT_OPCODE();
	}

	ce = Z_OBJCE_P(obj);
	clone = ce ? ce->clone : NULL;
	clone_call =  Z_OBJ_HT_P(obj)->clone_obj;
	if (!clone_call) {
		if (ce) {
			zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", ce->name);
		} else {
			zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object");
		}
		EX_T(opline->result.u.var).var.ptr = EG(error_zval_ptr);
		EX_T(opline->result.u.var).var.ptr->refcount++;
	}

	if (ce && clone) {
		if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) {
			/* Ensure that if we're calling a private function, we're allowed to do so.
			 */
			if (ce != EG(scope)) {
				zend_error_noreturn(E_ERROR, "Call to private %s::__clone() from context '%s'", ce->name, EG(scope) ? EG(scope)->name : "");
			}
		} else if ((clone->common.fn_flags & ZEND_ACC_PROTECTED)) {
			/* Ensure that if we're calling a protected function, we're allowed to do so.
			 */
			if (!zend_check_protected(clone->common.scope, EG(scope))) {
				zend_error_noreturn(E_ERROR, "Call to protected %s::__clone() from context '%s'", ce->name, EG(scope) ? EG(scope)->name : "");
			}
		}
	}

	EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
	if (!EG(exception)) {
		ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
		Z_OBJVAL_P(EX_T(opline->result.u.var).var.ptr) = clone_call(obj TSRMLS_CC);
		Z_TYPE_P(EX_T(opline->result.u.var).var.ptr) = IS_OBJECT;
		EX_T(opline->result.u.var).var.ptr->refcount=1;
		EX_T(opline->result.u.var).var.ptr->is_ref=1;
		if (!RETURN_VALUE_USED(opline) || EG(exception)) {
			zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CAST_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval *expr = &opline->op1.u.constant;
	zval *result = &EX_T(opline->result.u.var).tmp_var;

	if (opline->extended_value != IS_STRING) {
		*result = *expr;
		if (!0) {
			zendi_zval_copy_ctor(*result);
		}
	}
	switch (opline->extended_value) {
		case IS_NULL:
			convert_to_null(result);
			break;
		case IS_BOOL:
			convert_to_boolean(result);
			break;
		case IS_LONG:
			convert_to_long(result);
			break;
		case IS_DOUBLE:
			convert_to_double(result);
			break;
		case IS_STRING: {
			zval var_copy;
			int use_copy;

			zend_make_printable_zval(expr, &var_copy, &use_copy);
			if (use_copy) {
				*result = var_copy;
				if (0) {

				}
			} else {
				*result = *expr;
				if (!0) {
					zendi_zval_copy_ctor(*result);
				}
			}
			break;
		}
		case IS_ARRAY:
			convert_to_array(result);
			break;
		case IS_OBJECT:
			convert_to_object(result);
			break;
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op_array *new_op_array=NULL;
	zval **original_return_value = EG(return_value_ptr_ptr);
	int return_value_used;

	zval *inc_filename = &opline->op1.u.constant;
	zval tmp_inc_filename;
	zend_bool failure_retval=0;

	if (inc_filename->type!=IS_STRING) {
		tmp_inc_filename = *inc_filename;
		zval_copy_ctor(&tmp_inc_filename);
		convert_to_string(&tmp_inc_filename);
		inc_filename = &tmp_inc_filename;
	}

	return_value_used = RETURN_VALUE_USED(opline);

	switch (Z_LVAL(opline->op2.u.constant)) {
		case ZEND_INCLUDE_ONCE:
		case ZEND_REQUIRE_ONCE: {
				zend_file_handle file_handle;

				if (IS_ABSOLUTE_PATH(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename))) {
					cwd_state state;

					state.cwd_length = 0;
					state.cwd = malloc(1);
					state.cwd[0] = 0;

					failure_retval = (!virtual_file_ex(&state, Z_STRVAL_P(inc_filename), NULL, 1) &&
						zend_hash_exists(&EG(included_files), state.cwd, state.cwd_length+1));

					free(state.cwd);
				}

				if (failure_retval) {
					/* do nothing */
				} else if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) {

					if (!file_handle.opened_path) {
						file_handle.opened_path = estrndup(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename));
					}

					if (zend_hash_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1)==SUCCESS) {
						new_op_array = zend_compile_file(&file_handle, (Z_LVAL(opline->op2.u.constant)==ZEND_INCLUDE_ONCE?ZEND_INCLUDE:ZEND_REQUIRE) TSRMLS_CC);
						zend_destroy_file_handle(&file_handle TSRMLS_CC);
					} else {
						zend_file_handle_dtor(&file_handle);
						failure_retval=1;
					}
				} else {
					if (Z_LVAL(opline->op2.u.constant)==ZEND_INCLUDE_ONCE) {
						zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, Z_STRVAL_P(inc_filename));
					} else {
						zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename));
					}
				}
			}
			break;
		case ZEND_INCLUDE:
		case ZEND_REQUIRE:
			new_op_array = compile_filename(Z_LVAL(opline->op2.u.constant), inc_filename TSRMLS_CC);
			break;
		case ZEND_EVAL: {
				char *eval_desc = zend_make_compiled_string_description("eval()'d code" TSRMLS_CC);

				new_op_array = zend_compile_string(inc_filename, eval_desc TSRMLS_CC);
				efree(eval_desc);
			}
			break;
		EMPTY_SWITCH_DEFAULT_CASE()
	}
	if (inc_filename==&tmp_inc_filename) {
		zval_dtor(&tmp_inc_filename);
	}
	EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
	if (new_op_array) {
		zval *saved_object;
		zend_function *saved_function;

		EG(return_value_ptr_ptr) = EX_T(opline->result.u.var).var.ptr_ptr;
		EG(active_op_array) = new_op_array;
		EX_T(opline->result.u.var).var.ptr = NULL;

		saved_object = EX(object);
		saved_function = EX(function_state).function;

		EX(function_state).function = (zend_function *) new_op_array;
		EX(object) = NULL;

		zend_execute(new_op_array TSRMLS_CC);

		EX(function_state).function = saved_function;
		EX(object) = saved_object;

		if (!return_value_used) {
			if (EX_T(opline->result.u.var).var.ptr) {
				zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
			}
		} else { /* return value is used */
			if (!EX_T(opline->result.u.var).var.ptr) { /* there was no return statement */
				ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
				INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);
				Z_LVAL_P(EX_T(opline->result.u.var).var.ptr) = 1;
				Z_TYPE_P(EX_T(opline->result.u.var).var.ptr) = IS_BOOL;
			}
		}

		EG(opline_ptr) = &EX(opline);
		EG(active_op_array) = EX(op_array);
		EG(function_state_ptr) = &EX(function_state);
		destroy_op_array(new_op_array TSRMLS_CC);
		efree(new_op_array);
		if (EG(exception)) {
			zend_throw_exception_internal(NULL TSRMLS_CC);
		}
	} else {
		if (return_value_used) {
			ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
			INIT_ZVAL(*EX_T(opline->result.u.var).var.ptr);
			Z_LVAL_P(EX_T(opline->result.u.var).var.ptr) = failure_retval;
			Z_TYPE_P(EX_T(opline->result.u.var).var.ptr) = IS_BOOL;
		}
	}

	EG(return_value_ptr_ptr) = original_return_value;
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_UNSET_VAR_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval tmp, *varname;
	HashTable *target_symbol_table;


	varname = &opline->op1.u.constant;

	if (Z_TYPE_P(varname) != IS_STRING) {
		tmp = *varname;
		zval_copy_ctor(&tmp);
		convert_to_string(&tmp);
		varname = &tmp;
	} else if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
		varname->refcount++;
	}

	if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
		zend_std_unset_static_property(EX_T(opline->op2.u.var).class_entry, Z_STRVAL_P(varname), Z_STRLEN_P(varname) TSRMLS_CC);
	} else {
		target_symbol_table = zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
		if (zend_hash_del(target_symbol_table, varname->value.str.val, varname->value.str.len+1) == SUCCESS) {
			zend_execute_data *ex = execute_data;
			ulong hash_value = zend_inline_hash_func(varname->value.str.val, varname->value.str.len+1);

			do {
				int i;

				if (ex->op_array) {
					for (i = 0; i < ex->op_array->last_var; i++) {
						if (ex->op_array->vars[i].hash_value == hash_value &&
							ex->op_array->vars[i].name_len == varname->value.str.len &&
							!memcmp(ex->op_array->vars[i].name, varname->value.str.val, varname->value.str.len)) {
							ex->CVs[i] = NULL;
							break;
						}
					}
				}
				ex = ex->prev_execute_data;
			} while (ex && ex->symbol_table == target_symbol_table);
		}
	}

	if (varname == &tmp) {
		zval_dtor(&tmp);
	} else if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
		zval_ptr_dtor(&varname);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval *array_ptr, **array_ptr_ptr;
	HashTable *fe_ht;
	zend_object_iterator *iter = NULL;
	zend_class_entry *ce = NULL;
	zend_bool is_empty = 0;

	if (opline->extended_value & ZEND_FE_RESET_VARIABLE) {
		array_ptr_ptr = NULL;
		if (array_ptr_ptr == NULL || array_ptr_ptr == &EG(uninitialized_zval_ptr)) {
			ALLOC_INIT_ZVAL(array_ptr);
		} else if (Z_TYPE_PP(array_ptr_ptr) == IS_OBJECT) {
			if(Z_OBJ_HT_PP(array_ptr_ptr)->get_class_entry == NULL) {
				zend_error(E_WARNING, "foreach() can not iterate over objects without PHP class");
				ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.u.opline_num);
			}

			ce = Z_OBJCE_PP(array_ptr_ptr);
			if (!ce || ce->get_iterator == NULL) {
				SEPARATE_ZVAL_IF_NOT_REF(array_ptr_ptr);
				(*array_ptr_ptr)->refcount++;
			}
			array_ptr = *array_ptr_ptr;
		} else {
			if (Z_TYPE_PP(array_ptr_ptr) == IS_ARRAY) {
				SEPARATE_ZVAL_IF_NOT_REF(array_ptr_ptr);
				if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
					(*array_ptr_ptr)->is_ref = 1;
				}
			}
			array_ptr = *array_ptr_ptr;
			array_ptr->refcount++;
		}
	} else {
		array_ptr = &opline->op1.u.constant;
		if (0) { /* IS_TMP_VAR */
			zval *tmp;

			ALLOC_ZVAL(tmp);
			INIT_PZVAL_COPY(tmp, array_ptr);
			array_ptr = tmp;
			if (Z_TYPE_P(array_ptr) == IS_OBJECT) {
				ce = Z_OBJCE_P(array_ptr);
				if (ce && ce->get_iterator) {
					array_ptr->refcount--;
				}
			}
		} else if (Z_TYPE_P(array_ptr) == IS_OBJECT) {
			ce = Z_OBJCE_P(array_ptr);
			if (!ce || !ce->get_iterator) {
				array_ptr->refcount++;
			}
		} else {
			if (IS_CONST == IS_CONST ||
			    ((IS_CONST == IS_CV || IS_CONST == IS_VAR) &&
			    !array_ptr->is_ref &&
			    array_ptr->refcount > 1)) {
				zval *tmp;

				ALLOC_ZVAL(tmp);
				INIT_PZVAL_COPY(tmp, array_ptr);
				zval_copy_ctor(tmp);
				array_ptr = tmp;
			} else {
				array_ptr->refcount++;
			}
		}
	}

	if (ce && ce->get_iterator) {
		iter = ce->get_iterator(ce, array_ptr, opline->extended_value & ZEND_FE_RESET_REFERENCE TSRMLS_CC);

		if (iter && !EG(exception)) {
			array_ptr = zend_iterator_wrap(iter TSRMLS_CC);
		} else {
			if (opline->extended_value & ZEND_FE_RESET_VARIABLE) {

			} else {

			}
			if (!EG(exception)) {
				zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Object of type %s did not create an Iterator", ce->name);
			}
			zend_throw_exception_internal(NULL TSRMLS_CC);
			ZEND_VM_NEXT_OPCODE();
		}
	}

	PZVAL_LOCK(array_ptr);
	EX_T(opline->result.u.var).var.ptr = array_ptr;
	EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;

	if (iter) {
		iter->index = 0;
		if (iter->funcs->rewind) {
			iter->funcs->rewind(iter TSRMLS_CC);
			if (EG(exception)) {
				array_ptr->refcount--;
				zval_ptr_dtor(&array_ptr);
				if (opline->extended_value & ZEND_FE_RESET_VARIABLE) {

				} else {

				}
				ZEND_VM_NEXT_OPCODE();
			}
		}
		is_empty = iter->funcs->valid(iter TSRMLS_CC) != SUCCESS;
		if (EG(exception)) {
			array_ptr->refcount--;
			zval_ptr_dtor(&array_ptr);
			if (opline->extended_value & ZEND_FE_RESET_VARIABLE) {

			} else {

			}
			ZEND_VM_NEXT_OPCODE();
		}
		iter->index = -1; /* will be set to 0 before using next handler */
	} else if ((fe_ht = HASH_OF(array_ptr)) != NULL) {
		zend_hash_internal_pointer_reset(fe_ht);
		if (ce) {
			zend_object *zobj = zend_objects_get_address(array_ptr TSRMLS_CC);
			while (zend_hash_has_more_elements(fe_ht) == SUCCESS) {
				char *str_key;
				uint str_key_len;
				ulong int_key;
				zend_uchar key_type;

				key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 0, NULL);
				if (key_type != HASH_KEY_NON_EXISTANT &&
					(key_type == HASH_KEY_IS_LONG ||
				     zend_check_property_access(zobj, str_key, str_key_len-1 TSRMLS_CC) == SUCCESS)) {
					break;
				}
				zend_hash_move_forward(fe_ht);
			}
		}
		is_empty = zend_hash_has_more_elements(fe_ht) != SUCCESS;
		zend_hash_get_pointer(fe_ht, &EX_T(opline->result.u.var).fe.fe_pos);
	} else {
		zend_error(E_WARNING, "Invalid argument supplied for foreach()");
		is_empty = 1;
	}

	if (opline->extended_value & ZEND_FE_RESET_VARIABLE) {

	} else {

	}
	if (is_empty) {
		ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.u.opline_num);
	} else {
		ZEND_VM_NEXT_OPCODE();
	}
}

static int ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval tmp, *varname = &opline->op1.u.constant;
	zval **value;
	zend_bool isset = 1;
	HashTable *target_symbol_table;

	if (Z_TYPE_P(varname) != IS_STRING) {
		tmp = *varname;
		zval_copy_ctor(&tmp);
		convert_to_string(&tmp);
		varname = &tmp;
	}

	if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
		value = zend_std_get_static_property(EX_T(opline->op2.u.var).class_entry, Z_STRVAL_P(varname), Z_STRLEN_P(varname), 1 TSRMLS_CC);
		if (!value) {
			isset = 0;
		}
	} else {
		target_symbol_table = zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
		if (zend_hash_find(target_symbol_table, varname->value.str.val, varname->value.str.len+1, (void **) &value) == FAILURE) {
			isset = 0;
		}
	}

	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;

	switch (opline->extended_value) {
		case ZEND_ISSET:
			if (isset && Z_TYPE_PP(value) == IS_NULL) {
				Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 0;
			} else {
				Z_LVAL(EX_T(opline->result.u.var).tmp_var) = isset;
			}
			break;
		case ZEND_ISEMPTY:
			if (!isset || !i_zend_is_true(*value)) {
				Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 1;
			} else {
				Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 0;
			}
			break;
	}

	if (varname == &tmp) {
		zval_dtor(&tmp);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_EXIT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
#if 0 || (IS_CONST != IS_UNUSED)
	zend_op *opline = EX(opline);
	if (IS_CONST != IS_UNUSED) {

		zval *ptr = &opline->op1.u.constant;

		if (Z_TYPE_P(ptr) == IS_LONG) {
			EG(exit_status) = Z_LVAL_P(ptr);
		} else {
			zend_print_variable(ptr);
		}

	}
#endif
	zend_bailout();
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_QM_ASSIGN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval *value = &opline->op1.u.constant;

	EX_T(opline->result.u.var).tmp_var = *value;
	if (!0) {
		zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_TICKS_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	if (++EG(ticks_count)>=Z_LVAL(opline->op1.u.constant)) {
		EG(ticks_count)=0;
		if (zend_ticks_function) {
			zend_ticks_function(Z_LVAL(opline->op1.u.constant));
		}
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ADD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	add_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SUB_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	sub_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_MUL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	mul_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_DIV_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	div_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_MOD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	mod_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	shift_left_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	shift_right_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CONCAT_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	concat_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_IDENTICAL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	is_identical_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_NOT_IDENTICAL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	is_not_identical_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_EQUAL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	is_equal_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_NOT_EQUAL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	is_not_equal_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_SMALLER_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	is_smaller_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	is_smaller_or_equal_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_OR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	bitwise_or_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_AND_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	bitwise_and_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_XOR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	bitwise_xor_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BOOL_XOR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	boolean_xor_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_TMP_VAR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval *container = &opline->op1.u.constant;

	if (Z_TYPE_P(container) != IS_ARRAY) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
		}
	} else {

		zval *dim = &opline->op2.u.constant;

		EX_T(opline->result.u.var).var.ptr_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, BP_VAR_R TSRMLS_CC);
		SELECTIVE_PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &opline->result);

	}
	AI_USE_PTR(EX_T(opline->result.u.var).var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CASE_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	int switch_expr_is_overloaded=0;


	if (IS_CONST==IS_VAR) {
		if (EX_T(opline->op1.u.var).var.ptr_ptr) {
			PZVAL_LOCK(EX_T(opline->op1.u.var).var.ptr);
		} else {
			switch_expr_is_overloaded = 1;
			EX_T(opline->op1.u.var).str_offset.str->refcount++;
		}
	}
	is_equal_function(&EX_T(opline->result.u.var).tmp_var,
				 &opline->op1.u.constant,
				 &opline->op2.u.constant TSRMLS_CC);

	if (switch_expr_is_overloaded) {
		/* We only free op1 if this is a string offset,
		 * Since if it is a TMP_VAR, it'll be reused by
		 * other CASE opcodes (whereas string offsets
		 * are allocated at each get_zval_ptr())
		 */

		EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
		AI_USE_PTR(EX_T(opline->op1.u.var).var);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_class_entry *ce = NULL;
	zval **value;

	if (IS_CONST == IS_UNUSED) {
/* This seems to be a reminant of namespaces
		if (EG(scope)) {
			ce = EG(scope);
			if (zend_hash_find(&ce->constants_table, Z_STRVAL(opline->op2.u.constant), Z_STRLEN(opline->op2.u.constant)+1, (void **) &value) == SUCCESS) {
				zval_update_constant(value, (void *) 1 TSRMLS_CC);
				EX_T(opline->result.u.var).tmp_var = **value;
				zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var);
				ZEND_VM_NEXT_OPCODE();
			}
		}
*/
		if (!zend_get_constant(opline->op2.u.constant.value.str.val, opline->op2.u.constant.value.str.len, &EX_T(opline->result.u.var).tmp_var TSRMLS_CC)) {
			zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'",
						opline->op2.u.constant.value.str.val,
						opline->op2.u.constant.value.str.val);
			EX_T(opline->result.u.var).tmp_var = opline->op2.u.constant;
			zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var);
		}
		ZEND_VM_NEXT_OPCODE();
	}

	ce = EX_T(opline->op1.u.var).class_entry;

	if (zend_hash_find(&ce->constants_table, opline->op2.u.constant.value.str.val, opline->op2.u.constant.value.str.len+1, (void **) &value) == SUCCESS) {
		zend_class_entry *old_scope = EG(scope);

		EG(scope) = ce;
		zval_update_constant(value, (void *) 1 TSRMLS_CC);
		EG(scope) = old_scope;
		EX_T(opline->result.u.var).tmp_var = **value;
		zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var);
	} else {
		zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", opline->op2.u.constant.value.str.val);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval *array_ptr = &EX_T(opline->result.u.var).tmp_var;
	zval *expr_ptr;
	zval *offset=&opline->op2.u.constant;

#if 0 || IS_CONST == IS_VAR || IS_CONST == IS_CV
	zval **expr_ptr_ptr = NULL;

	if (opline->extended_value) {
		expr_ptr_ptr=NULL;
		expr_ptr = *expr_ptr_ptr;
	} else {
		expr_ptr=&opline->op1.u.constant;
	}
#else
	expr_ptr=&opline->op1.u.constant;
#endif

	if (0) { /* temporary variable */
		zval *new_expr;

		ALLOC_ZVAL(new_expr);
		INIT_PZVAL_COPY(new_expr, expr_ptr);
		expr_ptr = new_expr;
	} else {
#if 0 || IS_CONST == IS_VAR || IS_CONST == IS_CV
		if (opline->extended_value) {
			SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr_ptr);
			expr_ptr = *expr_ptr_ptr;
			expr_ptr->refcount++;
		} else
#endif
		if (PZVAL_IS_REF(expr_ptr)) {
			zval *new_expr;

			ALLOC_ZVAL(new_expr);
			INIT_PZVAL_COPY(new_expr, expr_ptr);
			expr_ptr = new_expr;
			zendi_zval_copy_ctor(*expr_ptr);
		} else {
			expr_ptr->refcount++;
		}
	}
	if (offset) {
		switch (Z_TYPE_P(offset)) {
			case IS_DOUBLE:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_LONG:
			case IS_BOOL:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), Z_LVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_STRING:
				zend_symtable_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_NULL:
				zend_hash_update(Z_ARRVAL_P(array_ptr), "", sizeof(""), &expr_ptr, sizeof(zval *), NULL);
				break;
			default:
				zend_error(E_WARNING, "Illegal offset type");
				zval_ptr_dtor(&expr_ptr);
				/* do nothing */
				break;
		}

	} else {
		zend_hash_next_index_insert(Z_ARRVAL_P(array_ptr), &expr_ptr, sizeof(zval *), NULL);
	}
	if (opline->extended_value) {

	} else {

	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_ARRAY_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	array_init(&EX_T(opline->result.u.var).tmp_var);
	if (IS_CONST == IS_UNUSED) {
		ZEND_VM_NEXT_OPCODE();
#if 0 || IS_CONST != IS_UNUSED
	} else {
		return ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
#endif
	}
}

static int ZEND_ADD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	add_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SUB_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	sub_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_MUL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	mul_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_DIV_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	div_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_MOD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	mod_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	shift_left_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SR_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	shift_right_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CONCAT_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	concat_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_IDENTICAL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	is_identical_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_NOT_IDENTICAL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	is_not_identical_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_EQUAL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	is_equal_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_NOT_EQUAL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	is_not_equal_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_SMALLER_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	is_smaller_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	is_smaller_or_equal_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_OR_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	bitwise_or_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_AND_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	bitwise_and_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_XOR_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	bitwise_xor_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BOOL_XOR_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	boolean_xor_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CASE_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	int switch_expr_is_overloaded=0;
	zend_free_op free_op2;

	if (IS_CONST==IS_VAR) {
		if (EX_T(opline->op1.u.var).var.ptr_ptr) {
			PZVAL_LOCK(EX_T(opline->op1.u.var).var.ptr);
		} else {
			switch_expr_is_overloaded = 1;
			EX_T(opline->op1.u.var).str_offset.str->refcount++;
		}
	}
	is_equal_function(&EX_T(opline->result.u.var).tmp_var,
				 &opline->op1.u.constant,
				 _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	if (switch_expr_is_overloaded) {
		/* We only free op1 if this is a string offset,
		 * Since if it is a TMP_VAR, it'll be reused by
		 * other CASE opcodes (whereas string offsets
		 * are allocated at each get_zval_ptr())
		 */

		EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
		AI_USE_PTR(EX_T(opline->op1.u.var).var);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zval *array_ptr = &EX_T(opline->result.u.var).tmp_var;
	zval *expr_ptr;
	zval *offset=_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

#if 0 || IS_CONST == IS_VAR || IS_CONST == IS_CV
	zval **expr_ptr_ptr = NULL;

	if (opline->extended_value) {
		expr_ptr_ptr=NULL;
		expr_ptr = *expr_ptr_ptr;
	} else {
		expr_ptr=&opline->op1.u.constant;
	}
#else
	expr_ptr=&opline->op1.u.constant;
#endif

	if (0) { /* temporary variable */
		zval *new_expr;

		ALLOC_ZVAL(new_expr);
		INIT_PZVAL_COPY(new_expr, expr_ptr);
		expr_ptr = new_expr;
	} else {
#if 0 || IS_CONST == IS_VAR || IS_CONST == IS_CV
		if (opline->extended_value) {
			SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr_ptr);
			expr_ptr = *expr_ptr_ptr;
			expr_ptr->refcount++;
		} else
#endif
		if (PZVAL_IS_REF(expr_ptr)) {
			zval *new_expr;

			ALLOC_ZVAL(new_expr);
			INIT_PZVAL_COPY(new_expr, expr_ptr);
			expr_ptr = new_expr;
			zendi_zval_copy_ctor(*expr_ptr);
		} else {
			expr_ptr->refcount++;
		}
	}
	if (offset) {
		switch (Z_TYPE_P(offset)) {
			case IS_DOUBLE:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_LONG:
			case IS_BOOL:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), Z_LVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_STRING:
				zend_symtable_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_NULL:
				zend_hash_update(Z_ARRVAL_P(array_ptr), "", sizeof(""), &expr_ptr, sizeof(zval *), NULL);
				break;
			default:
				zend_error(E_WARNING, "Illegal offset type");
				zval_ptr_dtor(&expr_ptr);
				/* do nothing */
				break;
		}
		zval_dtor(free_op2.var);
	} else {
		zend_hash_next_index_insert(Z_ARRVAL_P(array_ptr), &expr_ptr, sizeof(zval *), NULL);
	}
	if (opline->extended_value) {

	} else {

	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_ARRAY_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	array_init(&EX_T(opline->result.u.var).tmp_var);
	if (IS_CONST == IS_UNUSED) {
		ZEND_VM_NEXT_OPCODE();
#if 0 || IS_CONST != IS_UNUSED
	} else {
		return ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
#endif
	}
}

static int ZEND_ADD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	add_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SUB_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	sub_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_MUL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	mul_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_DIV_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	div_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_MOD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	mod_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	shift_left_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	shift_right_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CONCAT_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	concat_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_IDENTICAL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	is_identical_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_NOT_IDENTICAL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	is_not_identical_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_EQUAL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	is_equal_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_NOT_EQUAL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	is_not_equal_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_SMALLER_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	is_smaller_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	is_smaller_or_equal_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_OR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	bitwise_or_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_AND_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	bitwise_and_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_XOR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	bitwise_xor_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BOOL_XOR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	boolean_xor_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CASE_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	int switch_expr_is_overloaded=0;
	zend_free_op free_op2;

	if (IS_CONST==IS_VAR) {
		if (EX_T(opline->op1.u.var).var.ptr_ptr) {
			PZVAL_LOCK(EX_T(opline->op1.u.var).var.ptr);
		} else {
			switch_expr_is_overloaded = 1;
			EX_T(opline->op1.u.var).str_offset.str->refcount++;
		}
	}
	is_equal_function(&EX_T(opline->result.u.var).tmp_var,
				 &opline->op1.u.constant,
				 _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	if (switch_expr_is_overloaded) {
		/* We only free op1 if this is a string offset,
		 * Since if it is a TMP_VAR, it'll be reused by
		 * other CASE opcodes (whereas string offsets
		 * are allocated at each get_zval_ptr())
		 */

		EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
		AI_USE_PTR(EX_T(opline->op1.u.var).var);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zval *array_ptr = &EX_T(opline->result.u.var).tmp_var;
	zval *expr_ptr;
	zval *offset=_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

#if 0 || IS_CONST == IS_VAR || IS_CONST == IS_CV
	zval **expr_ptr_ptr = NULL;

	if (opline->extended_value) {
		expr_ptr_ptr=NULL;
		expr_ptr = *expr_ptr_ptr;
	} else {
		expr_ptr=&opline->op1.u.constant;
	}
#else
	expr_ptr=&opline->op1.u.constant;
#endif

	if (0) { /* temporary variable */
		zval *new_expr;

		ALLOC_ZVAL(new_expr);
		INIT_PZVAL_COPY(new_expr, expr_ptr);
		expr_ptr = new_expr;
	} else {
#if 0 || IS_CONST == IS_VAR || IS_CONST == IS_CV
		if (opline->extended_value) {
			SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr_ptr);
			expr_ptr = *expr_ptr_ptr;
			expr_ptr->refcount++;
		} else
#endif
		if (PZVAL_IS_REF(expr_ptr)) {
			zval *new_expr;

			ALLOC_ZVAL(new_expr);
			INIT_PZVAL_COPY(new_expr, expr_ptr);
			expr_ptr = new_expr;
			zendi_zval_copy_ctor(*expr_ptr);
		} else {
			expr_ptr->refcount++;
		}
	}
	if (offset) {
		switch (Z_TYPE_P(offset)) {
			case IS_DOUBLE:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_LONG:
			case IS_BOOL:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), Z_LVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_STRING:
				zend_symtable_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_NULL:
				zend_hash_update(Z_ARRVAL_P(array_ptr), "", sizeof(""), &expr_ptr, sizeof(zval *), NULL);
				break;
			default:
				zend_error(E_WARNING, "Illegal offset type");
				zval_ptr_dtor(&expr_ptr);
				/* do nothing */
				break;
		}
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	} else {
		zend_hash_next_index_insert(Z_ARRVAL_P(array_ptr), &expr_ptr, sizeof(zval *), NULL);
	}
	if (opline->extended_value) {

	} else {

	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_ARRAY_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	array_init(&EX_T(opline->result.u.var).tmp_var);
	if (IS_CONST == IS_UNUSED) {
		ZEND_VM_NEXT_OPCODE();
#if 0 || IS_CONST != IS_UNUSED
	} else {
		return ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
#endif
	}
}

static int ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval *array_ptr = &EX_T(opline->result.u.var).tmp_var;
	zval *expr_ptr;
	zval *offset=NULL;

#if 0 || IS_CONST == IS_VAR || IS_CONST == IS_CV
	zval **expr_ptr_ptr = NULL;

	if (opline->extended_value) {
		expr_ptr_ptr=NULL;
		expr_ptr = *expr_ptr_ptr;
	} else {
		expr_ptr=&opline->op1.u.constant;
	}
#else
	expr_ptr=&opline->op1.u.constant;
#endif

	if (0) { /* temporary variable */
		zval *new_expr;

		ALLOC_ZVAL(new_expr);
		INIT_PZVAL_COPY(new_expr, expr_ptr);
		expr_ptr = new_expr;
	} else {
#if 0 || IS_CONST == IS_VAR || IS_CONST == IS_CV
		if (opline->extended_value) {
			SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr_ptr);
			expr_ptr = *expr_ptr_ptr;
			expr_ptr->refcount++;
		} else
#endif
		if (PZVAL_IS_REF(expr_ptr)) {
			zval *new_expr;

			ALLOC_ZVAL(new_expr);
			INIT_PZVAL_COPY(new_expr, expr_ptr);
			expr_ptr = new_expr;
			zendi_zval_copy_ctor(*expr_ptr);
		} else {
			expr_ptr->refcount++;
		}
	}
	if (offset) {
		switch (Z_TYPE_P(offset)) {
			case IS_DOUBLE:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_LONG:
			case IS_BOOL:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), Z_LVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_STRING:
				zend_symtable_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_NULL:
				zend_hash_update(Z_ARRVAL_P(array_ptr), "", sizeof(""), &expr_ptr, sizeof(zval *), NULL);
				break;
			default:
				zend_error(E_WARNING, "Illegal offset type");
				zval_ptr_dtor(&expr_ptr);
				/* do nothing */
				break;
		}

	} else {
		zend_hash_next_index_insert(Z_ARRVAL_P(array_ptr), &expr_ptr, sizeof(zval *), NULL);
	}
	if (opline->extended_value) {

	} else {

	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_ARRAY_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	array_init(&EX_T(opline->result.u.var).tmp_var);
	if (IS_CONST == IS_UNUSED) {
		ZEND_VM_NEXT_OPCODE();
#if 0 || IS_CONST != IS_UNUSED
	} else {
		return ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
#endif
	}
}

static int ZEND_ADD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	add_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SUB_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	sub_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_MUL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	mul_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_DIV_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	div_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_MOD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	mod_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	shift_left_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SR_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	shift_right_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CONCAT_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	concat_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_IDENTICAL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	is_identical_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_NOT_IDENTICAL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	is_not_identical_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_EQUAL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	is_equal_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_NOT_EQUAL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	is_not_equal_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_SMALLER_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	is_smaller_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	is_smaller_or_equal_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_OR_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	bitwise_or_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_AND_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	bitwise_and_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_XOR_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	bitwise_xor_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BOOL_XOR_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	boolean_xor_function(&EX_T(opline->result.u.var).tmp_var,
		&opline->op1.u.constant,
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CASE_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	int switch_expr_is_overloaded=0;


	if (IS_CONST==IS_VAR) {
		if (EX_T(opline->op1.u.var).var.ptr_ptr) {
			PZVAL_LOCK(EX_T(opline->op1.u.var).var.ptr);
		} else {
			switch_expr_is_overloaded = 1;
			EX_T(opline->op1.u.var).str_offset.str->refcount++;
		}
	}
	is_equal_function(&EX_T(opline->result.u.var).tmp_var,
				 &opline->op1.u.constant,
				 _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);

	if (switch_expr_is_overloaded) {
		/* We only free op1 if this is a string offset,
		 * Since if it is a TMP_VAR, it'll be reused by
		 * other CASE opcodes (whereas string offsets
		 * are allocated at each get_zval_ptr())
		 */

		EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
		AI_USE_PTR(EX_T(opline->op1.u.var).var);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval *array_ptr = &EX_T(opline->result.u.var).tmp_var;
	zval *expr_ptr;
	zval *offset=_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

#if 0 || IS_CONST == IS_VAR || IS_CONST == IS_CV
	zval **expr_ptr_ptr = NULL;

	if (opline->extended_value) {
		expr_ptr_ptr=NULL;
		expr_ptr = *expr_ptr_ptr;
	} else {
		expr_ptr=&opline->op1.u.constant;
	}
#else
	expr_ptr=&opline->op1.u.constant;
#endif

	if (0) { /* temporary variable */
		zval *new_expr;

		ALLOC_ZVAL(new_expr);
		INIT_PZVAL_COPY(new_expr, expr_ptr);
		expr_ptr = new_expr;
	} else {
#if 0 || IS_CONST == IS_VAR || IS_CONST == IS_CV
		if (opline->extended_value) {
			SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr_ptr);
			expr_ptr = *expr_ptr_ptr;
			expr_ptr->refcount++;
		} else
#endif
		if (PZVAL_IS_REF(expr_ptr)) {
			zval *new_expr;

			ALLOC_ZVAL(new_expr);
			INIT_PZVAL_COPY(new_expr, expr_ptr);
			expr_ptr = new_expr;
			zendi_zval_copy_ctor(*expr_ptr);
		} else {
			expr_ptr->refcount++;
		}
	}
	if (offset) {
		switch (Z_TYPE_P(offset)) {
			case IS_DOUBLE:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_LONG:
			case IS_BOOL:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), Z_LVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_STRING:
				zend_symtable_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_NULL:
				zend_hash_update(Z_ARRVAL_P(array_ptr), "", sizeof(""), &expr_ptr, sizeof(zval *), NULL);
				break;
			default:
				zend_error(E_WARNING, "Illegal offset type");
				zval_ptr_dtor(&expr_ptr);
				/* do nothing */
				break;
		}

	} else {
		zend_hash_next_index_insert(Z_ARRVAL_P(array_ptr), &expr_ptr, sizeof(zval *), NULL);
	}
	if (opline->extended_value) {

	} else {

	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_ARRAY_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	array_init(&EX_T(opline->result.u.var).tmp_var);
	if (IS_CONST == IS_UNUSED) {
		ZEND_VM_NEXT_OPCODE();
#if 0 || IS_CONST != IS_UNUSED
	} else {
		return ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
#endif
	}
}

static int ZEND_BW_NOT_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	bitwise_not_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BOOL_NOT_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	boolean_not_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ECHO_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval z_copy;
	zval *z = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

	if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL &&
		zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
		zend_print_variable(&z_copy);
		zval_dtor(&z_copy);
	} else {
		zend_print_variable(z);
	}

	zval_dtor(free_op1.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_PRINT_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 1;
	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_LONG;

	return ZEND_ECHO_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_fetch_var_address_helper_SPEC_TMP(int type, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *varname = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval **retval;
	zval tmp_varname;
	HashTable *target_symbol_table;

 	if (Z_TYPE_P(varname) != IS_STRING) {
		tmp_varname = *varname;
		zval_copy_ctor(&tmp_varname);
		convert_to_string(&tmp_varname);
		varname = &tmp_varname;
	}

	if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
		retval = zend_std_get_static_property(EX_T(opline->op2.u.var).class_entry, Z_STRVAL_P(varname), Z_STRLEN_P(varname), 0 TSRMLS_CC);
		zval_dtor(free_op1.var);
	} else {
		target_symbol_table = zend_get_target_symbol_table(opline, EX(Ts), type, varname TSRMLS_CC);
/*
		if (!target_symbol_table) {
			ZEND_VM_NEXT_OPCODE();
		}
*/
		if (zend_hash_find(target_symbol_table, varname->value.str.val, varname->value.str.len+1, (void **) &retval) == FAILURE) {
			switch (type) {
				case BP_VAR_R:
				case BP_VAR_UNSET:
					zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
					/* break missing intentionally */
				case BP_VAR_IS:
					retval = &EG(uninitialized_zval_ptr);
					break;
				case BP_VAR_RW:
					zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
					/* break missing intentionally */
				case BP_VAR_W: {
						zval *new_zval = &EG(uninitialized_zval);

						new_zval->refcount++;
						zend_hash_update(target_symbol_table, varname->value.str.val, varname->value.str.len+1, &new_zval, sizeof(zval *), (void **) &retval);
					}
					break;
				EMPTY_SWITCH_DEFAULT_CASE()
			}
		}
		switch (opline->op2.u.EA.type) {
			case ZEND_FETCH_GLOBAL:
				if (IS_TMP_VAR != IS_TMP_VAR) {
					zval_dtor(free_op1.var);
				}
				break;
			case ZEND_FETCH_LOCAL:
				zval_dtor(free_op1.var);
				break;
			case ZEND_FETCH_STATIC:
				zval_update_constant(retval, (void*) 1 TSRMLS_CC);
				break;
			case ZEND_FETCH_GLOBAL_LOCK:
				if (IS_TMP_VAR == IS_VAR && !free_op1.var) {
					PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
				}
				break;
		}
	}


	if (varname == &tmp_varname) {
		zval_dtor(varname);
	}
	if (!RETURN_VALUE_UNUSED(&opline->result)) {
		EX_T(opline->result.u.var).var.ptr_ptr = retval;
		PZVAL_LOCK(*retval);
		switch (type) {
			case BP_VAR_R:
			case BP_VAR_IS:
				AI_USE_PTR(EX_T(opline->result.u.var).var);
				break;
			case BP_VAR_UNSET: {
				zend_free_op free_res;

				PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &free_res);
				if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
					SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
				}
				PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
				FREE_OP_VAR_PTR(free_res);
				break;
			}
		}
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_R_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_var_address_helper_SPEC_TMP(BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_W_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_var_address_helper_SPEC_TMP(BP_VAR_W, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_RW_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_var_address_helper_SPEC_TMP(BP_VAR_RW, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_FUNC_ARG_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_var_address_helper_SPEC_TMP(ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), EX(opline)->extended_value)?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_UNSET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_var_address_helper_SPEC_TMP(BP_VAR_UNSET, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_IS_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_var_address_helper_SPEC_TMP(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_JMPZ_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	int ret = i_zend_is_true(_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC));

	zval_dtor(free_op1.var);
	if (!ret) {
#if DEBUG_ZEND>=2
		printf("Conditional jmp to %d\n", opline->op2.u.opline_num);
#endif
		ZEND_VM_JMP(opline->op2.u.jmp_addr);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_JMPNZ_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	int ret = i_zend_is_true(_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC));

	zval_dtor(free_op1.var);
	if (ret) {
#if DEBUG_ZEND>=2
		printf("Conditional jmp to %d\n", opline->op2.u.opline_num);
#endif
		ZEND_VM_JMP(opline->op2.u.jmp_addr);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_JMPZNZ_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	int retval = i_zend_is_true(_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC));

	zval_dtor(free_op1.var);
	if (retval) {
#if DEBUG_ZEND>=2
		printf("Conditional jmp on true to %d\n", opline->extended_value);
#endif
		ZEND_VM_JMP(&EX(op_array)->opcodes[opline->extended_value]);
	} else {
#if DEBUG_ZEND>=2
		printf("Conditional jmp on false to %d\n", opline->op2.u.opline_num);
#endif
		ZEND_VM_JMP(&EX(op_array)->opcodes[opline->op2.u.opline_num]);
	}
}

static int ZEND_JMPZ_EX_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	int retval = i_zend_is_true(_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC));

	zval_dtor(free_op1.var);
	Z_LVAL(EX_T(opline->result.u.var).tmp_var) = retval;
	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
	if (!retval) {
#if DEBUG_ZEND>=2
		printf("Conditional jmp to %d\n", opline->op2.u.opline_num);
#endif
		ZEND_VM_JMP(opline->op2.u.jmp_addr);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_JMPNZ_EX_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	int retval = i_zend_is_true(_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC));

	zval_dtor(free_op1.var);
	Z_LVAL(EX_T(opline->result.u.var).tmp_var) = retval;
	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
	if (retval) {
#if DEBUG_ZEND>=2
		printf("Conditional jmp to %d\n", opline->op2.u.opline_num);
#endif
		ZEND_VM_JMP(opline->op2.u.jmp_addr);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FREE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zendi_zval_dtor(EX_T(EX(opline)->op1.u.var).tmp_var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *retval_ptr;
	zval **retval_ptr_ptr;
	zend_free_op free_op1;

	if (EG(active_op_array)->return_reference == ZEND_RETURN_REF) {

		if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) {
			/* Not supposed to happen, but we'll allow it */
			zend_error(E_NOTICE, "Only variable references should be returned by reference");
			goto return_by_value;
		}

		retval_ptr_ptr = NULL;

		if (!retval_ptr_ptr) {
			zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
		}

		if (IS_TMP_VAR == IS_VAR && !(*retval_ptr_ptr)->is_ref) {
			if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
			    EX_T(opline->op1.u.var).var.fcall_returned_reference) {
			} else if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
				if (IS_TMP_VAR == IS_VAR && !1) {
					PZVAL_LOCK(*retval_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
				}
				zend_error(E_NOTICE, "Only variable references should be returned by reference");
				goto return_by_value;
			}
		}

		SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr_ptr);
		(*retval_ptr_ptr)->refcount++;

		(*EG(return_value_ptr_ptr)) = (*retval_ptr_ptr);
	} else {
return_by_value:

		retval_ptr = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

		if (EG(ze1_compatibility_mode) && Z_TYPE_P(retval_ptr) == IS_OBJECT) {
			zval *ret;
			char *class_name;
			zend_uint class_name_len;
			int dup;

			ALLOC_ZVAL(ret);
			INIT_PZVAL_COPY(ret, retval_ptr);
			dup = zend_get_object_classname(retval_ptr, &class_name, &class_name_len TSRMLS_CC);
			if (Z_OBJ_HT_P(retval_ptr)->clone_obj == NULL) {
				zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s",  class_name);
			}
			zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name);
			ret->value.obj = Z_OBJ_HT_P(retval_ptr)->clone_obj(retval_ptr TSRMLS_CC);
			*EG(return_value_ptr_ptr) = ret;
			if (!dup) {
				efree(class_name);
			}
		} else if (!1) { /* Not a temp var */
			if (EG(active_op_array)->return_reference == ZEND_RETURN_REF ||
			    (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0)) {
				zval *ret;

				ALLOC_ZVAL(ret);
				INIT_PZVAL_COPY(ret, retval_ptr);
				zval_copy_ctor(ret);
				*EG(return_value_ptr_ptr) = ret;
			} else if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) &&
			           retval_ptr == &EG(uninitialized_zval)) {
				zval *ret;

				ALLOC_INIT_ZVAL(ret);
				*EG(return_value_ptr_ptr) = ret;
			} else {
				*EG(return_value_ptr_ptr) = retval_ptr;
				retval_ptr->refcount++;
			}
		} else {
			zval *ret;

			ALLOC_ZVAL(ret);
			INIT_PZVAL_COPY(ret, retval_ptr);
			*EG(return_value_ptr_ptr) = ret;
		}
	}

	ZEND_VM_RETURN_FROM_EXECUTE_LOOP();
}

static int ZEND_THROW_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *value;
	zval *exception;
	zend_free_op free_op1;

	value = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

	if (Z_TYPE_P(value) != IS_OBJECT) {
		zend_error_noreturn(E_ERROR, "Can only throw objects");
	}
	/* Not sure if a complete copy is what we want here */
	ALLOC_ZVAL(exception);
	INIT_PZVAL_COPY(exception, value);
	if (!1) {
		zval_copy_ctor(exception);
	}

	zend_throw_exception_object(exception TSRMLS_CC);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SEND_VAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	if (opline->extended_value==ZEND_DO_FCALL_BY_NAME
		&& ARG_MUST_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
			zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.u.opline_num);
	}
	{
		zval *valptr;
		zval *value;
		zend_free_op free_op1;

		value = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

		ALLOC_ZVAL(valptr);
		INIT_PZVAL_COPY(valptr, value);
		if (!1) {
			zval_copy_ctor(valptr);
		}
		zend_ptr_stack_push(&EG(argument_stack), valptr);

	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BOOL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	/* PHP 3.0 returned "" for false and 1 for true, here we use 0 and 1 for now */
	Z_LVAL(EX_T(opline->result.u.var).tmp_var) = i_zend_is_true(_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC));
	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SWITCH_FREE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_switch_free(EX(opline), EX(Ts) TSRMLS_CC);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CLONE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *obj = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zend_class_entry *ce;
	zend_function *clone;
	zend_object_clone_obj_t clone_call;

	if (!obj || Z_TYPE_P(obj) != IS_OBJECT) {
		zend_error_noreturn(E_ERROR, "__clone method called on non-object");
		EX_T(opline->result.u.var).var.ptr = EG(error_zval_ptr);
		EX_T(opline->result.u.var).var.ptr->refcount++;

		ZEND_VM_NEXT_OPCODE();
	}

	ce = Z_OBJCE_P(obj);
	clone = ce ? ce->clone : NULL;
	clone_call =  Z_OBJ_HT_P(obj)->clone_obj;
	if (!clone_call) {
		if (ce) {
			zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", ce->name);
		} else {
			zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object");
		}
		EX_T(opline->result.u.var).var.ptr = EG(error_zval_ptr);
		EX_T(opline->result.u.var).var.ptr->refcount++;
	}

	if (ce && clone) {
		if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) {
			/* Ensure that if we're calling a private function, we're allowed to do so.
			 */
			if (ce != EG(scope)) {
				zend_error_noreturn(E_ERROR, "Call to private %s::__clone() from context '%s'", ce->name, EG(scope) ? EG(scope)->name : "");
			}
		} else if ((clone->common.fn_flags & ZEND_ACC_PROTECTED)) {
			/* Ensure that if we're calling a protected function, we're allowed to do so.
			 */
			if (!zend_check_protected(clone->common.scope, EG(scope))) {
				zend_error_noreturn(E_ERROR, "Call to protected %s::__clone() from context '%s'", ce->name, EG(scope) ? EG(scope)->name : "");
			}
		}
	}

	EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
	if (!EG(exception)) {
		ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
		Z_OBJVAL_P(EX_T(opline->result.u.var).var.ptr) = clone_call(obj TSRMLS_CC);
		Z_TYPE_P(EX_T(opline->result.u.var).var.ptr) = IS_OBJECT;
		EX_T(opline->result.u.var).var.ptr->refcount=1;
		EX_T(opline->result.u.var).var.ptr->is_ref=1;
		if (!RETURN_VALUE_USED(opline) || EG(exception)) {
			zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CAST_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *expr = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval *result = &EX_T(opline->result.u.var).tmp_var;

	if (opline->extended_value != IS_STRING) {
		*result = *expr;
		if (!1) {
			zendi_zval_copy_ctor(*result);
		}
	}
	switch (opline->extended_value) {
		case IS_NULL:
			convert_to_null(result);
			break;
		case IS_BOOL:
			convert_to_boolean(result);
			break;
		case IS_LONG:
			convert_to_long(result);
			break;
		case IS_DOUBLE:
			convert_to_double(result);
			break;
		case IS_STRING: {
			zval var_copy;
			int use_copy;

			zend_make_printable_zval(expr, &var_copy, &use_copy);
			if (use_copy) {
				*result = var_copy;
				if (1) {
					zval_dtor(free_op1.var);
				}
			} else {
				*result = *expr;
				if (!1) {
					zendi_zval_copy_ctor(*result);
				}
			}
			break;
		}
		case IS_ARRAY:
			convert_to_array(result);
			break;
		case IS_OBJECT:
			convert_to_object(result);
			break;
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op_array *new_op_array=NULL;
	zval **original_return_value = EG(return_value_ptr_ptr);
	int return_value_used;
	zend_free_op free_op1;
	zval *inc_filename = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval tmp_inc_filename;
	zend_bool failure_retval=0;

	if (inc_filename->type!=IS_STRING) {
		tmp_inc_filename = *inc_filename;
		zval_copy_ctor(&tmp_inc_filename);
		convert_to_string(&tmp_inc_filename);
		inc_filename = &tmp_inc_filename;
	}

	return_value_used = RETURN_VALUE_USED(opline);

	switch (Z_LVAL(opline->op2.u.constant)) {
		case ZEND_INCLUDE_ONCE:
		case ZEND_REQUIRE_ONCE: {
				zend_file_handle file_handle;

				if (IS_ABSOLUTE_PATH(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename))) {
					cwd_state state;

					state.cwd_length = 0;
					state.cwd = malloc(1);
					state.cwd[0] = 0;

					failure_retval = (!virtual_file_ex(&state, Z_STRVAL_P(inc_filename), NULL, 1) &&
						zend_hash_exists(&EG(included_files), state.cwd, state.cwd_length+1));

					free(state.cwd);
				}

				if (failure_retval) {
					/* do nothing */
				} else if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) {

					if (!file_handle.opened_path) {
						file_handle.opened_path = estrndup(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename));
					}

					if (zend_hash_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1)==SUCCESS) {
						new_op_array = zend_compile_file(&file_handle, (Z_LVAL(opline->op2.u.constant)==ZEND_INCLUDE_ONCE?ZEND_INCLUDE:ZEND_REQUIRE) TSRMLS_CC);
						zend_destroy_file_handle(&file_handle TSRMLS_CC);
					} else {
						zend_file_handle_dtor(&file_handle);
						failure_retval=1;
					}
				} else {
					if (Z_LVAL(opline->op2.u.constant)==ZEND_INCLUDE_ONCE) {
						zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, Z_STRVAL_P(inc_filename));
					} else {
						zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename));
					}
				}
			}
			break;
		case ZEND_INCLUDE:
		case ZEND_REQUIRE:
			new_op_array = compile_filename(Z_LVAL(opline->op2.u.constant), inc_filename TSRMLS_CC);
			break;
		case ZEND_EVAL: {
				char *eval_desc = zend_make_compiled_string_description("eval()'d code" TSRMLS_CC);

				new_op_array = zend_compile_string(inc_filename, eval_desc TSRMLS_CC);
				efree(eval_desc);
			}
			break;
		EMPTY_SWITCH_DEFAULT_CASE()
	}
	if (inc_filename==&tmp_inc_filename) {
		zval_dtor(&tmp_inc_filename);
	}
	EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
	if (new_op_array) {
		zval *saved_object;
		zend_function *saved_function;

		EG(return_value_ptr_ptr) = EX_T(opline->result.u.var).var.ptr_ptr;
		EG(active_op_array) = new_op_array;
		EX_T(opline->result.u.var).var.ptr = NULL;

		saved_object = EX(object);
		saved_function = EX(function_state).function;

		EX(function_state).function = (zend_function *) new_op_array;
		EX(object) = NULL;

		zend_execute(new_op_array TSRMLS_CC);

		EX(function_state).function = saved_function;
		EX(object) = saved_object;

		if (!return_value_used) {
			if (EX_T(opline->result.u.var).var.ptr) {
				zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
			}
		} else { /* return value is used */
			if (!EX_T(opline->result.u.var).var.ptr) { /* there was no return statement */
				ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
				INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);
				Z_LVAL_P(EX_T(opline->result.u.var).var.ptr) = 1;
				Z_TYPE_P(EX_T(opline->result.u.var).var.ptr) = IS_BOOL;
			}
		}

		EG(opline_ptr) = &EX(opline);
		EG(active_op_array) = EX(op_array);
		EG(function_state_ptr) = &EX(function_state);
		destroy_op_array(new_op_array TSRMLS_CC);
		efree(new_op_array);
		if (EG(exception)) {
			zend_throw_exception_internal(NULL TSRMLS_CC);
		}
	} else {
		if (return_value_used) {
			ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
			INIT_ZVAL(*EX_T(opline->result.u.var).var.ptr);
			Z_LVAL_P(EX_T(opline->result.u.var).var.ptr) = failure_retval;
			Z_TYPE_P(EX_T(opline->result.u.var).var.ptr) = IS_BOOL;
		}
	}
	zval_dtor(free_op1.var);
	EG(return_value_ptr_ptr) = original_return_value;
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_UNSET_VAR_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval tmp, *varname;
	HashTable *target_symbol_table;
	zend_free_op free_op1;

	varname = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

	if (Z_TYPE_P(varname) != IS_STRING) {
		tmp = *varname;
		zval_copy_ctor(&tmp);
		convert_to_string(&tmp);
		varname = &tmp;
	} else if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
		varname->refcount++;
	}

	if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
		zend_std_unset_static_property(EX_T(opline->op2.u.var).class_entry, Z_STRVAL_P(varname), Z_STRLEN_P(varname) TSRMLS_CC);
	} else {
		target_symbol_table = zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
		if (zend_hash_del(target_symbol_table, varname->value.str.val, varname->value.str.len+1) == SUCCESS) {
			zend_execute_data *ex = execute_data;
			ulong hash_value = zend_inline_hash_func(varname->value.str.val, varname->value.str.len+1);

			do {
				int i;

				if (ex->op_array) {
					for (i = 0; i < ex->op_array->last_var; i++) {
						if (ex->op_array->vars[i].hash_value == hash_value &&
							ex->op_array->vars[i].name_len == varname->value.str.len &&
							!memcmp(ex->op_array->vars[i].name, varname->value.str.val, varname->value.str.len)) {
							ex->CVs[i] = NULL;
							break;
						}
					}
				}
				ex = ex->prev_execute_data;
			} while (ex && ex->symbol_table == target_symbol_table);
		}
	}

	if (varname == &tmp) {
		zval_dtor(&tmp);
	} else if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
		zval_ptr_dtor(&varname);
	}
	zval_dtor(free_op1.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *array_ptr, **array_ptr_ptr;
	HashTable *fe_ht;
	zend_object_iterator *iter = NULL;
	zend_class_entry *ce = NULL;
	zend_bool is_empty = 0;

	if (opline->extended_value & ZEND_FE_RESET_VARIABLE) {
		array_ptr_ptr = NULL;
		if (array_ptr_ptr == NULL || array_ptr_ptr == &EG(uninitialized_zval_ptr)) {
			ALLOC_INIT_ZVAL(array_ptr);
		} else if (Z_TYPE_PP(array_ptr_ptr) == IS_OBJECT) {
			if(Z_OBJ_HT_PP(array_ptr_ptr)->get_class_entry == NULL) {
				zend_error(E_WARNING, "foreach() can not iterate over objects without PHP class");
				ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.u.opline_num);
			}

			ce = Z_OBJCE_PP(array_ptr_ptr);
			if (!ce || ce->get_iterator == NULL) {
				SEPARATE_ZVAL_IF_NOT_REF(array_ptr_ptr);
				(*array_ptr_ptr)->refcount++;
			}
			array_ptr = *array_ptr_ptr;
		} else {
			if (Z_TYPE_PP(array_ptr_ptr) == IS_ARRAY) {
				SEPARATE_ZVAL_IF_NOT_REF(array_ptr_ptr);
				if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
					(*array_ptr_ptr)->is_ref = 1;
				}
			}
			array_ptr = *array_ptr_ptr;
			array_ptr->refcount++;
		}
	} else {
		array_ptr = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
		if (1) { /* IS_TMP_VAR */
			zval *tmp;

			ALLOC_ZVAL(tmp);
			INIT_PZVAL_COPY(tmp, array_ptr);
			array_ptr = tmp;
			if (Z_TYPE_P(array_ptr) == IS_OBJECT) {
				ce = Z_OBJCE_P(array_ptr);
				if (ce && ce->get_iterator) {
					array_ptr->refcount--;
				}
			}
		} else if (Z_TYPE_P(array_ptr) == IS_OBJECT) {
			ce = Z_OBJCE_P(array_ptr);
			if (!ce || !ce->get_iterator) {
				array_ptr->refcount++;
			}
		} else {
			if (IS_TMP_VAR == IS_CONST ||
			    ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) &&
			    !array_ptr->is_ref &&
			    array_ptr->refcount > 1)) {
				zval *tmp;

				ALLOC_ZVAL(tmp);
				INIT_PZVAL_COPY(tmp, array_ptr);
				zval_copy_ctor(tmp);
				array_ptr = tmp;
			} else {
				array_ptr->refcount++;
			}
		}
	}

	if (ce && ce->get_iterator) {
		iter = ce->get_iterator(ce, array_ptr, opline->extended_value & ZEND_FE_RESET_REFERENCE TSRMLS_CC);

		if (iter && !EG(exception)) {
			array_ptr = zend_iterator_wrap(iter TSRMLS_CC);
		} else {
			if (opline->extended_value & ZEND_FE_RESET_VARIABLE) {

			} else {

			}
			if (!EG(exception)) {
				zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Object of type %s did not create an Iterator", ce->name);
			}
			zend_throw_exception_internal(NULL TSRMLS_CC);
			ZEND_VM_NEXT_OPCODE();
		}
	}

	PZVAL_LOCK(array_ptr);
	EX_T(opline->result.u.var).var.ptr = array_ptr;
	EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;

	if (iter) {
		iter->index = 0;
		if (iter->funcs->rewind) {
			iter->funcs->rewind(iter TSRMLS_CC);
			if (EG(exception)) {
				array_ptr->refcount--;
				zval_ptr_dtor(&array_ptr);
				if (opline->extended_value & ZEND_FE_RESET_VARIABLE) {

				} else {

				}
				ZEND_VM_NEXT_OPCODE();
			}
		}
		is_empty = iter->funcs->valid(iter TSRMLS_CC) != SUCCESS;
		if (EG(exception)) {
			array_ptr->refcount--;
			zval_ptr_dtor(&array_ptr);
			if (opline->extended_value & ZEND_FE_RESET_VARIABLE) {

			} else {

			}
			ZEND_VM_NEXT_OPCODE();
		}
		iter->index = -1; /* will be set to 0 before using next handler */
	} else if ((fe_ht = HASH_OF(array_ptr)) != NULL) {
		zend_hash_internal_pointer_reset(fe_ht);
		if (ce) {
			zend_object *zobj = zend_objects_get_address(array_ptr TSRMLS_CC);
			while (zend_hash_has_more_elements(fe_ht) == SUCCESS) {
				char *str_key;
				uint str_key_len;
				ulong int_key;
				zend_uchar key_type;

				key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 0, NULL);
				if (key_type != HASH_KEY_NON_EXISTANT &&
					(key_type == HASH_KEY_IS_LONG ||
				     zend_check_property_access(zobj, str_key, str_key_len-1 TSRMLS_CC) == SUCCESS)) {
					break;
				}
				zend_hash_move_forward(fe_ht);
			}
		}
		is_empty = zend_hash_has_more_elements(fe_ht) != SUCCESS;
		zend_hash_get_pointer(fe_ht, &EX_T(opline->result.u.var).fe.fe_pos);
	} else {
		zend_error(E_WARNING, "Invalid argument supplied for foreach()");
		is_empty = 1;
	}

	if (opline->extended_value & ZEND_FE_RESET_VARIABLE) {

	} else {

	}
	if (is_empty) {
		ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.u.opline_num);
	} else {
		ZEND_VM_NEXT_OPCODE();
	}
}

static int ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval tmp, *varname = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval **value;
	zend_bool isset = 1;
	HashTable *target_symbol_table;

	if (Z_TYPE_P(varname) != IS_STRING) {
		tmp = *varname;
		zval_copy_ctor(&tmp);
		convert_to_string(&tmp);
		varname = &tmp;
	}

	if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
		value = zend_std_get_static_property(EX_T(opline->op2.u.var).class_entry, Z_STRVAL_P(varname), Z_STRLEN_P(varname), 1 TSRMLS_CC);
		if (!value) {
			isset = 0;
		}
	} else {
		target_symbol_table = zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
		if (zend_hash_find(target_symbol_table, varname->value.str.val, varname->value.str.len+1, (void **) &value) == FAILURE) {
			isset = 0;
		}
	}

	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;

	switch (opline->extended_value) {
		case ZEND_ISSET:
			if (isset && Z_TYPE_PP(value) == IS_NULL) {
				Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 0;
			} else {
				Z_LVAL(EX_T(opline->result.u.var).tmp_var) = isset;
			}
			break;
		case ZEND_ISEMPTY:
			if (!isset || !i_zend_is_true(*value)) {
				Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 1;
			} else {
				Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 0;
			}
			break;
	}

	if (varname == &tmp) {
		zval_dtor(&tmp);
	}
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_EXIT_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
#if 0 || (IS_TMP_VAR != IS_UNUSED)
	zend_op *opline = EX(opline);
	if (IS_TMP_VAR != IS_UNUSED) {
		zend_free_op free_op1;
		zval *ptr = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

		if (Z_TYPE_P(ptr) == IS_LONG) {
			EG(exit_status) = Z_LVAL_P(ptr);
		} else {
			zend_print_variable(ptr);
		}
		zval_dtor(free_op1.var);
	}
#endif
	zend_bailout();
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_END_SILENCE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval restored_error_reporting;

	if (!EG(error_reporting) && Z_LVAL(EX_T(opline->op1.u.var).tmp_var) != 0) {
		Z_TYPE(restored_error_reporting) = IS_LONG;
		Z_LVAL(restored_error_reporting) = Z_LVAL(EX_T(opline->op1.u.var).tmp_var);
		convert_to_string(&restored_error_reporting);
		zend_alter_ini_entry_ex("error_reporting", sizeof("error_reporting"), Z_STRVAL(restored_error_reporting), Z_STRLEN(restored_error_reporting), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME, 1);
		zendi_zval_dtor(restored_error_reporting);
	}
	if (EX(old_error_reporting) == &EX_T(opline->op1.u.var).tmp_var) {
		EX(old_error_reporting) = NULL;
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_QM_ASSIGN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *value = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

	EX_T(opline->result.u.var).tmp_var = *value;
	if (!1) {
		zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INSTANCEOF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *expr = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zend_bool result;

	if (Z_TYPE_P(expr) == IS_OBJECT && Z_OBJ_HT_P(expr)->get_class_entry) {
		result = instanceof_function(Z_OBJCE_P(expr), EX_T(opline->op2.u.var).class_entry TSRMLS_CC);
	} else {
		result = 0;
	}
	ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, result);
	zval_dtor(free_op1.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ADD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	add_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SUB_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	sub_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_MUL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	mul_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_DIV_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	div_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_MOD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	mod_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	shift_left_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	shift_right_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CONCAT_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	concat_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_IDENTICAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	is_identical_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	is_not_identical_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_EQUAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	is_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	is_not_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_SMALLER_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	is_smaller_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	is_smaller_or_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_OR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	bitwise_or_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_AND_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	bitwise_and_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_XOR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	bitwise_xor_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BOOL_XOR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	boolean_xor_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_TMP_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *container = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

	if (Z_TYPE_P(container) != IS_ARRAY) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
		}
	} else {

		zval *dim = &opline->op2.u.constant;

		EX_T(opline->result.u.var).var.ptr_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, BP_VAR_R TSRMLS_CC);
		SELECTIVE_PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &opline->result);

	}
	AI_USE_PTR(EX_T(opline->result.u.var).var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ADD_CHAR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	add_char_to_string(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant);
	/* FREE_OP is missing intentionally here - we're always working on the same temporary variable */
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ADD_STRING_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	add_string_to_string(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant);
	/* FREE_OP is missing intentionally here - we're always working on the same temporary variable */
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *function_name;
	char *function_name_strval;
	int function_name_strlen;
	zend_free_op free_op1;

	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), NULL);

	function_name = &opline->op2.u.constant;

	if (Z_TYPE_P(function_name)!=IS_STRING) {
		zend_error_noreturn(E_ERROR, "Method name must be a string");
	}

	function_name_strval = Z_STRVAL_P(function_name);
	function_name_strlen = Z_STRLEN_P(function_name);

	EX(object) = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

	if (EX(object) && Z_TYPE_P(EX(object)) == IS_OBJECT) {
		if (Z_OBJ_HT_P(EX(object))->get_method == NULL) {
			zend_error_noreturn(E_ERROR, "Object does not support method calls");
		}

		/* First, locate the function. */
		EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen TSRMLS_CC);
		if (!EX(fbc)) {
			zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
		}
	} else {
		zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
	}

	if (!EX(object) || (EX(fbc) && (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
		EX(object) = NULL;
	} else {
		if (!PZVAL_IS_REF(EX(object))) {
			EX(object)->refcount++; /* For $this pointer */
		} else {
			zval *this_ptr;
			ALLOC_ZVAL(this_ptr);
			INIT_PZVAL_COPY(this_ptr, EX(object));
			zval_copy_ctor(this_ptr);
			EX(object) = this_ptr;
		}
	}


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CASE_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	int switch_expr_is_overloaded=0;
	zend_free_op free_op1;

	if (IS_TMP_VAR==IS_VAR) {
		if (EX_T(opline->op1.u.var).var.ptr_ptr) {
			PZVAL_LOCK(EX_T(opline->op1.u.var).var.ptr);
		} else {
			switch_expr_is_overloaded = 1;
			EX_T(opline->op1.u.var).str_offset.str->refcount++;
		}
	}
	is_equal_function(&EX_T(opline->result.u.var).tmp_var,
				 _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
				 &opline->op2.u.constant TSRMLS_CC);

	if (switch_expr_is_overloaded) {
		/* We only free op1 if this is a string offset,
		 * Since if it is a TMP_VAR, it'll be reused by
		 * other CASE opcodes (whereas string offsets
		 * are allocated at each get_zval_ptr())
		 */
		zval_dtor(free_op1.var);
		EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
		AI_USE_PTR(EX_T(opline->op1.u.var).var);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *array_ptr = &EX_T(opline->result.u.var).tmp_var;
	zval *expr_ptr;
	zval *offset=&opline->op2.u.constant;

#if 0 || IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV
	zval **expr_ptr_ptr = NULL;

	if (opline->extended_value) {
		expr_ptr_ptr=NULL;
		expr_ptr = *expr_ptr_ptr;
	} else {
		expr_ptr=_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	}
#else
	expr_ptr=_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
#endif

	if (1) { /* temporary variable */
		zval *new_expr;

		ALLOC_ZVAL(new_expr);
		INIT_PZVAL_COPY(new_expr, expr_ptr);
		expr_ptr = new_expr;
	} else {
#if 0 || IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV
		if (opline->extended_value) {
			SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr_ptr);
			expr_ptr = *expr_ptr_ptr;
			expr_ptr->refcount++;
		} else
#endif
		if (PZVAL_IS_REF(expr_ptr)) {
			zval *new_expr;

			ALLOC_ZVAL(new_expr);
			INIT_PZVAL_COPY(new_expr, expr_ptr);
			expr_ptr = new_expr;
			zendi_zval_copy_ctor(*expr_ptr);
		} else {
			expr_ptr->refcount++;
		}
	}
	if (offset) {
		switch (Z_TYPE_P(offset)) {
			case IS_DOUBLE:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_LONG:
			case IS_BOOL:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), Z_LVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_STRING:
				zend_symtable_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_NULL:
				zend_hash_update(Z_ARRVAL_P(array_ptr), "", sizeof(""), &expr_ptr, sizeof(zval *), NULL);
				break;
			default:
				zend_error(E_WARNING, "Illegal offset type");
				zval_ptr_dtor(&expr_ptr);
				/* do nothing */
				break;
		}

	} else {
		zend_hash_next_index_insert(Z_ARRVAL_P(array_ptr), &expr_ptr, sizeof(zval *), NULL);
	}
	if (opline->extended_value) {

	} else {

	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_ARRAY_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	array_init(&EX_T(opline->result.u.var).tmp_var);
	if (IS_TMP_VAR == IS_UNUSED) {
		ZEND_VM_NEXT_OPCODE();
#if 0 || IS_TMP_VAR != IS_UNUSED
	} else {
		return ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
#endif
	}
}

static int ZEND_ADD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	add_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SUB_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	sub_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_MUL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	mul_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_DIV_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	div_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_MOD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	mod_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	shift_left_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	shift_right_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CONCAT_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	concat_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_IDENTICAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	is_identical_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_NOT_IDENTICAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	is_not_identical_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_EQUAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	is_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	is_not_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_SMALLER_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	is_smaller_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	is_smaller_or_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_OR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	bitwise_or_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_AND_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	bitwise_and_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_XOR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	bitwise_xor_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BOOL_XOR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	boolean_xor_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ADD_VAR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *var = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	zval var_copy;
	int use_copy = 0;

	if (Z_TYPE_P(var) != IS_STRING) {
		zend_make_printable_zval(var, &var_copy, &use_copy);

		if (use_copy) {
			var = &var_copy;
		}
	}
	add_string_to_string(	&EX_T(opline->result.u.var).tmp_var,
							_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
							var);
	if (use_copy) {
		zval_dtor(var);
	}
	/* original comment, possibly problematic:
	 * FREE_OP is missing intentionally here - we're always working on the same temporary variable
	 * (Zeev):  I don't think it's problematic, we only use variables
	 * which aren't affected by FREE_OP(Ts, )'s anyway, unless they're
	 * string offsets or overloaded objects
	 */
	zval_dtor(free_op2.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *function_name;
	char *function_name_strval;
	int function_name_strlen;
	zend_free_op free_op1, free_op2;

	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), NULL);

	function_name = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (Z_TYPE_P(function_name)!=IS_STRING) {
		zend_error_noreturn(E_ERROR, "Method name must be a string");
	}

	function_name_strval = Z_STRVAL_P(function_name);
	function_name_strlen = Z_STRLEN_P(function_name);

	EX(object) = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

	if (EX(object) && Z_TYPE_P(EX(object)) == IS_OBJECT) {
		if (Z_OBJ_HT_P(EX(object))->get_method == NULL) {
			zend_error_noreturn(E_ERROR, "Object does not support method calls");
		}

		/* First, locate the function. */
		EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen TSRMLS_CC);
		if (!EX(fbc)) {
			zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
		}
	} else {
		zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
	}

	if (!EX(object) || (EX(fbc) && (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
		EX(object) = NULL;
	} else {
		if (!PZVAL_IS_REF(EX(object))) {
			EX(object)->refcount++; /* For $this pointer */
		} else {
			zval *this_ptr;
			ALLOC_ZVAL(this_ptr);
			INIT_PZVAL_COPY(this_ptr, EX(object));
			zval_copy_ctor(this_ptr);
			EX(object) = this_ptr;
		}
	}

	zval_dtor(free_op2.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CASE_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	int switch_expr_is_overloaded=0;
	zend_free_op free_op1, free_op2;

	if (IS_TMP_VAR==IS_VAR) {
		if (EX_T(opline->op1.u.var).var.ptr_ptr) {
			PZVAL_LOCK(EX_T(opline->op1.u.var).var.ptr);
		} else {
			switch_expr_is_overloaded = 1;
			EX_T(opline->op1.u.var).str_offset.str->refcount++;
		}
	}
	is_equal_function(&EX_T(opline->result.u.var).tmp_var,
				 _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
				 _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	if (switch_expr_is_overloaded) {
		/* We only free op1 if this is a string offset,
		 * Since if it is a TMP_VAR, it'll be reused by
		 * other CASE opcodes (whereas string offsets
		 * are allocated at each get_zval_ptr())
		 */
		zval_dtor(free_op1.var);
		EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
		AI_USE_PTR(EX_T(opline->op1.u.var).var);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *array_ptr = &EX_T(opline->result.u.var).tmp_var;
	zval *expr_ptr;
	zval *offset=_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

#if 0 || IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV
	zval **expr_ptr_ptr = NULL;

	if (opline->extended_value) {
		expr_ptr_ptr=NULL;
		expr_ptr = *expr_ptr_ptr;
	} else {
		expr_ptr=_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	}
#else
	expr_ptr=_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
#endif

	if (1) { /* temporary variable */
		zval *new_expr;

		ALLOC_ZVAL(new_expr);
		INIT_PZVAL_COPY(new_expr, expr_ptr);
		expr_ptr = new_expr;
	} else {
#if 0 || IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV
		if (opline->extended_value) {
			SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr_ptr);
			expr_ptr = *expr_ptr_ptr;
			expr_ptr->refcount++;
		} else
#endif
		if (PZVAL_IS_REF(expr_ptr)) {
			zval *new_expr;

			ALLOC_ZVAL(new_expr);
			INIT_PZVAL_COPY(new_expr, expr_ptr);
			expr_ptr = new_expr;
			zendi_zval_copy_ctor(*expr_ptr);
		} else {
			expr_ptr->refcount++;
		}
	}
	if (offset) {
		switch (Z_TYPE_P(offset)) {
			case IS_DOUBLE:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_LONG:
			case IS_BOOL:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), Z_LVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_STRING:
				zend_symtable_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_NULL:
				zend_hash_update(Z_ARRVAL_P(array_ptr), "", sizeof(""), &expr_ptr, sizeof(zval *), NULL);
				break;
			default:
				zend_error(E_WARNING, "Illegal offset type");
				zval_ptr_dtor(&expr_ptr);
				/* do nothing */
				break;
		}
		zval_dtor(free_op2.var);
	} else {
		zend_hash_next_index_insert(Z_ARRVAL_P(array_ptr), &expr_ptr, sizeof(zval *), NULL);
	}
	if (opline->extended_value) {

	} else {

	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_ARRAY_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	array_init(&EX_T(opline->result.u.var).tmp_var);
	if (IS_TMP_VAR == IS_UNUSED) {
		ZEND_VM_NEXT_OPCODE();
#if 0 || IS_TMP_VAR != IS_UNUSED
	} else {
		return ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
#endif
	}
}

static int ZEND_ADD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	add_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SUB_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	sub_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_MUL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	mul_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_DIV_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	div_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_MOD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	mod_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	shift_left_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	shift_right_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CONCAT_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	concat_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_IDENTICAL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	is_identical_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_NOT_IDENTICAL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	is_not_identical_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_EQUAL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	is_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_NOT_EQUAL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	is_not_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_SMALLER_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	is_smaller_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	is_smaller_or_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_OR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	bitwise_or_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_AND_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	bitwise_and_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_XOR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	bitwise_xor_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BOOL_XOR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	boolean_xor_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ADD_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *var = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	zval var_copy;
	int use_copy = 0;

	if (Z_TYPE_P(var) != IS_STRING) {
		zend_make_printable_zval(var, &var_copy, &use_copy);

		if (use_copy) {
			var = &var_copy;
		}
	}
	add_string_to_string(	&EX_T(opline->result.u.var).tmp_var,
							_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
							var);
	if (use_copy) {
		zval_dtor(var);
	}
	/* original comment, possibly problematic:
	 * FREE_OP is missing intentionally here - we're always working on the same temporary variable
	 * (Zeev):  I don't think it's problematic, we only use variables
	 * which aren't affected by FREE_OP(Ts, )'s anyway, unless they're
	 * string offsets or overloaded objects
	 */
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_METHOD_CALL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *function_name;
	char *function_name_strval;
	int function_name_strlen;
	zend_free_op free_op1, free_op2;

	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), NULL);

	function_name = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (Z_TYPE_P(function_name)!=IS_STRING) {
		zend_error_noreturn(E_ERROR, "Method name must be a string");
	}

	function_name_strval = Z_STRVAL_P(function_name);
	function_name_strlen = Z_STRLEN_P(function_name);

	EX(object) = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

	if (EX(object) && Z_TYPE_P(EX(object)) == IS_OBJECT) {
		if (Z_OBJ_HT_P(EX(object))->get_method == NULL) {
			zend_error_noreturn(E_ERROR, "Object does not support method calls");
		}

		/* First, locate the function. */
		EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen TSRMLS_CC);
		if (!EX(fbc)) {
			zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
		}
	} else {
		zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
	}

	if (!EX(object) || (EX(fbc) && (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
		EX(object) = NULL;
	} else {
		if (!PZVAL_IS_REF(EX(object))) {
			EX(object)->refcount++; /* For $this pointer */
		} else {
			zval *this_ptr;
			ALLOC_ZVAL(this_ptr);
			INIT_PZVAL_COPY(this_ptr, EX(object));
			zval_copy_ctor(this_ptr);
			EX(object) = this_ptr;
		}
	}

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CASE_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	int switch_expr_is_overloaded=0;
	zend_free_op free_op1, free_op2;

	if (IS_TMP_VAR==IS_VAR) {
		if (EX_T(opline->op1.u.var).var.ptr_ptr) {
			PZVAL_LOCK(EX_T(opline->op1.u.var).var.ptr);
		} else {
			switch_expr_is_overloaded = 1;
			EX_T(opline->op1.u.var).str_offset.str->refcount++;
		}
	}
	is_equal_function(&EX_T(opline->result.u.var).tmp_var,
				 _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
				 _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	if (switch_expr_is_overloaded) {
		/* We only free op1 if this is a string offset,
		 * Since if it is a TMP_VAR, it'll be reused by
		 * other CASE opcodes (whereas string offsets
		 * are allocated at each get_zval_ptr())
		 */
		zval_dtor(free_op1.var);
		EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
		AI_USE_PTR(EX_T(opline->op1.u.var).var);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *array_ptr = &EX_T(opline->result.u.var).tmp_var;
	zval *expr_ptr;
	zval *offset=_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

#if 0 || IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV
	zval **expr_ptr_ptr = NULL;

	if (opline->extended_value) {
		expr_ptr_ptr=NULL;
		expr_ptr = *expr_ptr_ptr;
	} else {
		expr_ptr=_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	}
#else
	expr_ptr=_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
#endif

	if (1) { /* temporary variable */
		zval *new_expr;

		ALLOC_ZVAL(new_expr);
		INIT_PZVAL_COPY(new_expr, expr_ptr);
		expr_ptr = new_expr;
	} else {
#if 0 || IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV
		if (opline->extended_value) {
			SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr_ptr);
			expr_ptr = *expr_ptr_ptr;
			expr_ptr->refcount++;
		} else
#endif
		if (PZVAL_IS_REF(expr_ptr)) {
			zval *new_expr;

			ALLOC_ZVAL(new_expr);
			INIT_PZVAL_COPY(new_expr, expr_ptr);
			expr_ptr = new_expr;
			zendi_zval_copy_ctor(*expr_ptr);
		} else {
			expr_ptr->refcount++;
		}
	}
	if (offset) {
		switch (Z_TYPE_P(offset)) {
			case IS_DOUBLE:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_LONG:
			case IS_BOOL:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), Z_LVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_STRING:
				zend_symtable_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_NULL:
				zend_hash_update(Z_ARRVAL_P(array_ptr), "", sizeof(""), &expr_ptr, sizeof(zval *), NULL);
				break;
			default:
				zend_error(E_WARNING, "Illegal offset type");
				zval_ptr_dtor(&expr_ptr);
				/* do nothing */
				break;
		}
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	} else {
		zend_hash_next_index_insert(Z_ARRVAL_P(array_ptr), &expr_ptr, sizeof(zval *), NULL);
	}
	if (opline->extended_value) {

	} else {

	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_ARRAY_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	array_init(&EX_T(opline->result.u.var).tmp_var);
	if (IS_TMP_VAR == IS_UNUSED) {
		ZEND_VM_NEXT_OPCODE();
#if 0 || IS_TMP_VAR != IS_UNUSED
	} else {
		return ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
#endif
	}
}

static int ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *array_ptr = &EX_T(opline->result.u.var).tmp_var;
	zval *expr_ptr;
	zval *offset=NULL;

#if 0 || IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV
	zval **expr_ptr_ptr = NULL;

	if (opline->extended_value) {
		expr_ptr_ptr=NULL;
		expr_ptr = *expr_ptr_ptr;
	} else {
		expr_ptr=_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	}
#else
	expr_ptr=_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
#endif

	if (1) { /* temporary variable */
		zval *new_expr;

		ALLOC_ZVAL(new_expr);
		INIT_PZVAL_COPY(new_expr, expr_ptr);
		expr_ptr = new_expr;
	} else {
#if 0 || IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV
		if (opline->extended_value) {
			SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr_ptr);
			expr_ptr = *expr_ptr_ptr;
			expr_ptr->refcount++;
		} else
#endif
		if (PZVAL_IS_REF(expr_ptr)) {
			zval *new_expr;

			ALLOC_ZVAL(new_expr);
			INIT_PZVAL_COPY(new_expr, expr_ptr);
			expr_ptr = new_expr;
			zendi_zval_copy_ctor(*expr_ptr);
		} else {
			expr_ptr->refcount++;
		}
	}
	if (offset) {
		switch (Z_TYPE_P(offset)) {
			case IS_DOUBLE:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_LONG:
			case IS_BOOL:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), Z_LVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_STRING:
				zend_symtable_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_NULL:
				zend_hash_update(Z_ARRVAL_P(array_ptr), "", sizeof(""), &expr_ptr, sizeof(zval *), NULL);
				break;
			default:
				zend_error(E_WARNING, "Illegal offset type");
				zval_ptr_dtor(&expr_ptr);
				/* do nothing */
				break;
		}

	} else {
		zend_hash_next_index_insert(Z_ARRVAL_P(array_ptr), &expr_ptr, sizeof(zval *), NULL);
	}
	if (opline->extended_value) {

	} else {

	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_ARRAY_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	array_init(&EX_T(opline->result.u.var).tmp_var);
	if (IS_TMP_VAR == IS_UNUSED) {
		ZEND_VM_NEXT_OPCODE();
#if 0 || IS_TMP_VAR != IS_UNUSED
	} else {
		return ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
#endif
	}
}

static int ZEND_ADD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	add_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SUB_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	sub_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_MUL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	mul_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_DIV_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	div_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_MOD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	mod_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	shift_left_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SR_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	shift_right_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CONCAT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	concat_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_IDENTICAL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	is_identical_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	is_not_identical_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_EQUAL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	is_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_NOT_EQUAL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	is_not_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_SMALLER_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	is_smaller_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	is_smaller_or_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_OR_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	bitwise_or_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_AND_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	bitwise_and_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_XOR_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	bitwise_xor_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BOOL_XOR_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	boolean_xor_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	zval_dtor(free_op1.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ADD_VAR_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *var = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
	zval var_copy;
	int use_copy = 0;

	if (Z_TYPE_P(var) != IS_STRING) {
		zend_make_printable_zval(var, &var_copy, &use_copy);

		if (use_copy) {
			var = &var_copy;
		}
	}
	add_string_to_string(	&EX_T(opline->result.u.var).tmp_var,
							_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
							var);
	if (use_copy) {
		zval_dtor(var);
	}
	/* original comment, possibly problematic:
	 * FREE_OP is missing intentionally here - we're always working on the same temporary variable
	 * (Zeev):  I don't think it's problematic, we only use variables
	 * which aren't affected by FREE_OP(Ts, )'s anyway, unless they're
	 * string offsets or overloaded objects
	 */

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_METHOD_CALL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *function_name;
	char *function_name_strval;
	int function_name_strlen;
	zend_free_op free_op1;

	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), NULL);

	function_name = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

	if (Z_TYPE_P(function_name)!=IS_STRING) {
		zend_error_noreturn(E_ERROR, "Method name must be a string");
	}

	function_name_strval = Z_STRVAL_P(function_name);
	function_name_strlen = Z_STRLEN_P(function_name);

	EX(object) = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

	if (EX(object) && Z_TYPE_P(EX(object)) == IS_OBJECT) {
		if (Z_OBJ_HT_P(EX(object))->get_method == NULL) {
			zend_error_noreturn(E_ERROR, "Object does not support method calls");
		}

		/* First, locate the function. */
		EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen TSRMLS_CC);
		if (!EX(fbc)) {
			zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
		}
	} else {
		zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
	}

	if (!EX(object) || (EX(fbc) && (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
		EX(object) = NULL;
	} else {
		if (!PZVAL_IS_REF(EX(object))) {
			EX(object)->refcount++; /* For $this pointer */
		} else {
			zval *this_ptr;
			ALLOC_ZVAL(this_ptr);
			INIT_PZVAL_COPY(this_ptr, EX(object));
			zval_copy_ctor(this_ptr);
			EX(object) = this_ptr;
		}
	}


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CASE_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	int switch_expr_is_overloaded=0;
	zend_free_op free_op1;

	if (IS_TMP_VAR==IS_VAR) {
		if (EX_T(opline->op1.u.var).var.ptr_ptr) {
			PZVAL_LOCK(EX_T(opline->op1.u.var).var.ptr);
		} else {
			switch_expr_is_overloaded = 1;
			EX_T(opline->op1.u.var).str_offset.str->refcount++;
		}
	}
	is_equal_function(&EX_T(opline->result.u.var).tmp_var,
				 _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
				 _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);

	if (switch_expr_is_overloaded) {
		/* We only free op1 if this is a string offset,
		 * Since if it is a TMP_VAR, it'll be reused by
		 * other CASE opcodes (whereas string offsets
		 * are allocated at each get_zval_ptr())
		 */
		zval_dtor(free_op1.var);
		EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
		AI_USE_PTR(EX_T(opline->op1.u.var).var);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *array_ptr = &EX_T(opline->result.u.var).tmp_var;
	zval *expr_ptr;
	zval *offset=_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

#if 0 || IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV
	zval **expr_ptr_ptr = NULL;

	if (opline->extended_value) {
		expr_ptr_ptr=NULL;
		expr_ptr = *expr_ptr_ptr;
	} else {
		expr_ptr=_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	}
#else
	expr_ptr=_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
#endif

	if (1) { /* temporary variable */
		zval *new_expr;

		ALLOC_ZVAL(new_expr);
		INIT_PZVAL_COPY(new_expr, expr_ptr);
		expr_ptr = new_expr;
	} else {
#if 0 || IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV
		if (opline->extended_value) {
			SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr_ptr);
			expr_ptr = *expr_ptr_ptr;
			expr_ptr->refcount++;
		} else
#endif
		if (PZVAL_IS_REF(expr_ptr)) {
			zval *new_expr;

			ALLOC_ZVAL(new_expr);
			INIT_PZVAL_COPY(new_expr, expr_ptr);
			expr_ptr = new_expr;
			zendi_zval_copy_ctor(*expr_ptr);
		} else {
			expr_ptr->refcount++;
		}
	}
	if (offset) {
		switch (Z_TYPE_P(offset)) {
			case IS_DOUBLE:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_LONG:
			case IS_BOOL:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), Z_LVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_STRING:
				zend_symtable_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_NULL:
				zend_hash_update(Z_ARRVAL_P(array_ptr), "", sizeof(""), &expr_ptr, sizeof(zval *), NULL);
				break;
			default:
				zend_error(E_WARNING, "Illegal offset type");
				zval_ptr_dtor(&expr_ptr);
				/* do nothing */
				break;
		}

	} else {
		zend_hash_next_index_insert(Z_ARRVAL_P(array_ptr), &expr_ptr, sizeof(zval *), NULL);
	}
	if (opline->extended_value) {

	} else {

	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_ARRAY_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	array_init(&EX_T(opline->result.u.var).tmp_var);
	if (IS_TMP_VAR == IS_UNUSED) {
		ZEND_VM_NEXT_OPCODE();
#if 0 || IS_TMP_VAR != IS_UNUSED
	} else {
		return ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
#endif
	}
}

static int ZEND_BW_NOT_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	bitwise_not_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BOOL_NOT_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	boolean_not_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_PRE_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval **var_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

	if (!var_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}
	if (*var_ptr == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
		ZEND_VM_NEXT_OPCODE();
	}

	SEPARATE_ZVAL_IF_NOT_REF(var_ptr);

	if(Z_TYPE_PP(var_ptr) == IS_OBJECT && Z_OBJ_HANDLER_PP(var_ptr, get)
	   && Z_OBJ_HANDLER_PP(var_ptr, set)) {
		/* proxy object */
		zval *val = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
		val->refcount++;
		increment_function(val);
		Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, val TSRMLS_CC);
		zval_ptr_dtor(&val);
	} else {
		increment_function(*var_ptr);
	}

	if (!RETURN_VALUE_UNUSED(&opline->result)) {
		EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
		PZVAL_LOCK(*var_ptr);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
	}

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_PRE_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval **var_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

	if (!var_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}
	if (*var_ptr == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
		ZEND_VM_NEXT_OPCODE();
	}

	SEPARATE_ZVAL_IF_NOT_REF(var_ptr);

	if(Z_TYPE_PP(var_ptr) == IS_OBJECT && Z_OBJ_HANDLER_PP(var_ptr, get)
	   && Z_OBJ_HANDLER_PP(var_ptr, set)) {
		/* proxy object */
		zval *val = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
		val->refcount++;
		decrement_function(val);
		Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, val TSRMLS_CC);
		zval_ptr_dtor(&val);
	} else {
		decrement_function(*var_ptr);
	}

	if (!RETURN_VALUE_UNUSED(&opline->result)) {
		EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
		PZVAL_LOCK(*var_ptr);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
	}

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_POST_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval **var_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

	if (!var_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}
	if (*var_ptr == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			EX_T(opline->result.u.var).tmp_var = *EG(uninitialized_zval_ptr);
		}
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
		ZEND_VM_NEXT_OPCODE();
	}

	EX_T(opline->result.u.var).tmp_var = **var_ptr;
	zendi_zval_copy_ctor(EX_T(opline->result.u.var).tmp_var);

	SEPARATE_ZVAL_IF_NOT_REF(var_ptr);

	if(Z_TYPE_PP(var_ptr) == IS_OBJECT && Z_OBJ_HANDLER_PP(var_ptr, get)
	   && Z_OBJ_HANDLER_PP(var_ptr, set)) {
		/* proxy object */
		zval *val = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
		val->refcount++;
		increment_function(val);
		Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, val TSRMLS_CC);
		zval_ptr_dtor(&val);
	} else {
		increment_function(*var_ptr);
	}

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_POST_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval **var_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

	if (!var_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}
	if (*var_ptr == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			EX_T(opline->result.u.var).tmp_var = *EG(uninitialized_zval_ptr);
		}
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
		ZEND_VM_NEXT_OPCODE();
	}

	EX_T(opline->result.u.var).tmp_var = **var_ptr;
	zendi_zval_copy_ctor(EX_T(opline->result.u.var).tmp_var);

	SEPARATE_ZVAL_IF_NOT_REF(var_ptr);

	if(Z_TYPE_PP(var_ptr) == IS_OBJECT && Z_OBJ_HANDLER_PP(var_ptr, get)
	   && Z_OBJ_HANDLER_PP(var_ptr, set)) {
		/* proxy object */
		zval *val = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
		val->refcount++;
		decrement_function(val);
		Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, val TSRMLS_CC);
		zval_ptr_dtor(&val);
	} else {
		decrement_function(*var_ptr);
	}

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ECHO_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval z_copy;
	zval *z = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

	if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL &&
		zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
		zend_print_variable(&z_copy);
		zval_dtor(&z_copy);
	} else {
		zend_print_variable(z);
	}

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_PRINT_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 1;
	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_LONG;

	return ZEND_ECHO_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_fetch_var_address_helper_SPEC_VAR(int type, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *varname = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval **retval;
	zval tmp_varname;
	HashTable *target_symbol_table;

 	if (Z_TYPE_P(varname) != IS_STRING) {
		tmp_varname = *varname;
		zval_copy_ctor(&tmp_varname);
		convert_to_string(&tmp_varname);
		varname = &tmp_varname;
	}

	if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
		retval = zend_std_get_static_property(EX_T(opline->op2.u.var).class_entry, Z_STRVAL_P(varname), Z_STRLEN_P(varname), 0 TSRMLS_CC);
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	} else {
		target_symbol_table = zend_get_target_symbol_table(opline, EX(Ts), type, varname TSRMLS_CC);
/*
		if (!target_symbol_table) {
			ZEND_VM_NEXT_OPCODE();
		}
*/
		if (zend_hash_find(target_symbol_table, varname->value.str.val, varname->value.str.len+1, (void **) &retval) == FAILURE) {
			switch (type) {
				case BP_VAR_R:
				case BP_VAR_UNSET:
					zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
					/* break missing intentionally */
				case BP_VAR_IS:
					retval = &EG(uninitialized_zval_ptr);
					break;
				case BP_VAR_RW:
					zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
					/* break missing intentionally */
				case BP_VAR_W: {
						zval *new_zval = &EG(uninitialized_zval);

						new_zval->refcount++;
						zend_hash_update(target_symbol_table, varname->value.str.val, varname->value.str.len+1, &new_zval, sizeof(zval *), (void **) &retval);
					}
					break;
				EMPTY_SWITCH_DEFAULT_CASE()
			}
		}
		switch (opline->op2.u.EA.type) {
			case ZEND_FETCH_GLOBAL:
				if (IS_VAR != IS_TMP_VAR) {
					if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
				}
				break;
			case ZEND_FETCH_LOCAL:
				if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
				break;
			case ZEND_FETCH_STATIC:
				zval_update_constant(retval, (void*) 1 TSRMLS_CC);
				break;
			case ZEND_FETCH_GLOBAL_LOCK:
				if (IS_VAR == IS_VAR && !free_op1.var) {
					PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
				}
				break;
		}
	}


	if (varname == &tmp_varname) {
		zval_dtor(varname);
	}
	if (!RETURN_VALUE_UNUSED(&opline->result)) {
		EX_T(opline->result.u.var).var.ptr_ptr = retval;
		PZVAL_LOCK(*retval);
		switch (type) {
			case BP_VAR_R:
			case BP_VAR_IS:
				AI_USE_PTR(EX_T(opline->result.u.var).var);
				break;
			case BP_VAR_UNSET: {
				zend_free_op free_res;

				PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &free_res);
				if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
					SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
				}
				PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
				FREE_OP_VAR_PTR(free_res);
				break;
			}
		}
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_R_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_var_address_helper_SPEC_VAR(BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_W_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_var_address_helper_SPEC_VAR(BP_VAR_W, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_RW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_var_address_helper_SPEC_VAR(BP_VAR_RW, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_FUNC_ARG_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_var_address_helper_SPEC_VAR(ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), EX(opline)->extended_value)?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_UNSET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_var_address_helper_SPEC_VAR(BP_VAR_UNSET, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_IS_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_var_address_helper_SPEC_VAR(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_JMPZ_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	int ret = i_zend_is_true(_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC));

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	if (!ret) {
#if DEBUG_ZEND>=2
		printf("Conditional jmp to %d\n", opline->op2.u.opline_num);
#endif
		ZEND_VM_JMP(opline->op2.u.jmp_addr);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_JMPNZ_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	int ret = i_zend_is_true(_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC));

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	if (ret) {
#if DEBUG_ZEND>=2
		printf("Conditional jmp to %d\n", opline->op2.u.opline_num);
#endif
		ZEND_VM_JMP(opline->op2.u.jmp_addr);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_JMPZNZ_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	int retval = i_zend_is_true(_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC));

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	if (retval) {
#if DEBUG_ZEND>=2
		printf("Conditional jmp on true to %d\n", opline->extended_value);
#endif
		ZEND_VM_JMP(&EX(op_array)->opcodes[opline->extended_value]);
	} else {
#if DEBUG_ZEND>=2
		printf("Conditional jmp on false to %d\n", opline->op2.u.opline_num);
#endif
		ZEND_VM_JMP(&EX(op_array)->opcodes[opline->op2.u.opline_num]);
	}
}

static int ZEND_JMPZ_EX_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	int retval = i_zend_is_true(_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC));

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	Z_LVAL(EX_T(opline->result.u.var).tmp_var) = retval;
	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
	if (!retval) {
#if DEBUG_ZEND>=2
		printf("Conditional jmp to %d\n", opline->op2.u.opline_num);
#endif
		ZEND_VM_JMP(opline->op2.u.jmp_addr);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_JMPNZ_EX_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	int retval = i_zend_is_true(_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC));

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	Z_LVAL(EX_T(opline->result.u.var).tmp_var) = retval;
	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
	if (retval) {
#if DEBUG_ZEND>=2
		printf("Conditional jmp to %d\n", opline->op2.u.opline_num);
#endif
		ZEND_VM_JMP(opline->op2.u.jmp_addr);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *retval_ptr;
	zval **retval_ptr_ptr;
	zend_free_op free_op1;

	if (EG(active_op_array)->return_reference == ZEND_RETURN_REF) {

		if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) {
			/* Not supposed to happen, but we'll allow it */
			zend_error(E_NOTICE, "Only variable references should be returned by reference");
			goto return_by_value;
		}

		retval_ptr_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

		if (!retval_ptr_ptr) {
			zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
		}

		if (IS_VAR == IS_VAR && !(*retval_ptr_ptr)->is_ref) {
			if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
			    EX_T(opline->op1.u.var).var.fcall_returned_reference) {
			} else if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
				if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) {
					PZVAL_LOCK(*retval_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
				}
				zend_error(E_NOTICE, "Only variable references should be returned by reference");
				goto return_by_value;
			}
		}

		SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr_ptr);
		(*retval_ptr_ptr)->refcount++;

		(*EG(return_value_ptr_ptr)) = (*retval_ptr_ptr);
	} else {
return_by_value:

		retval_ptr = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

		if (EG(ze1_compatibility_mode) && Z_TYPE_P(retval_ptr) == IS_OBJECT) {
			zval *ret;
			char *class_name;
			zend_uint class_name_len;
			int dup;

			ALLOC_ZVAL(ret);
			INIT_PZVAL_COPY(ret, retval_ptr);
			dup = zend_get_object_classname(retval_ptr, &class_name, &class_name_len TSRMLS_CC);
			if (Z_OBJ_HT_P(retval_ptr)->clone_obj == NULL) {
				zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s",  class_name);
			}
			zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name);
			ret->value.obj = Z_OBJ_HT_P(retval_ptr)->clone_obj(retval_ptr TSRMLS_CC);
			*EG(return_value_ptr_ptr) = ret;
			if (!dup) {
				efree(class_name);
			}
		} else if (!0) { /* Not a temp var */
			if (EG(active_op_array)->return_reference == ZEND_RETURN_REF ||
			    (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0)) {
				zval *ret;

				ALLOC_ZVAL(ret);
				INIT_PZVAL_COPY(ret, retval_ptr);
				zval_copy_ctor(ret);
				*EG(return_value_ptr_ptr) = ret;
			} else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) &&
			           retval_ptr == &EG(uninitialized_zval)) {
				zval *ret;

				ALLOC_INIT_ZVAL(ret);
				*EG(return_value_ptr_ptr) = ret;
			} else {
				*EG(return_value_ptr_ptr) = retval_ptr;
				retval_ptr->refcount++;
			}
		} else {
			zval *ret;

			ALLOC_ZVAL(ret);
			INIT_PZVAL_COPY(ret, retval_ptr);
			*EG(return_value_ptr_ptr) = ret;
		}
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_RETURN_FROM_EXECUTE_LOOP();
}

static int ZEND_THROW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *value;
	zval *exception;
	zend_free_op free_op1;

	value = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

	if (Z_TYPE_P(value) != IS_OBJECT) {
		zend_error_noreturn(E_ERROR, "Can only throw objects");
	}
	/* Not sure if a complete copy is what we want here */
	ALLOC_ZVAL(exception);
	INIT_PZVAL_COPY(exception, value);
	if (!0) {
		zval_copy_ctor(exception);
	}

	zend_throw_exception_object(exception TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SEND_VAL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	if (opline->extended_value==ZEND_DO_FCALL_BY_NAME
		&& ARG_MUST_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
			zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.u.opline_num);
	}
	{
		zval *valptr;
		zval *value;
		zend_free_op free_op1;

		value = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

		ALLOC_ZVAL(valptr);
		INIT_PZVAL_COPY(valptr, value);
		if (!0) {
			zval_copy_ctor(valptr);
		}
		zend_ptr_stack_push(&EG(argument_stack), valptr);
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	}
	ZEND_VM_NEXT_OPCODE();
}

static int zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *varptr;
	zend_free_op free_op1;
	varptr = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

	if (varptr == &EG(uninitialized_zval)) {
		ALLOC_ZVAL(varptr);
		INIT_ZVAL(*varptr);
		varptr->refcount = 0;
	} else if (PZVAL_IS_REF(varptr)) {
		zval *original_var = varptr;

		ALLOC_ZVAL(varptr);
		*varptr = *original_var;
		varptr->is_ref = 0;
		varptr->refcount = 0;
		zval_copy_ctor(varptr);
	}
	varptr->refcount++;
	zend_ptr_stack_push(&EG(argument_stack), varptr);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};  /* for string offsets */

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *varptr;

	if (opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) { /* Had function_ptr at compile_time */
		if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF)) {
			return zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
		}
	} else if (!ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
		return zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
	}

	if (IS_VAR == IS_VAR &&
		(opline->extended_value & ZEND_ARG_SEND_FUNCTION) &&
		EX_T(opline->op1.u.var).var.fcall_returned_reference &&
		EX_T(opline->op1.u.var).var.ptr) {
		varptr = EX_T(opline->op1.u.var).var.ptr;
		PZVAL_UNLOCK_EX(varptr, &free_op1, 0);
	} else {
		varptr = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	}
	if ((!(opline->extended_value & ZEND_ARG_SEND_FUNCTION) ||
	     EX_T(opline->op1.u.var).var.fcall_returned_reference) &&
	    varptr != &EG(uninitialized_zval) &&
	    (PZVAL_IS_REF(varptr) ||
	     (varptr->refcount == 1 && (IS_VAR == IS_CV || free_op1.var)))) {
		varptr->is_ref = 1;
		varptr->refcount++;
		zend_ptr_stack_push(&EG(argument_stack), varptr);
	} else {
		zval *valptr;

		if (!(opline->extended_value & ZEND_ARG_SEND_SILENT)) {
			zend_error(E_STRICT, "Only variables should be passed by reference");
		}
		ALLOC_ZVAL(valptr);
		INIT_PZVAL_COPY(valptr, varptr);
		if (!0) {
			zval_copy_ctor(valptr);
		}
		zend_ptr_stack_push(&EG(argument_stack), valptr);
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval **varptr_ptr;
	zval *varptr;
	varptr_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

	if (!varptr_ptr) {
		zend_error_noreturn(E_ERROR, "Only variables can be passed by reference");
	}

	if (IS_VAR == IS_VAR && *varptr_ptr == EG(error_zval_ptr)) {
		(*varptr_ptr)->refcount--;
		ALLOC_ZVAL(*varptr_ptr);
		INIT_ZVAL(**varptr_ptr);
		(*varptr_ptr)->refcount = 0;
	}

	if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION && !ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
		return zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
	}

	SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr_ptr);
	varptr = *varptr_ptr;
	varptr->refcount++;
	zend_ptr_stack_push(&EG(argument_stack), varptr);

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SEND_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	if ((opline->extended_value == ZEND_DO_FCALL_BY_NAME)
		&& ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
		return ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
	}
	return zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_BOOL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	/* PHP 3.0 returned "" for false and 1 for true, here we use 0 and 1 for now */
	Z_LVAL(EX_T(opline->result.u.var).tmp_var) = i_zend_is_true(_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC));
	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SWITCH_FREE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_switch_free(EX(opline), EX(Ts) TSRMLS_CC);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CLONE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *obj = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zend_class_entry *ce;
	zend_function *clone;
	zend_object_clone_obj_t clone_call;

	if (!obj || Z_TYPE_P(obj) != IS_OBJECT) {
		zend_error_noreturn(E_ERROR, "__clone method called on non-object");
		EX_T(opline->result.u.var).var.ptr = EG(error_zval_ptr);
		EX_T(opline->result.u.var).var.ptr->refcount++;
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
		ZEND_VM_NEXT_OPCODE();
	}

	ce = Z_OBJCE_P(obj);
	clone = ce ? ce->clone : NULL;
	clone_call =  Z_OBJ_HT_P(obj)->clone_obj;
	if (!clone_call) {
		if (ce) {
			zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", ce->name);
		} else {
			zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object");
		}
		EX_T(opline->result.u.var).var.ptr = EG(error_zval_ptr);
		EX_T(opline->result.u.var).var.ptr->refcount++;
	}

	if (ce && clone) {
		if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) {
			/* Ensure that if we're calling a private function, we're allowed to do so.
			 */
			if (ce != EG(scope)) {
				zend_error_noreturn(E_ERROR, "Call to private %s::__clone() from context '%s'", ce->name, EG(scope) ? EG(scope)->name : "");
			}
		} else if ((clone->common.fn_flags & ZEND_ACC_PROTECTED)) {
			/* Ensure that if we're calling a protected function, we're allowed to do so.
			 */
			if (!zend_check_protected(clone->common.scope, EG(scope))) {
				zend_error_noreturn(E_ERROR, "Call to protected %s::__clone() from context '%s'", ce->name, EG(scope) ? EG(scope)->name : "");
			}
		}
	}

	EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
	if (!EG(exception)) {
		ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
		Z_OBJVAL_P(EX_T(opline->result.u.var).var.ptr) = clone_call(obj TSRMLS_CC);
		Z_TYPE_P(EX_T(opline->result.u.var).var.ptr) = IS_OBJECT;
		EX_T(opline->result.u.var).var.ptr->refcount=1;
		EX_T(opline->result.u.var).var.ptr->is_ref=1;
		if (!RETURN_VALUE_USED(opline) || EG(exception)) {
			zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
		}
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *expr = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval *result = &EX_T(opline->result.u.var).tmp_var;

	if (opline->extended_value != IS_STRING) {
		*result = *expr;
		if (!0) {
			zendi_zval_copy_ctor(*result);
		}
	}
	switch (opline->extended_value) {
		case IS_NULL:
			convert_to_null(result);
			break;
		case IS_BOOL:
			convert_to_boolean(result);
			break;
		case IS_LONG:
			convert_to_long(result);
			break;
		case IS_DOUBLE:
			convert_to_double(result);
			break;
		case IS_STRING: {
			zval var_copy;
			int use_copy;

			zend_make_printable_zval(expr, &var_copy, &use_copy);
			if (use_copy) {
				*result = var_copy;
				if (0) {
					if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
				}
			} else {
				*result = *expr;
				if (!0) {
					zendi_zval_copy_ctor(*result);
				}
			}
			break;
		}
		case IS_ARRAY:
			convert_to_array(result);
			break;
		case IS_OBJECT:
			convert_to_object(result);
			break;
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op_array *new_op_array=NULL;
	zval **original_return_value = EG(return_value_ptr_ptr);
	int return_value_used;
	zend_free_op free_op1;
	zval *inc_filename = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval tmp_inc_filename;
	zend_bool failure_retval=0;

	if (inc_filename->type!=IS_STRING) {
		tmp_inc_filename = *inc_filename;
		zval_copy_ctor(&tmp_inc_filename);
		convert_to_string(&tmp_inc_filename);
		inc_filename = &tmp_inc_filename;
	}

	return_value_used = RETURN_VALUE_USED(opline);

	switch (Z_LVAL(opline->op2.u.constant)) {
		case ZEND_INCLUDE_ONCE:
		case ZEND_REQUIRE_ONCE: {
				zend_file_handle file_handle;

				if (IS_ABSOLUTE_PATH(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename))) {
					cwd_state state;

					state.cwd_length = 0;
					state.cwd = malloc(1);
					state.cwd[0] = 0;

					failure_retval = (!virtual_file_ex(&state, Z_STRVAL_P(inc_filename), NULL, 1) &&
						zend_hash_exists(&EG(included_files), state.cwd, state.cwd_length+1));

					free(state.cwd);
				}

				if (failure_retval) {
					/* do nothing */
				} else if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) {

					if (!file_handle.opened_path) {
						file_handle.opened_path = estrndup(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename));
					}

					if (zend_hash_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1)==SUCCESS) {
						new_op_array = zend_compile_file(&file_handle, (Z_LVAL(opline->op2.u.constant)==ZEND_INCLUDE_ONCE?ZEND_INCLUDE:ZEND_REQUIRE) TSRMLS_CC);
						zend_destroy_file_handle(&file_handle TSRMLS_CC);
					} else {
						zend_file_handle_dtor(&file_handle);
						failure_retval=1;
					}
				} else {
					if (Z_LVAL(opline->op2.u.constant)==ZEND_INCLUDE_ONCE) {
						zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, Z_STRVAL_P(inc_filename));
					} else {
						zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename));
					}
				}
			}
			break;
		case ZEND_INCLUDE:
		case ZEND_REQUIRE:
			new_op_array = compile_filename(Z_LVAL(opline->op2.u.constant), inc_filename TSRMLS_CC);
			break;
		case ZEND_EVAL: {
				char *eval_desc = zend_make_compiled_string_description("eval()'d code" TSRMLS_CC);

				new_op_array = zend_compile_string(inc_filename, eval_desc TSRMLS_CC);
				efree(eval_desc);
			}
			break;
		EMPTY_SWITCH_DEFAULT_CASE()
	}
	if (inc_filename==&tmp_inc_filename) {
		zval_dtor(&tmp_inc_filename);
	}
	EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
	if (new_op_array) {
		zval *saved_object;
		zend_function *saved_function;

		EG(return_value_ptr_ptr) = EX_T(opline->result.u.var).var.ptr_ptr;
		EG(active_op_array) = new_op_array;
		EX_T(opline->result.u.var).var.ptr = NULL;

		saved_object = EX(object);
		saved_function = EX(function_state).function;

		EX(function_state).function = (zend_function *) new_op_array;
		EX(object) = NULL;

		zend_execute(new_op_array TSRMLS_CC);

		EX(function_state).function = saved_function;
		EX(object) = saved_object;

		if (!return_value_used) {
			if (EX_T(opline->result.u.var).var.ptr) {
				zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
			}
		} else { /* return value is used */
			if (!EX_T(opline->result.u.var).var.ptr) { /* there was no return statement */
				ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
				INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);
				Z_LVAL_P(EX_T(opline->result.u.var).var.ptr) = 1;
				Z_TYPE_P(EX_T(opline->result.u.var).var.ptr) = IS_BOOL;
			}
		}

		EG(opline_ptr) = &EX(opline);
		EG(active_op_array) = EX(op_array);
		EG(function_state_ptr) = &EX(function_state);
		destroy_op_array(new_op_array TSRMLS_CC);
		efree(new_op_array);
		if (EG(exception)) {
			zend_throw_exception_internal(NULL TSRMLS_CC);
		}
	} else {
		if (return_value_used) {
			ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
			INIT_ZVAL(*EX_T(opline->result.u.var).var.ptr);
			Z_LVAL_P(EX_T(opline->result.u.var).var.ptr) = failure_retval;
			Z_TYPE_P(EX_T(opline->result.u.var).var.ptr) = IS_BOOL;
		}
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	EG(return_value_ptr_ptr) = original_return_value;
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_UNSET_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval tmp, *varname;
	HashTable *target_symbol_table;
	zend_free_op free_op1;

	varname = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

	if (Z_TYPE_P(varname) != IS_STRING) {
		tmp = *varname;
		zval_copy_ctor(&tmp);
		convert_to_string(&tmp);
		varname = &tmp;
	} else if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
		varname->refcount++;
	}

	if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
		zend_std_unset_static_property(EX_T(opline->op2.u.var).class_entry, Z_STRVAL_P(varname), Z_STRLEN_P(varname) TSRMLS_CC);
	} else {
		target_symbol_table = zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
		if (zend_hash_del(target_symbol_table, varname->value.str.val, varname->value.str.len+1) == SUCCESS) {
			zend_execute_data *ex = execute_data;
			ulong hash_value = zend_inline_hash_func(varname->value.str.val, varname->value.str.len+1);

			do {
				int i;

				if (ex->op_array) {
					for (i = 0; i < ex->op_array->last_var; i++) {
						if (ex->op_array->vars[i].hash_value == hash_value &&
							ex->op_array->vars[i].name_len == varname->value.str.len &&
							!memcmp(ex->op_array->vars[i].name, varname->value.str.val, varname->value.str.len)) {
							ex->CVs[i] = NULL;
							break;
						}
					}
				}
				ex = ex->prev_execute_data;
			} while (ex && ex->symbol_table == target_symbol_table);
		}
	}

	if (varname == &tmp) {
		zval_dtor(&tmp);
	} else if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
		zval_ptr_dtor(&varname);
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *array_ptr, **array_ptr_ptr;
	HashTable *fe_ht;
	zend_object_iterator *iter = NULL;
	zend_class_entry *ce = NULL;
	zend_bool is_empty = 0;

	if (opline->extended_value & ZEND_FE_RESET_VARIABLE) {
		array_ptr_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
		if (array_ptr_ptr == NULL || array_ptr_ptr == &EG(uninitialized_zval_ptr)) {
			ALLOC_INIT_ZVAL(array_ptr);
		} else if (Z_TYPE_PP(array_ptr_ptr) == IS_OBJECT) {
			if(Z_OBJ_HT_PP(array_ptr_ptr)->get_class_entry == NULL) {
				zend_error(E_WARNING, "foreach() can not iterate over objects without PHP class");
				ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.u.opline_num);
			}

			ce = Z_OBJCE_PP(array_ptr_ptr);
			if (!ce || ce->get_iterator == NULL) {
				SEPARATE_ZVAL_IF_NOT_REF(array_ptr_ptr);
				(*array_ptr_ptr)->refcount++;
			}
			array_ptr = *array_ptr_ptr;
		} else {
			if (Z_TYPE_PP(array_ptr_ptr) == IS_ARRAY) {
				SEPARATE_ZVAL_IF_NOT_REF(array_ptr_ptr);
				if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
					(*array_ptr_ptr)->is_ref = 1;
				}
			}
			array_ptr = *array_ptr_ptr;
			array_ptr->refcount++;
		}
	} else {
		array_ptr = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
		if (0) { /* IS_TMP_VAR */
			zval *tmp;

			ALLOC_ZVAL(tmp);
			INIT_PZVAL_COPY(tmp, array_ptr);
			array_ptr = tmp;
			if (Z_TYPE_P(array_ptr) == IS_OBJECT) {
				ce = Z_OBJCE_P(array_ptr);
				if (ce && ce->get_iterator) {
					array_ptr->refcount--;
				}
			}
		} else if (Z_TYPE_P(array_ptr) == IS_OBJECT) {
			ce = Z_OBJCE_P(array_ptr);
			if (!ce || !ce->get_iterator) {
				array_ptr->refcount++;
			}
		} else {
			if (IS_VAR == IS_CONST ||
			    ((IS_VAR == IS_CV || IS_VAR == IS_VAR) &&
			    !array_ptr->is_ref &&
			    array_ptr->refcount > 1)) {
				zval *tmp;

				ALLOC_ZVAL(tmp);
				INIT_PZVAL_COPY(tmp, array_ptr);
				zval_copy_ctor(tmp);
				array_ptr = tmp;
			} else {
				array_ptr->refcount++;
			}
		}
	}

	if (ce && ce->get_iterator) {
		iter = ce->get_iterator(ce, array_ptr, opline->extended_value & ZEND_FE_RESET_REFERENCE TSRMLS_CC);

		if (iter && !EG(exception)) {
			array_ptr = zend_iterator_wrap(iter TSRMLS_CC);
		} else {
			if (opline->extended_value & ZEND_FE_RESET_VARIABLE) {
				if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
			} else {
				if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
			}
			if (!EG(exception)) {
				zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Object of type %s did not create an Iterator", ce->name);
			}
			zend_throw_exception_internal(NULL TSRMLS_CC);
			ZEND_VM_NEXT_OPCODE();
		}
	}

	PZVAL_LOCK(array_ptr);
	EX_T(opline->result.u.var).var.ptr = array_ptr;
	EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;

	if (iter) {
		iter->index = 0;
		if (iter->funcs->rewind) {
			iter->funcs->rewind(iter TSRMLS_CC);
			if (EG(exception)) {
				array_ptr->refcount--;
				zval_ptr_dtor(&array_ptr);
				if (opline->extended_value & ZEND_FE_RESET_VARIABLE) {
					if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
				} else {
					if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
				}
				ZEND_VM_NEXT_OPCODE();
			}
		}
		is_empty = iter->funcs->valid(iter TSRMLS_CC) != SUCCESS;
		if (EG(exception)) {
			array_ptr->refcount--;
			zval_ptr_dtor(&array_ptr);
			if (opline->extended_value & ZEND_FE_RESET_VARIABLE) {
				if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
			} else {
				if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
			}
			ZEND_VM_NEXT_OPCODE();
		}
		iter->index = -1; /* will be set to 0 before using next handler */
	} else if ((fe_ht = HASH_OF(array_ptr)) != NULL) {
		zend_hash_internal_pointer_reset(fe_ht);
		if (ce) {
			zend_object *zobj = zend_objects_get_address(array_ptr TSRMLS_CC);
			while (zend_hash_has_more_elements(fe_ht) == SUCCESS) {
				char *str_key;
				uint str_key_len;
				ulong int_key;
				zend_uchar key_type;

				key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 0, NULL);
				if (key_type != HASH_KEY_NON_EXISTANT &&
					(key_type == HASH_KEY_IS_LONG ||
				     zend_check_property_access(zobj, str_key, str_key_len-1 TSRMLS_CC) == SUCCESS)) {
					break;
				}
				zend_hash_move_forward(fe_ht);
			}
		}
		is_empty = zend_hash_has_more_elements(fe_ht) != SUCCESS;
		zend_hash_get_pointer(fe_ht, &EX_T(opline->result.u.var).fe.fe_pos);
	} else {
		zend_error(E_WARNING, "Invalid argument supplied for foreach()");
		is_empty = 1;
	}

	if (opline->extended_value & ZEND_FE_RESET_VARIABLE) {
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	} else {
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	}
	if (is_empty) {
		ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.u.opline_num);
	} else {
		ZEND_VM_NEXT_OPCODE();
	}
}

static int ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *array = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval **value;
	char *str_key;
	uint str_key_len;
	ulong int_key;
	HashTable *fe_ht;
	zend_object_iterator *iter = NULL;
	int key_type = 0;
	zend_bool use_key = (zend_bool)(opline->extended_value & ZEND_FE_FETCH_WITH_KEY);

	PZVAL_LOCK(array);

	switch (zend_iterator_unwrap(array, &iter TSRMLS_CC)) {
		default:
		case ZEND_ITER_INVALID:
			zend_error(E_WARNING, "Invalid argument supplied for foreach()");
			ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.u.opline_num);

		case ZEND_ITER_PLAIN_OBJECT: {
			char *class_name, *prop_name;
			zend_object *zobj = zend_objects_get_address(array TSRMLS_CC);

			fe_ht = HASH_OF(array);
			zend_hash_set_pointer(fe_ht, &EX_T(opline->op1.u.var).fe.fe_pos);
			do {
				if (zend_hash_get_current_data(fe_ht, (void **) &value)==FAILURE) {
					/* reached end of iteration */
					ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.u.opline_num);
				}
				key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 0, NULL);

				zend_hash_move_forward(fe_ht);
			} while (key_type == HASH_KEY_NON_EXISTANT ||
			         (key_type != HASH_KEY_IS_LONG &&
			          zend_check_property_access(zobj, str_key, str_key_len-1 TSRMLS_CC) != SUCCESS));
			zend_hash_get_pointer(fe_ht, &EX_T(opline->op1.u.var).fe.fe_pos);
			if (use_key && key_type != HASH_KEY_IS_LONG) {
				zend_unmangle_property_name(str_key, str_key_len-1, &class_name, &prop_name);
				str_key_len = strlen(prop_name);
				str_key = estrndup(prop_name, str_key_len);
				str_key_len++;
			}
			break;
		}

		case ZEND_ITER_PLAIN_ARRAY:
			fe_ht = HASH_OF(array);
			zend_hash_set_pointer(fe_ht, &EX_T(opline->op1.u.var).fe.fe_pos);
			if (zend_hash_get_current_data(fe_ht, (void **) &value)==FAILURE) {
				/* reached end of iteration */
				ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.u.opline_num);
			}
			if (use_key) {
				key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 1, NULL);
			}
			zend_hash_move_forward(fe_ht);
			zend_hash_get_pointer(fe_ht, &EX_T(opline->op1.u.var).fe.fe_pos);
			break;

		case ZEND_ITER_OBJECT:
			/* !iter happens from exception */
			if (iter && ++iter->index > 0) {
				/* This could cause an endless loop if index becomes zero again.
				 * In case that ever happens we need an additional flag. */
				iter->funcs->move_forward(iter TSRMLS_CC);
				if (EG(exception)) {
					array->refcount--;
					zval_ptr_dtor(&array);
					ZEND_VM_NEXT_OPCODE();
				}
			}
			/* If index is zero we come from FE_RESET and checked valid() already. */
			if (!iter || (iter->index > 0 && iter->funcs->valid(iter TSRMLS_CC) == FAILURE)) {
				/* reached end of iteration */
				if (EG(exception)) {
					array->refcount--;
					zval_ptr_dtor(&array);
					ZEND_VM_NEXT_OPCODE();
				}
				ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.u.opline_num);
			}
			iter->funcs->get_current_data(iter, &value TSRMLS_CC);
			if (EG(exception)) {
				array->refcount--;
				zval_ptr_dtor(&array);
				ZEND_VM_NEXT_OPCODE();
			}
			if (!value) {
				/* failure in get_current_data */
				ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.u.opline_num);
			}
			if (use_key) {
				if (iter->funcs->get_current_key) {
					key_type = iter->funcs->get_current_key(iter, &str_key, &str_key_len, &int_key TSRMLS_CC);
					if (EG(exception)) {
						array->refcount--;
						zval_ptr_dtor(&array);
						ZEND_VM_NEXT_OPCODE();
					}
				} else {
					key_type = HASH_KEY_IS_LONG;
					int_key = iter->index;
				}
			}
			break;
	}

	if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
		SEPARATE_ZVAL_IF_NOT_REF(value);
		(*value)->is_ref = 1;
		EX_T(opline->result.u.var).var.ptr_ptr = value;
		(*value)->refcount++;
	} else {
		EX_T(opline->result.u.var).var.ptr_ptr = value;
		PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
	}

	if (use_key) {
		zend_op *op_data = opline+1;
		zval *key = &EX_T(op_data->result.u.var).tmp_var;

		switch (key_type) {
			case HASH_KEY_IS_STRING:
				Z_STRVAL_P(key) = str_key;
				Z_STRLEN_P(key) = str_key_len-1;
				Z_TYPE_P(key) = IS_STRING;
				break;
			case HASH_KEY_IS_LONG:
				Z_LVAL_P(key) = int_key;
				Z_TYPE_P(key) = IS_LONG;
				break;
			default:
			case HASH_KEY_NON_EXISTANT:
				ZVAL_NULL(key);
				break;
		}
	}

	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval tmp, *varname = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval **value;
	zend_bool isset = 1;
	HashTable *target_symbol_table;

	if (Z_TYPE_P(varname) != IS_STRING) {
		tmp = *varname;
		zval_copy_ctor(&tmp);
		convert_to_string(&tmp);
		varname = &tmp;
	}

	if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
		value = zend_std_get_static_property(EX_T(opline->op2.u.var).class_entry, Z_STRVAL_P(varname), Z_STRLEN_P(varname), 1 TSRMLS_CC);
		if (!value) {
			isset = 0;
		}
	} else {
		target_symbol_table = zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
		if (zend_hash_find(target_symbol_table, varname->value.str.val, varname->value.str.len+1, (void **) &value) == FAILURE) {
			isset = 0;
		}
	}

	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;

	switch (opline->extended_value) {
		case ZEND_ISSET:
			if (isset && Z_TYPE_PP(value) == IS_NULL) {
				Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 0;
			} else {
				Z_LVAL(EX_T(opline->result.u.var).tmp_var) = isset;
			}
			break;
		case ZEND_ISEMPTY:
			if (!isset || !i_zend_is_true(*value)) {
				Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 1;
			} else {
				Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 0;
			}
			break;
	}

	if (varname == &tmp) {
		zval_dtor(&tmp);
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_EXIT_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
#if 0 || (IS_VAR != IS_UNUSED)
	zend_op *opline = EX(opline);
	if (IS_VAR != IS_UNUSED) {
		zend_free_op free_op1;
		zval *ptr = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

		if (Z_TYPE_P(ptr) == IS_LONG) {
			EG(exit_status) = Z_LVAL_P(ptr);
		} else {
			zend_print_variable(ptr);
		}
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	}
#endif
	zend_bailout();
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_QM_ASSIGN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *value = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

	EX_T(opline->result.u.var).tmp_var = *value;
	if (!0) {
		zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var);
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INSTANCEOF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *expr = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zend_bool result;

	if (Z_TYPE_P(expr) == IS_OBJECT && Z_OBJ_HT_P(expr)->get_class_entry) {
		result = instanceof_function(Z_OBJCE_P(expr), EX_T(opline->op2.u.var).class_entry TSRMLS_CC);
	} else {
		result = 0;
	}
	ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, result);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ADD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	add_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SUB_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	sub_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_MUL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	mul_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_DIV_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	div_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_MOD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	mod_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	shift_left_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	shift_right_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CONCAT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	concat_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_IDENTICAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	is_identical_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	is_not_identical_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_EQUAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	is_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_NOT_EQUAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	is_not_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_SMALLER_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	is_smaller_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_SMALLER_OR_EQUAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	is_smaller_or_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_OR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	bitwise_or_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_AND_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	bitwise_and_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_XOR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	bitwise_xor_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BOOL_XOR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	boolean_xor_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;
	zend_free_op free_op1, free_op_data1;
	zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval *object;
	zval *property = &opline->op2.u.constant;
	zval *value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
	znode *result = &opline->result;
	zval **retval = &EX_T(result->u.var).var.ptr;
	int have_get_ptr = 0;

	if (IS_VAR == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
	}

	EX_T(result->u.var).var.ptr_ptr = NULL;
	make_real_object(object_ptr TSRMLS_CC);
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to assign property of non-object");

		FREE_OP(free_op_data1);

		if (!RETURN_VALUE_UNUSED(result)) {
			*retval = EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*retval);
		}
	} else {
		/* here we are sure we are dealing with an object */
		if (0) {
			MAKE_REAL_ZVAL_PTR(property);
		}

		/* here property is a string */
		if (opline->extended_value == ZEND_ASSIGN_OBJ
			&& Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
			zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
			if (zptr != NULL) { 			/* NULL means no success in getting PTR */
				SEPARATE_ZVAL_IF_NOT_REF(zptr);

				have_get_ptr = 1;
				binary_op(*zptr, *zptr, value TSRMLS_CC);
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = *zptr;
					PZVAL_LOCK(*retval);
				}
			}
		}

		if (!have_get_ptr) {
			zval *z = NULL;

			switch (opline->extended_value) {
				case ZEND_ASSIGN_OBJ:
					if (Z_OBJ_HT_P(object)->read_property) {
						z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
					}
					break;
				case ZEND_ASSIGN_DIM:
					if (Z_OBJ_HT_P(object)->read_dimension) {
						z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
					}
					break;
			}
			if (z) {
				if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
					zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

					if (z->refcount == 0) {
						zval_dtor(z);
						FREE_ZVAL(z);
					}
					z = value;
				}
				z->refcount++;
				SEPARATE_ZVAL_IF_NOT_REF(&z);
				binary_op(z, z, value TSRMLS_CC);
				switch (opline->extended_value) {
					case ZEND_ASSIGN_OBJ:
						Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
						break;
					case ZEND_ASSIGN_DIM:
						Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
						break;
				}
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = z;
					PZVAL_LOCK(*retval);
				}
				zval_ptr_dtor(&z);
			} else {
				zend_error(E_WARNING, "Attempt to assign property of non-object");
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = EG(uninitialized_zval_ptr);
					PZVAL_LOCK(*retval);
				}
			}
		}

		if (0) {
			zval_ptr_dtor(&property);
		} else {

		}
		FREE_OP(free_op_data1);
	}

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	/* assign_obj has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int zend_binary_assign_op_helper_SPEC_VAR_CONST(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op_data2, free_op_data1;
	zval **var_ptr;
	zval *value;
	zend_bool increment_opline = 0;

	switch (opline->extended_value) {
		case ZEND_ASSIGN_OBJ:
			return zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
			break;
		case ZEND_ASSIGN_DIM: {
				zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

				if (object_ptr && IS_VAR != IS_CV && !(free_op1.var != NULL)) {
					(*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
				}

				if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
					return zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
				} else {
					zend_op *op_data = opline+1;
					zval *dim = &opline->op2.u.constant;

					zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC);
					value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
					var_ptr = get_zval_ptr_ptr(&op_data->op2, EX(Ts), &free_op_data2, BP_VAR_RW);
					increment_opline = 1;
				}
			}
			break;
		default:
			value = &opline->op2.u.constant;
			var_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
			/* do nothing */
			break;
	}

	if (!var_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets");
	}

	if (*var_ptr == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}

		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
		if (increment_opline) {
			ZEND_VM_INC_OPCODE();
		}
		ZEND_VM_NEXT_OPCODE();
	}

	SEPARATE_ZVAL_IF_NOT_REF(var_ptr);

	if(Z_TYPE_PP(var_ptr) == IS_OBJECT && Z_OBJ_HANDLER_PP(var_ptr, get)
	   && Z_OBJ_HANDLER_PP(var_ptr, set)) {
		/* proxy object */
		zval *objval = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
		objval->refcount++;
		binary_op(objval, objval, value TSRMLS_CC);
		Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, objval TSRMLS_CC);
		zval_ptr_dtor(&objval);
	} else {
		binary_op(*var_ptr, *var_ptr, value TSRMLS_CC);
	}

	if (!RETURN_VALUE_UNUSED(&opline->result)) {
		EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
		PZVAL_LOCK(*var_ptr);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
	}

	if (increment_opline) {
		ZEND_VM_INC_OPCODE();
		FREE_OP(free_op_data1);
		FREE_OP_VAR_PTR(free_op_data2);
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_ADD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_CONST(add_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SUB_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_CONST(sub_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_MUL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_CONST(mul_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_DIV_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_CONST(div_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_MOD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_CONST(mod_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_CONST(shift_left_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_CONST(shift_right_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_CONCAT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_CONST(concat_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_OR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_CONST(bitwise_or_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_AND_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_CONST(bitwise_and_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_XOR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_CONST(bitwise_xor_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_pre_incdec_property_helper_SPEC_VAR_CONST(incdec_t incdec_op, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval *object;
	zval *property = &opline->op2.u.constant;
	zval **retval = &EX_T(opline->result.u.var).var.ptr;
	int have_get_ptr = 0;

	if (IS_VAR == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}

	make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");

		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			*retval = EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*retval);
		}
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
		ZEND_VM_NEXT_OPCODE();
	}

	/* here we are sure we are dealing with an object */

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}

	if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
		zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
		if (zptr != NULL) { 			/* NULL means no success in getting PTR */
			SEPARATE_ZVAL_IF_NOT_REF(zptr);

			have_get_ptr = 1;
			incdec_op(*zptr);
			if (!RETURN_VALUE_UNUSED(&opline->result)) {
				*retval = *zptr;
				PZVAL_LOCK(*retval);
			}
		}
	}

	if (!have_get_ptr) {
		if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
			zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);

			if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
				zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

				if (z->refcount == 0) {
					zval_dtor(z);
					FREE_ZVAL(z);
				}
				z = value;
			}
			z->refcount++;
			SEPARATE_ZVAL_IF_NOT_REF(&z);
			incdec_op(z);
			*retval = z;
			Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
			SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
			zval_ptr_dtor(&z);
		} else {
			zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
			if (!RETURN_VALUE_UNUSED(&opline->result)) {
				*retval = EG(uninitialized_zval_ptr);
				PZVAL_LOCK(*retval);
			}
		}
	}

	if (0) {
		zval_ptr_dtor(&property);
	} else {

	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_PRE_INC_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_pre_incdec_property_helper_SPEC_VAR_CONST(increment_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_PRE_DEC_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_pre_incdec_property_helper_SPEC_VAR_CONST(decrement_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_post_incdec_property_helper_SPEC_VAR_CONST(incdec_t incdec_op, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval *object;
	zval *property = &opline->op2.u.constant;
	zval *retval = &EX_T(opline->result.u.var).tmp_var;
	int have_get_ptr = 0;

	if (IS_VAR == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}

	make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");

		*retval = *EG(uninitialized_zval_ptr);
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
		ZEND_VM_NEXT_OPCODE();
	}

	/* here we are sure we are dealing with an object */

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}

	if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
		zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
		if (zptr != NULL) { 			/* NULL means no success in getting PTR */
			have_get_ptr = 1;
			SEPARATE_ZVAL_IF_NOT_REF(zptr);

			*retval = **zptr;
			zendi_zval_copy_ctor(*retval);

			incdec_op(*zptr);

		}
	}

	if (!have_get_ptr) {
		if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
			zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
			zval *z_copy;

			if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
				zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

				if (z->refcount == 0) {
					zval_dtor(z);
					FREE_ZVAL(z);
				}
				z = value;
			}
			*retval = *z;
			zendi_zval_copy_ctor(*retval);
			ALLOC_ZVAL(z_copy);
			*z_copy = *z;
			zendi_zval_copy_ctor(*z_copy);
			INIT_PZVAL(z_copy);
			incdec_op(z_copy);
			z->refcount++;
			Z_OBJ_HT_P(object)->write_property(object, property, z_copy TSRMLS_CC);
			zval_ptr_dtor(&z_copy);
			zval_ptr_dtor(&z);
		} else {
			zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
			*retval = *EG(uninitialized_zval_ptr);
		}
	}

	if (0) {
		zval_ptr_dtor(&property);
	} else {

	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_POST_INC_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_post_incdec_property_helper_SPEC_VAR_CONST(increment_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_POST_DEC_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_post_incdec_property_helper_SPEC_VAR_CONST(decrement_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_DIM_R_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *dim = &opline->op2.u.constant;

	if (opline->extended_value == ZEND_FETCH_ADD_LOCK &&
	    IS_VAR != IS_CV &&
	    EX_T(opline->op1.u.var).var.ptr_ptr) {
		PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
	}
	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC);

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *dim = &opline->op2.u.constant;

	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_W TSRMLS_CC);

	if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *dim = &opline->op2.u.constant;

	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC);

	if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_IS_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *dim = &opline->op2.u.constant;

	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_IS TSRMLS_CC);

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
	zval *dim;

	if (IS_CONST == IS_UNUSED && type == BP_VAR_R) {
		zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
	}
	dim = &opline->op2.u.constant;
	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, type TSRMLS_CC);

	if (IS_VAR == IS_VAR && type == BP_VAR_W && (free_op1.var != NULL) &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval *dim = &opline->op2.u.constant;

	/* Not needed in DIM_UNSET
	if (opline->extended_value == ZEND_FETCH_ADD_LOCK) {
		PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
	}
	*/
	if (IS_VAR == IS_CV) {
		if (container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
	}
	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_UNSET TSRMLS_CC);

	if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	if (EX_T(opline->result.u.var).var.ptr_ptr == NULL) {
		zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
	} else {
		zend_free_op free_res;

		PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &free_res);
		if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
		}
		PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
		FREE_OP_VAR_PTR(free_res);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int zend_fetch_property_address_read_helper_SPEC_VAR_CONST(int type, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *container;
	zval **retval;
	zend_free_op free_op1;

	zval *offset  = &opline->op2.u.constant;

	retval = &EX_T(opline->result.u.var).var.ptr;
	EX_T(opline->result.u.var).var.ptr_ptr = retval;

	container = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

	if (container == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			*retval = EG(error_zval_ptr);
			PZVAL_LOCK(*retval);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}

		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
		ZEND_VM_NEXT_OPCODE();
	}


	if (Z_TYPE_P(container) != IS_OBJECT || !Z_OBJ_HT_P(container)->read_property) {
		if (type != BP_VAR_IS) {
			zend_error(E_NOTICE, "Trying to get property of non-object");
		}
		*retval = EG(uninitialized_zval_ptr);
		SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
		AI_USE_PTR(EX_T(opline->result.u.var).var);

	} else {
		if (0) {
			MAKE_REAL_ZVAL_PTR(offset);
		}

		/* here we are sure we are dealing with an object */
		*retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);

		if (RETURN_VALUE_UNUSED(&opline->result) && ((*retval)->refcount == 0)) {
			zval_dtor(*retval);
			FREE_ZVAL(*retval);
		} else {
			SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}

		if (0) {
			zval_ptr_dtor(&offset);
		} else {

		}
	}

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_R_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_property_address_read_helper_SPEC_VAR_CONST(BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *property = &opline->op2.u.constant;

	if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_VAR != IS_CV) {
		PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
		EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr;
	}

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), property, BP_VAR_W TSRMLS_CC);
	if (0) {
		zval_ptr_dtor(&property);
	} else {

	}
	if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *property = &opline->op2.u.constant;

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), property, BP_VAR_RW TSRMLS_CC);
	if (0) {
		zval_ptr_dtor(&property);
	} else {

	}
	if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_IS_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_property_address_read_helper_SPEC_VAR_CONST(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) {
		/* Behave like FETCH_OBJ_W */
		zend_free_op free_op1;
		zval *property = &opline->op2.u.constant;

		if (0) {
			MAKE_REAL_ZVAL_PTR(property);
		}
		zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), property, BP_VAR_W TSRMLS_CC);
		if (0) {
			zval_ptr_dtor(&property);
		} else {

		}
		if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
		    READY_TO_DESTROY(free_op1.var) &&
		    !RETURN_VALUE_UNUSED(&opline->result)) {
			AI_USE_PTR(EX_T(opline->result.u.var).var);
			if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
			    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
				SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
			}
		}
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
		ZEND_VM_NEXT_OPCODE();
	} else {
		return zend_fetch_property_address_read_helper_SPEC_VAR_CONST(BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
	}
}

static int ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_res;
	zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval *property = &opline->op2.u.constant;

	if (IS_VAR == IS_CV) {
		if (container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
	}
	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC);
	if (0) {
		zval_ptr_dtor(&property);
	} else {

	}
	if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &free_res);
	if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
		SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
	}
	PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
	FREE_OP_VAR_PTR(free_res);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;
	zend_free_op free_op1;
	zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

	zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	/* assign_obj has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;
	zend_free_op free_op1;
	zval **object_ptr;

	if (IS_VAR == IS_CV || EX_T(opline->op1.u.var).var.ptr_ptr) {
		/* not an array offset */
		object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	} else {
		object_ptr = NULL;
	}

	if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
		zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC);
	} else {
		zend_free_op free_op_data1;
		zval *value;
		zval *dim = &opline->op2.u.constant;

		zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 0, BP_VAR_W TSRMLS_CC);

		value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
	 	zend_assign_to_variable(&opline->result, &op_data->op2, &op_data->op1, value, (IS_TMP_FREE(free_op_data1)?IS_TMP_VAR:op_data->op1.op_type), EX(Ts) TSRMLS_CC);
	 	FREE_OP_IF_VAR(free_op_data1);
	}
 	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	/* assign_dim has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval *value = &opline->op2.u.constant;

 	zend_assign_to_variable(&opline->result, &opline->op1, &opline->op2, value, (0?IS_TMP_VAR:IS_CONST), EX(Ts) TSRMLS_CC);
	/* zend_assign_to_variable() always takes care of op2, never free it! */

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *function_name;
	char *function_name_strval;
	int function_name_strlen;
	zend_free_op free_op1;

	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), NULL);

	function_name = &opline->op2.u.constant;

	if (Z_TYPE_P(function_name)!=IS_STRING) {
		zend_error_noreturn(E_ERROR, "Method name must be a string");
	}

	function_name_strval = Z_STRVAL_P(function_name);
	function_name_strlen = Z_STRLEN_P(function_name);

	EX(object) = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

	if (EX(object) && Z_TYPE_P(EX(object)) == IS_OBJECT) {
		if (Z_OBJ_HT_P(EX(object))->get_method == NULL) {
			zend_error_noreturn(E_ERROR, "Object does not support method calls");
		}

		/* First, locate the function. */
		EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen TSRMLS_CC);
		if (!EX(fbc)) {
			zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
		}
	} else {
		zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
	}

	if (!EX(object) || (EX(fbc) && (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
		EX(object) = NULL;
	} else {
		if (!PZVAL_IS_REF(EX(object))) {
			EX(object)->refcount++; /* For $this pointer */
		} else {
			zval *this_ptr;
			ALLOC_ZVAL(this_ptr);
			INIT_PZVAL_COPY(this_ptr, EX(object));
			zval_copy_ctor(this_ptr);
			EX(object) = this_ptr;
		}
	}

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CASE_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	int switch_expr_is_overloaded=0;
	zend_free_op free_op1;

	if (IS_VAR==IS_VAR) {
		if (EX_T(opline->op1.u.var).var.ptr_ptr) {
			PZVAL_LOCK(EX_T(opline->op1.u.var).var.ptr);
		} else {
			switch_expr_is_overloaded = 1;
			EX_T(opline->op1.u.var).str_offset.str->refcount++;
		}
	}
	is_equal_function(&EX_T(opline->result.u.var).tmp_var,
				 _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
				 &opline->op2.u.constant TSRMLS_CC);

	if (switch_expr_is_overloaded) {
		/* We only free op1 if this is a string offset,
		 * Since if it is a TMP_VAR, it'll be reused by
		 * other CASE opcodes (whereas string offsets
		 * are allocated at each get_zval_ptr())
		 */
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
		EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
		AI_USE_PTR(EX_T(opline->op1.u.var).var);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *array_ptr = &EX_T(opline->result.u.var).tmp_var;
	zval *expr_ptr;
	zval *offset=&opline->op2.u.constant;

#if 0 || IS_VAR == IS_VAR || IS_VAR == IS_CV
	zval **expr_ptr_ptr = NULL;

	if (opline->extended_value) {
		expr_ptr_ptr=_get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
		expr_ptr = *expr_ptr_ptr;
	} else {
		expr_ptr=_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	}
#else
	expr_ptr=_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
#endif

	if (0) { /* temporary variable */
		zval *new_expr;

		ALLOC_ZVAL(new_expr);
		INIT_PZVAL_COPY(new_expr, expr_ptr);
		expr_ptr = new_expr;
	} else {
#if 0 || IS_VAR == IS_VAR || IS_VAR == IS_CV
		if (opline->extended_value) {
			SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr_ptr);
			expr_ptr = *expr_ptr_ptr;
			expr_ptr->refcount++;
		} else
#endif
		if (PZVAL_IS_REF(expr_ptr)) {
			zval *new_expr;

			ALLOC_ZVAL(new_expr);
			INIT_PZVAL_COPY(new_expr, expr_ptr);
			expr_ptr = new_expr;
			zendi_zval_copy_ctor(*expr_ptr);
		} else {
			expr_ptr->refcount++;
		}
	}
	if (offset) {
		switch (Z_TYPE_P(offset)) {
			case IS_DOUBLE:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_LONG:
			case IS_BOOL:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), Z_LVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_STRING:
				zend_symtable_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_NULL:
				zend_hash_update(Z_ARRVAL_P(array_ptr), "", sizeof(""), &expr_ptr, sizeof(zval *), NULL);
				break;
			default:
				zend_error(E_WARNING, "Illegal offset type");
				zval_ptr_dtor(&expr_ptr);
				/* do nothing */
				break;
		}

	} else {
		zend_hash_next_index_insert(Z_ARRVAL_P(array_ptr), &expr_ptr, sizeof(zval *), NULL);
	}
	if (opline->extended_value) {
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	} else {
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_ARRAY_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	array_init(&EX_T(opline->result.u.var).tmp_var);
	if (IS_VAR == IS_UNUSED) {
		ZEND_VM_NEXT_OPCODE();
#if 0 || IS_VAR != IS_UNUSED
	} else {
		return ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
#endif
	}
}

static int ZEND_UNSET_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval *offset = &opline->op2.u.constant;
	long index;

	if (container) {
		if (IS_VAR == IS_CV && container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
		switch (Z_TYPE_PP(container)) {
			case IS_ARRAY: {
				HashTable *ht = Z_ARRVAL_PP(container);

				switch (Z_TYPE_P(offset)) {
					case IS_DOUBLE:
						index = (long) Z_DVAL_P(offset);
						zend_hash_index_del(ht, index);
						break;
					case IS_RESOURCE:
					case IS_BOOL:
					case IS_LONG:
						index = Z_LVAL_P(offset);
						zend_hash_index_del(ht, index);
						break;
					case IS_STRING:
						if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
							offset->refcount++;
						}
						if (zend_symtable_del(ht, offset->value.str.val, offset->value.str.len+1) == SUCCESS &&
					    ht == &EG(symbol_table)) {
							zend_execute_data *ex;
							ulong hash_value = zend_inline_hash_func(offset->value.str.val, offset->value.str.len+1);

							for (ex = execute_data; ex; ex = ex->prev_execute_data) {
								if (ex->op_array && ex->symbol_table == ht) {
									int i;

									for (i = 0; i < ex->op_array->last_var; i++) {
										if (ex->op_array->vars[i].hash_value == hash_value &&
										    ex->op_array->vars[i].name_len == offset->value.str.len &&
										    !memcmp(ex->op_array->vars[i].name, offset->value.str.val, offset->value.str.len)) {
											ex->CVs[i] = NULL;
											break;
										}
									}
								}
							}
						}
						if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
							zval_ptr_dtor(&offset);
						}
						break;
					case IS_NULL:
						zend_hash_del(ht, "", sizeof(""));
						break;
					default:
						zend_error(E_WARNING, "Illegal offset type in unset");
						break;
				}

				break;
			}
			case IS_OBJECT:
				if (!Z_OBJ_HT_P(*container)->unset_dimension) {
					zend_error_noreturn(E_ERROR, "Cannot use object as array");
				}
				if (0) {
					MAKE_REAL_ZVAL_PTR(offset);
				}
				Z_OBJ_HT_P(*container)->unset_dimension(*container, offset TSRMLS_CC);
				if (0) {
					zval_ptr_dtor(&offset);
				} else {

				}
				break;
			case IS_STRING:
				zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
				ZEND_VM_CONTINUE(); /* bailed out before */
			default:

				break;
		}
	} else {

	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_UNSET_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval *offset = &opline->op2.u.constant;

	if (container) {
		if (IS_VAR == IS_CV && container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
		if (Z_TYPE_PP(container) == IS_OBJECT) {
			if (0) {
				MAKE_REAL_ZVAL_PTR(offset);
			}
			Z_OBJ_HT_P(*container)->unset_property(*container, offset TSRMLS_CC);
			if (0) {
				zval_ptr_dtor(&offset);
			} else {

			}
		} else {

		}
	} else {

	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CONST(int prop_dim, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval **value = NULL;
	int result = 0;
	long index;

	if (container) {

		zval *offset = &opline->op2.u.constant;

		if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
			HashTable *ht;
			int isset = 0;

			ht = Z_ARRVAL_PP(container);

			switch (Z_TYPE_P(offset)) {
				case IS_DOUBLE:
					index = (long) Z_DVAL_P(offset);
					if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_RESOURCE:
				case IS_BOOL:
				case IS_LONG:
					index = Z_LVAL_P(offset);
					if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_STRING:
					if (zend_symtable_find(ht, offset->value.str.val, offset->value.str.len+1, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_NULL:
					if (zend_hash_find(ht, "", sizeof(""), (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				default:
					zend_error(E_WARNING, "Illegal offset type in isset or empty");

					break;
			}

			switch (opline->extended_value) {
				case ZEND_ISSET:
					if (isset && Z_TYPE_PP(value) == IS_NULL) {
						result = 0;
					} else {
						result = isset;
					}
					break;
				case ZEND_ISEMPTY:
					if (!isset || !i_zend_is_true(*value)) {
						result = 0;
					} else {
						result = 1;
					}
					break;
			}

		} else if (Z_TYPE_PP(container) == IS_OBJECT) {
			if (0) {
				MAKE_REAL_ZVAL_PTR(offset);
			}
			if (prop_dim) {
				result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value == ZEND_ISEMPTY) TSRMLS_CC);
			} else {
				result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value == ZEND_ISEMPTY) TSRMLS_CC);
			}
			if (0) {
				zval_ptr_dtor(&offset);
			} else {

			}
		} else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
			zval tmp;

			if (Z_TYPE_P(offset) != IS_LONG) {
				tmp = *offset;
				zval_copy_ctor(&tmp);
				convert_to_long(&tmp);
				offset = &tmp;
			}
			if (Z_TYPE_P(offset) == IS_LONG) {
				switch (opline->extended_value) {
					case ZEND_ISSET:
						if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
							result = 1;
						}
						break;
					case ZEND_ISEMPTY:
						if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
							result = 1;
						}
						break;
				}
			}

		} else {

		}
	}

	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;

	switch (opline->extended_value) {
		case ZEND_ISSET:
			Z_LVAL(EX_T(opline->result.u.var).tmp_var) = result;
			break;
		case ZEND_ISEMPTY:
			Z_LVAL(EX_T(opline->result.u.var).tmp_var) = !result;
			break;
	}

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CONST(0, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CONST(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ADD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	add_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SUB_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	sub_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_MUL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	mul_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_DIV_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	div_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_MOD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	mod_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	shift_left_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SR_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	shift_right_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CONCAT_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	concat_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_IDENTICAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	is_identical_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_NOT_IDENTICAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	is_not_identical_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_EQUAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	is_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_NOT_EQUAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	is_not_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_SMALLER_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	is_smaller_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_SMALLER_OR_EQUAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	is_smaller_or_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_OR_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	bitwise_or_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_AND_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	bitwise_and_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_XOR_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	bitwise_xor_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BOOL_XOR_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	boolean_xor_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;
	zend_free_op free_op1, free_op2, free_op_data1;
	zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval *object;
	zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	zval *value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
	znode *result = &opline->result;
	zval **retval = &EX_T(result->u.var).var.ptr;
	int have_get_ptr = 0;

	if (IS_VAR == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
	}

	EX_T(result->u.var).var.ptr_ptr = NULL;
	make_real_object(object_ptr TSRMLS_CC);
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to assign property of non-object");
		zval_dtor(free_op2.var);
		FREE_OP(free_op_data1);

		if (!RETURN_VALUE_UNUSED(result)) {
			*retval = EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*retval);
		}
	} else {
		/* here we are sure we are dealing with an object */
		if (1) {
			MAKE_REAL_ZVAL_PTR(property);
		}

		/* here property is a string */
		if (opline->extended_value == ZEND_ASSIGN_OBJ
			&& Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
			zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
			if (zptr != NULL) { 			/* NULL means no success in getting PTR */
				SEPARATE_ZVAL_IF_NOT_REF(zptr);

				have_get_ptr = 1;
				binary_op(*zptr, *zptr, value TSRMLS_CC);
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = *zptr;
					PZVAL_LOCK(*retval);
				}
			}
		}

		if (!have_get_ptr) {
			zval *z = NULL;

			switch (opline->extended_value) {
				case ZEND_ASSIGN_OBJ:
					if (Z_OBJ_HT_P(object)->read_property) {
						z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
					}
					break;
				case ZEND_ASSIGN_DIM:
					if (Z_OBJ_HT_P(object)->read_dimension) {
						z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
					}
					break;
			}
			if (z) {
				if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
					zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

					if (z->refcount == 0) {
						zval_dtor(z);
						FREE_ZVAL(z);
					}
					z = value;
				}
				z->refcount++;
				SEPARATE_ZVAL_IF_NOT_REF(&z);
				binary_op(z, z, value TSRMLS_CC);
				switch (opline->extended_value) {
					case ZEND_ASSIGN_OBJ:
						Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
						break;
					case ZEND_ASSIGN_DIM:
						Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
						break;
				}
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = z;
					PZVAL_LOCK(*retval);
				}
				zval_ptr_dtor(&z);
			} else {
				zend_error(E_WARNING, "Attempt to assign property of non-object");
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = EG(uninitialized_zval_ptr);
					PZVAL_LOCK(*retval);
				}
			}
		}

		if (1) {
			zval_ptr_dtor(&property);
		} else {
			zval_dtor(free_op2.var);
		}
		FREE_OP(free_op_data1);
	}

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	/* assign_obj has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int zend_binary_assign_op_helper_SPEC_VAR_TMP(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2, free_op_data2, free_op_data1;
	zval **var_ptr;
	zval *value;
	zend_bool increment_opline = 0;

	switch (opline->extended_value) {
		case ZEND_ASSIGN_OBJ:
			return zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
			break;
		case ZEND_ASSIGN_DIM: {
				zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

				if (object_ptr && IS_VAR != IS_CV && !(free_op1.var != NULL)) {
					(*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
				}

				if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
					return zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
				} else {
					zend_op *op_data = opline+1;
					zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

					zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 1, BP_VAR_RW TSRMLS_CC);
					value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
					var_ptr = get_zval_ptr_ptr(&op_data->op2, EX(Ts), &free_op_data2, BP_VAR_RW);
					increment_opline = 1;
				}
			}
			break;
		default:
			value = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
			var_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
			/* do nothing */
			break;
	}

	if (!var_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets");
	}

	if (*var_ptr == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}
		zval_dtor(free_op2.var);
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
		if (increment_opline) {
			ZEND_VM_INC_OPCODE();
		}
		ZEND_VM_NEXT_OPCODE();
	}

	SEPARATE_ZVAL_IF_NOT_REF(var_ptr);

	if(Z_TYPE_PP(var_ptr) == IS_OBJECT && Z_OBJ_HANDLER_PP(var_ptr, get)
	   && Z_OBJ_HANDLER_PP(var_ptr, set)) {
		/* proxy object */
		zval *objval = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
		objval->refcount++;
		binary_op(objval, objval, value TSRMLS_CC);
		Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, objval TSRMLS_CC);
		zval_ptr_dtor(&objval);
	} else {
		binary_op(*var_ptr, *var_ptr, value TSRMLS_CC);
	}

	if (!RETURN_VALUE_UNUSED(&opline->result)) {
		EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
		PZVAL_LOCK(*var_ptr);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
	}
	zval_dtor(free_op2.var);

	if (increment_opline) {
		ZEND_VM_INC_OPCODE();
		FREE_OP(free_op_data1);
		FREE_OP_VAR_PTR(free_op_data2);
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_ADD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_TMP(add_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SUB_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_TMP(sub_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_MUL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_TMP(mul_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_DIV_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_TMP(div_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_MOD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_TMP(mod_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_TMP(shift_left_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SR_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_TMP(shift_right_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_CONCAT_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_TMP(concat_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_OR_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_TMP(bitwise_or_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_AND_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_TMP(bitwise_and_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_XOR_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_TMP(bitwise_xor_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_pre_incdec_property_helper_SPEC_VAR_TMP(incdec_t incdec_op, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval *object;
	zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	zval **retval = &EX_T(opline->result.u.var).var.ptr;
	int have_get_ptr = 0;

	if (IS_VAR == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}

	make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
		zval_dtor(free_op2.var);
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			*retval = EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*retval);
		}
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
		ZEND_VM_NEXT_OPCODE();
	}

	/* here we are sure we are dealing with an object */

	if (1) {
		MAKE_REAL_ZVAL_PTR(property);
	}

	if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
		zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
		if (zptr != NULL) { 			/* NULL means no success in getting PTR */
			SEPARATE_ZVAL_IF_NOT_REF(zptr);

			have_get_ptr = 1;
			incdec_op(*zptr);
			if (!RETURN_VALUE_UNUSED(&opline->result)) {
				*retval = *zptr;
				PZVAL_LOCK(*retval);
			}
		}
	}

	if (!have_get_ptr) {
		if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
			zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);

			if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
				zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

				if (z->refcount == 0) {
					zval_dtor(z);
					FREE_ZVAL(z);
				}
				z = value;
			}
			z->refcount++;
			SEPARATE_ZVAL_IF_NOT_REF(&z);
			incdec_op(z);
			*retval = z;
			Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
			SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
			zval_ptr_dtor(&z);
		} else {
			zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
			if (!RETURN_VALUE_UNUSED(&opline->result)) {
				*retval = EG(uninitialized_zval_ptr);
				PZVAL_LOCK(*retval);
			}
		}
	}

	if (1) {
		zval_ptr_dtor(&property);
	} else {
		zval_dtor(free_op2.var);
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_PRE_INC_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_pre_incdec_property_helper_SPEC_VAR_TMP(increment_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_PRE_DEC_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_pre_incdec_property_helper_SPEC_VAR_TMP(decrement_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_post_incdec_property_helper_SPEC_VAR_TMP(incdec_t incdec_op, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval *object;
	zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	zval *retval = &EX_T(opline->result.u.var).tmp_var;
	int have_get_ptr = 0;

	if (IS_VAR == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}

	make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
		zval_dtor(free_op2.var);
		*retval = *EG(uninitialized_zval_ptr);
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
		ZEND_VM_NEXT_OPCODE();
	}

	/* here we are sure we are dealing with an object */

	if (1) {
		MAKE_REAL_ZVAL_PTR(property);
	}

	if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
		zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
		if (zptr != NULL) { 			/* NULL means no success in getting PTR */
			have_get_ptr = 1;
			SEPARATE_ZVAL_IF_NOT_REF(zptr);

			*retval = **zptr;
			zendi_zval_copy_ctor(*retval);

			incdec_op(*zptr);

		}
	}

	if (!have_get_ptr) {
		if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
			zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
			zval *z_copy;

			if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
				zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

				if (z->refcount == 0) {
					zval_dtor(z);
					FREE_ZVAL(z);
				}
				z = value;
			}
			*retval = *z;
			zendi_zval_copy_ctor(*retval);
			ALLOC_ZVAL(z_copy);
			*z_copy = *z;
			zendi_zval_copy_ctor(*z_copy);
			INIT_PZVAL(z_copy);
			incdec_op(z_copy);
			z->refcount++;
			Z_OBJ_HT_P(object)->write_property(object, property, z_copy TSRMLS_CC);
			zval_ptr_dtor(&z_copy);
			zval_ptr_dtor(&z);
		} else {
			zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
			*retval = *EG(uninitialized_zval_ptr);
		}
	}

	if (1) {
		zval_ptr_dtor(&property);
	} else {
		zval_dtor(free_op2.var);
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_POST_INC_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_post_incdec_property_helper_SPEC_VAR_TMP(increment_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_POST_DEC_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_post_incdec_property_helper_SPEC_VAR_TMP(decrement_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_DIM_R_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (opline->extended_value == ZEND_FETCH_ADD_LOCK &&
	    IS_VAR != IS_CV &&
	    EX_T(opline->op1.u.var).var.ptr_ptr) {
		PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
	}
	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 1, BP_VAR_R TSRMLS_CC);
	zval_dtor(free_op2.var);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 1, BP_VAR_W TSRMLS_CC);
	zval_dtor(free_op2.var);
	if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 1, BP_VAR_RW TSRMLS_CC);
	zval_dtor(free_op2.var);
	if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_IS_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 1, BP_VAR_IS TSRMLS_CC);
	zval_dtor(free_op2.var);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
	zval *dim;

	if (IS_TMP_VAR == IS_UNUSED && type == BP_VAR_R) {
		zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
	}
	dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 1, type TSRMLS_CC);
	zval_dtor(free_op2.var);
	if (IS_VAR == IS_VAR && type == BP_VAR_W && (free_op1.var != NULL) &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	/* Not needed in DIM_UNSET
	if (opline->extended_value == ZEND_FETCH_ADD_LOCK) {
		PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
	}
	*/
	if (IS_VAR == IS_CV) {
		if (container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
	}
	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, dim, 1, BP_VAR_UNSET TSRMLS_CC);
	zval_dtor(free_op2.var);
	if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	if (EX_T(opline->result.u.var).var.ptr_ptr == NULL) {
		zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
	} else {
		zend_free_op free_res;

		PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &free_res);
		if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
		}
		PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
		FREE_OP_VAR_PTR(free_res);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int zend_fetch_property_address_read_helper_SPEC_VAR_TMP(int type, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *container;
	zval **retval;
	zend_free_op free_op1;
	zend_free_op free_op2;
	zval *offset  = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	retval = &EX_T(opline->result.u.var).var.ptr;
	EX_T(opline->result.u.var).var.ptr_ptr = retval;

	container = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

	if (container == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			*retval = EG(error_zval_ptr);
			PZVAL_LOCK(*retval);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}
		zval_dtor(free_op2.var);
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
		ZEND_VM_NEXT_OPCODE();
	}


	if (Z_TYPE_P(container) != IS_OBJECT || !Z_OBJ_HT_P(container)->read_property) {
		if (type != BP_VAR_IS) {
			zend_error(E_NOTICE, "Trying to get property of non-object");
		}
		*retval = EG(uninitialized_zval_ptr);
		SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		zval_dtor(free_op2.var);
	} else {
		if (1) {
			MAKE_REAL_ZVAL_PTR(offset);
		}

		/* here we are sure we are dealing with an object */
		*retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);

		if (RETURN_VALUE_UNUSED(&opline->result) && ((*retval)->refcount == 0)) {
			zval_dtor(*retval);
			FREE_ZVAL(*retval);
		} else {
			SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}

		if (1) {
			zval_ptr_dtor(&offset);
		} else {
			zval_dtor(free_op2.var);
		}
	}

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_R_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_property_address_read_helper_SPEC_VAR_TMP(BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_VAR != IS_CV) {
		PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
		EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr;
	}

	if (1) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), property, BP_VAR_W TSRMLS_CC);
	if (1) {
		zval_ptr_dtor(&property);
	} else {
		zval_dtor(free_op2.var);
	}
	if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (1) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), property, BP_VAR_RW TSRMLS_CC);
	if (1) {
		zval_ptr_dtor(&property);
	} else {
		zval_dtor(free_op2.var);
	}
	if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_IS_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_property_address_read_helper_SPEC_VAR_TMP(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) {
		/* Behave like FETCH_OBJ_W */
		zend_free_op free_op1, free_op2;
		zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

		if (1) {
			MAKE_REAL_ZVAL_PTR(property);
		}
		zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), property, BP_VAR_W TSRMLS_CC);
		if (1) {
			zval_ptr_dtor(&property);
		} else {
			zval_dtor(free_op2.var);
		}
		if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
		    READY_TO_DESTROY(free_op1.var) &&
		    !RETURN_VALUE_UNUSED(&opline->result)) {
			AI_USE_PTR(EX_T(opline->result.u.var).var);
			if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
			    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
				SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
			}
		}
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
		ZEND_VM_NEXT_OPCODE();
	} else {
		return zend_fetch_property_address_read_helper_SPEC_VAR_TMP(BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
	}
}

static int ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2, free_res;
	zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (IS_VAR == IS_CV) {
		if (container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
	}
	if (1) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC);
	if (1) {
		zval_ptr_dtor(&property);
	} else {
		zval_dtor(free_op2.var);
	}
	if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &free_res);
	if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
		SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
	}
	PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
	FREE_OP_VAR_PTR(free_res);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;
	zend_free_op free_op1;
	zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

	zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	/* assign_obj has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;
	zend_free_op free_op1;
	zval **object_ptr;

	if (IS_VAR == IS_CV || EX_T(opline->op1.u.var).var.ptr_ptr) {
		/* not an array offset */
		object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	} else {
		object_ptr = NULL;
	}

	if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
		zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC);
	} else {
		zend_free_op free_op2, free_op_data1;
		zval *value;
		zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

		zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 1, BP_VAR_W TSRMLS_CC);
		zval_dtor(free_op2.var);

		value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
	 	zend_assign_to_variable(&opline->result, &op_data->op2, &op_data->op1, value, (IS_TMP_FREE(free_op_data1)?IS_TMP_VAR:op_data->op1.op_type), EX(Ts) TSRMLS_CC);
	 	FREE_OP_IF_VAR(free_op_data1);
	}
 	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	/* assign_dim has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zval *value = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

 	zend_assign_to_variable(&opline->result, &opline->op1, &opline->op2, value, (1?IS_TMP_VAR:IS_TMP_VAR), EX(Ts) TSRMLS_CC);
	/* zend_assign_to_variable() always takes care of op2, never free it! */

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *function_name;
	char *function_name_strval;
	int function_name_strlen;
	zend_free_op free_op1, free_op2;

	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), NULL);

	function_name = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (Z_TYPE_P(function_name)!=IS_STRING) {
		zend_error_noreturn(E_ERROR, "Method name must be a string");
	}

	function_name_strval = Z_STRVAL_P(function_name);
	function_name_strlen = Z_STRLEN_P(function_name);

	EX(object) = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

	if (EX(object) && Z_TYPE_P(EX(object)) == IS_OBJECT) {
		if (Z_OBJ_HT_P(EX(object))->get_method == NULL) {
			zend_error_noreturn(E_ERROR, "Object does not support method calls");
		}

		/* First, locate the function. */
		EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen TSRMLS_CC);
		if (!EX(fbc)) {
			zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
		}
	} else {
		zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
	}

	if (!EX(object) || (EX(fbc) && (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
		EX(object) = NULL;
	} else {
		if (!PZVAL_IS_REF(EX(object))) {
			EX(object)->refcount++; /* For $this pointer */
		} else {
			zval *this_ptr;
			ALLOC_ZVAL(this_ptr);
			INIT_PZVAL_COPY(this_ptr, EX(object));
			zval_copy_ctor(this_ptr);
			EX(object) = this_ptr;
		}
	}

	zval_dtor(free_op2.var);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CASE_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	int switch_expr_is_overloaded=0;
	zend_free_op free_op1, free_op2;

	if (IS_VAR==IS_VAR) {
		if (EX_T(opline->op1.u.var).var.ptr_ptr) {
			PZVAL_LOCK(EX_T(opline->op1.u.var).var.ptr);
		} else {
			switch_expr_is_overloaded = 1;
			EX_T(opline->op1.u.var).str_offset.str->refcount++;
		}
	}
	is_equal_function(&EX_T(opline->result.u.var).tmp_var,
				 _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
				 _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	if (switch_expr_is_overloaded) {
		/* We only free op1 if this is a string offset,
		 * Since if it is a TMP_VAR, it'll be reused by
		 * other CASE opcodes (whereas string offsets
		 * are allocated at each get_zval_ptr())
		 */
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
		EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
		AI_USE_PTR(EX_T(opline->op1.u.var).var);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *array_ptr = &EX_T(opline->result.u.var).tmp_var;
	zval *expr_ptr;
	zval *offset=_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

#if 0 || IS_VAR == IS_VAR || IS_VAR == IS_CV
	zval **expr_ptr_ptr = NULL;

	if (opline->extended_value) {
		expr_ptr_ptr=_get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
		expr_ptr = *expr_ptr_ptr;
	} else {
		expr_ptr=_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	}
#else
	expr_ptr=_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
#endif

	if (0) { /* temporary variable */
		zval *new_expr;

		ALLOC_ZVAL(new_expr);
		INIT_PZVAL_COPY(new_expr, expr_ptr);
		expr_ptr = new_expr;
	} else {
#if 0 || IS_VAR == IS_VAR || IS_VAR == IS_CV
		if (opline->extended_value) {
			SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr_ptr);
			expr_ptr = *expr_ptr_ptr;
			expr_ptr->refcount++;
		} else
#endif
		if (PZVAL_IS_REF(expr_ptr)) {
			zval *new_expr;

			ALLOC_ZVAL(new_expr);
			INIT_PZVAL_COPY(new_expr, expr_ptr);
			expr_ptr = new_expr;
			zendi_zval_copy_ctor(*expr_ptr);
		} else {
			expr_ptr->refcount++;
		}
	}
	if (offset) {
		switch (Z_TYPE_P(offset)) {
			case IS_DOUBLE:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_LONG:
			case IS_BOOL:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), Z_LVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_STRING:
				zend_symtable_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_NULL:
				zend_hash_update(Z_ARRVAL_P(array_ptr), "", sizeof(""), &expr_ptr, sizeof(zval *), NULL);
				break;
			default:
				zend_error(E_WARNING, "Illegal offset type");
				zval_ptr_dtor(&expr_ptr);
				/* do nothing */
				break;
		}
		zval_dtor(free_op2.var);
	} else {
		zend_hash_next_index_insert(Z_ARRVAL_P(array_ptr), &expr_ptr, sizeof(zval *), NULL);
	}
	if (opline->extended_value) {
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	} else {
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_ARRAY_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	array_init(&EX_T(opline->result.u.var).tmp_var);
	if (IS_VAR == IS_UNUSED) {
		ZEND_VM_NEXT_OPCODE();
#if 0 || IS_VAR != IS_UNUSED
	} else {
		return ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
#endif
	}
}

static int ZEND_UNSET_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval *offset = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	long index;

	if (container) {
		if (IS_VAR == IS_CV && container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
		switch (Z_TYPE_PP(container)) {
			case IS_ARRAY: {
				HashTable *ht = Z_ARRVAL_PP(container);

				switch (Z_TYPE_P(offset)) {
					case IS_DOUBLE:
						index = (long) Z_DVAL_P(offset);
						zend_hash_index_del(ht, index);
						break;
					case IS_RESOURCE:
					case IS_BOOL:
					case IS_LONG:
						index = Z_LVAL_P(offset);
						zend_hash_index_del(ht, index);
						break;
					case IS_STRING:
						if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
							offset->refcount++;
						}
						if (zend_symtable_del(ht, offset->value.str.val, offset->value.str.len+1) == SUCCESS &&
					    ht == &EG(symbol_table)) {
							zend_execute_data *ex;
							ulong hash_value = zend_inline_hash_func(offset->value.str.val, offset->value.str.len+1);

							for (ex = execute_data; ex; ex = ex->prev_execute_data) {
								if (ex->op_array && ex->symbol_table == ht) {
									int i;

									for (i = 0; i < ex->op_array->last_var; i++) {
										if (ex->op_array->vars[i].hash_value == hash_value &&
										    ex->op_array->vars[i].name_len == offset->value.str.len &&
										    !memcmp(ex->op_array->vars[i].name, offset->value.str.val, offset->value.str.len)) {
											ex->CVs[i] = NULL;
											break;
										}
									}
								}
							}
						}
						if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
							zval_ptr_dtor(&offset);
						}
						break;
					case IS_NULL:
						zend_hash_del(ht, "", sizeof(""));
						break;
					default:
						zend_error(E_WARNING, "Illegal offset type in unset");
						break;
				}
				zval_dtor(free_op2.var);
				break;
			}
			case IS_OBJECT:
				if (!Z_OBJ_HT_P(*container)->unset_dimension) {
					zend_error_noreturn(E_ERROR, "Cannot use object as array");
				}
				if (1) {
					MAKE_REAL_ZVAL_PTR(offset);
				}
				Z_OBJ_HT_P(*container)->unset_dimension(*container, offset TSRMLS_CC);
				if (1) {
					zval_ptr_dtor(&offset);
				} else {
					zval_dtor(free_op2.var);
				}
				break;
			case IS_STRING:
				zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
				ZEND_VM_CONTINUE(); /* bailed out before */
			default:
				zval_dtor(free_op2.var);
				break;
		}
	} else {
		zval_dtor(free_op2.var);
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_UNSET_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval *offset = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (container) {
		if (IS_VAR == IS_CV && container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
		if (Z_TYPE_PP(container) == IS_OBJECT) {
			if (1) {
				MAKE_REAL_ZVAL_PTR(offset);
			}
			Z_OBJ_HT_P(*container)->unset_property(*container, offset TSRMLS_CC);
			if (1) {
				zval_ptr_dtor(&offset);
			} else {
				zval_dtor(free_op2.var);
			}
		} else {
			zval_dtor(free_op2.var);
		}
	} else {
		zval_dtor(free_op2.var);
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_TMP(int prop_dim, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval **value = NULL;
	int result = 0;
	long index;

	if (container) {
		zend_free_op free_op2;
		zval *offset = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

		if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
			HashTable *ht;
			int isset = 0;

			ht = Z_ARRVAL_PP(container);

			switch (Z_TYPE_P(offset)) {
				case IS_DOUBLE:
					index = (long) Z_DVAL_P(offset);
					if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_RESOURCE:
				case IS_BOOL:
				case IS_LONG:
					index = Z_LVAL_P(offset);
					if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_STRING:
					if (zend_symtable_find(ht, offset->value.str.val, offset->value.str.len+1, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_NULL:
					if (zend_hash_find(ht, "", sizeof(""), (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				default:
					zend_error(E_WARNING, "Illegal offset type in isset or empty");

					break;
			}

			switch (opline->extended_value) {
				case ZEND_ISSET:
					if (isset && Z_TYPE_PP(value) == IS_NULL) {
						result = 0;
					} else {
						result = isset;
					}
					break;
				case ZEND_ISEMPTY:
					if (!isset || !i_zend_is_true(*value)) {
						result = 0;
					} else {
						result = 1;
					}
					break;
			}
			zval_dtor(free_op2.var);
		} else if (Z_TYPE_PP(container) == IS_OBJECT) {
			if (1) {
				MAKE_REAL_ZVAL_PTR(offset);
			}
			if (prop_dim) {
				result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value == ZEND_ISEMPTY) TSRMLS_CC);
			} else {
				result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value == ZEND_ISEMPTY) TSRMLS_CC);
			}
			if (1) {
				zval_ptr_dtor(&offset);
			} else {
				zval_dtor(free_op2.var);
			}
		} else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
			zval tmp;

			if (Z_TYPE_P(offset) != IS_LONG) {
				tmp = *offset;
				zval_copy_ctor(&tmp);
				convert_to_long(&tmp);
				offset = &tmp;
			}
			if (Z_TYPE_P(offset) == IS_LONG) {
				switch (opline->extended_value) {
					case ZEND_ISSET:
						if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
							result = 1;
						}
						break;
					case ZEND_ISEMPTY:
						if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
							result = 1;
						}
						break;
				}
			}
			zval_dtor(free_op2.var);
		} else {
			zval_dtor(free_op2.var);
		}
	}

	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;

	switch (opline->extended_value) {
		case ZEND_ISSET:
			Z_LVAL(EX_T(opline->result.u.var).tmp_var) = result;
			break;
		case ZEND_ISEMPTY:
			Z_LVAL(EX_T(opline->result.u.var).tmp_var) = !result;
			break;
	}

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_TMP(0, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_TMP(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ADD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	add_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SUB_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	sub_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_MUL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	mul_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_DIV_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	div_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_MOD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	mod_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	shift_left_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	shift_right_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CONCAT_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	concat_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_IDENTICAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	is_identical_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_NOT_IDENTICAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	is_not_identical_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_EQUAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	is_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_NOT_EQUAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	is_not_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_SMALLER_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	is_smaller_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_SMALLER_OR_EQUAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	is_smaller_or_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_OR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	bitwise_or_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_AND_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	bitwise_and_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_XOR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	bitwise_xor_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BOOL_XOR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;

	boolean_xor_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;
	zend_free_op free_op1, free_op2, free_op_data1;
	zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval *object;
	zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	zval *value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
	znode *result = &opline->result;
	zval **retval = &EX_T(result->u.var).var.ptr;
	int have_get_ptr = 0;

	if (IS_VAR == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
	}

	EX_T(result->u.var).var.ptr_ptr = NULL;
	make_real_object(object_ptr TSRMLS_CC);
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to assign property of non-object");
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
		FREE_OP(free_op_data1);

		if (!RETURN_VALUE_UNUSED(result)) {
			*retval = EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*retval);
		}
	} else {
		/* here we are sure we are dealing with an object */
		if (0) {
			MAKE_REAL_ZVAL_PTR(property);
		}

		/* here property is a string */
		if (opline->extended_value == ZEND_ASSIGN_OBJ
			&& Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
			zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
			if (zptr != NULL) { 			/* NULL means no success in getting PTR */
				SEPARATE_ZVAL_IF_NOT_REF(zptr);

				have_get_ptr = 1;
				binary_op(*zptr, *zptr, value TSRMLS_CC);
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = *zptr;
					PZVAL_LOCK(*retval);
				}
			}
		}

		if (!have_get_ptr) {
			zval *z = NULL;

			switch (opline->extended_value) {
				case ZEND_ASSIGN_OBJ:
					if (Z_OBJ_HT_P(object)->read_property) {
						z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
					}
					break;
				case ZEND_ASSIGN_DIM:
					if (Z_OBJ_HT_P(object)->read_dimension) {
						z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
					}
					break;
			}
			if (z) {
				if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
					zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

					if (z->refcount == 0) {
						zval_dtor(z);
						FREE_ZVAL(z);
					}
					z = value;
				}
				z->refcount++;
				SEPARATE_ZVAL_IF_NOT_REF(&z);
				binary_op(z, z, value TSRMLS_CC);
				switch (opline->extended_value) {
					case ZEND_ASSIGN_OBJ:
						Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
						break;
					case ZEND_ASSIGN_DIM:
						Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
						break;
				}
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = z;
					PZVAL_LOCK(*retval);
				}
				zval_ptr_dtor(&z);
			} else {
				zend_error(E_WARNING, "Attempt to assign property of non-object");
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = EG(uninitialized_zval_ptr);
					PZVAL_LOCK(*retval);
				}
			}
		}

		if (0) {
			zval_ptr_dtor(&property);
		} else {
			if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
		}
		FREE_OP(free_op_data1);
	}

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	/* assign_obj has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int zend_binary_assign_op_helper_SPEC_VAR_VAR(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2, free_op_data2, free_op_data1;
	zval **var_ptr;
	zval *value;
	zend_bool increment_opline = 0;

	switch (opline->extended_value) {
		case ZEND_ASSIGN_OBJ:
			return zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
			break;
		case ZEND_ASSIGN_DIM: {
				zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

				if (object_ptr && IS_VAR != IS_CV && !(free_op1.var != NULL)) {
					(*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
				}

				if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
					return zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
				} else {
					zend_op *op_data = opline+1;
					zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

					zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC);
					value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
					var_ptr = get_zval_ptr_ptr(&op_data->op2, EX(Ts), &free_op_data2, BP_VAR_RW);
					increment_opline = 1;
				}
			}
			break;
		default:
			value = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
			var_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
			/* do nothing */
			break;
	}

	if (!var_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets");
	}

	if (*var_ptr == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
		if (increment_opline) {
			ZEND_VM_INC_OPCODE();
		}
		ZEND_VM_NEXT_OPCODE();
	}

	SEPARATE_ZVAL_IF_NOT_REF(var_ptr);

	if(Z_TYPE_PP(var_ptr) == IS_OBJECT && Z_OBJ_HANDLER_PP(var_ptr, get)
	   && Z_OBJ_HANDLER_PP(var_ptr, set)) {
		/* proxy object */
		zval *objval = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
		objval->refcount++;
		binary_op(objval, objval, value TSRMLS_CC);
		Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, objval TSRMLS_CC);
		zval_ptr_dtor(&objval);
	} else {
		binary_op(*var_ptr, *var_ptr, value TSRMLS_CC);
	}

	if (!RETURN_VALUE_UNUSED(&opline->result)) {
		EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
		PZVAL_LOCK(*var_ptr);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
	}
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};

	if (increment_opline) {
		ZEND_VM_INC_OPCODE();
		FREE_OP(free_op_data1);
		FREE_OP_VAR_PTR(free_op_data2);
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_ADD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_VAR(add_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SUB_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_VAR(sub_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_MUL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_VAR(mul_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_DIV_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_VAR(div_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_MOD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_VAR(mod_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_VAR(shift_left_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_VAR(shift_right_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_CONCAT_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_VAR(concat_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_OR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_VAR(bitwise_or_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_AND_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_VAR(bitwise_and_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_XOR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_VAR(bitwise_xor_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_pre_incdec_property_helper_SPEC_VAR_VAR(incdec_t incdec_op, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval *object;
	zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	zval **retval = &EX_T(opline->result.u.var).var.ptr;
	int have_get_ptr = 0;

	if (IS_VAR == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}

	make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			*retval = EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*retval);
		}
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
		ZEND_VM_NEXT_OPCODE();
	}

	/* here we are sure we are dealing with an object */

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}

	if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
		zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
		if (zptr != NULL) { 			/* NULL means no success in getting PTR */
			SEPARATE_ZVAL_IF_NOT_REF(zptr);

			have_get_ptr = 1;
			incdec_op(*zptr);
			if (!RETURN_VALUE_UNUSED(&opline->result)) {
				*retval = *zptr;
				PZVAL_LOCK(*retval);
			}
		}
	}

	if (!have_get_ptr) {
		if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
			zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);

			if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
				zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

				if (z->refcount == 0) {
					zval_dtor(z);
					FREE_ZVAL(z);
				}
				z = value;
			}
			z->refcount++;
			SEPARATE_ZVAL_IF_NOT_REF(&z);
			incdec_op(z);
			*retval = z;
			Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
			SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
			zval_ptr_dtor(&z);
		} else {
			zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
			if (!RETURN_VALUE_UNUSED(&opline->result)) {
				*retval = EG(uninitialized_zval_ptr);
				PZVAL_LOCK(*retval);
			}
		}
	}

	if (0) {
		zval_ptr_dtor(&property);
	} else {
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_PRE_INC_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_pre_incdec_property_helper_SPEC_VAR_VAR(increment_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_PRE_DEC_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_pre_incdec_property_helper_SPEC_VAR_VAR(decrement_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_post_incdec_property_helper_SPEC_VAR_VAR(incdec_t incdec_op, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval *object;
	zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	zval *retval = &EX_T(opline->result.u.var).tmp_var;
	int have_get_ptr = 0;

	if (IS_VAR == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}

	make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
		*retval = *EG(uninitialized_zval_ptr);
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
		ZEND_VM_NEXT_OPCODE();
	}

	/* here we are sure we are dealing with an object */

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}

	if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
		zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
		if (zptr != NULL) { 			/* NULL means no success in getting PTR */
			have_get_ptr = 1;
			SEPARATE_ZVAL_IF_NOT_REF(zptr);

			*retval = **zptr;
			zendi_zval_copy_ctor(*retval);

			incdec_op(*zptr);

		}
	}

	if (!have_get_ptr) {
		if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
			zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
			zval *z_copy;

			if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
				zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

				if (z->refcount == 0) {
					zval_dtor(z);
					FREE_ZVAL(z);
				}
				z = value;
			}
			*retval = *z;
			zendi_zval_copy_ctor(*retval);
			ALLOC_ZVAL(z_copy);
			*z_copy = *z;
			zendi_zval_copy_ctor(*z_copy);
			INIT_PZVAL(z_copy);
			incdec_op(z_copy);
			z->refcount++;
			Z_OBJ_HT_P(object)->write_property(object, property, z_copy TSRMLS_CC);
			zval_ptr_dtor(&z_copy);
			zval_ptr_dtor(&z);
		} else {
			zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
			*retval = *EG(uninitialized_zval_ptr);
		}
	}

	if (0) {
		zval_ptr_dtor(&property);
	} else {
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_POST_INC_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_post_incdec_property_helper_SPEC_VAR_VAR(increment_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_POST_DEC_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_post_incdec_property_helper_SPEC_VAR_VAR(decrement_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_DIM_R_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (opline->extended_value == ZEND_FETCH_ADD_LOCK &&
	    IS_VAR != IS_CV &&
	    EX_T(opline->op1.u.var).var.ptr_ptr) {
		PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
	}
	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_W TSRMLS_CC);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_RW_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_IS_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_IS TSRMLS_CC);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
	zval *dim;

	if (IS_VAR == IS_UNUSED && type == BP_VAR_R) {
		zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
	}
	dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, type TSRMLS_CC);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	if (IS_VAR == IS_VAR && type == BP_VAR_W && (free_op1.var != NULL) &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	/* Not needed in DIM_UNSET
	if (opline->extended_value == ZEND_FETCH_ADD_LOCK) {
		PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
	}
	*/
	if (IS_VAR == IS_CV) {
		if (container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
	}
	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_UNSET TSRMLS_CC);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	if (EX_T(opline->result.u.var).var.ptr_ptr == NULL) {
		zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
	} else {
		zend_free_op free_res;

		PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &free_res);
		if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
		}
		PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
		FREE_OP_VAR_PTR(free_res);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int zend_fetch_property_address_read_helper_SPEC_VAR_VAR(int type, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *container;
	zval **retval;
	zend_free_op free_op1;
	zend_free_op free_op2;
	zval *offset  = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	retval = &EX_T(opline->result.u.var).var.ptr;
	EX_T(opline->result.u.var).var.ptr_ptr = retval;

	container = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

	if (container == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			*retval = EG(error_zval_ptr);
			PZVAL_LOCK(*retval);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
		ZEND_VM_NEXT_OPCODE();
	}


	if (Z_TYPE_P(container) != IS_OBJECT || !Z_OBJ_HT_P(container)->read_property) {
		if (type != BP_VAR_IS) {
			zend_error(E_NOTICE, "Trying to get property of non-object");
		}
		*retval = EG(uninitialized_zval_ptr);
		SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	} else {
		if (0) {
			MAKE_REAL_ZVAL_PTR(offset);
		}

		/* here we are sure we are dealing with an object */
		*retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);

		if (RETURN_VALUE_UNUSED(&opline->result) && ((*retval)->refcount == 0)) {
			zval_dtor(*retval);
			FREE_ZVAL(*retval);
		} else {
			SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}

		if (0) {
			zval_ptr_dtor(&offset);
		} else {
			if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
		}
	}

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_R_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_property_address_read_helper_SPEC_VAR_VAR(BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_OBJ_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_VAR != IS_CV) {
		PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
		EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr;
	}

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), property, BP_VAR_W TSRMLS_CC);
	if (0) {
		zval_ptr_dtor(&property);
	} else {
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	}
	if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_RW_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), property, BP_VAR_RW TSRMLS_CC);
	if (0) {
		zval_ptr_dtor(&property);
	} else {
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	}
	if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_IS_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_property_address_read_helper_SPEC_VAR_VAR(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) {
		/* Behave like FETCH_OBJ_W */
		zend_free_op free_op1, free_op2;
		zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

		if (0) {
			MAKE_REAL_ZVAL_PTR(property);
		}
		zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), property, BP_VAR_W TSRMLS_CC);
		if (0) {
			zval_ptr_dtor(&property);
		} else {
			if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
		}
		if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
		    READY_TO_DESTROY(free_op1.var) &&
		    !RETURN_VALUE_UNUSED(&opline->result)) {
			AI_USE_PTR(EX_T(opline->result.u.var).var);
			if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
			    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
				SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
			}
		}
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
		ZEND_VM_NEXT_OPCODE();
	} else {
		return zend_fetch_property_address_read_helper_SPEC_VAR_VAR(BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
	}
}

static int ZEND_FETCH_OBJ_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2, free_res;
	zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (IS_VAR == IS_CV) {
		if (container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
	}
	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC);
	if (0) {
		zval_ptr_dtor(&property);
	} else {
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	}
	if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &free_res);
	if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
		SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
	}
	PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
	FREE_OP_VAR_PTR(free_res);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;
	zend_free_op free_op1;
	zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

	zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	/* assign_obj has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;
	zend_free_op free_op1;
	zval **object_ptr;

	if (IS_VAR == IS_CV || EX_T(opline->op1.u.var).var.ptr_ptr) {
		/* not an array offset */
		object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	} else {
		object_ptr = NULL;
	}

	if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
		zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC);
	} else {
		zend_free_op free_op2, free_op_data1;
		zval *value;
		zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

		zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 0, BP_VAR_W TSRMLS_CC);
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};

		value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
	 	zend_assign_to_variable(&opline->result, &op_data->op2, &op_data->op1, value, (IS_TMP_FREE(free_op_data1)?IS_TMP_VAR:op_data->op1.op_type), EX(Ts) TSRMLS_CC);
	 	FREE_OP_IF_VAR(free_op_data1);
	}
 	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	/* assign_dim has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zval *value = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

 	zend_assign_to_variable(&opline->result, &opline->op1, &opline->op2, value, (0?IS_TMP_VAR:IS_VAR), EX(Ts) TSRMLS_CC);
	/* zend_assign_to_variable() always takes care of op2, never free it! */
 	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval **variable_ptr_ptr;
	zval **value_ptr_ptr = _get_zval_ptr_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (IS_VAR == IS_VAR &&
	    value_ptr_ptr &&
	    !(*value_ptr_ptr)->is_ref &&
	    opline->extended_value == ZEND_RETURNS_FUNCTION &&
	    !EX_T(opline->op2.u.var).var.fcall_returned_reference) {
		if (free_op2.var == NULL) {
			PZVAL_LOCK(*value_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
		}
		zend_error(E_STRICT, "Only variables should be assigned by reference");
		if (EG(exception)) {
			if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
			ZEND_VM_NEXT_OPCODE();
		}
		return ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
	} else if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
		PZVAL_LOCK(*value_ptr_ptr);
	}
	if (IS_VAR == IS_VAR && EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
		zend_error(E_ERROR, "Cannot assign by reference to overloaded object");
	}

	variable_ptr_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);

	if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
		(*variable_ptr_ptr)->refcount--;
	}

	if (!RETURN_VALUE_UNUSED(&opline->result)) {
		EX_T(opline->result.u.var).var.ptr_ptr = variable_ptr_ptr;
		PZVAL_LOCK(*variable_ptr_ptr);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
	}

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *function_name;
	char *function_name_strval;
	int function_name_strlen;
	zend_free_op free_op1, free_op2;

	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), NULL);

	function_name = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (Z_TYPE_P(function_name)!=IS_STRING) {
		zend_error_noreturn(E_ERROR, "Method name must be a string");
	}

	function_name_strval = Z_STRVAL_P(function_name);
	function_name_strlen = Z_STRLEN_P(function_name);

	EX(object) = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

	if (EX(object) && Z_TYPE_P(EX(object)) == IS_OBJECT) {
		if (Z_OBJ_HT_P(EX(object))->get_method == NULL) {
			zend_error_noreturn(E_ERROR, "Object does not support method calls");
		}

		/* First, locate the function. */
		EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen TSRMLS_CC);
		if (!EX(fbc)) {
			zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
		}
	} else {
		zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
	}

	if (!EX(object) || (EX(fbc) && (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
		EX(object) = NULL;
	} else {
		if (!PZVAL_IS_REF(EX(object))) {
			EX(object)->refcount++; /* For $this pointer */
		} else {
			zval *this_ptr;
			ALLOC_ZVAL(this_ptr);
			INIT_PZVAL_COPY(this_ptr, EX(object));
			zval_copy_ctor(this_ptr);
			EX(object) = this_ptr;
		}
	}

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CASE_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	int switch_expr_is_overloaded=0;
	zend_free_op free_op1, free_op2;

	if (IS_VAR==IS_VAR) {
		if (EX_T(opline->op1.u.var).var.ptr_ptr) {
			PZVAL_LOCK(EX_T(opline->op1.u.var).var.ptr);
		} else {
			switch_expr_is_overloaded = 1;
			EX_T(opline->op1.u.var).str_offset.str->refcount++;
		}
	}
	is_equal_function(&EX_T(opline->result.u.var).tmp_var,
				 _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
				 _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	if (switch_expr_is_overloaded) {
		/* We only free op1 if this is a string offset,
		 * Since if it is a TMP_VAR, it'll be reused by
		 * other CASE opcodes (whereas string offsets
		 * are allocated at each get_zval_ptr())
		 */
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
		EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
		AI_USE_PTR(EX_T(opline->op1.u.var).var);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *array_ptr = &EX_T(opline->result.u.var).tmp_var;
	zval *expr_ptr;
	zval *offset=_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

#if 0 || IS_VAR == IS_VAR || IS_VAR == IS_CV
	zval **expr_ptr_ptr = NULL;

	if (opline->extended_value) {
		expr_ptr_ptr=_get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
		expr_ptr = *expr_ptr_ptr;
	} else {
		expr_ptr=_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	}
#else
	expr_ptr=_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
#endif

	if (0) { /* temporary variable */
		zval *new_expr;

		ALLOC_ZVAL(new_expr);
		INIT_PZVAL_COPY(new_expr, expr_ptr);
		expr_ptr = new_expr;
	} else {
#if 0 || IS_VAR == IS_VAR || IS_VAR == IS_CV
		if (opline->extended_value) {
			SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr_ptr);
			expr_ptr = *expr_ptr_ptr;
			expr_ptr->refcount++;
		} else
#endif
		if (PZVAL_IS_REF(expr_ptr)) {
			zval *new_expr;

			ALLOC_ZVAL(new_expr);
			INIT_PZVAL_COPY(new_expr, expr_ptr);
			expr_ptr = new_expr;
			zendi_zval_copy_ctor(*expr_ptr);
		} else {
			expr_ptr->refcount++;
		}
	}
	if (offset) {
		switch (Z_TYPE_P(offset)) {
			case IS_DOUBLE:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_LONG:
			case IS_BOOL:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), Z_LVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_STRING:
				zend_symtable_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_NULL:
				zend_hash_update(Z_ARRVAL_P(array_ptr), "", sizeof(""), &expr_ptr, sizeof(zval *), NULL);
				break;
			default:
				zend_error(E_WARNING, "Illegal offset type");
				zval_ptr_dtor(&expr_ptr);
				/* do nothing */
				break;
		}
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	} else {
		zend_hash_next_index_insert(Z_ARRVAL_P(array_ptr), &expr_ptr, sizeof(zval *), NULL);
	}
	if (opline->extended_value) {
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	} else {
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_ARRAY_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	array_init(&EX_T(opline->result.u.var).tmp_var);
	if (IS_VAR == IS_UNUSED) {
		ZEND_VM_NEXT_OPCODE();
#if 0 || IS_VAR != IS_UNUSED
	} else {
		return ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
#endif
	}
}

static int ZEND_UNSET_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval *offset = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	long index;

	if (container) {
		if (IS_VAR == IS_CV && container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
		switch (Z_TYPE_PP(container)) {
			case IS_ARRAY: {
				HashTable *ht = Z_ARRVAL_PP(container);

				switch (Z_TYPE_P(offset)) {
					case IS_DOUBLE:
						index = (long) Z_DVAL_P(offset);
						zend_hash_index_del(ht, index);
						break;
					case IS_RESOURCE:
					case IS_BOOL:
					case IS_LONG:
						index = Z_LVAL_P(offset);
						zend_hash_index_del(ht, index);
						break;
					case IS_STRING:
						if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
							offset->refcount++;
						}
						if (zend_symtable_del(ht, offset->value.str.val, offset->value.str.len+1) == SUCCESS &&
					    ht == &EG(symbol_table)) {
							zend_execute_data *ex;
							ulong hash_value = zend_inline_hash_func(offset->value.str.val, offset->value.str.len+1);

							for (ex = execute_data; ex; ex = ex->prev_execute_data) {
								if (ex->op_array && ex->symbol_table == ht) {
									int i;

									for (i = 0; i < ex->op_array->last_var; i++) {
										if (ex->op_array->vars[i].hash_value == hash_value &&
										    ex->op_array->vars[i].name_len == offset->value.str.len &&
										    !memcmp(ex->op_array->vars[i].name, offset->value.str.val, offset->value.str.len)) {
											ex->CVs[i] = NULL;
											break;
										}
									}
								}
							}
						}
						if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
							zval_ptr_dtor(&offset);
						}
						break;
					case IS_NULL:
						zend_hash_del(ht, "", sizeof(""));
						break;
					default:
						zend_error(E_WARNING, "Illegal offset type in unset");
						break;
				}
				if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
				break;
			}
			case IS_OBJECT:
				if (!Z_OBJ_HT_P(*container)->unset_dimension) {
					zend_error_noreturn(E_ERROR, "Cannot use object as array");
				}
				if (0) {
					MAKE_REAL_ZVAL_PTR(offset);
				}
				Z_OBJ_HT_P(*container)->unset_dimension(*container, offset TSRMLS_CC);
				if (0) {
					zval_ptr_dtor(&offset);
				} else {
					if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
				}
				break;
			case IS_STRING:
				zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
				ZEND_VM_CONTINUE(); /* bailed out before */
			default:
				if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
				break;
		}
	} else {
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_UNSET_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval *offset = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (container) {
		if (IS_VAR == IS_CV && container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
		if (Z_TYPE_PP(container) == IS_OBJECT) {
			if (0) {
				MAKE_REAL_ZVAL_PTR(offset);
			}
			Z_OBJ_HT_P(*container)->unset_property(*container, offset TSRMLS_CC);
			if (0) {
				zval_ptr_dtor(&offset);
			} else {
				if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
			}
		} else {
			if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
		}
	} else {
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_VAR(int prop_dim, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval **value = NULL;
	int result = 0;
	long index;

	if (container) {
		zend_free_op free_op2;
		zval *offset = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

		if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
			HashTable *ht;
			int isset = 0;

			ht = Z_ARRVAL_PP(container);

			switch (Z_TYPE_P(offset)) {
				case IS_DOUBLE:
					index = (long) Z_DVAL_P(offset);
					if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_RESOURCE:
				case IS_BOOL:
				case IS_LONG:
					index = Z_LVAL_P(offset);
					if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_STRING:
					if (zend_symtable_find(ht, offset->value.str.val, offset->value.str.len+1, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_NULL:
					if (zend_hash_find(ht, "", sizeof(""), (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				default:
					zend_error(E_WARNING, "Illegal offset type in isset or empty");

					break;
			}

			switch (opline->extended_value) {
				case ZEND_ISSET:
					if (isset && Z_TYPE_PP(value) == IS_NULL) {
						result = 0;
					} else {
						result = isset;
					}
					break;
				case ZEND_ISEMPTY:
					if (!isset || !i_zend_is_true(*value)) {
						result = 0;
					} else {
						result = 1;
					}
					break;
			}
			if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
		} else if (Z_TYPE_PP(container) == IS_OBJECT) {
			if (0) {
				MAKE_REAL_ZVAL_PTR(offset);
			}
			if (prop_dim) {
				result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value == ZEND_ISEMPTY) TSRMLS_CC);
			} else {
				result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value == ZEND_ISEMPTY) TSRMLS_CC);
			}
			if (0) {
				zval_ptr_dtor(&offset);
			} else {
				if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
			}
		} else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
			zval tmp;

			if (Z_TYPE_P(offset) != IS_LONG) {
				tmp = *offset;
				zval_copy_ctor(&tmp);
				convert_to_long(&tmp);
				offset = &tmp;
			}
			if (Z_TYPE_P(offset) == IS_LONG) {
				switch (opline->extended_value) {
					case ZEND_ISSET:
						if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
							result = 1;
						}
						break;
					case ZEND_ISEMPTY:
						if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
							result = 1;
						}
						break;
				}
			}
			if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
		} else {
			if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
		}
	}

	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;

	switch (opline->extended_value) {
		case ZEND_ISSET:
			Z_LVAL(EX_T(opline->result.u.var).tmp_var) = result;
			break;
		case ZEND_ISEMPTY:
			Z_LVAL(EX_T(opline->result.u.var).tmp_var) = !result;
			break;
	}

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_VAR(0, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_VAR(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;
	zend_free_op free_op1, free_op_data1;
	zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval *object;
	zval *property = NULL;
	zval *value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
	znode *result = &opline->result;
	zval **retval = &EX_T(result->u.var).var.ptr;
	int have_get_ptr = 0;

	if (IS_VAR == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
	}

	EX_T(result->u.var).var.ptr_ptr = NULL;
	make_real_object(object_ptr TSRMLS_CC);
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to assign property of non-object");

		FREE_OP(free_op_data1);

		if (!RETURN_VALUE_UNUSED(result)) {
			*retval = EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*retval);
		}
	} else {
		/* here we are sure we are dealing with an object */
		if (0) {
			MAKE_REAL_ZVAL_PTR(property);
		}

		/* here property is a string */
		if (opline->extended_value == ZEND_ASSIGN_OBJ
			&& Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
			zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
			if (zptr != NULL) { 			/* NULL means no success in getting PTR */
				SEPARATE_ZVAL_IF_NOT_REF(zptr);

				have_get_ptr = 1;
				binary_op(*zptr, *zptr, value TSRMLS_CC);
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = *zptr;
					PZVAL_LOCK(*retval);
				}
			}
		}

		if (!have_get_ptr) {
			zval *z = NULL;

			switch (opline->extended_value) {
				case ZEND_ASSIGN_OBJ:
					if (Z_OBJ_HT_P(object)->read_property) {
						z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
					}
					break;
				case ZEND_ASSIGN_DIM:
					if (Z_OBJ_HT_P(object)->read_dimension) {
						z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
					}
					break;
			}
			if (z) {
				if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
					zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

					if (z->refcount == 0) {
						zval_dtor(z);
						FREE_ZVAL(z);
					}
					z = value;
				}
				z->refcount++;
				SEPARATE_ZVAL_IF_NOT_REF(&z);
				binary_op(z, z, value TSRMLS_CC);
				switch (opline->extended_value) {
					case ZEND_ASSIGN_OBJ:
						Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
						break;
					case ZEND_ASSIGN_DIM:
						Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
						break;
				}
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = z;
					PZVAL_LOCK(*retval);
				}
				zval_ptr_dtor(&z);
			} else {
				zend_error(E_WARNING, "Attempt to assign property of non-object");
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = EG(uninitialized_zval_ptr);
					PZVAL_LOCK(*retval);
				}
			}
		}

		if (0) {
			zval_ptr_dtor(&property);
		} else {

		}
		FREE_OP(free_op_data1);
	}

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	/* assign_obj has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int zend_binary_assign_op_helper_SPEC_VAR_UNUSED(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op_data2, free_op_data1;
	zval **var_ptr;
	zval *value;
	zend_bool increment_opline = 0;

	switch (opline->extended_value) {
		case ZEND_ASSIGN_OBJ:
			return zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
			break;
		case ZEND_ASSIGN_DIM: {
				zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

				if (object_ptr && IS_VAR != IS_CV && !(free_op1.var != NULL)) {
					(*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
				}

				if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
					return zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
				} else {
					zend_op *op_data = opline+1;
					zval *dim = NULL;

					zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC);
					value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
					var_ptr = get_zval_ptr_ptr(&op_data->op2, EX(Ts), &free_op_data2, BP_VAR_RW);
					increment_opline = 1;
				}
			}
			break;
		default:
			value = NULL;
			var_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
			/* do nothing */
			break;
	}

	if (!var_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets");
	}

	if (*var_ptr == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}

		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
		if (increment_opline) {
			ZEND_VM_INC_OPCODE();
		}
		ZEND_VM_NEXT_OPCODE();
	}

	SEPARATE_ZVAL_IF_NOT_REF(var_ptr);

	if(Z_TYPE_PP(var_ptr) == IS_OBJECT && Z_OBJ_HANDLER_PP(var_ptr, get)
	   && Z_OBJ_HANDLER_PP(var_ptr, set)) {
		/* proxy object */
		zval *objval = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
		objval->refcount++;
		binary_op(objval, objval, value TSRMLS_CC);
		Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, objval TSRMLS_CC);
		zval_ptr_dtor(&objval);
	} else {
		binary_op(*var_ptr, *var_ptr, value TSRMLS_CC);
	}

	if (!RETURN_VALUE_UNUSED(&opline->result)) {
		EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
		PZVAL_LOCK(*var_ptr);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
	}

	if (increment_opline) {
		ZEND_VM_INC_OPCODE();
		FREE_OP(free_op_data1);
		FREE_OP_VAR_PTR(free_op_data2);
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_ADD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_UNUSED(add_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SUB_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_UNUSED(sub_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_MUL_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_UNUSED(mul_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_DIV_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_UNUSED(div_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_MOD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_UNUSED(mod_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SL_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_UNUSED(shift_left_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SR_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_UNUSED(shift_right_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_CONCAT_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_UNUSED(concat_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_OR_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_UNUSED(bitwise_or_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_AND_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_UNUSED(bitwise_and_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_XOR_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_UNUSED(bitwise_xor_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *dim = NULL;

	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_W TSRMLS_CC);

	if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *dim = NULL;

	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC);

	if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
	zval *dim;

	if (IS_UNUSED == IS_UNUSED && type == BP_VAR_R) {
		zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
	}
	dim = NULL;
	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, type TSRMLS_CC);

	if (IS_VAR == IS_VAR && type == BP_VAR_W && (free_op1.var != NULL) &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;
	zend_free_op free_op1;
	zval **object_ptr;

	if (IS_VAR == IS_CV || EX_T(opline->op1.u.var).var.ptr_ptr) {
		/* not an array offset */
		object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	} else {
		object_ptr = NULL;
	}

	if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
		zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC);
	} else {
		zend_free_op free_op_data1;
		zval *value;
		zval *dim = NULL;

		zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 0, BP_VAR_W TSRMLS_CC);

		value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
	 	zend_assign_to_variable(&opline->result, &op_data->op2, &op_data->op1, value, (IS_TMP_FREE(free_op_data1)?IS_TMP_VAR:op_data->op1.op_type), EX(Ts) TSRMLS_CC);
	 	FREE_OP_IF_VAR(free_op_data1);
	}
 	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	/* assign_dim has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *array_ptr = &EX_T(opline->result.u.var).tmp_var;
	zval *expr_ptr;
	zval *offset=NULL;

#if 0 || IS_VAR == IS_VAR || IS_VAR == IS_CV
	zval **expr_ptr_ptr = NULL;

	if (opline->extended_value) {
		expr_ptr_ptr=_get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
		expr_ptr = *expr_ptr_ptr;
	} else {
		expr_ptr=_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	}
#else
	expr_ptr=_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
#endif

	if (0) { /* temporary variable */
		zval *new_expr;

		ALLOC_ZVAL(new_expr);
		INIT_PZVAL_COPY(new_expr, expr_ptr);
		expr_ptr = new_expr;
	} else {
#if 0 || IS_VAR == IS_VAR || IS_VAR == IS_CV
		if (opline->extended_value) {
			SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr_ptr);
			expr_ptr = *expr_ptr_ptr;
			expr_ptr->refcount++;
		} else
#endif
		if (PZVAL_IS_REF(expr_ptr)) {
			zval *new_expr;

			ALLOC_ZVAL(new_expr);
			INIT_PZVAL_COPY(new_expr, expr_ptr);
			expr_ptr = new_expr;
			zendi_zval_copy_ctor(*expr_ptr);
		} else {
			expr_ptr->refcount++;
		}
	}
	if (offset) {
		switch (Z_TYPE_P(offset)) {
			case IS_DOUBLE:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_LONG:
			case IS_BOOL:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), Z_LVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_STRING:
				zend_symtable_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_NULL:
				zend_hash_update(Z_ARRVAL_P(array_ptr), "", sizeof(""), &expr_ptr, sizeof(zval *), NULL);
				break;
			default:
				zend_error(E_WARNING, "Illegal offset type");
				zval_ptr_dtor(&expr_ptr);
				/* do nothing */
				break;
		}

	} else {
		zend_hash_next_index_insert(Z_ARRVAL_P(array_ptr), &expr_ptr, sizeof(zval *), NULL);
	}
	if (opline->extended_value) {
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	} else {
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_ARRAY_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	array_init(&EX_T(opline->result.u.var).tmp_var);
	if (IS_VAR == IS_UNUSED) {
		ZEND_VM_NEXT_OPCODE();
#if 0 || IS_VAR != IS_UNUSED
	} else {
		return ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
#endif
	}
}

static int ZEND_ADD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	add_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SUB_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	sub_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_MUL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	mul_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_DIV_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	div_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_MOD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	mod_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	shift_left_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SR_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	shift_right_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CONCAT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	concat_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_IDENTICAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	is_identical_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	is_not_identical_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_EQUAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	is_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_NOT_EQUAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	is_not_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_SMALLER_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	is_smaller_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_SMALLER_OR_EQUAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	is_smaller_or_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_OR_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	bitwise_or_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_AND_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	bitwise_and_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_XOR_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	bitwise_xor_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BOOL_XOR_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;

	boolean_xor_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;
	zend_free_op free_op1, free_op_data1;
	zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval *object;
	zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
	zval *value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
	znode *result = &opline->result;
	zval **retval = &EX_T(result->u.var).var.ptr;
	int have_get_ptr = 0;

	if (IS_VAR == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
	}

	EX_T(result->u.var).var.ptr_ptr = NULL;
	make_real_object(object_ptr TSRMLS_CC);
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to assign property of non-object");

		FREE_OP(free_op_data1);

		if (!RETURN_VALUE_UNUSED(result)) {
			*retval = EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*retval);
		}
	} else {
		/* here we are sure we are dealing with an object */
		if (0) {
			MAKE_REAL_ZVAL_PTR(property);
		}

		/* here property is a string */
		if (opline->extended_value == ZEND_ASSIGN_OBJ
			&& Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
			zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
			if (zptr != NULL) { 			/* NULL means no success in getting PTR */
				SEPARATE_ZVAL_IF_NOT_REF(zptr);

				have_get_ptr = 1;
				binary_op(*zptr, *zptr, value TSRMLS_CC);
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = *zptr;
					PZVAL_LOCK(*retval);
				}
			}
		}

		if (!have_get_ptr) {
			zval *z = NULL;

			switch (opline->extended_value) {
				case ZEND_ASSIGN_OBJ:
					if (Z_OBJ_HT_P(object)->read_property) {
						z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
					}
					break;
				case ZEND_ASSIGN_DIM:
					if (Z_OBJ_HT_P(object)->read_dimension) {
						z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
					}
					break;
			}
			if (z) {
				if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
					zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

					if (z->refcount == 0) {
						zval_dtor(z);
						FREE_ZVAL(z);
					}
					z = value;
				}
				z->refcount++;
				SEPARATE_ZVAL_IF_NOT_REF(&z);
				binary_op(z, z, value TSRMLS_CC);
				switch (opline->extended_value) {
					case ZEND_ASSIGN_OBJ:
						Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
						break;
					case ZEND_ASSIGN_DIM:
						Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
						break;
				}
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = z;
					PZVAL_LOCK(*retval);
				}
				zval_ptr_dtor(&z);
			} else {
				zend_error(E_WARNING, "Attempt to assign property of non-object");
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = EG(uninitialized_zval_ptr);
					PZVAL_LOCK(*retval);
				}
			}
		}

		if (0) {
			zval_ptr_dtor(&property);
		} else {

		}
		FREE_OP(free_op_data1);
	}

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	/* assign_obj has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int zend_binary_assign_op_helper_SPEC_VAR_CV(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op_data2, free_op_data1;
	zval **var_ptr;
	zval *value;
	zend_bool increment_opline = 0;

	switch (opline->extended_value) {
		case ZEND_ASSIGN_OBJ:
			return zend_binary_assign_op_obj_helper_SPEC_VAR_CV(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
			break;
		case ZEND_ASSIGN_DIM: {
				zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

				if (object_ptr && IS_VAR != IS_CV && !(free_op1.var != NULL)) {
					(*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
				}

				if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
					return zend_binary_assign_op_obj_helper_SPEC_VAR_CV(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
				} else {
					zend_op *op_data = opline+1;
					zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

					zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC);
					value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
					var_ptr = get_zval_ptr_ptr(&op_data->op2, EX(Ts), &free_op_data2, BP_VAR_RW);
					increment_opline = 1;
				}
			}
			break;
		default:
			value = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
			var_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
			/* do nothing */
			break;
	}

	if (!var_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets");
	}

	if (*var_ptr == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}

		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
		if (increment_opline) {
			ZEND_VM_INC_OPCODE();
		}
		ZEND_VM_NEXT_OPCODE();
	}

	SEPARATE_ZVAL_IF_NOT_REF(var_ptr);

	if(Z_TYPE_PP(var_ptr) == IS_OBJECT && Z_OBJ_HANDLER_PP(var_ptr, get)
	   && Z_OBJ_HANDLER_PP(var_ptr, set)) {
		/* proxy object */
		zval *objval = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
		objval->refcount++;
		binary_op(objval, objval, value TSRMLS_CC);
		Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, objval TSRMLS_CC);
		zval_ptr_dtor(&objval);
	} else {
		binary_op(*var_ptr, *var_ptr, value TSRMLS_CC);
	}

	if (!RETURN_VALUE_UNUSED(&opline->result)) {
		EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
		PZVAL_LOCK(*var_ptr);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
	}

	if (increment_opline) {
		ZEND_VM_INC_OPCODE();
		FREE_OP(free_op_data1);
		FREE_OP_VAR_PTR(free_op_data2);
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_ADD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_CV(add_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SUB_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_CV(sub_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_MUL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_CV(mul_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_DIV_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_CV(div_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_MOD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_CV(mod_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_CV(shift_left_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SR_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_CV(shift_right_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_CONCAT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_CV(concat_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_OR_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_CV(bitwise_or_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_AND_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_CV(bitwise_and_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_XOR_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_VAR_CV(bitwise_xor_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_pre_incdec_property_helper_SPEC_VAR_CV(incdec_t incdec_op, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval *object;
	zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
	zval **retval = &EX_T(opline->result.u.var).var.ptr;
	int have_get_ptr = 0;

	if (IS_VAR == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}

	make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");

		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			*retval = EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*retval);
		}
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
		ZEND_VM_NEXT_OPCODE();
	}

	/* here we are sure we are dealing with an object */

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}

	if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
		zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
		if (zptr != NULL) { 			/* NULL means no success in getting PTR */
			SEPARATE_ZVAL_IF_NOT_REF(zptr);

			have_get_ptr = 1;
			incdec_op(*zptr);
			if (!RETURN_VALUE_UNUSED(&opline->result)) {
				*retval = *zptr;
				PZVAL_LOCK(*retval);
			}
		}
	}

	if (!have_get_ptr) {
		if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
			zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);

			if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
				zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

				if (z->refcount == 0) {
					zval_dtor(z);
					FREE_ZVAL(z);
				}
				z = value;
			}
			z->refcount++;
			SEPARATE_ZVAL_IF_NOT_REF(&z);
			incdec_op(z);
			*retval = z;
			Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
			SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
			zval_ptr_dtor(&z);
		} else {
			zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
			if (!RETURN_VALUE_UNUSED(&opline->result)) {
				*retval = EG(uninitialized_zval_ptr);
				PZVAL_LOCK(*retval);
			}
		}
	}

	if (0) {
		zval_ptr_dtor(&property);
	} else {

	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_PRE_INC_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_pre_incdec_property_helper_SPEC_VAR_CV(increment_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_PRE_DEC_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_pre_incdec_property_helper_SPEC_VAR_CV(decrement_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_post_incdec_property_helper_SPEC_VAR_CV(incdec_t incdec_op, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval *object;
	zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
	zval *retval = &EX_T(opline->result.u.var).tmp_var;
	int have_get_ptr = 0;

	if (IS_VAR == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}

	make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");

		*retval = *EG(uninitialized_zval_ptr);
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
		ZEND_VM_NEXT_OPCODE();
	}

	/* here we are sure we are dealing with an object */

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}

	if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
		zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
		if (zptr != NULL) { 			/* NULL means no success in getting PTR */
			have_get_ptr = 1;
			SEPARATE_ZVAL_IF_NOT_REF(zptr);

			*retval = **zptr;
			zendi_zval_copy_ctor(*retval);

			incdec_op(*zptr);

		}
	}

	if (!have_get_ptr) {
		if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
			zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
			zval *z_copy;

			if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
				zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

				if (z->refcount == 0) {
					zval_dtor(z);
					FREE_ZVAL(z);
				}
				z = value;
			}
			*retval = *z;
			zendi_zval_copy_ctor(*retval);
			ALLOC_ZVAL(z_copy);
			*z_copy = *z;
			zendi_zval_copy_ctor(*z_copy);
			INIT_PZVAL(z_copy);
			incdec_op(z_copy);
			z->refcount++;
			Z_OBJ_HT_P(object)->write_property(object, property, z_copy TSRMLS_CC);
			zval_ptr_dtor(&z_copy);
			zval_ptr_dtor(&z);
		} else {
			zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
			*retval = *EG(uninitialized_zval_ptr);
		}
	}

	if (0) {
		zval_ptr_dtor(&property);
	} else {

	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_POST_INC_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_post_incdec_property_helper_SPEC_VAR_CV(increment_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_POST_DEC_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_post_incdec_property_helper_SPEC_VAR_CV(decrement_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_DIM_R_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

	if (opline->extended_value == ZEND_FETCH_ADD_LOCK &&
	    IS_VAR != IS_CV &&
	    EX_T(opline->op1.u.var).var.ptr_ptr) {
		PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
	}
	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC);

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_W TSRMLS_CC);

	if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC);

	if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_IS_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_IS TSRMLS_CC);

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
	zval *dim;

	if (IS_CV == IS_UNUSED && type == BP_VAR_R) {
		zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
	}
	dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, type TSRMLS_CC);

	if (IS_VAR == IS_VAR && type == BP_VAR_W && (free_op1.var != NULL) &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

	/* Not needed in DIM_UNSET
	if (opline->extended_value == ZEND_FETCH_ADD_LOCK) {
		PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
	}
	*/
	if (IS_VAR == IS_CV) {
		if (container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
	}
	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_UNSET TSRMLS_CC);

	if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	if (EX_T(opline->result.u.var).var.ptr_ptr == NULL) {
		zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
	} else {
		zend_free_op free_res;

		PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &free_res);
		if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
		}
		PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
		FREE_OP_VAR_PTR(free_res);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int zend_fetch_property_address_read_helper_SPEC_VAR_CV(int type, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *container;
	zval **retval;
	zend_free_op free_op1;

	zval *offset  = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

	retval = &EX_T(opline->result.u.var).var.ptr;
	EX_T(opline->result.u.var).var.ptr_ptr = retval;

	container = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

	if (container == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			*retval = EG(error_zval_ptr);
			PZVAL_LOCK(*retval);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}

		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
		ZEND_VM_NEXT_OPCODE();
	}


	if (Z_TYPE_P(container) != IS_OBJECT || !Z_OBJ_HT_P(container)->read_property) {
		if (type != BP_VAR_IS) {
			zend_error(E_NOTICE, "Trying to get property of non-object");
		}
		*retval = EG(uninitialized_zval_ptr);
		SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
		AI_USE_PTR(EX_T(opline->result.u.var).var);

	} else {
		if (0) {
			MAKE_REAL_ZVAL_PTR(offset);
		}

		/* here we are sure we are dealing with an object */
		*retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);

		if (RETURN_VALUE_UNUSED(&opline->result) && ((*retval)->refcount == 0)) {
			zval_dtor(*retval);
			FREE_ZVAL(*retval);
		} else {
			SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}

		if (0) {
			zval_ptr_dtor(&offset);
		} else {

		}
	}

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_R_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_property_address_read_helper_SPEC_VAR_CV(BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

	if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_VAR != IS_CV) {
		PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
		EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr;
	}

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), property, BP_VAR_W TSRMLS_CC);
	if (0) {
		zval_ptr_dtor(&property);
	} else {

	}
	if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), property, BP_VAR_RW TSRMLS_CC);
	if (0) {
		zval_ptr_dtor(&property);
	} else {

	}
	if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_IS_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_property_address_read_helper_SPEC_VAR_CV(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) {
		/* Behave like FETCH_OBJ_W */
		zend_free_op free_op1;
		zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

		if (0) {
			MAKE_REAL_ZVAL_PTR(property);
		}
		zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), property, BP_VAR_W TSRMLS_CC);
		if (0) {
			zval_ptr_dtor(&property);
		} else {

		}
		if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
		    READY_TO_DESTROY(free_op1.var) &&
		    !RETURN_VALUE_UNUSED(&opline->result)) {
			AI_USE_PTR(EX_T(opline->result.u.var).var);
			if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
			    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
				SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
			}
		}
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
		ZEND_VM_NEXT_OPCODE();
	} else {
		return zend_fetch_property_address_read_helper_SPEC_VAR_CV(BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
	}
}

static int ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_res;
	zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

	if (IS_VAR == IS_CV) {
		if (container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
	}
	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC);
	if (0) {
		zval_ptr_dtor(&property);
	} else {

	}
	if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &free_res);
	if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
		SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
	}
	PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
	FREE_OP_VAR_PTR(free_res);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;
	zend_free_op free_op1;
	zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

	zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	/* assign_obj has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;
	zend_free_op free_op1;
	zval **object_ptr;

	if (IS_VAR == IS_CV || EX_T(opline->op1.u.var).var.ptr_ptr) {
		/* not an array offset */
		object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	} else {
		object_ptr = NULL;
	}

	if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
		zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC);
	} else {
		zend_free_op free_op_data1;
		zval *value;
		zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

		zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 0, BP_VAR_W TSRMLS_CC);

		value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
	 	zend_assign_to_variable(&opline->result, &op_data->op2, &op_data->op1, value, (IS_TMP_FREE(free_op_data1)?IS_TMP_VAR:op_data->op1.op_type), EX(Ts) TSRMLS_CC);
	 	FREE_OP_IF_VAR(free_op_data1);
	}
 	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	/* assign_dim has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval *value = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

 	zend_assign_to_variable(&opline->result, &opline->op1, &opline->op2, value, (0?IS_TMP_VAR:IS_CV), EX(Ts) TSRMLS_CC);
	/* zend_assign_to_variable() always takes care of op2, never free it! */

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval **variable_ptr_ptr;
	zval **value_ptr_ptr = _get_zval_ptr_ptr_cv(&opline->op2, EX(Ts), BP_VAR_W TSRMLS_CC);

	if (IS_CV == IS_VAR &&
	    value_ptr_ptr &&
	    !(*value_ptr_ptr)->is_ref &&
	    opline->extended_value == ZEND_RETURNS_FUNCTION &&
	    !EX_T(opline->op2.u.var).var.fcall_returned_reference) {
		if (free_op2.var == NULL) {
			PZVAL_LOCK(*value_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
		}
		zend_error(E_STRICT, "Only variables should be assigned by reference");
		if (EG(exception)) {

			ZEND_VM_NEXT_OPCODE();
		}
		return ZEND_ASSIGN_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
	} else if (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
		PZVAL_LOCK(*value_ptr_ptr);
	}
	if (IS_VAR == IS_VAR && EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
		zend_error(E_ERROR, "Cannot assign by reference to overloaded object");
	}

	variable_ptr_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);

	if (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
		(*variable_ptr_ptr)->refcount--;
	}

	if (!RETURN_VALUE_UNUSED(&opline->result)) {
		EX_T(opline->result.u.var).var.ptr_ptr = variable_ptr_ptr;
		PZVAL_LOCK(*variable_ptr_ptr);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
	}

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *function_name;
	char *function_name_strval;
	int function_name_strlen;
	zend_free_op free_op1;

	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), NULL);

	function_name = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

	if (Z_TYPE_P(function_name)!=IS_STRING) {
		zend_error_noreturn(E_ERROR, "Method name must be a string");
	}

	function_name_strval = Z_STRVAL_P(function_name);
	function_name_strlen = Z_STRLEN_P(function_name);

	EX(object) = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);

	if (EX(object) && Z_TYPE_P(EX(object)) == IS_OBJECT) {
		if (Z_OBJ_HT_P(EX(object))->get_method == NULL) {
			zend_error_noreturn(E_ERROR, "Object does not support method calls");
		}

		/* First, locate the function. */
		EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen TSRMLS_CC);
		if (!EX(fbc)) {
			zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
		}
	} else {
		zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
	}

	if (!EX(object) || (EX(fbc) && (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
		EX(object) = NULL;
	} else {
		if (!PZVAL_IS_REF(EX(object))) {
			EX(object)->refcount++; /* For $this pointer */
		} else {
			zval *this_ptr;
			ALLOC_ZVAL(this_ptr);
			INIT_PZVAL_COPY(this_ptr, EX(object));
			zval_copy_ctor(this_ptr);
			EX(object) = this_ptr;
		}
	}

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CASE_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	int switch_expr_is_overloaded=0;
	zend_free_op free_op1;

	if (IS_VAR==IS_VAR) {
		if (EX_T(opline->op1.u.var).var.ptr_ptr) {
			PZVAL_LOCK(EX_T(opline->op1.u.var).var.ptr);
		} else {
			switch_expr_is_overloaded = 1;
			EX_T(opline->op1.u.var).str_offset.str->refcount++;
		}
	}
	is_equal_function(&EX_T(opline->result.u.var).tmp_var,
				 _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC),
				 _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);

	if (switch_expr_is_overloaded) {
		/* We only free op1 if this is a string offset,
		 * Since if it is a TMP_VAR, it'll be reused by
		 * other CASE opcodes (whereas string offsets
		 * are allocated at each get_zval_ptr())
		 */
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
		EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
		AI_USE_PTR(EX_T(opline->op1.u.var).var);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *array_ptr = &EX_T(opline->result.u.var).tmp_var;
	zval *expr_ptr;
	zval *offset=_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

#if 0 || IS_VAR == IS_VAR || IS_VAR == IS_CV
	zval **expr_ptr_ptr = NULL;

	if (opline->extended_value) {
		expr_ptr_ptr=_get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
		expr_ptr = *expr_ptr_ptr;
	} else {
		expr_ptr=_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	}
#else
	expr_ptr=_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
#endif

	if (0) { /* temporary variable */
		zval *new_expr;

		ALLOC_ZVAL(new_expr);
		INIT_PZVAL_COPY(new_expr, expr_ptr);
		expr_ptr = new_expr;
	} else {
#if 0 || IS_VAR == IS_VAR || IS_VAR == IS_CV
		if (opline->extended_value) {
			SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr_ptr);
			expr_ptr = *expr_ptr_ptr;
			expr_ptr->refcount++;
		} else
#endif
		if (PZVAL_IS_REF(expr_ptr)) {
			zval *new_expr;

			ALLOC_ZVAL(new_expr);
			INIT_PZVAL_COPY(new_expr, expr_ptr);
			expr_ptr = new_expr;
			zendi_zval_copy_ctor(*expr_ptr);
		} else {
			expr_ptr->refcount++;
		}
	}
	if (offset) {
		switch (Z_TYPE_P(offset)) {
			case IS_DOUBLE:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_LONG:
			case IS_BOOL:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), Z_LVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_STRING:
				zend_symtable_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_NULL:
				zend_hash_update(Z_ARRVAL_P(array_ptr), "", sizeof(""), &expr_ptr, sizeof(zval *), NULL);
				break;
			default:
				zend_error(E_WARNING, "Illegal offset type");
				zval_ptr_dtor(&expr_ptr);
				/* do nothing */
				break;
		}

	} else {
		zend_hash_next_index_insert(Z_ARRVAL_P(array_ptr), &expr_ptr, sizeof(zval *), NULL);
	}
	if (opline->extended_value) {
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	} else {
		if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_ARRAY_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	array_init(&EX_T(opline->result.u.var).tmp_var);
	if (IS_VAR == IS_UNUSED) {
		ZEND_VM_NEXT_OPCODE();
#if 0 || IS_VAR != IS_UNUSED
	} else {
		return ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
#endif
	}
}

static int ZEND_UNSET_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval *offset = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
	long index;

	if (container) {
		if (IS_VAR == IS_CV && container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
		switch (Z_TYPE_PP(container)) {
			case IS_ARRAY: {
				HashTable *ht = Z_ARRVAL_PP(container);

				switch (Z_TYPE_P(offset)) {
					case IS_DOUBLE:
						index = (long) Z_DVAL_P(offset);
						zend_hash_index_del(ht, index);
						break;
					case IS_RESOURCE:
					case IS_BOOL:
					case IS_LONG:
						index = Z_LVAL_P(offset);
						zend_hash_index_del(ht, index);
						break;
					case IS_STRING:
						if (IS_CV == IS_CV || IS_CV == IS_VAR) {
							offset->refcount++;
						}
						if (zend_symtable_del(ht, offset->value.str.val, offset->value.str.len+1) == SUCCESS &&
					    ht == &EG(symbol_table)) {
							zend_execute_data *ex;
							ulong hash_value = zend_inline_hash_func(offset->value.str.val, offset->value.str.len+1);

							for (ex = execute_data; ex; ex = ex->prev_execute_data) {
								if (ex->op_array && ex->symbol_table == ht) {
									int i;

									for (i = 0; i < ex->op_array->last_var; i++) {
										if (ex->op_array->vars[i].hash_value == hash_value &&
										    ex->op_array->vars[i].name_len == offset->value.str.len &&
										    !memcmp(ex->op_array->vars[i].name, offset->value.str.val, offset->value.str.len)) {
											ex->CVs[i] = NULL;
											break;
										}
									}
								}
							}
						}
						if (IS_CV == IS_CV || IS_CV == IS_VAR) {
							zval_ptr_dtor(&offset);
						}
						break;
					case IS_NULL:
						zend_hash_del(ht, "", sizeof(""));
						break;
					default:
						zend_error(E_WARNING, "Illegal offset type in unset");
						break;
				}

				break;
			}
			case IS_OBJECT:
				if (!Z_OBJ_HT_P(*container)->unset_dimension) {
					zend_error_noreturn(E_ERROR, "Cannot use object as array");
				}
				if (0) {
					MAKE_REAL_ZVAL_PTR(offset);
				}
				Z_OBJ_HT_P(*container)->unset_dimension(*container, offset TSRMLS_CC);
				if (0) {
					zval_ptr_dtor(&offset);
				} else {

				}
				break;
			case IS_STRING:
				zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
				ZEND_VM_CONTINUE(); /* bailed out before */
			default:

				break;
		}
	} else {

	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_UNSET_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval *offset = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

	if (container) {
		if (IS_VAR == IS_CV && container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
		if (Z_TYPE_PP(container) == IS_OBJECT) {
			if (0) {
				MAKE_REAL_ZVAL_PTR(offset);
			}
			Z_OBJ_HT_P(*container)->unset_property(*container, offset TSRMLS_CC);
			if (0) {
				zval_ptr_dtor(&offset);
			} else {

			}
		} else {

		}
	} else {

	}
	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CV(int prop_dim, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
	zval **value = NULL;
	int result = 0;
	long index;

	if (container) {

		zval *offset = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

		if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
			HashTable *ht;
			int isset = 0;

			ht = Z_ARRVAL_PP(container);

			switch (Z_TYPE_P(offset)) {
				case IS_DOUBLE:
					index = (long) Z_DVAL_P(offset);
					if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_RESOURCE:
				case IS_BOOL:
				case IS_LONG:
					index = Z_LVAL_P(offset);
					if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_STRING:
					if (zend_symtable_find(ht, offset->value.str.val, offset->value.str.len+1, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_NULL:
					if (zend_hash_find(ht, "", sizeof(""), (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				default:
					zend_error(E_WARNING, "Illegal offset type in isset or empty");

					break;
			}

			switch (opline->extended_value) {
				case ZEND_ISSET:
					if (isset && Z_TYPE_PP(value) == IS_NULL) {
						result = 0;
					} else {
						result = isset;
					}
					break;
				case ZEND_ISEMPTY:
					if (!isset || !i_zend_is_true(*value)) {
						result = 0;
					} else {
						result = 1;
					}
					break;
			}

		} else if (Z_TYPE_PP(container) == IS_OBJECT) {
			if (0) {
				MAKE_REAL_ZVAL_PTR(offset);
			}
			if (prop_dim) {
				result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value == ZEND_ISEMPTY) TSRMLS_CC);
			} else {
				result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value == ZEND_ISEMPTY) TSRMLS_CC);
			}
			if (0) {
				zval_ptr_dtor(&offset);
			} else {

			}
		} else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
			zval tmp;

			if (Z_TYPE_P(offset) != IS_LONG) {
				tmp = *offset;
				zval_copy_ctor(&tmp);
				convert_to_long(&tmp);
				offset = &tmp;
			}
			if (Z_TYPE_P(offset) == IS_LONG) {
				switch (opline->extended_value) {
					case ZEND_ISSET:
						if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
							result = 1;
						}
						break;
					case ZEND_ISEMPTY:
						if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
							result = 1;
						}
						break;
				}
			}

		} else {

		}
	}

	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;

	switch (opline->extended_value) {
		case ZEND_ISSET:
			Z_LVAL(EX_T(opline->result.u.var).tmp_var) = result;
			break;
		case ZEND_ISEMPTY:
			Z_LVAL(EX_T(opline->result.u.var).tmp_var) = !result;
			break;
	}

	if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CV(0, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CV(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval *obj = _get_obj_zval_ptr_unused(TSRMLS_C);
	zend_class_entry *ce;
	zend_function *clone;
	zend_object_clone_obj_t clone_call;

	if (!obj || Z_TYPE_P(obj) != IS_OBJECT) {
		zend_error_noreturn(E_ERROR, "__clone method called on non-object");
		EX_T(opline->result.u.var).var.ptr = EG(error_zval_ptr);
		EX_T(opline->result.u.var).var.ptr->refcount++;

		ZEND_VM_NEXT_OPCODE();
	}

	ce = Z_OBJCE_P(obj);
	clone = ce ? ce->clone : NULL;
	clone_call =  Z_OBJ_HT_P(obj)->clone_obj;
	if (!clone_call) {
		if (ce) {
			zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", ce->name);
		} else {
			zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object");
		}
		EX_T(opline->result.u.var).var.ptr = EG(error_zval_ptr);
		EX_T(opline->result.u.var).var.ptr->refcount++;
	}

	if (ce && clone) {
		if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) {
			/* Ensure that if we're calling a private function, we're allowed to do so.
			 */
			if (ce != EG(scope)) {
				zend_error_noreturn(E_ERROR, "Call to private %s::__clone() from context '%s'", ce->name, EG(scope) ? EG(scope)->name : "");
			}
		} else if ((clone->common.fn_flags & ZEND_ACC_PROTECTED)) {
			/* Ensure that if we're calling a protected function, we're allowed to do so.
			 */
			if (!zend_check_protected(clone->common.scope, EG(scope))) {
				zend_error_noreturn(E_ERROR, "Call to protected %s::__clone() from context '%s'", ce->name, EG(scope) ? EG(scope)->name : "");
			}
		}
	}

	EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
	if (!EG(exception)) {
		ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
		Z_OBJVAL_P(EX_T(opline->result.u.var).var.ptr) = clone_call(obj TSRMLS_CC);
		Z_TYPE_P(EX_T(opline->result.u.var).var.ptr) = IS_OBJECT;
		EX_T(opline->result.u.var).var.ptr->refcount=1;
		EX_T(opline->result.u.var).var.ptr->is_ref=1;
		if (!RETURN_VALUE_USED(opline) || EG(exception)) {
			zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_EXIT_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
#if 0 || (IS_UNUSED != IS_UNUSED)
	zend_op *opline = EX(opline);
	if (IS_UNUSED != IS_UNUSED) {

		zval *ptr = NULL;

		if (Z_TYPE_P(ptr) == IS_LONG) {
			EG(exit_status) = Z_LVAL_P(ptr);
		} else {
			zend_print_variable(ptr);
		}

	}
#endif
	zend_bailout();
	ZEND_VM_NEXT_OPCODE();
}

static int zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;
	zend_free_op free_op_data1;
	zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
	zval *object;
	zval *property = &opline->op2.u.constant;
	zval *value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
	znode *result = &opline->result;
	zval **retval = &EX_T(result->u.var).var.ptr;
	int have_get_ptr = 0;

	if (IS_UNUSED == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
	}

	EX_T(result->u.var).var.ptr_ptr = NULL;
	make_real_object(object_ptr TSRMLS_CC);
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to assign property of non-object");

		FREE_OP(free_op_data1);

		if (!RETURN_VALUE_UNUSED(result)) {
			*retval = EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*retval);
		}
	} else {
		/* here we are sure we are dealing with an object */
		if (0) {
			MAKE_REAL_ZVAL_PTR(property);
		}

		/* here property is a string */
		if (opline->extended_value == ZEND_ASSIGN_OBJ
			&& Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
			zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
			if (zptr != NULL) { 			/* NULL means no success in getting PTR */
				SEPARATE_ZVAL_IF_NOT_REF(zptr);

				have_get_ptr = 1;
				binary_op(*zptr, *zptr, value TSRMLS_CC);
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = *zptr;
					PZVAL_LOCK(*retval);
				}
			}
		}

		if (!have_get_ptr) {
			zval *z = NULL;

			switch (opline->extended_value) {
				case ZEND_ASSIGN_OBJ:
					if (Z_OBJ_HT_P(object)->read_property) {
						z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
					}
					break;
				case ZEND_ASSIGN_DIM:
					if (Z_OBJ_HT_P(object)->read_dimension) {
						z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
					}
					break;
			}
			if (z) {
				if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
					zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

					if (z->refcount == 0) {
						zval_dtor(z);
						FREE_ZVAL(z);
					}
					z = value;
				}
				z->refcount++;
				SEPARATE_ZVAL_IF_NOT_REF(&z);
				binary_op(z, z, value TSRMLS_CC);
				switch (opline->extended_value) {
					case ZEND_ASSIGN_OBJ:
						Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
						break;
					case ZEND_ASSIGN_DIM:
						Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
						break;
				}
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = z;
					PZVAL_LOCK(*retval);
				}
				zval_ptr_dtor(&z);
			} else {
				zend_error(E_WARNING, "Attempt to assign property of non-object");
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = EG(uninitialized_zval_ptr);
					PZVAL_LOCK(*retval);
				}
			}
		}

		if (0) {
			zval_ptr_dtor(&property);
		} else {

		}
		FREE_OP(free_op_data1);
	}

	/* assign_obj has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int zend_binary_assign_op_helper_SPEC_UNUSED_CONST(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op_data2, free_op_data1;
	zval **var_ptr;
	zval *value;
	zend_bool increment_opline = 0;

	switch (opline->extended_value) {
		case ZEND_ASSIGN_OBJ:
			return zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
			break;
		case ZEND_ASSIGN_DIM: {
				zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);

				if (object_ptr && IS_UNUSED != IS_CV && !0) {
					(*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
				}

				if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
					return zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
				} else {
					zend_op *op_data = opline+1;
					zval *dim = &opline->op2.u.constant;

					zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), NULL, dim, 0, BP_VAR_RW TSRMLS_CC);
					value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
					var_ptr = get_zval_ptr_ptr(&op_data->op2, EX(Ts), &free_op_data2, BP_VAR_RW);
					increment_opline = 1;
				}
			}
			break;
		default:
			value = &opline->op2.u.constant;
			var_ptr = NULL;
			/* do nothing */
			break;
	}

	if (!var_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets");
	}

	if (*var_ptr == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}


		if (increment_opline) {
			ZEND_VM_INC_OPCODE();
		}
		ZEND_VM_NEXT_OPCODE();
	}

	SEPARATE_ZVAL_IF_NOT_REF(var_ptr);

	if(Z_TYPE_PP(var_ptr) == IS_OBJECT && Z_OBJ_HANDLER_PP(var_ptr, get)
	   && Z_OBJ_HANDLER_PP(var_ptr, set)) {
		/* proxy object */
		zval *objval = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
		objval->refcount++;
		binary_op(objval, objval, value TSRMLS_CC);
		Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, objval TSRMLS_CC);
		zval_ptr_dtor(&objval);
	} else {
		binary_op(*var_ptr, *var_ptr, value TSRMLS_CC);
	}

	if (!RETURN_VALUE_UNUSED(&opline->result)) {
		EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
		PZVAL_LOCK(*var_ptr);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
	}

	if (increment_opline) {
		ZEND_VM_INC_OPCODE();
		FREE_OP(free_op_data1);
		FREE_OP_VAR_PTR(free_op_data2);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_ADD_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_CONST(add_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SUB_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_CONST(sub_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_MUL_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_CONST(mul_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_DIV_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_CONST(div_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_MOD_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_CONST(mod_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SL_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_CONST(shift_left_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SR_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_CONST(shift_right_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_CONCAT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_CONST(concat_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_OR_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_CONST(bitwise_or_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_AND_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_CONST(bitwise_and_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_XOR_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_CONST(bitwise_xor_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(incdec_t incdec_op, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
	zval *object;
	zval *property = &opline->op2.u.constant;
	zval **retval = &EX_T(opline->result.u.var).var.ptr;
	int have_get_ptr = 0;

	if (IS_UNUSED == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}

	make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");

		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			*retval = EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*retval);
		}

		ZEND_VM_NEXT_OPCODE();
	}

	/* here we are sure we are dealing with an object */

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}

	if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
		zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
		if (zptr != NULL) { 			/* NULL means no success in getting PTR */
			SEPARATE_ZVAL_IF_NOT_REF(zptr);

			have_get_ptr = 1;
			incdec_op(*zptr);
			if (!RETURN_VALUE_UNUSED(&opline->result)) {
				*retval = *zptr;
				PZVAL_LOCK(*retval);
			}
		}
	}

	if (!have_get_ptr) {
		if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
			zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);

			if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
				zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

				if (z->refcount == 0) {
					zval_dtor(z);
					FREE_ZVAL(z);
				}
				z = value;
			}
			z->refcount++;
			SEPARATE_ZVAL_IF_NOT_REF(&z);
			incdec_op(z);
			*retval = z;
			Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
			SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
			zval_ptr_dtor(&z);
		} else {
			zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
			if (!RETURN_VALUE_UNUSED(&opline->result)) {
				*retval = EG(uninitialized_zval_ptr);
				PZVAL_LOCK(*retval);
			}
		}
	}

	if (0) {
		zval_ptr_dtor(&property);
	} else {

	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_PRE_INC_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(increment_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_PRE_DEC_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(decrement_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_post_incdec_property_helper_SPEC_UNUSED_CONST(incdec_t incdec_op, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
	zval *object;
	zval *property = &opline->op2.u.constant;
	zval *retval = &EX_T(opline->result.u.var).tmp_var;
	int have_get_ptr = 0;

	if (IS_UNUSED == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}

	make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");

		*retval = *EG(uninitialized_zval_ptr);

		ZEND_VM_NEXT_OPCODE();
	}

	/* here we are sure we are dealing with an object */

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}

	if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
		zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
		if (zptr != NULL) { 			/* NULL means no success in getting PTR */
			have_get_ptr = 1;
			SEPARATE_ZVAL_IF_NOT_REF(zptr);

			*retval = **zptr;
			zendi_zval_copy_ctor(*retval);

			incdec_op(*zptr);

		}
	}

	if (!have_get_ptr) {
		if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
			zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
			zval *z_copy;

			if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
				zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

				if (z->refcount == 0) {
					zval_dtor(z);
					FREE_ZVAL(z);
				}
				z = value;
			}
			*retval = *z;
			zendi_zval_copy_ctor(*retval);
			ALLOC_ZVAL(z_copy);
			*z_copy = *z;
			zendi_zval_copy_ctor(*z_copy);
			INIT_PZVAL(z_copy);
			incdec_op(z_copy);
			z->refcount++;
			Z_OBJ_HT_P(object)->write_property(object, property, z_copy TSRMLS_CC);
			zval_ptr_dtor(&z_copy);
			zval_ptr_dtor(&z);
		} else {
			zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
			*retval = *EG(uninitialized_zval_ptr);
		}
	}

	if (0) {
		zval_ptr_dtor(&property);
	} else {

	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_post_incdec_property_helper_SPEC_UNUSED_CONST(increment_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_POST_DEC_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_post_incdec_property_helper_SPEC_UNUSED_CONST(decrement_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_fetch_property_address_read_helper_SPEC_UNUSED_CONST(int type, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *container;
	zval **retval;


	zval *offset  = &opline->op2.u.constant;

	retval = &EX_T(opline->result.u.var).var.ptr;
	EX_T(opline->result.u.var).var.ptr_ptr = retval;

	container = _get_obj_zval_ptr_unused(TSRMLS_C);

	if (container == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			*retval = EG(error_zval_ptr);
			PZVAL_LOCK(*retval);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}


		ZEND_VM_NEXT_OPCODE();
	}


	if (Z_TYPE_P(container) != IS_OBJECT || !Z_OBJ_HT_P(container)->read_property) {
		if (type != BP_VAR_IS) {
			zend_error(E_NOTICE, "Trying to get property of non-object");
		}
		*retval = EG(uninitialized_zval_ptr);
		SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
		AI_USE_PTR(EX_T(opline->result.u.var).var);

	} else {
		if (0) {
			MAKE_REAL_ZVAL_PTR(offset);
		}

		/* here we are sure we are dealing with an object */
		*retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);

		if (RETURN_VALUE_UNUSED(&opline->result) && ((*retval)->refcount == 0)) {
			zval_dtor(*retval);
			FREE_ZVAL(*retval);
		} else {
			SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}

		if (0) {
			zval_ptr_dtor(&offset);
		} else {

		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_property_address_read_helper_SPEC_UNUSED_CONST(BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *property = &opline->op2.u.constant;

	if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_UNUSED != IS_CV) {
		PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
		EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr;
	}

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_obj_zval_ptr_ptr_unused(TSRMLS_C), property, BP_VAR_W TSRMLS_CC);
	if (0) {
		zval_ptr_dtor(&property);
	} else {

	}
	if (IS_UNUSED == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *property = &opline->op2.u.constant;

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_obj_zval_ptr_ptr_unused(TSRMLS_C), property, BP_VAR_RW TSRMLS_CC);
	if (0) {
		zval_ptr_dtor(&property);
	} else {

	}
	if (IS_UNUSED == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_property_address_read_helper_SPEC_UNUSED_CONST(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) {
		/* Behave like FETCH_OBJ_W */
		zend_free_op free_op1;
		zval *property = &opline->op2.u.constant;

		if (0) {
			MAKE_REAL_ZVAL_PTR(property);
		}
		zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_obj_zval_ptr_ptr_unused(TSRMLS_C), property, BP_VAR_W TSRMLS_CC);
		if (0) {
			zval_ptr_dtor(&property);
		} else {

		}
		if (IS_UNUSED == IS_VAR && 0 &&
		    READY_TO_DESTROY(free_op1.var) &&
		    !RETURN_VALUE_UNUSED(&opline->result)) {
			AI_USE_PTR(EX_T(opline->result.u.var).var);
			if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
			    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
				SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
			}
		}

		ZEND_VM_NEXT_OPCODE();
	} else {
		return zend_fetch_property_address_read_helper_SPEC_UNUSED_CONST(BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
	}
}

static int ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_res;
	zval **container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
	zval *property = &opline->op2.u.constant;

	if (IS_UNUSED == IS_CV) {
		if (container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
	}
	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC);
	if (0) {
		zval_ptr_dtor(&property);
	} else {

	}
	if (IS_UNUSED == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &free_res);
	if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
		SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
	}
	PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
	FREE_OP_VAR_PTR(free_res);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;

	zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);

	zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);

	/* assign_obj has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *function_name;
	char *function_name_strval;
	int function_name_strlen;


	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), NULL);

	function_name = &opline->op2.u.constant;

	if (Z_TYPE_P(function_name)!=IS_STRING) {
		zend_error_noreturn(E_ERROR, "Method name must be a string");
	}

	function_name_strval = Z_STRVAL_P(function_name);
	function_name_strlen = Z_STRLEN_P(function_name);

	EX(object) = _get_obj_zval_ptr_unused(TSRMLS_C);

	if (EX(object) && Z_TYPE_P(EX(object)) == IS_OBJECT) {
		if (Z_OBJ_HT_P(EX(object))->get_method == NULL) {
			zend_error_noreturn(E_ERROR, "Object does not support method calls");
		}

		/* First, locate the function. */
		EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen TSRMLS_CC);
		if (!EX(fbc)) {
			zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
		}
	} else {
		zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
	}

	if (!EX(object) || (EX(fbc) && (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
		EX(object) = NULL;
	} else {
		if (!PZVAL_IS_REF(EX(object))) {
			EX(object)->refcount++; /* For $this pointer */
		} else {
			zval *this_ptr;
			ALLOC_ZVAL(this_ptr);
			INIT_PZVAL_COPY(this_ptr, EX(object));
			zval_copy_ctor(this_ptr);
			EX(object) = this_ptr;
		}
	}


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_class_entry *ce = NULL;
	zval **value;

	if (IS_UNUSED == IS_UNUSED) {
/* This seems to be a reminant of namespaces
		if (EG(scope)) {
			ce = EG(scope);
			if (zend_hash_find(&ce->constants_table, Z_STRVAL(opline->op2.u.constant), Z_STRLEN(opline->op2.u.constant)+1, (void **) &value) == SUCCESS) {
				zval_update_constant(value, (void *) 1 TSRMLS_CC);
				EX_T(opline->result.u.var).tmp_var = **value;
				zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var);
				ZEND_VM_NEXT_OPCODE();
			}
		}
*/
		if (!zend_get_constant(opline->op2.u.constant.value.str.val, opline->op2.u.constant.value.str.len, &EX_T(opline->result.u.var).tmp_var TSRMLS_CC)) {
			zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'",
						opline->op2.u.constant.value.str.val,
						opline->op2.u.constant.value.str.val);
			EX_T(opline->result.u.var).tmp_var = opline->op2.u.constant;
			zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var);
		}
		ZEND_VM_NEXT_OPCODE();
	}

	ce = EX_T(opline->op1.u.var).class_entry;

	if (zend_hash_find(&ce->constants_table, opline->op2.u.constant.value.str.val, opline->op2.u.constant.value.str.len+1, (void **) &value) == SUCCESS) {
		zend_class_entry *old_scope = EG(scope);

		EG(scope) = ce;
		zval_update_constant(value, (void *) 1 TSRMLS_CC);
		EG(scope) = old_scope;
		EX_T(opline->result.u.var).tmp_var = **value;
		zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var);
	} else {
		zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", opline->op2.u.constant.value.str.val);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_ARRAY_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	array_init(&EX_T(opline->result.u.var).tmp_var);
	if (IS_UNUSED == IS_UNUSED) {
		ZEND_VM_NEXT_OPCODE();
#if 0 || IS_UNUSED != IS_UNUSED
	} else {
		return ZEND_ADD_ARRAY_ELEMENT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
#endif
	}
}

static int ZEND_UNSET_DIM_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval **container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
	zval *offset = &opline->op2.u.constant;
	long index;

	if (container) {
		if (IS_UNUSED == IS_CV && container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
		switch (Z_TYPE_PP(container)) {
			case IS_ARRAY: {
				HashTable *ht = Z_ARRVAL_PP(container);

				switch (Z_TYPE_P(offset)) {
					case IS_DOUBLE:
						index = (long) Z_DVAL_P(offset);
						zend_hash_index_del(ht, index);
						break;
					case IS_RESOURCE:
					case IS_BOOL:
					case IS_LONG:
						index = Z_LVAL_P(offset);
						zend_hash_index_del(ht, index);
						break;
					case IS_STRING:
						if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
							offset->refcount++;
						}
						if (zend_symtable_del(ht, offset->value.str.val, offset->value.str.len+1) == SUCCESS &&
					    ht == &EG(symbol_table)) {
							zend_execute_data *ex;
							ulong hash_value = zend_inline_hash_func(offset->value.str.val, offset->value.str.len+1);

							for (ex = execute_data; ex; ex = ex->prev_execute_data) {
								if (ex->op_array && ex->symbol_table == ht) {
									int i;

									for (i = 0; i < ex->op_array->last_var; i++) {
										if (ex->op_array->vars[i].hash_value == hash_value &&
										    ex->op_array->vars[i].name_len == offset->value.str.len &&
										    !memcmp(ex->op_array->vars[i].name, offset->value.str.val, offset->value.str.len)) {
											ex->CVs[i] = NULL;
											break;
										}
									}
								}
							}
						}
						if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
							zval_ptr_dtor(&offset);
						}
						break;
					case IS_NULL:
						zend_hash_del(ht, "", sizeof(""));
						break;
					default:
						zend_error(E_WARNING, "Illegal offset type in unset");
						break;
				}

				break;
			}
			case IS_OBJECT:
				if (!Z_OBJ_HT_P(*container)->unset_dimension) {
					zend_error_noreturn(E_ERROR, "Cannot use object as array");
				}
				if (0) {
					MAKE_REAL_ZVAL_PTR(offset);
				}
				Z_OBJ_HT_P(*container)->unset_dimension(*container, offset TSRMLS_CC);
				if (0) {
					zval_ptr_dtor(&offset);
				} else {

				}
				break;
			case IS_STRING:
				zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
				ZEND_VM_CONTINUE(); /* bailed out before */
			default:

				break;
		}
	} else {

	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval **container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
	zval *offset = &opline->op2.u.constant;

	if (container) {
		if (IS_UNUSED == IS_CV && container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
		if (Z_TYPE_PP(container) == IS_OBJECT) {
			if (0) {
				MAKE_REAL_ZVAL_PTR(offset);
			}
			Z_OBJ_HT_P(*container)->unset_property(*container, offset TSRMLS_CC);
			if (0) {
				zval_ptr_dtor(&offset);
			} else {

			}
		} else {

		}
	} else {

	}

	ZEND_VM_NEXT_OPCODE();
}

static int zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CONST(int prop_dim, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval **container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
	zval **value = NULL;
	int result = 0;
	long index;

	if (container) {

		zval *offset = &opline->op2.u.constant;

		if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
			HashTable *ht;
			int isset = 0;

			ht = Z_ARRVAL_PP(container);

			switch (Z_TYPE_P(offset)) {
				case IS_DOUBLE:
					index = (long) Z_DVAL_P(offset);
					if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_RESOURCE:
				case IS_BOOL:
				case IS_LONG:
					index = Z_LVAL_P(offset);
					if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_STRING:
					if (zend_symtable_find(ht, offset->value.str.val, offset->value.str.len+1, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_NULL:
					if (zend_hash_find(ht, "", sizeof(""), (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				default:
					zend_error(E_WARNING, "Illegal offset type in isset or empty");

					break;
			}

			switch (opline->extended_value) {
				case ZEND_ISSET:
					if (isset && Z_TYPE_PP(value) == IS_NULL) {
						result = 0;
					} else {
						result = isset;
					}
					break;
				case ZEND_ISEMPTY:
					if (!isset || !i_zend_is_true(*value)) {
						result = 0;
					} else {
						result = 1;
					}
					break;
			}

		} else if (Z_TYPE_PP(container) == IS_OBJECT) {
			if (0) {
				MAKE_REAL_ZVAL_PTR(offset);
			}
			if (prop_dim) {
				result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value == ZEND_ISEMPTY) TSRMLS_CC);
			} else {
				result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value == ZEND_ISEMPTY) TSRMLS_CC);
			}
			if (0) {
				zval_ptr_dtor(&offset);
			} else {

			}
		} else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
			zval tmp;

			if (Z_TYPE_P(offset) != IS_LONG) {
				tmp = *offset;
				zval_copy_ctor(&tmp);
				convert_to_long(&tmp);
				offset = &tmp;
			}
			if (Z_TYPE_P(offset) == IS_LONG) {
				switch (opline->extended_value) {
					case ZEND_ISSET:
						if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
							result = 1;
						}
						break;
					case ZEND_ISEMPTY:
						if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
							result = 1;
						}
						break;
				}
			}

		} else {

		}
	}

	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;

	switch (opline->extended_value) {
		case ZEND_ISSET:
			Z_LVAL(EX_T(opline->result.u.var).tmp_var) = result;
			break;
		case ZEND_ISEMPTY:
			Z_LVAL(EX_T(opline->result.u.var).tmp_var) = !result;
			break;
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CONST(0, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CONST(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;
	zend_free_op free_op2, free_op_data1;
	zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
	zval *object;
	zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	zval *value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
	znode *result = &opline->result;
	zval **retval = &EX_T(result->u.var).var.ptr;
	int have_get_ptr = 0;

	if (IS_UNUSED == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
	}

	EX_T(result->u.var).var.ptr_ptr = NULL;
	make_real_object(object_ptr TSRMLS_CC);
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to assign property of non-object");
		zval_dtor(free_op2.var);
		FREE_OP(free_op_data1);

		if (!RETURN_VALUE_UNUSED(result)) {
			*retval = EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*retval);
		}
	} else {
		/* here we are sure we are dealing with an object */
		if (1) {
			MAKE_REAL_ZVAL_PTR(property);
		}

		/* here property is a string */
		if (opline->extended_value == ZEND_ASSIGN_OBJ
			&& Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
			zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
			if (zptr != NULL) { 			/* NULL means no success in getting PTR */
				SEPARATE_ZVAL_IF_NOT_REF(zptr);

				have_get_ptr = 1;
				binary_op(*zptr, *zptr, value TSRMLS_CC);
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = *zptr;
					PZVAL_LOCK(*retval);
				}
			}
		}

		if (!have_get_ptr) {
			zval *z = NULL;

			switch (opline->extended_value) {
				case ZEND_ASSIGN_OBJ:
					if (Z_OBJ_HT_P(object)->read_property) {
						z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
					}
					break;
				case ZEND_ASSIGN_DIM:
					if (Z_OBJ_HT_P(object)->read_dimension) {
						z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
					}
					break;
			}
			if (z) {
				if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
					zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

					if (z->refcount == 0) {
						zval_dtor(z);
						FREE_ZVAL(z);
					}
					z = value;
				}
				z->refcount++;
				SEPARATE_ZVAL_IF_NOT_REF(&z);
				binary_op(z, z, value TSRMLS_CC);
				switch (opline->extended_value) {
					case ZEND_ASSIGN_OBJ:
						Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
						break;
					case ZEND_ASSIGN_DIM:
						Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
						break;
				}
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = z;
					PZVAL_LOCK(*retval);
				}
				zval_ptr_dtor(&z);
			} else {
				zend_error(E_WARNING, "Attempt to assign property of non-object");
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = EG(uninitialized_zval_ptr);
					PZVAL_LOCK(*retval);
				}
			}
		}

		if (1) {
			zval_ptr_dtor(&property);
		} else {
			zval_dtor(free_op2.var);
		}
		FREE_OP(free_op_data1);
	}

	/* assign_obj has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int zend_binary_assign_op_helper_SPEC_UNUSED_TMP(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2, free_op_data2, free_op_data1;
	zval **var_ptr;
	zval *value;
	zend_bool increment_opline = 0;

	switch (opline->extended_value) {
		case ZEND_ASSIGN_OBJ:
			return zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
			break;
		case ZEND_ASSIGN_DIM: {
				zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);

				if (object_ptr && IS_UNUSED != IS_CV && !0) {
					(*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
				}

				if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
					return zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
				} else {
					zend_op *op_data = opline+1;
					zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

					zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), NULL, dim, 1, BP_VAR_RW TSRMLS_CC);
					value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
					var_ptr = get_zval_ptr_ptr(&op_data->op2, EX(Ts), &free_op_data2, BP_VAR_RW);
					increment_opline = 1;
				}
			}
			break;
		default:
			value = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
			var_ptr = NULL;
			/* do nothing */
			break;
	}

	if (!var_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets");
	}

	if (*var_ptr == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}
		zval_dtor(free_op2.var);

		if (increment_opline) {
			ZEND_VM_INC_OPCODE();
		}
		ZEND_VM_NEXT_OPCODE();
	}

	SEPARATE_ZVAL_IF_NOT_REF(var_ptr);

	if(Z_TYPE_PP(var_ptr) == IS_OBJECT && Z_OBJ_HANDLER_PP(var_ptr, get)
	   && Z_OBJ_HANDLER_PP(var_ptr, set)) {
		/* proxy object */
		zval *objval = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
		objval->refcount++;
		binary_op(objval, objval, value TSRMLS_CC);
		Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, objval TSRMLS_CC);
		zval_ptr_dtor(&objval);
	} else {
		binary_op(*var_ptr, *var_ptr, value TSRMLS_CC);
	}

	if (!RETURN_VALUE_UNUSED(&opline->result)) {
		EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
		PZVAL_LOCK(*var_ptr);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
	}
	zval_dtor(free_op2.var);

	if (increment_opline) {
		ZEND_VM_INC_OPCODE();
		FREE_OP(free_op_data1);
		FREE_OP_VAR_PTR(free_op_data2);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_ADD_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_TMP(add_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SUB_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_TMP(sub_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_MUL_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_TMP(mul_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_DIV_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_TMP(div_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_MOD_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_TMP(mod_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SL_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_TMP(shift_left_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SR_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_TMP(shift_right_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_CONCAT_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_TMP(concat_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_OR_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_TMP(bitwise_or_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_AND_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_TMP(bitwise_and_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_XOR_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_TMP(bitwise_xor_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_pre_incdec_property_helper_SPEC_UNUSED_TMP(incdec_t incdec_op, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
	zval *object;
	zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	zval **retval = &EX_T(opline->result.u.var).var.ptr;
	int have_get_ptr = 0;

	if (IS_UNUSED == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}

	make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
		zval_dtor(free_op2.var);
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			*retval = EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*retval);
		}

		ZEND_VM_NEXT_OPCODE();
	}

	/* here we are sure we are dealing with an object */

	if (1) {
		MAKE_REAL_ZVAL_PTR(property);
	}

	if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
		zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
		if (zptr != NULL) { 			/* NULL means no success in getting PTR */
			SEPARATE_ZVAL_IF_NOT_REF(zptr);

			have_get_ptr = 1;
			incdec_op(*zptr);
			if (!RETURN_VALUE_UNUSED(&opline->result)) {
				*retval = *zptr;
				PZVAL_LOCK(*retval);
			}
		}
	}

	if (!have_get_ptr) {
		if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
			zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);

			if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
				zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

				if (z->refcount == 0) {
					zval_dtor(z);
					FREE_ZVAL(z);
				}
				z = value;
			}
			z->refcount++;
			SEPARATE_ZVAL_IF_NOT_REF(&z);
			incdec_op(z);
			*retval = z;
			Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
			SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
			zval_ptr_dtor(&z);
		} else {
			zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
			if (!RETURN_VALUE_UNUSED(&opline->result)) {
				*retval = EG(uninitialized_zval_ptr);
				PZVAL_LOCK(*retval);
			}
		}
	}

	if (1) {
		zval_ptr_dtor(&property);
	} else {
		zval_dtor(free_op2.var);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_pre_incdec_property_helper_SPEC_UNUSED_TMP(increment_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_PRE_DEC_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_pre_incdec_property_helper_SPEC_UNUSED_TMP(decrement_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_post_incdec_property_helper_SPEC_UNUSED_TMP(incdec_t incdec_op, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
	zval *object;
	zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	zval *retval = &EX_T(opline->result.u.var).tmp_var;
	int have_get_ptr = 0;

	if (IS_UNUSED == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}

	make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
		zval_dtor(free_op2.var);
		*retval = *EG(uninitialized_zval_ptr);

		ZEND_VM_NEXT_OPCODE();
	}

	/* here we are sure we are dealing with an object */

	if (1) {
		MAKE_REAL_ZVAL_PTR(property);
	}

	if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
		zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
		if (zptr != NULL) { 			/* NULL means no success in getting PTR */
			have_get_ptr = 1;
			SEPARATE_ZVAL_IF_NOT_REF(zptr);

			*retval = **zptr;
			zendi_zval_copy_ctor(*retval);

			incdec_op(*zptr);

		}
	}

	if (!have_get_ptr) {
		if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
			zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
			zval *z_copy;

			if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
				zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

				if (z->refcount == 0) {
					zval_dtor(z);
					FREE_ZVAL(z);
				}
				z = value;
			}
			*retval = *z;
			zendi_zval_copy_ctor(*retval);
			ALLOC_ZVAL(z_copy);
			*z_copy = *z;
			zendi_zval_copy_ctor(*z_copy);
			INIT_PZVAL(z_copy);
			incdec_op(z_copy);
			z->refcount++;
			Z_OBJ_HT_P(object)->write_property(object, property, z_copy TSRMLS_CC);
			zval_ptr_dtor(&z_copy);
			zval_ptr_dtor(&z);
		} else {
			zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
			*retval = *EG(uninitialized_zval_ptr);
		}
	}

	if (1) {
		zval_ptr_dtor(&property);
	} else {
		zval_dtor(free_op2.var);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_POST_INC_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_post_incdec_property_helper_SPEC_UNUSED_TMP(increment_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_POST_DEC_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_post_incdec_property_helper_SPEC_UNUSED_TMP(decrement_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_fetch_property_address_read_helper_SPEC_UNUSED_TMP(int type, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *container;
	zval **retval;

	zend_free_op free_op2;
	zval *offset  = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	retval = &EX_T(opline->result.u.var).var.ptr;
	EX_T(opline->result.u.var).var.ptr_ptr = retval;

	container = _get_obj_zval_ptr_unused(TSRMLS_C);

	if (container == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			*retval = EG(error_zval_ptr);
			PZVAL_LOCK(*retval);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}
		zval_dtor(free_op2.var);

		ZEND_VM_NEXT_OPCODE();
	}


	if (Z_TYPE_P(container) != IS_OBJECT || !Z_OBJ_HT_P(container)->read_property) {
		if (type != BP_VAR_IS) {
			zend_error(E_NOTICE, "Trying to get property of non-object");
		}
		*retval = EG(uninitialized_zval_ptr);
		SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		zval_dtor(free_op2.var);
	} else {
		if (1) {
			MAKE_REAL_ZVAL_PTR(offset);
		}

		/* here we are sure we are dealing with an object */
		*retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);

		if (RETURN_VALUE_UNUSED(&opline->result) && ((*retval)->refcount == 0)) {
			zval_dtor(*retval);
			FREE_ZVAL(*retval);
		} else {
			SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}

		if (1) {
			zval_ptr_dtor(&offset);
		} else {
			zval_dtor(free_op2.var);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_property_address_read_helper_SPEC_UNUSED_TMP(BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_UNUSED != IS_CV) {
		PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
		EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr;
	}

	if (1) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_obj_zval_ptr_ptr_unused(TSRMLS_C), property, BP_VAR_W TSRMLS_CC);
	if (1) {
		zval_ptr_dtor(&property);
	} else {
		zval_dtor(free_op2.var);
	}
	if (IS_UNUSED == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (1) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_obj_zval_ptr_ptr_unused(TSRMLS_C), property, BP_VAR_RW TSRMLS_CC);
	if (1) {
		zval_ptr_dtor(&property);
	} else {
		zval_dtor(free_op2.var);
	}
	if (IS_UNUSED == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_property_address_read_helper_SPEC_UNUSED_TMP(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) {
		/* Behave like FETCH_OBJ_W */
		zend_free_op free_op1, free_op2;
		zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

		if (1) {
			MAKE_REAL_ZVAL_PTR(property);
		}
		zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_obj_zval_ptr_ptr_unused(TSRMLS_C), property, BP_VAR_W TSRMLS_CC);
		if (1) {
			zval_ptr_dtor(&property);
		} else {
			zval_dtor(free_op2.var);
		}
		if (IS_UNUSED == IS_VAR && 0 &&
		    READY_TO_DESTROY(free_op1.var) &&
		    !RETURN_VALUE_UNUSED(&opline->result)) {
			AI_USE_PTR(EX_T(opline->result.u.var).var);
			if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
			    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
				SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
			}
		}

		ZEND_VM_NEXT_OPCODE();
	} else {
		return zend_fetch_property_address_read_helper_SPEC_UNUSED_TMP(BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
	}
}

static int ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2, free_res;
	zval **container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
	zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (IS_UNUSED == IS_CV) {
		if (container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
	}
	if (1) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC);
	if (1) {
		zval_ptr_dtor(&property);
	} else {
		zval_dtor(free_op2.var);
	}
	if (IS_UNUSED == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &free_res);
	if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
		SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
	}
	PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
	FREE_OP_VAR_PTR(free_res);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;

	zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);

	zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);

	/* assign_obj has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *function_name;
	char *function_name_strval;
	int function_name_strlen;
	zend_free_op free_op2;

	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), NULL);

	function_name = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (Z_TYPE_P(function_name)!=IS_STRING) {
		zend_error_noreturn(E_ERROR, "Method name must be a string");
	}

	function_name_strval = Z_STRVAL_P(function_name);
	function_name_strlen = Z_STRLEN_P(function_name);

	EX(object) = _get_obj_zval_ptr_unused(TSRMLS_C);

	if (EX(object) && Z_TYPE_P(EX(object)) == IS_OBJECT) {
		if (Z_OBJ_HT_P(EX(object))->get_method == NULL) {
			zend_error_noreturn(E_ERROR, "Object does not support method calls");
		}

		/* First, locate the function. */
		EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen TSRMLS_CC);
		if (!EX(fbc)) {
			zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
		}
	} else {
		zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
	}

	if (!EX(object) || (EX(fbc) && (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
		EX(object) = NULL;
	} else {
		if (!PZVAL_IS_REF(EX(object))) {
			EX(object)->refcount++; /* For $this pointer */
		} else {
			zval *this_ptr;
			ALLOC_ZVAL(this_ptr);
			INIT_PZVAL_COPY(this_ptr, EX(object));
			zval_copy_ctor(this_ptr);
			EX(object) = this_ptr;
		}
	}

	zval_dtor(free_op2.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_ARRAY_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	array_init(&EX_T(opline->result.u.var).tmp_var);
	if (IS_UNUSED == IS_UNUSED) {
		ZEND_VM_NEXT_OPCODE();
#if 0 || IS_UNUSED != IS_UNUSED
	} else {
		return ZEND_ADD_ARRAY_ELEMENT_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
#endif
	}
}

static int ZEND_UNSET_DIM_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zval **container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
	zval *offset = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	long index;

	if (container) {
		if (IS_UNUSED == IS_CV && container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
		switch (Z_TYPE_PP(container)) {
			case IS_ARRAY: {
				HashTable *ht = Z_ARRVAL_PP(container);

				switch (Z_TYPE_P(offset)) {
					case IS_DOUBLE:
						index = (long) Z_DVAL_P(offset);
						zend_hash_index_del(ht, index);
						break;
					case IS_RESOURCE:
					case IS_BOOL:
					case IS_LONG:
						index = Z_LVAL_P(offset);
						zend_hash_index_del(ht, index);
						break;
					case IS_STRING:
						if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
							offset->refcount++;
						}
						if (zend_symtable_del(ht, offset->value.str.val, offset->value.str.len+1) == SUCCESS &&
					    ht == &EG(symbol_table)) {
							zend_execute_data *ex;
							ulong hash_value = zend_inline_hash_func(offset->value.str.val, offset->value.str.len+1);

							for (ex = execute_data; ex; ex = ex->prev_execute_data) {
								if (ex->op_array && ex->symbol_table == ht) {
									int i;

									for (i = 0; i < ex->op_array->last_var; i++) {
										if (ex->op_array->vars[i].hash_value == hash_value &&
										    ex->op_array->vars[i].name_len == offset->value.str.len &&
										    !memcmp(ex->op_array->vars[i].name, offset->value.str.val, offset->value.str.len)) {
											ex->CVs[i] = NULL;
											break;
										}
									}
								}
							}
						}
						if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
							zval_ptr_dtor(&offset);
						}
						break;
					case IS_NULL:
						zend_hash_del(ht, "", sizeof(""));
						break;
					default:
						zend_error(E_WARNING, "Illegal offset type in unset");
						break;
				}
				zval_dtor(free_op2.var);
				break;
			}
			case IS_OBJECT:
				if (!Z_OBJ_HT_P(*container)->unset_dimension) {
					zend_error_noreturn(E_ERROR, "Cannot use object as array");
				}
				if (1) {
					MAKE_REAL_ZVAL_PTR(offset);
				}
				Z_OBJ_HT_P(*container)->unset_dimension(*container, offset TSRMLS_CC);
				if (1) {
					zval_ptr_dtor(&offset);
				} else {
					zval_dtor(free_op2.var);
				}
				break;
			case IS_STRING:
				zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
				ZEND_VM_CONTINUE(); /* bailed out before */
			default:
				zval_dtor(free_op2.var);
				break;
		}
	} else {
		zval_dtor(free_op2.var);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_UNSET_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zval **container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
	zval *offset = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (container) {
		if (IS_UNUSED == IS_CV && container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
		if (Z_TYPE_PP(container) == IS_OBJECT) {
			if (1) {
				MAKE_REAL_ZVAL_PTR(offset);
			}
			Z_OBJ_HT_P(*container)->unset_property(*container, offset TSRMLS_CC);
			if (1) {
				zval_ptr_dtor(&offset);
			} else {
				zval_dtor(free_op2.var);
			}
		} else {
			zval_dtor(free_op2.var);
		}
	} else {
		zval_dtor(free_op2.var);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_TMP(int prop_dim, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval **container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
	zval **value = NULL;
	int result = 0;
	long index;

	if (container) {
		zend_free_op free_op2;
		zval *offset = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

		if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
			HashTable *ht;
			int isset = 0;

			ht = Z_ARRVAL_PP(container);

			switch (Z_TYPE_P(offset)) {
				case IS_DOUBLE:
					index = (long) Z_DVAL_P(offset);
					if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_RESOURCE:
				case IS_BOOL:
				case IS_LONG:
					index = Z_LVAL_P(offset);
					if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_STRING:
					if (zend_symtable_find(ht, offset->value.str.val, offset->value.str.len+1, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_NULL:
					if (zend_hash_find(ht, "", sizeof(""), (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				default:
					zend_error(E_WARNING, "Illegal offset type in isset or empty");

					break;
			}

			switch (opline->extended_value) {
				case ZEND_ISSET:
					if (isset && Z_TYPE_PP(value) == IS_NULL) {
						result = 0;
					} else {
						result = isset;
					}
					break;
				case ZEND_ISEMPTY:
					if (!isset || !i_zend_is_true(*value)) {
						result = 0;
					} else {
						result = 1;
					}
					break;
			}
			zval_dtor(free_op2.var);
		} else if (Z_TYPE_PP(container) == IS_OBJECT) {
			if (1) {
				MAKE_REAL_ZVAL_PTR(offset);
			}
			if (prop_dim) {
				result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value == ZEND_ISEMPTY) TSRMLS_CC);
			} else {
				result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value == ZEND_ISEMPTY) TSRMLS_CC);
			}
			if (1) {
				zval_ptr_dtor(&offset);
			} else {
				zval_dtor(free_op2.var);
			}
		} else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
			zval tmp;

			if (Z_TYPE_P(offset) != IS_LONG) {
				tmp = *offset;
				zval_copy_ctor(&tmp);
				convert_to_long(&tmp);
				offset = &tmp;
			}
			if (Z_TYPE_P(offset) == IS_LONG) {
				switch (opline->extended_value) {
					case ZEND_ISSET:
						if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
							result = 1;
						}
						break;
					case ZEND_ISEMPTY:
						if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
							result = 1;
						}
						break;
				}
			}
			zval_dtor(free_op2.var);
		} else {
			zval_dtor(free_op2.var);
		}
	}

	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;

	switch (opline->extended_value) {
		case ZEND_ISSET:
			Z_LVAL(EX_T(opline->result.u.var).tmp_var) = result;
			break;
		case ZEND_ISEMPTY:
			Z_LVAL(EX_T(opline->result.u.var).tmp_var) = !result;
			break;
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_TMP(0, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_TMP(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;
	zend_free_op free_op2, free_op_data1;
	zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
	zval *object;
	zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	zval *value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
	znode *result = &opline->result;
	zval **retval = &EX_T(result->u.var).var.ptr;
	int have_get_ptr = 0;

	if (IS_UNUSED == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
	}

	EX_T(result->u.var).var.ptr_ptr = NULL;
	make_real_object(object_ptr TSRMLS_CC);
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to assign property of non-object");
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
		FREE_OP(free_op_data1);

		if (!RETURN_VALUE_UNUSED(result)) {
			*retval = EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*retval);
		}
	} else {
		/* here we are sure we are dealing with an object */
		if (0) {
			MAKE_REAL_ZVAL_PTR(property);
		}

		/* here property is a string */
		if (opline->extended_value == ZEND_ASSIGN_OBJ
			&& Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
			zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
			if (zptr != NULL) { 			/* NULL means no success in getting PTR */
				SEPARATE_ZVAL_IF_NOT_REF(zptr);

				have_get_ptr = 1;
				binary_op(*zptr, *zptr, value TSRMLS_CC);
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = *zptr;
					PZVAL_LOCK(*retval);
				}
			}
		}

		if (!have_get_ptr) {
			zval *z = NULL;

			switch (opline->extended_value) {
				case ZEND_ASSIGN_OBJ:
					if (Z_OBJ_HT_P(object)->read_property) {
						z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
					}
					break;
				case ZEND_ASSIGN_DIM:
					if (Z_OBJ_HT_P(object)->read_dimension) {
						z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
					}
					break;
			}
			if (z) {
				if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
					zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

					if (z->refcount == 0) {
						zval_dtor(z);
						FREE_ZVAL(z);
					}
					z = value;
				}
				z->refcount++;
				SEPARATE_ZVAL_IF_NOT_REF(&z);
				binary_op(z, z, value TSRMLS_CC);
				switch (opline->extended_value) {
					case ZEND_ASSIGN_OBJ:
						Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
						break;
					case ZEND_ASSIGN_DIM:
						Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
						break;
				}
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = z;
					PZVAL_LOCK(*retval);
				}
				zval_ptr_dtor(&z);
			} else {
				zend_error(E_WARNING, "Attempt to assign property of non-object");
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = EG(uninitialized_zval_ptr);
					PZVAL_LOCK(*retval);
				}
			}
		}

		if (0) {
			zval_ptr_dtor(&property);
		} else {
			if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
		}
		FREE_OP(free_op_data1);
	}

	/* assign_obj has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int zend_binary_assign_op_helper_SPEC_UNUSED_VAR(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2, free_op_data2, free_op_data1;
	zval **var_ptr;
	zval *value;
	zend_bool increment_opline = 0;

	switch (opline->extended_value) {
		case ZEND_ASSIGN_OBJ:
			return zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
			break;
		case ZEND_ASSIGN_DIM: {
				zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);

				if (object_ptr && IS_UNUSED != IS_CV && !0) {
					(*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
				}

				if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
					return zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
				} else {
					zend_op *op_data = opline+1;
					zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

					zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), NULL, dim, 0, BP_VAR_RW TSRMLS_CC);
					value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
					var_ptr = get_zval_ptr_ptr(&op_data->op2, EX(Ts), &free_op_data2, BP_VAR_RW);
					increment_opline = 1;
				}
			}
			break;
		default:
			value = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
			var_ptr = NULL;
			/* do nothing */
			break;
	}

	if (!var_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets");
	}

	if (*var_ptr == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};

		if (increment_opline) {
			ZEND_VM_INC_OPCODE();
		}
		ZEND_VM_NEXT_OPCODE();
	}

	SEPARATE_ZVAL_IF_NOT_REF(var_ptr);

	if(Z_TYPE_PP(var_ptr) == IS_OBJECT && Z_OBJ_HANDLER_PP(var_ptr, get)
	   && Z_OBJ_HANDLER_PP(var_ptr, set)) {
		/* proxy object */
		zval *objval = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
		objval->refcount++;
		binary_op(objval, objval, value TSRMLS_CC);
		Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, objval TSRMLS_CC);
		zval_ptr_dtor(&objval);
	} else {
		binary_op(*var_ptr, *var_ptr, value TSRMLS_CC);
	}

	if (!RETURN_VALUE_UNUSED(&opline->result)) {
		EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
		PZVAL_LOCK(*var_ptr);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
	}
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};

	if (increment_opline) {
		ZEND_VM_INC_OPCODE();
		FREE_OP(free_op_data1);
		FREE_OP_VAR_PTR(free_op_data2);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_ADD_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_VAR(add_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SUB_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_VAR(sub_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_MUL_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_VAR(mul_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_DIV_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_VAR(div_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_MOD_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_VAR(mod_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SL_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_VAR(shift_left_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SR_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_VAR(shift_right_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_CONCAT_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_VAR(concat_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_OR_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_VAR(bitwise_or_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_AND_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_VAR(bitwise_and_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_XOR_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_VAR(bitwise_xor_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_pre_incdec_property_helper_SPEC_UNUSED_VAR(incdec_t incdec_op, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
	zval *object;
	zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	zval **retval = &EX_T(opline->result.u.var).var.ptr;
	int have_get_ptr = 0;

	if (IS_UNUSED == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}

	make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			*retval = EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*retval);
		}

		ZEND_VM_NEXT_OPCODE();
	}

	/* here we are sure we are dealing with an object */

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}

	if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
		zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
		if (zptr != NULL) { 			/* NULL means no success in getting PTR */
			SEPARATE_ZVAL_IF_NOT_REF(zptr);

			have_get_ptr = 1;
			incdec_op(*zptr);
			if (!RETURN_VALUE_UNUSED(&opline->result)) {
				*retval = *zptr;
				PZVAL_LOCK(*retval);
			}
		}
	}

	if (!have_get_ptr) {
		if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
			zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);

			if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
				zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

				if (z->refcount == 0) {
					zval_dtor(z);
					FREE_ZVAL(z);
				}
				z = value;
			}
			z->refcount++;
			SEPARATE_ZVAL_IF_NOT_REF(&z);
			incdec_op(z);
			*retval = z;
			Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
			SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
			zval_ptr_dtor(&z);
		} else {
			zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
			if (!RETURN_VALUE_UNUSED(&opline->result)) {
				*retval = EG(uninitialized_zval_ptr);
				PZVAL_LOCK(*retval);
			}
		}
	}

	if (0) {
		zval_ptr_dtor(&property);
	} else {
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_PRE_INC_OBJ_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_pre_incdec_property_helper_SPEC_UNUSED_VAR(increment_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_PRE_DEC_OBJ_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_pre_incdec_property_helper_SPEC_UNUSED_VAR(decrement_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_post_incdec_property_helper_SPEC_UNUSED_VAR(incdec_t incdec_op, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
	zval *object;
	zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	zval *retval = &EX_T(opline->result.u.var).tmp_var;
	int have_get_ptr = 0;

	if (IS_UNUSED == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}

	make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
		*retval = *EG(uninitialized_zval_ptr);

		ZEND_VM_NEXT_OPCODE();
	}

	/* here we are sure we are dealing with an object */

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}

	if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
		zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
		if (zptr != NULL) { 			/* NULL means no success in getting PTR */
			have_get_ptr = 1;
			SEPARATE_ZVAL_IF_NOT_REF(zptr);

			*retval = **zptr;
			zendi_zval_copy_ctor(*retval);

			incdec_op(*zptr);

		}
	}

	if (!have_get_ptr) {
		if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
			zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
			zval *z_copy;

			if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
				zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

				if (z->refcount == 0) {
					zval_dtor(z);
					FREE_ZVAL(z);
				}
				z = value;
			}
			*retval = *z;
			zendi_zval_copy_ctor(*retval);
			ALLOC_ZVAL(z_copy);
			*z_copy = *z;
			zendi_zval_copy_ctor(*z_copy);
			INIT_PZVAL(z_copy);
			incdec_op(z_copy);
			z->refcount++;
			Z_OBJ_HT_P(object)->write_property(object, property, z_copy TSRMLS_CC);
			zval_ptr_dtor(&z_copy);
			zval_ptr_dtor(&z);
		} else {
			zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
			*retval = *EG(uninitialized_zval_ptr);
		}
	}

	if (0) {
		zval_ptr_dtor(&property);
	} else {
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_POST_INC_OBJ_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_post_incdec_property_helper_SPEC_UNUSED_VAR(increment_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_POST_DEC_OBJ_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_post_incdec_property_helper_SPEC_UNUSED_VAR(decrement_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_fetch_property_address_read_helper_SPEC_UNUSED_VAR(int type, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *container;
	zval **retval;

	zend_free_op free_op2;
	zval *offset  = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	retval = &EX_T(opline->result.u.var).var.ptr;
	EX_T(opline->result.u.var).var.ptr_ptr = retval;

	container = _get_obj_zval_ptr_unused(TSRMLS_C);

	if (container == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			*retval = EG(error_zval_ptr);
			PZVAL_LOCK(*retval);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};

		ZEND_VM_NEXT_OPCODE();
	}


	if (Z_TYPE_P(container) != IS_OBJECT || !Z_OBJ_HT_P(container)->read_property) {
		if (type != BP_VAR_IS) {
			zend_error(E_NOTICE, "Trying to get property of non-object");
		}
		*retval = EG(uninitialized_zval_ptr);
		SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	} else {
		if (0) {
			MAKE_REAL_ZVAL_PTR(offset);
		}

		/* here we are sure we are dealing with an object */
		*retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);

		if (RETURN_VALUE_UNUSED(&opline->result) && ((*retval)->refcount == 0)) {
			zval_dtor(*retval);
			FREE_ZVAL(*retval);
		} else {
			SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}

		if (0) {
			zval_ptr_dtor(&offset);
		} else {
			if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_R_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_property_address_read_helper_SPEC_UNUSED_VAR(BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_OBJ_W_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_UNUSED != IS_CV) {
		PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
		EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr;
	}

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_obj_zval_ptr_ptr_unused(TSRMLS_C), property, BP_VAR_W TSRMLS_CC);
	if (0) {
		zval_ptr_dtor(&property);
	} else {
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	}
	if (IS_UNUSED == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_RW_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_obj_zval_ptr_ptr_unused(TSRMLS_C), property, BP_VAR_RW TSRMLS_CC);
	if (0) {
		zval_ptr_dtor(&property);
	} else {
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	}
	if (IS_UNUSED == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_IS_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_property_address_read_helper_SPEC_UNUSED_VAR(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) {
		/* Behave like FETCH_OBJ_W */
		zend_free_op free_op1, free_op2;
		zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

		if (0) {
			MAKE_REAL_ZVAL_PTR(property);
		}
		zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_obj_zval_ptr_ptr_unused(TSRMLS_C), property, BP_VAR_W TSRMLS_CC);
		if (0) {
			zval_ptr_dtor(&property);
		} else {
			if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
		}
		if (IS_UNUSED == IS_VAR && 0 &&
		    READY_TO_DESTROY(free_op1.var) &&
		    !RETURN_VALUE_UNUSED(&opline->result)) {
			AI_USE_PTR(EX_T(opline->result.u.var).var);
			if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
			    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
				SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
			}
		}

		ZEND_VM_NEXT_OPCODE();
	} else {
		return zend_fetch_property_address_read_helper_SPEC_UNUSED_VAR(BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
	}
}

static int ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2, free_res;
	zval **container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
	zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (IS_UNUSED == IS_CV) {
		if (container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
	}
	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC);
	if (0) {
		zval_ptr_dtor(&property);
	} else {
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	}
	if (IS_UNUSED == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &free_res);
	if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
		SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
	}
	PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
	FREE_OP_VAR_PTR(free_res);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_OBJ_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;

	zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);

	zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);

	/* assign_obj has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_METHOD_CALL_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *function_name;
	char *function_name_strval;
	int function_name_strlen;
	zend_free_op free_op2;

	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), NULL);

	function_name = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (Z_TYPE_P(function_name)!=IS_STRING) {
		zend_error_noreturn(E_ERROR, "Method name must be a string");
	}

	function_name_strval = Z_STRVAL_P(function_name);
	function_name_strlen = Z_STRLEN_P(function_name);

	EX(object) = _get_obj_zval_ptr_unused(TSRMLS_C);

	if (EX(object) && Z_TYPE_P(EX(object)) == IS_OBJECT) {
		if (Z_OBJ_HT_P(EX(object))->get_method == NULL) {
			zend_error_noreturn(E_ERROR, "Object does not support method calls");
		}

		/* First, locate the function. */
		EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen TSRMLS_CC);
		if (!EX(fbc)) {
			zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
		}
	} else {
		zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
	}

	if (!EX(object) || (EX(fbc) && (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
		EX(object) = NULL;
	} else {
		if (!PZVAL_IS_REF(EX(object))) {
			EX(object)->refcount++; /* For $this pointer */
		} else {
			zval *this_ptr;
			ALLOC_ZVAL(this_ptr);
			INIT_PZVAL_COPY(this_ptr, EX(object));
			zval_copy_ctor(this_ptr);
			EX(object) = this_ptr;
		}
	}

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_ARRAY_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	array_init(&EX_T(opline->result.u.var).tmp_var);
	if (IS_UNUSED == IS_UNUSED) {
		ZEND_VM_NEXT_OPCODE();
#if 0 || IS_UNUSED != IS_UNUSED
	} else {
		return ZEND_ADD_ARRAY_ELEMENT_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
#endif
	}
}

static int ZEND_UNSET_DIM_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zval **container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
	zval *offset = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	long index;

	if (container) {
		if (IS_UNUSED == IS_CV && container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
		switch (Z_TYPE_PP(container)) {
			case IS_ARRAY: {
				HashTable *ht = Z_ARRVAL_PP(container);

				switch (Z_TYPE_P(offset)) {
					case IS_DOUBLE:
						index = (long) Z_DVAL_P(offset);
						zend_hash_index_del(ht, index);
						break;
					case IS_RESOURCE:
					case IS_BOOL:
					case IS_LONG:
						index = Z_LVAL_P(offset);
						zend_hash_index_del(ht, index);
						break;
					case IS_STRING:
						if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
							offset->refcount++;
						}
						if (zend_symtable_del(ht, offset->value.str.val, offset->value.str.len+1) == SUCCESS &&
					    ht == &EG(symbol_table)) {
							zend_execute_data *ex;
							ulong hash_value = zend_inline_hash_func(offset->value.str.val, offset->value.str.len+1);

							for (ex = execute_data; ex; ex = ex->prev_execute_data) {
								if (ex->op_array && ex->symbol_table == ht) {
									int i;

									for (i = 0; i < ex->op_array->last_var; i++) {
										if (ex->op_array->vars[i].hash_value == hash_value &&
										    ex->op_array->vars[i].name_len == offset->value.str.len &&
										    !memcmp(ex->op_array->vars[i].name, offset->value.str.val, offset->value.str.len)) {
											ex->CVs[i] = NULL;
											break;
										}
									}
								}
							}
						}
						if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
							zval_ptr_dtor(&offset);
						}
						break;
					case IS_NULL:
						zend_hash_del(ht, "", sizeof(""));
						break;
					default:
						zend_error(E_WARNING, "Illegal offset type in unset");
						break;
				}
				if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
				break;
			}
			case IS_OBJECT:
				if (!Z_OBJ_HT_P(*container)->unset_dimension) {
					zend_error_noreturn(E_ERROR, "Cannot use object as array");
				}
				if (0) {
					MAKE_REAL_ZVAL_PTR(offset);
				}
				Z_OBJ_HT_P(*container)->unset_dimension(*container, offset TSRMLS_CC);
				if (0) {
					zval_ptr_dtor(&offset);
				} else {
					if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
				}
				break;
			case IS_STRING:
				zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
				ZEND_VM_CONTINUE(); /* bailed out before */
			default:
				if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
				break;
		}
	} else {
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_UNSET_OBJ_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zval **container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
	zval *offset = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (container) {
		if (IS_UNUSED == IS_CV && container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
		if (Z_TYPE_PP(container) == IS_OBJECT) {
			if (0) {
				MAKE_REAL_ZVAL_PTR(offset);
			}
			Z_OBJ_HT_P(*container)->unset_property(*container, offset TSRMLS_CC);
			if (0) {
				zval_ptr_dtor(&offset);
			} else {
				if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
			}
		} else {
			if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
		}
	} else {
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	}

	ZEND_VM_NEXT_OPCODE();
}

static int zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_VAR(int prop_dim, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval **container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
	zval **value = NULL;
	int result = 0;
	long index;

	if (container) {
		zend_free_op free_op2;
		zval *offset = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

		if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
			HashTable *ht;
			int isset = 0;

			ht = Z_ARRVAL_PP(container);

			switch (Z_TYPE_P(offset)) {
				case IS_DOUBLE:
					index = (long) Z_DVAL_P(offset);
					if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_RESOURCE:
				case IS_BOOL:
				case IS_LONG:
					index = Z_LVAL_P(offset);
					if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_STRING:
					if (zend_symtable_find(ht, offset->value.str.val, offset->value.str.len+1, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_NULL:
					if (zend_hash_find(ht, "", sizeof(""), (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				default:
					zend_error(E_WARNING, "Illegal offset type in isset or empty");

					break;
			}

			switch (opline->extended_value) {
				case ZEND_ISSET:
					if (isset && Z_TYPE_PP(value) == IS_NULL) {
						result = 0;
					} else {
						result = isset;
					}
					break;
				case ZEND_ISEMPTY:
					if (!isset || !i_zend_is_true(*value)) {
						result = 0;
					} else {
						result = 1;
					}
					break;
			}
			if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
		} else if (Z_TYPE_PP(container) == IS_OBJECT) {
			if (0) {
				MAKE_REAL_ZVAL_PTR(offset);
			}
			if (prop_dim) {
				result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value == ZEND_ISEMPTY) TSRMLS_CC);
			} else {
				result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value == ZEND_ISEMPTY) TSRMLS_CC);
			}
			if (0) {
				zval_ptr_dtor(&offset);
			} else {
				if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
			}
		} else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
			zval tmp;

			if (Z_TYPE_P(offset) != IS_LONG) {
				tmp = *offset;
				zval_copy_ctor(&tmp);
				convert_to_long(&tmp);
				offset = &tmp;
			}
			if (Z_TYPE_P(offset) == IS_LONG) {
				switch (opline->extended_value) {
					case ZEND_ISSET:
						if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
							result = 1;
						}
						break;
					case ZEND_ISEMPTY:
						if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
							result = 1;
						}
						break;
				}
			}
			if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
		} else {
			if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
		}
	}

	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;

	switch (opline->extended_value) {
		case ZEND_ISSET:
			Z_LVAL(EX_T(opline->result.u.var).tmp_var) = result;
			break;
		case ZEND_ISEMPTY:
			Z_LVAL(EX_T(opline->result.u.var).tmp_var) = !result;
			break;
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_VAR(0, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_VAR(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;
	zend_free_op free_op_data1;
	zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
	zval *object;
	zval *property = NULL;
	zval *value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
	znode *result = &opline->result;
	zval **retval = &EX_T(result->u.var).var.ptr;
	int have_get_ptr = 0;

	if (IS_UNUSED == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
	}

	EX_T(result->u.var).var.ptr_ptr = NULL;
	make_real_object(object_ptr TSRMLS_CC);
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to assign property of non-object");

		FREE_OP(free_op_data1);

		if (!RETURN_VALUE_UNUSED(result)) {
			*retval = EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*retval);
		}
	} else {
		/* here we are sure we are dealing with an object */
		if (0) {
			MAKE_REAL_ZVAL_PTR(property);
		}

		/* here property is a string */
		if (opline->extended_value == ZEND_ASSIGN_OBJ
			&& Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
			zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
			if (zptr != NULL) { 			/* NULL means no success in getting PTR */
				SEPARATE_ZVAL_IF_NOT_REF(zptr);

				have_get_ptr = 1;
				binary_op(*zptr, *zptr, value TSRMLS_CC);
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = *zptr;
					PZVAL_LOCK(*retval);
				}
			}
		}

		if (!have_get_ptr) {
			zval *z = NULL;

			switch (opline->extended_value) {
				case ZEND_ASSIGN_OBJ:
					if (Z_OBJ_HT_P(object)->read_property) {
						z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
					}
					break;
				case ZEND_ASSIGN_DIM:
					if (Z_OBJ_HT_P(object)->read_dimension) {
						z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
					}
					break;
			}
			if (z) {
				if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
					zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

					if (z->refcount == 0) {
						zval_dtor(z);
						FREE_ZVAL(z);
					}
					z = value;
				}
				z->refcount++;
				SEPARATE_ZVAL_IF_NOT_REF(&z);
				binary_op(z, z, value TSRMLS_CC);
				switch (opline->extended_value) {
					case ZEND_ASSIGN_OBJ:
						Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
						break;
					case ZEND_ASSIGN_DIM:
						Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
						break;
				}
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = z;
					PZVAL_LOCK(*retval);
				}
				zval_ptr_dtor(&z);
			} else {
				zend_error(E_WARNING, "Attempt to assign property of non-object");
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = EG(uninitialized_zval_ptr);
					PZVAL_LOCK(*retval);
				}
			}
		}

		if (0) {
			zval_ptr_dtor(&property);
		} else {

		}
		FREE_OP(free_op_data1);
	}

	/* assign_obj has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int zend_binary_assign_op_helper_SPEC_UNUSED_UNUSED(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op_data2, free_op_data1;
	zval **var_ptr;
	zval *value;
	zend_bool increment_opline = 0;

	switch (opline->extended_value) {
		case ZEND_ASSIGN_OBJ:
			return zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
			break;
		case ZEND_ASSIGN_DIM: {
				zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);

				if (object_ptr && IS_UNUSED != IS_CV && !0) {
					(*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
				}

				if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
					return zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
				} else {
					zend_op *op_data = opline+1;
					zval *dim = NULL;

					zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), NULL, dim, 0, BP_VAR_RW TSRMLS_CC);
					value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
					var_ptr = get_zval_ptr_ptr(&op_data->op2, EX(Ts), &free_op_data2, BP_VAR_RW);
					increment_opline = 1;
				}
			}
			break;
		default:
			value = NULL;
			var_ptr = NULL;
			/* do nothing */
			break;
	}

	if (!var_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets");
	}

	if (*var_ptr == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}


		if (increment_opline) {
			ZEND_VM_INC_OPCODE();
		}
		ZEND_VM_NEXT_OPCODE();
	}

	SEPARATE_ZVAL_IF_NOT_REF(var_ptr);

	if(Z_TYPE_PP(var_ptr) == IS_OBJECT && Z_OBJ_HANDLER_PP(var_ptr, get)
	   && Z_OBJ_HANDLER_PP(var_ptr, set)) {
		/* proxy object */
		zval *objval = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
		objval->refcount++;
		binary_op(objval, objval, value TSRMLS_CC);
		Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, objval TSRMLS_CC);
		zval_ptr_dtor(&objval);
	} else {
		binary_op(*var_ptr, *var_ptr, value TSRMLS_CC);
	}

	if (!RETURN_VALUE_UNUSED(&opline->result)) {
		EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
		PZVAL_LOCK(*var_ptr);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
	}

	if (increment_opline) {
		ZEND_VM_INC_OPCODE();
		FREE_OP(free_op_data1);
		FREE_OP_VAR_PTR(free_op_data2);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_ADD_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_UNUSED(add_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SUB_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_UNUSED(sub_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_MUL_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_UNUSED(mul_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_DIV_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_UNUSED(div_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_MOD_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_UNUSED(mod_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SL_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_UNUSED(shift_left_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SR_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_UNUSED(shift_right_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_CONCAT_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_UNUSED(concat_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_OR_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_UNUSED(bitwise_or_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_AND_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_UNUSED(bitwise_and_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_XOR_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_UNUSED(bitwise_xor_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_INIT_ARRAY_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	array_init(&EX_T(opline->result.u.var).tmp_var);
	if (IS_UNUSED == IS_UNUSED) {
		ZEND_VM_NEXT_OPCODE();
#if 0 || IS_UNUSED != IS_UNUSED
	} else {
		return ZEND_ADD_ARRAY_ELEMENT_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
#endif
	}
}

static int zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;
	zend_free_op free_op_data1;
	zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
	zval *object;
	zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
	zval *value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
	znode *result = &opline->result;
	zval **retval = &EX_T(result->u.var).var.ptr;
	int have_get_ptr = 0;

	if (IS_UNUSED == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
	}

	EX_T(result->u.var).var.ptr_ptr = NULL;
	make_real_object(object_ptr TSRMLS_CC);
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to assign property of non-object");

		FREE_OP(free_op_data1);

		if (!RETURN_VALUE_UNUSED(result)) {
			*retval = EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*retval);
		}
	} else {
		/* here we are sure we are dealing with an object */
		if (0) {
			MAKE_REAL_ZVAL_PTR(property);
		}

		/* here property is a string */
		if (opline->extended_value == ZEND_ASSIGN_OBJ
			&& Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
			zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
			if (zptr != NULL) { 			/* NULL means no success in getting PTR */
				SEPARATE_ZVAL_IF_NOT_REF(zptr);

				have_get_ptr = 1;
				binary_op(*zptr, *zptr, value TSRMLS_CC);
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = *zptr;
					PZVAL_LOCK(*retval);
				}
			}
		}

		if (!have_get_ptr) {
			zval *z = NULL;

			switch (opline->extended_value) {
				case ZEND_ASSIGN_OBJ:
					if (Z_OBJ_HT_P(object)->read_property) {
						z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
					}
					break;
				case ZEND_ASSIGN_DIM:
					if (Z_OBJ_HT_P(object)->read_dimension) {
						z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
					}
					break;
			}
			if (z) {
				if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
					zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

					if (z->refcount == 0) {
						zval_dtor(z);
						FREE_ZVAL(z);
					}
					z = value;
				}
				z->refcount++;
				SEPARATE_ZVAL_IF_NOT_REF(&z);
				binary_op(z, z, value TSRMLS_CC);
				switch (opline->extended_value) {
					case ZEND_ASSIGN_OBJ:
						Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
						break;
					case ZEND_ASSIGN_DIM:
						Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
						break;
				}
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = z;
					PZVAL_LOCK(*retval);
				}
				zval_ptr_dtor(&z);
			} else {
				zend_error(E_WARNING, "Attempt to assign property of non-object");
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = EG(uninitialized_zval_ptr);
					PZVAL_LOCK(*retval);
				}
			}
		}

		if (0) {
			zval_ptr_dtor(&property);
		} else {

		}
		FREE_OP(free_op_data1);
	}

	/* assign_obj has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int zend_binary_assign_op_helper_SPEC_UNUSED_CV(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op_data2, free_op_data1;
	zval **var_ptr;
	zval *value;
	zend_bool increment_opline = 0;

	switch (opline->extended_value) {
		case ZEND_ASSIGN_OBJ:
			return zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
			break;
		case ZEND_ASSIGN_DIM: {
				zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);

				if (object_ptr && IS_UNUSED != IS_CV && !0) {
					(*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
				}

				if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
					return zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
				} else {
					zend_op *op_data = opline+1;
					zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

					zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), NULL, dim, 0, BP_VAR_RW TSRMLS_CC);
					value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
					var_ptr = get_zval_ptr_ptr(&op_data->op2, EX(Ts), &free_op_data2, BP_VAR_RW);
					increment_opline = 1;
				}
			}
			break;
		default:
			value = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
			var_ptr = NULL;
			/* do nothing */
			break;
	}

	if (!var_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets");
	}

	if (*var_ptr == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}


		if (increment_opline) {
			ZEND_VM_INC_OPCODE();
		}
		ZEND_VM_NEXT_OPCODE();
	}

	SEPARATE_ZVAL_IF_NOT_REF(var_ptr);

	if(Z_TYPE_PP(var_ptr) == IS_OBJECT && Z_OBJ_HANDLER_PP(var_ptr, get)
	   && Z_OBJ_HANDLER_PP(var_ptr, set)) {
		/* proxy object */
		zval *objval = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
		objval->refcount++;
		binary_op(objval, objval, value TSRMLS_CC);
		Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, objval TSRMLS_CC);
		zval_ptr_dtor(&objval);
	} else {
		binary_op(*var_ptr, *var_ptr, value TSRMLS_CC);
	}

	if (!RETURN_VALUE_UNUSED(&opline->result)) {
		EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
		PZVAL_LOCK(*var_ptr);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
	}

	if (increment_opline) {
		ZEND_VM_INC_OPCODE();
		FREE_OP(free_op_data1);
		FREE_OP_VAR_PTR(free_op_data2);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_ADD_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_CV(add_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SUB_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_CV(sub_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_MUL_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_CV(mul_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_DIV_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_CV(div_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_MOD_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_CV(mod_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SL_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_CV(shift_left_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SR_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_CV(shift_right_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_CONCAT_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_CV(concat_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_OR_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_CV(bitwise_or_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_AND_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_CV(bitwise_and_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_XOR_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_UNUSED_CV(bitwise_xor_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_pre_incdec_property_helper_SPEC_UNUSED_CV(incdec_t incdec_op, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
	zval *object;
	zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
	zval **retval = &EX_T(opline->result.u.var).var.ptr;
	int have_get_ptr = 0;

	if (IS_UNUSED == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}

	make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");

		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			*retval = EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*retval);
		}

		ZEND_VM_NEXT_OPCODE();
	}

	/* here we are sure we are dealing with an object */

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}

	if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
		zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
		if (zptr != NULL) { 			/* NULL means no success in getting PTR */
			SEPARATE_ZVAL_IF_NOT_REF(zptr);

			have_get_ptr = 1;
			incdec_op(*zptr);
			if (!RETURN_VALUE_UNUSED(&opline->result)) {
				*retval = *zptr;
				PZVAL_LOCK(*retval);
			}
		}
	}

	if (!have_get_ptr) {
		if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
			zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);

			if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
				zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

				if (z->refcount == 0) {
					zval_dtor(z);
					FREE_ZVAL(z);
				}
				z = value;
			}
			z->refcount++;
			SEPARATE_ZVAL_IF_NOT_REF(&z);
			incdec_op(z);
			*retval = z;
			Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
			SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
			zval_ptr_dtor(&z);
		} else {
			zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
			if (!RETURN_VALUE_UNUSED(&opline->result)) {
				*retval = EG(uninitialized_zval_ptr);
				PZVAL_LOCK(*retval);
			}
		}
	}

	if (0) {
		zval_ptr_dtor(&property);
	} else {

	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_PRE_INC_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_pre_incdec_property_helper_SPEC_UNUSED_CV(increment_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_PRE_DEC_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_pre_incdec_property_helper_SPEC_UNUSED_CV(decrement_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_post_incdec_property_helper_SPEC_UNUSED_CV(incdec_t incdec_op, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
	zval *object;
	zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
	zval *retval = &EX_T(opline->result.u.var).tmp_var;
	int have_get_ptr = 0;

	if (IS_UNUSED == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}

	make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");

		*retval = *EG(uninitialized_zval_ptr);

		ZEND_VM_NEXT_OPCODE();
	}

	/* here we are sure we are dealing with an object */

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}

	if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
		zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
		if (zptr != NULL) { 			/* NULL means no success in getting PTR */
			have_get_ptr = 1;
			SEPARATE_ZVAL_IF_NOT_REF(zptr);

			*retval = **zptr;
			zendi_zval_copy_ctor(*retval);

			incdec_op(*zptr);

		}
	}

	if (!have_get_ptr) {
		if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
			zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
			zval *z_copy;

			if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
				zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

				if (z->refcount == 0) {
					zval_dtor(z);
					FREE_ZVAL(z);
				}
				z = value;
			}
			*retval = *z;
			zendi_zval_copy_ctor(*retval);
			ALLOC_ZVAL(z_copy);
			*z_copy = *z;
			zendi_zval_copy_ctor(*z_copy);
			INIT_PZVAL(z_copy);
			incdec_op(z_copy);
			z->refcount++;
			Z_OBJ_HT_P(object)->write_property(object, property, z_copy TSRMLS_CC);
			zval_ptr_dtor(&z_copy);
			zval_ptr_dtor(&z);
		} else {
			zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
			*retval = *EG(uninitialized_zval_ptr);
		}
	}

	if (0) {
		zval_ptr_dtor(&property);
	} else {

	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_POST_INC_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_post_incdec_property_helper_SPEC_UNUSED_CV(increment_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_POST_DEC_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_post_incdec_property_helper_SPEC_UNUSED_CV(decrement_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_fetch_property_address_read_helper_SPEC_UNUSED_CV(int type, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *container;
	zval **retval;


	zval *offset  = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

	retval = &EX_T(opline->result.u.var).var.ptr;
	EX_T(opline->result.u.var).var.ptr_ptr = retval;

	container = _get_obj_zval_ptr_unused(TSRMLS_C);

	if (container == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			*retval = EG(error_zval_ptr);
			PZVAL_LOCK(*retval);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}


		ZEND_VM_NEXT_OPCODE();
	}


	if (Z_TYPE_P(container) != IS_OBJECT || !Z_OBJ_HT_P(container)->read_property) {
		if (type != BP_VAR_IS) {
			zend_error(E_NOTICE, "Trying to get property of non-object");
		}
		*retval = EG(uninitialized_zval_ptr);
		SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
		AI_USE_PTR(EX_T(opline->result.u.var).var);

	} else {
		if (0) {
			MAKE_REAL_ZVAL_PTR(offset);
		}

		/* here we are sure we are dealing with an object */
		*retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);

		if (RETURN_VALUE_UNUSED(&opline->result) && ((*retval)->refcount == 0)) {
			zval_dtor(*retval);
			FREE_ZVAL(*retval);
		} else {
			SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}

		if (0) {
			zval_ptr_dtor(&offset);
		} else {

		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_property_address_read_helper_SPEC_UNUSED_CV(BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

	if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_UNUSED != IS_CV) {
		PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
		EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr;
	}

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_obj_zval_ptr_ptr_unused(TSRMLS_C), property, BP_VAR_W TSRMLS_CC);
	if (0) {
		zval_ptr_dtor(&property);
	} else {

	}
	if (IS_UNUSED == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_obj_zval_ptr_ptr_unused(TSRMLS_C), property, BP_VAR_RW TSRMLS_CC);
	if (0) {
		zval_ptr_dtor(&property);
	} else {

	}
	if (IS_UNUSED == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_property_address_read_helper_SPEC_UNUSED_CV(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) {
		/* Behave like FETCH_OBJ_W */
		zend_free_op free_op1;
		zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

		if (0) {
			MAKE_REAL_ZVAL_PTR(property);
		}
		zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_obj_zval_ptr_ptr_unused(TSRMLS_C), property, BP_VAR_W TSRMLS_CC);
		if (0) {
			zval_ptr_dtor(&property);
		} else {

		}
		if (IS_UNUSED == IS_VAR && 0 &&
		    READY_TO_DESTROY(free_op1.var) &&
		    !RETURN_VALUE_UNUSED(&opline->result)) {
			AI_USE_PTR(EX_T(opline->result.u.var).var);
			if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
			    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
				SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
			}
		}

		ZEND_VM_NEXT_OPCODE();
	} else {
		return zend_fetch_property_address_read_helper_SPEC_UNUSED_CV(BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
	}
}

static int ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_res;
	zval **container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
	zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

	if (IS_UNUSED == IS_CV) {
		if (container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
	}
	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC);
	if (0) {
		zval_ptr_dtor(&property);
	} else {

	}
	if (IS_UNUSED == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &free_res);
	if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
		SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
	}
	PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
	FREE_OP_VAR_PTR(free_res);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;

	zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);

	zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);

	/* assign_obj has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *function_name;
	char *function_name_strval;
	int function_name_strlen;


	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), NULL);

	function_name = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

	if (Z_TYPE_P(function_name)!=IS_STRING) {
		zend_error_noreturn(E_ERROR, "Method name must be a string");
	}

	function_name_strval = Z_STRVAL_P(function_name);
	function_name_strlen = Z_STRLEN_P(function_name);

	EX(object) = _get_obj_zval_ptr_unused(TSRMLS_C);

	if (EX(object) && Z_TYPE_P(EX(object)) == IS_OBJECT) {
		if (Z_OBJ_HT_P(EX(object))->get_method == NULL) {
			zend_error_noreturn(E_ERROR, "Object does not support method calls");
		}

		/* First, locate the function. */
		EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen TSRMLS_CC);
		if (!EX(fbc)) {
			zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
		}
	} else {
		zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
	}

	if (!EX(object) || (EX(fbc) && (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
		EX(object) = NULL;
	} else {
		if (!PZVAL_IS_REF(EX(object))) {
			EX(object)->refcount++; /* For $this pointer */
		} else {
			zval *this_ptr;
			ALLOC_ZVAL(this_ptr);
			INIT_PZVAL_COPY(this_ptr, EX(object));
			zval_copy_ctor(this_ptr);
			EX(object) = this_ptr;
		}
	}


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_ARRAY_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	array_init(&EX_T(opline->result.u.var).tmp_var);
	if (IS_UNUSED == IS_UNUSED) {
		ZEND_VM_NEXT_OPCODE();
#if 0 || IS_UNUSED != IS_UNUSED
	} else {
		return ZEND_ADD_ARRAY_ELEMENT_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
#endif
	}
}

static int ZEND_UNSET_DIM_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval **container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
	zval *offset = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
	long index;

	if (container) {
		if (IS_UNUSED == IS_CV && container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
		switch (Z_TYPE_PP(container)) {
			case IS_ARRAY: {
				HashTable *ht = Z_ARRVAL_PP(container);

				switch (Z_TYPE_P(offset)) {
					case IS_DOUBLE:
						index = (long) Z_DVAL_P(offset);
						zend_hash_index_del(ht, index);
						break;
					case IS_RESOURCE:
					case IS_BOOL:
					case IS_LONG:
						index = Z_LVAL_P(offset);
						zend_hash_index_del(ht, index);
						break;
					case IS_STRING:
						if (IS_CV == IS_CV || IS_CV == IS_VAR) {
							offset->refcount++;
						}
						if (zend_symtable_del(ht, offset->value.str.val, offset->value.str.len+1) == SUCCESS &&
					    ht == &EG(symbol_table)) {
							zend_execute_data *ex;
							ulong hash_value = zend_inline_hash_func(offset->value.str.val, offset->value.str.len+1);

							for (ex = execute_data; ex; ex = ex->prev_execute_data) {
								if (ex->op_array && ex->symbol_table == ht) {
									int i;

									for (i = 0; i < ex->op_array->last_var; i++) {
										if (ex->op_array->vars[i].hash_value == hash_value &&
										    ex->op_array->vars[i].name_len == offset->value.str.len &&
										    !memcmp(ex->op_array->vars[i].name, offset->value.str.val, offset->value.str.len)) {
											ex->CVs[i] = NULL;
											break;
										}
									}
								}
							}
						}
						if (IS_CV == IS_CV || IS_CV == IS_VAR) {
							zval_ptr_dtor(&offset);
						}
						break;
					case IS_NULL:
						zend_hash_del(ht, "", sizeof(""));
						break;
					default:
						zend_error(E_WARNING, "Illegal offset type in unset");
						break;
				}

				break;
			}
			case IS_OBJECT:
				if (!Z_OBJ_HT_P(*container)->unset_dimension) {
					zend_error_noreturn(E_ERROR, "Cannot use object as array");
				}
				if (0) {
					MAKE_REAL_ZVAL_PTR(offset);
				}
				Z_OBJ_HT_P(*container)->unset_dimension(*container, offset TSRMLS_CC);
				if (0) {
					zval_ptr_dtor(&offset);
				} else {

				}
				break;
			case IS_STRING:
				zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
				ZEND_VM_CONTINUE(); /* bailed out before */
			default:

				break;
		}
	} else {

	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_UNSET_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval **container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
	zval *offset = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

	if (container) {
		if (IS_UNUSED == IS_CV && container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
		if (Z_TYPE_PP(container) == IS_OBJECT) {
			if (0) {
				MAKE_REAL_ZVAL_PTR(offset);
			}
			Z_OBJ_HT_P(*container)->unset_property(*container, offset TSRMLS_CC);
			if (0) {
				zval_ptr_dtor(&offset);
			} else {

			}
		} else {

		}
	} else {

	}

	ZEND_VM_NEXT_OPCODE();
}

static int zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CV(int prop_dim, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval **container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
	zval **value = NULL;
	int result = 0;
	long index;

	if (container) {

		zval *offset = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

		if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
			HashTable *ht;
			int isset = 0;

			ht = Z_ARRVAL_PP(container);

			switch (Z_TYPE_P(offset)) {
				case IS_DOUBLE:
					index = (long) Z_DVAL_P(offset);
					if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_RESOURCE:
				case IS_BOOL:
				case IS_LONG:
					index = Z_LVAL_P(offset);
					if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_STRING:
					if (zend_symtable_find(ht, offset->value.str.val, offset->value.str.len+1, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_NULL:
					if (zend_hash_find(ht, "", sizeof(""), (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				default:
					zend_error(E_WARNING, "Illegal offset type in isset or empty");

					break;
			}

			switch (opline->extended_value) {
				case ZEND_ISSET:
					if (isset && Z_TYPE_PP(value) == IS_NULL) {
						result = 0;
					} else {
						result = isset;
					}
					break;
				case ZEND_ISEMPTY:
					if (!isset || !i_zend_is_true(*value)) {
						result = 0;
					} else {
						result = 1;
					}
					break;
			}

		} else if (Z_TYPE_PP(container) == IS_OBJECT) {
			if (0) {
				MAKE_REAL_ZVAL_PTR(offset);
			}
			if (prop_dim) {
				result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value == ZEND_ISEMPTY) TSRMLS_CC);
			} else {
				result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value == ZEND_ISEMPTY) TSRMLS_CC);
			}
			if (0) {
				zval_ptr_dtor(&offset);
			} else {

			}
		} else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
			zval tmp;

			if (Z_TYPE_P(offset) != IS_LONG) {
				tmp = *offset;
				zval_copy_ctor(&tmp);
				convert_to_long(&tmp);
				offset = &tmp;
			}
			if (Z_TYPE_P(offset) == IS_LONG) {
				switch (opline->extended_value) {
					case ZEND_ISSET:
						if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
							result = 1;
						}
						break;
					case ZEND_ISEMPTY:
						if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
							result = 1;
						}
						break;
				}
			}

		} else {

		}
	}

	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;

	switch (opline->extended_value) {
		case ZEND_ISSET:
			Z_LVAL(EX_T(opline->result.u.var).tmp_var) = result;
			break;
		case ZEND_ISEMPTY:
			Z_LVAL(EX_T(opline->result.u.var).tmp_var) = !result;
			break;
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CV(0, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CV(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_BW_NOT_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	bitwise_not_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BOOL_NOT_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	boolean_not_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_PRE_INC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval **var_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC);

	if (!var_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}
	if (*var_ptr == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}

		ZEND_VM_NEXT_OPCODE();
	}

	SEPARATE_ZVAL_IF_NOT_REF(var_ptr);

	if(Z_TYPE_PP(var_ptr) == IS_OBJECT && Z_OBJ_HANDLER_PP(var_ptr, get)
	   && Z_OBJ_HANDLER_PP(var_ptr, set)) {
		/* proxy object */
		zval *val = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
		val->refcount++;
		increment_function(val);
		Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, val TSRMLS_CC);
		zval_ptr_dtor(&val);
	} else {
		increment_function(*var_ptr);
	}

	if (!RETURN_VALUE_UNUSED(&opline->result)) {
		EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
		PZVAL_LOCK(*var_ptr);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_PRE_DEC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval **var_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC);

	if (!var_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}
	if (*var_ptr == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}

		ZEND_VM_NEXT_OPCODE();
	}

	SEPARATE_ZVAL_IF_NOT_REF(var_ptr);

	if(Z_TYPE_PP(var_ptr) == IS_OBJECT && Z_OBJ_HANDLER_PP(var_ptr, get)
	   && Z_OBJ_HANDLER_PP(var_ptr, set)) {
		/* proxy object */
		zval *val = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
		val->refcount++;
		decrement_function(val);
		Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, val TSRMLS_CC);
		zval_ptr_dtor(&val);
	} else {
		decrement_function(*var_ptr);
	}

	if (!RETURN_VALUE_UNUSED(&opline->result)) {
		EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
		PZVAL_LOCK(*var_ptr);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_POST_INC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval **var_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC);

	if (!var_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}
	if (*var_ptr == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			EX_T(opline->result.u.var).tmp_var = *EG(uninitialized_zval_ptr);
		}

		ZEND_VM_NEXT_OPCODE();
	}

	EX_T(opline->result.u.var).tmp_var = **var_ptr;
	zendi_zval_copy_ctor(EX_T(opline->result.u.var).tmp_var);

	SEPARATE_ZVAL_IF_NOT_REF(var_ptr);

	if(Z_TYPE_PP(var_ptr) == IS_OBJECT && Z_OBJ_HANDLER_PP(var_ptr, get)
	   && Z_OBJ_HANDLER_PP(var_ptr, set)) {
		/* proxy object */
		zval *val = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
		val->refcount++;
		increment_function(val);
		Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, val TSRMLS_CC);
		zval_ptr_dtor(&val);
	} else {
		increment_function(*var_ptr);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_POST_DEC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval **var_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC);

	if (!var_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}
	if (*var_ptr == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			EX_T(opline->result.u.var).tmp_var = *EG(uninitialized_zval_ptr);
		}

		ZEND_VM_NEXT_OPCODE();
	}

	EX_T(opline->result.u.var).tmp_var = **var_ptr;
	zendi_zval_copy_ctor(EX_T(opline->result.u.var).tmp_var);

	SEPARATE_ZVAL_IF_NOT_REF(var_ptr);

	if(Z_TYPE_PP(var_ptr) == IS_OBJECT && Z_OBJ_HANDLER_PP(var_ptr, get)
	   && Z_OBJ_HANDLER_PP(var_ptr, set)) {
		/* proxy object */
		zval *val = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
		val->refcount++;
		decrement_function(val);
		Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, val TSRMLS_CC);
		zval_ptr_dtor(&val);
	} else {
		decrement_function(*var_ptr);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ECHO_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval z_copy;
	zval *z = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);

	if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL &&
		zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
		zend_print_variable(&z_copy);
		zval_dtor(&z_copy);
	} else {
		zend_print_variable(z);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_PRINT_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 1;
	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_LONG;

	return ZEND_ECHO_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_fetch_var_address_helper_SPEC_CV(int type, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *varname = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
	zval **retval;
	zval tmp_varname;
	HashTable *target_symbol_table;

 	if (Z_TYPE_P(varname) != IS_STRING) {
		tmp_varname = *varname;
		zval_copy_ctor(&tmp_varname);
		convert_to_string(&tmp_varname);
		varname = &tmp_varname;
	}

	if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
		retval = zend_std_get_static_property(EX_T(opline->op2.u.var).class_entry, Z_STRVAL_P(varname), Z_STRLEN_P(varname), 0 TSRMLS_CC);

	} else {
		target_symbol_table = zend_get_target_symbol_table(opline, EX(Ts), type, varname TSRMLS_CC);
/*
		if (!target_symbol_table) {
			ZEND_VM_NEXT_OPCODE();
		}
*/
		if (zend_hash_find(target_symbol_table, varname->value.str.val, varname->value.str.len+1, (void **) &retval) == FAILURE) {
			switch (type) {
				case BP_VAR_R:
				case BP_VAR_UNSET:
					zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
					/* break missing intentionally */
				case BP_VAR_IS:
					retval = &EG(uninitialized_zval_ptr);
					break;
				case BP_VAR_RW:
					zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
					/* break missing intentionally */
				case BP_VAR_W: {
						zval *new_zval = &EG(uninitialized_zval);

						new_zval->refcount++;
						zend_hash_update(target_symbol_table, varname->value.str.val, varname->value.str.len+1, &new_zval, sizeof(zval *), (void **) &retval);
					}
					break;
				EMPTY_SWITCH_DEFAULT_CASE()
			}
		}
		switch (opline->op2.u.EA.type) {
			case ZEND_FETCH_GLOBAL:
				if (IS_CV != IS_TMP_VAR) {

				}
				break;
			case ZEND_FETCH_LOCAL:

				break;
			case ZEND_FETCH_STATIC:
				zval_update_constant(retval, (void*) 1 TSRMLS_CC);
				break;
			case ZEND_FETCH_GLOBAL_LOCK:
				if (IS_CV == IS_VAR && !free_op1.var) {
					PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
				}
				break;
		}
	}


	if (varname == &tmp_varname) {
		zval_dtor(varname);
	}
	if (!RETURN_VALUE_UNUSED(&opline->result)) {
		EX_T(opline->result.u.var).var.ptr_ptr = retval;
		PZVAL_LOCK(*retval);
		switch (type) {
			case BP_VAR_R:
			case BP_VAR_IS:
				AI_USE_PTR(EX_T(opline->result.u.var).var);
				break;
			case BP_VAR_UNSET: {
				zend_free_op free_res;

				PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &free_res);
				if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
					SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
				}
				PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
				FREE_OP_VAR_PTR(free_res);
				break;
			}
		}
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_R_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_var_address_helper_SPEC_CV(BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_W_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_var_address_helper_SPEC_CV(BP_VAR_W, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_RW_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_var_address_helper_SPEC_CV(BP_VAR_RW, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_FUNC_ARG_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_var_address_helper_SPEC_CV(ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), EX(opline)->extended_value)?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_UNSET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_var_address_helper_SPEC_CV(BP_VAR_UNSET, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_IS_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_var_address_helper_SPEC_CV(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_JMPZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	int ret = i_zend_is_true(_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC));

	if (!ret) {
#if DEBUG_ZEND>=2
		printf("Conditional jmp to %d\n", opline->op2.u.opline_num);
#endif
		ZEND_VM_JMP(opline->op2.u.jmp_addr);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_JMPNZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	int ret = i_zend_is_true(_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC));

	if (ret) {
#if DEBUG_ZEND>=2
		printf("Conditional jmp to %d\n", opline->op2.u.opline_num);
#endif
		ZEND_VM_JMP(opline->op2.u.jmp_addr);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_JMPZNZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	int retval = i_zend_is_true(_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC));

	if (retval) {
#if DEBUG_ZEND>=2
		printf("Conditional jmp on true to %d\n", opline->extended_value);
#endif
		ZEND_VM_JMP(&EX(op_array)->opcodes[opline->extended_value]);
	} else {
#if DEBUG_ZEND>=2
		printf("Conditional jmp on false to %d\n", opline->op2.u.opline_num);
#endif
		ZEND_VM_JMP(&EX(op_array)->opcodes[opline->op2.u.opline_num]);
	}
}

static int ZEND_JMPZ_EX_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	int retval = i_zend_is_true(_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC));

	Z_LVAL(EX_T(opline->result.u.var).tmp_var) = retval;
	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
	if (!retval) {
#if DEBUG_ZEND>=2
		printf("Conditional jmp to %d\n", opline->op2.u.opline_num);
#endif
		ZEND_VM_JMP(opline->op2.u.jmp_addr);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_JMPNZ_EX_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	int retval = i_zend_is_true(_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC));

	Z_LVAL(EX_T(opline->result.u.var).tmp_var) = retval;
	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
	if (retval) {
#if DEBUG_ZEND>=2
		printf("Conditional jmp to %d\n", opline->op2.u.opline_num);
#endif
		ZEND_VM_JMP(opline->op2.u.jmp_addr);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_RETURN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *retval_ptr;
	zval **retval_ptr_ptr;


	if (EG(active_op_array)->return_reference == ZEND_RETURN_REF) {

		if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) {
			/* Not supposed to happen, but we'll allow it */
			zend_error(E_NOTICE, "Only variable references should be returned by reference");
			goto return_by_value;
		}

		retval_ptr_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);

		if (!retval_ptr_ptr) {
			zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
		}

		if (IS_CV == IS_VAR && !(*retval_ptr_ptr)->is_ref) {
			if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
			    EX_T(opline->op1.u.var).var.fcall_returned_reference) {
			} else if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
				if (IS_CV == IS_VAR && !0) {
					PZVAL_LOCK(*retval_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
				}
				zend_error(E_NOTICE, "Only variable references should be returned by reference");
				goto return_by_value;
			}
		}

		SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr_ptr);
		(*retval_ptr_ptr)->refcount++;

		(*EG(return_value_ptr_ptr)) = (*retval_ptr_ptr);
	} else {
return_by_value:

		retval_ptr = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);

		if (EG(ze1_compatibility_mode) && Z_TYPE_P(retval_ptr) == IS_OBJECT) {
			zval *ret;
			char *class_name;
			zend_uint class_name_len;
			int dup;

			ALLOC_ZVAL(ret);
			INIT_PZVAL_COPY(ret, retval_ptr);
			dup = zend_get_object_classname(retval_ptr, &class_name, &class_name_len TSRMLS_CC);
			if (Z_OBJ_HT_P(retval_ptr)->clone_obj == NULL) {
				zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s",  class_name);
			}
			zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name);
			ret->value.obj = Z_OBJ_HT_P(retval_ptr)->clone_obj(retval_ptr TSRMLS_CC);
			*EG(return_value_ptr_ptr) = ret;
			if (!dup) {
				efree(class_name);
			}
		} else if (!0) { /* Not a temp var */
			if (EG(active_op_array)->return_reference == ZEND_RETURN_REF ||
			    (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0)) {
				zval *ret;

				ALLOC_ZVAL(ret);
				INIT_PZVAL_COPY(ret, retval_ptr);
				zval_copy_ctor(ret);
				*EG(return_value_ptr_ptr) = ret;
			} else if ((IS_CV == IS_CV || IS_CV == IS_VAR) &&
			           retval_ptr == &EG(uninitialized_zval)) {
				zval *ret;

				ALLOC_INIT_ZVAL(ret);
				*EG(return_value_ptr_ptr) = ret;
			} else {
				*EG(return_value_ptr_ptr) = retval_ptr;
				retval_ptr->refcount++;
			}
		} else {
			zval *ret;

			ALLOC_ZVAL(ret);
			INIT_PZVAL_COPY(ret, retval_ptr);
			*EG(return_value_ptr_ptr) = ret;
		}
	}

	ZEND_VM_RETURN_FROM_EXECUTE_LOOP();
}

static int ZEND_THROW_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *value;
	zval *exception;


	value = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);

	if (Z_TYPE_P(value) != IS_OBJECT) {
		zend_error_noreturn(E_ERROR, "Can only throw objects");
	}
	/* Not sure if a complete copy is what we want here */
	ALLOC_ZVAL(exception);
	INIT_PZVAL_COPY(exception, value);
	if (!0) {
		zval_copy_ctor(exception);
	}

	zend_throw_exception_object(exception TSRMLS_CC);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SEND_VAL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	if (opline->extended_value==ZEND_DO_FCALL_BY_NAME
		&& ARG_MUST_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
			zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.u.opline_num);
	}
	{
		zval *valptr;
		zval *value;


		value = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);

		ALLOC_ZVAL(valptr);
		INIT_PZVAL_COPY(valptr, value);
		if (!0) {
			zval_copy_ctor(valptr);
		}
		zend_ptr_stack_push(&EG(argument_stack), valptr);

	}
	ZEND_VM_NEXT_OPCODE();
}

static int zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *varptr;

	varptr = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);

	if (varptr == &EG(uninitialized_zval)) {
		ALLOC_ZVAL(varptr);
		INIT_ZVAL(*varptr);
		varptr->refcount = 0;
	} else if (PZVAL_IS_REF(varptr)) {
		zval *original_var = varptr;

		ALLOC_ZVAL(varptr);
		*varptr = *original_var;
		varptr->is_ref = 0;
		varptr->refcount = 0;
		zval_copy_ctor(varptr);
	}
	varptr->refcount++;
	zend_ptr_stack_push(&EG(argument_stack), varptr);
	;  /* for string offsets */

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *varptr;

	if (opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) { /* Had function_ptr at compile_time */
		if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF)) {
			return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
		}
	} else if (!ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
		return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
	}

	if (IS_CV == IS_VAR &&
		(opline->extended_value & ZEND_ARG_SEND_FUNCTION) &&
		EX_T(opline->op1.u.var).var.fcall_returned_reference &&
		EX_T(opline->op1.u.var).var.ptr) {
		varptr = EX_T(opline->op1.u.var).var.ptr;
		PZVAL_UNLOCK_EX(varptr, &free_op1, 0);
	} else {
		varptr = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
	}
	if ((!(opline->extended_value & ZEND_ARG_SEND_FUNCTION) ||
	     EX_T(opline->op1.u.var).var.fcall_returned_reference) &&
	    varptr != &EG(uninitialized_zval) &&
	    (PZVAL_IS_REF(varptr) ||
	     (varptr->refcount == 1 && (IS_CV == IS_CV || free_op1.var)))) {
		varptr->is_ref = 1;
		varptr->refcount++;
		zend_ptr_stack_push(&EG(argument_stack), varptr);
	} else {
		zval *valptr;

		if (!(opline->extended_value & ZEND_ARG_SEND_SILENT)) {
			zend_error(E_STRICT, "Only variables should be passed by reference");
		}
		ALLOC_ZVAL(valptr);
		INIT_PZVAL_COPY(valptr, varptr);
		if (!0) {
			zval_copy_ctor(valptr);
		}
		zend_ptr_stack_push(&EG(argument_stack), valptr);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval **varptr_ptr;
	zval *varptr;
	varptr_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);

	if (!varptr_ptr) {
		zend_error_noreturn(E_ERROR, "Only variables can be passed by reference");
	}

	if (IS_CV == IS_VAR && *varptr_ptr == EG(error_zval_ptr)) {
		(*varptr_ptr)->refcount--;
		ALLOC_ZVAL(*varptr_ptr);
		INIT_ZVAL(**varptr_ptr);
		(*varptr_ptr)->refcount = 0;
	}

	if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION && !ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
		return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
	}

	SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr_ptr);
	varptr = *varptr_ptr;
	varptr->refcount++;
	zend_ptr_stack_push(&EG(argument_stack), varptr);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SEND_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	if ((opline->extended_value == ZEND_DO_FCALL_BY_NAME)
		&& ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
		return ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
	}
	return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_BOOL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	/* PHP 3.0 returned "" for false and 1 for true, here we use 0 and 1 for now */
	Z_LVAL(EX_T(opline->result.u.var).tmp_var) = i_zend_is_true(_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC));
	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval *obj = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
	zend_class_entry *ce;
	zend_function *clone;
	zend_object_clone_obj_t clone_call;

	if (!obj || Z_TYPE_P(obj) != IS_OBJECT) {
		zend_error_noreturn(E_ERROR, "__clone method called on non-object");
		EX_T(opline->result.u.var).var.ptr = EG(error_zval_ptr);
		EX_T(opline->result.u.var).var.ptr->refcount++;

		ZEND_VM_NEXT_OPCODE();
	}

	ce = Z_OBJCE_P(obj);
	clone = ce ? ce->clone : NULL;
	clone_call =  Z_OBJ_HT_P(obj)->clone_obj;
	if (!clone_call) {
		if (ce) {
			zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", ce->name);
		} else {
			zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object");
		}
		EX_T(opline->result.u.var).var.ptr = EG(error_zval_ptr);
		EX_T(opline->result.u.var).var.ptr->refcount++;
	}

	if (ce && clone) {
		if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) {
			/* Ensure that if we're calling a private function, we're allowed to do so.
			 */
			if (ce != EG(scope)) {
				zend_error_noreturn(E_ERROR, "Call to private %s::__clone() from context '%s'", ce->name, EG(scope) ? EG(scope)->name : "");
			}
		} else if ((clone->common.fn_flags & ZEND_ACC_PROTECTED)) {
			/* Ensure that if we're calling a protected function, we're allowed to do so.
			 */
			if (!zend_check_protected(clone->common.scope, EG(scope))) {
				zend_error_noreturn(E_ERROR, "Call to protected %s::__clone() from context '%s'", ce->name, EG(scope) ? EG(scope)->name : "");
			}
		}
	}

	EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
	if (!EG(exception)) {
		ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
		Z_OBJVAL_P(EX_T(opline->result.u.var).var.ptr) = clone_call(obj TSRMLS_CC);
		Z_TYPE_P(EX_T(opline->result.u.var).var.ptr) = IS_OBJECT;
		EX_T(opline->result.u.var).var.ptr->refcount=1;
		EX_T(opline->result.u.var).var.ptr->is_ref=1;
		if (!RETURN_VALUE_USED(opline) || EG(exception)) {
			zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CAST_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval *expr = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
	zval *result = &EX_T(opline->result.u.var).tmp_var;

	if (opline->extended_value != IS_STRING) {
		*result = *expr;
		if (!0) {
			zendi_zval_copy_ctor(*result);
		}
	}
	switch (opline->extended_value) {
		case IS_NULL:
			convert_to_null(result);
			break;
		case IS_BOOL:
			convert_to_boolean(result);
			break;
		case IS_LONG:
			convert_to_long(result);
			break;
		case IS_DOUBLE:
			convert_to_double(result);
			break;
		case IS_STRING: {
			zval var_copy;
			int use_copy;

			zend_make_printable_zval(expr, &var_copy, &use_copy);
			if (use_copy) {
				*result = var_copy;
				if (0) {

				}
			} else {
				*result = *expr;
				if (!0) {
					zendi_zval_copy_ctor(*result);
				}
			}
			break;
		}
		case IS_ARRAY:
			convert_to_array(result);
			break;
		case IS_OBJECT:
			convert_to_object(result);
			break;
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op_array *new_op_array=NULL;
	zval **original_return_value = EG(return_value_ptr_ptr);
	int return_value_used;

	zval *inc_filename = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
	zval tmp_inc_filename;
	zend_bool failure_retval=0;

	if (inc_filename->type!=IS_STRING) {
		tmp_inc_filename = *inc_filename;
		zval_copy_ctor(&tmp_inc_filename);
		convert_to_string(&tmp_inc_filename);
		inc_filename = &tmp_inc_filename;
	}

	return_value_used = RETURN_VALUE_USED(opline);

	switch (Z_LVAL(opline->op2.u.constant)) {
		case ZEND_INCLUDE_ONCE:
		case ZEND_REQUIRE_ONCE: {
				zend_file_handle file_handle;

				if (IS_ABSOLUTE_PATH(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename))) {
					cwd_state state;

					state.cwd_length = 0;
					state.cwd = malloc(1);
					state.cwd[0] = 0;

					failure_retval = (!virtual_file_ex(&state, Z_STRVAL_P(inc_filename), NULL, 1) &&
						zend_hash_exists(&EG(included_files), state.cwd, state.cwd_length+1));

					free(state.cwd);
				}

				if (failure_retval) {
					/* do nothing */
				} else if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) {

					if (!file_handle.opened_path) {
						file_handle.opened_path = estrndup(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename));
					}

					if (zend_hash_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1)==SUCCESS) {
						new_op_array = zend_compile_file(&file_handle, (Z_LVAL(opline->op2.u.constant)==ZEND_INCLUDE_ONCE?ZEND_INCLUDE:ZEND_REQUIRE) TSRMLS_CC);
						zend_destroy_file_handle(&file_handle TSRMLS_CC);
					} else {
						zend_file_handle_dtor(&file_handle);
						failure_retval=1;
					}
				} else {
					if (Z_LVAL(opline->op2.u.constant)==ZEND_INCLUDE_ONCE) {
						zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, Z_STRVAL_P(inc_filename));
					} else {
						zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename));
					}
				}
			}
			break;
		case ZEND_INCLUDE:
		case ZEND_REQUIRE:
			new_op_array = compile_filename(Z_LVAL(opline->op2.u.constant), inc_filename TSRMLS_CC);
			break;
		case ZEND_EVAL: {
				char *eval_desc = zend_make_compiled_string_description("eval()'d code" TSRMLS_CC);

				new_op_array = zend_compile_string(inc_filename, eval_desc TSRMLS_CC);
				efree(eval_desc);
			}
			break;
		EMPTY_SWITCH_DEFAULT_CASE()
	}
	if (inc_filename==&tmp_inc_filename) {
		zval_dtor(&tmp_inc_filename);
	}
	EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
	if (new_op_array) {
		zval *saved_object;
		zend_function *saved_function;

		EG(return_value_ptr_ptr) = EX_T(opline->result.u.var).var.ptr_ptr;
		EG(active_op_array) = new_op_array;
		EX_T(opline->result.u.var).var.ptr = NULL;

		saved_object = EX(object);
		saved_function = EX(function_state).function;

		EX(function_state).function = (zend_function *) new_op_array;
		EX(object) = NULL;

		zend_execute(new_op_array TSRMLS_CC);

		EX(function_state).function = saved_function;
		EX(object) = saved_object;

		if (!return_value_used) {
			if (EX_T(opline->result.u.var).var.ptr) {
				zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
			}
		} else { /* return value is used */
			if (!EX_T(opline->result.u.var).var.ptr) { /* there was no return statement */
				ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
				INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);
				Z_LVAL_P(EX_T(opline->result.u.var).var.ptr) = 1;
				Z_TYPE_P(EX_T(opline->result.u.var).var.ptr) = IS_BOOL;
			}
		}

		EG(opline_ptr) = &EX(opline);
		EG(active_op_array) = EX(op_array);
		EG(function_state_ptr) = &EX(function_state);
		destroy_op_array(new_op_array TSRMLS_CC);
		efree(new_op_array);
		if (EG(exception)) {
			zend_throw_exception_internal(NULL TSRMLS_CC);
		}
	} else {
		if (return_value_used) {
			ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
			INIT_ZVAL(*EX_T(opline->result.u.var).var.ptr);
			Z_LVAL_P(EX_T(opline->result.u.var).var.ptr) = failure_retval;
			Z_TYPE_P(EX_T(opline->result.u.var).var.ptr) = IS_BOOL;
		}
	}

	EG(return_value_ptr_ptr) = original_return_value;
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_UNSET_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval tmp, *varname;
	HashTable *target_symbol_table;


	varname = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);

	if (Z_TYPE_P(varname) != IS_STRING) {
		tmp = *varname;
		zval_copy_ctor(&tmp);
		convert_to_string(&tmp);
		varname = &tmp;
	} else if (IS_CV == IS_CV || IS_CV == IS_VAR) {
		varname->refcount++;
	}

	if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
		zend_std_unset_static_property(EX_T(opline->op2.u.var).class_entry, Z_STRVAL_P(varname), Z_STRLEN_P(varname) TSRMLS_CC);
	} else {
		target_symbol_table = zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
		if (zend_hash_del(target_symbol_table, varname->value.str.val, varname->value.str.len+1) == SUCCESS) {
			zend_execute_data *ex = execute_data;
			ulong hash_value = zend_inline_hash_func(varname->value.str.val, varname->value.str.len+1);

			do {
				int i;

				if (ex->op_array) {
					for (i = 0; i < ex->op_array->last_var; i++) {
						if (ex->op_array->vars[i].hash_value == hash_value &&
							ex->op_array->vars[i].name_len == varname->value.str.len &&
							!memcmp(ex->op_array->vars[i].name, varname->value.str.val, varname->value.str.len)) {
							ex->CVs[i] = NULL;
							break;
						}
					}
				}
				ex = ex->prev_execute_data;
			} while (ex && ex->symbol_table == target_symbol_table);
		}
	}

	if (varname == &tmp) {
		zval_dtor(&tmp);
	} else if (IS_CV == IS_CV || IS_CV == IS_VAR) {
		zval_ptr_dtor(&varname);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval *array_ptr, **array_ptr_ptr;
	HashTable *fe_ht;
	zend_object_iterator *iter = NULL;
	zend_class_entry *ce = NULL;
	zend_bool is_empty = 0;

	if (opline->extended_value & ZEND_FE_RESET_VARIABLE) {
		array_ptr_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
		if (array_ptr_ptr == NULL || array_ptr_ptr == &EG(uninitialized_zval_ptr)) {
			ALLOC_INIT_ZVAL(array_ptr);
		} else if (Z_TYPE_PP(array_ptr_ptr) == IS_OBJECT) {
			if(Z_OBJ_HT_PP(array_ptr_ptr)->get_class_entry == NULL) {
				zend_error(E_WARNING, "foreach() can not iterate over objects without PHP class");
				ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.u.opline_num);
			}

			ce = Z_OBJCE_PP(array_ptr_ptr);
			if (!ce || ce->get_iterator == NULL) {
				SEPARATE_ZVAL_IF_NOT_REF(array_ptr_ptr);
				(*array_ptr_ptr)->refcount++;
			}
			array_ptr = *array_ptr_ptr;
		} else {
			if (Z_TYPE_PP(array_ptr_ptr) == IS_ARRAY) {
				SEPARATE_ZVAL_IF_NOT_REF(array_ptr_ptr);
				if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
					(*array_ptr_ptr)->is_ref = 1;
				}
			}
			array_ptr = *array_ptr_ptr;
			array_ptr->refcount++;
		}
	} else {
		array_ptr = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
		if (0) { /* IS_TMP_VAR */
			zval *tmp;

			ALLOC_ZVAL(tmp);
			INIT_PZVAL_COPY(tmp, array_ptr);
			array_ptr = tmp;
			if (Z_TYPE_P(array_ptr) == IS_OBJECT) {
				ce = Z_OBJCE_P(array_ptr);
				if (ce && ce->get_iterator) {
					array_ptr->refcount--;
				}
			}
		} else if (Z_TYPE_P(array_ptr) == IS_OBJECT) {
			ce = Z_OBJCE_P(array_ptr);
			if (!ce || !ce->get_iterator) {
				array_ptr->refcount++;
			}
		} else {
			if (IS_CV == IS_CONST ||
			    ((IS_CV == IS_CV || IS_CV == IS_VAR) &&
			    !array_ptr->is_ref &&
			    array_ptr->refcount > 1)) {
				zval *tmp;

				ALLOC_ZVAL(tmp);
				INIT_PZVAL_COPY(tmp, array_ptr);
				zval_copy_ctor(tmp);
				array_ptr = tmp;
			} else {
				array_ptr->refcount++;
			}
		}
	}

	if (ce && ce->get_iterator) {
		iter = ce->get_iterator(ce, array_ptr, opline->extended_value & ZEND_FE_RESET_REFERENCE TSRMLS_CC);

		if (iter && !EG(exception)) {
			array_ptr = zend_iterator_wrap(iter TSRMLS_CC);
		} else {
			if (opline->extended_value & ZEND_FE_RESET_VARIABLE) {

			} else {

			}
			if (!EG(exception)) {
				zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Object of type %s did not create an Iterator", ce->name);
			}
			zend_throw_exception_internal(NULL TSRMLS_CC);
			ZEND_VM_NEXT_OPCODE();
		}
	}

	PZVAL_LOCK(array_ptr);
	EX_T(opline->result.u.var).var.ptr = array_ptr;
	EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;

	if (iter) {
		iter->index = 0;
		if (iter->funcs->rewind) {
			iter->funcs->rewind(iter TSRMLS_CC);
			if (EG(exception)) {
				array_ptr->refcount--;
				zval_ptr_dtor(&array_ptr);
				if (opline->extended_value & ZEND_FE_RESET_VARIABLE) {

				} else {

				}
				ZEND_VM_NEXT_OPCODE();
			}
		}
		is_empty = iter->funcs->valid(iter TSRMLS_CC) != SUCCESS;
		if (EG(exception)) {
			array_ptr->refcount--;
			zval_ptr_dtor(&array_ptr);
			if (opline->extended_value & ZEND_FE_RESET_VARIABLE) {

			} else {

			}
			ZEND_VM_NEXT_OPCODE();
		}
		iter->index = -1; /* will be set to 0 before using next handler */
	} else if ((fe_ht = HASH_OF(array_ptr)) != NULL) {
		zend_hash_internal_pointer_reset(fe_ht);
		if (ce) {
			zend_object *zobj = zend_objects_get_address(array_ptr TSRMLS_CC);
			while (zend_hash_has_more_elements(fe_ht) == SUCCESS) {
				char *str_key;
				uint str_key_len;
				ulong int_key;
				zend_uchar key_type;

				key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 0, NULL);
				if (key_type != HASH_KEY_NON_EXISTANT &&
					(key_type == HASH_KEY_IS_LONG ||
				     zend_check_property_access(zobj, str_key, str_key_len-1 TSRMLS_CC) == SUCCESS)) {
					break;
				}
				zend_hash_move_forward(fe_ht);
			}
		}
		is_empty = zend_hash_has_more_elements(fe_ht) != SUCCESS;
		zend_hash_get_pointer(fe_ht, &EX_T(opline->result.u.var).fe.fe_pos);
	} else {
		zend_error(E_WARNING, "Invalid argument supplied for foreach()");
		is_empty = 1;
	}

	if (opline->extended_value & ZEND_FE_RESET_VARIABLE) {

	} else {

	}
	if (is_empty) {
		ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.u.opline_num);
	} else {
		ZEND_VM_NEXT_OPCODE();
	}
}

static int ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval tmp, *varname = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_IS TSRMLS_CC);
	zval **value;
	zend_bool isset = 1;
	HashTable *target_symbol_table;

	if (Z_TYPE_P(varname) != IS_STRING) {
		tmp = *varname;
		zval_copy_ctor(&tmp);
		convert_to_string(&tmp);
		varname = &tmp;
	}

	if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
		value = zend_std_get_static_property(EX_T(opline->op2.u.var).class_entry, Z_STRVAL_P(varname), Z_STRLEN_P(varname), 1 TSRMLS_CC);
		if (!value) {
			isset = 0;
		}
	} else {
		target_symbol_table = zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
		if (zend_hash_find(target_symbol_table, varname->value.str.val, varname->value.str.len+1, (void **) &value) == FAILURE) {
			isset = 0;
		}
	}

	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;

	switch (opline->extended_value) {
		case ZEND_ISSET:
			if (isset && Z_TYPE_PP(value) == IS_NULL) {
				Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 0;
			} else {
				Z_LVAL(EX_T(opline->result.u.var).tmp_var) = isset;
			}
			break;
		case ZEND_ISEMPTY:
			if (!isset || !i_zend_is_true(*value)) {
				Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 1;
			} else {
				Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 0;
			}
			break;
	}

	if (varname == &tmp) {
		zval_dtor(&tmp);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_EXIT_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
#if 0 || (IS_CV != IS_UNUSED)
	zend_op *opline = EX(opline);
	if (IS_CV != IS_UNUSED) {

		zval *ptr = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);

		if (Z_TYPE_P(ptr) == IS_LONG) {
			EG(exit_status) = Z_LVAL_P(ptr);
		} else {
			zend_print_variable(ptr);
		}

	}
#endif
	zend_bailout();
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_QM_ASSIGN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval *value = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);

	EX_T(opline->result.u.var).tmp_var = *value;
	if (!0) {
		zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INSTANCEOF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval *expr = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
	zend_bool result;

	if (Z_TYPE_P(expr) == IS_OBJECT && Z_OBJ_HT_P(expr)->get_class_entry) {
		result = instanceof_function(Z_OBJCE_P(expr), EX_T(opline->op2.u.var).class_entry TSRMLS_CC);
	} else {
		result = 0;
	}
	ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, result);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ADD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	add_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SUB_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	sub_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_MUL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	mul_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_DIV_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	div_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_MOD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	mod_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	shift_left_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	shift_right_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CONCAT_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	concat_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_IDENTICAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	is_identical_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_NOT_IDENTICAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	is_not_identical_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_EQUAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	is_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	is_not_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_SMALLER_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	is_smaller_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	is_smaller_or_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_OR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	bitwise_or_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_AND_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	bitwise_and_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_XOR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	bitwise_xor_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BOOL_XOR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	boolean_xor_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		&opline->op2.u.constant TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;
	zend_free_op free_op_data1;
	zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
	zval *object;
	zval *property = &opline->op2.u.constant;
	zval *value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
	znode *result = &opline->result;
	zval **retval = &EX_T(result->u.var).var.ptr;
	int have_get_ptr = 0;

	if (IS_CV == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
	}

	EX_T(result->u.var).var.ptr_ptr = NULL;
	make_real_object(object_ptr TSRMLS_CC);
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to assign property of non-object");

		FREE_OP(free_op_data1);

		if (!RETURN_VALUE_UNUSED(result)) {
			*retval = EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*retval);
		}
	} else {
		/* here we are sure we are dealing with an object */
		if (0) {
			MAKE_REAL_ZVAL_PTR(property);
		}

		/* here property is a string */
		if (opline->extended_value == ZEND_ASSIGN_OBJ
			&& Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
			zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
			if (zptr != NULL) { 			/* NULL means no success in getting PTR */
				SEPARATE_ZVAL_IF_NOT_REF(zptr);

				have_get_ptr = 1;
				binary_op(*zptr, *zptr, value TSRMLS_CC);
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = *zptr;
					PZVAL_LOCK(*retval);
				}
			}
		}

		if (!have_get_ptr) {
			zval *z = NULL;

			switch (opline->extended_value) {
				case ZEND_ASSIGN_OBJ:
					if (Z_OBJ_HT_P(object)->read_property) {
						z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
					}
					break;
				case ZEND_ASSIGN_DIM:
					if (Z_OBJ_HT_P(object)->read_dimension) {
						z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
					}
					break;
			}
			if (z) {
				if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
					zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

					if (z->refcount == 0) {
						zval_dtor(z);
						FREE_ZVAL(z);
					}
					z = value;
				}
				z->refcount++;
				SEPARATE_ZVAL_IF_NOT_REF(&z);
				binary_op(z, z, value TSRMLS_CC);
				switch (opline->extended_value) {
					case ZEND_ASSIGN_OBJ:
						Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
						break;
					case ZEND_ASSIGN_DIM:
						Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
						break;
				}
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = z;
					PZVAL_LOCK(*retval);
				}
				zval_ptr_dtor(&z);
			} else {
				zend_error(E_WARNING, "Attempt to assign property of non-object");
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = EG(uninitialized_zval_ptr);
					PZVAL_LOCK(*retval);
				}
			}
		}

		if (0) {
			zval_ptr_dtor(&property);
		} else {

		}
		FREE_OP(free_op_data1);
	}

	/* assign_obj has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int zend_binary_assign_op_helper_SPEC_CV_CONST(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op_data2, free_op_data1;
	zval **var_ptr;
	zval *value;
	zend_bool increment_opline = 0;

	switch (opline->extended_value) {
		case ZEND_ASSIGN_OBJ:
			return zend_binary_assign_op_obj_helper_SPEC_CV_CONST(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
			break;
		case ZEND_ASSIGN_DIM: {
				zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);

				if (object_ptr && IS_CV != IS_CV && !0) {
					(*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
				}

				if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
					return zend_binary_assign_op_obj_helper_SPEC_CV_CONST(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
				} else {
					zend_op *op_data = opline+1;
					zval *dim = &opline->op2.u.constant;

					zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC);
					value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
					var_ptr = get_zval_ptr_ptr(&op_data->op2, EX(Ts), &free_op_data2, BP_VAR_RW);
					increment_opline = 1;
				}
			}
			break;
		default:
			value = &opline->op2.u.constant;
			var_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC);
			/* do nothing */
			break;
	}

	if (!var_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets");
	}

	if (*var_ptr == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}


		if (increment_opline) {
			ZEND_VM_INC_OPCODE();
		}
		ZEND_VM_NEXT_OPCODE();
	}

	SEPARATE_ZVAL_IF_NOT_REF(var_ptr);

	if(Z_TYPE_PP(var_ptr) == IS_OBJECT && Z_OBJ_HANDLER_PP(var_ptr, get)
	   && Z_OBJ_HANDLER_PP(var_ptr, set)) {
		/* proxy object */
		zval *objval = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
		objval->refcount++;
		binary_op(objval, objval, value TSRMLS_CC);
		Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, objval TSRMLS_CC);
		zval_ptr_dtor(&objval);
	} else {
		binary_op(*var_ptr, *var_ptr, value TSRMLS_CC);
	}

	if (!RETURN_VALUE_UNUSED(&opline->result)) {
		EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
		PZVAL_LOCK(*var_ptr);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
	}

	if (increment_opline) {
		ZEND_VM_INC_OPCODE();
		FREE_OP(free_op_data1);
		FREE_OP_VAR_PTR(free_op_data2);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_ADD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_CONST(add_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SUB_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_CONST(sub_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_MUL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_CONST(mul_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_DIV_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_CONST(div_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_MOD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_CONST(mod_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_CONST(shift_left_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_CONST(shift_right_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_CONCAT_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_CONST(concat_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_OR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_CONST(bitwise_or_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_AND_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_CONST(bitwise_and_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_XOR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_CONST(bitwise_xor_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_pre_incdec_property_helper_SPEC_CV_CONST(incdec_t incdec_op, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
	zval *object;
	zval *property = &opline->op2.u.constant;
	zval **retval = &EX_T(opline->result.u.var).var.ptr;
	int have_get_ptr = 0;

	if (IS_CV == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}

	make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");

		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			*retval = EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*retval);
		}

		ZEND_VM_NEXT_OPCODE();
	}

	/* here we are sure we are dealing with an object */

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}

	if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
		zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
		if (zptr != NULL) { 			/* NULL means no success in getting PTR */
			SEPARATE_ZVAL_IF_NOT_REF(zptr);

			have_get_ptr = 1;
			incdec_op(*zptr);
			if (!RETURN_VALUE_UNUSED(&opline->result)) {
				*retval = *zptr;
				PZVAL_LOCK(*retval);
			}
		}
	}

	if (!have_get_ptr) {
		if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
			zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);

			if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
				zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

				if (z->refcount == 0) {
					zval_dtor(z);
					FREE_ZVAL(z);
				}
				z = value;
			}
			z->refcount++;
			SEPARATE_ZVAL_IF_NOT_REF(&z);
			incdec_op(z);
			*retval = z;
			Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
			SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
			zval_ptr_dtor(&z);
		} else {
			zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
			if (!RETURN_VALUE_UNUSED(&opline->result)) {
				*retval = EG(uninitialized_zval_ptr);
				PZVAL_LOCK(*retval);
			}
		}
	}

	if (0) {
		zval_ptr_dtor(&property);
	} else {

	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_PRE_INC_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_pre_incdec_property_helper_SPEC_CV_CONST(increment_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_PRE_DEC_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_pre_incdec_property_helper_SPEC_CV_CONST(decrement_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_post_incdec_property_helper_SPEC_CV_CONST(incdec_t incdec_op, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
	zval *object;
	zval *property = &opline->op2.u.constant;
	zval *retval = &EX_T(opline->result.u.var).tmp_var;
	int have_get_ptr = 0;

	if (IS_CV == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}

	make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");

		*retval = *EG(uninitialized_zval_ptr);

		ZEND_VM_NEXT_OPCODE();
	}

	/* here we are sure we are dealing with an object */

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}

	if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
		zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
		if (zptr != NULL) { 			/* NULL means no success in getting PTR */
			have_get_ptr = 1;
			SEPARATE_ZVAL_IF_NOT_REF(zptr);

			*retval = **zptr;
			zendi_zval_copy_ctor(*retval);

			incdec_op(*zptr);

		}
	}

	if (!have_get_ptr) {
		if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
			zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
			zval *z_copy;

			if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
				zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

				if (z->refcount == 0) {
					zval_dtor(z);
					FREE_ZVAL(z);
				}
				z = value;
			}
			*retval = *z;
			zendi_zval_copy_ctor(*retval);
			ALLOC_ZVAL(z_copy);
			*z_copy = *z;
			zendi_zval_copy_ctor(*z_copy);
			INIT_PZVAL(z_copy);
			incdec_op(z_copy);
			z->refcount++;
			Z_OBJ_HT_P(object)->write_property(object, property, z_copy TSRMLS_CC);
			zval_ptr_dtor(&z_copy);
			zval_ptr_dtor(&z);
		} else {
			zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
			*retval = *EG(uninitialized_zval_ptr);
		}
	}

	if (0) {
		zval_ptr_dtor(&property);
	} else {

	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_POST_INC_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_post_incdec_property_helper_SPEC_CV_CONST(increment_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_POST_DEC_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_post_incdec_property_helper_SPEC_CV_CONST(decrement_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_DIM_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval *dim = &opline->op2.u.constant;

	if (opline->extended_value == ZEND_FETCH_ADD_LOCK &&
	    IS_CV != IS_CV &&
	    EX_T(opline->op1.u.var).var.ptr_ptr) {
		PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
	}
	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *dim = &opline->op2.u.constant;

	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), dim, 0, BP_VAR_W TSRMLS_CC);

	if (IS_CV == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *dim = &opline->op2.u.constant;

	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC);

	if (IS_CV == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_IS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval *dim = &opline->op2.u.constant;

	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_IS TSRMLS_CC), dim, 0, BP_VAR_IS TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
	zval *dim;

	if (IS_CONST == IS_UNUSED && type == BP_VAR_R) {
		zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
	}
	dim = &opline->op2.u.constant;
	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), type TSRMLS_CC), dim, 0, type TSRMLS_CC);

	if (IS_CV == IS_VAR && type == BP_VAR_W && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_UNSET TSRMLS_CC);
	zval *dim = &opline->op2.u.constant;

	/* Not needed in DIM_UNSET
	if (opline->extended_value == ZEND_FETCH_ADD_LOCK) {
		PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
	}
	*/
	if (IS_CV == IS_CV) {
		if (container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
	}
	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_UNSET TSRMLS_CC);

	if (IS_CV == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	if (EX_T(opline->result.u.var).var.ptr_ptr == NULL) {
		zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
	} else {
		zend_free_op free_res;

		PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &free_res);
		if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
		}
		PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
		FREE_OP_VAR_PTR(free_res);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int zend_fetch_property_address_read_helper_SPEC_CV_CONST(int type, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *container;
	zval **retval;


	zval *offset  = &opline->op2.u.constant;

	retval = &EX_T(opline->result.u.var).var.ptr;
	EX_T(opline->result.u.var).var.ptr_ptr = retval;

	container = _get_zval_ptr_cv(&opline->op1, EX(Ts), type TSRMLS_CC);

	if (container == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			*retval = EG(error_zval_ptr);
			PZVAL_LOCK(*retval);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}


		ZEND_VM_NEXT_OPCODE();
	}


	if (Z_TYPE_P(container) != IS_OBJECT || !Z_OBJ_HT_P(container)->read_property) {
		if (type != BP_VAR_IS) {
			zend_error(E_NOTICE, "Trying to get property of non-object");
		}
		*retval = EG(uninitialized_zval_ptr);
		SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
		AI_USE_PTR(EX_T(opline->result.u.var).var);

	} else {
		if (0) {
			MAKE_REAL_ZVAL_PTR(offset);
		}

		/* here we are sure we are dealing with an object */
		*retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);

		if (RETURN_VALUE_UNUSED(&opline->result) && ((*retval)->refcount == 0)) {
			zval_dtor(*retval);
			FREE_ZVAL(*retval);
		} else {
			SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}

		if (0) {
			zval_ptr_dtor(&offset);
		} else {

		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_property_address_read_helper_SPEC_CV_CONST(BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *property = &opline->op2.u.constant;

	if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_CV != IS_CV) {
		PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
		EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr;
	}

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), property, BP_VAR_W TSRMLS_CC);
	if (0) {
		zval_ptr_dtor(&property);
	} else {

	}
	if (IS_CV == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *property = &opline->op2.u.constant;

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), property, BP_VAR_RW TSRMLS_CC);
	if (0) {
		zval_ptr_dtor(&property);
	} else {

	}
	if (IS_CV == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_property_address_read_helper_SPEC_CV_CONST(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) {
		/* Behave like FETCH_OBJ_W */
		zend_free_op free_op1;
		zval *property = &opline->op2.u.constant;

		if (0) {
			MAKE_REAL_ZVAL_PTR(property);
		}
		zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), property, BP_VAR_W TSRMLS_CC);
		if (0) {
			zval_ptr_dtor(&property);
		} else {

		}
		if (IS_CV == IS_VAR && 0 &&
		    READY_TO_DESTROY(free_op1.var) &&
		    !RETURN_VALUE_UNUSED(&opline->result)) {
			AI_USE_PTR(EX_T(opline->result.u.var).var);
			if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
			    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
				SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
			}
		}

		ZEND_VM_NEXT_OPCODE();
	} else {
		return zend_fetch_property_address_read_helper_SPEC_CV_CONST(BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
	}
}

static int ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_res;
	zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
	zval *property = &opline->op2.u.constant;

	if (IS_CV == IS_CV) {
		if (container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
	}
	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC);
	if (0) {
		zval_ptr_dtor(&property);
	} else {

	}
	if (IS_CV == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &free_res);
	if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
		SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
	}
	PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
	FREE_OP_VAR_PTR(free_res);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;

	zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);

	zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);

	/* assign_obj has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;

	zval **object_ptr;

	if (IS_CV == IS_CV || EX_T(opline->op1.u.var).var.ptr_ptr) {
		/* not an array offset */
		object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
	} else {
		object_ptr = NULL;
	}

	if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
		zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC);
	} else {
		zend_free_op free_op_data1;
		zval *value;
		zval *dim = &opline->op2.u.constant;

		zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 0, BP_VAR_W TSRMLS_CC);

		value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
	 	zend_assign_to_variable(&opline->result, &op_data->op2, &op_data->op1, value, (IS_TMP_FREE(free_op_data1)?IS_TMP_VAR:op_data->op1.op_type), EX(Ts) TSRMLS_CC);
	 	FREE_OP_IF_VAR(free_op_data1);
	}

	/* assign_dim has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval *value = &opline->op2.u.constant;

 	zend_assign_to_variable(&opline->result, &opline->op1, &opline->op2, value, (0?IS_TMP_VAR:IS_CONST), EX(Ts) TSRMLS_CC);
	/* zend_assign_to_variable() always takes care of op2, never free it! */

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *function_name;
	char *function_name_strval;
	int function_name_strlen;


	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), NULL);

	function_name = &opline->op2.u.constant;

	if (Z_TYPE_P(function_name)!=IS_STRING) {
		zend_error_noreturn(E_ERROR, "Method name must be a string");
	}

	function_name_strval = Z_STRVAL_P(function_name);
	function_name_strlen = Z_STRLEN_P(function_name);

	EX(object) = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);

	if (EX(object) && Z_TYPE_P(EX(object)) == IS_OBJECT) {
		if (Z_OBJ_HT_P(EX(object))->get_method == NULL) {
			zend_error_noreturn(E_ERROR, "Object does not support method calls");
		}

		/* First, locate the function. */
		EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen TSRMLS_CC);
		if (!EX(fbc)) {
			zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
		}
	} else {
		zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
	}

	if (!EX(object) || (EX(fbc) && (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
		EX(object) = NULL;
	} else {
		if (!PZVAL_IS_REF(EX(object))) {
			EX(object)->refcount++; /* For $this pointer */
		} else {
			zval *this_ptr;
			ALLOC_ZVAL(this_ptr);
			INIT_PZVAL_COPY(this_ptr, EX(object));
			zval_copy_ctor(this_ptr);
			EX(object) = this_ptr;
		}
	}


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CASE_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	int switch_expr_is_overloaded=0;


	if (IS_CV==IS_VAR) {
		if (EX_T(opline->op1.u.var).var.ptr_ptr) {
			PZVAL_LOCK(EX_T(opline->op1.u.var).var.ptr);
		} else {
			switch_expr_is_overloaded = 1;
			EX_T(opline->op1.u.var).str_offset.str->refcount++;
		}
	}
	is_equal_function(&EX_T(opline->result.u.var).tmp_var,
				 _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
				 &opline->op2.u.constant TSRMLS_CC);

	if (switch_expr_is_overloaded) {
		/* We only free op1 if this is a string offset,
		 * Since if it is a TMP_VAR, it'll be reused by
		 * other CASE opcodes (whereas string offsets
		 * are allocated at each get_zval_ptr())
		 */

		EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
		AI_USE_PTR(EX_T(opline->op1.u.var).var);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval *array_ptr = &EX_T(opline->result.u.var).tmp_var;
	zval *expr_ptr;
	zval *offset=&opline->op2.u.constant;

#if 0 || IS_CV == IS_VAR || IS_CV == IS_CV
	zval **expr_ptr_ptr = NULL;

	if (opline->extended_value) {
		expr_ptr_ptr=_get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
		expr_ptr = *expr_ptr_ptr;
	} else {
		expr_ptr=_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
	}
#else
	expr_ptr=_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
#endif

	if (0) { /* temporary variable */
		zval *new_expr;

		ALLOC_ZVAL(new_expr);
		INIT_PZVAL_COPY(new_expr, expr_ptr);
		expr_ptr = new_expr;
	} else {
#if 0 || IS_CV == IS_VAR || IS_CV == IS_CV
		if (opline->extended_value) {
			SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr_ptr);
			expr_ptr = *expr_ptr_ptr;
			expr_ptr->refcount++;
		} else
#endif
		if (PZVAL_IS_REF(expr_ptr)) {
			zval *new_expr;

			ALLOC_ZVAL(new_expr);
			INIT_PZVAL_COPY(new_expr, expr_ptr);
			expr_ptr = new_expr;
			zendi_zval_copy_ctor(*expr_ptr);
		} else {
			expr_ptr->refcount++;
		}
	}
	if (offset) {
		switch (Z_TYPE_P(offset)) {
			case IS_DOUBLE:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_LONG:
			case IS_BOOL:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), Z_LVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_STRING:
				zend_symtable_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_NULL:
				zend_hash_update(Z_ARRVAL_P(array_ptr), "", sizeof(""), &expr_ptr, sizeof(zval *), NULL);
				break;
			default:
				zend_error(E_WARNING, "Illegal offset type");
				zval_ptr_dtor(&expr_ptr);
				/* do nothing */
				break;
		}

	} else {
		zend_hash_next_index_insert(Z_ARRVAL_P(array_ptr), &expr_ptr, sizeof(zval *), NULL);
	}
	if (opline->extended_value) {

	} else {

	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_ARRAY_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	array_init(&EX_T(opline->result.u.var).tmp_var);
	if (IS_CV == IS_UNUSED) {
		ZEND_VM_NEXT_OPCODE();
#if 0 || IS_CV != IS_UNUSED
	} else {
		return ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
#endif
	}
}

static int ZEND_UNSET_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_UNSET TSRMLS_CC);
	zval *offset = &opline->op2.u.constant;
	long index;

	if (container) {
		if (IS_CV == IS_CV && container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
		switch (Z_TYPE_PP(container)) {
			case IS_ARRAY: {
				HashTable *ht = Z_ARRVAL_PP(container);

				switch (Z_TYPE_P(offset)) {
					case IS_DOUBLE:
						index = (long) Z_DVAL_P(offset);
						zend_hash_index_del(ht, index);
						break;
					case IS_RESOURCE:
					case IS_BOOL:
					case IS_LONG:
						index = Z_LVAL_P(offset);
						zend_hash_index_del(ht, index);
						break;
					case IS_STRING:
						if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
							offset->refcount++;
						}
						if (zend_symtable_del(ht, offset->value.str.val, offset->value.str.len+1) == SUCCESS &&
					    ht == &EG(symbol_table)) {
							zend_execute_data *ex;
							ulong hash_value = zend_inline_hash_func(offset->value.str.val, offset->value.str.len+1);

							for (ex = execute_data; ex; ex = ex->prev_execute_data) {
								if (ex->op_array && ex->symbol_table == ht) {
									int i;

									for (i = 0; i < ex->op_array->last_var; i++) {
										if (ex->op_array->vars[i].hash_value == hash_value &&
										    ex->op_array->vars[i].name_len == offset->value.str.len &&
										    !memcmp(ex->op_array->vars[i].name, offset->value.str.val, offset->value.str.len)) {
											ex->CVs[i] = NULL;
											break;
										}
									}
								}
							}
						}
						if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
							zval_ptr_dtor(&offset);
						}
						break;
					case IS_NULL:
						zend_hash_del(ht, "", sizeof(""));
						break;
					default:
						zend_error(E_WARNING, "Illegal offset type in unset");
						break;
				}

				break;
			}
			case IS_OBJECT:
				if (!Z_OBJ_HT_P(*container)->unset_dimension) {
					zend_error_noreturn(E_ERROR, "Cannot use object as array");
				}
				if (0) {
					MAKE_REAL_ZVAL_PTR(offset);
				}
				Z_OBJ_HT_P(*container)->unset_dimension(*container, offset TSRMLS_CC);
				if (0) {
					zval_ptr_dtor(&offset);
				} else {

				}
				break;
			case IS_STRING:
				zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
				ZEND_VM_CONTINUE(); /* bailed out before */
			default:

				break;
		}
	} else {

	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_UNSET_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_UNSET TSRMLS_CC);
	zval *offset = &opline->op2.u.constant;

	if (container) {
		if (IS_CV == IS_CV && container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
		if (Z_TYPE_PP(container) == IS_OBJECT) {
			if (0) {
				MAKE_REAL_ZVAL_PTR(offset);
			}
			Z_OBJ_HT_P(*container)->unset_property(*container, offset TSRMLS_CC);
			if (0) {
				zval_ptr_dtor(&offset);
			} else {

			}
		} else {

		}
	} else {

	}

	ZEND_VM_NEXT_OPCODE();
}

static int zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CONST(int prop_dim, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_IS TSRMLS_CC);
	zval **value = NULL;
	int result = 0;
	long index;

	if (container) {

		zval *offset = &opline->op2.u.constant;

		if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
			HashTable *ht;
			int isset = 0;

			ht = Z_ARRVAL_PP(container);

			switch (Z_TYPE_P(offset)) {
				case IS_DOUBLE:
					index = (long) Z_DVAL_P(offset);
					if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_RESOURCE:
				case IS_BOOL:
				case IS_LONG:
					index = Z_LVAL_P(offset);
					if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_STRING:
					if (zend_symtable_find(ht, offset->value.str.val, offset->value.str.len+1, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_NULL:
					if (zend_hash_find(ht, "", sizeof(""), (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				default:
					zend_error(E_WARNING, "Illegal offset type in isset or empty");

					break;
			}

			switch (opline->extended_value) {
				case ZEND_ISSET:
					if (isset && Z_TYPE_PP(value) == IS_NULL) {
						result = 0;
					} else {
						result = isset;
					}
					break;
				case ZEND_ISEMPTY:
					if (!isset || !i_zend_is_true(*value)) {
						result = 0;
					} else {
						result = 1;
					}
					break;
			}

		} else if (Z_TYPE_PP(container) == IS_OBJECT) {
			if (0) {
				MAKE_REAL_ZVAL_PTR(offset);
			}
			if (prop_dim) {
				result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value == ZEND_ISEMPTY) TSRMLS_CC);
			} else {
				result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value == ZEND_ISEMPTY) TSRMLS_CC);
			}
			if (0) {
				zval_ptr_dtor(&offset);
			} else {

			}
		} else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
			zval tmp;

			if (Z_TYPE_P(offset) != IS_LONG) {
				tmp = *offset;
				zval_copy_ctor(&tmp);
				convert_to_long(&tmp);
				offset = &tmp;
			}
			if (Z_TYPE_P(offset) == IS_LONG) {
				switch (opline->extended_value) {
					case ZEND_ISSET:
						if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
							result = 1;
						}
						break;
					case ZEND_ISEMPTY:
						if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
							result = 1;
						}
						break;
				}
			}

		} else {

		}
	}

	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;

	switch (opline->extended_value) {
		case ZEND_ISSET:
			Z_LVAL(EX_T(opline->result.u.var).tmp_var) = result;
			break;
		case ZEND_ISEMPTY:
			Z_LVAL(EX_T(opline->result.u.var).tmp_var) = !result;
			break;
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CONST(0, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CONST(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ADD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	add_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SUB_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	sub_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_MUL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	mul_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_DIV_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	div_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_MOD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	mod_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	shift_left_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SR_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	shift_right_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CONCAT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	concat_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_IDENTICAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	is_identical_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_NOT_IDENTICAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	is_not_identical_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_EQUAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	is_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	is_not_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_SMALLER_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	is_smaller_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	is_smaller_or_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_OR_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	bitwise_or_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_AND_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	bitwise_and_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_XOR_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	bitwise_xor_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BOOL_XOR_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	boolean_xor_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	ZEND_VM_NEXT_OPCODE();
}

static int zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;
	zend_free_op free_op2, free_op_data1;
	zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
	zval *object;
	zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	zval *value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
	znode *result = &opline->result;
	zval **retval = &EX_T(result->u.var).var.ptr;
	int have_get_ptr = 0;

	if (IS_CV == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
	}

	EX_T(result->u.var).var.ptr_ptr = NULL;
	make_real_object(object_ptr TSRMLS_CC);
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to assign property of non-object");
		zval_dtor(free_op2.var);
		FREE_OP(free_op_data1);

		if (!RETURN_VALUE_UNUSED(result)) {
			*retval = EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*retval);
		}
	} else {
		/* here we are sure we are dealing with an object */
		if (1) {
			MAKE_REAL_ZVAL_PTR(property);
		}

		/* here property is a string */
		if (opline->extended_value == ZEND_ASSIGN_OBJ
			&& Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
			zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
			if (zptr != NULL) { 			/* NULL means no success in getting PTR */
				SEPARATE_ZVAL_IF_NOT_REF(zptr);

				have_get_ptr = 1;
				binary_op(*zptr, *zptr, value TSRMLS_CC);
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = *zptr;
					PZVAL_LOCK(*retval);
				}
			}
		}

		if (!have_get_ptr) {
			zval *z = NULL;

			switch (opline->extended_value) {
				case ZEND_ASSIGN_OBJ:
					if (Z_OBJ_HT_P(object)->read_property) {
						z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
					}
					break;
				case ZEND_ASSIGN_DIM:
					if (Z_OBJ_HT_P(object)->read_dimension) {
						z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
					}
					break;
			}
			if (z) {
				if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
					zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

					if (z->refcount == 0) {
						zval_dtor(z);
						FREE_ZVAL(z);
					}
					z = value;
				}
				z->refcount++;
				SEPARATE_ZVAL_IF_NOT_REF(&z);
				binary_op(z, z, value TSRMLS_CC);
				switch (opline->extended_value) {
					case ZEND_ASSIGN_OBJ:
						Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
						break;
					case ZEND_ASSIGN_DIM:
						Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
						break;
				}
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = z;
					PZVAL_LOCK(*retval);
				}
				zval_ptr_dtor(&z);
			} else {
				zend_error(E_WARNING, "Attempt to assign property of non-object");
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = EG(uninitialized_zval_ptr);
					PZVAL_LOCK(*retval);
				}
			}
		}

		if (1) {
			zval_ptr_dtor(&property);
		} else {
			zval_dtor(free_op2.var);
		}
		FREE_OP(free_op_data1);
	}

	/* assign_obj has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int zend_binary_assign_op_helper_SPEC_CV_TMP(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2, free_op_data2, free_op_data1;
	zval **var_ptr;
	zval *value;
	zend_bool increment_opline = 0;

	switch (opline->extended_value) {
		case ZEND_ASSIGN_OBJ:
			return zend_binary_assign_op_obj_helper_SPEC_CV_TMP(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
			break;
		case ZEND_ASSIGN_DIM: {
				zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);

				if (object_ptr && IS_CV != IS_CV && !0) {
					(*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
				}

				if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
					return zend_binary_assign_op_obj_helper_SPEC_CV_TMP(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
				} else {
					zend_op *op_data = opline+1;
					zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

					zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), dim, 1, BP_VAR_RW TSRMLS_CC);
					value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
					var_ptr = get_zval_ptr_ptr(&op_data->op2, EX(Ts), &free_op_data2, BP_VAR_RW);
					increment_opline = 1;
				}
			}
			break;
		default:
			value = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
			var_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC);
			/* do nothing */
			break;
	}

	if (!var_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets");
	}

	if (*var_ptr == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}
		zval_dtor(free_op2.var);

		if (increment_opline) {
			ZEND_VM_INC_OPCODE();
		}
		ZEND_VM_NEXT_OPCODE();
	}

	SEPARATE_ZVAL_IF_NOT_REF(var_ptr);

	if(Z_TYPE_PP(var_ptr) == IS_OBJECT && Z_OBJ_HANDLER_PP(var_ptr, get)
	   && Z_OBJ_HANDLER_PP(var_ptr, set)) {
		/* proxy object */
		zval *objval = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
		objval->refcount++;
		binary_op(objval, objval, value TSRMLS_CC);
		Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, objval TSRMLS_CC);
		zval_ptr_dtor(&objval);
	} else {
		binary_op(*var_ptr, *var_ptr, value TSRMLS_CC);
	}

	if (!RETURN_VALUE_UNUSED(&opline->result)) {
		EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
		PZVAL_LOCK(*var_ptr);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
	}
	zval_dtor(free_op2.var);

	if (increment_opline) {
		ZEND_VM_INC_OPCODE();
		FREE_OP(free_op_data1);
		FREE_OP_VAR_PTR(free_op_data2);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_ADD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_TMP(add_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SUB_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_TMP(sub_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_MUL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_TMP(mul_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_DIV_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_TMP(div_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_MOD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_TMP(mod_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_TMP(shift_left_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SR_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_TMP(shift_right_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_CONCAT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_TMP(concat_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_OR_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_TMP(bitwise_or_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_AND_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_TMP(bitwise_and_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_XOR_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_TMP(bitwise_xor_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_pre_incdec_property_helper_SPEC_CV_TMP(incdec_t incdec_op, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
	zval *object;
	zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	zval **retval = &EX_T(opline->result.u.var).var.ptr;
	int have_get_ptr = 0;

	if (IS_CV == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}

	make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
		zval_dtor(free_op2.var);
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			*retval = EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*retval);
		}

		ZEND_VM_NEXT_OPCODE();
	}

	/* here we are sure we are dealing with an object */

	if (1) {
		MAKE_REAL_ZVAL_PTR(property);
	}

	if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
		zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
		if (zptr != NULL) { 			/* NULL means no success in getting PTR */
			SEPARATE_ZVAL_IF_NOT_REF(zptr);

			have_get_ptr = 1;
			incdec_op(*zptr);
			if (!RETURN_VALUE_UNUSED(&opline->result)) {
				*retval = *zptr;
				PZVAL_LOCK(*retval);
			}
		}
	}

	if (!have_get_ptr) {
		if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
			zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);

			if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
				zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

				if (z->refcount == 0) {
					zval_dtor(z);
					FREE_ZVAL(z);
				}
				z = value;
			}
			z->refcount++;
			SEPARATE_ZVAL_IF_NOT_REF(&z);
			incdec_op(z);
			*retval = z;
			Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
			SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
			zval_ptr_dtor(&z);
		} else {
			zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
			if (!RETURN_VALUE_UNUSED(&opline->result)) {
				*retval = EG(uninitialized_zval_ptr);
				PZVAL_LOCK(*retval);
			}
		}
	}

	if (1) {
		zval_ptr_dtor(&property);
	} else {
		zval_dtor(free_op2.var);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_PRE_INC_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_pre_incdec_property_helper_SPEC_CV_TMP(increment_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_PRE_DEC_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_pre_incdec_property_helper_SPEC_CV_TMP(decrement_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_post_incdec_property_helper_SPEC_CV_TMP(incdec_t incdec_op, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
	zval *object;
	zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	zval *retval = &EX_T(opline->result.u.var).tmp_var;
	int have_get_ptr = 0;

	if (IS_CV == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}

	make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
		zval_dtor(free_op2.var);
		*retval = *EG(uninitialized_zval_ptr);

		ZEND_VM_NEXT_OPCODE();
	}

	/* here we are sure we are dealing with an object */

	if (1) {
		MAKE_REAL_ZVAL_PTR(property);
	}

	if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
		zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
		if (zptr != NULL) { 			/* NULL means no success in getting PTR */
			have_get_ptr = 1;
			SEPARATE_ZVAL_IF_NOT_REF(zptr);

			*retval = **zptr;
			zendi_zval_copy_ctor(*retval);

			incdec_op(*zptr);

		}
	}

	if (!have_get_ptr) {
		if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
			zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
			zval *z_copy;

			if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
				zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

				if (z->refcount == 0) {
					zval_dtor(z);
					FREE_ZVAL(z);
				}
				z = value;
			}
			*retval = *z;
			zendi_zval_copy_ctor(*retval);
			ALLOC_ZVAL(z_copy);
			*z_copy = *z;
			zendi_zval_copy_ctor(*z_copy);
			INIT_PZVAL(z_copy);
			incdec_op(z_copy);
			z->refcount++;
			Z_OBJ_HT_P(object)->write_property(object, property, z_copy TSRMLS_CC);
			zval_ptr_dtor(&z_copy);
			zval_ptr_dtor(&z);
		} else {
			zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
			*retval = *EG(uninitialized_zval_ptr);
		}
	}

	if (1) {
		zval_ptr_dtor(&property);
	} else {
		zval_dtor(free_op2.var);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_POST_INC_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_post_incdec_property_helper_SPEC_CV_TMP(increment_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_POST_DEC_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_post_incdec_property_helper_SPEC_CV_TMP(decrement_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_DIM_R_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (opline->extended_value == ZEND_FETCH_ADD_LOCK &&
	    IS_CV != IS_CV &&
	    EX_T(opline->op1.u.var).var.ptr_ptr) {
		PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
	}
	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), dim, 1, BP_VAR_R TSRMLS_CC);
	zval_dtor(free_op2.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), dim, 1, BP_VAR_W TSRMLS_CC);
	zval_dtor(free_op2.var);
	if (IS_CV == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_RW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), dim, 1, BP_VAR_RW TSRMLS_CC);
	zval_dtor(free_op2.var);
	if (IS_CV == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_IS_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_IS TSRMLS_CC), dim, 1, BP_VAR_IS TSRMLS_CC);
	zval_dtor(free_op2.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
	zval *dim;

	if (IS_TMP_VAR == IS_UNUSED && type == BP_VAR_R) {
		zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
	}
	dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), type TSRMLS_CC), dim, 1, type TSRMLS_CC);
	zval_dtor(free_op2.var);
	if (IS_CV == IS_VAR && type == BP_VAR_W && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_UNSET TSRMLS_CC);
	zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	/* Not needed in DIM_UNSET
	if (opline->extended_value == ZEND_FETCH_ADD_LOCK) {
		PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
	}
	*/
	if (IS_CV == IS_CV) {
		if (container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
	}
	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, dim, 1, BP_VAR_UNSET TSRMLS_CC);
	zval_dtor(free_op2.var);
	if (IS_CV == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	if (EX_T(opline->result.u.var).var.ptr_ptr == NULL) {
		zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
	} else {
		zend_free_op free_res;

		PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &free_res);
		if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
		}
		PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
		FREE_OP_VAR_PTR(free_res);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int zend_fetch_property_address_read_helper_SPEC_CV_TMP(int type, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *container;
	zval **retval;

	zend_free_op free_op2;
	zval *offset  = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	retval = &EX_T(opline->result.u.var).var.ptr;
	EX_T(opline->result.u.var).var.ptr_ptr = retval;

	container = _get_zval_ptr_cv(&opline->op1, EX(Ts), type TSRMLS_CC);

	if (container == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			*retval = EG(error_zval_ptr);
			PZVAL_LOCK(*retval);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}
		zval_dtor(free_op2.var);

		ZEND_VM_NEXT_OPCODE();
	}


	if (Z_TYPE_P(container) != IS_OBJECT || !Z_OBJ_HT_P(container)->read_property) {
		if (type != BP_VAR_IS) {
			zend_error(E_NOTICE, "Trying to get property of non-object");
		}
		*retval = EG(uninitialized_zval_ptr);
		SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		zval_dtor(free_op2.var);
	} else {
		if (1) {
			MAKE_REAL_ZVAL_PTR(offset);
		}

		/* here we are sure we are dealing with an object */
		*retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);

		if (RETURN_VALUE_UNUSED(&opline->result) && ((*retval)->refcount == 0)) {
			zval_dtor(*retval);
			FREE_ZVAL(*retval);
		} else {
			SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}

		if (1) {
			zval_ptr_dtor(&offset);
		} else {
			zval_dtor(free_op2.var);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_R_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_property_address_read_helper_SPEC_CV_TMP(BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_OBJ_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_CV != IS_CV) {
		PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
		EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr;
	}

	if (1) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), property, BP_VAR_W TSRMLS_CC);
	if (1) {
		zval_ptr_dtor(&property);
	} else {
		zval_dtor(free_op2.var);
	}
	if (IS_CV == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_RW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (1) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), property, BP_VAR_RW TSRMLS_CC);
	if (1) {
		zval_ptr_dtor(&property);
	} else {
		zval_dtor(free_op2.var);
	}
	if (IS_CV == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_IS_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_property_address_read_helper_SPEC_CV_TMP(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) {
		/* Behave like FETCH_OBJ_W */
		zend_free_op free_op1, free_op2;
		zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

		if (1) {
			MAKE_REAL_ZVAL_PTR(property);
		}
		zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), property, BP_VAR_W TSRMLS_CC);
		if (1) {
			zval_ptr_dtor(&property);
		} else {
			zval_dtor(free_op2.var);
		}
		if (IS_CV == IS_VAR && 0 &&
		    READY_TO_DESTROY(free_op1.var) &&
		    !RETURN_VALUE_UNUSED(&opline->result)) {
			AI_USE_PTR(EX_T(opline->result.u.var).var);
			if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
			    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
				SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
			}
		}

		ZEND_VM_NEXT_OPCODE();
	} else {
		return zend_fetch_property_address_read_helper_SPEC_CV_TMP(BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
	}
}

static int ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2, free_res;
	zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
	zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (IS_CV == IS_CV) {
		if (container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
	}
	if (1) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC);
	if (1) {
		zval_ptr_dtor(&property);
	} else {
		zval_dtor(free_op2.var);
	}
	if (IS_CV == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &free_res);
	if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
		SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
	}
	PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
	FREE_OP_VAR_PTR(free_res);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;

	zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);

	zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);

	/* assign_obj has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;

	zval **object_ptr;

	if (IS_CV == IS_CV || EX_T(opline->op1.u.var).var.ptr_ptr) {
		/* not an array offset */
		object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
	} else {
		object_ptr = NULL;
	}

	if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
		zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC);
	} else {
		zend_free_op free_op2, free_op_data1;
		zval *value;
		zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

		zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 1, BP_VAR_W TSRMLS_CC);
		zval_dtor(free_op2.var);

		value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
	 	zend_assign_to_variable(&opline->result, &op_data->op2, &op_data->op1, value, (IS_TMP_FREE(free_op_data1)?IS_TMP_VAR:op_data->op1.op_type), EX(Ts) TSRMLS_CC);
	 	FREE_OP_IF_VAR(free_op_data1);
	}

	/* assign_dim has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zval *value = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

 	zend_assign_to_variable(&opline->result, &opline->op1, &opline->op2, value, (1?IS_TMP_VAR:IS_TMP_VAR), EX(Ts) TSRMLS_CC);
	/* zend_assign_to_variable() always takes care of op2, never free it! */

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_METHOD_CALL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *function_name;
	char *function_name_strval;
	int function_name_strlen;
	zend_free_op free_op2;

	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), NULL);

	function_name = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (Z_TYPE_P(function_name)!=IS_STRING) {
		zend_error_noreturn(E_ERROR, "Method name must be a string");
	}

	function_name_strval = Z_STRVAL_P(function_name);
	function_name_strlen = Z_STRLEN_P(function_name);

	EX(object) = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);

	if (EX(object) && Z_TYPE_P(EX(object)) == IS_OBJECT) {
		if (Z_OBJ_HT_P(EX(object))->get_method == NULL) {
			zend_error_noreturn(E_ERROR, "Object does not support method calls");
		}

		/* First, locate the function. */
		EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen TSRMLS_CC);
		if (!EX(fbc)) {
			zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
		}
	} else {
		zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
	}

	if (!EX(object) || (EX(fbc) && (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
		EX(object) = NULL;
	} else {
		if (!PZVAL_IS_REF(EX(object))) {
			EX(object)->refcount++; /* For $this pointer */
		} else {
			zval *this_ptr;
			ALLOC_ZVAL(this_ptr);
			INIT_PZVAL_COPY(this_ptr, EX(object));
			zval_copy_ctor(this_ptr);
			EX(object) = this_ptr;
		}
	}

	zval_dtor(free_op2.var);

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CASE_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	int switch_expr_is_overloaded=0;
	zend_free_op free_op2;

	if (IS_CV==IS_VAR) {
		if (EX_T(opline->op1.u.var).var.ptr_ptr) {
			PZVAL_LOCK(EX_T(opline->op1.u.var).var.ptr);
		} else {
			switch_expr_is_overloaded = 1;
			EX_T(opline->op1.u.var).str_offset.str->refcount++;
		}
	}
	is_equal_function(&EX_T(opline->result.u.var).tmp_var,
				 _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
				 _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	zval_dtor(free_op2.var);
	if (switch_expr_is_overloaded) {
		/* We only free op1 if this is a string offset,
		 * Since if it is a TMP_VAR, it'll be reused by
		 * other CASE opcodes (whereas string offsets
		 * are allocated at each get_zval_ptr())
		 */

		EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
		AI_USE_PTR(EX_T(opline->op1.u.var).var);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zval *array_ptr = &EX_T(opline->result.u.var).tmp_var;
	zval *expr_ptr;
	zval *offset=_get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

#if 0 || IS_CV == IS_VAR || IS_CV == IS_CV
	zval **expr_ptr_ptr = NULL;

	if (opline->extended_value) {
		expr_ptr_ptr=_get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
		expr_ptr = *expr_ptr_ptr;
	} else {
		expr_ptr=_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
	}
#else
	expr_ptr=_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
#endif

	if (0) { /* temporary variable */
		zval *new_expr;

		ALLOC_ZVAL(new_expr);
		INIT_PZVAL_COPY(new_expr, expr_ptr);
		expr_ptr = new_expr;
	} else {
#if 0 || IS_CV == IS_VAR || IS_CV == IS_CV
		if (opline->extended_value) {
			SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr_ptr);
			expr_ptr = *expr_ptr_ptr;
			expr_ptr->refcount++;
		} else
#endif
		if (PZVAL_IS_REF(expr_ptr)) {
			zval *new_expr;

			ALLOC_ZVAL(new_expr);
			INIT_PZVAL_COPY(new_expr, expr_ptr);
			expr_ptr = new_expr;
			zendi_zval_copy_ctor(*expr_ptr);
		} else {
			expr_ptr->refcount++;
		}
	}
	if (offset) {
		switch (Z_TYPE_P(offset)) {
			case IS_DOUBLE:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_LONG:
			case IS_BOOL:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), Z_LVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_STRING:
				zend_symtable_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_NULL:
				zend_hash_update(Z_ARRVAL_P(array_ptr), "", sizeof(""), &expr_ptr, sizeof(zval *), NULL);
				break;
			default:
				zend_error(E_WARNING, "Illegal offset type");
				zval_ptr_dtor(&expr_ptr);
				/* do nothing */
				break;
		}
		zval_dtor(free_op2.var);
	} else {
		zend_hash_next_index_insert(Z_ARRVAL_P(array_ptr), &expr_ptr, sizeof(zval *), NULL);
	}
	if (opline->extended_value) {

	} else {

	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_ARRAY_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	array_init(&EX_T(opline->result.u.var).tmp_var);
	if (IS_CV == IS_UNUSED) {
		ZEND_VM_NEXT_OPCODE();
#if 0 || IS_CV != IS_UNUSED
	} else {
		return ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
#endif
	}
}

static int ZEND_UNSET_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_UNSET TSRMLS_CC);
	zval *offset = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	long index;

	if (container) {
		if (IS_CV == IS_CV && container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
		switch (Z_TYPE_PP(container)) {
			case IS_ARRAY: {
				HashTable *ht = Z_ARRVAL_PP(container);

				switch (Z_TYPE_P(offset)) {
					case IS_DOUBLE:
						index = (long) Z_DVAL_P(offset);
						zend_hash_index_del(ht, index);
						break;
					case IS_RESOURCE:
					case IS_BOOL:
					case IS_LONG:
						index = Z_LVAL_P(offset);
						zend_hash_index_del(ht, index);
						break;
					case IS_STRING:
						if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
							offset->refcount++;
						}
						if (zend_symtable_del(ht, offset->value.str.val, offset->value.str.len+1) == SUCCESS &&
					    ht == &EG(symbol_table)) {
							zend_execute_data *ex;
							ulong hash_value = zend_inline_hash_func(offset->value.str.val, offset->value.str.len+1);

							for (ex = execute_data; ex; ex = ex->prev_execute_data) {
								if (ex->op_array && ex->symbol_table == ht) {
									int i;

									for (i = 0; i < ex->op_array->last_var; i++) {
										if (ex->op_array->vars[i].hash_value == hash_value &&
										    ex->op_array->vars[i].name_len == offset->value.str.len &&
										    !memcmp(ex->op_array->vars[i].name, offset->value.str.val, offset->value.str.len)) {
											ex->CVs[i] = NULL;
											break;
										}
									}
								}
							}
						}
						if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
							zval_ptr_dtor(&offset);
						}
						break;
					case IS_NULL:
						zend_hash_del(ht, "", sizeof(""));
						break;
					default:
						zend_error(E_WARNING, "Illegal offset type in unset");
						break;
				}
				zval_dtor(free_op2.var);
				break;
			}
			case IS_OBJECT:
				if (!Z_OBJ_HT_P(*container)->unset_dimension) {
					zend_error_noreturn(E_ERROR, "Cannot use object as array");
				}
				if (1) {
					MAKE_REAL_ZVAL_PTR(offset);
				}
				Z_OBJ_HT_P(*container)->unset_dimension(*container, offset TSRMLS_CC);
				if (1) {
					zval_ptr_dtor(&offset);
				} else {
					zval_dtor(free_op2.var);
				}
				break;
			case IS_STRING:
				zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
				ZEND_VM_CONTINUE(); /* bailed out before */
			default:
				zval_dtor(free_op2.var);
				break;
		}
	} else {
		zval_dtor(free_op2.var);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_UNSET_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_UNSET TSRMLS_CC);
	zval *offset = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (container) {
		if (IS_CV == IS_CV && container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
		if (Z_TYPE_PP(container) == IS_OBJECT) {
			if (1) {
				MAKE_REAL_ZVAL_PTR(offset);
			}
			Z_OBJ_HT_P(*container)->unset_property(*container, offset TSRMLS_CC);
			if (1) {
				zval_ptr_dtor(&offset);
			} else {
				zval_dtor(free_op2.var);
			}
		} else {
			zval_dtor(free_op2.var);
		}
	} else {
		zval_dtor(free_op2.var);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_TMP(int prop_dim, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_IS TSRMLS_CC);
	zval **value = NULL;
	int result = 0;
	long index;

	if (container) {
		zend_free_op free_op2;
		zval *offset = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

		if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
			HashTable *ht;
			int isset = 0;

			ht = Z_ARRVAL_PP(container);

			switch (Z_TYPE_P(offset)) {
				case IS_DOUBLE:
					index = (long) Z_DVAL_P(offset);
					if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_RESOURCE:
				case IS_BOOL:
				case IS_LONG:
					index = Z_LVAL_P(offset);
					if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_STRING:
					if (zend_symtable_find(ht, offset->value.str.val, offset->value.str.len+1, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_NULL:
					if (zend_hash_find(ht, "", sizeof(""), (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				default:
					zend_error(E_WARNING, "Illegal offset type in isset or empty");

					break;
			}

			switch (opline->extended_value) {
				case ZEND_ISSET:
					if (isset && Z_TYPE_PP(value) == IS_NULL) {
						result = 0;
					} else {
						result = isset;
					}
					break;
				case ZEND_ISEMPTY:
					if (!isset || !i_zend_is_true(*value)) {
						result = 0;
					} else {
						result = 1;
					}
					break;
			}
			zval_dtor(free_op2.var);
		} else if (Z_TYPE_PP(container) == IS_OBJECT) {
			if (1) {
				MAKE_REAL_ZVAL_PTR(offset);
			}
			if (prop_dim) {
				result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value == ZEND_ISEMPTY) TSRMLS_CC);
			} else {
				result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value == ZEND_ISEMPTY) TSRMLS_CC);
			}
			if (1) {
				zval_ptr_dtor(&offset);
			} else {
				zval_dtor(free_op2.var);
			}
		} else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
			zval tmp;

			if (Z_TYPE_P(offset) != IS_LONG) {
				tmp = *offset;
				zval_copy_ctor(&tmp);
				convert_to_long(&tmp);
				offset = &tmp;
			}
			if (Z_TYPE_P(offset) == IS_LONG) {
				switch (opline->extended_value) {
					case ZEND_ISSET:
						if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
							result = 1;
						}
						break;
					case ZEND_ISEMPTY:
						if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
							result = 1;
						}
						break;
				}
			}
			zval_dtor(free_op2.var);
		} else {
			zval_dtor(free_op2.var);
		}
	}

	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;

	switch (opline->extended_value) {
		case ZEND_ISSET:
			Z_LVAL(EX_T(opline->result.u.var).tmp_var) = result;
			break;
		case ZEND_ISEMPTY:
			Z_LVAL(EX_T(opline->result.u.var).tmp_var) = !result;
			break;
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_TMP(0, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_TMP(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ADD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	add_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SUB_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	sub_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_MUL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	mul_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_DIV_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	div_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_MOD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	mod_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	shift_left_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	shift_right_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CONCAT_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	concat_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_IDENTICAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	is_identical_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	is_not_identical_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_EQUAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	is_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_NOT_EQUAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	is_not_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_SMALLER_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	is_smaller_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	is_smaller_or_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_OR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	bitwise_or_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_AND_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	bitwise_and_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_XOR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	bitwise_xor_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BOOL_XOR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;

	boolean_xor_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	ZEND_VM_NEXT_OPCODE();
}

static int zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;
	zend_free_op free_op2, free_op_data1;
	zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
	zval *object;
	zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	zval *value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
	znode *result = &opline->result;
	zval **retval = &EX_T(result->u.var).var.ptr;
	int have_get_ptr = 0;

	if (IS_CV == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
	}

	EX_T(result->u.var).var.ptr_ptr = NULL;
	make_real_object(object_ptr TSRMLS_CC);
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to assign property of non-object");
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
		FREE_OP(free_op_data1);

		if (!RETURN_VALUE_UNUSED(result)) {
			*retval = EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*retval);
		}
	} else {
		/* here we are sure we are dealing with an object */
		if (0) {
			MAKE_REAL_ZVAL_PTR(property);
		}

		/* here property is a string */
		if (opline->extended_value == ZEND_ASSIGN_OBJ
			&& Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
			zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
			if (zptr != NULL) { 			/* NULL means no success in getting PTR */
				SEPARATE_ZVAL_IF_NOT_REF(zptr);

				have_get_ptr = 1;
				binary_op(*zptr, *zptr, value TSRMLS_CC);
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = *zptr;
					PZVAL_LOCK(*retval);
				}
			}
		}

		if (!have_get_ptr) {
			zval *z = NULL;

			switch (opline->extended_value) {
				case ZEND_ASSIGN_OBJ:
					if (Z_OBJ_HT_P(object)->read_property) {
						z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
					}
					break;
				case ZEND_ASSIGN_DIM:
					if (Z_OBJ_HT_P(object)->read_dimension) {
						z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
					}
					break;
			}
			if (z) {
				if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
					zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

					if (z->refcount == 0) {
						zval_dtor(z);
						FREE_ZVAL(z);
					}
					z = value;
				}
				z->refcount++;
				SEPARATE_ZVAL_IF_NOT_REF(&z);
				binary_op(z, z, value TSRMLS_CC);
				switch (opline->extended_value) {
					case ZEND_ASSIGN_OBJ:
						Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
						break;
					case ZEND_ASSIGN_DIM:
						Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
						break;
				}
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = z;
					PZVAL_LOCK(*retval);
				}
				zval_ptr_dtor(&z);
			} else {
				zend_error(E_WARNING, "Attempt to assign property of non-object");
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = EG(uninitialized_zval_ptr);
					PZVAL_LOCK(*retval);
				}
			}
		}

		if (0) {
			zval_ptr_dtor(&property);
		} else {
			if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
		}
		FREE_OP(free_op_data1);
	}

	/* assign_obj has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int zend_binary_assign_op_helper_SPEC_CV_VAR(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2, free_op_data2, free_op_data1;
	zval **var_ptr;
	zval *value;
	zend_bool increment_opline = 0;

	switch (opline->extended_value) {
		case ZEND_ASSIGN_OBJ:
			return zend_binary_assign_op_obj_helper_SPEC_CV_VAR(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
			break;
		case ZEND_ASSIGN_DIM: {
				zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);

				if (object_ptr && IS_CV != IS_CV && !0) {
					(*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
				}

				if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
					return zend_binary_assign_op_obj_helper_SPEC_CV_VAR(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
				} else {
					zend_op *op_data = opline+1;
					zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

					zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC);
					value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
					var_ptr = get_zval_ptr_ptr(&op_data->op2, EX(Ts), &free_op_data2, BP_VAR_RW);
					increment_opline = 1;
				}
			}
			break;
		default:
			value = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
			var_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC);
			/* do nothing */
			break;
	}

	if (!var_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets");
	}

	if (*var_ptr == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};

		if (increment_opline) {
			ZEND_VM_INC_OPCODE();
		}
		ZEND_VM_NEXT_OPCODE();
	}

	SEPARATE_ZVAL_IF_NOT_REF(var_ptr);

	if(Z_TYPE_PP(var_ptr) == IS_OBJECT && Z_OBJ_HANDLER_PP(var_ptr, get)
	   && Z_OBJ_HANDLER_PP(var_ptr, set)) {
		/* proxy object */
		zval *objval = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
		objval->refcount++;
		binary_op(objval, objval, value TSRMLS_CC);
		Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, objval TSRMLS_CC);
		zval_ptr_dtor(&objval);
	} else {
		binary_op(*var_ptr, *var_ptr, value TSRMLS_CC);
	}

	if (!RETURN_VALUE_UNUSED(&opline->result)) {
		EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
		PZVAL_LOCK(*var_ptr);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
	}
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};

	if (increment_opline) {
		ZEND_VM_INC_OPCODE();
		FREE_OP(free_op_data1);
		FREE_OP_VAR_PTR(free_op_data2);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_ADD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_VAR(add_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SUB_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_VAR(sub_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_MUL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_VAR(mul_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_DIV_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_VAR(div_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_MOD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_VAR(mod_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_VAR(shift_left_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_VAR(shift_right_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_CONCAT_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_VAR(concat_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_OR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_VAR(bitwise_or_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_AND_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_VAR(bitwise_and_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_XOR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_VAR(bitwise_xor_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_pre_incdec_property_helper_SPEC_CV_VAR(incdec_t incdec_op, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
	zval *object;
	zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	zval **retval = &EX_T(opline->result.u.var).var.ptr;
	int have_get_ptr = 0;

	if (IS_CV == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}

	make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			*retval = EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*retval);
		}

		ZEND_VM_NEXT_OPCODE();
	}

	/* here we are sure we are dealing with an object */

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}

	if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
		zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
		if (zptr != NULL) { 			/* NULL means no success in getting PTR */
			SEPARATE_ZVAL_IF_NOT_REF(zptr);

			have_get_ptr = 1;
			incdec_op(*zptr);
			if (!RETURN_VALUE_UNUSED(&opline->result)) {
				*retval = *zptr;
				PZVAL_LOCK(*retval);
			}
		}
	}

	if (!have_get_ptr) {
		if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
			zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);

			if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
				zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

				if (z->refcount == 0) {
					zval_dtor(z);
					FREE_ZVAL(z);
				}
				z = value;
			}
			z->refcount++;
			SEPARATE_ZVAL_IF_NOT_REF(&z);
			incdec_op(z);
			*retval = z;
			Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
			SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
			zval_ptr_dtor(&z);
		} else {
			zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
			if (!RETURN_VALUE_UNUSED(&opline->result)) {
				*retval = EG(uninitialized_zval_ptr);
				PZVAL_LOCK(*retval);
			}
		}
	}

	if (0) {
		zval_ptr_dtor(&property);
	} else {
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_PRE_INC_OBJ_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_pre_incdec_property_helper_SPEC_CV_VAR(increment_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_PRE_DEC_OBJ_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_pre_incdec_property_helper_SPEC_CV_VAR(decrement_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_post_incdec_property_helper_SPEC_CV_VAR(incdec_t incdec_op, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
	zval *object;
	zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	zval *retval = &EX_T(opline->result.u.var).tmp_var;
	int have_get_ptr = 0;

	if (IS_CV == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}

	make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
		*retval = *EG(uninitialized_zval_ptr);

		ZEND_VM_NEXT_OPCODE();
	}

	/* here we are sure we are dealing with an object */

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}

	if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
		zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
		if (zptr != NULL) { 			/* NULL means no success in getting PTR */
			have_get_ptr = 1;
			SEPARATE_ZVAL_IF_NOT_REF(zptr);

			*retval = **zptr;
			zendi_zval_copy_ctor(*retval);

			incdec_op(*zptr);

		}
	}

	if (!have_get_ptr) {
		if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
			zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
			zval *z_copy;

			if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
				zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

				if (z->refcount == 0) {
					zval_dtor(z);
					FREE_ZVAL(z);
				}
				z = value;
			}
			*retval = *z;
			zendi_zval_copy_ctor(*retval);
			ALLOC_ZVAL(z_copy);
			*z_copy = *z;
			zendi_zval_copy_ctor(*z_copy);
			INIT_PZVAL(z_copy);
			incdec_op(z_copy);
			z->refcount++;
			Z_OBJ_HT_P(object)->write_property(object, property, z_copy TSRMLS_CC);
			zval_ptr_dtor(&z_copy);
			zval_ptr_dtor(&z);
		} else {
			zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
			*retval = *EG(uninitialized_zval_ptr);
		}
	}

	if (0) {
		zval_ptr_dtor(&property);
	} else {
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_POST_INC_OBJ_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_post_incdec_property_helper_SPEC_CV_VAR(increment_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_POST_DEC_OBJ_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_post_incdec_property_helper_SPEC_CV_VAR(decrement_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_DIM_R_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (opline->extended_value == ZEND_FETCH_ADD_LOCK &&
	    IS_CV != IS_CV &&
	    EX_T(opline->op1.u.var).var.ptr_ptr) {
		PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
	}
	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), dim, 0, BP_VAR_W TSRMLS_CC);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	if (IS_CV == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_RW_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	if (IS_CV == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_IS_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_IS TSRMLS_CC), dim, 0, BP_VAR_IS TSRMLS_CC);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
	zval *dim;

	if (IS_VAR == IS_UNUSED && type == BP_VAR_R) {
		zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
	}
	dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), type TSRMLS_CC), dim, 0, type TSRMLS_CC);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	if (IS_CV == IS_VAR && type == BP_VAR_W && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_UNSET TSRMLS_CC);
	zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	/* Not needed in DIM_UNSET
	if (opline->extended_value == ZEND_FETCH_ADD_LOCK) {
		PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
	}
	*/
	if (IS_CV == IS_CV) {
		if (container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
	}
	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_UNSET TSRMLS_CC);
	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	if (IS_CV == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	if (EX_T(opline->result.u.var).var.ptr_ptr == NULL) {
		zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
	} else {
		zend_free_op free_res;

		PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &free_res);
		if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
		}
		PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
		FREE_OP_VAR_PTR(free_res);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int zend_fetch_property_address_read_helper_SPEC_CV_VAR(int type, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *container;
	zval **retval;

	zend_free_op free_op2;
	zval *offset  = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	retval = &EX_T(opline->result.u.var).var.ptr;
	EX_T(opline->result.u.var).var.ptr_ptr = retval;

	container = _get_zval_ptr_cv(&opline->op1, EX(Ts), type TSRMLS_CC);

	if (container == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			*retval = EG(error_zval_ptr);
			PZVAL_LOCK(*retval);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};

		ZEND_VM_NEXT_OPCODE();
	}


	if (Z_TYPE_P(container) != IS_OBJECT || !Z_OBJ_HT_P(container)->read_property) {
		if (type != BP_VAR_IS) {
			zend_error(E_NOTICE, "Trying to get property of non-object");
		}
		*retval = EG(uninitialized_zval_ptr);
		SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	} else {
		if (0) {
			MAKE_REAL_ZVAL_PTR(offset);
		}

		/* here we are sure we are dealing with an object */
		*retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);

		if (RETURN_VALUE_UNUSED(&opline->result) && ((*retval)->refcount == 0)) {
			zval_dtor(*retval);
			FREE_ZVAL(*retval);
		} else {
			SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}

		if (0) {
			zval_ptr_dtor(&offset);
		} else {
			if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_R_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_property_address_read_helper_SPEC_CV_VAR(BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_OBJ_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_CV != IS_CV) {
		PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
		EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr;
	}

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), property, BP_VAR_W TSRMLS_CC);
	if (0) {
		zval_ptr_dtor(&property);
	} else {
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	}
	if (IS_CV == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_RW_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2;
	zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), property, BP_VAR_RW TSRMLS_CC);
	if (0) {
		zval_ptr_dtor(&property);
	} else {
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	}
	if (IS_CV == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_IS_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_property_address_read_helper_SPEC_CV_VAR(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) {
		/* Behave like FETCH_OBJ_W */
		zend_free_op free_op1, free_op2;
		zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

		if (0) {
			MAKE_REAL_ZVAL_PTR(property);
		}
		zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), property, BP_VAR_W TSRMLS_CC);
		if (0) {
			zval_ptr_dtor(&property);
		} else {
			if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
		}
		if (IS_CV == IS_VAR && 0 &&
		    READY_TO_DESTROY(free_op1.var) &&
		    !RETURN_VALUE_UNUSED(&opline->result)) {
			AI_USE_PTR(EX_T(opline->result.u.var).var);
			if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
			    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
				SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
			}
		}

		ZEND_VM_NEXT_OPCODE();
	} else {
		return zend_fetch_property_address_read_helper_SPEC_CV_VAR(BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
	}
}

static int ZEND_FETCH_OBJ_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_op2, free_res;
	zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
	zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (IS_CV == IS_CV) {
		if (container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
	}
	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC);
	if (0) {
		zval_ptr_dtor(&property);
	} else {
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	}
	if (IS_CV == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &free_res);
	if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
		SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
	}
	PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
	FREE_OP_VAR_PTR(free_res);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_OBJ_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;

	zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);

	zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);

	/* assign_obj has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;

	zval **object_ptr;

	if (IS_CV == IS_CV || EX_T(opline->op1.u.var).var.ptr_ptr) {
		/* not an array offset */
		object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
	} else {
		object_ptr = NULL;
	}

	if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
		zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC);
	} else {
		zend_free_op free_op2, free_op_data1;
		zval *value;
		zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

		zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 0, BP_VAR_W TSRMLS_CC);
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};

		value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
	 	zend_assign_to_variable(&opline->result, &op_data->op2, &op_data->op1, value, (IS_TMP_FREE(free_op_data1)?IS_TMP_VAR:op_data->op1.op_type), EX(Ts) TSRMLS_CC);
	 	FREE_OP_IF_VAR(free_op_data1);
	}

	/* assign_dim has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zval *value = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

 	zend_assign_to_variable(&opline->result, &opline->op1, &opline->op2, value, (0?IS_TMP_VAR:IS_VAR), EX(Ts) TSRMLS_CC);
	/* zend_assign_to_variable() always takes care of op2, never free it! */
 	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zval **variable_ptr_ptr;
	zval **value_ptr_ptr = _get_zval_ptr_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (IS_VAR == IS_VAR &&
	    value_ptr_ptr &&
	    !(*value_ptr_ptr)->is_ref &&
	    opline->extended_value == ZEND_RETURNS_FUNCTION &&
	    !EX_T(opline->op2.u.var).var.fcall_returned_reference) {
		if (free_op2.var == NULL) {
			PZVAL_LOCK(*value_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
		}
		zend_error(E_STRICT, "Only variables should be assigned by reference");
		if (EG(exception)) {
			if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
			ZEND_VM_NEXT_OPCODE();
		}
		return ZEND_ASSIGN_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
	} else if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
		PZVAL_LOCK(*value_ptr_ptr);
	}
	if (IS_CV == IS_VAR && EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
		zend_error(E_ERROR, "Cannot assign by reference to overloaded object");
	}

	variable_ptr_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
	zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);

	if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
		(*variable_ptr_ptr)->refcount--;
	}

	if (!RETURN_VALUE_UNUSED(&opline->result)) {
		EX_T(opline->result.u.var).var.ptr_ptr = variable_ptr_ptr;
		PZVAL_LOCK(*variable_ptr_ptr);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
	}

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_METHOD_CALL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *function_name;
	char *function_name_strval;
	int function_name_strlen;
	zend_free_op free_op2;

	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), NULL);

	function_name = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (Z_TYPE_P(function_name)!=IS_STRING) {
		zend_error_noreturn(E_ERROR, "Method name must be a string");
	}

	function_name_strval = Z_STRVAL_P(function_name);
	function_name_strlen = Z_STRLEN_P(function_name);

	EX(object) = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);

	if (EX(object) && Z_TYPE_P(EX(object)) == IS_OBJECT) {
		if (Z_OBJ_HT_P(EX(object))->get_method == NULL) {
			zend_error_noreturn(E_ERROR, "Object does not support method calls");
		}

		/* First, locate the function. */
		EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen TSRMLS_CC);
		if (!EX(fbc)) {
			zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
		}
	} else {
		zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
	}

	if (!EX(object) || (EX(fbc) && (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
		EX(object) = NULL;
	} else {
		if (!PZVAL_IS_REF(EX(object))) {
			EX(object)->refcount++; /* For $this pointer */
		} else {
			zval *this_ptr;
			ALLOC_ZVAL(this_ptr);
			INIT_PZVAL_COPY(this_ptr, EX(object));
			zval_copy_ctor(this_ptr);
			EX(object) = this_ptr;
		}
	}

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CASE_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	int switch_expr_is_overloaded=0;
	zend_free_op free_op2;

	if (IS_CV==IS_VAR) {
		if (EX_T(opline->op1.u.var).var.ptr_ptr) {
			PZVAL_LOCK(EX_T(opline->op1.u.var).var.ptr);
		} else {
			switch_expr_is_overloaded = 1;
			EX_T(opline->op1.u.var).str_offset.str->refcount++;
		}
	}
	is_equal_function(&EX_T(opline->result.u.var).tmp_var,
				 _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
				 _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC);

	if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	if (switch_expr_is_overloaded) {
		/* We only free op1 if this is a string offset,
		 * Since if it is a TMP_VAR, it'll be reused by
		 * other CASE opcodes (whereas string offsets
		 * are allocated at each get_zval_ptr())
		 */

		EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
		AI_USE_PTR(EX_T(opline->op1.u.var).var);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zval *array_ptr = &EX_T(opline->result.u.var).tmp_var;
	zval *expr_ptr;
	zval *offset=_get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

#if 0 || IS_CV == IS_VAR || IS_CV == IS_CV
	zval **expr_ptr_ptr = NULL;

	if (opline->extended_value) {
		expr_ptr_ptr=_get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
		expr_ptr = *expr_ptr_ptr;
	} else {
		expr_ptr=_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
	}
#else
	expr_ptr=_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
#endif

	if (0) { /* temporary variable */
		zval *new_expr;

		ALLOC_ZVAL(new_expr);
		INIT_PZVAL_COPY(new_expr, expr_ptr);
		expr_ptr = new_expr;
	} else {
#if 0 || IS_CV == IS_VAR || IS_CV == IS_CV
		if (opline->extended_value) {
			SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr_ptr);
			expr_ptr = *expr_ptr_ptr;
			expr_ptr->refcount++;
		} else
#endif
		if (PZVAL_IS_REF(expr_ptr)) {
			zval *new_expr;

			ALLOC_ZVAL(new_expr);
			INIT_PZVAL_COPY(new_expr, expr_ptr);
			expr_ptr = new_expr;
			zendi_zval_copy_ctor(*expr_ptr);
		} else {
			expr_ptr->refcount++;
		}
	}
	if (offset) {
		switch (Z_TYPE_P(offset)) {
			case IS_DOUBLE:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_LONG:
			case IS_BOOL:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), Z_LVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_STRING:
				zend_symtable_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_NULL:
				zend_hash_update(Z_ARRVAL_P(array_ptr), "", sizeof(""), &expr_ptr, sizeof(zval *), NULL);
				break;
			default:
				zend_error(E_WARNING, "Illegal offset type");
				zval_ptr_dtor(&expr_ptr);
				/* do nothing */
				break;
		}
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	} else {
		zend_hash_next_index_insert(Z_ARRVAL_P(array_ptr), &expr_ptr, sizeof(zval *), NULL);
	}
	if (opline->extended_value) {

	} else {

	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_ARRAY_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	array_init(&EX_T(opline->result.u.var).tmp_var);
	if (IS_CV == IS_UNUSED) {
		ZEND_VM_NEXT_OPCODE();
#if 0 || IS_CV != IS_UNUSED
	} else {
		return ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
#endif
	}
}

static int ZEND_UNSET_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_UNSET TSRMLS_CC);
	zval *offset = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
	long index;

	if (container) {
		if (IS_CV == IS_CV && container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
		switch (Z_TYPE_PP(container)) {
			case IS_ARRAY: {
				HashTable *ht = Z_ARRVAL_PP(container);

				switch (Z_TYPE_P(offset)) {
					case IS_DOUBLE:
						index = (long) Z_DVAL_P(offset);
						zend_hash_index_del(ht, index);
						break;
					case IS_RESOURCE:
					case IS_BOOL:
					case IS_LONG:
						index = Z_LVAL_P(offset);
						zend_hash_index_del(ht, index);
						break;
					case IS_STRING:
						if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
							offset->refcount++;
						}
						if (zend_symtable_del(ht, offset->value.str.val, offset->value.str.len+1) == SUCCESS &&
					    ht == &EG(symbol_table)) {
							zend_execute_data *ex;
							ulong hash_value = zend_inline_hash_func(offset->value.str.val, offset->value.str.len+1);

							for (ex = execute_data; ex; ex = ex->prev_execute_data) {
								if (ex->op_array && ex->symbol_table == ht) {
									int i;

									for (i = 0; i < ex->op_array->last_var; i++) {
										if (ex->op_array->vars[i].hash_value == hash_value &&
										    ex->op_array->vars[i].name_len == offset->value.str.len &&
										    !memcmp(ex->op_array->vars[i].name, offset->value.str.val, offset->value.str.len)) {
											ex->CVs[i] = NULL;
											break;
										}
									}
								}
							}
						}
						if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
							zval_ptr_dtor(&offset);
						}
						break;
					case IS_NULL:
						zend_hash_del(ht, "", sizeof(""));
						break;
					default:
						zend_error(E_WARNING, "Illegal offset type in unset");
						break;
				}
				if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
				break;
			}
			case IS_OBJECT:
				if (!Z_OBJ_HT_P(*container)->unset_dimension) {
					zend_error_noreturn(E_ERROR, "Cannot use object as array");
				}
				if (0) {
					MAKE_REAL_ZVAL_PTR(offset);
				}
				Z_OBJ_HT_P(*container)->unset_dimension(*container, offset TSRMLS_CC);
				if (0) {
					zval_ptr_dtor(&offset);
				} else {
					if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
				}
				break;
			case IS_STRING:
				zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
				ZEND_VM_CONTINUE(); /* bailed out before */
			default:
				if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
				break;
		}
	} else {
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_UNSET_OBJ_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_UNSET TSRMLS_CC);
	zval *offset = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

	if (container) {
		if (IS_CV == IS_CV && container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
		if (Z_TYPE_PP(container) == IS_OBJECT) {
			if (0) {
				MAKE_REAL_ZVAL_PTR(offset);
			}
			Z_OBJ_HT_P(*container)->unset_property(*container, offset TSRMLS_CC);
			if (0) {
				zval_ptr_dtor(&offset);
			} else {
				if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
			}
		} else {
			if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
		}
	} else {
		if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
	}

	ZEND_VM_NEXT_OPCODE();
}

static int zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_VAR(int prop_dim, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_IS TSRMLS_CC);
	zval **value = NULL;
	int result = 0;
	long index;

	if (container) {
		zend_free_op free_op2;
		zval *offset = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);

		if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
			HashTable *ht;
			int isset = 0;

			ht = Z_ARRVAL_PP(container);

			switch (Z_TYPE_P(offset)) {
				case IS_DOUBLE:
					index = (long) Z_DVAL_P(offset);
					if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_RESOURCE:
				case IS_BOOL:
				case IS_LONG:
					index = Z_LVAL_P(offset);
					if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_STRING:
					if (zend_symtable_find(ht, offset->value.str.val, offset->value.str.len+1, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_NULL:
					if (zend_hash_find(ht, "", sizeof(""), (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				default:
					zend_error(E_WARNING, "Illegal offset type in isset or empty");

					break;
			}

			switch (opline->extended_value) {
				case ZEND_ISSET:
					if (isset && Z_TYPE_PP(value) == IS_NULL) {
						result = 0;
					} else {
						result = isset;
					}
					break;
				case ZEND_ISEMPTY:
					if (!isset || !i_zend_is_true(*value)) {
						result = 0;
					} else {
						result = 1;
					}
					break;
			}
			if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
		} else if (Z_TYPE_PP(container) == IS_OBJECT) {
			if (0) {
				MAKE_REAL_ZVAL_PTR(offset);
			}
			if (prop_dim) {
				result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value == ZEND_ISEMPTY) TSRMLS_CC);
			} else {
				result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value == ZEND_ISEMPTY) TSRMLS_CC);
			}
			if (0) {
				zval_ptr_dtor(&offset);
			} else {
				if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
			}
		} else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
			zval tmp;

			if (Z_TYPE_P(offset) != IS_LONG) {
				tmp = *offset;
				zval_copy_ctor(&tmp);
				convert_to_long(&tmp);
				offset = &tmp;
			}
			if (Z_TYPE_P(offset) == IS_LONG) {
				switch (opline->extended_value) {
					case ZEND_ISSET:
						if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
							result = 1;
						}
						break;
					case ZEND_ISEMPTY:
						if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
							result = 1;
						}
						break;
				}
			}
			if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
		} else {
			if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
		}
	}

	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;

	switch (opline->extended_value) {
		case ZEND_ISSET:
			Z_LVAL(EX_T(opline->result.u.var).tmp_var) = result;
			break;
		case ZEND_ISEMPTY:
			Z_LVAL(EX_T(opline->result.u.var).tmp_var) = !result;
			break;
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_VAR(0, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_VAR(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;
	zend_free_op free_op_data1;
	zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
	zval *object;
	zval *property = NULL;
	zval *value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
	znode *result = &opline->result;
	zval **retval = &EX_T(result->u.var).var.ptr;
	int have_get_ptr = 0;

	if (IS_CV == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
	}

	EX_T(result->u.var).var.ptr_ptr = NULL;
	make_real_object(object_ptr TSRMLS_CC);
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to assign property of non-object");

		FREE_OP(free_op_data1);

		if (!RETURN_VALUE_UNUSED(result)) {
			*retval = EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*retval);
		}
	} else {
		/* here we are sure we are dealing with an object */
		if (0) {
			MAKE_REAL_ZVAL_PTR(property);
		}

		/* here property is a string */
		if (opline->extended_value == ZEND_ASSIGN_OBJ
			&& Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
			zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
			if (zptr != NULL) { 			/* NULL means no success in getting PTR */
				SEPARATE_ZVAL_IF_NOT_REF(zptr);

				have_get_ptr = 1;
				binary_op(*zptr, *zptr, value TSRMLS_CC);
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = *zptr;
					PZVAL_LOCK(*retval);
				}
			}
		}

		if (!have_get_ptr) {
			zval *z = NULL;

			switch (opline->extended_value) {
				case ZEND_ASSIGN_OBJ:
					if (Z_OBJ_HT_P(object)->read_property) {
						z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
					}
					break;
				case ZEND_ASSIGN_DIM:
					if (Z_OBJ_HT_P(object)->read_dimension) {
						z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
					}
					break;
			}
			if (z) {
				if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
					zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

					if (z->refcount == 0) {
						zval_dtor(z);
						FREE_ZVAL(z);
					}
					z = value;
				}
				z->refcount++;
				SEPARATE_ZVAL_IF_NOT_REF(&z);
				binary_op(z, z, value TSRMLS_CC);
				switch (opline->extended_value) {
					case ZEND_ASSIGN_OBJ:
						Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
						break;
					case ZEND_ASSIGN_DIM:
						Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
						break;
				}
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = z;
					PZVAL_LOCK(*retval);
				}
				zval_ptr_dtor(&z);
			} else {
				zend_error(E_WARNING, "Attempt to assign property of non-object");
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = EG(uninitialized_zval_ptr);
					PZVAL_LOCK(*retval);
				}
			}
		}

		if (0) {
			zval_ptr_dtor(&property);
		} else {

		}
		FREE_OP(free_op_data1);
	}

	/* assign_obj has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int zend_binary_assign_op_helper_SPEC_CV_UNUSED(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op_data2, free_op_data1;
	zval **var_ptr;
	zval *value;
	zend_bool increment_opline = 0;

	switch (opline->extended_value) {
		case ZEND_ASSIGN_OBJ:
			return zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
			break;
		case ZEND_ASSIGN_DIM: {
				zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);

				if (object_ptr && IS_CV != IS_CV && !0) {
					(*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
				}

				if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
					return zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
				} else {
					zend_op *op_data = opline+1;
					zval *dim = NULL;

					zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC);
					value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
					var_ptr = get_zval_ptr_ptr(&op_data->op2, EX(Ts), &free_op_data2, BP_VAR_RW);
					increment_opline = 1;
				}
			}
			break;
		default:
			value = NULL;
			var_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC);
			/* do nothing */
			break;
	}

	if (!var_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets");
	}

	if (*var_ptr == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}


		if (increment_opline) {
			ZEND_VM_INC_OPCODE();
		}
		ZEND_VM_NEXT_OPCODE();
	}

	SEPARATE_ZVAL_IF_NOT_REF(var_ptr);

	if(Z_TYPE_PP(var_ptr) == IS_OBJECT && Z_OBJ_HANDLER_PP(var_ptr, get)
	   && Z_OBJ_HANDLER_PP(var_ptr, set)) {
		/* proxy object */
		zval *objval = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
		objval->refcount++;
		binary_op(objval, objval, value TSRMLS_CC);
		Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, objval TSRMLS_CC);
		zval_ptr_dtor(&objval);
	} else {
		binary_op(*var_ptr, *var_ptr, value TSRMLS_CC);
	}

	if (!RETURN_VALUE_UNUSED(&opline->result)) {
		EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
		PZVAL_LOCK(*var_ptr);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
	}

	if (increment_opline) {
		ZEND_VM_INC_OPCODE();
		FREE_OP(free_op_data1);
		FREE_OP_VAR_PTR(free_op_data2);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_ADD_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_UNUSED(add_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SUB_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_UNUSED(sub_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_MUL_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_UNUSED(mul_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_DIV_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_UNUSED(div_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_MOD_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_UNUSED(mod_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SL_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_UNUSED(shift_left_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_UNUSED(shift_right_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_CONCAT_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_UNUSED(concat_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_OR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_UNUSED(bitwise_or_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_AND_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_UNUSED(bitwise_and_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_XOR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_UNUSED(bitwise_xor_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *dim = NULL;

	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), dim, 0, BP_VAR_W TSRMLS_CC);

	if (IS_CV == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *dim = NULL;

	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC);

	if (IS_CV == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
	zval *dim;

	if (IS_UNUSED == IS_UNUSED && type == BP_VAR_R) {
		zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
	}
	dim = NULL;
	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), type TSRMLS_CC), dim, 0, type TSRMLS_CC);

	if (IS_CV == IS_VAR && type == BP_VAR_W && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;

	zval **object_ptr;

	if (IS_CV == IS_CV || EX_T(opline->op1.u.var).var.ptr_ptr) {
		/* not an array offset */
		object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
	} else {
		object_ptr = NULL;
	}

	if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
		zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC);
	} else {
		zend_free_op free_op_data1;
		zval *value;
		zval *dim = NULL;

		zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 0, BP_VAR_W TSRMLS_CC);

		value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
	 	zend_assign_to_variable(&opline->result, &op_data->op2, &op_data->op1, value, (IS_TMP_FREE(free_op_data1)?IS_TMP_VAR:op_data->op1.op_type), EX(Ts) TSRMLS_CC);
	 	FREE_OP_IF_VAR(free_op_data1);
	}

	/* assign_dim has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval *array_ptr = &EX_T(opline->result.u.var).tmp_var;
	zval *expr_ptr;
	zval *offset=NULL;

#if 0 || IS_CV == IS_VAR || IS_CV == IS_CV
	zval **expr_ptr_ptr = NULL;

	if (opline->extended_value) {
		expr_ptr_ptr=_get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
		expr_ptr = *expr_ptr_ptr;
	} else {
		expr_ptr=_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
	}
#else
	expr_ptr=_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
#endif

	if (0) { /* temporary variable */
		zval *new_expr;

		ALLOC_ZVAL(new_expr);
		INIT_PZVAL_COPY(new_expr, expr_ptr);
		expr_ptr = new_expr;
	} else {
#if 0 || IS_CV == IS_VAR || IS_CV == IS_CV
		if (opline->extended_value) {
			SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr_ptr);
			expr_ptr = *expr_ptr_ptr;
			expr_ptr->refcount++;
		} else
#endif
		if (PZVAL_IS_REF(expr_ptr)) {
			zval *new_expr;

			ALLOC_ZVAL(new_expr);
			INIT_PZVAL_COPY(new_expr, expr_ptr);
			expr_ptr = new_expr;
			zendi_zval_copy_ctor(*expr_ptr);
		} else {
			expr_ptr->refcount++;
		}
	}
	if (offset) {
		switch (Z_TYPE_P(offset)) {
			case IS_DOUBLE:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_LONG:
			case IS_BOOL:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), Z_LVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_STRING:
				zend_symtable_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_NULL:
				zend_hash_update(Z_ARRVAL_P(array_ptr), "", sizeof(""), &expr_ptr, sizeof(zval *), NULL);
				break;
			default:
				zend_error(E_WARNING, "Illegal offset type");
				zval_ptr_dtor(&expr_ptr);
				/* do nothing */
				break;
		}

	} else {
		zend_hash_next_index_insert(Z_ARRVAL_P(array_ptr), &expr_ptr, sizeof(zval *), NULL);
	}
	if (opline->extended_value) {

	} else {

	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_ARRAY_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	array_init(&EX_T(opline->result.u.var).tmp_var);
	if (IS_CV == IS_UNUSED) {
		ZEND_VM_NEXT_OPCODE();
#if 0 || IS_CV != IS_UNUSED
	} else {
		return ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
#endif
	}
}

static int ZEND_ADD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	add_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SUB_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	sub_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_MUL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	mul_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_DIV_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	div_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_MOD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	mod_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	shift_left_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_SR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	shift_right_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CONCAT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	concat_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_IDENTICAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	is_identical_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_NOT_IDENTICAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	is_not_identical_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_EQUAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	is_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_NOT_EQUAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	is_not_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_SMALLER_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	is_smaller_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	is_smaller_or_equal_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_OR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	bitwise_or_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_AND_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	bitwise_and_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BW_XOR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	bitwise_xor_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_BOOL_XOR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);


	boolean_xor_function(&EX_T(opline->result.u.var).tmp_var,
		_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
		_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;
	zend_free_op free_op_data1;
	zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
	zval *object;
	zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
	zval *value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
	znode *result = &opline->result;
	zval **retval = &EX_T(result->u.var).var.ptr;
	int have_get_ptr = 0;

	if (IS_CV == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
	}

	EX_T(result->u.var).var.ptr_ptr = NULL;
	make_real_object(object_ptr TSRMLS_CC);
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to assign property of non-object");

		FREE_OP(free_op_data1);

		if (!RETURN_VALUE_UNUSED(result)) {
			*retval = EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*retval);
		}
	} else {
		/* here we are sure we are dealing with an object */
		if (0) {
			MAKE_REAL_ZVAL_PTR(property);
		}

		/* here property is a string */
		if (opline->extended_value == ZEND_ASSIGN_OBJ
			&& Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
			zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
			if (zptr != NULL) { 			/* NULL means no success in getting PTR */
				SEPARATE_ZVAL_IF_NOT_REF(zptr);

				have_get_ptr = 1;
				binary_op(*zptr, *zptr, value TSRMLS_CC);
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = *zptr;
					PZVAL_LOCK(*retval);
				}
			}
		}

		if (!have_get_ptr) {
			zval *z = NULL;

			switch (opline->extended_value) {
				case ZEND_ASSIGN_OBJ:
					if (Z_OBJ_HT_P(object)->read_property) {
						z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
					}
					break;
				case ZEND_ASSIGN_DIM:
					if (Z_OBJ_HT_P(object)->read_dimension) {
						z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
					}
					break;
			}
			if (z) {
				if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
					zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

					if (z->refcount == 0) {
						zval_dtor(z);
						FREE_ZVAL(z);
					}
					z = value;
				}
				z->refcount++;
				SEPARATE_ZVAL_IF_NOT_REF(&z);
				binary_op(z, z, value TSRMLS_CC);
				switch (opline->extended_value) {
					case ZEND_ASSIGN_OBJ:
						Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
						break;
					case ZEND_ASSIGN_DIM:
						Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
						break;
				}
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = z;
					PZVAL_LOCK(*retval);
				}
				zval_ptr_dtor(&z);
			} else {
				zend_error(E_WARNING, "Attempt to assign property of non-object");
				if (!RETURN_VALUE_UNUSED(result)) {
					*retval = EG(uninitialized_zval_ptr);
					PZVAL_LOCK(*retval);
				}
			}
		}

		if (0) {
			zval_ptr_dtor(&property);
		} else {

		}
		FREE_OP(free_op_data1);
	}

	/* assign_obj has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int zend_binary_assign_op_helper_SPEC_CV_CV(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op_data2, free_op_data1;
	zval **var_ptr;
	zval *value;
	zend_bool increment_opline = 0;

	switch (opline->extended_value) {
		case ZEND_ASSIGN_OBJ:
			return zend_binary_assign_op_obj_helper_SPEC_CV_CV(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
			break;
		case ZEND_ASSIGN_DIM: {
				zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);

				if (object_ptr && IS_CV != IS_CV && !0) {
					(*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
				}

				if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
					return zend_binary_assign_op_obj_helper_SPEC_CV_CV(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
				} else {
					zend_op *op_data = opline+1;
					zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

					zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC);
					value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
					var_ptr = get_zval_ptr_ptr(&op_data->op2, EX(Ts), &free_op_data2, BP_VAR_RW);
					increment_opline = 1;
				}
			}
			break;
		default:
			value = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
			var_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC);
			/* do nothing */
			break;
	}

	if (!var_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets");
	}

	if (*var_ptr == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}


		if (increment_opline) {
			ZEND_VM_INC_OPCODE();
		}
		ZEND_VM_NEXT_OPCODE();
	}

	SEPARATE_ZVAL_IF_NOT_REF(var_ptr);

	if(Z_TYPE_PP(var_ptr) == IS_OBJECT && Z_OBJ_HANDLER_PP(var_ptr, get)
	   && Z_OBJ_HANDLER_PP(var_ptr, set)) {
		/* proxy object */
		zval *objval = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
		objval->refcount++;
		binary_op(objval, objval, value TSRMLS_CC);
		Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, objval TSRMLS_CC);
		zval_ptr_dtor(&objval);
	} else {
		binary_op(*var_ptr, *var_ptr, value TSRMLS_CC);
	}

	if (!RETURN_VALUE_UNUSED(&opline->result)) {
		EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
		PZVAL_LOCK(*var_ptr);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
	}

	if (increment_opline) {
		ZEND_VM_INC_OPCODE();
		FREE_OP(free_op_data1);
		FREE_OP_VAR_PTR(free_op_data2);
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_ADD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_CV(add_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SUB_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_CV(sub_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_MUL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_CV(mul_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_DIV_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_CV(div_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_MOD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_CV(mod_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_CV(shift_left_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_SR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_CV(shift_right_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_CONCAT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_CV(concat_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_OR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_CV(bitwise_or_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_AND_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_CV(bitwise_and_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ASSIGN_BW_XOR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_binary_assign_op_helper_SPEC_CV_CV(bitwise_xor_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_pre_incdec_property_helper_SPEC_CV_CV(incdec_t incdec_op, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
	zval *object;
	zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
	zval **retval = &EX_T(opline->result.u.var).var.ptr;
	int have_get_ptr = 0;

	if (IS_CV == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}

	make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");

		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			*retval = EG(uninitialized_zval_ptr);
			PZVAL_LOCK(*retval);
		}

		ZEND_VM_NEXT_OPCODE();
	}

	/* here we are sure we are dealing with an object */

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}

	if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
		zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
		if (zptr != NULL) { 			/* NULL means no success in getting PTR */
			SEPARATE_ZVAL_IF_NOT_REF(zptr);

			have_get_ptr = 1;
			incdec_op(*zptr);
			if (!RETURN_VALUE_UNUSED(&opline->result)) {
				*retval = *zptr;
				PZVAL_LOCK(*retval);
			}
		}
	}

	if (!have_get_ptr) {
		if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
			zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);

			if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
				zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

				if (z->refcount == 0) {
					zval_dtor(z);
					FREE_ZVAL(z);
				}
				z = value;
			}
			z->refcount++;
			SEPARATE_ZVAL_IF_NOT_REF(&z);
			incdec_op(z);
			*retval = z;
			Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
			SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
			zval_ptr_dtor(&z);
		} else {
			zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
			if (!RETURN_VALUE_UNUSED(&opline->result)) {
				*retval = EG(uninitialized_zval_ptr);
				PZVAL_LOCK(*retval);
			}
		}
	}

	if (0) {
		zval_ptr_dtor(&property);
	} else {

	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_PRE_INC_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_pre_incdec_property_helper_SPEC_CV_CV(increment_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_PRE_DEC_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_pre_incdec_property_helper_SPEC_CV_CV(decrement_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int zend_post_incdec_property_helper_SPEC_CV_CV(incdec_t incdec_op, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
	zval *object;
	zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
	zval *retval = &EX_T(opline->result.u.var).tmp_var;
	int have_get_ptr = 0;

	if (IS_CV == IS_VAR && !object_ptr) {
		zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
	}

	make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
	object = *object_ptr;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");

		*retval = *EG(uninitialized_zval_ptr);

		ZEND_VM_NEXT_OPCODE();
	}

	/* here we are sure we are dealing with an object */

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}

	if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
		zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
		if (zptr != NULL) { 			/* NULL means no success in getting PTR */
			have_get_ptr = 1;
			SEPARATE_ZVAL_IF_NOT_REF(zptr);

			*retval = **zptr;
			zendi_zval_copy_ctor(*retval);

			incdec_op(*zptr);

		}
	}

	if (!have_get_ptr) {
		if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
			zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
			zval *z_copy;

			if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
				zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);

				if (z->refcount == 0) {
					zval_dtor(z);
					FREE_ZVAL(z);
				}
				z = value;
			}
			*retval = *z;
			zendi_zval_copy_ctor(*retval);
			ALLOC_ZVAL(z_copy);
			*z_copy = *z;
			zendi_zval_copy_ctor(*z_copy);
			INIT_PZVAL(z_copy);
			incdec_op(z_copy);
			z->refcount++;
			Z_OBJ_HT_P(object)->write_property(object, property, z_copy TSRMLS_CC);
			zval_ptr_dtor(&z_copy);
			zval_ptr_dtor(&z);
		} else {
			zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
			*retval = *EG(uninitialized_zval_ptr);
		}
	}

	if (0) {
		zval_ptr_dtor(&property);
	} else {

	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_POST_INC_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_post_incdec_property_helper_SPEC_CV_CV(increment_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_POST_DEC_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_post_incdec_property_helper_SPEC_CV_CV(decrement_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

	if (opline->extended_value == ZEND_FETCH_ADD_LOCK &&
	    IS_CV != IS_CV &&
	    EX_T(opline->op1.u.var).var.ptr_ptr) {
		PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
	}
	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), dim, 0, BP_VAR_W TSRMLS_CC);

	if (IS_CV == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC);

	if (IS_CV == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_IS TSRMLS_CC), dim, 0, BP_VAR_IS TSRMLS_CC);


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
	zval *dim;

	if (IS_CV == IS_UNUSED && type == BP_VAR_R) {
		zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
	}
	dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), type TSRMLS_CC), dim, 0, type TSRMLS_CC);

	if (IS_CV == IS_VAR && type == BP_VAR_W && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_UNSET TSRMLS_CC);
	zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

	/* Not needed in DIM_UNSET
	if (opline->extended_value == ZEND_FETCH_ADD_LOCK) {
		PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
	}
	*/
	if (IS_CV == IS_CV) {
		if (container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
	}
	zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_UNSET TSRMLS_CC);

	if (IS_CV == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	if (EX_T(opline->result.u.var).var.ptr_ptr == NULL) {
		zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
	} else {
		zend_free_op free_res;

		PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &free_res);
		if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
		}
		PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
		FREE_OP_VAR_PTR(free_res);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int zend_fetch_property_address_read_helper_SPEC_CV_CV(int type, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *container;
	zval **retval;


	zval *offset  = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

	retval = &EX_T(opline->result.u.var).var.ptr;
	EX_T(opline->result.u.var).var.ptr_ptr = retval;

	container = _get_zval_ptr_cv(&opline->op1, EX(Ts), type TSRMLS_CC);

	if (container == EG(error_zval_ptr)) {
		if (!RETURN_VALUE_UNUSED(&opline->result)) {
			*retval = EG(error_zval_ptr);
			PZVAL_LOCK(*retval);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}


		ZEND_VM_NEXT_OPCODE();
	}


	if (Z_TYPE_P(container) != IS_OBJECT || !Z_OBJ_HT_P(container)->read_property) {
		if (type != BP_VAR_IS) {
			zend_error(E_NOTICE, "Trying to get property of non-object");
		}
		*retval = EG(uninitialized_zval_ptr);
		SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
		AI_USE_PTR(EX_T(opline->result.u.var).var);

	} else {
		if (0) {
			MAKE_REAL_ZVAL_PTR(offset);
		}

		/* here we are sure we are dealing with an object */
		*retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);

		if (RETURN_VALUE_UNUSED(&opline->result) && ((*retval)->refcount == 0)) {
			zval_dtor(*retval);
			FREE_ZVAL(*retval);
		} else {
			SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
			AI_USE_PTR(EX_T(opline->result.u.var).var);
		}

		if (0) {
			zval_ptr_dtor(&offset);
		} else {

		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_property_address_read_helper_SPEC_CV_CV(BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

	if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_CV != IS_CV) {
		PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
		EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr;
	}

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), property, BP_VAR_W TSRMLS_CC);
	if (0) {
		zval_ptr_dtor(&property);
	} else {

	}
	if (IS_CV == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1;
	zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), property, BP_VAR_RW TSRMLS_CC);
	if (0) {
		zval_ptr_dtor(&property);
	} else {

	}
	if (IS_CV == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_fetch_property_address_read_helper_SPEC_CV_CV(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) {
		/* Behave like FETCH_OBJ_W */
		zend_free_op free_op1;
		zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

		if (0) {
			MAKE_REAL_ZVAL_PTR(property);
		}
		zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), property, BP_VAR_W TSRMLS_CC);
		if (0) {
			zval_ptr_dtor(&property);
		} else {

		}
		if (IS_CV == IS_VAR && 0 &&
		    READY_TO_DESTROY(free_op1.var) &&
		    !RETURN_VALUE_UNUSED(&opline->result)) {
			AI_USE_PTR(EX_T(opline->result.u.var).var);
			if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
			    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
				SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
			}
		}

		ZEND_VM_NEXT_OPCODE();
	} else {
		return zend_fetch_property_address_read_helper_SPEC_CV_CV(BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
	}
}

static int ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op1, free_res;
	zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
	zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

	if (IS_CV == IS_CV) {
		if (container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
	}
	if (0) {
		MAKE_REAL_ZVAL_PTR(property);
	}
	zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC);
	if (0) {
		zval_ptr_dtor(&property);
	} else {

	}
	if (IS_CV == IS_VAR && 0 &&
	    READY_TO_DESTROY(free_op1.var) &&
	    !RETURN_VALUE_UNUSED(&opline->result)) {
		AI_USE_PTR(EX_T(opline->result.u.var).var);
		if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
		    ZVAL_REFCOUNT(*EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
			SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
		}
	}

	PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &free_res);
	if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
		SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
	}
	PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
	FREE_OP_VAR_PTR(free_res);
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;

	zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);

	zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);

	/* assign_obj has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_op *op_data = opline+1;

	zval **object_ptr;

	if (IS_CV == IS_CV || EX_T(opline->op1.u.var).var.ptr_ptr) {
		/* not an array offset */
		object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
	} else {
		object_ptr = NULL;
	}

	if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
		zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC);
	} else {
		zend_free_op free_op_data1;
		zval *value;
		zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

		zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 0, BP_VAR_W TSRMLS_CC);

		value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
	 	zend_assign_to_variable(&opline->result, &op_data->op2, &op_data->op1, value, (IS_TMP_FREE(free_op_data1)?IS_TMP_VAR:op_data->op1.op_type), EX(Ts) TSRMLS_CC);
	 	FREE_OP_IF_VAR(free_op_data1);
	}

	/* assign_dim has two opcodes! */
	ZEND_VM_INC_OPCODE();
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval *value = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

 	zend_assign_to_variable(&opline->result, &opline->op1, &opline->op2, value, (0?IS_TMP_VAR:IS_CV), EX(Ts) TSRMLS_CC);
	/* zend_assign_to_variable() always takes care of op2, never free it! */

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zend_free_op free_op2;
	zval **variable_ptr_ptr;
	zval **value_ptr_ptr = _get_zval_ptr_ptr_cv(&opline->op2, EX(Ts), BP_VAR_W TSRMLS_CC);

	if (IS_CV == IS_VAR &&
	    value_ptr_ptr &&
	    !(*value_ptr_ptr)->is_ref &&
	    opline->extended_value == ZEND_RETURNS_FUNCTION &&
	    !EX_T(opline->op2.u.var).var.fcall_returned_reference) {
		if (free_op2.var == NULL) {
			PZVAL_LOCK(*value_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
		}
		zend_error(E_STRICT, "Only variables should be assigned by reference");
		if (EG(exception)) {

			ZEND_VM_NEXT_OPCODE();
		}
		return ZEND_ASSIGN_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
	} else if (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
		PZVAL_LOCK(*value_ptr_ptr);
	}
	if (IS_CV == IS_VAR && EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
		zend_error(E_ERROR, "Cannot assign by reference to overloaded object");
	}

	variable_ptr_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
	zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);

	if (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
		(*variable_ptr_ptr)->refcount--;
	}

	if (!RETURN_VALUE_UNUSED(&opline->result)) {
		EX_T(opline->result.u.var).var.ptr_ptr = variable_ptr_ptr;
		PZVAL_LOCK(*variable_ptr_ptr);
		AI_USE_PTR(EX_T(opline->result.u.var).var);
	}


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	zval *function_name;
	char *function_name_strval;
	int function_name_strlen;


	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), NULL);

	function_name = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

	if (Z_TYPE_P(function_name)!=IS_STRING) {
		zend_error_noreturn(E_ERROR, "Method name must be a string");
	}

	function_name_strval = Z_STRVAL_P(function_name);
	function_name_strlen = Z_STRLEN_P(function_name);

	EX(object) = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);

	if (EX(object) && Z_TYPE_P(EX(object)) == IS_OBJECT) {
		if (Z_OBJ_HT_P(EX(object))->get_method == NULL) {
			zend_error_noreturn(E_ERROR, "Object does not support method calls");
		}

		/* First, locate the function. */
		EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen TSRMLS_CC);
		if (!EX(fbc)) {
			zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
		}
	} else {
		zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
	}

	if (!EX(object) || (EX(fbc) && (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
		EX(object) = NULL;
	} else {
		if (!PZVAL_IS_REF(EX(object))) {
			EX(object)->refcount++; /* For $this pointer */
		} else {
			zval *this_ptr;
			ALLOC_ZVAL(this_ptr);
			INIT_PZVAL_COPY(this_ptr, EX(object));
			zval_copy_ctor(this_ptr);
			EX(object) = this_ptr;
		}
	}


	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_CASE_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);
	int switch_expr_is_overloaded=0;


	if (IS_CV==IS_VAR) {
		if (EX_T(opline->op1.u.var).var.ptr_ptr) {
			PZVAL_LOCK(EX_T(opline->op1.u.var).var.ptr);
		} else {
			switch_expr_is_overloaded = 1;
			EX_T(opline->op1.u.var).str_offset.str->refcount++;
		}
	}
	is_equal_function(&EX_T(opline->result.u.var).tmp_var,
				 _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC),
				 _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC);

	if (switch_expr_is_overloaded) {
		/* We only free op1 if this is a string offset,
		 * Since if it is a TMP_VAR, it'll be reused by
		 * other CASE opcodes (whereas string offsets
		 * are allocated at each get_zval_ptr())
		 */

		EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
		AI_USE_PTR(EX_T(opline->op1.u.var).var);
	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval *array_ptr = &EX_T(opline->result.u.var).tmp_var;
	zval *expr_ptr;
	zval *offset=_get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

#if 0 || IS_CV == IS_VAR || IS_CV == IS_CV
	zval **expr_ptr_ptr = NULL;

	if (opline->extended_value) {
		expr_ptr_ptr=_get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
		expr_ptr = *expr_ptr_ptr;
	} else {
		expr_ptr=_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
	}
#else
	expr_ptr=_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
#endif

	if (0) { /* temporary variable */
		zval *new_expr;

		ALLOC_ZVAL(new_expr);
		INIT_PZVAL_COPY(new_expr, expr_ptr);
		expr_ptr = new_expr;
	} else {
#if 0 || IS_CV == IS_VAR || IS_CV == IS_CV
		if (opline->extended_value) {
			SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr_ptr);
			expr_ptr = *expr_ptr_ptr;
			expr_ptr->refcount++;
		} else
#endif
		if (PZVAL_IS_REF(expr_ptr)) {
			zval *new_expr;

			ALLOC_ZVAL(new_expr);
			INIT_PZVAL_COPY(new_expr, expr_ptr);
			expr_ptr = new_expr;
			zendi_zval_copy_ctor(*expr_ptr);
		} else {
			expr_ptr->refcount++;
		}
	}
	if (offset) {
		switch (Z_TYPE_P(offset)) {
			case IS_DOUBLE:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_LONG:
			case IS_BOOL:
				zend_hash_index_update(Z_ARRVAL_P(array_ptr), Z_LVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_STRING:
				zend_symtable_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, &expr_ptr, sizeof(zval *), NULL);
				break;
			case IS_NULL:
				zend_hash_update(Z_ARRVAL_P(array_ptr), "", sizeof(""), &expr_ptr, sizeof(zval *), NULL);
				break;
			default:
				zend_error(E_WARNING, "Illegal offset type");
				zval_ptr_dtor(&expr_ptr);
				/* do nothing */
				break;
		}

	} else {
		zend_hash_next_index_insert(Z_ARRVAL_P(array_ptr), &expr_ptr, sizeof(zval *), NULL);
	}
	if (opline->extended_value) {

	} else {

	}
	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_INIT_ARRAY_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	array_init(&EX_T(opline->result.u.var).tmp_var);
	if (IS_CV == IS_UNUSED) {
		ZEND_VM_NEXT_OPCODE();
#if 0 || IS_CV != IS_UNUSED
	} else {
		return ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
#endif
	}
}

static int ZEND_UNSET_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_UNSET TSRMLS_CC);
	zval *offset = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
	long index;

	if (container) {
		if (IS_CV == IS_CV && container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
		switch (Z_TYPE_PP(container)) {
			case IS_ARRAY: {
				HashTable *ht = Z_ARRVAL_PP(container);

				switch (Z_TYPE_P(offset)) {
					case IS_DOUBLE:
						index = (long) Z_DVAL_P(offset);
						zend_hash_index_del(ht, index);
						break;
					case IS_RESOURCE:
					case IS_BOOL:
					case IS_LONG:
						index = Z_LVAL_P(offset);
						zend_hash_index_del(ht, index);
						break;
					case IS_STRING:
						if (IS_CV == IS_CV || IS_CV == IS_VAR) {
							offset->refcount++;
						}
						if (zend_symtable_del(ht, offset->value.str.val, offset->value.str.len+1) == SUCCESS &&
					    ht == &EG(symbol_table)) {
							zend_execute_data *ex;
							ulong hash_value = zend_inline_hash_func(offset->value.str.val, offset->value.str.len+1);

							for (ex = execute_data; ex; ex = ex->prev_execute_data) {
								if (ex->op_array && ex->symbol_table == ht) {
									int i;

									for (i = 0; i < ex->op_array->last_var; i++) {
										if (ex->op_array->vars[i].hash_value == hash_value &&
										    ex->op_array->vars[i].name_len == offset->value.str.len &&
										    !memcmp(ex->op_array->vars[i].name, offset->value.str.val, offset->value.str.len)) {
											ex->CVs[i] = NULL;
											break;
										}
									}
								}
							}
						}
						if (IS_CV == IS_CV || IS_CV == IS_VAR) {
							zval_ptr_dtor(&offset);
						}
						break;
					case IS_NULL:
						zend_hash_del(ht, "", sizeof(""));
						break;
					default:
						zend_error(E_WARNING, "Illegal offset type in unset");
						break;
				}

				break;
			}
			case IS_OBJECT:
				if (!Z_OBJ_HT_P(*container)->unset_dimension) {
					zend_error_noreturn(E_ERROR, "Cannot use object as array");
				}
				if (0) {
					MAKE_REAL_ZVAL_PTR(offset);
				}
				Z_OBJ_HT_P(*container)->unset_dimension(*container, offset TSRMLS_CC);
				if (0) {
					zval_ptr_dtor(&offset);
				} else {

				}
				break;
			case IS_STRING:
				zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
				ZEND_VM_CONTINUE(); /* bailed out before */
			default:

				break;
		}
	} else {

	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_UNSET_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_UNSET TSRMLS_CC);
	zval *offset = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

	if (container) {
		if (IS_CV == IS_CV && container != &EG(uninitialized_zval_ptr)) {
			SEPARATE_ZVAL_IF_NOT_REF(container);
		}
		if (Z_TYPE_PP(container) == IS_OBJECT) {
			if (0) {
				MAKE_REAL_ZVAL_PTR(offset);
			}
			Z_OBJ_HT_P(*container)->unset_property(*container, offset TSRMLS_CC);
			if (0) {
				zval_ptr_dtor(&offset);
			} else {

			}
		} else {

		}
	} else {

	}

	ZEND_VM_NEXT_OPCODE();
}

static int zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CV(int prop_dim, ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_IS TSRMLS_CC);
	zval **value = NULL;
	int result = 0;
	long index;

	if (container) {

		zval *offset = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);

		if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
			HashTable *ht;
			int isset = 0;

			ht = Z_ARRVAL_PP(container);

			switch (Z_TYPE_P(offset)) {
				case IS_DOUBLE:
					index = (long) Z_DVAL_P(offset);
					if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_RESOURCE:
				case IS_BOOL:
				case IS_LONG:
					index = Z_LVAL_P(offset);
					if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_STRING:
					if (zend_symtable_find(ht, offset->value.str.val, offset->value.str.len+1, (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				case IS_NULL:
					if (zend_hash_find(ht, "", sizeof(""), (void **) &value) == SUCCESS) {
						isset = 1;
					}
					break;
				default:
					zend_error(E_WARNING, "Illegal offset type in isset or empty");

					break;
			}

			switch (opline->extended_value) {
				case ZEND_ISSET:
					if (isset && Z_TYPE_PP(value) == IS_NULL) {
						result = 0;
					} else {
						result = isset;
					}
					break;
				case ZEND_ISEMPTY:
					if (!isset || !i_zend_is_true(*value)) {
						result = 0;
					} else {
						result = 1;
					}
					break;
			}

		} else if (Z_TYPE_PP(container) == IS_OBJECT) {
			if (0) {
				MAKE_REAL_ZVAL_PTR(offset);
			}
			if (prop_dim) {
				result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value == ZEND_ISEMPTY) TSRMLS_CC);
			} else {
				result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value == ZEND_ISEMPTY) TSRMLS_CC);
			}
			if (0) {
				zval_ptr_dtor(&offset);
			} else {

			}
		} else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
			zval tmp;

			if (Z_TYPE_P(offset) != IS_LONG) {
				tmp = *offset;
				zval_copy_ctor(&tmp);
				convert_to_long(&tmp);
				offset = &tmp;
			}
			if (Z_TYPE_P(offset) == IS_LONG) {
				switch (opline->extended_value) {
					case ZEND_ISSET:
						if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
							result = 1;
						}
						break;
					case ZEND_ISEMPTY:
						if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
							result = 1;
						}
						break;
				}
			}

		} else {

		}
	}

	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;

	switch (opline->extended_value) {
		case ZEND_ISSET:
			Z_LVAL(EX_T(opline->result.u.var).tmp_var) = result;
			break;
		case ZEND_ISEMPTY:
			Z_LVAL(EX_T(opline->result.u.var).tmp_var) = !result;
			break;
	}

	ZEND_VM_NEXT_OPCODE();
}

static int ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CV(0, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CV(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

static int ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_error_noreturn(E_ERROR, "Invalid opcode %d/%d/%d.", EX(opline)->opcode, EX(opline)->op1.op_type, EX(opline)->op2.op_type);
	ZEND_VM_RETURN_FROM_EXECUTE_LOOP();
}


void zend_init_opcodes_handlers(void)
{
  static const opcode_handler_t labels[] = {
  	ZEND_NOP_SPEC_HANDLER,
  	ZEND_NOP_SPEC_HANDLER,
  	ZEND_NOP_SPEC_HANDLER,
  	ZEND_NOP_SPEC_HANDLER,
  	ZEND_NOP_SPEC_HANDLER,
  	ZEND_NOP_SPEC_HANDLER,
  	ZEND_NOP_SPEC_HANDLER,
  	ZEND_NOP_SPEC_HANDLER,
  	ZEND_NOP_SPEC_HANDLER,
  	ZEND_NOP_SPEC_HANDLER,
  	ZEND_NOP_SPEC_HANDLER,
  	ZEND_NOP_SPEC_HANDLER,
  	ZEND_NOP_SPEC_HANDLER,
  	ZEND_NOP_SPEC_HANDLER,
  	ZEND_NOP_SPEC_HANDLER,
  	ZEND_NOP_SPEC_HANDLER,
  	ZEND_NOP_SPEC_HANDLER,
  	ZEND_NOP_SPEC_HANDLER,
  	ZEND_NOP_SPEC_HANDLER,
  	ZEND_NOP_SPEC_HANDLER,
  	ZEND_NOP_SPEC_HANDLER,
  	ZEND_NOP_SPEC_HANDLER,
  	ZEND_NOP_SPEC_HANDLER,
  	ZEND_NOP_SPEC_HANDLER,
  	ZEND_NOP_SPEC_HANDLER,
  	ZEND_ADD_SPEC_CONST_CONST_HANDLER,
  	ZEND_ADD_SPEC_CONST_TMP_HANDLER,
  	ZEND_ADD_SPEC_CONST_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ADD_SPEC_CONST_CV_HANDLER,
  	ZEND_ADD_SPEC_TMP_CONST_HANDLER,
  	ZEND_ADD_SPEC_TMP_TMP_HANDLER,
  	ZEND_ADD_SPEC_TMP_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ADD_SPEC_TMP_CV_HANDLER,
  	ZEND_ADD_SPEC_VAR_CONST_HANDLER,
  	ZEND_ADD_SPEC_VAR_TMP_HANDLER,
  	ZEND_ADD_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ADD_SPEC_VAR_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ADD_SPEC_CV_CONST_HANDLER,
  	ZEND_ADD_SPEC_CV_TMP_HANDLER,
  	ZEND_ADD_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ADD_SPEC_CV_CV_HANDLER,
  	ZEND_SUB_SPEC_CONST_CONST_HANDLER,
  	ZEND_SUB_SPEC_CONST_TMP_HANDLER,
  	ZEND_SUB_SPEC_CONST_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_SUB_SPEC_CONST_CV_HANDLER,
  	ZEND_SUB_SPEC_TMP_CONST_HANDLER,
  	ZEND_SUB_SPEC_TMP_TMP_HANDLER,
  	ZEND_SUB_SPEC_TMP_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_SUB_SPEC_TMP_CV_HANDLER,
  	ZEND_SUB_SPEC_VAR_CONST_HANDLER,
  	ZEND_SUB_SPEC_VAR_TMP_HANDLER,
  	ZEND_SUB_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_SUB_SPEC_VAR_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_SUB_SPEC_CV_CONST_HANDLER,
  	ZEND_SUB_SPEC_CV_TMP_HANDLER,
  	ZEND_SUB_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_SUB_SPEC_CV_CV_HANDLER,
  	ZEND_MUL_SPEC_CONST_CONST_HANDLER,
  	ZEND_MUL_SPEC_CONST_TMP_HANDLER,
  	ZEND_MUL_SPEC_CONST_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_MUL_SPEC_CONST_CV_HANDLER,
  	ZEND_MUL_SPEC_TMP_CONST_HANDLER,
  	ZEND_MUL_SPEC_TMP_TMP_HANDLER,
  	ZEND_MUL_SPEC_TMP_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_MUL_SPEC_TMP_CV_HANDLER,
  	ZEND_MUL_SPEC_VAR_CONST_HANDLER,
  	ZEND_MUL_SPEC_VAR_TMP_HANDLER,
  	ZEND_MUL_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_MUL_SPEC_VAR_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_MUL_SPEC_CV_CONST_HANDLER,
  	ZEND_MUL_SPEC_CV_TMP_HANDLER,
  	ZEND_MUL_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_MUL_SPEC_CV_CV_HANDLER,
  	ZEND_DIV_SPEC_CONST_CONST_HANDLER,
  	ZEND_DIV_SPEC_CONST_TMP_HANDLER,
  	ZEND_DIV_SPEC_CONST_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_DIV_SPEC_CONST_CV_HANDLER,
  	ZEND_DIV_SPEC_TMP_CONST_HANDLER,
  	ZEND_DIV_SPEC_TMP_TMP_HANDLER,
  	ZEND_DIV_SPEC_TMP_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_DIV_SPEC_TMP_CV_HANDLER,
  	ZEND_DIV_SPEC_VAR_CONST_HANDLER,
  	ZEND_DIV_SPEC_VAR_TMP_HANDLER,
  	ZEND_DIV_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_DIV_SPEC_VAR_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_DIV_SPEC_CV_CONST_HANDLER,
  	ZEND_DIV_SPEC_CV_TMP_HANDLER,
  	ZEND_DIV_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_DIV_SPEC_CV_CV_HANDLER,
  	ZEND_MOD_SPEC_CONST_CONST_HANDLER,
  	ZEND_MOD_SPEC_CONST_TMP_HANDLER,
  	ZEND_MOD_SPEC_CONST_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_MOD_SPEC_CONST_CV_HANDLER,
  	ZEND_MOD_SPEC_TMP_CONST_HANDLER,
  	ZEND_MOD_SPEC_TMP_TMP_HANDLER,
  	ZEND_MOD_SPEC_TMP_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_MOD_SPEC_TMP_CV_HANDLER,
  	ZEND_MOD_SPEC_VAR_CONST_HANDLER,
  	ZEND_MOD_SPEC_VAR_TMP_HANDLER,
  	ZEND_MOD_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_MOD_SPEC_VAR_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_MOD_SPEC_CV_CONST_HANDLER,
  	ZEND_MOD_SPEC_CV_TMP_HANDLER,
  	ZEND_MOD_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_MOD_SPEC_CV_CV_HANDLER,
  	ZEND_SL_SPEC_CONST_CONST_HANDLER,
  	ZEND_SL_SPEC_CONST_TMP_HANDLER,
  	ZEND_SL_SPEC_CONST_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_SL_SPEC_CONST_CV_HANDLER,
  	ZEND_SL_SPEC_TMP_CONST_HANDLER,
  	ZEND_SL_SPEC_TMP_TMP_HANDLER,
  	ZEND_SL_SPEC_TMP_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_SL_SPEC_TMP_CV_HANDLER,
  	ZEND_SL_SPEC_VAR_CONST_HANDLER,
  	ZEND_SL_SPEC_VAR_TMP_HANDLER,
  	ZEND_SL_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_SL_SPEC_VAR_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_SL_SPEC_CV_CONST_HANDLER,
  	ZEND_SL_SPEC_CV_TMP_HANDLER,
  	ZEND_SL_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_SL_SPEC_CV_CV_HANDLER,
  	ZEND_SR_SPEC_CONST_CONST_HANDLER,
  	ZEND_SR_SPEC_CONST_TMP_HANDLER,
  	ZEND_SR_SPEC_CONST_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_SR_SPEC_CONST_CV_HANDLER,
  	ZEND_SR_SPEC_TMP_CONST_HANDLER,
  	ZEND_SR_SPEC_TMP_TMP_HANDLER,
  	ZEND_SR_SPEC_TMP_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_SR_SPEC_TMP_CV_HANDLER,
  	ZEND_SR_SPEC_VAR_CONST_HANDLER,
  	ZEND_SR_SPEC_VAR_TMP_HANDLER,
  	ZEND_SR_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_SR_SPEC_VAR_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_SR_SPEC_CV_CONST_HANDLER,
  	ZEND_SR_SPEC_CV_TMP_HANDLER,
  	ZEND_SR_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_SR_SPEC_CV_CV_HANDLER,
  	ZEND_CONCAT_SPEC_CONST_CONST_HANDLER,
  	ZEND_CONCAT_SPEC_CONST_TMP_HANDLER,
  	ZEND_CONCAT_SPEC_CONST_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_CONCAT_SPEC_CONST_CV_HANDLER,
  	ZEND_CONCAT_SPEC_TMP_CONST_HANDLER,
  	ZEND_CONCAT_SPEC_TMP_TMP_HANDLER,
  	ZEND_CONCAT_SPEC_TMP_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_CONCAT_SPEC_TMP_CV_HANDLER,
  	ZEND_CONCAT_SPEC_VAR_CONST_HANDLER,
  	ZEND_CONCAT_SPEC_VAR_TMP_HANDLER,
  	ZEND_CONCAT_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_CONCAT_SPEC_VAR_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_CONCAT_SPEC_CV_CONST_HANDLER,
  	ZEND_CONCAT_SPEC_CV_TMP_HANDLER,
  	ZEND_CONCAT_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_CONCAT_SPEC_CV_CV_HANDLER,
  	ZEND_BW_OR_SPEC_CONST_CONST_HANDLER,
  	ZEND_BW_OR_SPEC_CONST_TMP_HANDLER,
  	ZEND_BW_OR_SPEC_CONST_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_BW_OR_SPEC_CONST_CV_HANDLER,
  	ZEND_BW_OR_SPEC_TMP_CONST_HANDLER,
  	ZEND_BW_OR_SPEC_TMP_TMP_HANDLER,
  	ZEND_BW_OR_SPEC_TMP_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_BW_OR_SPEC_TMP_CV_HANDLER,
  	ZEND_BW_OR_SPEC_VAR_CONST_HANDLER,
  	ZEND_BW_OR_SPEC_VAR_TMP_HANDLER,
  	ZEND_BW_OR_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_BW_OR_SPEC_VAR_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_BW_OR_SPEC_CV_CONST_HANDLER,
  	ZEND_BW_OR_SPEC_CV_TMP_HANDLER,
  	ZEND_BW_OR_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_BW_OR_SPEC_CV_CV_HANDLER,
  	ZEND_BW_AND_SPEC_CONST_CONST_HANDLER,
  	ZEND_BW_AND_SPEC_CONST_TMP_HANDLER,
  	ZEND_BW_AND_SPEC_CONST_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_BW_AND_SPEC_CONST_CV_HANDLER,
  	ZEND_BW_AND_SPEC_TMP_CONST_HANDLER,
  	ZEND_BW_AND_SPEC_TMP_TMP_HANDLER,
  	ZEND_BW_AND_SPEC_TMP_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_BW_AND_SPEC_TMP_CV_HANDLER,
  	ZEND_BW_AND_SPEC_VAR_CONST_HANDLER,
  	ZEND_BW_AND_SPEC_VAR_TMP_HANDLER,
  	ZEND_BW_AND_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_BW_AND_SPEC_VAR_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_BW_AND_SPEC_CV_CONST_HANDLER,
  	ZEND_BW_AND_SPEC_CV_TMP_HANDLER,
  	ZEND_BW_AND_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_BW_AND_SPEC_CV_CV_HANDLER,
  	ZEND_BW_XOR_SPEC_CONST_CONST_HANDLER,
  	ZEND_BW_XOR_SPEC_CONST_TMP_HANDLER,
  	ZEND_BW_XOR_SPEC_CONST_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_BW_XOR_SPEC_CONST_CV_HANDLER,
  	ZEND_BW_XOR_SPEC_TMP_CONST_HANDLER,
  	ZEND_BW_XOR_SPEC_TMP_TMP_HANDLER,
  	ZEND_BW_XOR_SPEC_TMP_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_BW_XOR_SPEC_TMP_CV_HANDLER,
  	ZEND_BW_XOR_SPEC_VAR_CONST_HANDLER,
  	ZEND_BW_XOR_SPEC_VAR_TMP_HANDLER,
  	ZEND_BW_XOR_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_BW_XOR_SPEC_VAR_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_BW_XOR_SPEC_CV_CONST_HANDLER,
  	ZEND_BW_XOR_SPEC_CV_TMP_HANDLER,
  	ZEND_BW_XOR_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_BW_XOR_SPEC_CV_CV_HANDLER,
  	ZEND_BW_NOT_SPEC_CONST_HANDLER,
  	ZEND_BW_NOT_SPEC_CONST_HANDLER,
  	ZEND_BW_NOT_SPEC_CONST_HANDLER,
  	ZEND_BW_NOT_SPEC_CONST_HANDLER,
  	ZEND_BW_NOT_SPEC_CONST_HANDLER,
  	ZEND_BW_NOT_SPEC_TMP_HANDLER,
  	ZEND_BW_NOT_SPEC_TMP_HANDLER,
  	ZEND_BW_NOT_SPEC_TMP_HANDLER,
  	ZEND_BW_NOT_SPEC_TMP_HANDLER,
  	ZEND_BW_NOT_SPEC_TMP_HANDLER,
  	ZEND_BW_NOT_SPEC_VAR_HANDLER,
  	ZEND_BW_NOT_SPEC_VAR_HANDLER,
  	ZEND_BW_NOT_SPEC_VAR_HANDLER,
  	ZEND_BW_NOT_SPEC_VAR_HANDLER,
  	ZEND_BW_NOT_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_BW_NOT_SPEC_CV_HANDLER,
  	ZEND_BW_NOT_SPEC_CV_HANDLER,
  	ZEND_BW_NOT_SPEC_CV_HANDLER,
  	ZEND_BW_NOT_SPEC_CV_HANDLER,
  	ZEND_BW_NOT_SPEC_CV_HANDLER,
  	ZEND_BOOL_NOT_SPEC_CONST_HANDLER,
  	ZEND_BOOL_NOT_SPEC_CONST_HANDLER,
  	ZEND_BOOL_NOT_SPEC_CONST_HANDLER,
  	ZEND_BOOL_NOT_SPEC_CONST_HANDLER,
  	ZEND_BOOL_NOT_SPEC_CONST_HANDLER,
  	ZEND_BOOL_NOT_SPEC_TMP_HANDLER,
  	ZEND_BOOL_NOT_SPEC_TMP_HANDLER,
  	ZEND_BOOL_NOT_SPEC_TMP_HANDLER,
  	ZEND_BOOL_NOT_SPEC_TMP_HANDLER,
  	ZEND_BOOL_NOT_SPEC_TMP_HANDLER,
  	ZEND_BOOL_NOT_SPEC_VAR_HANDLER,
  	ZEND_BOOL_NOT_SPEC_VAR_HANDLER,
  	ZEND_BOOL_NOT_SPEC_VAR_HANDLER,
  	ZEND_BOOL_NOT_SPEC_VAR_HANDLER,
  	ZEND_BOOL_NOT_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_BOOL_NOT_SPEC_CV_HANDLER,
  	ZEND_BOOL_NOT_SPEC_CV_HANDLER,
  	ZEND_BOOL_NOT_SPEC_CV_HANDLER,
  	ZEND_BOOL_NOT_SPEC_CV_HANDLER,
  	ZEND_BOOL_NOT_SPEC_CV_HANDLER,
  	ZEND_BOOL_XOR_SPEC_CONST_CONST_HANDLER,
  	ZEND_BOOL_XOR_SPEC_CONST_TMP_HANDLER,
  	ZEND_BOOL_XOR_SPEC_CONST_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_BOOL_XOR_SPEC_CONST_CV_HANDLER,
  	ZEND_BOOL_XOR_SPEC_TMP_CONST_HANDLER,
  	ZEND_BOOL_XOR_SPEC_TMP_TMP_HANDLER,
  	ZEND_BOOL_XOR_SPEC_TMP_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_BOOL_XOR_SPEC_TMP_CV_HANDLER,
  	ZEND_BOOL_XOR_SPEC_VAR_CONST_HANDLER,
  	ZEND_BOOL_XOR_SPEC_VAR_TMP_HANDLER,
  	ZEND_BOOL_XOR_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_BOOL_XOR_SPEC_VAR_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_BOOL_XOR_SPEC_CV_CONST_HANDLER,
  	ZEND_BOOL_XOR_SPEC_CV_TMP_HANDLER,
  	ZEND_BOOL_XOR_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_BOOL_XOR_SPEC_CV_CV_HANDLER,
  	ZEND_IS_IDENTICAL_SPEC_CONST_CONST_HANDLER,
  	ZEND_IS_IDENTICAL_SPEC_CONST_TMP_HANDLER,
  	ZEND_IS_IDENTICAL_SPEC_CONST_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_IS_IDENTICAL_SPEC_CONST_CV_HANDLER,
  	ZEND_IS_IDENTICAL_SPEC_TMP_CONST_HANDLER,
  	ZEND_IS_IDENTICAL_SPEC_TMP_TMP_HANDLER,
  	ZEND_IS_IDENTICAL_SPEC_TMP_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_IS_IDENTICAL_SPEC_TMP_CV_HANDLER,
  	ZEND_IS_IDENTICAL_SPEC_VAR_CONST_HANDLER,
  	ZEND_IS_IDENTICAL_SPEC_VAR_TMP_HANDLER,
  	ZEND_IS_IDENTICAL_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_IS_IDENTICAL_SPEC_VAR_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_IS_IDENTICAL_SPEC_CV_CONST_HANDLER,
  	ZEND_IS_IDENTICAL_SPEC_CV_TMP_HANDLER,
  	ZEND_IS_IDENTICAL_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_IS_IDENTICAL_SPEC_CV_CV_HANDLER,
  	ZEND_IS_NOT_IDENTICAL_SPEC_CONST_CONST_HANDLER,
  	ZEND_IS_NOT_IDENTICAL_SPEC_CONST_TMP_HANDLER,
  	ZEND_IS_NOT_IDENTICAL_SPEC_CONST_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_IS_NOT_IDENTICAL_SPEC_CONST_CV_HANDLER,
  	ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CONST_HANDLER,
  	ZEND_IS_NOT_IDENTICAL_SPEC_TMP_TMP_HANDLER,
  	ZEND_IS_NOT_IDENTICAL_SPEC_TMP_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CV_HANDLER,
  	ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CONST_HANDLER,
  	ZEND_IS_NOT_IDENTICAL_SPEC_VAR_TMP_HANDLER,
  	ZEND_IS_NOT_IDENTICAL_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_IS_NOT_IDENTICAL_SPEC_CV_CONST_HANDLER,
  	ZEND_IS_NOT_IDENTICAL_SPEC_CV_TMP_HANDLER,
  	ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_IS_NOT_IDENTICAL_SPEC_CV_CV_HANDLER,
  	ZEND_IS_EQUAL_SPEC_CONST_CONST_HANDLER,
  	ZEND_IS_EQUAL_SPEC_CONST_TMP_HANDLER,
  	ZEND_IS_EQUAL_SPEC_CONST_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_IS_EQUAL_SPEC_CONST_CV_HANDLER,
  	ZEND_IS_EQUAL_SPEC_TMP_CONST_HANDLER,
  	ZEND_IS_EQUAL_SPEC_TMP_TMP_HANDLER,
  	ZEND_IS_EQUAL_SPEC_TMP_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_IS_EQUAL_SPEC_TMP_CV_HANDLER,
  	ZEND_IS_EQUAL_SPEC_VAR_CONST_HANDLER,
  	ZEND_IS_EQUAL_SPEC_VAR_TMP_HANDLER,
  	ZEND_IS_EQUAL_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_IS_EQUAL_SPEC_VAR_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_IS_EQUAL_SPEC_CV_CONST_HANDLER,
  	ZEND_IS_EQUAL_SPEC_CV_TMP_HANDLER,
  	ZEND_IS_EQUAL_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_IS_EQUAL_SPEC_CV_CV_HANDLER,
  	ZEND_IS_NOT_EQUAL_SPEC_CONST_CONST_HANDLER,
  	ZEND_IS_NOT_EQUAL_SPEC_CONST_TMP_HANDLER,
  	ZEND_IS_NOT_EQUAL_SPEC_CONST_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_IS_NOT_EQUAL_SPEC_CONST_CV_HANDLER,
  	ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_HANDLER,
  	ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_HANDLER,
  	ZEND_IS_NOT_EQUAL_SPEC_TMP_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_IS_NOT_EQUAL_SPEC_TMP_CV_HANDLER,
  	ZEND_IS_NOT_EQUAL_SPEC_VAR_CONST_HANDLER,
  	ZEND_IS_NOT_EQUAL_SPEC_VAR_TMP_HANDLER,
  	ZEND_IS_NOT_EQUAL_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_IS_NOT_EQUAL_SPEC_VAR_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_HANDLER,
  	ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_HANDLER,
  	ZEND_IS_NOT_EQUAL_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_IS_NOT_EQUAL_SPEC_CV_CV_HANDLER,
  	ZEND_IS_SMALLER_SPEC_CONST_CONST_HANDLER,
  	ZEND_IS_SMALLER_SPEC_CONST_TMP_HANDLER,
  	ZEND_IS_SMALLER_SPEC_CONST_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_IS_SMALLER_SPEC_CONST_CV_HANDLER,
  	ZEND_IS_SMALLER_SPEC_TMP_CONST_HANDLER,
  	ZEND_IS_SMALLER_SPEC_TMP_TMP_HANDLER,
  	ZEND_IS_SMALLER_SPEC_TMP_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_IS_SMALLER_SPEC_TMP_CV_HANDLER,
  	ZEND_IS_SMALLER_SPEC_VAR_CONST_HANDLER,
  	ZEND_IS_SMALLER_SPEC_VAR_TMP_HANDLER,
  	ZEND_IS_SMALLER_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_IS_SMALLER_SPEC_VAR_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_IS_SMALLER_SPEC_CV_CONST_HANDLER,
  	ZEND_IS_SMALLER_SPEC_CV_TMP_HANDLER,
  	ZEND_IS_SMALLER_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_IS_SMALLER_SPEC_CV_CV_HANDLER,
  	ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_CONST_HANDLER,
  	ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMP_HANDLER,
  	ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_CV_HANDLER,
  	ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMP_CONST_HANDLER,
  	ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMP_TMP_HANDLER,
  	ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMP_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMP_CV_HANDLER,
  	ZEND_IS_SMALLER_OR_EQUAL_SPEC_VAR_CONST_HANDLER,
  	ZEND_IS_SMALLER_OR_EQUAL_SPEC_VAR_TMP_HANDLER,
  	ZEND_IS_SMALLER_OR_EQUAL_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_IS_SMALLER_OR_EQUAL_SPEC_VAR_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_CONST_HANDLER,
  	ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_TMP_HANDLER,
  	ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_CV_HANDLER,
  	ZEND_CAST_SPEC_CONST_HANDLER,
  	ZEND_CAST_SPEC_CONST_HANDLER,
  	ZEND_CAST_SPEC_CONST_HANDLER,
  	ZEND_CAST_SPEC_CONST_HANDLER,
  	ZEND_CAST_SPEC_CONST_HANDLER,
  	ZEND_CAST_SPEC_TMP_HANDLER,
  	ZEND_CAST_SPEC_TMP_HANDLER,
  	ZEND_CAST_SPEC_TMP_HANDLER,
  	ZEND_CAST_SPEC_TMP_HANDLER,
  	ZEND_CAST_SPEC_TMP_HANDLER,
  	ZEND_CAST_SPEC_VAR_HANDLER,
  	ZEND_CAST_SPEC_VAR_HANDLER,
  	ZEND_CAST_SPEC_VAR_HANDLER,
  	ZEND_CAST_SPEC_VAR_HANDLER,
  	ZEND_CAST_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_CAST_SPEC_CV_HANDLER,
  	ZEND_CAST_SPEC_CV_HANDLER,
  	ZEND_CAST_SPEC_CV_HANDLER,
  	ZEND_CAST_SPEC_CV_HANDLER,
  	ZEND_CAST_SPEC_CV_HANDLER,
  	ZEND_QM_ASSIGN_SPEC_CONST_HANDLER,
  	ZEND_QM_ASSIGN_SPEC_CONST_HANDLER,
  	ZEND_QM_ASSIGN_SPEC_CONST_HANDLER,
  	ZEND_QM_ASSIGN_SPEC_CONST_HANDLER,
  	ZEND_QM_ASSIGN_SPEC_CONST_HANDLER,
  	ZEND_QM_ASSIGN_SPEC_TMP_HANDLER,
  	ZEND_QM_ASSIGN_SPEC_TMP_HANDLER,
  	ZEND_QM_ASSIGN_SPEC_TMP_HANDLER,
  	ZEND_QM_ASSIGN_SPEC_TMP_HANDLER,
  	ZEND_QM_ASSIGN_SPEC_TMP_HANDLER,
  	ZEND_QM_ASSIGN_SPEC_VAR_HANDLER,
  	ZEND_QM_ASSIGN_SPEC_VAR_HANDLER,
  	ZEND_QM_ASSIGN_SPEC_VAR_HANDLER,
  	ZEND_QM_ASSIGN_SPEC_VAR_HANDLER,
  	ZEND_QM_ASSIGN_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_QM_ASSIGN_SPEC_CV_HANDLER,
  	ZEND_QM_ASSIGN_SPEC_CV_HANDLER,
  	ZEND_QM_ASSIGN_SPEC_CV_HANDLER,
  	ZEND_QM_ASSIGN_SPEC_CV_HANDLER,
  	ZEND_QM_ASSIGN_SPEC_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ASSIGN_ADD_SPEC_VAR_CONST_HANDLER,
  	ZEND_ASSIGN_ADD_SPEC_VAR_TMP_HANDLER,
  	ZEND_ASSIGN_ADD_SPEC_VAR_VAR_HANDLER,
  	ZEND_ASSIGN_ADD_SPEC_VAR_UNUSED_HANDLER,
  	ZEND_ASSIGN_ADD_SPEC_VAR_CV_HANDLER,
  	ZEND_ASSIGN_ADD_SPEC_UNUSED_CONST_HANDLER,
  	ZEND_ASSIGN_ADD_SPEC_UNUSED_TMP_HANDLER,
  	ZEND_ASSIGN_ADD_SPEC_UNUSED_VAR_HANDLER,
  	ZEND_ASSIGN_ADD_SPEC_UNUSED_UNUSED_HANDLER,
  	ZEND_ASSIGN_ADD_SPEC_UNUSED_CV_HANDLER,
  	ZEND_ASSIGN_ADD_SPEC_CV_CONST_HANDLER,
  	ZEND_ASSIGN_ADD_SPEC_CV_TMP_HANDLER,
  	ZEND_ASSIGN_ADD_SPEC_CV_VAR_HANDLER,
  	ZEND_ASSIGN_ADD_SPEC_CV_UNUSED_HANDLER,
  	ZEND_ASSIGN_ADD_SPEC_CV_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ASSIGN_SUB_SPEC_VAR_CONST_HANDLER,
  	ZEND_ASSIGN_SUB_SPEC_VAR_TMP_HANDLER,
  	ZEND_ASSIGN_SUB_SPEC_VAR_VAR_HANDLER,
  	ZEND_ASSIGN_SUB_SPEC_VAR_UNUSED_HANDLER,
  	ZEND_ASSIGN_SUB_SPEC_VAR_CV_HANDLER,
  	ZEND_ASSIGN_SUB_SPEC_UNUSED_CONST_HANDLER,
  	ZEND_ASSIGN_SUB_SPEC_UNUSED_TMP_HANDLER,
  	ZEND_ASSIGN_SUB_SPEC_UNUSED_VAR_HANDLER,
  	ZEND_ASSIGN_SUB_SPEC_UNUSED_UNUSED_HANDLER,
  	ZEND_ASSIGN_SUB_SPEC_UNUSED_CV_HANDLER,
  	ZEND_ASSIGN_SUB_SPEC_CV_CONST_HANDLER,
  	ZEND_ASSIGN_SUB_SPEC_CV_TMP_HANDLER,
  	ZEND_ASSIGN_SUB_SPEC_CV_VAR_HANDLER,
  	ZEND_ASSIGN_SUB_SPEC_CV_UNUSED_HANDLER,
  	ZEND_ASSIGN_SUB_SPEC_CV_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ASSIGN_MUL_SPEC_VAR_CONST_HANDLER,
  	ZEND_ASSIGN_MUL_SPEC_VAR_TMP_HANDLER,
  	ZEND_ASSIGN_MUL_SPEC_VAR_VAR_HANDLER,
  	ZEND_ASSIGN_MUL_SPEC_VAR_UNUSED_HANDLER,
  	ZEND_ASSIGN_MUL_SPEC_VAR_CV_HANDLER,
  	ZEND_ASSIGN_MUL_SPEC_UNUSED_CONST_HANDLER,
  	ZEND_ASSIGN_MUL_SPEC_UNUSED_TMP_HANDLER,
  	ZEND_ASSIGN_MUL_SPEC_UNUSED_VAR_HANDLER,
  	ZEND_ASSIGN_MUL_SPEC_UNUSED_UNUSED_HANDLER,
  	ZEND_ASSIGN_MUL_SPEC_UNUSED_CV_HANDLER,
  	ZEND_ASSIGN_MUL_SPEC_CV_CONST_HANDLER,
  	ZEND_ASSIGN_MUL_SPEC_CV_TMP_HANDLER,
  	ZEND_ASSIGN_MUL_SPEC_CV_VAR_HANDLER,
  	ZEND_ASSIGN_MUL_SPEC_CV_UNUSED_HANDLER,
  	ZEND_ASSIGN_MUL_SPEC_CV_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ASSIGN_DIV_SPEC_VAR_CONST_HANDLER,
  	ZEND_ASSIGN_DIV_SPEC_VAR_TMP_HANDLER,
  	ZEND_ASSIGN_DIV_SPEC_VAR_VAR_HANDLER,
  	ZEND_ASSIGN_DIV_SPEC_VAR_UNUSED_HANDLER,
  	ZEND_ASSIGN_DIV_SPEC_VAR_CV_HANDLER,
  	ZEND_ASSIGN_DIV_SPEC_UNUSED_CONST_HANDLER,
  	ZEND_ASSIGN_DIV_SPEC_UNUSED_TMP_HANDLER,
  	ZEND_ASSIGN_DIV_SPEC_UNUSED_VAR_HANDLER,
  	ZEND_ASSIGN_DIV_SPEC_UNUSED_UNUSED_HANDLER,
  	ZEND_ASSIGN_DIV_SPEC_UNUSED_CV_HANDLER,
  	ZEND_ASSIGN_DIV_SPEC_CV_CONST_HANDLER,
  	ZEND_ASSIGN_DIV_SPEC_CV_TMP_HANDLER,
  	ZEND_ASSIGN_DIV_SPEC_CV_VAR_HANDLER,
  	ZEND_ASSIGN_DIV_SPEC_CV_UNUSED_HANDLER,
  	ZEND_ASSIGN_DIV_SPEC_CV_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ASSIGN_MOD_SPEC_VAR_CONST_HANDLER,
  	ZEND_ASSIGN_MOD_SPEC_VAR_TMP_HANDLER,
  	ZEND_ASSIGN_MOD_SPEC_VAR_VAR_HANDLER,
  	ZEND_ASSIGN_MOD_SPEC_VAR_UNUSED_HANDLER,
  	ZEND_ASSIGN_MOD_SPEC_VAR_CV_HANDLER,
  	ZEND_ASSIGN_MOD_SPEC_UNUSED_CONST_HANDLER,
  	ZEND_ASSIGN_MOD_SPEC_UNUSED_TMP_HANDLER,
  	ZEND_ASSIGN_MOD_SPEC_UNUSED_VAR_HANDLER,
  	ZEND_ASSIGN_MOD_SPEC_UNUSED_UNUSED_HANDLER,
  	ZEND_ASSIGN_MOD_SPEC_UNUSED_CV_HANDLER,
  	ZEND_ASSIGN_MOD_SPEC_CV_CONST_HANDLER,
  	ZEND_ASSIGN_MOD_SPEC_CV_TMP_HANDLER,
  	ZEND_ASSIGN_MOD_SPEC_CV_VAR_HANDLER,
  	ZEND_ASSIGN_MOD_SPEC_CV_UNUSED_HANDLER,
  	ZEND_ASSIGN_MOD_SPEC_CV_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ASSIGN_SL_SPEC_VAR_CONST_HANDLER,
  	ZEND_ASSIGN_SL_SPEC_VAR_TMP_HANDLER,
  	ZEND_ASSIGN_SL_SPEC_VAR_VAR_HANDLER,
  	ZEND_ASSIGN_SL_SPEC_VAR_UNUSED_HANDLER,
  	ZEND_ASSIGN_SL_SPEC_VAR_CV_HANDLER,
  	ZEND_ASSIGN_SL_SPEC_UNUSED_CONST_HANDLER,
  	ZEND_ASSIGN_SL_SPEC_UNUSED_TMP_HANDLER,
  	ZEND_ASSIGN_SL_SPEC_UNUSED_VAR_HANDLER,
  	ZEND_ASSIGN_SL_SPEC_UNUSED_UNUSED_HANDLER,
  	ZEND_ASSIGN_SL_SPEC_UNUSED_CV_HANDLER,
  	ZEND_ASSIGN_SL_SPEC_CV_CONST_HANDLER,
  	ZEND_ASSIGN_SL_SPEC_CV_TMP_HANDLER,
  	ZEND_ASSIGN_SL_SPEC_CV_VAR_HANDLER,
  	ZEND_ASSIGN_SL_SPEC_CV_UNUSED_HANDLER,
  	ZEND_ASSIGN_SL_SPEC_CV_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ASSIGN_SR_SPEC_VAR_CONST_HANDLER,
  	ZEND_ASSIGN_SR_SPEC_VAR_TMP_HANDLER,
  	ZEND_ASSIGN_SR_SPEC_VAR_VAR_HANDLER,
  	ZEND_ASSIGN_SR_SPEC_VAR_UNUSED_HANDLER,
  	ZEND_ASSIGN_SR_SPEC_VAR_CV_HANDLER,
  	ZEND_ASSIGN_SR_SPEC_UNUSED_CONST_HANDLER,
  	ZEND_ASSIGN_SR_SPEC_UNUSED_TMP_HANDLER,
  	ZEND_ASSIGN_SR_SPEC_UNUSED_VAR_HANDLER,
  	ZEND_ASSIGN_SR_SPEC_UNUSED_UNUSED_HANDLER,
  	ZEND_ASSIGN_SR_SPEC_UNUSED_CV_HANDLER,
  	ZEND_ASSIGN_SR_SPEC_CV_CONST_HANDLER,
  	ZEND_ASSIGN_SR_SPEC_CV_TMP_HANDLER,
  	ZEND_ASSIGN_SR_SPEC_CV_VAR_HANDLER,
  	ZEND_ASSIGN_SR_SPEC_CV_UNUSED_HANDLER,
  	ZEND_ASSIGN_SR_SPEC_CV_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ASSIGN_CONCAT_SPEC_VAR_CONST_HANDLER,
  	ZEND_ASSIGN_CONCAT_SPEC_VAR_TMP_HANDLER,
  	ZEND_ASSIGN_CONCAT_SPEC_VAR_VAR_HANDLER,
  	ZEND_ASSIGN_CONCAT_SPEC_VAR_UNUSED_HANDLER,
  	ZEND_ASSIGN_CONCAT_SPEC_VAR_CV_HANDLER,
  	ZEND_ASSIGN_CONCAT_SPEC_UNUSED_CONST_HANDLER,
  	ZEND_ASSIGN_CONCAT_SPEC_UNUSED_TMP_HANDLER,
  	ZEND_ASSIGN_CONCAT_SPEC_UNUSED_VAR_HANDLER,
  	ZEND_ASSIGN_CONCAT_SPEC_UNUSED_UNUSED_HANDLER,
  	ZEND_ASSIGN_CONCAT_SPEC_UNUSED_CV_HANDLER,
  	ZEND_ASSIGN_CONCAT_SPEC_CV_CONST_HANDLER,
  	ZEND_ASSIGN_CONCAT_SPEC_CV_TMP_HANDLER,
  	ZEND_ASSIGN_CONCAT_SPEC_CV_VAR_HANDLER,
  	ZEND_ASSIGN_CONCAT_SPEC_CV_UNUSED_HANDLER,
  	ZEND_ASSIGN_CONCAT_SPEC_CV_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ASSIGN_BW_OR_SPEC_VAR_CONST_HANDLER,
  	ZEND_ASSIGN_BW_OR_SPEC_VAR_TMP_HANDLER,
  	ZEND_ASSIGN_BW_OR_SPEC_VAR_VAR_HANDLER,
  	ZEND_ASSIGN_BW_OR_SPEC_VAR_UNUSED_HANDLER,
  	ZEND_ASSIGN_BW_OR_SPEC_VAR_CV_HANDLER,
  	ZEND_ASSIGN_BW_OR_SPEC_UNUSED_CONST_HANDLER,
  	ZEND_ASSIGN_BW_OR_SPEC_UNUSED_TMP_HANDLER,
  	ZEND_ASSIGN_BW_OR_SPEC_UNUSED_VAR_HANDLER,
  	ZEND_ASSIGN_BW_OR_SPEC_UNUSED_UNUSED_HANDLER,
  	ZEND_ASSIGN_BW_OR_SPEC_UNUSED_CV_HANDLER,
  	ZEND_ASSIGN_BW_OR_SPEC_CV_CONST_HANDLER,
  	ZEND_ASSIGN_BW_OR_SPEC_CV_TMP_HANDLER,
  	ZEND_ASSIGN_BW_OR_SPEC_CV_VAR_HANDLER,
  	ZEND_ASSIGN_BW_OR_SPEC_CV_UNUSED_HANDLER,
  	ZEND_ASSIGN_BW_OR_SPEC_CV_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ASSIGN_BW_AND_SPEC_VAR_CONST_HANDLER,
  	ZEND_ASSIGN_BW_AND_SPEC_VAR_TMP_HANDLER,
  	ZEND_ASSIGN_BW_AND_SPEC_VAR_VAR_HANDLER,
  	ZEND_ASSIGN_BW_AND_SPEC_VAR_UNUSED_HANDLER,
  	ZEND_ASSIGN_BW_AND_SPEC_VAR_CV_HANDLER,
  	ZEND_ASSIGN_BW_AND_SPEC_UNUSED_CONST_HANDLER,
  	ZEND_ASSIGN_BW_AND_SPEC_UNUSED_TMP_HANDLER,
  	ZEND_ASSIGN_BW_AND_SPEC_UNUSED_VAR_HANDLER,
  	ZEND_ASSIGN_BW_AND_SPEC_UNUSED_UNUSED_HANDLER,
  	ZEND_ASSIGN_BW_AND_SPEC_UNUSED_CV_HANDLER,
  	ZEND_ASSIGN_BW_AND_SPEC_CV_CONST_HANDLER,
  	ZEND_ASSIGN_BW_AND_SPEC_CV_TMP_HANDLER,
  	ZEND_ASSIGN_BW_AND_SPEC_CV_VAR_HANDLER,
  	ZEND_ASSIGN_BW_AND_SPEC_CV_UNUSED_HANDLER,
  	ZEND_ASSIGN_BW_AND_SPEC_CV_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ASSIGN_BW_XOR_SPEC_VAR_CONST_HANDLER,
  	ZEND_ASSIGN_BW_XOR_SPEC_VAR_TMP_HANDLER,
  	ZEND_ASSIGN_BW_XOR_SPEC_VAR_VAR_HANDLER,
  	ZEND_ASSIGN_BW_XOR_SPEC_VAR_UNUSED_HANDLER,
  	ZEND_ASSIGN_BW_XOR_SPEC_VAR_CV_HANDLER,
  	ZEND_ASSIGN_BW_XOR_SPEC_UNUSED_CONST_HANDLER,
  	ZEND_ASSIGN_BW_XOR_SPEC_UNUSED_TMP_HANDLER,
  	ZEND_ASSIGN_BW_XOR_SPEC_UNUSED_VAR_HANDLER,
  	ZEND_ASSIGN_BW_XOR_SPEC_UNUSED_UNUSED_HANDLER,
  	ZEND_ASSIGN_BW_XOR_SPEC_UNUSED_CV_HANDLER,
  	ZEND_ASSIGN_BW_XOR_SPEC_CV_CONST_HANDLER,
  	ZEND_ASSIGN_BW_XOR_SPEC_CV_TMP_HANDLER,
  	ZEND_ASSIGN_BW_XOR_SPEC_CV_VAR_HANDLER,
  	ZEND_ASSIGN_BW_XOR_SPEC_CV_UNUSED_HANDLER,
  	ZEND_ASSIGN_BW_XOR_SPEC_CV_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_PRE_INC_SPEC_VAR_HANDLER,
  	ZEND_PRE_INC_SPEC_VAR_HANDLER,
  	ZEND_PRE_INC_SPEC_VAR_HANDLER,
  	ZEND_PRE_INC_SPEC_VAR_HANDLER,
  	ZEND_PRE_INC_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_PRE_INC_SPEC_CV_HANDLER,
  	ZEND_PRE_INC_SPEC_CV_HANDLER,
  	ZEND_PRE_INC_SPEC_CV_HANDLER,
  	ZEND_PRE_INC_SPEC_CV_HANDLER,
  	ZEND_PRE_INC_SPEC_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_PRE_DEC_SPEC_VAR_HANDLER,
  	ZEND_PRE_DEC_SPEC_VAR_HANDLER,
  	ZEND_PRE_DEC_SPEC_VAR_HANDLER,
  	ZEND_PRE_DEC_SPEC_VAR_HANDLER,
  	ZEND_PRE_DEC_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_PRE_DEC_SPEC_CV_HANDLER,
  	ZEND_PRE_DEC_SPEC_CV_HANDLER,
  	ZEND_PRE_DEC_SPEC_CV_HANDLER,
  	ZEND_PRE_DEC_SPEC_CV_HANDLER,
  	ZEND_PRE_DEC_SPEC_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_POST_INC_SPEC_VAR_HANDLER,
  	ZEND_POST_INC_SPEC_VAR_HANDLER,
  	ZEND_POST_INC_SPEC_VAR_HANDLER,
  	ZEND_POST_INC_SPEC_VAR_HANDLER,
  	ZEND_POST_INC_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_POST_INC_SPEC_CV_HANDLER,
  	ZEND_POST_INC_SPEC_CV_HANDLER,
  	ZEND_POST_INC_SPEC_CV_HANDLER,
  	ZEND_POST_INC_SPEC_CV_HANDLER,
  	ZEND_POST_INC_SPEC_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_POST_DEC_SPEC_VAR_HANDLER,
  	ZEND_POST_DEC_SPEC_VAR_HANDLER,
  	ZEND_POST_DEC_SPEC_VAR_HANDLER,
  	ZEND_POST_DEC_SPEC_VAR_HANDLER,
  	ZEND_POST_DEC_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_POST_DEC_SPEC_CV_HANDLER,
  	ZEND_POST_DEC_SPEC_CV_HANDLER,
  	ZEND_POST_DEC_SPEC_CV_HANDLER,
  	ZEND_POST_DEC_SPEC_CV_HANDLER,
  	ZEND_POST_DEC_SPEC_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ASSIGN_SPEC_VAR_CONST_HANDLER,
  	ZEND_ASSIGN_SPEC_VAR_TMP_HANDLER,
  	ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ASSIGN_SPEC_VAR_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ASSIGN_SPEC_CV_CONST_HANDLER,
  	ZEND_ASSIGN_SPEC_CV_TMP_HANDLER,
  	ZEND_ASSIGN_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ASSIGN_SPEC_CV_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER,
  	ZEND_ECHO_SPEC_CONST_HANDLER,
  	ZEND_ECHO_SPEC_CONST_HANDLER,
  	ZEND_ECHO_SPEC_CONST_HANDLER,
  	ZEND_ECHO_SPEC_CONST_HANDLER,
  	ZEND_ECHO_SPEC_CONST_HANDLER,
  	ZEND_ECHO_SPEC_TMP_HANDLER,
  	ZEND_ECHO_SPEC_TMP_HANDLER,
  	ZEND_ECHO_SPEC_TMP_HANDLER,
  	ZEND_ECHO_SPEC_TMP_HANDLER,
  	ZEND_ECHO_SPEC_TMP_HANDLER,
  	ZEND_ECHO_SPEC_VAR_HANDLER,
  	ZEND_ECHO_SPEC_VAR_HANDLER,
  	ZEND_ECHO_SPEC_VAR_HANDLER,
  	ZEND_ECHO_SPEC_VAR_HANDLER,
  	ZEND_ECHO_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ECHO_SPEC_CV_HANDLER,
  	ZEND_ECHO_SPEC_CV_HANDLER,
  	ZEND_ECHO_SPEC_CV_HANDLER,
  	ZEND_ECHO_SPEC_CV_HANDLER,
  	ZEND_ECHO_SPEC_CV_HANDLER,
  	ZEND_PRINT_SPEC_CONST_HANDLER,
  	ZEND_PRINT_SPEC_CONST_HANDLER,
  	ZEND_PRINT_SPEC_CONST_HANDLER,
  	ZEND_PRINT_SPEC_CONST_HANDLER,
  	ZEND_PRINT_SPEC_CONST_HANDLER,
  	ZEND_PRINT_SPEC_TMP_HANDLER,
  	ZEND_PRINT_SPEC_TMP_HANDLER,
  	ZEND_PRINT_SPEC_TMP_HANDLER,
  	ZEND_PRINT_SPEC_TMP_HANDLER,
  	ZEND_PRINT_SPEC_TMP_HANDLER,
  	ZEND_PRINT_SPEC_VAR_HANDLER,
  	ZEND_PRINT_SPEC_VAR_HANDLER,
  	ZEND_PRINT_SPEC_VAR_HANDLER,
  	ZEND_PRINT_SPEC_VAR_HANDLER,
  	ZEND_PRINT_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_PRINT_SPEC_CV_HANDLER,
  	ZEND_PRINT_SPEC_CV_HANDLER,
  	ZEND_PRINT_SPEC_CV_HANDLER,
  	ZEND_PRINT_SPEC_CV_HANDLER,
  	ZEND_PRINT_SPEC_CV_HANDLER,
  	ZEND_JMP_SPEC_HANDLER,
  	ZEND_JMP_SPEC_HANDLER,
  	ZEND_JMP_SPEC_HANDLER,
  	ZEND_JMP_SPEC_HANDLER,
  	ZEND_JMP_SPEC_HANDLER,
  	ZEND_JMP_SPEC_HANDLER,
  	ZEND_JMP_SPEC_HANDLER,
  	ZEND_JMP_SPEC_HANDLER,
  	ZEND_JMP_SPEC_HANDLER,
  	ZEND_JMP_SPEC_HANDLER,
  	ZEND_JMP_SPEC_HANDLER,
  	ZEND_JMP_SPEC_HANDLER,
  	ZEND_JMP_SPEC_HANDLER,
  	ZEND_JMP_SPEC_HANDLER,
  	ZEND_JMP_SPEC_HANDLER,
  	ZEND_JMP_SPEC_HANDLER,
  	ZEND_JMP_SPEC_HANDLER,
  	ZEND_JMP_SPEC_HANDLER,
  	ZEND_JMP_SPEC_HANDLER,
  	ZEND_JMP_SPEC_HANDLER,
  	ZEND_JMP_SPEC_HANDLER,
  	ZEND_JMP_SPEC_HANDLER,
  	ZEND_JMP_SPEC_HANDLER,
  	ZEND_JMP_SPEC_HANDLER,
  	ZEND_JMP_SPEC_HANDLER,
  	ZEND_JMPZ_SPEC_CONST_HANDLER,
  	ZEND_JMPZ_SPEC_CONST_HANDLER,
  	ZEND_JMPZ_SPEC_CONST_HANDLER,
  	ZEND_JMPZ_SPEC_CONST_HANDLER,
  	ZEND_JMPZ_SPEC_CONST_HANDLER,
  	ZEND_JMPZ_SPEC_TMP_HANDLER,
  	ZEND_JMPZ_SPEC_TMP_HANDLER,
  	ZEND_JMPZ_SPEC_TMP_HANDLER,
  	ZEND_JMPZ_SPEC_TMP_HANDLER,
  	ZEND_JMPZ_SPEC_TMP_HANDLER,
  	ZEND_JMPZ_SPEC_VAR_HANDLER,
  	ZEND_JMPZ_SPEC_VAR_HANDLER,
  	ZEND_JMPZ_SPEC_VAR_HANDLER,
  	ZEND_JMPZ_SPEC_VAR_HANDLER,
  	ZEND_JMPZ_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_JMPZ_SPEC_CV_HANDLER,
  	ZEND_JMPZ_SPEC_CV_HANDLER,
  	ZEND_JMPZ_SPEC_CV_HANDLER,
  	ZEND_JMPZ_SPEC_CV_HANDLER,
  	ZEND_JMPZ_SPEC_CV_HANDLER,
  	ZEND_JMPNZ_SPEC_CONST_HANDLER,
  	ZEND_JMPNZ_SPEC_CONST_HANDLER,
  	ZEND_JMPNZ_SPEC_CONST_HANDLER,
  	ZEND_JMPNZ_SPEC_CONST_HANDLER,
  	ZEND_JMPNZ_SPEC_CONST_HANDLER,
  	ZEND_JMPNZ_SPEC_TMP_HANDLER,
  	ZEND_JMPNZ_SPEC_TMP_HANDLER,
  	ZEND_JMPNZ_SPEC_TMP_HANDLER,
  	ZEND_JMPNZ_SPEC_TMP_HANDLER,
  	ZEND_JMPNZ_SPEC_TMP_HANDLER,
  	ZEND_JMPNZ_SPEC_VAR_HANDLER,
  	ZEND_JMPNZ_SPEC_VAR_HANDLER,
  	ZEND_JMPNZ_SPEC_VAR_HANDLER,
  	ZEND_JMPNZ_SPEC_VAR_HANDLER,
  	ZEND_JMPNZ_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_JMPNZ_SPEC_CV_HANDLER,
  	ZEND_JMPNZ_SPEC_CV_HANDLER,
  	ZEND_JMPNZ_SPEC_CV_HANDLER,
  	ZEND_JMPNZ_SPEC_CV_HANDLER,
  	ZEND_JMPNZ_SPEC_CV_HANDLER,
  	ZEND_JMPZNZ_SPEC_CONST_HANDLER,
  	ZEND_JMPZNZ_SPEC_CONST_HANDLER,
  	ZEND_JMPZNZ_SPEC_CONST_HANDLER,
  	ZEND_JMPZNZ_SPEC_CONST_HANDLER,
  	ZEND_JMPZNZ_SPEC_CONST_HANDLER,
  	ZEND_JMPZNZ_SPEC_TMP_HANDLER,
  	ZEND_JMPZNZ_SPEC_TMP_HANDLER,
  	ZEND_JMPZNZ_SPEC_TMP_HANDLER,
  	ZEND_JMPZNZ_SPEC_TMP_HANDLER,
  	ZEND_JMPZNZ_SPEC_TMP_HANDLER,
  	ZEND_JMPZNZ_SPEC_VAR_HANDLER,
  	ZEND_JMPZNZ_SPEC_VAR_HANDLER,
  	ZEND_JMPZNZ_SPEC_VAR_HANDLER,
  	ZEND_JMPZNZ_SPEC_VAR_HANDLER,
  	ZEND_JMPZNZ_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_JMPZNZ_SPEC_CV_HANDLER,
  	ZEND_JMPZNZ_SPEC_CV_HANDLER,
  	ZEND_JMPZNZ_SPEC_CV_HANDLER,
  	ZEND_JMPZNZ_SPEC_CV_HANDLER,
  	ZEND_JMPZNZ_SPEC_CV_HANDLER,
  	ZEND_JMPZ_EX_SPEC_CONST_HANDLER,
  	ZEND_JMPZ_EX_SPEC_CONST_HANDLER,
  	ZEND_JMPZ_EX_SPEC_CONST_HANDLER,
  	ZEND_JMPZ_EX_SPEC_CONST_HANDLER,
  	ZEND_JMPZ_EX_SPEC_CONST_HANDLER,
  	ZEND_JMPZ_EX_SPEC_TMP_HANDLER,
  	ZEND_JMPZ_EX_SPEC_TMP_HANDLER,
  	ZEND_JMPZ_EX_SPEC_TMP_HANDLER,
  	ZEND_JMPZ_EX_SPEC_TMP_HANDLER,
  	ZEND_JMPZ_EX_SPEC_TMP_HANDLER,
  	ZEND_JMPZ_EX_SPEC_VAR_HANDLER,
  	ZEND_JMPZ_EX_SPEC_VAR_HANDLER,
  	ZEND_JMPZ_EX_SPEC_VAR_HANDLER,
  	ZEND_JMPZ_EX_SPEC_VAR_HANDLER,
  	ZEND_JMPZ_EX_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_JMPZ_EX_SPEC_CV_HANDLER,
  	ZEND_JMPZ_EX_SPEC_CV_HANDLER,
  	ZEND_JMPZ_EX_SPEC_CV_HANDLER,
  	ZEND_JMPZ_EX_SPEC_CV_HANDLER,
  	ZEND_JMPZ_EX_SPEC_CV_HANDLER,
  	ZEND_JMPNZ_EX_SPEC_CONST_HANDLER,
  	ZEND_JMPNZ_EX_SPEC_CONST_HANDLER,
  	ZEND_JMPNZ_EX_SPEC_CONST_HANDLER,
  	ZEND_JMPNZ_EX_SPEC_CONST_HANDLER,
  	ZEND_JMPNZ_EX_SPEC_CONST_HANDLER,
  	ZEND_JMPNZ_EX_SPEC_TMP_HANDLER,
  	ZEND_JMPNZ_EX_SPEC_TMP_HANDLER,
  	ZEND_JMPNZ_EX_SPEC_TMP_HANDLER,
  	ZEND_JMPNZ_EX_SPEC_TMP_HANDLER,
  	ZEND_JMPNZ_EX_SPEC_TMP_HANDLER,
  	ZEND_JMPNZ_EX_SPEC_VAR_HANDLER,
  	ZEND_JMPNZ_EX_SPEC_VAR_HANDLER,
  	ZEND_JMPNZ_EX_SPEC_VAR_HANDLER,
  	ZEND_JMPNZ_EX_SPEC_VAR_HANDLER,
  	ZEND_JMPNZ_EX_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_JMPNZ_EX_SPEC_CV_HANDLER,
  	ZEND_JMPNZ_EX_SPEC_CV_HANDLER,
  	ZEND_JMPNZ_EX_SPEC_CV_HANDLER,
  	ZEND_JMPNZ_EX_SPEC_CV_HANDLER,
  	ZEND_JMPNZ_EX_SPEC_CV_HANDLER,
  	ZEND_CASE_SPEC_CONST_CONST_HANDLER,
  	ZEND_CASE_SPEC_CONST_TMP_HANDLER,
  	ZEND_CASE_SPEC_CONST_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_CASE_SPEC_CONST_CV_HANDLER,
  	ZEND_CASE_SPEC_TMP_CONST_HANDLER,
  	ZEND_CASE_SPEC_TMP_TMP_HANDLER,
  	ZEND_CASE_SPEC_TMP_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_CASE_SPEC_TMP_CV_HANDLER,
  	ZEND_CASE_SPEC_VAR_CONST_HANDLER,
  	ZEND_CASE_SPEC_VAR_TMP_HANDLER,
  	ZEND_CASE_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_CASE_SPEC_VAR_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_CASE_SPEC_CV_CONST_HANDLER,
  	ZEND_CASE_SPEC_CV_TMP_HANDLER,
  	ZEND_CASE_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_CASE_SPEC_CV_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_SWITCH_FREE_SPEC_TMP_HANDLER,
  	ZEND_SWITCH_FREE_SPEC_TMP_HANDLER,
  	ZEND_SWITCH_FREE_SPEC_TMP_HANDLER,
  	ZEND_SWITCH_FREE_SPEC_TMP_HANDLER,
  	ZEND_SWITCH_FREE_SPEC_TMP_HANDLER,
  	ZEND_SWITCH_FREE_SPEC_VAR_HANDLER,
  	ZEND_SWITCH_FREE_SPEC_VAR_HANDLER,
  	ZEND_SWITCH_FREE_SPEC_VAR_HANDLER,
  	ZEND_SWITCH_FREE_SPEC_VAR_HANDLER,
  	ZEND_SWITCH_FREE_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_BRK_SPEC_CONST_HANDLER,
  	ZEND_BRK_SPEC_TMP_HANDLER,
  	ZEND_BRK_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_BRK_SPEC_CV_HANDLER,
  	ZEND_BRK_SPEC_CONST_HANDLER,
  	ZEND_BRK_SPEC_TMP_HANDLER,
  	ZEND_BRK_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_BRK_SPEC_CV_HANDLER,
  	ZEND_BRK_SPEC_CONST_HANDLER,
  	ZEND_BRK_SPEC_TMP_HANDLER,
  	ZEND_BRK_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_BRK_SPEC_CV_HANDLER,
  	ZEND_BRK_SPEC_CONST_HANDLER,
  	ZEND_BRK_SPEC_TMP_HANDLER,
  	ZEND_BRK_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_BRK_SPEC_CV_HANDLER,
  	ZEND_BRK_SPEC_CONST_HANDLER,
  	ZEND_BRK_SPEC_TMP_HANDLER,
  	ZEND_BRK_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_BRK_SPEC_CV_HANDLER,
  	ZEND_CONT_SPEC_CONST_HANDLER,
  	ZEND_CONT_SPEC_TMP_HANDLER,
  	ZEND_CONT_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_CONT_SPEC_CV_HANDLER,
  	ZEND_CONT_SPEC_CONST_HANDLER,
  	ZEND_CONT_SPEC_TMP_HANDLER,
  	ZEND_CONT_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_CONT_SPEC_CV_HANDLER,
  	ZEND_CONT_SPEC_CONST_HANDLER,
  	ZEND_CONT_SPEC_TMP_HANDLER,
  	ZEND_CONT_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_CONT_SPEC_CV_HANDLER,
  	ZEND_CONT_SPEC_CONST_HANDLER,
  	ZEND_CONT_SPEC_TMP_HANDLER,
  	ZEND_CONT_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_CONT_SPEC_CV_HANDLER,
  	ZEND_CONT_SPEC_CONST_HANDLER,
  	ZEND_CONT_SPEC_TMP_HANDLER,
  	ZEND_CONT_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_CONT_SPEC_CV_HANDLER,
  	ZEND_BOOL_SPEC_CONST_HANDLER,
  	ZEND_BOOL_SPEC_CONST_HANDLER,
  	ZEND_BOOL_SPEC_CONST_HANDLER,
  	ZEND_BOOL_SPEC_CONST_HANDLER,
  	ZEND_BOOL_SPEC_CONST_HANDLER,
  	ZEND_BOOL_SPEC_TMP_HANDLER,
  	ZEND_BOOL_SPEC_TMP_HANDLER,
  	ZEND_BOOL_SPEC_TMP_HANDLER,
  	ZEND_BOOL_SPEC_TMP_HANDLER,
  	ZEND_BOOL_SPEC_TMP_HANDLER,
  	ZEND_BOOL_SPEC_VAR_HANDLER,
  	ZEND_BOOL_SPEC_VAR_HANDLER,
  	ZEND_BOOL_SPEC_VAR_HANDLER,
  	ZEND_BOOL_SPEC_VAR_HANDLER,
  	ZEND_BOOL_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_BOOL_SPEC_CV_HANDLER,
  	ZEND_BOOL_SPEC_CV_HANDLER,
  	ZEND_BOOL_SPEC_CV_HANDLER,
  	ZEND_BOOL_SPEC_CV_HANDLER,
  	ZEND_BOOL_SPEC_CV_HANDLER,
  	ZEND_INIT_STRING_SPEC_HANDLER,
  	ZEND_INIT_STRING_SPEC_HANDLER,
  	ZEND_INIT_STRING_SPEC_HANDLER,
  	ZEND_INIT_STRING_SPEC_HANDLER,
  	ZEND_INIT_STRING_SPEC_HANDLER,
  	ZEND_INIT_STRING_SPEC_HANDLER,
  	ZEND_INIT_STRING_SPEC_HANDLER,
  	ZEND_INIT_STRING_SPEC_HANDLER,
  	ZEND_INIT_STRING_SPEC_HANDLER,
  	ZEND_INIT_STRING_SPEC_HANDLER,
  	ZEND_INIT_STRING_SPEC_HANDLER,
  	ZEND_INIT_STRING_SPEC_HANDLER,
  	ZEND_INIT_STRING_SPEC_HANDLER,
  	ZEND_INIT_STRING_SPEC_HANDLER,
  	ZEND_INIT_STRING_SPEC_HANDLER,
  	ZEND_INIT_STRING_SPEC_HANDLER,
  	ZEND_INIT_STRING_SPEC_HANDLER,
  	ZEND_INIT_STRING_SPEC_HANDLER,
  	ZEND_INIT_STRING_SPEC_HANDLER,
  	ZEND_INIT_STRING_SPEC_HANDLER,
  	ZEND_INIT_STRING_SPEC_HANDLER,
  	ZEND_INIT_STRING_SPEC_HANDLER,
  	ZEND_INIT_STRING_SPEC_HANDLER,
  	ZEND_INIT_STRING_SPEC_HANDLER,
  	ZEND_INIT_STRING_SPEC_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ADD_CHAR_SPEC_TMP_CONST_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ADD_STRING_SPEC_TMP_CONST_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ADD_VAR_SPEC_TMP_TMP_HANDLER,
  	ZEND_ADD_VAR_SPEC_TMP_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ADD_VAR_SPEC_TMP_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_BEGIN_SILENCE_SPEC_HANDLER,
  	ZEND_BEGIN_SILENCE_SPEC_HANDLER,
  	ZEND_BEGIN_SILENCE_SPEC_HANDLER,
  	ZEND_BEGIN_SILENCE_SPEC_HANDLER,
  	ZEND_BEGIN_SILENCE_SPEC_HANDLER,
  	ZEND_BEGIN_SILENCE_SPEC_HANDLER,
  	ZEND_BEGIN_SILENCE_SPEC_HANDLER,
  	ZEND_BEGIN_SILENCE_SPEC_HANDLER,
  	ZEND_BEGIN_SILENCE_SPEC_HANDLER,
  	ZEND_BEGIN_SILENCE_SPEC_HANDLER,
  	ZEND_BEGIN_SILENCE_SPEC_HANDLER,
  	ZEND_BEGIN_SILENCE_SPEC_HANDLER,
  	ZEND_BEGIN_SILENCE_SPEC_HANDLER,
  	ZEND_BEGIN_SILENCE_SPEC_HANDLER,
  	ZEND_BEGIN_SILENCE_SPEC_HANDLER,
  	ZEND_BEGIN_SILENCE_SPEC_HANDLER,
  	ZEND_BEGIN_SILENCE_SPEC_HANDLER,
  	ZEND_BEGIN_SILENCE_SPEC_HANDLER,
  	ZEND_BEGIN_SILENCE_SPEC_HANDLER,
  	ZEND_BEGIN_SILENCE_SPEC_HANDLER,
  	ZEND_BEGIN_SILENCE_SPEC_HANDLER,
  	ZEND_BEGIN_SILENCE_SPEC_HANDLER,
  	ZEND_BEGIN_SILENCE_SPEC_HANDLER,
  	ZEND_BEGIN_SILENCE_SPEC_HANDLER,
  	ZEND_BEGIN_SILENCE_SPEC_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_END_SILENCE_SPEC_TMP_HANDLER,
  	ZEND_END_SILENCE_SPEC_TMP_HANDLER,
  	ZEND_END_SILENCE_SPEC_TMP_HANDLER,
  	ZEND_END_SILENCE_SPEC_TMP_HANDLER,
  	ZEND_END_SILENCE_SPEC_TMP_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER,
  	ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER,
  	ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER,
  	ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER,
  	ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER,
  	ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER,
  	ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER,
  	ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER,
  	ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER,
  	ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER,
  	ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER,
  	ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER,
  	ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER,
  	ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER,
  	ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER,
  	ZEND_DO_FCALL_SPEC_CONST_HANDLER,
  	ZEND_DO_FCALL_SPEC_CONST_HANDLER,
  	ZEND_DO_FCALL_SPEC_CONST_HANDLER,
  	ZEND_DO_FCALL_SPEC_CONST_HANDLER,
  	ZEND_DO_FCALL_SPEC_CONST_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
  	ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
  	ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
  	ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
  	ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
  	ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
  	ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
  	ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
  	ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
  	ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
  	ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
  	ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
  	ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
  	ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
  	ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
  	ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
  	ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
  	ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
  	ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
  	ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
  	ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
  	ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
  	ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
  	ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
  	ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
  	ZEND_RETURN_SPEC_CONST_HANDLER,
  	ZEND_RETURN_SPEC_CONST_HANDLER,
  	ZEND_RETURN_SPEC_CONST_HANDLER,
  	ZEND_RETURN_SPEC_CONST_HANDLER,
  	ZEND_RETURN_SPEC_CONST_HANDLER,
  	ZEND_RETURN_SPEC_TMP_HANDLER,
  	ZEND_RETURN_SPEC_TMP_HANDLER,
  	ZEND_RETURN_SPEC_TMP_HANDLER,
  	ZEND_RETURN_SPEC_TMP_HANDLER,
  	ZEND_RETURN_SPEC_TMP_HANDLER,
  	ZEND_RETURN_SPEC_VAR_HANDLER,
  	ZEND_RETURN_SPEC_VAR_HANDLER,
  	ZEND_RETURN_SPEC_VAR_HANDLER,
  	ZEND_RETURN_SPEC_VAR_HANDLER,
  	ZEND_RETURN_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_RETURN_SPEC_CV_HANDLER,
  	ZEND_RETURN_SPEC_CV_HANDLER,
  	ZEND_RETURN_SPEC_CV_HANDLER,
  	ZEND_RETURN_SPEC_CV_HANDLER,
  	ZEND_RETURN_SPEC_CV_HANDLER,
  	ZEND_RECV_SPEC_HANDLER,
  	ZEND_RECV_SPEC_HANDLER,
  	ZEND_RECV_SPEC_HANDLER,
  	ZEND_RECV_SPEC_HANDLER,
  	ZEND_RECV_SPEC_HANDLER,
  	ZEND_RECV_SPEC_HANDLER,
  	ZEND_RECV_SPEC_HANDLER,
  	ZEND_RECV_SPEC_HANDLER,
  	ZEND_RECV_SPEC_HANDLER,
  	ZEND_RECV_SPEC_HANDLER,
  	ZEND_RECV_SPEC_HANDLER,
  	ZEND_RECV_SPEC_HANDLER,
  	ZEND_RECV_SPEC_HANDLER,
  	ZEND_RECV_SPEC_HANDLER,
  	ZEND_RECV_SPEC_HANDLER,
  	ZEND_RECV_SPEC_HANDLER,
  	ZEND_RECV_SPEC_HANDLER,
  	ZEND_RECV_SPEC_HANDLER,
  	ZEND_RECV_SPEC_HANDLER,
  	ZEND_RECV_SPEC_HANDLER,
  	ZEND_RECV_SPEC_HANDLER,
  	ZEND_RECV_SPEC_HANDLER,
  	ZEND_RECV_SPEC_HANDLER,
  	ZEND_RECV_SPEC_HANDLER,
  	ZEND_RECV_SPEC_HANDLER,
  	ZEND_RECV_INIT_SPEC_CONST_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_RECV_INIT_SPEC_CONST_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_RECV_INIT_SPEC_CONST_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_RECV_INIT_SPEC_CONST_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_RECV_INIT_SPEC_CONST_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_SEND_VAL_SPEC_CONST_HANDLER,
  	ZEND_SEND_VAL_SPEC_CONST_HANDLER,
  	ZEND_SEND_VAL_SPEC_CONST_HANDLER,
  	ZEND_SEND_VAL_SPEC_CONST_HANDLER,
  	ZEND_SEND_VAL_SPEC_CONST_HANDLER,
  	ZEND_SEND_VAL_SPEC_TMP_HANDLER,
  	ZEND_SEND_VAL_SPEC_TMP_HANDLER,
  	ZEND_SEND_VAL_SPEC_TMP_HANDLER,
  	ZEND_SEND_VAL_SPEC_TMP_HANDLER,
  	ZEND_SEND_VAL_SPEC_TMP_HANDLER,
  	ZEND_SEND_VAL_SPEC_VAR_HANDLER,
  	ZEND_SEND_VAL_SPEC_VAR_HANDLER,
  	ZEND_SEND_VAL_SPEC_VAR_HANDLER,
  	ZEND_SEND_VAL_SPEC_VAR_HANDLER,
  	ZEND_SEND_VAL_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_SEND_VAL_SPEC_CV_HANDLER,
  	ZEND_SEND_VAL_SPEC_CV_HANDLER,
  	ZEND_SEND_VAL_SPEC_CV_HANDLER,
  	ZEND_SEND_VAL_SPEC_CV_HANDLER,
  	ZEND_SEND_VAL_SPEC_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_SEND_VAR_SPEC_VAR_HANDLER,
  	ZEND_SEND_VAR_SPEC_VAR_HANDLER,
  	ZEND_SEND_VAR_SPEC_VAR_HANDLER,
  	ZEND_SEND_VAR_SPEC_VAR_HANDLER,
  	ZEND_SEND_VAR_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_SEND_VAR_SPEC_CV_HANDLER,
  	ZEND_SEND_VAR_SPEC_CV_HANDLER,
  	ZEND_SEND_VAR_SPEC_CV_HANDLER,
  	ZEND_SEND_VAR_SPEC_CV_HANDLER,
  	ZEND_SEND_VAR_SPEC_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_SEND_REF_SPEC_VAR_HANDLER,
  	ZEND_SEND_REF_SPEC_VAR_HANDLER,
  	ZEND_SEND_REF_SPEC_VAR_HANDLER,
  	ZEND_SEND_REF_SPEC_VAR_HANDLER,
  	ZEND_SEND_REF_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_SEND_REF_SPEC_CV_HANDLER,
  	ZEND_SEND_REF_SPEC_CV_HANDLER,
  	ZEND_SEND_REF_SPEC_CV_HANDLER,
  	ZEND_SEND_REF_SPEC_CV_HANDLER,
  	ZEND_SEND_REF_SPEC_CV_HANDLER,
  	ZEND_NEW_SPEC_HANDLER,
  	ZEND_NEW_SPEC_HANDLER,
  	ZEND_NEW_SPEC_HANDLER,
  	ZEND_NEW_SPEC_HANDLER,
  	ZEND_NEW_SPEC_HANDLER,
  	ZEND_NEW_SPEC_HANDLER,
  	ZEND_NEW_SPEC_HANDLER,
  	ZEND_NEW_SPEC_HANDLER,
  	ZEND_NEW_SPEC_HANDLER,
  	ZEND_NEW_SPEC_HANDLER,
  	ZEND_NEW_SPEC_HANDLER,
  	ZEND_NEW_SPEC_HANDLER,
  	ZEND_NEW_SPEC_HANDLER,
  	ZEND_NEW_SPEC_HANDLER,
  	ZEND_NEW_SPEC_HANDLER,
  	ZEND_NEW_SPEC_HANDLER,
  	ZEND_NEW_SPEC_HANDLER,
  	ZEND_NEW_SPEC_HANDLER,
  	ZEND_NEW_SPEC_HANDLER,
  	ZEND_NEW_SPEC_HANDLER,
  	ZEND_NEW_SPEC_HANDLER,
  	ZEND_NEW_SPEC_HANDLER,
  	ZEND_NEW_SPEC_HANDLER,
  	ZEND_NEW_SPEC_HANDLER,
  	ZEND_NEW_SPEC_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FREE_SPEC_TMP_HANDLER,
  	ZEND_FREE_SPEC_TMP_HANDLER,
  	ZEND_FREE_SPEC_TMP_HANDLER,
  	ZEND_FREE_SPEC_TMP_HANDLER,
  	ZEND_FREE_SPEC_TMP_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_INIT_ARRAY_SPEC_CONST_CONST_HANDLER,
  	ZEND_INIT_ARRAY_SPEC_CONST_TMP_HANDLER,
  	ZEND_INIT_ARRAY_SPEC_CONST_VAR_HANDLER,
  	ZEND_INIT_ARRAY_SPEC_CONST_UNUSED_HANDLER,
  	ZEND_INIT_ARRAY_SPEC_CONST_CV_HANDLER,
  	ZEND_INIT_ARRAY_SPEC_TMP_CONST_HANDLER,
  	ZEND_INIT_ARRAY_SPEC_TMP_TMP_HANDLER,
  	ZEND_INIT_ARRAY_SPEC_TMP_VAR_HANDLER,
  	ZEND_INIT_ARRAY_SPEC_TMP_UNUSED_HANDLER,
  	ZEND_INIT_ARRAY_SPEC_TMP_CV_HANDLER,
  	ZEND_INIT_ARRAY_SPEC_VAR_CONST_HANDLER,
  	ZEND_INIT_ARRAY_SPEC_VAR_TMP_HANDLER,
  	ZEND_INIT_ARRAY_SPEC_VAR_VAR_HANDLER,
  	ZEND_INIT_ARRAY_SPEC_VAR_UNUSED_HANDLER,
  	ZEND_INIT_ARRAY_SPEC_VAR_CV_HANDLER,
  	ZEND_INIT_ARRAY_SPEC_UNUSED_CONST_HANDLER,
  	ZEND_INIT_ARRAY_SPEC_UNUSED_TMP_HANDLER,
  	ZEND_INIT_ARRAY_SPEC_UNUSED_VAR_HANDLER,
  	ZEND_INIT_ARRAY_SPEC_UNUSED_UNUSED_HANDLER,
  	ZEND_INIT_ARRAY_SPEC_UNUSED_CV_HANDLER,
  	ZEND_INIT_ARRAY_SPEC_CV_CONST_HANDLER,
  	ZEND_INIT_ARRAY_SPEC_CV_TMP_HANDLER,
  	ZEND_INIT_ARRAY_SPEC_CV_VAR_HANDLER,
  	ZEND_INIT_ARRAY_SPEC_CV_UNUSED_HANDLER,
  	ZEND_INIT_ARRAY_SPEC_CV_CV_HANDLER,
  	ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER,
  	ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP_HANDLER,
  	ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_VAR_HANDLER,
  	ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER,
  	ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER,
  	ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER,
  	ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_HANDLER,
  	ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_VAR_HANDLER,
  	ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER,
  	ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER,
  	ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER,
  	ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_HANDLER,
  	ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_VAR_HANDLER,
  	ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER,
  	ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER,
  	ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_HANDLER,
  	ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_VAR_HANDLER,
  	ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER,
  	ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER,
  	ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER,
  	ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER,
  	ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER,
  	ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER,
  	ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER,
  	ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER,
  	ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER,
  	ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER,
  	ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER,
  	ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER,
  	ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER,
  	ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER,
  	ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER,
  	ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER,
  	ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER,
  	ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER,
  	ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER,
  	ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER,
  	ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER,
  	ZEND_UNSET_VAR_SPEC_CONST_HANDLER,
  	ZEND_UNSET_VAR_SPEC_CONST_HANDLER,
  	ZEND_UNSET_VAR_SPEC_CONST_HANDLER,
  	ZEND_UNSET_VAR_SPEC_CONST_HANDLER,
  	ZEND_UNSET_VAR_SPEC_CONST_HANDLER,
  	ZEND_UNSET_VAR_SPEC_TMP_HANDLER,
  	ZEND_UNSET_VAR_SPEC_TMP_HANDLER,
  	ZEND_UNSET_VAR_SPEC_TMP_HANDLER,
  	ZEND_UNSET_VAR_SPEC_TMP_HANDLER,
  	ZEND_UNSET_VAR_SPEC_TMP_HANDLER,
  	ZEND_UNSET_VAR_SPEC_VAR_HANDLER,
  	ZEND_UNSET_VAR_SPEC_VAR_HANDLER,
  	ZEND_UNSET_VAR_SPEC_VAR_HANDLER,
  	ZEND_UNSET_VAR_SPEC_VAR_HANDLER,
  	ZEND_UNSET_VAR_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_UNSET_VAR_SPEC_CV_HANDLER,
  	ZEND_UNSET_VAR_SPEC_CV_HANDLER,
  	ZEND_UNSET_VAR_SPEC_CV_HANDLER,
  	ZEND_UNSET_VAR_SPEC_CV_HANDLER,
  	ZEND_UNSET_VAR_SPEC_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_UNSET_DIM_SPEC_VAR_CONST_HANDLER,
  	ZEND_UNSET_DIM_SPEC_VAR_TMP_HANDLER,
  	ZEND_UNSET_DIM_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_UNSET_DIM_SPEC_VAR_CV_HANDLER,
  	ZEND_UNSET_DIM_SPEC_UNUSED_CONST_HANDLER,
  	ZEND_UNSET_DIM_SPEC_UNUSED_TMP_HANDLER,
  	ZEND_UNSET_DIM_SPEC_UNUSED_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_UNSET_DIM_SPEC_UNUSED_CV_HANDLER,
  	ZEND_UNSET_DIM_SPEC_CV_CONST_HANDLER,
  	ZEND_UNSET_DIM_SPEC_CV_TMP_HANDLER,
  	ZEND_UNSET_DIM_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_UNSET_DIM_SPEC_CV_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_UNSET_OBJ_SPEC_VAR_CONST_HANDLER,
  	ZEND_UNSET_OBJ_SPEC_VAR_TMP_HANDLER,
  	ZEND_UNSET_OBJ_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_UNSET_OBJ_SPEC_VAR_CV_HANDLER,
  	ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_HANDLER,
  	ZEND_UNSET_OBJ_SPEC_UNUSED_TMP_HANDLER,
  	ZEND_UNSET_OBJ_SPEC_UNUSED_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_UNSET_OBJ_SPEC_UNUSED_CV_HANDLER,
  	ZEND_UNSET_OBJ_SPEC_CV_CONST_HANDLER,
  	ZEND_UNSET_OBJ_SPEC_CV_TMP_HANDLER,
  	ZEND_UNSET_OBJ_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_UNSET_OBJ_SPEC_CV_CV_HANDLER,
  	ZEND_FE_RESET_SPEC_CONST_HANDLER,
  	ZEND_FE_RESET_SPEC_CONST_HANDLER,
  	ZEND_FE_RESET_SPEC_CONST_HANDLER,
  	ZEND_FE_RESET_SPEC_CONST_HANDLER,
  	ZEND_FE_RESET_SPEC_CONST_HANDLER,
  	ZEND_FE_RESET_SPEC_TMP_HANDLER,
  	ZEND_FE_RESET_SPEC_TMP_HANDLER,
  	ZEND_FE_RESET_SPEC_TMP_HANDLER,
  	ZEND_FE_RESET_SPEC_TMP_HANDLER,
  	ZEND_FE_RESET_SPEC_TMP_HANDLER,
  	ZEND_FE_RESET_SPEC_VAR_HANDLER,
  	ZEND_FE_RESET_SPEC_VAR_HANDLER,
  	ZEND_FE_RESET_SPEC_VAR_HANDLER,
  	ZEND_FE_RESET_SPEC_VAR_HANDLER,
  	ZEND_FE_RESET_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FE_RESET_SPEC_CV_HANDLER,
  	ZEND_FE_RESET_SPEC_CV_HANDLER,
  	ZEND_FE_RESET_SPEC_CV_HANDLER,
  	ZEND_FE_RESET_SPEC_CV_HANDLER,
  	ZEND_FE_RESET_SPEC_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FE_FETCH_SPEC_VAR_HANDLER,
  	ZEND_FE_FETCH_SPEC_VAR_HANDLER,
  	ZEND_FE_FETCH_SPEC_VAR_HANDLER,
  	ZEND_FE_FETCH_SPEC_VAR_HANDLER,
  	ZEND_FE_FETCH_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_EXIT_SPEC_CONST_HANDLER,
  	ZEND_EXIT_SPEC_CONST_HANDLER,
  	ZEND_EXIT_SPEC_CONST_HANDLER,
  	ZEND_EXIT_SPEC_CONST_HANDLER,
  	ZEND_EXIT_SPEC_CONST_HANDLER,
  	ZEND_EXIT_SPEC_TMP_HANDLER,
  	ZEND_EXIT_SPEC_TMP_HANDLER,
  	ZEND_EXIT_SPEC_TMP_HANDLER,
  	ZEND_EXIT_SPEC_TMP_HANDLER,
  	ZEND_EXIT_SPEC_TMP_HANDLER,
  	ZEND_EXIT_SPEC_VAR_HANDLER,
  	ZEND_EXIT_SPEC_VAR_HANDLER,
  	ZEND_EXIT_SPEC_VAR_HANDLER,
  	ZEND_EXIT_SPEC_VAR_HANDLER,
  	ZEND_EXIT_SPEC_VAR_HANDLER,
  	ZEND_EXIT_SPEC_UNUSED_HANDLER,
  	ZEND_EXIT_SPEC_UNUSED_HANDLER,
  	ZEND_EXIT_SPEC_UNUSED_HANDLER,
  	ZEND_EXIT_SPEC_UNUSED_HANDLER,
  	ZEND_EXIT_SPEC_UNUSED_HANDLER,
  	ZEND_EXIT_SPEC_CV_HANDLER,
  	ZEND_EXIT_SPEC_CV_HANDLER,
  	ZEND_EXIT_SPEC_CV_HANDLER,
  	ZEND_EXIT_SPEC_CV_HANDLER,
  	ZEND_EXIT_SPEC_CV_HANDLER,
  	ZEND_FETCH_R_SPEC_CONST_HANDLER,
  	ZEND_FETCH_R_SPEC_CONST_HANDLER,
  	ZEND_FETCH_R_SPEC_CONST_HANDLER,
  	ZEND_FETCH_R_SPEC_CONST_HANDLER,
  	ZEND_FETCH_R_SPEC_CONST_HANDLER,
  	ZEND_FETCH_R_SPEC_TMP_HANDLER,
  	ZEND_FETCH_R_SPEC_TMP_HANDLER,
  	ZEND_FETCH_R_SPEC_TMP_HANDLER,
  	ZEND_FETCH_R_SPEC_TMP_HANDLER,
  	ZEND_FETCH_R_SPEC_TMP_HANDLER,
  	ZEND_FETCH_R_SPEC_VAR_HANDLER,
  	ZEND_FETCH_R_SPEC_VAR_HANDLER,
  	ZEND_FETCH_R_SPEC_VAR_HANDLER,
  	ZEND_FETCH_R_SPEC_VAR_HANDLER,
  	ZEND_FETCH_R_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_R_SPEC_CV_HANDLER,
  	ZEND_FETCH_R_SPEC_CV_HANDLER,
  	ZEND_FETCH_R_SPEC_CV_HANDLER,
  	ZEND_FETCH_R_SPEC_CV_HANDLER,
  	ZEND_FETCH_R_SPEC_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_DIM_R_SPEC_VAR_CONST_HANDLER,
  	ZEND_FETCH_DIM_R_SPEC_VAR_TMP_HANDLER,
  	ZEND_FETCH_DIM_R_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_DIM_R_SPEC_VAR_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_DIM_R_SPEC_CV_CONST_HANDLER,
  	ZEND_FETCH_DIM_R_SPEC_CV_TMP_HANDLER,
  	ZEND_FETCH_DIM_R_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_OBJ_R_SPEC_VAR_CONST_HANDLER,
  	ZEND_FETCH_OBJ_R_SPEC_VAR_TMP_HANDLER,
  	ZEND_FETCH_OBJ_R_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_OBJ_R_SPEC_VAR_CV_HANDLER,
  	ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_HANDLER,
  	ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMP_HANDLER,
  	ZEND_FETCH_OBJ_R_SPEC_UNUSED_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HANDLER,
  	ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HANDLER,
  	ZEND_FETCH_OBJ_R_SPEC_CV_TMP_HANDLER,
  	ZEND_FETCH_OBJ_R_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER,
  	ZEND_FETCH_W_SPEC_CONST_HANDLER,
  	ZEND_FETCH_W_SPEC_CONST_HANDLER,
  	ZEND_FETCH_W_SPEC_CONST_HANDLER,
  	ZEND_FETCH_W_SPEC_CONST_HANDLER,
  	ZEND_FETCH_W_SPEC_CONST_HANDLER,
  	ZEND_FETCH_W_SPEC_TMP_HANDLER,
  	ZEND_FETCH_W_SPEC_TMP_HANDLER,
  	ZEND_FETCH_W_SPEC_TMP_HANDLER,
  	ZEND_FETCH_W_SPEC_TMP_HANDLER,
  	ZEND_FETCH_W_SPEC_TMP_HANDLER,
  	ZEND_FETCH_W_SPEC_VAR_HANDLER,
  	ZEND_FETCH_W_SPEC_VAR_HANDLER,
  	ZEND_FETCH_W_SPEC_VAR_HANDLER,
  	ZEND_FETCH_W_SPEC_VAR_HANDLER,
  	ZEND_FETCH_W_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_W_SPEC_CV_HANDLER,
  	ZEND_FETCH_W_SPEC_CV_HANDLER,
  	ZEND_FETCH_W_SPEC_CV_HANDLER,
  	ZEND_FETCH_W_SPEC_CV_HANDLER,
  	ZEND_FETCH_W_SPEC_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER,
  	ZEND_FETCH_DIM_W_SPEC_VAR_TMP_HANDLER,
  	ZEND_FETCH_DIM_W_SPEC_VAR_VAR_HANDLER,
  	ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER,
  	ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_DIM_W_SPEC_CV_CONST_HANDLER,
  	ZEND_FETCH_DIM_W_SPEC_CV_TMP_HANDLER,
  	ZEND_FETCH_DIM_W_SPEC_CV_VAR_HANDLER,
  	ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER,
  	ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER,
  	ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_HANDLER,
  	ZEND_FETCH_OBJ_W_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER,
  	ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER,
  	ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP_HANDLER,
  	ZEND_FETCH_OBJ_W_SPEC_UNUSED_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HANDLER,
  	ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HANDLER,
  	ZEND_FETCH_OBJ_W_SPEC_CV_TMP_HANDLER,
  	ZEND_FETCH_OBJ_W_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER,
  	ZEND_FETCH_RW_SPEC_CONST_HANDLER,
  	ZEND_FETCH_RW_SPEC_CONST_HANDLER,
  	ZEND_FETCH_RW_SPEC_CONST_HANDLER,
  	ZEND_FETCH_RW_SPEC_CONST_HANDLER,
  	ZEND_FETCH_RW_SPEC_CONST_HANDLER,
  	ZEND_FETCH_RW_SPEC_TMP_HANDLER,
  	ZEND_FETCH_RW_SPEC_TMP_HANDLER,
  	ZEND_FETCH_RW_SPEC_TMP_HANDLER,
  	ZEND_FETCH_RW_SPEC_TMP_HANDLER,
  	ZEND_FETCH_RW_SPEC_TMP_HANDLER,
  	ZEND_FETCH_RW_SPEC_VAR_HANDLER,
  	ZEND_FETCH_RW_SPEC_VAR_HANDLER,
  	ZEND_FETCH_RW_SPEC_VAR_HANDLER,
  	ZEND_FETCH_RW_SPEC_VAR_HANDLER,
  	ZEND_FETCH_RW_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_RW_SPEC_CV_HANDLER,
  	ZEND_FETCH_RW_SPEC_CV_HANDLER,
  	ZEND_FETCH_RW_SPEC_CV_HANDLER,
  	ZEND_FETCH_RW_SPEC_CV_HANDLER,
  	ZEND_FETCH_RW_SPEC_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_HANDLER,
  	ZEND_FETCH_DIM_RW_SPEC_VAR_TMP_HANDLER,
  	ZEND_FETCH_DIM_RW_SPEC_VAR_VAR_HANDLER,
  	ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_HANDLER,
  	ZEND_FETCH_DIM_RW_SPEC_VAR_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_DIM_RW_SPEC_CV_CONST_HANDLER,
  	ZEND_FETCH_DIM_RW_SPEC_CV_TMP_HANDLER,
  	ZEND_FETCH_DIM_RW_SPEC_CV_VAR_HANDLER,
  	ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_HANDLER,
  	ZEND_FETCH_DIM_RW_SPEC_CV_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_HANDLER,
  	ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP_HANDLER,
  	ZEND_FETCH_OBJ_RW_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_HANDLER,
  	ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST_HANDLER,
  	ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMP_HANDLER,
  	ZEND_FETCH_OBJ_RW_SPEC_UNUSED_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV_HANDLER,
  	ZEND_FETCH_OBJ_RW_SPEC_CV_CONST_HANDLER,
  	ZEND_FETCH_OBJ_RW_SPEC_CV_TMP_HANDLER,
  	ZEND_FETCH_OBJ_RW_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_OBJ_RW_SPEC_CV_CV_HANDLER,
  	ZEND_FETCH_IS_SPEC_CONST_HANDLER,
  	ZEND_FETCH_IS_SPEC_CONST_HANDLER,
  	ZEND_FETCH_IS_SPEC_CONST_HANDLER,
  	ZEND_FETCH_IS_SPEC_CONST_HANDLER,
  	ZEND_FETCH_IS_SPEC_CONST_HANDLER,
  	ZEND_FETCH_IS_SPEC_TMP_HANDLER,
  	ZEND_FETCH_IS_SPEC_TMP_HANDLER,
  	ZEND_FETCH_IS_SPEC_TMP_HANDLER,
  	ZEND_FETCH_IS_SPEC_TMP_HANDLER,
  	ZEND_FETCH_IS_SPEC_TMP_HANDLER,
  	ZEND_FETCH_IS_SPEC_VAR_HANDLER,
  	ZEND_FETCH_IS_SPEC_VAR_HANDLER,
  	ZEND_FETCH_IS_SPEC_VAR_HANDLER,
  	ZEND_FETCH_IS_SPEC_VAR_HANDLER,
  	ZEND_FETCH_IS_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_IS_SPEC_CV_HANDLER,
  	ZEND_FETCH_IS_SPEC_CV_HANDLER,
  	ZEND_FETCH_IS_SPEC_CV_HANDLER,
  	ZEND_FETCH_IS_SPEC_CV_HANDLER,
  	ZEND_FETCH_IS_SPEC_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_DIM_IS_SPEC_VAR_CONST_HANDLER,
  	ZEND_FETCH_DIM_IS_SPEC_VAR_TMP_HANDLER,
  	ZEND_FETCH_DIM_IS_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_DIM_IS_SPEC_VAR_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_DIM_IS_SPEC_CV_CONST_HANDLER,
  	ZEND_FETCH_DIM_IS_SPEC_CV_TMP_HANDLER,
  	ZEND_FETCH_DIM_IS_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_DIM_IS_SPEC_CV_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_OBJ_IS_SPEC_VAR_CONST_HANDLER,
  	ZEND_FETCH_OBJ_IS_SPEC_VAR_TMP_HANDLER,
  	ZEND_FETCH_OBJ_IS_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_OBJ_IS_SPEC_VAR_CV_HANDLER,
  	ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST_HANDLER,
  	ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMP_HANDLER,
  	ZEND_FETCH_OBJ_IS_SPEC_UNUSED_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_HANDLER,
  	ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HANDLER,
  	ZEND_FETCH_OBJ_IS_SPEC_CV_TMP_HANDLER,
  	ZEND_FETCH_OBJ_IS_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLER,
  	ZEND_FETCH_FUNC_ARG_SPEC_CONST_HANDLER,
  	ZEND_FETCH_FUNC_ARG_SPEC_CONST_HANDLER,
  	ZEND_FETCH_FUNC_ARG_SPEC_CONST_HANDLER,
  	ZEND_FETCH_FUNC_ARG_SPEC_CONST_HANDLER,
  	ZEND_FETCH_FUNC_ARG_SPEC_CONST_HANDLER,
  	ZEND_FETCH_FUNC_ARG_SPEC_TMP_HANDLER,
  	ZEND_FETCH_FUNC_ARG_SPEC_TMP_HANDLER,
  	ZEND_FETCH_FUNC_ARG_SPEC_TMP_HANDLER,
  	ZEND_FETCH_FUNC_ARG_SPEC_TMP_HANDLER,
  	ZEND_FETCH_FUNC_ARG_SPEC_TMP_HANDLER,
  	ZEND_FETCH_FUNC_ARG_SPEC_VAR_HANDLER,
  	ZEND_FETCH_FUNC_ARG_SPEC_VAR_HANDLER,
  	ZEND_FETCH_FUNC_ARG_SPEC_VAR_HANDLER,
  	ZEND_FETCH_FUNC_ARG_SPEC_VAR_HANDLER,
  	ZEND_FETCH_FUNC_ARG_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_FUNC_ARG_SPEC_CV_HANDLER,
  	ZEND_FETCH_FUNC_ARG_SPEC_CV_HANDLER,
  	ZEND_FETCH_FUNC_ARG_SPEC_CV_HANDLER,
  	ZEND_FETCH_FUNC_ARG_SPEC_CV_HANDLER,
  	ZEND_FETCH_FUNC_ARG_SPEC_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_HANDLER,
  	ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_HANDLER,
  	ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_VAR_HANDLER,
  	ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER,
  	ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_HANDLER,
  	ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_HANDLER,
  	ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_VAR_HANDLER,
  	ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_HANDLER,
  	ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST_HANDLER,
  	ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP_HANDLER,
  	ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV_HANDLER,
  	ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST_HANDLER,
  	ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP_HANDLER,
  	ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV_HANDLER,
  	ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST_HANDLER,
  	ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP_HANDLER,
  	ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_HANDLER,
  	ZEND_FETCH_UNSET_SPEC_CONST_HANDLER,
  	ZEND_FETCH_UNSET_SPEC_CONST_HANDLER,
  	ZEND_FETCH_UNSET_SPEC_CONST_HANDLER,
  	ZEND_FETCH_UNSET_SPEC_CONST_HANDLER,
  	ZEND_FETCH_UNSET_SPEC_CONST_HANDLER,
  	ZEND_FETCH_UNSET_SPEC_TMP_HANDLER,
  	ZEND_FETCH_UNSET_SPEC_TMP_HANDLER,
  	ZEND_FETCH_UNSET_SPEC_TMP_HANDLER,
  	ZEND_FETCH_UNSET_SPEC_TMP_HANDLER,
  	ZEND_FETCH_UNSET_SPEC_TMP_HANDLER,
  	ZEND_FETCH_UNSET_SPEC_VAR_HANDLER,
  	ZEND_FETCH_UNSET_SPEC_VAR_HANDLER,
  	ZEND_FETCH_UNSET_SPEC_VAR_HANDLER,
  	ZEND_FETCH_UNSET_SPEC_VAR_HANDLER,
  	ZEND_FETCH_UNSET_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_UNSET_SPEC_CV_HANDLER,
  	ZEND_FETCH_UNSET_SPEC_CV_HANDLER,
  	ZEND_FETCH_UNSET_SPEC_CV_HANDLER,
  	ZEND_FETCH_UNSET_SPEC_CV_HANDLER,
  	ZEND_FETCH_UNSET_SPEC_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_HANDLER,
  	ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP_HANDLER,
  	ZEND_FETCH_DIM_UNSET_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_HANDLER,
  	ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP_HANDLER,
  	ZEND_FETCH_DIM_UNSET_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST_HANDLER,
  	ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP_HANDLER,
  	ZEND_FETCH_OBJ_UNSET_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_HANDLER,
  	ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST_HANDLER,
  	ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP_HANDLER,
  	ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV_HANDLER,
  	ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_HANDLER,
  	ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMP_HANDLER,
  	ZEND_FETCH_OBJ_UNSET_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HANDLER,
  	ZEND_FETCH_DIM_TMP_VAR_SPEC_CONST_CONST_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_DIM_TMP_VAR_SPEC_TMP_CONST_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_EXT_STMT_SPEC_HANDLER,
  	ZEND_EXT_STMT_SPEC_HANDLER,
  	ZEND_EXT_STMT_SPEC_HANDLER,
  	ZEND_EXT_STMT_SPEC_HANDLER,
  	ZEND_EXT_STMT_SPEC_HANDLER,
  	ZEND_EXT_STMT_SPEC_HANDLER,
  	ZEND_EXT_STMT_SPEC_HANDLER,
  	ZEND_EXT_STMT_SPEC_HANDLER,
  	ZEND_EXT_STMT_SPEC_HANDLER,
  	ZEND_EXT_STMT_SPEC_HANDLER,
  	ZEND_EXT_STMT_SPEC_HANDLER,
  	ZEND_EXT_STMT_SPEC_HANDLER,
  	ZEND_EXT_STMT_SPEC_HANDLER,
  	ZEND_EXT_STMT_SPEC_HANDLER,
  	ZEND_EXT_STMT_SPEC_HANDLER,
  	ZEND_EXT_STMT_SPEC_HANDLER,
  	ZEND_EXT_STMT_SPEC_HANDLER,
  	ZEND_EXT_STMT_SPEC_HANDLER,
  	ZEND_EXT_STMT_SPEC_HANDLER,
  	ZEND_EXT_STMT_SPEC_HANDLER,
  	ZEND_EXT_STMT_SPEC_HANDLER,
  	ZEND_EXT_STMT_SPEC_HANDLER,
  	ZEND_EXT_STMT_SPEC_HANDLER,
  	ZEND_EXT_STMT_SPEC_HANDLER,
  	ZEND_EXT_STMT_SPEC_HANDLER,
  	ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER,
  	ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER,
  	ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER,
  	ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER,
  	ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER,
  	ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER,
  	ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER,
  	ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER,
  	ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER,
  	ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER,
  	ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER,
  	ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER,
  	ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER,
  	ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER,
  	ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER,
  	ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER,
  	ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER,
  	ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER,
  	ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER,
  	ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER,
  	ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER,
  	ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER,
  	ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER,
  	ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER,
  	ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER,
  	ZEND_EXT_FCALL_END_SPEC_HANDLER,
  	ZEND_EXT_FCALL_END_SPEC_HANDLER,
  	ZEND_EXT_FCALL_END_SPEC_HANDLER,
  	ZEND_EXT_FCALL_END_SPEC_HANDLER,
  	ZEND_EXT_FCALL_END_SPEC_HANDLER,
  	ZEND_EXT_FCALL_END_SPEC_HANDLER,
  	ZEND_EXT_FCALL_END_SPEC_HANDLER,
  	ZEND_EXT_FCALL_END_SPEC_HANDLER,
  	ZEND_EXT_FCALL_END_SPEC_HANDLER,
  	ZEND_EXT_FCALL_END_SPEC_HANDLER,
  	ZEND_EXT_FCALL_END_SPEC_HANDLER,
  	ZEND_EXT_FCALL_END_SPEC_HANDLER,
  	ZEND_EXT_FCALL_END_SPEC_HANDLER,
  	ZEND_EXT_FCALL_END_SPEC_HANDLER,
  	ZEND_EXT_FCALL_END_SPEC_HANDLER,
  	ZEND_EXT_FCALL_END_SPEC_HANDLER,
  	ZEND_EXT_FCALL_END_SPEC_HANDLER,
  	ZEND_EXT_FCALL_END_SPEC_HANDLER,
  	ZEND_EXT_FCALL_END_SPEC_HANDLER,
  	ZEND_EXT_FCALL_END_SPEC_HANDLER,
  	ZEND_EXT_FCALL_END_SPEC_HANDLER,
  	ZEND_EXT_FCALL_END_SPEC_HANDLER,
  	ZEND_EXT_FCALL_END_SPEC_HANDLER,
  	ZEND_EXT_FCALL_END_SPEC_HANDLER,
  	ZEND_EXT_FCALL_END_SPEC_HANDLER,
  	ZEND_EXT_NOP_SPEC_HANDLER,
  	ZEND_EXT_NOP_SPEC_HANDLER,
  	ZEND_EXT_NOP_SPEC_HANDLER,
  	ZEND_EXT_NOP_SPEC_HANDLER,
  	ZEND_EXT_NOP_SPEC_HANDLER,
  	ZEND_EXT_NOP_SPEC_HANDLER,
  	ZEND_EXT_NOP_SPEC_HANDLER,
  	ZEND_EXT_NOP_SPEC_HANDLER,
  	ZEND_EXT_NOP_SPEC_HANDLER,
  	ZEND_EXT_NOP_SPEC_HANDLER,
  	ZEND_EXT_NOP_SPEC_HANDLER,
  	ZEND_EXT_NOP_SPEC_HANDLER,
  	ZEND_EXT_NOP_SPEC_HANDLER,
  	ZEND_EXT_NOP_SPEC_HANDLER,
  	ZEND_EXT_NOP_SPEC_HANDLER,
  	ZEND_EXT_NOP_SPEC_HANDLER,
  	ZEND_EXT_NOP_SPEC_HANDLER,
  	ZEND_EXT_NOP_SPEC_HANDLER,
  	ZEND_EXT_NOP_SPEC_HANDLER,
  	ZEND_EXT_NOP_SPEC_HANDLER,
  	ZEND_EXT_NOP_SPEC_HANDLER,
  	ZEND_EXT_NOP_SPEC_HANDLER,
  	ZEND_EXT_NOP_SPEC_HANDLER,
  	ZEND_EXT_NOP_SPEC_HANDLER,
  	ZEND_EXT_NOP_SPEC_HANDLER,
  	ZEND_TICKS_SPEC_CONST_HANDLER,
  	ZEND_TICKS_SPEC_CONST_HANDLER,
  	ZEND_TICKS_SPEC_CONST_HANDLER,
  	ZEND_TICKS_SPEC_CONST_HANDLER,
  	ZEND_TICKS_SPEC_CONST_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER,
  	ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER,
  	ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER,
  	ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER,
  	ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER,
  	ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER,
  	ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER,
  	ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER,
  	ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER,
  	ZEND_CATCH_SPEC_HANDLER,
  	ZEND_CATCH_SPEC_HANDLER,
  	ZEND_CATCH_SPEC_HANDLER,
  	ZEND_CATCH_SPEC_HANDLER,
  	ZEND_CATCH_SPEC_HANDLER,
  	ZEND_CATCH_SPEC_HANDLER,
  	ZEND_CATCH_SPEC_HANDLER,
  	ZEND_CATCH_SPEC_HANDLER,
  	ZEND_CATCH_SPEC_HANDLER,
  	ZEND_CATCH_SPEC_HANDLER,
  	ZEND_CATCH_SPEC_HANDLER,
  	ZEND_CATCH_SPEC_HANDLER,
  	ZEND_CATCH_SPEC_HANDLER,
  	ZEND_CATCH_SPEC_HANDLER,
  	ZEND_CATCH_SPEC_HANDLER,
  	ZEND_CATCH_SPEC_HANDLER,
  	ZEND_CATCH_SPEC_HANDLER,
  	ZEND_CATCH_SPEC_HANDLER,
  	ZEND_CATCH_SPEC_HANDLER,
  	ZEND_CATCH_SPEC_HANDLER,
  	ZEND_CATCH_SPEC_HANDLER,
  	ZEND_CATCH_SPEC_HANDLER,
  	ZEND_CATCH_SPEC_HANDLER,
  	ZEND_CATCH_SPEC_HANDLER,
  	ZEND_CATCH_SPEC_HANDLER,
  	ZEND_THROW_SPEC_CONST_HANDLER,
  	ZEND_THROW_SPEC_CONST_HANDLER,
  	ZEND_THROW_SPEC_CONST_HANDLER,
  	ZEND_THROW_SPEC_CONST_HANDLER,
  	ZEND_THROW_SPEC_CONST_HANDLER,
  	ZEND_THROW_SPEC_TMP_HANDLER,
  	ZEND_THROW_SPEC_TMP_HANDLER,
  	ZEND_THROW_SPEC_TMP_HANDLER,
  	ZEND_THROW_SPEC_TMP_HANDLER,
  	ZEND_THROW_SPEC_TMP_HANDLER,
  	ZEND_THROW_SPEC_VAR_HANDLER,
  	ZEND_THROW_SPEC_VAR_HANDLER,
  	ZEND_THROW_SPEC_VAR_HANDLER,
  	ZEND_THROW_SPEC_VAR_HANDLER,
  	ZEND_THROW_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_THROW_SPEC_CV_HANDLER,
  	ZEND_THROW_SPEC_CV_HANDLER,
  	ZEND_THROW_SPEC_CV_HANDLER,
  	ZEND_THROW_SPEC_CV_HANDLER,
  	ZEND_THROW_SPEC_CV_HANDLER,
  	ZEND_FETCH_CLASS_SPEC_CONST_HANDLER,
  	ZEND_FETCH_CLASS_SPEC_TMP_HANDLER,
  	ZEND_FETCH_CLASS_SPEC_VAR_HANDLER,
  	ZEND_FETCH_CLASS_SPEC_UNUSED_HANDLER,
  	ZEND_FETCH_CLASS_SPEC_CV_HANDLER,
  	ZEND_FETCH_CLASS_SPEC_CONST_HANDLER,
  	ZEND_FETCH_CLASS_SPEC_TMP_HANDLER,
  	ZEND_FETCH_CLASS_SPEC_VAR_HANDLER,
  	ZEND_FETCH_CLASS_SPEC_UNUSED_HANDLER,
  	ZEND_FETCH_CLASS_SPEC_CV_HANDLER,
  	ZEND_FETCH_CLASS_SPEC_CONST_HANDLER,
  	ZEND_FETCH_CLASS_SPEC_TMP_HANDLER,
  	ZEND_FETCH_CLASS_SPEC_VAR_HANDLER,
  	ZEND_FETCH_CLASS_SPEC_UNUSED_HANDLER,
  	ZEND_FETCH_CLASS_SPEC_CV_HANDLER,
  	ZEND_FETCH_CLASS_SPEC_CONST_HANDLER,
  	ZEND_FETCH_CLASS_SPEC_TMP_HANDLER,
  	ZEND_FETCH_CLASS_SPEC_VAR_HANDLER,
  	ZEND_FETCH_CLASS_SPEC_UNUSED_HANDLER,
  	ZEND_FETCH_CLASS_SPEC_CV_HANDLER,
  	ZEND_FETCH_CLASS_SPEC_CONST_HANDLER,
  	ZEND_FETCH_CLASS_SPEC_TMP_HANDLER,
  	ZEND_FETCH_CLASS_SPEC_VAR_HANDLER,
  	ZEND_FETCH_CLASS_SPEC_UNUSED_HANDLER,
  	ZEND_FETCH_CLASS_SPEC_CV_HANDLER,
  	ZEND_CLONE_SPEC_CONST_HANDLER,
  	ZEND_CLONE_SPEC_CONST_HANDLER,
  	ZEND_CLONE_SPEC_CONST_HANDLER,
  	ZEND_CLONE_SPEC_CONST_HANDLER,
  	ZEND_CLONE_SPEC_CONST_HANDLER,
  	ZEND_CLONE_SPEC_TMP_HANDLER,
  	ZEND_CLONE_SPEC_TMP_HANDLER,
  	ZEND_CLONE_SPEC_TMP_HANDLER,
  	ZEND_CLONE_SPEC_TMP_HANDLER,
  	ZEND_CLONE_SPEC_TMP_HANDLER,
  	ZEND_CLONE_SPEC_VAR_HANDLER,
  	ZEND_CLONE_SPEC_VAR_HANDLER,
  	ZEND_CLONE_SPEC_VAR_HANDLER,
  	ZEND_CLONE_SPEC_VAR_HANDLER,
  	ZEND_CLONE_SPEC_VAR_HANDLER,
  	ZEND_CLONE_SPEC_UNUSED_HANDLER,
  	ZEND_CLONE_SPEC_UNUSED_HANDLER,
  	ZEND_CLONE_SPEC_UNUSED_HANDLER,
  	ZEND_CLONE_SPEC_UNUSED_HANDLER,
  	ZEND_CLONE_SPEC_UNUSED_HANDLER,
  	ZEND_CLONE_SPEC_CV_HANDLER,
  	ZEND_CLONE_SPEC_CV_HANDLER,
  	ZEND_CLONE_SPEC_CV_HANDLER,
  	ZEND_CLONE_SPEC_CV_HANDLER,
  	ZEND_CLONE_SPEC_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST_HANDLER,
  	ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP_HANDLER,
  	ZEND_INIT_METHOD_CALL_SPEC_TMP_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_INIT_METHOD_CALL_SPEC_TMP_CV_HANDLER,
  	ZEND_INIT_METHOD_CALL_SPEC_VAR_CONST_HANDLER,
  	ZEND_INIT_METHOD_CALL_SPEC_VAR_TMP_HANDLER,
  	ZEND_INIT_METHOD_CALL_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_INIT_METHOD_CALL_SPEC_VAR_CV_HANDLER,
  	ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER,
  	ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP_HANDLER,
  	ZEND_INIT_METHOD_CALL_SPEC_UNUSED_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_HANDLER,
  	ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_HANDLER,
  	ZEND_INIT_METHOD_CALL_SPEC_CV_TMP_HANDLER,
  	ZEND_INIT_METHOD_CALL_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HANDLER,
  	ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_HANDLER,
  	ZEND_INIT_STATIC_METHOD_CALL_SPEC_TMP_HANDLER,
  	ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_HANDLER,
  	ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_HANDLER,
  	ZEND_INIT_STATIC_METHOD_CALL_SPEC_CV_HANDLER,
  	ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_HANDLER,
  	ZEND_INIT_STATIC_METHOD_CALL_SPEC_TMP_HANDLER,
  	ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_HANDLER,
  	ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_HANDLER,
  	ZEND_INIT_STATIC_METHOD_CALL_SPEC_CV_HANDLER,
  	ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_HANDLER,
  	ZEND_INIT_STATIC_METHOD_CALL_SPEC_TMP_HANDLER,
  	ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_HANDLER,
  	ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_HANDLER,
  	ZEND_INIT_STATIC_METHOD_CALL_SPEC_CV_HANDLER,
  	ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_HANDLER,
  	ZEND_INIT_STATIC_METHOD_CALL_SPEC_TMP_HANDLER,
  	ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_HANDLER,
  	ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_HANDLER,
  	ZEND_INIT_STATIC_METHOD_CALL_SPEC_CV_HANDLER,
  	ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_HANDLER,
  	ZEND_INIT_STATIC_METHOD_CALL_SPEC_TMP_HANDLER,
  	ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_HANDLER,
  	ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_HANDLER,
  	ZEND_INIT_STATIC_METHOD_CALL_SPEC_CV_HANDLER,
  	ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_HANDLER,
  	ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_HANDLER,
  	ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_HANDLER,
  	ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_HANDLER,
  	ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_HANDLER,
  	ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_HANDLER,
  	ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_HANDLER,
  	ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_HANDLER,
  	ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_HANDLER,
  	ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_HANDLER,
  	ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_HANDLER,
  	ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_HANDLER,
  	ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_HANDLER,
  	ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_HANDLER,
  	ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_HANDLER,
  	ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_HANDLER,
  	ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_HANDLER,
  	ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_HANDLER,
  	ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_VAR_CONST_HANDLER,
  	ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_VAR_TMP_HANDLER,
  	ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_VAR_CV_HANDLER,
  	ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNUSED_CONST_HANDLER,
  	ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNUSED_TMP_HANDLER,
  	ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNUSED_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNUSED_CV_HANDLER,
  	ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CONST_HANDLER,
  	ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMP_HANDLER,
  	ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_PRE_INC_OBJ_SPEC_VAR_CONST_HANDLER,
  	ZEND_PRE_INC_OBJ_SPEC_VAR_TMP_HANDLER,
  	ZEND_PRE_INC_OBJ_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_PRE_INC_OBJ_SPEC_VAR_CV_HANDLER,
  	ZEND_PRE_INC_OBJ_SPEC_UNUSED_CONST_HANDLER,
  	ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMP_HANDLER,
  	ZEND_PRE_INC_OBJ_SPEC_UNUSED_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_PRE_INC_OBJ_SPEC_UNUSED_CV_HANDLER,
  	ZEND_PRE_INC_OBJ_SPEC_CV_CONST_HANDLER,
  	ZEND_PRE_INC_OBJ_SPEC_CV_TMP_HANDLER,
  	ZEND_PRE_INC_OBJ_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_PRE_INC_OBJ_SPEC_CV_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_PRE_DEC_OBJ_SPEC_VAR_CONST_HANDLER,
  	ZEND_PRE_DEC_OBJ_SPEC_VAR_TMP_HANDLER,
  	ZEND_PRE_DEC_OBJ_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_PRE_DEC_OBJ_SPEC_VAR_CV_HANDLER,
  	ZEND_PRE_DEC_OBJ_SPEC_UNUSED_CONST_HANDLER,
  	ZEND_PRE_DEC_OBJ_SPEC_UNUSED_TMP_HANDLER,
  	ZEND_PRE_DEC_OBJ_SPEC_UNUSED_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_PRE_DEC_OBJ_SPEC_UNUSED_CV_HANDLER,
  	ZEND_PRE_DEC_OBJ_SPEC_CV_CONST_HANDLER,
  	ZEND_PRE_DEC_OBJ_SPEC_CV_TMP_HANDLER,
  	ZEND_PRE_DEC_OBJ_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_PRE_DEC_OBJ_SPEC_CV_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_POST_INC_OBJ_SPEC_VAR_CONST_HANDLER,
  	ZEND_POST_INC_OBJ_SPEC_VAR_TMP_HANDLER,
  	ZEND_POST_INC_OBJ_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_POST_INC_OBJ_SPEC_VAR_CV_HANDLER,
  	ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST_HANDLER,
  	ZEND_POST_INC_OBJ_SPEC_UNUSED_TMP_HANDLER,
  	ZEND_POST_INC_OBJ_SPEC_UNUSED_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_POST_INC_OBJ_SPEC_UNUSED_CV_HANDLER,
  	ZEND_POST_INC_OBJ_SPEC_CV_CONST_HANDLER,
  	ZEND_POST_INC_OBJ_SPEC_CV_TMP_HANDLER,
  	ZEND_POST_INC_OBJ_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_POST_INC_OBJ_SPEC_CV_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_POST_DEC_OBJ_SPEC_VAR_CONST_HANDLER,
  	ZEND_POST_DEC_OBJ_SPEC_VAR_TMP_HANDLER,
  	ZEND_POST_DEC_OBJ_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_POST_DEC_OBJ_SPEC_VAR_CV_HANDLER,
  	ZEND_POST_DEC_OBJ_SPEC_UNUSED_CONST_HANDLER,
  	ZEND_POST_DEC_OBJ_SPEC_UNUSED_TMP_HANDLER,
  	ZEND_POST_DEC_OBJ_SPEC_UNUSED_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_POST_DEC_OBJ_SPEC_UNUSED_CV_HANDLER,
  	ZEND_POST_DEC_OBJ_SPEC_CV_CONST_HANDLER,
  	ZEND_POST_DEC_OBJ_SPEC_CV_TMP_HANDLER,
  	ZEND_POST_DEC_OBJ_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_POST_DEC_OBJ_SPEC_CV_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_HANDLER,
  	ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_HANDLER,
  	ZEND_ASSIGN_OBJ_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ASSIGN_OBJ_SPEC_VAR_CV_HANDLER,
  	ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_HANDLER,
  	ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_HANDLER,
  	ZEND_ASSIGN_OBJ_SPEC_UNUSED_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_HANDLER,
  	ZEND_ASSIGN_OBJ_SPEC_CV_CONST_HANDLER,
  	ZEND_ASSIGN_OBJ_SPEC_CV_TMP_HANDLER,
  	ZEND_ASSIGN_OBJ_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ASSIGN_OBJ_SPEC_CV_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_INSTANCEOF_SPEC_TMP_HANDLER,
  	ZEND_INSTANCEOF_SPEC_TMP_HANDLER,
  	ZEND_INSTANCEOF_SPEC_TMP_HANDLER,
  	ZEND_INSTANCEOF_SPEC_TMP_HANDLER,
  	ZEND_INSTANCEOF_SPEC_TMP_HANDLER,
  	ZEND_INSTANCEOF_SPEC_VAR_HANDLER,
  	ZEND_INSTANCEOF_SPEC_VAR_HANDLER,
  	ZEND_INSTANCEOF_SPEC_VAR_HANDLER,
  	ZEND_INSTANCEOF_SPEC_VAR_HANDLER,
  	ZEND_INSTANCEOF_SPEC_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_INSTANCEOF_SPEC_CV_HANDLER,
  	ZEND_INSTANCEOF_SPEC_CV_HANDLER,
  	ZEND_INSTANCEOF_SPEC_CV_HANDLER,
  	ZEND_INSTANCEOF_SPEC_CV_HANDLER,
  	ZEND_INSTANCEOF_SPEC_CV_HANDLER,
  	ZEND_DECLARE_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER,
  	ZEND_DECLARE_FUNCTION_SPEC_HANDLER,
  	ZEND_DECLARE_FUNCTION_SPEC_HANDLER,
  	ZEND_DECLARE_FUNCTION_SPEC_HANDLER,
  	ZEND_DECLARE_FUNCTION_SPEC_HANDLER,
  	ZEND_DECLARE_FUNCTION_SPEC_HANDLER,
  	ZEND_DECLARE_FUNCTION_SPEC_HANDLER,
  	ZEND_DECLARE_FUNCTION_SPEC_HANDLER,
  	ZEND_DECLARE_FUNCTION_SPEC_HANDLER,
  	ZEND_DECLARE_FUNCTION_SPEC_HANDLER,
  	ZEND_DECLARE_FUNCTION_SPEC_HANDLER,
  	ZEND_DECLARE_FUNCTION_SPEC_HANDLER,
  	ZEND_DECLARE_FUNCTION_SPEC_HANDLER,
  	ZEND_DECLARE_FUNCTION_SPEC_HANDLER,
  	ZEND_DECLARE_FUNCTION_SPEC_HANDLER,
  	ZEND_DECLARE_FUNCTION_SPEC_HANDLER,
  	ZEND_DECLARE_FUNCTION_SPEC_HANDLER,
  	ZEND_DECLARE_FUNCTION_SPEC_HANDLER,
  	ZEND_DECLARE_FUNCTION_SPEC_HANDLER,
  	ZEND_DECLARE_FUNCTION_SPEC_HANDLER,
  	ZEND_DECLARE_FUNCTION_SPEC_HANDLER,
  	ZEND_DECLARE_FUNCTION_SPEC_HANDLER,
  	ZEND_DECLARE_FUNCTION_SPEC_HANDLER,
  	ZEND_DECLARE_FUNCTION_SPEC_HANDLER,
  	ZEND_DECLARE_FUNCTION_SPEC_HANDLER,
  	ZEND_DECLARE_FUNCTION_SPEC_HANDLER,
  	ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
  	ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
  	ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
  	ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
  	ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
  	ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
  	ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
  	ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
  	ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
  	ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
  	ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
  	ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
  	ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
  	ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
  	ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
  	ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
  	ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
  	ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
  	ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
  	ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
  	ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
  	ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
  	ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
  	ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
  	ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ADD_INTERFACE_SPEC_HANDLER,
  	ZEND_ADD_INTERFACE_SPEC_HANDLER,
  	ZEND_ADD_INTERFACE_SPEC_HANDLER,
  	ZEND_ADD_INTERFACE_SPEC_HANDLER,
  	ZEND_ADD_INTERFACE_SPEC_HANDLER,
  	ZEND_ADD_INTERFACE_SPEC_HANDLER,
  	ZEND_ADD_INTERFACE_SPEC_HANDLER,
  	ZEND_ADD_INTERFACE_SPEC_HANDLER,
  	ZEND_ADD_INTERFACE_SPEC_HANDLER,
  	ZEND_ADD_INTERFACE_SPEC_HANDLER,
  	ZEND_ADD_INTERFACE_SPEC_HANDLER,
  	ZEND_ADD_INTERFACE_SPEC_HANDLER,
  	ZEND_ADD_INTERFACE_SPEC_HANDLER,
  	ZEND_ADD_INTERFACE_SPEC_HANDLER,
  	ZEND_ADD_INTERFACE_SPEC_HANDLER,
  	ZEND_ADD_INTERFACE_SPEC_HANDLER,
  	ZEND_ADD_INTERFACE_SPEC_HANDLER,
  	ZEND_ADD_INTERFACE_SPEC_HANDLER,
  	ZEND_ADD_INTERFACE_SPEC_HANDLER,
  	ZEND_ADD_INTERFACE_SPEC_HANDLER,
  	ZEND_ADD_INTERFACE_SPEC_HANDLER,
  	ZEND_ADD_INTERFACE_SPEC_HANDLER,
  	ZEND_ADD_INTERFACE_SPEC_HANDLER,
  	ZEND_ADD_INTERFACE_SPEC_HANDLER,
  	ZEND_ADD_INTERFACE_SPEC_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER,
  	ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER,
  	ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER,
  	ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER,
  	ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER,
  	ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER,
  	ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER,
  	ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER,
  	ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER,
  	ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER,
  	ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER,
  	ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER,
  	ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER,
  	ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER,
  	ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER,
  	ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER,
  	ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER,
  	ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER,
  	ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER,
  	ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER,
  	ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER,
  	ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER,
  	ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER,
  	ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER,
  	ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER,
  	ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER,
  	ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER,
  	ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER,
  	ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER,
  	ZEND_ASSIGN_DIM_SPEC_CV_TMP_HANDLER,
  	ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER,
  	ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER,
  	ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_CONST_HANDLER,
  	ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_TMP_HANDLER,
  	ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_CV_HANDLER,
  	ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST_HANDLER,
  	ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMP_HANDLER,
  	ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CV_HANDLER,
  	ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST_HANDLER,
  	ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMP_HANDLER,
  	ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_VAR_HANDLER,
  	ZEND_NULL_HANDLER,
  	ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CV_HANDLER,
  	ZEND_HANDLE_EXCEPTION_SPEC_HANDLER,
  	ZEND_HANDLE_EXCEPTION_SPEC_HANDLER,
  	ZEND_HANDLE_EXCEPTION_SPEC_HANDLER,
  	ZEND_HANDLE_EXCEPTION_SPEC_HANDLER,
  	ZEND_HANDLE_EXCEPTION_SPEC_HANDLER,
  	ZEND_HANDLE_EXCEPTION_SPEC_HANDLER,
  	ZEND_HANDLE_EXCEPTION_SPEC_HANDLER,
  	ZEND_HANDLE_EXCEPTION_SPEC_HANDLER,
  	ZEND_HANDLE_EXCEPTION_SPEC_HANDLER,
  	ZEND_HANDLE_EXCEPTION_SPEC_HANDLER,
  	ZEND_HANDLE_EXCEPTION_SPEC_HANDLER,
  	ZEND_HANDLE_EXCEPTION_SPEC_HANDLER,
  	ZEND_HANDLE_EXCEPTION_SPEC_HANDLER,
  	ZEND_HANDLE_EXCEPTION_SPEC_HANDLER,
  	ZEND_HANDLE_EXCEPTION_SPEC_HANDLER,
  	ZEND_HANDLE_EXCEPTION_SPEC_HANDLER,
  	ZEND_HANDLE_EXCEPTION_SPEC_HANDLER,
  	ZEND_HANDLE_EXCEPTION_SPEC_HANDLER,
  	ZEND_HANDLE_EXCEPTION_SPEC_HANDLER,
  	ZEND_HANDLE_EXCEPTION_SPEC_HANDLER,
  	ZEND_HANDLE_EXCEPTION_SPEC_HANDLER,
  	ZEND_HANDLE_EXCEPTION_SPEC_HANDLER,
  	ZEND_HANDLE_EXCEPTION_SPEC_HANDLER,
  	ZEND_HANDLE_EXCEPTION_SPEC_HANDLER,
  	ZEND_HANDLE_EXCEPTION_SPEC_HANDLER,
  	ZEND_USER_OPCODE_SPEC_HANDLER,
  	ZEND_USER_OPCODE_SPEC_HANDLER,
  	ZEND_USER_OPCODE_SPEC_HANDLER,
  	ZEND_USER_OPCODE_SPEC_HANDLER,
  	ZEND_USER_OPCODE_SPEC_HANDLER,
  	ZEND_USER_OPCODE_SPEC_HANDLER,
  	ZEND_USER_OPCODE_SPEC_HANDLER,
  	ZEND_USER_OPCODE_SPEC_HANDLER,
  	ZEND_USER_OPCODE_SPEC_HANDLER,
  	ZEND_USER_OPCODE_SPEC_HANDLER,
  	ZEND_USER_OPCODE_SPEC_HANDLER,
  	ZEND_USER_OPCODE_SPEC_HANDLER,
  	ZEND_USER_OPCODE_SPEC_HANDLER,
  	ZEND_USER_OPCODE_SPEC_HANDLER,
  	ZEND_USER_OPCODE_SPEC_HANDLER,
  	ZEND_USER_OPCODE_SPEC_HANDLER,
  	ZEND_USER_OPCODE_SPEC_HANDLER,
  	ZEND_USER_OPCODE_SPEC_HANDLER,
  	ZEND_USER_OPCODE_SPEC_HANDLER,
  	ZEND_USER_OPCODE_SPEC_HANDLER,
  	ZEND_USER_OPCODE_SPEC_HANDLER,
  	ZEND_USER_OPCODE_SPEC_HANDLER,
  	ZEND_USER_OPCODE_SPEC_HANDLER,
  	ZEND_USER_OPCODE_SPEC_HANDLER,
  	ZEND_USER_OPCODE_SPEC_HANDLER,
  	ZEND_NULL_HANDLER
  };
  zend_opcode_handlers = (opcode_handler_t*)labels;
}
static opcode_handler_t zend_vm_get_opcode_handler(zend_uchar opcode, zend_op* op)
{
		static const int zend_vm_decode[] = {
			_UNUSED_CODE, /* 0              */
			_CONST_CODE,  /* 1 = IS_CONST   */
			_TMP_CODE,    /* 2 = IS_TMP_VAR */
			_UNUSED_CODE, /* 3              */
			_VAR_CODE,    /* 4 = IS_VAR     */
			_UNUSED_CODE, /* 5              */
			_UNUSED_CODE, /* 6              */
			_UNUSED_CODE, /* 7              */
			_UNUSED_CODE, /* 8 = IS_UNUSED  */
			_UNUSED_CODE, /* 9              */
			_UNUSED_CODE, /* 10             */
			_UNUSED_CODE, /* 11             */
			_UNUSED_CODE, /* 12             */
			_UNUSED_CODE, /* 13             */
			_UNUSED_CODE, /* 14             */
			_UNUSED_CODE, /* 15             */
			_CV_CODE      /* 16 = IS_CV     */
		};
		return zend_opcode_handlers[opcode * 25 + zend_vm_decode[op->op1.op_type] * 5 + zend_vm_decode[op->op2.op_type]];
}

ZEND_API void zend_vm_set_opcode_handler(zend_op* op)
{
	op->handler = zend_vm_get_opcode_handler(zend_user_opcodes[op->opcode], op);
}

ZEND_API int zend_do_fcall(ZEND_OPCODE_HANDLER_ARGS)
{
	return zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

php/Zend/zend_strtod.h000064400000003450151730542020010744 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        | 
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Derick Rethans <derick@php.net>                             |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_strtod.h 293155 2010-01-05 20:46:53Z sebastian $ */

/* This is a header file for the strtod implementation by David M. Gay which
 * can be found in zend_strtod.c */
#ifndef ZEND_STRTOD_H
#define ZEND_STRTOD_H
#include <zend.h>

BEGIN_EXTERN_C()
ZEND_API void zend_freedtoa(char *s);
ZEND_API char * zend_dtoa(double _d, int mode, int ndigits, int *decpt, int *sign, char **rve);
ZEND_API double zend_strtod(const char *s00, char **se);
ZEND_API double zend_hex_strtod(const char *str, char **endptr);
ZEND_API double zend_oct_strtod(const char *str, char **endptr);
ZEND_API int zend_startup_strtod(void);
ZEND_API int zend_shutdown_strtod(void);
END_EXTERN_C()

#endif
php/Zend/zend_constants.h000064400000010246151730542020011442 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        | 
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_constants.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef ZEND_CONSTANTS_H
#define ZEND_CONSTANTS_H

#include "zend_globals.h"

#define CONST_CS				(1<<0)				/* Case Sensitive */
#define CONST_PERSISTENT		(1<<1)				/* Persistent */
#define CONST_CT_SUBST			(1<<2)				/* Allow compile-time substitution */

#define	PHP_USER_CONSTANT INT_MAX	/* a constant defined in user space */

typedef struct _zend_constant {
	zval value;
	int flags;
	char *name;
	uint name_len;
	int module_number;
} zend_constant;

#define REGISTER_LONG_CONSTANT(name, lval, flags)  zend_register_long_constant((name), sizeof(name), (lval), (flags), module_number TSRMLS_CC)
#define REGISTER_DOUBLE_CONSTANT(name, dval, flags)  zend_register_double_constant((name), sizeof(name), (dval), (flags), module_number TSRMLS_CC)
#define REGISTER_STRING_CONSTANT(name, str, flags)  zend_register_string_constant((name), sizeof(name), (str), (flags), module_number TSRMLS_CC)
#define REGISTER_STRINGL_CONSTANT(name, str, len, flags)  zend_register_stringl_constant((name), sizeof(name), (str), (len), (flags), module_number TSRMLS_CC)

#define REGISTER_MAIN_LONG_CONSTANT(name, lval, flags)  zend_register_long_constant((name), sizeof(name), (lval), (flags), 0 TSRMLS_CC)
#define REGISTER_MAIN_DOUBLE_CONSTANT(name, dval, flags)  zend_register_double_constant((name), sizeof(name), (dval), (flags), 0 TSRMLS_CC)
#define REGISTER_MAIN_STRING_CONSTANT(name, str, flags)  zend_register_string_constant((name), sizeof(name), (str), (flags), 0 TSRMLS_CC)
#define REGISTER_MAIN_STRINGL_CONSTANT(name, str, len, flags)  zend_register_stringl_constant((name), sizeof(name), (str), (len), (flags), 0 TSRMLS_CC)

BEGIN_EXTERN_C()
void clean_module_constants(int module_number TSRMLS_DC);
void free_zend_constant(zend_constant *c);
int zend_startup_constants(TSRMLS_D);
int zend_shutdown_constants(TSRMLS_D);
void zend_register_standard_constants(TSRMLS_D);
void clean_non_persistent_constants(TSRMLS_D);
ZEND_API int zend_get_constant(char *name, uint name_len, zval *result TSRMLS_DC);
ZEND_API int zend_get_constant_ex(char *name, uint name_len, zval *result, zend_class_entry *scope TSRMLS_DC);
ZEND_API void zend_register_long_constant(char *name, uint name_len, long lval, int flags, int module_number TSRMLS_DC);
ZEND_API void zend_register_double_constant(char *name, uint name_len, double dval, int flags, int module_number TSRMLS_DC);
ZEND_API void zend_register_string_constant(char *name, uint name_len, char *strval, int flags, int module_number TSRMLS_DC);
ZEND_API void zend_register_stringl_constant(char *name, uint name_len, char *strval, uint strlen, int flags, int module_number TSRMLS_DC);
ZEND_API int zend_register_constant(zend_constant *c TSRMLS_DC);
void zend_copy_constants(HashTable *target, HashTable *sourc);
void copy_zend_constant(zend_constant *c);
END_EXTERN_C()

#define ZEND_CONSTANT_DTOR (void (*)(void *)) free_zend_constant

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_ptr_stack.h000064400000007654151730542020011431 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        | 
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_ptr_stack.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef ZEND_PTR_STACK_H
#define ZEND_PTR_STACK_H

typedef struct _zend_ptr_stack {
	int top, max;
	void **elements;
	void **top_element;
} zend_ptr_stack;


#define PTR_STACK_BLOCK_SIZE 64

BEGIN_EXTERN_C()
ZEND_API void zend_ptr_stack_init(zend_ptr_stack *stack);
ZEND_API void zend_ptr_stack_n_push(zend_ptr_stack *stack, int count, ...);
ZEND_API void zend_ptr_stack_n_pop(zend_ptr_stack *stack, int count, ...);
ZEND_API void zend_ptr_stack_destroy(zend_ptr_stack *stack);
ZEND_API void zend_ptr_stack_apply(zend_ptr_stack *stack, void (*func)(void *));
ZEND_API void zend_ptr_stack_clean(zend_ptr_stack *stack, void (*func)(void *), zend_bool free_elements);
ZEND_API int zend_ptr_stack_num_elements(zend_ptr_stack *stack);
END_EXTERN_C()

#define ZEND_PTR_STACK_RESIZE_IF_NEEDED(stack, count)		\
	if (stack->top+count > stack->max) {					\
		/* we need to allocate more memory */				\
		stack->max *= 2;									\
		stack->max += count;								\
		stack->elements = (void **) erealloc(stack->elements, (sizeof(void *) * (stack->max)));	\
		stack->top_element = stack->elements+stack->top;	\
	}

/*	Not doing this with a macro because of the loop unrolling in the element assignment.
	Just using a macro for 3 in the body for readability sake. */
static inline void zend_ptr_stack_3_push(zend_ptr_stack *stack, void *a, void *b, void *c)
{
#define ZEND_PTR_STACK_NUM_ARGS 3

	ZEND_PTR_STACK_RESIZE_IF_NEEDED(stack, ZEND_PTR_STACK_NUM_ARGS)

	stack->top += ZEND_PTR_STACK_NUM_ARGS;
	*(stack->top_element++) = a;
	*(stack->top_element++) = b;
	*(stack->top_element++) = c;

#undef ZEND_PTR_STACK_NUM_ARGS
}

static inline void zend_ptr_stack_2_push(zend_ptr_stack *stack, void *a, void *b)
{
#define ZEND_PTR_STACK_NUM_ARGS 2

	ZEND_PTR_STACK_RESIZE_IF_NEEDED(stack, ZEND_PTR_STACK_NUM_ARGS)

	stack->top += ZEND_PTR_STACK_NUM_ARGS;
	*(stack->top_element++) = a;
	*(stack->top_element++) = b;

#undef ZEND_PTR_STACK_NUM_ARGS
}

static inline void zend_ptr_stack_3_pop(zend_ptr_stack *stack, void **a, void **b, void **c)
{
	*a = *(--stack->top_element);
	*b = *(--stack->top_element);
	*c = *(--stack->top_element);
	stack->top -= 3;
}

static inline void zend_ptr_stack_2_pop(zend_ptr_stack *stack, void **a, void **b)
{
	*a = *(--stack->top_element);
	*b = *(--stack->top_element);
	stack->top -= 2;
}

static inline void zend_ptr_stack_push(zend_ptr_stack *stack, void *ptr)
{
	ZEND_PTR_STACK_RESIZE_IF_NEEDED(stack, 1)

	stack->top++;
	*(stack->top_element++) = ptr;
}

static inline void *zend_ptr_stack_pop(zend_ptr_stack *stack)
{
	stack->top--;
	return *(--stack->top_element);
}

#endif /* ZEND_PTR_STACK_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_globals.h000064400000015230151730542020011047 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        | 
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_globals.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef ZEND_GLOBALS_H
#define ZEND_GLOBALS_H


#include <setjmp.h>

#include "zend_globals_macros.h"

#include "zend_stack.h"
#include "zend_ptr_stack.h"
#include "zend_hash.h"
#include "zend_llist.h"
#include "zend_objects.h"
#include "zend_objects_API.h"
#include "zend_modules.h"

#ifdef ZEND_MULTIBYTE
#include "zend_multibyte.h"
#endif /* ZEND_MULTIBYTE */

/* Define ZTS if you want a thread-safe Zend */
/*#undef ZTS*/

#ifdef ZTS

BEGIN_EXTERN_C()
ZEND_API extern int compiler_globals_id;
ZEND_API extern int executor_globals_id;
END_EXTERN_C()

#endif

#define SYMTABLE_CACHE_SIZE 32


#include "zend_compile.h"

/* excpt.h on Digital Unix 4.0 defines function_table */
#undef function_table


typedef struct _zend_declarables {
	zval ticks;
} zend_declarables;


struct _zend_compiler_globals {
	zend_stack bp_stack;
	zend_stack switch_cond_stack;
	zend_stack foreach_copy_stack;
	zend_stack object_stack;
	zend_stack declare_stack;

	zend_class_entry *active_class_entry;

	/* variables for list() compilation */
	zend_llist list_llist;
	zend_llist dimension_llist;
	zend_stack list_stack;

	zend_stack function_call_stack;

	char *compiled_filename;

	int zend_lineno;
	int comment_start_line;
	char *heredoc;
	int heredoc_len;

	zend_op_array *active_op_array;

	HashTable *function_table;	/* function symbol table */
	HashTable *class_table;		/* class table */

	HashTable filenames_table;

	HashTable *auto_globals;

	zend_bool in_compilation;
	zend_bool short_tags;
	zend_bool asp_tags;
	zend_bool allow_call_time_pass_reference;

	zend_declarables declarables;

	/* For extensions support */
	zend_bool extended_info;	/* generate extension information for debugger/profiler */
	zend_bool handle_op_arrays;	/* run op_arrays through op_array handlers */

	zend_bool unclean_shutdown;

	zend_bool ini_parser_unbuffered_errors;

	zend_llist open_files;

	long catch_begin;

	struct _zend_ini_parser_param *ini_parser_param;

	int interactive;

	zend_uint start_lineno;
	zend_bool increment_lineno;

	znode implementing_class;

	zend_uint access_type;

	char *doc_comment;
	zend_uint doc_comment_len;

#ifdef ZEND_MULTIBYTE
	zend_encoding **script_encoding_list;
	int script_encoding_list_size;
	zend_bool detect_unicode;

	zend_encoding *internal_encoding;

	/* multibyte utility functions */
	zend_encoding_detector encoding_detector;
	zend_encoding_converter encoding_converter;
	zend_encoding_oddlen encoding_oddlen;
#endif /* ZEND_MULTIBYTE */

#ifdef ZTS
	HashTable **static_members;
	int last_static_member;
#endif
};


struct _zend_executor_globals {
	zval **return_value_ptr_ptr;

	zval uninitialized_zval;
	zval *uninitialized_zval_ptr;

	zval error_zval;
	zval *error_zval_ptr;

	zend_function_state *function_state_ptr;
	zend_ptr_stack arg_types_stack;

	/* symbol table cache */
	HashTable *symtable_cache[SYMTABLE_CACHE_SIZE];
	HashTable **symtable_cache_limit;
	HashTable **symtable_cache_ptr;

	zend_op **opline_ptr;

	HashTable *active_symbol_table;
	HashTable symbol_table;		/* main symbol table */

	HashTable included_files;	/* files already included */

	jmp_buf *bailout;

	int error_reporting;
	int orig_error_reporting;
	int exit_status;

	zend_op_array *active_op_array;

	HashTable *function_table;	/* function symbol table */
	HashTable *class_table;		/* class table */
	HashTable *zend_constants;	/* constants table */

	zend_class_entry *scope;

	zval *This;

	long precision;

	int ticks_count;

	zend_bool in_execution;
	HashTable *in_autoload;
	zend_function *autoload_func;
	zend_bool full_tables_cleanup;
	zend_bool ze1_compatibility_mode;

	/* for extended information support */
	zend_bool no_extensions;

#ifdef ZEND_WIN32
	zend_bool timed_out;
#endif

	HashTable regular_list;
	HashTable persistent_list;

	zend_ptr_stack argument_stack;

	int user_error_handler_error_reporting;
	zval *user_error_handler;
	zval *user_exception_handler;
	zend_stack user_error_handlers_error_reporting;
	zend_ptr_stack user_error_handlers;
	zend_ptr_stack user_exception_handlers;

	/* timeout support */
	int timeout_seconds;

	int lambda_count;

	HashTable *ini_directives;
	HashTable *modified_ini_directives;

	zend_objects_store objects_store;
	zval *exception;
	zend_op *opline_before_exception;

	struct _zend_execute_data *current_execute_data;

	struct _zend_module_entry *current_module;

	zend_property_info std_property_info;

	zend_bool active; 

	void *reserved[ZEND_MAX_RESERVED_RESOURCES];
};

struct _zend_scanner_globals {
	zend_file_handle *yy_in;
	zend_file_handle *yy_out;
	int yy_leng;
	char *yy_text;
	struct yy_buffer_state *current_buffer;
	char *c_buf_p;
	int init;
	int start;
	int lineno;
	char _yy_hold_char;
	int yy_n_chars;
	int _yy_did_buffer_switch_on_eof;
	int _yy_last_accepting_state; /* Must be of the same type as yy_state_type,
								   * if for whatever reason it's no longer int!
								   */
	char *_yy_last_accepting_cpos;
	int _yy_more_flag;
	int _yy_more_len;
	int yy_start_stack_ptr;
	int yy_start_stack_depth;
	int *yy_start_stack;

#ifdef ZEND_MULTIBYTE
	/* original (unfiltered) script */
	char *script_org;
	int script_org_size;

	/* filtered script */
	char *script_filtered;
	int script_filtered_size;

	/* input/ouput filters */
	zend_encoding_filter input_filter;
	zend_encoding_filter output_filter;
	zend_encoding *script_encoding;
	zend_encoding *internal_encoding;
#endif /* ZEND_MULTIBYTE */
};

#endif /* ZEND_GLOBALS_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_language_scanner_defs.h000064400000000451151730542020013720 0ustar00/* Generated by re2c 1.0.1 */
#line 3 "Zend/zend_language_scanner_defs.h"

enum YYCONDTYPE {
	yycST_IN_SCRIPTING,
	yycST_LOOKING_FOR_PROPERTY,
	yycST_BACKQUOTE,
	yycST_DOUBLE_QUOTES,
	yycST_HEREDOC,
	yycST_LOOKING_FOR_VARNAME,
	yycST_VAR_OFFSET,
	yycINITIAL,
	yycST_END_HEREDOC,
	yycST_NOWDOC,
};
php/Zend/zend_range_check.h000064400000006116151730542030011661 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2018 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Anatol Belski <ab@php.net>                                  |
   +----------------------------------------------------------------------+
*/

#ifndef ZEND_RANGE_CHECK_H
#define ZEND_RANGE_CHECK_H

#include "zend_long.h"

/* Flag macros for basic range recognition. Notable is that
   always sizeof(signed) == sizeof(unsigned), so no need to
   overcomplicate things. */
#if SIZEOF_INT < SIZEOF_ZEND_LONG
# define ZEND_LONG_CAN_OVFL_INT 1
# define ZEND_LONG_CAN_OVFL_UINT 1
#endif

#if SIZEOF_INT < SIZEOF_SIZE_T
/* size_t can always overflow signed int on the same platform.
   Furthermore, by the current design, size_t can always
   overflow zend_long. */
# define ZEND_SIZE_T_CAN_OVFL_UINT 1
#endif


/* zend_long vs. (unsigned) int checks. */
#ifdef ZEND_LONG_CAN_OVFL_INT
# define ZEND_LONG_INT_OVFL(zlong) UNEXPECTED((zlong) > (zend_long)INT_MAX)
# define ZEND_LONG_INT_UDFL(zlong) UNEXPECTED((zlong) < (zend_long)INT_MIN)
# define ZEND_LONG_EXCEEDS_INT(zlong) UNEXPECTED(ZEND_LONG_INT_OVFL(zlong) || ZEND_LONG_INT_UDFL(zlong))
# define ZEND_LONG_UINT_OVFL(zlong) UNEXPECTED((zlong) < 0 || (zlong) > (zend_long)UINT_MAX)
#else
# define ZEND_LONG_INT_OVFL(zl) (0)
# define ZEND_LONG_INT_UDFL(zl) (0)
# define ZEND_LONG_EXCEEDS_INT(zlong) (0)
# define ZEND_LONG_UINT_OVFL(zl) (0)
#endif

/* size_t vs (unsigned) int checks. */
#define ZEND_SIZE_T_INT_OVFL(size) 	UNEXPECTED((size) > (size_t)INT_MAX)
#ifdef ZEND_SIZE_T_CAN_OVFL_UINT
# define ZEND_SIZE_T_UINT_OVFL(size) UNEXPECTED((size) > (size_t)UINT_MAX)
#else
# define ZEND_SIZE_T_UINT_OVFL(size) (0)
#endif

/* Comparison zend_long vs size_t */
#define ZEND_SIZE_T_GT_ZEND_LONG(size, zlong) ((zlong) < 0 || (size) > (size_t)(zlong))
#define ZEND_SIZE_T_GTE_ZEND_LONG(size, zlong) ((zlong) < 0 || (size) >= (size_t)(zlong))
#define ZEND_SIZE_T_LT_ZEND_LONG(size, zlong) ((zlong) >= 0 && (size) < (size_t)(zlong))
#define ZEND_SIZE_T_LTE_ZEND_LONG(size, zlong) ((zlong) >= 0 && (size) <= (size_t)(zlong))

#endif /* ZEND_RANGE_CHECK_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/Zend/zend_smart_str_public.h000064400000002625151730542030013005 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 7                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2018 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Sascha Schumann <sascha@schumann.cx>                         |
   +----------------------------------------------------------------------+
 */

#ifndef ZEND_SMART_STR_PUBLIC_H
#define ZEND_SMART_STR_PUBLIC_H

typedef struct {
	zend_string *s;
	size_t a;
} smart_str;

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/Zend/zend_interfaces.h000064400000006735151730542030011562 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Marcus Boerger <helly@php.net>                              |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_interfaces.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef ZEND_INTERFACES_H
#define ZEND_INTERFACES_H

#include "zend.h"
#include "zend_API.h"

BEGIN_EXTERN_C()

extern ZEND_API zend_class_entry *zend_ce_traversable;
extern ZEND_API zend_class_entry *zend_ce_aggregate;
extern ZEND_API zend_class_entry *zend_ce_iterator;
extern ZEND_API zend_class_entry *zend_ce_arrayaccess;
extern ZEND_API zend_class_entry *zend_ce_serializable;

typedef struct _zend_user_iterator {
	zend_object_iterator     it;
	zend_class_entry         *ce;
	zval                     *value;
} zend_user_iterator;

ZEND_API zval* zend_call_method(zval **object_pp, zend_class_entry *obj_ce, zend_function **fn_proxy, char *function_name, int function_name_len, zval **retval_ptr_ptr, int param_count, zval* arg1, zval* arg2 TSRMLS_DC);

#define zend_call_method_with_0_params(obj, obj_ce, fn_proxy, function_name, retval) \
	zend_call_method(obj, obj_ce, fn_proxy, function_name, sizeof(function_name)-1, retval, 0, NULL, NULL TSRMLS_CC)

#define zend_call_method_with_1_params(obj, obj_ce, fn_proxy, function_name, retval, arg1) \
	zend_call_method(obj, obj_ce, fn_proxy, function_name, sizeof(function_name)-1, retval, 1, arg1, NULL TSRMLS_CC)

#define zend_call_method_with_2_params(obj, obj_ce, fn_proxy, function_name, retval, arg1, arg2) \
	zend_call_method(obj, obj_ce, fn_proxy, function_name, sizeof(function_name)-1, retval, 2, arg1, arg2 TSRMLS_CC)

ZEND_API void zend_user_it_rewind(zend_object_iterator *_iter TSRMLS_DC);
ZEND_API int zend_user_it_valid(zend_object_iterator *_iter TSRMLS_DC);
ZEND_API int zend_user_it_get_current_key(zend_object_iterator *_iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC);
ZEND_API void zend_user_it_get_current_data(zend_object_iterator *_iter, zval ***data TSRMLS_DC);
ZEND_API void zend_user_it_move_forward(zend_object_iterator *_iter TSRMLS_DC);
ZEND_API void zend_user_it_invalidate_current(zend_object_iterator *_iter TSRMLS_DC);

ZEND_API zval *zend_user_it_new_iterator(zend_class_entry *ce, zval *object TSRMLS_DC);
ZEND_API zend_object_iterator *zend_user_it_get_new_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC);

ZEND_API void zend_register_interfaces(TSRMLS_D);

END_EXTERN_C()

#endif /* ZEND_INTERFACES_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_types.h000064400000003731151730542030010574 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_types.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef ZEND_TYPES_H
#define ZEND_TYPES_H

typedef unsigned char zend_bool;
typedef unsigned char zend_uchar;
typedef unsigned int zend_uint;
typedef unsigned long zend_ulong;
typedef unsigned short zend_ushort;

#ifdef _WIN64
typedef __int64 zend_intptr_t;
typedef unsigned __int64 zend_uintptr_t;
#else
typedef long zend_intptr_t;
typedef unsigned long zend_uintptr_t;
#endif

typedef unsigned int zend_object_handle;
typedef struct _zend_object_handlers zend_object_handlers;

typedef struct _zend_object_value {
	zend_object_handle handle;
	zend_object_handlers *handlers;
} zend_object_value;

#endif /* ZEND_TYPES_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_object_handlers.h000064400000020006151730542030012550 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_object_handlers.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef ZEND_OBJECT_HANDLERS_H
#define ZEND_OBJECT_HANDLERS_H

union _zend_function;
struct _zend_property_info;

/* The following rule applies to read_property() and read_dimension() implementations:
   If you return a zval which is not otherwise referenced by the extension or the engine's
   symbol table, its reference count should be 0.
*/
/* Used to fetch property from the object, read-only */
typedef zval *(*zend_object_read_property_t)(zval *object, zval *member, int type TSRMLS_DC);

/* Used to fetch dimension from the object, read-only */
typedef zval *(*zend_object_read_dimension_t)(zval *object, zval *offset, int type TSRMLS_DC);


/* The following rule applies to write_property() and write_dimension() implementations:
   If you receive a value zval in write_property/write_dimension, you may only modify it if
   its reference count is 1.  Otherwise, you must create a copy of that zval before making
   any changes.  You should NOT modify the reference count of the value passed to you.
*/
/* Used to set property of the object */
typedef void (*zend_object_write_property_t)(zval *object, zval *member, zval *value TSRMLS_DC);

/* Used to set dimension of the object */
typedef void (*zend_object_write_dimension_t)(zval *object, zval *offset, zval *value TSRMLS_DC);


/* Used to create pointer to the property of the object, for future direct r/w access */
typedef zval **(*zend_object_get_property_ptr_ptr_t)(zval *object, zval *member TSRMLS_DC);

/* Used to set object value. Can be used to override assignments and scalar
   write ops (like ++, +=) on the object */
typedef void (*zend_object_set_t)(zval **object, zval *value TSRMLS_DC);

/* Used to get object value. Can be used when converting object value to
 * one of the basic types and when using scalar ops (like ++, +=) on the object
 */
typedef zval* (*zend_object_get_t)(zval *object TSRMLS_DC);

/* Used to check if a property of the object exists */
/* param has_set_exists:
 * 0 (has) whether property exists and is not NULL
 * 1 (set) whether property exists and is true
 * 2 (exists) whether property exists
 */
typedef int (*zend_object_has_property_t)(zval *object, zval *member, int has_set_exists TSRMLS_DC);

/* Used to check if a dimension of the object exists */
typedef int (*zend_object_has_dimension_t)(zval *object, zval *member, int check_empty TSRMLS_DC);

/* Used to remove a property of the object */
typedef void (*zend_object_unset_property_t)(zval *object, zval *member TSRMLS_DC);

/* Used to remove a dimension of the object */
typedef void (*zend_object_unset_dimension_t)(zval *object, zval *offset TSRMLS_DC);

/* Used to get hash of the properties of the object, as hash of zval's */
typedef HashTable *(*zend_object_get_properties_t)(zval *object TSRMLS_DC);

/* Used to call methods */
/* args on stack! */
/* Andi - EX(fbc) (function being called) needs to be initialized already in the INIT fcall opcode so that the parameters can be parsed the right way. We need to add another callback for this.
 */
typedef int (*zend_object_call_method_t)(char *method, INTERNAL_FUNCTION_PARAMETERS);
typedef union _zend_function *(*zend_object_get_method_t)(zval **object_ptr, char *method, int method_len TSRMLS_DC);
typedef union _zend_function *(*zend_object_get_constructor_t)(zval *object TSRMLS_DC);

/* Object maintenance/destruction */
typedef void (*zend_object_add_ref_t)(zval *object TSRMLS_DC);
typedef void (*zend_object_del_ref_t)(zval *object TSRMLS_DC);
typedef void (*zend_object_delete_obj_t)(zval *object TSRMLS_DC);
typedef zend_object_value (*zend_object_clone_obj_t)(zval *object TSRMLS_DC);

typedef zend_class_entry *(*zend_object_get_class_entry_t)(zval *object TSRMLS_DC);
typedef int (*zend_object_get_class_name_t)(zval *object, char **class_name, zend_uint *class_name_len, int parent TSRMLS_DC);
typedef int (*zend_object_compare_t)(zval *object1, zval *object2 TSRMLS_DC);

/* Cast an object to some other type
 */
typedef int (*zend_object_cast_t)(zval *readobj, zval *retval, int type TSRMLS_DC);

/* updates *count to hold the number of elements present and returns SUCCESS.
 * Returns FAILURE if the object does not have any sense of overloaded dimensions */
typedef int (*zend_object_count_elements_t)(zval *object, long *count TSRMLS_DC);

struct _zend_object_handlers {
	/* general object functions */
	zend_object_add_ref_t					add_ref;
	zend_object_del_ref_t					del_ref;
	zend_object_clone_obj_t					clone_obj;
	/* individual object functions */
	zend_object_read_property_t				read_property;
	zend_object_write_property_t			write_property;
	zend_object_read_dimension_t			read_dimension;
	zend_object_write_dimension_t			write_dimension;
	zend_object_get_property_ptr_ptr_t		get_property_ptr_ptr;
	zend_object_get_t						get;
	zend_object_set_t						set;
	zend_object_has_property_t				has_property;
	zend_object_unset_property_t			unset_property;
	zend_object_has_dimension_t				has_dimension;
	zend_object_unset_dimension_t			unset_dimension;
	zend_object_get_properties_t			get_properties;
	zend_object_get_method_t				get_method;
	zend_object_call_method_t				call_method;
	zend_object_get_constructor_t			get_constructor;
	zend_object_get_class_entry_t			get_class_entry;
	zend_object_get_class_name_t			get_class_name;
	zend_object_compare_t					compare_objects;
	zend_object_cast_t						cast_object;
	zend_object_count_elements_t			count_elements;
};

extern ZEND_API zend_object_handlers std_object_handlers;

BEGIN_EXTERN_C()
ZEND_API union _zend_function *zend_std_get_static_method(zend_class_entry *ce, char *function_name_strval, int function_name_strlen TSRMLS_DC);
ZEND_API zval **zend_std_get_static_property(zend_class_entry *ce, char *property_name, int property_name_len, zend_bool silent TSRMLS_DC);
ZEND_API zend_bool zend_std_unset_static_property(zend_class_entry *ce, char *property_name, int property_name_len TSRMLS_DC);
ZEND_API union _zend_function *zend_std_get_constructor(zval *object TSRMLS_DC);
ZEND_API struct _zend_property_info *zend_get_property_info(zend_class_entry *ce, zval *member, int silent TSRMLS_DC);

ZEND_API int zend_std_cast_object_tostring(zval *readobj, zval *writeobj, int type TSRMLS_DC);


#define IS_ZEND_STD_OBJECT(z)  (Z_TYPE(z) == IS_OBJECT && (Z_OBJ_HT((z))->get_class_entry != NULL))
#define HAS_CLASS_ENTRY(z) (Z_OBJ_HT(z)->get_class_entry != NULL)

ZEND_API int zend_check_private(union _zend_function *fbc, zend_class_entry *ce, char *function_name_strval, int function_name_strlen TSRMLS_DC);

ZEND_API int zend_check_protected(zend_class_entry *ce, zend_class_entry *scope);

ZEND_API int zend_check_property_access(zend_object *zobj, char *prop_info_name, int prop_info_name_len TSRMLS_DC);

ZEND_API void zend_std_call_user_call(INTERNAL_FUNCTION_PARAMETERS);
END_EXTERN_C()

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_istdiostream.h000064400000003252151730542030012135 0ustar00/* 
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_istdiostream.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef _ZEND_STDIOSTREAM
#define _ZEND_STDIOSTREAM

#if defined(ZTS) && !defined(HAVE_CLASS_ISTDIOSTREAM)
class istdiostream : public istream
{
private:
	stdiobuf _file;
public:
	istdiostream (FILE* __f) : istream(), _file(__f) { init(&_file); }
	stdiobuf* rdbuf()/* const */ { return &_file; }
};
#endif

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_alloc_sizes.h000064400000005333151730542030011737 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2018 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Dmitry Stogov <dmitry@zend.com>                             |
   +----------------------------------------------------------------------+
*/

#ifndef ZEND_ALLOC_SIZES_H
#define ZEND_ALLOC_SIZES_H

#define ZEND_MM_CHUNK_SIZE (2 * 1024 * 1024)               /* 2 MB  */
#define ZEND_MM_PAGE_SIZE  (4 * 1024)                      /* 4 KB  */
#define ZEND_MM_PAGES      (ZEND_MM_CHUNK_SIZE / ZEND_MM_PAGE_SIZE)  /* 512 */
#define ZEND_MM_FIRST_PAGE (1)

#define ZEND_MM_MIN_SMALL_SIZE		8
#define ZEND_MM_MAX_SMALL_SIZE      3072
#define ZEND_MM_MAX_LARGE_SIZE      (ZEND_MM_CHUNK_SIZE - (ZEND_MM_PAGE_SIZE * ZEND_MM_FIRST_PAGE))

/* num, size, count, pages */
#define ZEND_MM_BINS_INFO(_, x, y) \
	_( 0,    8,  512, 1, x, y) \
	_( 1,   16,  256, 1, x, y) \
	_( 2,   24,  170, 1, x, y) \
	_( 3,   32,  128, 1, x, y) \
	_( 4,   40,  102, 1, x, y) \
	_( 5,   48,   85, 1, x, y) \
	_( 6,   56,   73, 1, x, y) \
	_( 7,   64,   64, 1, x, y) \
	_( 8,   80,   51, 1, x, y) \
	_( 9,   96,   42, 1, x, y) \
	_(10,  112,   36, 1, x, y) \
	_(11,  128,   32, 1, x, y) \
	_(12,  160,   25, 1, x, y) \
	_(13,  192,   21, 1, x, y) \
	_(14,  224,   18, 1, x, y) \
	_(15,  256,   16, 1, x, y) \
	_(16,  320,   64, 5, x, y) \
	_(17,  384,   32, 3, x, y) \
	_(18,  448,    9, 1, x, y) \
	_(19,  512,    8, 1, x, y) \
	_(20,  640,   32, 5, x, y) \
	_(21,  768,   16, 3, x, y) \
	_(22,  896,    9, 2, x, y) \
	_(23, 1024,    8, 2, x, y) \
	_(24, 1280,   16, 5, x, y) \
	_(25, 1536,    8, 3, x, y) \
	_(26, 1792,   16, 7, x, y) \
	_(27, 2048,    8, 4, x, y) \
	_(28, 2560,    8, 5, x, y) \
	_(29, 3072,    4, 3, x, y)

#endif /* ZEND_ALLOC_SIZES_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/Zend/zend_list.h000064400000012140151730542040010376 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        | 
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_list.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef ZEND_LIST_H
#define ZEND_LIST_H

#include "zend_hash.h"
#include "zend_globals.h"

BEGIN_EXTERN_C()

#define ZEND_RESOURCE_LIST_TYPE_STD	1
#define ZEND_RESOURCE_LIST_TYPE_EX	2

typedef struct _zend_rsrc_list_entry {
	void *ptr;
	int type;
	int refcount;
} zend_rsrc_list_entry;

typedef void (*rsrc_dtor_func_t)(zend_rsrc_list_entry *rsrc TSRMLS_DC);
#define ZEND_RSRC_DTOR_FUNC(name)		void name(zend_rsrc_list_entry *rsrc TSRMLS_DC)

typedef struct _zend_rsrc_list_dtors_entry {
	/* old style destructors */
	void (*list_dtor)(void *);
	void (*plist_dtor)(void *);

	/* new style destructors */
	rsrc_dtor_func_t list_dtor_ex;
	rsrc_dtor_func_t plist_dtor_ex;

	char *type_name;

	int module_number;
	int resource_id;
	unsigned char type;
} zend_rsrc_list_dtors_entry;


#define register_list_destructors(ld, pld) zend_register_list_destructors((void (*)(void *))ld, (void (*)(void *))pld, module_number);
ZEND_API int zend_register_list_destructors(void (*ld)(void *), void (*pld)(void *), int module_number);
ZEND_API int zend_register_list_destructors_ex(rsrc_dtor_func_t ld, rsrc_dtor_func_t pld, char *type_name, int module_number);

void list_entry_destructor(void *ptr);
void plist_entry_destructor(void *ptr);

void zend_clean_module_rsrc_dtors(int module_number TSRMLS_DC);
int zend_init_rsrc_list(TSRMLS_D);
int zend_init_rsrc_plist(TSRMLS_D);
void zend_destroy_rsrc_list(HashTable *ht TSRMLS_DC);
int zend_init_rsrc_list_dtors(void);
void zend_destroy_rsrc_list_dtors(void);

ZEND_API int zend_list_insert(void *ptr, int type);
ZEND_API int _zend_list_addref(int id TSRMLS_DC);
ZEND_API int _zend_list_delete(int id TSRMLS_DC);
ZEND_API void *_zend_list_find(int id, int *type TSRMLS_DC);

#define zend_list_addref(id)		_zend_list_addref(id TSRMLS_CC)
#define zend_list_delete(id)		_zend_list_delete(id TSRMLS_CC)
#define zend_list_find(id, type)	_zend_list_find(id, type TSRMLS_CC)

ZEND_API int zend_register_resource(zval *rsrc_result, void *rsrc_pointer, int rsrc_type);
ZEND_API void *zend_fetch_resource(zval **passed_id TSRMLS_DC, int default_id, char *resource_type_name, int *found_resource_type, int num_resource_types, ...);

ZEND_API char *zend_rsrc_list_get_rsrc_type(int resource TSRMLS_DC);
ZEND_API int zend_fetch_list_dtor_id(char *type_name);

extern ZEND_API int le_index_ptr;  /* list entry type for index pointers */

#define ZEND_VERIFY_RESOURCE(rsrc)		\
	if (!rsrc) {						\
		RETURN_FALSE;					\
	}

#define ZEND_FETCH_RESOURCE(rsrc, rsrc_type, passed_id, default_id, resource_type_name, resource_type)	\
	rsrc = (rsrc_type) zend_fetch_resource(passed_id TSRMLS_CC, default_id, resource_type_name, NULL, 1, resource_type);	\
	ZEND_VERIFY_RESOURCE(rsrc);
	
#define ZEND_FETCH_RESOURCE_NO_RETURN(rsrc, rsrc_type, passed_id, default_id, resource_type_name, resource_type)	\
	(rsrc = (rsrc_type) zend_fetch_resource(passed_id TSRMLS_CC, default_id, resource_type_name, NULL, 1, resource_type))

#define ZEND_FETCH_RESOURCE2(rsrc, rsrc_type, passed_id, default_id, resource_type_name, resource_type1, resource_type2)	\
	rsrc = (rsrc_type) zend_fetch_resource(passed_id TSRMLS_CC, default_id, resource_type_name, NULL, 2, resource_type1, resource_type2);	\
	ZEND_VERIFY_RESOURCE(rsrc);
	
#define ZEND_FETCH_RESOURCE2_NO_RETURN(rsrc, rsrc_type, passed_id, default_id, resource_type_name, resource_type1, resource_type2)	\
	(rsrc = (rsrc_type) zend_fetch_resource(passed_id TSRMLS_CC, default_id, resource_type_name, NULL, 2, resource_type1, resource_type2))

#define ZEND_REGISTER_RESOURCE(rsrc_result, rsrc_pointer, rsrc_type)  \
    zend_register_resource(rsrc_result, rsrc_pointer, rsrc_type);

#define ZEND_GET_RESOURCE_TYPE_ID(le_id, le_type_name) \
    if (le_id == 0) {                                  \
        le_id = zend_fetch_list_dtor_id(le_type_name); \
	}
END_EXTERN_C()

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_alloc.h000064400000027020151730542040010520 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        | 
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_alloc.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef ZEND_ALLOC_H
#define ZEND_ALLOC_H

#include <stdio.h>

#include "../TSRM/TSRM.h"
#include "zend.h"

typedef struct _zend_leak_info {
	void *addr;
	size_t size;
	char *filename;
	uint lineno;
	char *orig_filename;
	uint orig_lineno;
} zend_leak_info;

BEGIN_EXTERN_C()

ZEND_API char *zend_strndup(const char *s, unsigned int length) ZEND_ATTRIBUTE_MALLOC;

ZEND_API void *_emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
ZEND_API void *_safe_emalloc(size_t nmemb, size_t size, size_t offset ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
ZEND_API void *_safe_malloc(size_t nmemb, size_t size, size_t offset) ZEND_ATTRIBUTE_MALLOC;
ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
ZEND_API void *_safe_erealloc(void *ptr, size_t nmemb, size_t size, size_t offset ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
ZEND_API void *_safe_realloc(void *ptr, size_t nmemb, size_t size, size_t offset);
ZEND_API char *_estrdup(const char *s ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
ZEND_API char *_estrndup(const char *s, unsigned int length ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
ZEND_API size_t _zend_mem_block_size(void *ptr TSRMLS_DC ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);

/* Standard wrapper macros */
#define emalloc(size)						_emalloc((size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
#define safe_emalloc(nmemb, size, offset)	_safe_emalloc((nmemb), (size), (offset) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
#define efree(ptr)							_efree((ptr) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
#define ecalloc(nmemb, size)				_ecalloc((nmemb), (size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
#define erealloc(ptr, size)					_erealloc((ptr), (size), 0 ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
#define safe_erealloc(ptr, nmemb, size, offset)	_safe_erealloc((ptr), (nmemb), (size), (offset) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
#define erealloc_recoverable(ptr, size)		_erealloc((ptr), (size), 1 ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
#define estrdup(s)							_estrdup((s) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
#define estrndup(s, length)					_estrndup((s), (length) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
#define zend_mem_block_size(ptr)			_zend_mem_block_size((ptr) TSRMLS_CC ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)

/* Relay wrapper macros */
#define emalloc_rel(size)						_emalloc((size) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
#define safe_emalloc_rel(nmemb, size, offset)	_safe_emalloc((nmemb), (size), (offset) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
#define efree_rel(ptr)							_efree((ptr) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
#define ecalloc_rel(nmemb, size)				_ecalloc((nmemb), (size) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
#define erealloc_rel(ptr, size)					_erealloc((ptr), (size), 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
#define erealloc_recoverable_rel(ptr, size)		_erealloc((ptr), (size), 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
#define safe_erealloc_rel(ptr, nmemb, size, offset)	_safe_erealloc((ptr), (nmemb), (size), (offset) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
#define estrdup_rel(s)							_estrdup((s) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
#define estrndup_rel(s, length)					_estrndup((s), (length) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
#define zend_mem_block_size_rel(ptr)			_zend_mem_block_size((ptr) TSRMLS_CC ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)

inline static void * __zend_malloc(size_t len)
{
	void *tmp = malloc(len);
	if (tmp) {
		return tmp;
	}
	fprintf(stderr, "Out of memory\n");
	exit(1);
}

inline static void * __zend_calloc(size_t nmemb, size_t len)
{
	void *tmp = _safe_malloc(nmemb, len, 0);
	memset(tmp, 0, nmemb * len);
	return tmp;
}

inline static void * __zend_realloc(void *p, size_t len)
{
	p = realloc(p, len);
	if (p) {
		return p;
	}
	fprintf(stderr, "Out of memory\n");
	exit(1);
}


/* Selective persistent/non persistent allocation macros */
#define pemalloc(size, persistent) ((persistent)?__zend_malloc(size):emalloc(size))
#define safe_pemalloc(nmemb, size, offset, persistent)	((persistent)?_safe_malloc(nmemb, size, offset):safe_emalloc(nmemb, size, offset))
#define pefree(ptr, persistent)  ((persistent)?free(ptr):efree(ptr))
#define pecalloc(nmemb, size, persistent) ((persistent)?__zend_calloc((nmemb), (size)):ecalloc((nmemb), (size)))
#define perealloc(ptr, size, persistent) ((persistent)?__zend_realloc((ptr), (size)):erealloc((ptr), (size)))
#define safe_perealloc(ptr, nmemb, size, offset, persistent)	((persistent)?_safe_realloc((ptr), (nmemb), (size), (offset)):safe_erealloc((ptr), (nmemb), (size), (offset)))
#define perealloc_recoverable(ptr, size, persistent) ((persistent)?__zend_realloc((ptr), (size)):erealloc_recoverable((ptr), (size)))
#define pestrdup(s, persistent) ((persistent)?strdup(s):estrdup(s))
#define pestrndup(s, length, persistent) ((persistent)?zend_strndup((s),(length)):estrndup((s),(length)))

#define pemalloc_rel(size, persistent) ((persistent)?__zend_malloc(size):emalloc_rel(size))
#define pefree_rel(ptr, persistent)	((persistent)?free(ptr):efree_rel(ptr))
#define pecalloc_rel(nmemb, size, persistent) ((persistent)?__zend_calloc((nmemb), (size)):ecalloc_rel((nmemb), (size)))
#define perealloc_rel(ptr, size, persistent) ((persistent)?__zend_realloc((ptr), (size)):erealloc_rel((ptr), (size)))
#define perealloc_recoverable_rel(ptr, size, persistent) ((persistent)?__zend_realloc((ptr), (size)):erealloc_recoverable_rel((ptr), (size)))
#define pestrdup_rel(s, persistent) ((persistent)?strdup(s):estrdup_rel(s))

#define safe_estrdup(ptr)  ((ptr)?(estrdup(ptr)):STR_EMPTY_ALLOC())
#define safe_estrndup(ptr, len) ((ptr)?(estrndup((ptr), (len))):STR_EMPTY_ALLOC())

ZEND_API int zend_set_memory_limit(size_t memory_limit);

ZEND_API void start_memory_manager(TSRMLS_D);
ZEND_API void shutdown_memory_manager(int silent, int full_shutdown TSRMLS_DC);
ZEND_API int is_zend_mm(TSRMLS_D);

#if ZEND_DEBUG
ZEND_API int _mem_block_check(void *ptr, int silent ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
ZEND_API void _full_mem_check(int silent ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
void zend_debug_alloc_output(char *format, ...);
#define mem_block_check(ptr, silent) _mem_block_check(ptr, silent ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
#define full_mem_check(silent) _full_mem_check(silent ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
#else
#define mem_block_check(type, ptr, silent)
#define full_mem_check(silent)
#endif

ZEND_API size_t zend_memory_usage(int real_usage TSRMLS_DC);
ZEND_API size_t zend_memory_peak_usage(int real_usage TSRMLS_DC);

END_EXTERN_C()

/* Macroses for zend_fast_cache.h compatibility */

#define ZEND_FAST_ALLOC(p, type, fc_type)	\
	(p) = (type *) emalloc(sizeof(type))

#define ZEND_FAST_FREE(p, fc_type)	\
	efree(p)

#define ZEND_FAST_ALLOC_REL(p, type, fc_type)	\
	(p) = (type *) emalloc_rel(sizeof(type))

#define ZEND_FAST_FREE_REL(p, fc_type)	\
	efree_rel(p)

/* fast cache for zval's */
#define ALLOC_ZVAL(z)	\
	ZEND_FAST_ALLOC(z, zval, ZVAL_CACHE_LIST)

#define FREE_ZVAL(z)	\
	ZEND_FAST_FREE(z, ZVAL_CACHE_LIST)

#define ALLOC_ZVAL_REL(z)	\
	ZEND_FAST_ALLOC_REL(z, zval, ZVAL_CACHE_LIST)

#define FREE_ZVAL_REL(z)	\
	ZEND_FAST_FREE_REL(z, ZVAL_CACHE_LIST)

/* fast cache for HashTables */
#define ALLOC_HASHTABLE(ht)	\
	ZEND_FAST_ALLOC(ht, HashTable, HASHTABLE_CACHE_LIST)

#define FREE_HASHTABLE(ht)	\
	ZEND_FAST_FREE(ht, HASHTABLE_CACHE_LIST)

#define ALLOC_HASHTABLE_REL(ht)	\
	ZEND_FAST_ALLOC_REL(ht, HashTable, HASHTABLE_CACHE_LIST)

#define FREE_HASHTABLE_REL(ht)	\
	ZEND_FAST_FREE_REL(ht, HASHTABLE_CACHE_LIST)

/* Heap functions */
typedef struct _zend_mm_heap zend_mm_heap;

ZEND_API zend_mm_heap *zend_mm_startup(void);
ZEND_API void zend_mm_shutdown(zend_mm_heap *heap, int full_shutdown, int silent);
ZEND_API void *_zend_mm_alloc(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
ZEND_API void _zend_mm_free(zend_mm_heap *heap, void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
ZEND_API void *_zend_mm_realloc(zend_mm_heap *heap, void *p, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
ZEND_API size_t _zend_mm_block_size(zend_mm_heap *heap, void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);

#define zend_mm_alloc(heap, size)			_zend_mm_alloc((heap), (size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
#define zend_mm_free(heap, p)				_zend_mm_free((heap), (p) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
#define zend_mm_realloc(heap, p, size)		_zend_mm_realloc((heap), (p), (size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
#define zend_mm_block_size(heap, p)			_zend_mm_block_size((heap), (p) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)

#define zend_mm_alloc_rel(heap, size)		_zend_mm_alloc((heap), (size) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
#define zend_mm_free_rel(heap, p)			_zend_mm_free((heap), (p) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
#define zend_mm_realloc_rel(heap, p, size)	_zend_mm_realloc((heap), (p), (size) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
#define zend_mm_block_size_rel(heap, p)		_zend_mm_block_size((heap), (p) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)

/* Heaps with user defined storage */
typedef struct _zend_mm_storage zend_mm_storage;

typedef struct _zend_mm_segment {
	size_t	size;
	struct _zend_mm_segment *next_segment;
} zend_mm_segment;

typedef struct _zend_mm_mem_handlers {
	const char *name;
	zend_mm_storage* (*init)(void *params);
	void (*dtor)(zend_mm_storage *storage);
	zend_mm_segment* (*_alloc)(zend_mm_storage *storage, size_t size);
	zend_mm_segment* (*_realloc)(zend_mm_storage *storage, zend_mm_segment *ptr, size_t size);
	void (*_free)(zend_mm_storage *storage, zend_mm_segment *ptr);
} zend_mm_mem_handlers;

struct _zend_mm_storage {
	const zend_mm_mem_handlers *handlers;
	void *data;
};

ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_mem_handlers *handlers, size_t block_size, size_t reserve_size, int internal, void *params);
ZEND_API zend_mm_heap *zend_mm_set_heap(zend_mm_heap *new_heap TSRMLS_DC);
ZEND_API zend_mm_storage *zend_mm_get_storage(zend_mm_heap *heap);

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_objects.h000064400000004330151730542040011056 0ustar00/* 
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_objects.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef ZEND_OBJECTS_H
#define ZEND_OBJECTS_H

#include "zend.h"

BEGIN_EXTERN_C()
ZEND_API void zend_object_std_init(zend_object *object, zend_class_entry *ce TSRMLS_DC);
ZEND_API void zend_object_std_dtor(zend_object *object TSRMLS_DC);
ZEND_API zend_object_value zend_objects_new(zend_object **object, zend_class_entry *class_type TSRMLS_DC);
ZEND_API void zend_objects_destroy_object(zend_object *object, zend_object_handle handle TSRMLS_DC);
ZEND_API zend_object *zend_objects_get_address(zval *object TSRMLS_DC);
ZEND_API void zend_objects_clone_members(zend_object *new_object, zend_object_value new_obj_val, zend_object *old_object, zend_object_handle handle TSRMLS_DC);
ZEND_API zend_object_value zend_objects_clone_obj(zval *object TSRMLS_DC);
ZEND_API void zend_objects_free_object_storage(zend_object *object TSRMLS_DC);
END_EXTERN_C()

#endif /* ZEND_OBJECTS_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_compile.h000064400000062162151730542040011064 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_compile.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef ZEND_COMPILE_H
#define ZEND_COMPILE_H

#include "zend.h"

#ifdef HAVE_STDARG_H
# include <stdarg.h>
#endif

#include "zend_llist.h"

#define DEBUG_ZEND 0

#define FREE_PNODE(znode)	zval_dtor(&znode->u.constant);

#define SET_UNUSED(op)  (op).op_type = IS_UNUSED

#define INC_BPC(op_array)	if (op_array->fn_flags & ZEND_ACC_INTERACTIVE) { ((op_array)->backpatch_count++); }
#define DEC_BPC(op_array)	if (op_array->fn_flags & ZEND_ACC_INTERACTIVE) { ((op_array)->backpatch_count--); }
#define HANDLE_INTERACTIVE()  if (CG(active_op_array)->fn_flags & ZEND_ACC_INTERACTIVE) { execute_new_code(TSRMLS_C); }

#define RESET_DOC_COMMENT()        \
    {                              \
        if (CG(doc_comment)) {     \
          efree(CG(doc_comment));  \
          CG(doc_comment) = NULL;  \
        }                          \
        CG(doc_comment_len) = 0;   \
    }

typedef struct _zend_op_array zend_op_array;
typedef struct _zend_op zend_op;

typedef struct _znode {
	int op_type;
	union {
		zval constant;

		zend_uint var;
		zend_uint opline_num; /*  Needs to be signed */
		zend_op_array *op_array;
		zend_op *jmp_addr;
		struct {
			zend_uint var;	/* dummy */
			zend_uint type;
		} EA;
	} u;
} znode;

typedef struct _zend_execute_data zend_execute_data;

#define ZEND_OPCODE_HANDLER_ARGS zend_execute_data *execute_data TSRMLS_DC
#define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU execute_data TSRMLS_CC

typedef int (*opcode_handler_t) (ZEND_OPCODE_HANDLER_ARGS);

extern ZEND_API opcode_handler_t *zend_opcode_handlers;

struct _zend_op {
	opcode_handler_t handler;
	znode result;
	znode op1;
	znode op2;
	ulong extended_value;
	uint lineno;
	zend_uchar opcode;
};


typedef struct _zend_brk_cont_element {
	int start;
	int cont;
	int brk;
	int parent;
} zend_brk_cont_element;


typedef struct _zend_try_catch_element {
	zend_uint try_op;
	zend_uint catch_op;  /* ketchup! */
} zend_try_catch_element;


/* method flags (types) */
#define ZEND_ACC_STATIC			0x01
#define ZEND_ACC_ABSTRACT		0x02
#define ZEND_ACC_FINAL			0x04
#define ZEND_ACC_IMPLEMENTED_ABSTRACT		0x08

/* class flags (types) */
/* ZEND_ACC_IMPLICIT_ABSTRACT_CLASS is used for abstract classes (since it is set by any abstract method even interfaces MAY have it set, too). */
/* ZEND_ACC_EXPLICIT_ABSTRACT_CLASS denotes that a class was explicitly defined as abstract by using the keyword. */
#define ZEND_ACC_IMPLICIT_ABSTRACT_CLASS	0x10
#define ZEND_ACC_EXPLICIT_ABSTRACT_CLASS	0x20
#define ZEND_ACC_FINAL_CLASS	            0x40
#define ZEND_ACC_INTERFACE		            0x80

/* op_array flags */
#define ZEND_ACC_INTERACTIVE				0x10

/* method flags (visibility) */
/* The order of those must be kept - public < protected < private */
#define ZEND_ACC_PUBLIC		0x100
#define ZEND_ACC_PROTECTED	0x200
#define ZEND_ACC_PRIVATE	0x400
#define ZEND_ACC_PPP_MASK  (ZEND_ACC_PUBLIC | ZEND_ACC_PROTECTED | ZEND_ACC_PRIVATE)

#define ZEND_ACC_CHANGED	0x800
#define ZEND_ACC_IMPLICIT_PUBLIC	0x1000

/* method flags (special method detection) */
#define ZEND_ACC_CTOR		0x2000
#define ZEND_ACC_DTOR		0x4000
#define ZEND_ACC_CLONE		0x8000

/* method flag (bc only), any method that has this flag can be used statically and non statically. */
#define ZEND_ACC_ALLOW_STATIC	0x10000

/* shadow of parent's private method/property */
#define ZEND_ACC_SHADOW 0x20000

/* deprecation flag */
#define ZEND_ACC_DEPRECATED 0x40000

/* function flag for internal user call handler __call */
#define ZEND_ACC_CALL_VIA_HANDLER     0x200000


char *zend_visibility_string(zend_uint fn_flags);


typedef struct _zend_property_info {
	zend_uint flags;
	char *name;
	int name_length;
	ulong h;
	char *doc_comment;
	int doc_comment_len;
	zend_class_entry *ce;
} zend_property_info;


typedef struct _zend_arg_info {
	char *name;
	zend_uint name_len;
	char *class_name;
	zend_uint class_name_len;
	zend_bool array_type_hint;
	zend_bool allow_null;
	zend_bool pass_by_reference;
	zend_bool return_reference;
	int required_num_args;
} zend_arg_info;

typedef struct _zend_compiled_variable {
	char *name;
	int name_len;
	ulong hash_value;
} zend_compiled_variable;

struct _zend_op_array {
	/* Common elements */
	zend_uchar type;
	char *function_name;		
	zend_class_entry *scope;
	zend_uint fn_flags;
	union _zend_function *prototype;
	zend_uint num_args;
	zend_uint required_num_args;
	zend_arg_info *arg_info;
	zend_bool pass_rest_by_reference;
	unsigned char return_reference;
	/* END of common elements */

	zend_uint *refcount;

	zend_op *opcodes;
	zend_uint last, size;

	zend_compiled_variable *vars;
	int last_var, size_var;

	zend_uint T;

	zend_brk_cont_element *brk_cont_array;
	zend_uint last_brk_cont;
	zend_uint current_brk_cont;

	zend_try_catch_element *try_catch_array;
	int last_try_catch;

	/* static variables support */
	HashTable *static_variables;

	zend_op *start_op;
	int backpatch_count;

	zend_bool done_pass_two;
	zend_bool uses_this;

	char *filename;
	zend_uint line_start;
	zend_uint line_end;
	char *doc_comment;
	zend_uint doc_comment_len;

	void *reserved[ZEND_MAX_RESERVED_RESOURCES];
};


#define ZEND_RETURN_VALUE				0
#define ZEND_RETURN_REFERENCE			1

typedef struct _zend_internal_function {
	/* Common elements */
	zend_uchar type;
	char * function_name;
	zend_class_entry *scope;
	zend_uint fn_flags;
	union _zend_function *prototype;
	zend_uint num_args;
	zend_uint required_num_args;
	zend_arg_info *arg_info;
	zend_bool pass_rest_by_reference;
	unsigned char return_reference;
	/* END of common elements */

	void (*handler)(INTERNAL_FUNCTION_PARAMETERS);
	struct _zend_module_entry *module;
} zend_internal_function;

#define ZEND_FN_SCOPE_NAME(function)  ((function) && (function)->common.scope ? (function)->common.scope->name : "")

typedef union _zend_function {
	zend_uchar type;	/* MUST be the first element of this struct! */

	struct {
		zend_uchar type;  /* never used */
		char *function_name;
		zend_class_entry *scope;
		zend_uint fn_flags;
		union _zend_function *prototype;
		zend_uint num_args;
		zend_uint required_num_args;
		zend_arg_info *arg_info;
		zend_bool pass_rest_by_reference;
		unsigned char return_reference;
	} common;

	zend_op_array op_array;
	zend_internal_function internal_function;
} zend_function;


typedef struct _zend_function_state {
	HashTable *function_symbol_table;
	zend_function *function;
	void *reserved[ZEND_MAX_RESERVED_RESOURCES];
} zend_function_state;


typedef struct _zend_switch_entry {
	znode cond;
	int default_case;
	int control_var;
} zend_switch_entry;


typedef struct _list_llist_element {
	znode var;
	zend_llist dimensions;
	znode value;
} list_llist_element;

union _temp_variable;

struct _zend_execute_data {
	struct _zend_op *opline;
	zend_function_state function_state;
	zend_function *fbc; /* Function Being Called */
	zend_op_array *op_array;
	zval *object;
	union _temp_variable *Ts;
	zval ***CVs;
	zend_bool original_in_execution;
	HashTable *symbol_table;
	struct _zend_execute_data *prev_execute_data;
	zval *old_error_reporting;
};

#define EX(element) execute_data.element


#define IS_CONST	(1<<0)
#define IS_TMP_VAR	(1<<1)
#define IS_VAR		(1<<2)
#define IS_UNUSED	(1<<3)	/* Unused variable */
#define IS_CV		(1<<4)	/* Compiled variable */

#define EXT_TYPE_UNUSED		(1<<0)

#include "zend_globals.h"

BEGIN_EXTERN_C()

void init_compiler(TSRMLS_D);
void shutdown_compiler(TSRMLS_D);
void zend_init_compiler_data_structures(TSRMLS_D);

extern ZEND_API zend_op_array *(*zend_compile_file)(zend_file_handle *file_handle, int type TSRMLS_DC);
extern ZEND_API zend_op_array *(*zend_compile_string)(zval *source_string, char *filename TSRMLS_DC);

ZEND_API int lex_scan(zval *zendlval TSRMLS_DC);
void startup_scanner(TSRMLS_D);
void shutdown_scanner(TSRMLS_D);

ZEND_API char *zend_set_compiled_filename(char *new_compiled_filename TSRMLS_DC);
ZEND_API void zend_restore_compiled_filename(char *original_compiled_filename TSRMLS_DC);
ZEND_API char *zend_get_compiled_filename(TSRMLS_D);
ZEND_API int zend_get_compiled_lineno(TSRMLS_D);
ZEND_API int zend_get_scanned_file_offset(TSRMLS_D);

ZEND_API char* zend_get_compiled_variable_name(zend_op_array *op_array, zend_uint var, int* name_len);

#ifdef ZTS
const char *zend_get_zendtext(TSRMLS_D);
int zend_get_zendleng(TSRMLS_D);
#endif


/* parser-driven code generators */
void zend_do_binary_op(zend_uchar op, znode *result, znode *op1, znode *op2 TSRMLS_DC);
void zend_do_unary_op(zend_uchar op, znode *result, znode *op1 TSRMLS_DC);
void zend_do_binary_assign_op(zend_uchar op, znode *result, znode *op1, znode *op2 TSRMLS_DC);
void zend_do_assign(znode *result, znode *variable, znode *value TSRMLS_DC);
void zend_do_assign_ref(znode *result, znode *lvar, znode *rvar TSRMLS_DC);
void fetch_simple_variable(znode *result, znode *varname, int bp TSRMLS_DC);
void fetch_simple_variable_ex(znode *result, znode *varname, int bp, zend_uchar op TSRMLS_DC);
void zend_do_indirect_references(znode *result, znode *num_references, znode *variable TSRMLS_DC);
void zend_do_fetch_static_variable(znode *varname, znode *static_assignment, int fetch_type TSRMLS_DC);
void zend_do_fetch_global_variable(znode *varname, znode *static_assignment, int fetch_type TSRMLS_DC);

void fetch_array_begin(znode *result, znode *varname, znode *first_dim TSRMLS_DC);
void fetch_array_dim(znode *result, znode *parent, znode *dim TSRMLS_DC);
void fetch_string_offset(znode *result, znode *parent, znode *offset TSRMLS_DC);
void zend_do_fetch_static_member(znode *result, znode *class_znode TSRMLS_DC);
void zend_do_print(znode *result, znode *arg TSRMLS_DC);
void zend_do_echo(znode *arg TSRMLS_DC);
typedef int (*unary_op_type)(zval *, zval *);
ZEND_API unary_op_type get_unary_op(int opcode);
ZEND_API void *get_binary_op(int opcode);

void zend_do_while_cond(znode *expr, znode *close_bracket_token TSRMLS_DC);
void zend_do_while_end(znode *while_token, znode *close_bracket_token TSRMLS_DC);
void zend_do_do_while_begin(TSRMLS_D);
void zend_do_do_while_end(znode *do_token, znode *expr_open_bracket, znode *expr TSRMLS_DC);


void zend_do_if_cond(znode *cond, znode *closing_bracket_token TSRMLS_DC);
void zend_do_if_after_statement(znode *closing_bracket_token, unsigned char initialize TSRMLS_DC);
void zend_do_if_end(TSRMLS_D);

void zend_do_for_cond(znode *expr, znode *second_semicolon_token TSRMLS_DC);
void zend_do_for_before_statement(znode *cond_start, znode *second_semicolon_token TSRMLS_DC);
void zend_do_for_end(znode *second_semicolon_token TSRMLS_DC);

void zend_do_pre_incdec(znode *result, znode *op1, zend_uchar op TSRMLS_DC);
void zend_do_post_incdec(znode *result, znode *op1, zend_uchar op TSRMLS_DC);

void zend_do_begin_variable_parse(TSRMLS_D);
void zend_do_end_variable_parse(int type, int arg_offset TSRMLS_DC);

void zend_check_writable_variable(znode *variable);

void zend_do_free(znode *op1 TSRMLS_DC);

void zend_do_init_string(znode *result TSRMLS_DC);
void zend_do_add_string(znode *result, znode *op1, znode *op2 TSRMLS_DC);
void zend_do_add_variable(znode *result, znode *op1, znode *op2 TSRMLS_DC);

int zend_do_verify_access_types(znode *current_access_type, znode *new_modifier);
void zend_do_begin_function_declaration(znode *function_token, znode *function_name, int is_method, int return_reference, znode *fn_flags_znode TSRMLS_DC);
void zend_do_end_function_declaration(znode *function_token TSRMLS_DC);
void zend_do_receive_arg(zend_uchar op, znode *var, znode *offset, znode *initialization, znode *class_type, znode *varname, zend_bool pass_by_reference TSRMLS_DC);
int zend_do_begin_function_call(znode *function_name TSRMLS_DC);
void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC);
void zend_do_clone(znode *result, znode *expr TSRMLS_DC);
void zend_do_begin_dynamic_function_call(znode *function_name TSRMLS_DC);
void zend_do_fetch_class(znode *result, znode *class_name TSRMLS_DC);
void zend_do_fetch_class_name(znode *result, znode *class_entry, znode *class_name TSRMLS_DC);
void zend_do_begin_class_member_function_call(znode *class_name, znode *method_name TSRMLS_DC);
void zend_do_end_function_call(znode *function_name, znode *result, znode *argument_list, int is_method, int is_dynamic_fcall TSRMLS_DC);
void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC);
void zend_do_handle_exception(TSRMLS_D);

void zend_do_try(znode *try_token TSRMLS_DC);
void zend_do_begin_catch(znode *try_token, znode *catch_class, znode *catch_var, zend_bool first_catch TSRMLS_DC);
void zend_do_end_catch(znode *try_token TSRMLS_DC);
void zend_do_throw(znode *expr TSRMLS_DC);

ZEND_API int do_bind_function(zend_op *opline, HashTable *function_table, zend_bool compile_time);
ZEND_API zend_class_entry *do_bind_class(zend_op *opline, HashTable *class_table, zend_bool compile_time TSRMLS_DC);
ZEND_API zend_class_entry *do_bind_inherited_class(zend_op *opline, HashTable *class_table, zend_class_entry *parent_ce, zend_bool compile_time TSRMLS_DC);
ZEND_API void zend_do_inherit_interfaces(zend_class_entry *ce, zend_class_entry *iface TSRMLS_DC);
ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry *iface TSRMLS_DC);
void zend_do_implements_interface(znode *interface_znode TSRMLS_DC);

ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent_ce TSRMLS_DC);
void zend_do_early_binding(TSRMLS_D);

void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC);


void zend_do_boolean_or_begin(znode *expr1, znode *op_token TSRMLS_DC);
void zend_do_boolean_or_end(znode *result, znode *expr1, znode *expr2, znode *op_token TSRMLS_DC);
void zend_do_boolean_and_begin(znode *expr1, znode *op_token TSRMLS_DC);
void zend_do_boolean_and_end(znode *result, znode *expr1, znode *expr2, znode *op_token TSRMLS_DC);

void zend_do_brk_cont(zend_uchar op, znode *expr TSRMLS_DC);

void zend_do_switch_cond(znode *cond TSRMLS_DC);
void zend_do_switch_end(znode *case_list TSRMLS_DC);
void zend_do_case_before_statement(znode *case_list, znode *case_token, znode *case_expr TSRMLS_DC);
void zend_do_case_after_statement(znode *result, znode *case_token TSRMLS_DC);
void zend_do_default_before_statement(znode *case_list, znode *default_token TSRMLS_DC);

void zend_do_begin_class_declaration(znode *class_token, znode *class_name, znode *parent_class_name TSRMLS_DC);
void zend_do_end_class_declaration(znode *class_token, znode *parent_token TSRMLS_DC);
void zend_do_declare_property(znode *var_name, znode *value, zend_uint access_type TSRMLS_DC);
void zend_do_declare_implicit_property(TSRMLS_D);
void zend_do_declare_class_constant(znode *var_name, znode *value TSRMLS_DC);

void zend_do_fetch_property(znode *result, znode *object, znode *property TSRMLS_DC);

void zend_do_halt_compiler_register(TSRMLS_D);

void zend_do_push_object(znode *object TSRMLS_DC);
void zend_do_pop_object(znode *object TSRMLS_DC);


void zend_do_begin_new_object(znode *new_token, znode *class_type TSRMLS_DC);
void zend_do_end_new_object(znode *result, znode *new_token, znode *argument_list TSRMLS_DC);

void zend_do_fetch_constant(znode *result, znode *constant_container, znode *constant_name, int mode TSRMLS_DC);

void zend_do_shell_exec(znode *result, znode *cmd TSRMLS_DC);

void zend_do_init_array(znode *result, znode *expr, znode *offset, zend_bool is_ref TSRMLS_DC);
void zend_do_add_array_element(znode *result, znode *expr, znode *offset, zend_bool is_ref TSRMLS_DC);
void zend_do_add_static_array_element(znode *result, znode *offset, znode *expr);
void zend_do_list_init(TSRMLS_D);
void zend_do_list_end(znode *result, znode *expr TSRMLS_DC);
void zend_do_add_list_element(znode *element TSRMLS_DC);
void zend_do_new_list_begin(TSRMLS_D);
void zend_do_new_list_end(TSRMLS_D);

void zend_do_cast(znode *result, znode *expr, int type TSRMLS_DC);
void zend_do_include_or_eval(int type, znode *result, znode *op1 TSRMLS_DC);

void zend_do_unset(znode *variable TSRMLS_DC);
void zend_do_isset_or_isempty(int type, znode *result, znode *variable TSRMLS_DC);

void zend_do_instanceof(znode *result, znode *expr, znode *class_znode, int type TSRMLS_DC);

void zend_do_foreach_begin(znode *foreach_token, znode *open_brackets_token, znode *array, znode *as_token, int variable TSRMLS_DC);
void zend_do_foreach_cont(znode *foreach_token, znode *open_brackets_token, znode *as_token, znode *value, znode *key TSRMLS_DC);
void zend_do_foreach_end(znode *foreach_token, znode *as_token TSRMLS_DC);

void zend_do_declare_begin(TSRMLS_D);
void zend_do_declare_stmt(znode *var, znode *val TSRMLS_DC);
void zend_do_declare_end(znode *declare_token TSRMLS_DC);

void zend_do_exit(znode *result, znode *message TSRMLS_DC);

void zend_do_begin_silence(znode *strudel_token TSRMLS_DC);
void zend_do_end_silence(znode *strudel_token TSRMLS_DC);

void zend_do_begin_qm_op(znode *cond, znode *qm_token TSRMLS_DC);
void zend_do_qm_true(znode *true_value, znode *qm_token, znode *colon_token TSRMLS_DC);
void zend_do_qm_false(znode *result, znode *false_value, znode *qm_token, znode *colon_token TSRMLS_DC);

void zend_do_extended_info(TSRMLS_D);
void zend_do_extended_fcall_begin(TSRMLS_D);
void zend_do_extended_fcall_end(TSRMLS_D);

void zend_do_ticks(TSRMLS_D);

void zend_do_abstract_method(znode *function_name, znode *modifiers, znode *body TSRMLS_DC);

ZEND_API void function_add_ref(zend_function *function);

#define INITIAL_OP_ARRAY_SIZE 64


/* helper functions in zend_language_scanner.l */
ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type TSRMLS_DC);
ZEND_API zend_op_array *compile_string(zval *source_string, char *filename TSRMLS_DC);
ZEND_API zend_op_array *compile_filename(int type, zval *filename TSRMLS_DC);
ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval **retval, int file_count, ...);
ZEND_API int open_file_for_scanning(zend_file_handle *file_handle TSRMLS_DC);
ZEND_API void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_size TSRMLS_DC);
ZEND_API void destroy_op_array(zend_op_array *op_array TSRMLS_DC);
ZEND_API void zend_destroy_file_handle(zend_file_handle *file_handle TSRMLS_DC);
ZEND_API void zend_file_handle_dtor(zend_file_handle *fh);
ZEND_API int zend_cleanup_class_data(zend_class_entry **pce TSRMLS_DC);
ZEND_API int zend_cleanup_function_data(zend_function *function TSRMLS_DC);
ZEND_API int zend_cleanup_function_data_full(zend_function *function TSRMLS_DC);

ZEND_API void destroy_zend_function(zend_function *function TSRMLS_DC);
ZEND_API void zend_function_dtor(zend_function *function);
ZEND_API void destroy_zend_class(zend_class_entry **pce);
void zend_class_add_ref(zend_class_entry **ce);

ZEND_API void zend_mangle_property_name(char **dest, int *dest_length, char *src1, int src1_length, char *src2, int src2_length, int internal);
ZEND_API int zend_unmangle_property_name(char *mangled_property, int mangled_property_len, char **prop_name, char **class_name);

#define ZEND_FUNCTION_DTOR (void (*)(void *)) zend_function_dtor
#define ZEND_CLASS_DTOR (void (*)(void *)) destroy_zend_class

zend_op *get_next_op(zend_op_array *op_array TSRMLS_DC);
void init_op(zend_op *op TSRMLS_DC);
int get_next_op_number(zend_op_array *op_array);
int print_class(zend_class_entry *class_entry TSRMLS_DC);
void print_op_array(zend_op_array *op_array, int optimizations);
int pass_two(zend_op_array *op_array TSRMLS_DC);
zend_brk_cont_element *get_next_brk_cont_element(zend_op_array *op_array);
void zend_do_first_catch(znode *open_parentheses TSRMLS_DC);
void zend_initialize_try_catch_element(znode *try_token TSRMLS_DC);
void zend_do_mark_last_catch(znode *first_catch, znode *last_additional_catch TSRMLS_DC);
ZEND_API zend_bool zend_is_compiling(TSRMLS_D);
ZEND_API char *zend_make_compiled_string_description(char *name TSRMLS_DC);
ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify_handlers TSRMLS_DC);
int zend_get_class_fetch_type(char *class_name, uint class_name_len);

typedef zend_bool (*zend_auto_global_callback)(char *name, uint name_len TSRMLS_DC);
typedef struct _zend_auto_global {
	char *name;
	uint name_len;
	zend_auto_global_callback auto_global_callback;
	zend_bool armed;
} zend_auto_global;

void zend_auto_global_dtor(zend_auto_global *auto_global);
ZEND_API int zend_register_auto_global(char *name, uint name_len, zend_auto_global_callback auto_global_callback TSRMLS_DC);
ZEND_API zend_bool zend_is_auto_global(char *name, uint name_len TSRMLS_DC);
ZEND_API int zend_auto_global_disable_jit(char *varname, zend_uint varname_length TSRMLS_DC);

int zendlex(znode *zendlval TSRMLS_DC);

/* BEGIN: OPCODES */

#include "zend_vm_opcodes.h"

#define ZEND_OP_DATA				137

/* END: OPCODES */




/* global/local fetches */
#define ZEND_FETCH_GLOBAL			0
#define ZEND_FETCH_LOCAL			1
#define ZEND_FETCH_STATIC			2
#define ZEND_FETCH_STATIC_MEMBER	3
#define ZEND_FETCH_GLOBAL_LOCK	4


/* class fetches */
#define ZEND_FETCH_CLASS_DEFAULT	0
#define ZEND_FETCH_CLASS_SELF		1
#define ZEND_FETCH_CLASS_PARENT		2
#define ZEND_FETCH_CLASS_MAIN		3
#define ZEND_FETCH_CLASS_GLOBAL		4
#define ZEND_FETCH_CLASS_AUTO		5
#define ZEND_FETCH_CLASS_INTERFACE	6
#define ZEND_FETCH_CLASS_NO_AUTOLOAD 0x80

/* variable parsing type (compile-time) */
#define ZEND_PARSED_MEMBER				(1<<0)
#define ZEND_PARSED_METHOD_CALL			(1<<1)
#define ZEND_PARSED_STATIC_MEMBER		(1<<2)
#define ZEND_PARSED_FUNCTION_CALL		(1<<3)
#define ZEND_PARSED_VARIABLE			(1<<4)
#define ZEND_PARSED_REFERENCE_VARIABLE	(1<<5)
#define ZEND_PARSED_NEW					(1<<6)


/* unset types */
#define ZEND_UNSET_REG 0

/* var status for backpatching */
#define BP_VAR_R			0
#define BP_VAR_W			1
#define BP_VAR_RW			2
#define BP_VAR_IS			3
#define BP_VAR_NA			4	/* if not applicable */
#define BP_VAR_FUNC_ARG		5
#define BP_VAR_UNSET		6


#define ZEND_INTERNAL_FUNCTION				1
#define ZEND_USER_FUNCTION					2
#define ZEND_OVERLOADED_FUNCTION			3
#define	ZEND_EVAL_CODE						4
#define ZEND_OVERLOADED_FUNCTION_TEMPORARY	5

#define ZEND_INTERNAL_CLASS         1
#define ZEND_USER_CLASS             2

#define ZEND_EVAL				(1<<0)
#define ZEND_INCLUDE			(1<<1)
#define ZEND_INCLUDE_ONCE		(1<<2)
#define ZEND_REQUIRE			(1<<3)
#define ZEND_REQUIRE_ONCE		(1<<4)

#define ZEND_ISSET				(1<<0)
#define ZEND_ISEMPTY			(1<<1)

#define ZEND_CT	(1<<0)
#define ZEND_RT (1<<1)


#define ZEND_HANDLE_FILENAME		0
#define ZEND_HANDLE_FD				1
#define ZEND_HANDLE_FP				2
#define ZEND_HANDLE_STDIOSTREAM		3
#define ZEND_HANDLE_FSTREAM			4
#define ZEND_HANDLE_STREAM			5

#define ZEND_FETCH_STANDARD		0
#define ZEND_FETCH_ADD_LOCK		1

#define ZEND_FE_FETCH_BYREF	1
#define ZEND_FE_FETCH_WITH_KEY	2

#define ZEND_FE_RESET_VARIABLE 		1
#define ZEND_FE_RESET_REFERENCE		2

#define ZEND_MEMBER_FUNC_CALL	1<<0

#define ZEND_ARG_SEND_BY_REF (1<<0)
#define ZEND_ARG_COMPILE_TIME_BOUND (1<<1)
#define ZEND_ARG_SEND_FUNCTION (1<<2)
#define ZEND_ARG_SEND_SILENT   (1<<3)

#define ZEND_SEND_BY_VAL     0
#define ZEND_SEND_BY_REF     1
#define ZEND_SEND_PREFER_REF 2

#define ARG_SEND_TYPE(zf, arg_num)												\
	((zf) ?                                                                     \
	 ((((zend_function*)(zf))->common.arg_info &&                               \
	   arg_num<=((zend_function*)(zf))->common.num_args) ?                      \
	  ((zend_function *)(zf))->common.arg_info[arg_num-1].pass_by_reference :   \
	  ((zend_function *)(zf))->common.pass_rest_by_reference) :                 \
	 ZEND_SEND_BY_VAL)	

#define ARG_MUST_BE_SENT_BY_REF(zf, arg_num) \
	(ARG_SEND_TYPE(zf, arg_num) == ZEND_SEND_BY_REF)

#define ARG_SHOULD_BE_SENT_BY_REF(zf, arg_num) \
	(ARG_SEND_TYPE(zf, arg_num) & (ZEND_SEND_BY_REF|ZEND_SEND_PREFER_REF))

#define ARG_MAY_BE_SENT_BY_REF(zf, arg_num) \
	(ARG_SEND_TYPE(zf, arg_num) == ZEND_SEND_PREFER_REF)

#define ZEND_RETURN_VAL 0
#define ZEND_RETURN_REF 1


#define ZEND_RETURNS_FUNCTION 1<<0
#define ZEND_RETURNS_NEW      1<<1

END_EXTERN_C()

#define ZEND_CLONE_FUNC_NAME		"__clone"
#define ZEND_CONSTRUCTOR_FUNC_NAME	"__construct"
#define ZEND_DESTRUCTOR_FUNC_NAME	"__destruct"
#define ZEND_GET_FUNC_NAME          "__get"
#define ZEND_SET_FUNC_NAME          "__set"
#define ZEND_UNSET_FUNC_NAME        "__unset"
#define ZEND_ISSET_FUNC_NAME        "__isset"
#define ZEND_CALL_FUNC_NAME         "__call"
#define ZEND_TOSTRING_FUNC_NAME     "__tostring"
#define ZEND_AUTOLOAD_FUNC_NAME     "__autoload"

#endif /* ZEND_COMPILE_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_execute.h000064400000020207151730542040011070 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        | 
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_execute.h 299766 2010-05-26 00:00:58Z felipe $ */

#ifndef ZEND_EXECUTE_H
#define ZEND_EXECUTE_H

#include "zend_compile.h"
#include "zend_hash.h"
#include "zend_operators.h"
#include "zend_variables.h"

typedef union _temp_variable {
	zval tmp_var;
	struct {
		zval **ptr_ptr;
		zval *ptr;
		zend_bool fcall_returned_reference;
	} var;
	struct {
		zval **ptr_ptr;
		zval *ptr;
		zend_bool fcall_returned_reference;
		zval *str;
		zend_uint offset;
	} str_offset;
	struct {
		zval **ptr_ptr;
		zval *ptr;
		zend_bool fcall_returned_reference;
		HashPointer fe_pos;
	} fe;
	zend_class_entry *class_entry;
} temp_variable;


BEGIN_EXTERN_C()
ZEND_API extern void (*zend_execute)(zend_op_array *op_array TSRMLS_DC);
ZEND_API extern void (*zend_execute_internal)(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC);

void init_executor(TSRMLS_D);
void shutdown_executor(TSRMLS_D);
void shutdown_destructors(TSRMLS_D);
ZEND_API void execute(zend_op_array *op_array TSRMLS_DC);
ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC);
ZEND_API int zend_is_true(zval *op);
#define safe_free_zval_ptr(p) safe_free_zval_ptr_rel(p ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
static inline void safe_free_zval_ptr_rel(zval *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
{
	TSRMLS_FETCH();

	if (p!=EG(uninitialized_zval_ptr)) {
		FREE_ZVAL_REL(p);
	}
}
ZEND_API int zend_lookup_class(char *name, int name_length, zend_class_entry ***ce TSRMLS_DC);
ZEND_API int zend_lookup_class_ex(char *name, int name_length, int use_autoload, zend_class_entry ***ce TSRMLS_DC);
ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC);
ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC);

static inline int i_zend_is_true(zval *op)
{
	int result;

	switch (Z_TYPE_P(op)) {
		case IS_NULL:
			result = 0;
			break;
		case IS_LONG:
		case IS_BOOL:
		case IS_RESOURCE:
			result = (Z_LVAL_P(op)?1:0);
			break;
		case IS_DOUBLE:
			result = (Z_DVAL_P(op) ? 1 : 0);
			break;
		case IS_STRING:
			if (Z_STRLEN_P(op) == 0
				|| (Z_STRLEN_P(op)==1 && Z_STRVAL_P(op)[0]=='0')) {
				result = 0;
			} else {
				result = 1;
			}
			break;
		case IS_ARRAY:
			result = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
			break;
		case IS_OBJECT:
			if(IS_ZEND_STD_OBJECT(*op)) {
				TSRMLS_FETCH();

				if (Z_OBJ_HT_P(op)->cast_object) {
					zval tmp;
					if (Z_OBJ_HT_P(op)->cast_object(op, &tmp, IS_BOOL TSRMLS_CC) == SUCCESS) {
						result = Z_LVAL(tmp);
						break;
					}
				} else if (Z_OBJ_HT_P(op)->get) {
					zval *tmp = Z_OBJ_HT_P(op)->get(op TSRMLS_CC);
					if(Z_TYPE_P(tmp) != IS_OBJECT) {
						/* for safety - avoid loop */
						convert_to_boolean(tmp);
						result = Z_LVAL_P(tmp);
						zval_ptr_dtor(&tmp);
						break;
					}
				}
			
				if(EG(ze1_compatibility_mode)) {
					result = (zend_hash_num_elements(Z_OBJPROP_P(op))?1:0);
				} else {
					result = 1;
				}
			} else {
				result = 1;
			}
			break;
		default:
			result = 0;
			break;
	}
	return result;
}

ZEND_API int zval_update_constant(zval **pp, void *arg TSRMLS_DC);
ZEND_API int zval_update_constant_inline_change(zval **pp, void *arg TSRMLS_DC);
ZEND_API int zval_update_constant_no_inline_change(zval **pp, void *arg TSRMLS_DC);
ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *scope TSRMLS_DC);

/* dedicated Zend executor functions - do not use! */
static inline void zend_ptr_stack_clear_multiple(TSRMLS_D)
{
	void **p = EG(argument_stack).top_element-2;
	int delete_count = (int)(zend_uintptr_t) *p;

	EG(argument_stack).top -= (delete_count+2);
	while (--delete_count>=0) {
		zval *q = *(zval **)(--p);
		*p = NULL;
		zval_ptr_dtor(&q);
	}
	EG(argument_stack).top_element = p;
}

static inline int zend_ptr_stack_get_arg(int requested_arg, void **data TSRMLS_DC)
{
	void **p = EG(argument_stack).top_element-2;
	int arg_count = (int)(zend_uintptr_t) *p;

	if (requested_arg>arg_count) {
		return FAILURE;
	}
	*data = (p-arg_count+requested_arg-1);
	return SUCCESS;
}

static inline void zend_arg_types_stack_2_pop(zend_ptr_stack *stack, zval **object, zend_function **fbc)
{
	void *a, *b;

	zend_ptr_stack_2_pop(stack, &a, &b);

	*object =  (zval *) a;
	*fbc = (zend_function *) b;
}

static inline void zend_arg_types_stack_3_pop(zend_ptr_stack *stack, zend_class_entry **called_scope, zval **object, zend_function **fbc)
{
	void *a, *b, *c;

	zend_ptr_stack_3_pop(stack, &a, &b, &c);

	*called_scope = (zend_class_entry *) a;
	*object = (zval *) b;
	*fbc = (zend_function *) c;
}

void execute_new_code(TSRMLS_D);


/* services */
ZEND_API char *get_active_class_name(char **space TSRMLS_DC);
ZEND_API char *get_active_function_name(TSRMLS_D);
ZEND_API char *zend_get_executed_filename(TSRMLS_D);
ZEND_API uint zend_get_executed_lineno(TSRMLS_D);
ZEND_API zend_bool zend_is_executing(TSRMLS_D);

ZEND_API void zend_set_timeout(long seconds);
ZEND_API void zend_unset_timeout(TSRMLS_D);
ZEND_API void zend_timeout(int dummy);
ZEND_API zend_class_entry *zend_fetch_class(char *class_name, uint class_name_len, int fetch_type TSRMLS_DC);
void zend_verify_abstract_class(zend_class_entry *ce TSRMLS_DC);

#ifdef ZEND_WIN32
void zend_init_timeout_thread(void);
void zend_shutdown_timeout_thread(void);
#define WM_REGISTER_ZEND_TIMEOUT		(WM_USER+1)
#define WM_UNREGISTER_ZEND_TIMEOUT		(WM_USER+2)
#endif

#define zendi_zval_copy_ctor(p) zval_copy_ctor(&(p))
#define zendi_zval_dtor(p) zval_dtor(&(p))

#define active_opline (*EG(opline_ptr))

/* The following tries to resolve the classname of a zval of type object.
 * Since it is slow it should be only used in error messages.
 */
#define Z_OBJ_CLASS_NAME_P(zval) ((zval) && Z_TYPE_P(zval) == IS_OBJECT && Z_OBJ_HT_P(zval)->get_class_entry != NULL && Z_OBJ_HT_P(zval)->get_class_entry(zval TSRMLS_CC) ? Z_OBJ_HT_P(zval)->get_class_entry(zval TSRMLS_CC)->name : "")

ZEND_API zval** zend_get_compiled_variable_value(zend_execute_data *execute_data_ptr, zend_uint var);

#define ZEND_USER_OPCODE_CONTINUE   0 /* execute next opcode */
#define ZEND_USER_OPCODE_RETURN     1 /* exit from executor (return from function) */
#define ZEND_USER_OPCODE_DISPATCH   2 /* call original opcode handler */

#define ZEND_USER_OPCODE_DISPATCH_TO 0x100 /* call original handler of returned opcode */

ZEND_API int zend_set_user_opcode_handler(zend_uchar opcode, opcode_handler_t handler);
ZEND_API opcode_handler_t zend_get_user_opcode_handler(zend_uchar opcode);

/* former zend_execute_locks.h */
typedef struct _zend_free_op {
	zval* var;
/*	int   is_var; */
} zend_free_op;

ZEND_API zval *zend_get_zval_ptr(znode *node, temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC);
ZEND_API zval **zend_get_zval_ptr_ptr(znode *node, temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC);

ZEND_API int zend_do_fcall(ZEND_OPCODE_HANDLER_ARGS);

END_EXTERN_C()

#endif /* ZEND_EXECUTE_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_virtual_cwd.h000064400000030571151730542040011756 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 7                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2018 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Sascha Schumann <sascha@schumann.cx>                        |
   |          Pierre Joye <pierre@php.net>                                |
   +----------------------------------------------------------------------+
*/

/* $Id$ */

#ifndef VIRTUAL_CWD_H
#define VIRTUAL_CWD_H

#include "TSRM.h"
#include "tsrm_config_common.h"

#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>

#ifdef HAVE_UTIME_H
#include <utime.h>
#endif

#ifdef HAVE_STDARG_H
#include <stdarg.h>
#endif

#ifdef ZTS
#define VIRTUAL_DIR
#endif

#ifndef ZEND_WIN32
#include <unistd.h>
#else
#include <direct.h>
#endif

#if defined(__osf__) || defined(_AIX)
#include <errno.h>
#endif

#ifdef ZEND_WIN32
#include "readdir.h"
#include <sys/utime.h>
#include "win32/ioutil.h"
/* mode_t isn't defined on Windows */
typedef unsigned short mode_t;

#define DEFAULT_SLASH '\\'
#define DEFAULT_DIR_SEPARATOR	';'
#define IS_SLASH(c)	((c) == '/' || (c) == '\\')
#define IS_SLASH_P(c)	(*(c) == '/' || \
        (*(c) == '\\' && !IsDBCSLeadByte(*(c-1))))

/* COPY_WHEN_ABSOLUTE is 2 under Win32 because by chance both regular absolute paths
   in the file system and UNC paths need copying of two characters */
#define COPY_WHEN_ABSOLUTE(path) 2
#define IS_UNC_PATH(path, len) \
	(len >= 2 && IS_SLASH(path[0]) && IS_SLASH(path[1]))
#define IS_ABSOLUTE_PATH(path, len) \
	(len >= 2 && (/* is local */isalpha(path[0]) && path[1] == ':' || /* is UNC */IS_SLASH(path[0]) && IS_SLASH(path[1])))

#else
#ifdef HAVE_DIRENT_H
#include <dirent.h>
#endif

#define DEFAULT_SLASH '/'

#ifdef __riscos__
#define DEFAULT_DIR_SEPARATOR  ';'
#else
#define DEFAULT_DIR_SEPARATOR  ':'
#endif

#define IS_SLASH(c)	((c) == '/')
#define IS_SLASH_P(c)	(*(c) == '/')

#endif


#ifndef COPY_WHEN_ABSOLUTE
#define COPY_WHEN_ABSOLUTE(path) 0
#endif

#ifndef IS_ABSOLUTE_PATH
#define IS_ABSOLUTE_PATH(path, len) \
	(IS_SLASH(path[0]))
#endif

#ifdef TSRM_EXPORTS
#define CWD_EXPORTS
#endif

#ifdef ZEND_WIN32
#	ifdef CWD_EXPORTS
#		define CWD_API __declspec(dllexport)
#	else
#		define CWD_API __declspec(dllimport)
#	endif
#elif defined(__GNUC__) && __GNUC__ >= 4
#	define CWD_API __attribute__ ((visibility("default")))
#else
#	define CWD_API
#endif

#ifdef ZEND_WIN32
CWD_API int php_sys_stat_ex(const char *path, zend_stat_t *buf, int lstat);
# define php_sys_stat(path, buf) php_sys_stat_ex(path, buf, 0)
# define php_sys_lstat(path, buf) php_sys_stat_ex(path, buf, 1)
CWD_API int php_sys_readlink(const char *link, char *target, size_t target_len);
#else
# define php_sys_stat stat
# define php_sys_lstat lstat
# ifdef HAVE_SYMLINK
# define php_sys_readlink(link, target, target_len) readlink(link, target, target_len)
# endif
#endif

typedef struct _cwd_state {
	char *cwd;
	int cwd_length;
} cwd_state;

typedef int (*verify_path_func)(const cwd_state *);

CWD_API void virtual_cwd_startup(void);
CWD_API void virtual_cwd_shutdown(void);
CWD_API int virtual_cwd_activate(void);
CWD_API int virtual_cwd_deactivate(void);
CWD_API char *virtual_getcwd_ex(size_t *length);
CWD_API char *virtual_getcwd(char *buf, size_t size);
CWD_API int virtual_chdir(const char *path);
CWD_API int virtual_chdir_file(const char *path, int (*p_chdir)(const char *path));
CWD_API int virtual_filepath(const char *path, char **filepath);
CWD_API int virtual_filepath_ex(const char *path, char **filepath, verify_path_func verify_path);
CWD_API char *virtual_realpath(const char *path, char *real_path);
CWD_API FILE *virtual_fopen(const char *path, const char *mode);
CWD_API int virtual_open(const char *path, int flags, ...);
CWD_API int virtual_creat(const char *path, mode_t mode);
CWD_API int virtual_rename(const char *oldname, const char *newname);
CWD_API int virtual_stat(const char *path, zend_stat_t *buf);
CWD_API int virtual_lstat(const char *path, zend_stat_t *buf);
CWD_API int virtual_unlink(const char *path);
CWD_API int virtual_mkdir(const char *pathname, mode_t mode);
CWD_API int virtual_rmdir(const char *pathname);
CWD_API DIR *virtual_opendir(const char *pathname);
CWD_API FILE *virtual_popen(const char *command, const char *type);
CWD_API int virtual_access(const char *pathname, int mode);
#if defined(ZEND_WIN32)
/* these are not defined in win32 headers */
#ifndef W_OK
#define W_OK 0x02
#endif
#ifndef R_OK
#define R_OK 0x04
#endif
#ifndef X_OK
#define X_OK 0x01
#endif
#ifndef F_OK
#define F_OK 0x00
#endif
#endif

#if HAVE_UTIME
CWD_API int virtual_utime(const char *filename, struct utimbuf *buf);
#endif
CWD_API int virtual_chmod(const char *filename, mode_t mode);
#if !defined(ZEND_WIN32)
CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group, int link);
#endif

/* One of the following constants must be used as the last argument
   in virtual_file_ex() call. */

#define CWD_EXPAND   0 /* expand "." and ".." but dont resolve symlinks      */
#define CWD_FILEPATH 1 /* resolve symlinks if file is exist otherwise expand */
#define CWD_REALPATH 2 /* call realpath(), resolve symlinks. File must exist */

CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func verify_path, int use_realpath);

CWD_API char *tsrm_realpath(const char *path, char *real_path);

#define REALPATH_CACHE_TTL  (2*60) /* 2 minutes */
#define REALPATH_CACHE_SIZE 0      /* disabled while php.ini isn't loaded */

typedef struct _realpath_cache_bucket {
	zend_ulong                    key;
	char                          *path;
	char                          *realpath;
	struct _realpath_cache_bucket *next;
	time_t                         expires;
	uint16_t                       path_len;
	uint16_t                       realpath_len;
	uint8_t                        is_dir:1;
#ifdef ZEND_WIN32
	uint8_t                        is_rvalid:1;
	uint8_t                        is_readable:1;
	uint8_t                        is_wvalid:1;
	uint8_t                        is_writable:1;
#endif
} realpath_cache_bucket;

typedef struct _virtual_cwd_globals {
	cwd_state cwd;
	zend_long                   realpath_cache_size;
	zend_long                   realpath_cache_size_limit;
	zend_long                   realpath_cache_ttl;
	realpath_cache_bucket *realpath_cache[1024];
} virtual_cwd_globals;

#ifdef ZTS
extern ts_rsrc_id cwd_globals_id;
# define CWDG(v) ZEND_TSRMG(cwd_globals_id, virtual_cwd_globals *, v)
#else
extern virtual_cwd_globals cwd_globals;
# define CWDG(v) (cwd_globals.v)
#endif

CWD_API void realpath_cache_clean(void);
CWD_API void realpath_cache_del(const char *path, size_t path_len);
CWD_API realpath_cache_bucket* realpath_cache_lookup(const char *path, size_t path_len, time_t t);
CWD_API zend_long realpath_cache_size(void);
CWD_API zend_long realpath_cache_max_buckets(void);
CWD_API realpath_cache_bucket** realpath_cache_get_buckets(void);

#ifdef CWD_EXPORTS
extern void virtual_cwd_main_cwd_init(uint8_t);
#endif

/* The actual macros to be used in programs using TSRM
 * If the program defines VIRTUAL_DIR it will use the
 * virtual_* functions
 */

#ifdef VIRTUAL_DIR

#define VCWD_GETCWD(buff, size) virtual_getcwd(buff, size)
#define VCWD_FOPEN(path, mode) virtual_fopen(path, mode)
/* Because open() has two modes, we have to macros to replace it */
#define VCWD_OPEN(path, flags) virtual_open(path, flags)
#define VCWD_OPEN_MODE(path, flags, mode) virtual_open(path, flags, mode)
#define VCWD_CREAT(path, mode) virtual_creat(path, mode)
#define VCWD_CHDIR(path) virtual_chdir(path)
#define VCWD_CHDIR_FILE(path) virtual_chdir_file(path, virtual_chdir)
#define VCWD_GETWD(buf)
#define VCWD_REALPATH(path, real_path) virtual_realpath(path, real_path)
#define VCWD_RENAME(oldname, newname) virtual_rename(oldname, newname)
#define VCWD_STAT(path, buff) virtual_stat(path, buff)
# define VCWD_LSTAT(path, buff) virtual_lstat(path, buff)
#define VCWD_UNLINK(path) virtual_unlink(path)
#define VCWD_MKDIR(pathname, mode) virtual_mkdir(pathname, mode)
#define VCWD_RMDIR(pathname) virtual_rmdir(pathname)
#define VCWD_OPENDIR(pathname) virtual_opendir(pathname)
#define VCWD_POPEN(command, type) virtual_popen(command, type)
#define VCWD_ACCESS(pathname, mode) virtual_access(pathname, mode)
#if HAVE_UTIME
#define VCWD_UTIME(path, time) virtual_utime(path, time)
#endif
#define VCWD_CHMOD(path, mode) virtual_chmod(path, mode)
#if !defined(ZEND_WIN32)
#define VCWD_CHOWN(path, owner, group) virtual_chown(path, owner, group, 0)
#if HAVE_LCHOWN
#define VCWD_LCHOWN(path, owner, group) virtual_chown(path, owner, group, 1)
#endif
#endif

#else

#define VCWD_CREAT(path, mode) creat(path, mode)
/* rename on windows will fail if newname already exists.
   MoveFileEx has to be used */
#if defined(ZEND_WIN32)
#define VCWD_FOPEN(path, mode)  php_win32_ioutil_fopen(path, mode)
#define VCWD_OPEN(path, flags) php_win32_ioutil_open(path, flags)
#define VCWD_OPEN_MODE(path, flags, mode) php_win32_ioutil_open(path, flags, mode)
# define VCWD_RENAME(oldname, newname) php_win32_ioutil_rename(oldname, newname)
#define VCWD_MKDIR(pathname, mode) php_win32_ioutil_mkdir(pathname, mode)
#define VCWD_RMDIR(pathname) php_win32_ioutil_rmdir(pathname)
#define VCWD_UNLINK(path) php_win32_ioutil_unlink(path)
#define VCWD_CHDIR(path) php_win32_ioutil_chdir(path)
#define VCWD_ACCESS(pathname, mode) tsrm_win32_access(pathname, mode)
#define VCWD_GETCWD(buff, size) php_win32_ioutil_getcwd(buff, size)
#define VCWD_CHMOD(path, mode) php_win32_ioutil_chmod(path, mode)
#else
#define VCWD_FOPEN(path, mode)  fopen(path, mode)
#define VCWD_OPEN(path, flags) open(path, flags)
#define VCWD_OPEN_MODE(path, flags, mode)	open(path, flags, mode)
# define VCWD_RENAME(oldname, newname) rename(oldname, newname)
#define VCWD_MKDIR(pathname, mode) mkdir(pathname, mode)
#define VCWD_RMDIR(pathname) rmdir(pathname)
#define VCWD_UNLINK(path) unlink(path)
#define VCWD_CHDIR(path) chdir(path)
#define VCWD_ACCESS(pathname, mode) access(pathname, mode)
#define VCWD_GETCWD(buff, size) getcwd(buff, size)
#define VCWD_CHMOD(path, mode) chmod(path, mode)
#endif

#define VCWD_CHDIR_FILE(path) virtual_chdir_file(path, chdir)
#define VCWD_GETWD(buf) getwd(buf)
#define VCWD_STAT(path, buff) php_sys_stat(path, buff)
#define VCWD_LSTAT(path, buff) lstat(path, buff)
#define VCWD_OPENDIR(pathname) opendir(pathname)
#define VCWD_POPEN(command, type) popen(command, type)

#define VCWD_REALPATH(path, real_path) tsrm_realpath(path, real_path)

#if HAVE_UTIME
# ifdef ZEND_WIN32
#  define VCWD_UTIME(path, time) win32_utime(path, time)
# else
#  define VCWD_UTIME(path, time) utime(path, time)
# endif
#endif

#if !defined(ZEND_WIN32)
#define VCWD_CHOWN(path, owner, group) chown(path, owner, group)
#if HAVE_LCHOWN
#define VCWD_LCHOWN(path, owner, group) lchown(path, owner, group)
#endif
#endif

#endif

/* Global stat declarations */
#ifndef _S_IFDIR
#define _S_IFDIR S_IFDIR
#endif

#ifndef _S_IFREG
#define _S_IFREG S_IFREG
#endif

#ifndef S_IFLNK
#define _IFLNK  0120000	/* symbolic link */
#define S_IFLNK _IFLNK
#endif

#ifndef S_ISDIR
#define S_ISDIR(mode)	(((mode)&S_IFMT) == S_IFDIR)
#endif

#ifndef S_ISREG
#define S_ISREG(mode)	(((mode)&S_IFMT) == S_IFREG)
#endif

#ifndef S_ISLNK
#define S_ISLNK(mode)	(((mode)&S_IFMT) == S_IFLNK)
#endif

#ifndef S_IXROOT
#define S_IXROOT ( S_IXUSR | S_IXGRP | S_IXOTH )
#endif

/* XXX should be _S_IFIFO? */
#ifndef S_IFIFO
#define	_IFIFO  0010000	/* fifo */
#define S_IFIFO	_IFIFO
#endif

#ifndef S_IFBLK
#define	_IFBLK  0060000	/* block special */
#define S_IFBLK	_IFBLK
#endif

#endif /* VIRTUAL_CWD_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/Zend/zend_highlight.h000064400000004742151730542040011403 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        | 
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_highlight.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef ZEND_HIGHLIGHT_H
#define ZEND_HIGHLIGHT_H

#define HL_COMMENT_COLOR     "#FF8000"    /* orange */
#define HL_DEFAULT_COLOR     "#0000BB"    /* blue */
#define HL_HTML_COLOR        "#000000"    /* black */
#define HL_STRING_COLOR      "#DD0000"    /* red */
#define HL_BG_COLOR          "#FFFFFF"    /* white */
#define HL_KEYWORD_COLOR     "#007700"    /* green */


typedef struct _zend_syntax_highlighter_ini {
	char *highlight_html;
	char *highlight_comment;
	char *highlight_default;
	char *highlight_string;
	char *highlight_keyword;
} zend_syntax_highlighter_ini;


BEGIN_EXTERN_C()
ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini TSRMLS_DC);
ZEND_API void zend_strip(TSRMLS_D);
ZEND_API int highlight_file(char *filename, zend_syntax_highlighter_ini *syntax_highlighter_ini TSRMLS_DC);
ZEND_API int highlight_string(zval *str, zend_syntax_highlighter_ini *syntax_highlighter_ini, char *str_name TSRMLS_DC);
ZEND_API void zend_html_putc(char c);
ZEND_API void zend_html_puts(const char *s, uint len TSRMLS_DC);
END_EXTERN_C()

extern zend_syntax_highlighter_ini syntax_highlighter_ini;

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_gc.h000064400000012024151730542040010015 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2018 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: David Wang <planetbeing@gmail.com>                          |
   |          Dmitry Stogov <dmitry@zend.com>                             |
   +----------------------------------------------------------------------+
*/

/* $Id$ */

#ifndef ZEND_GC_H
#define ZEND_GC_H

#ifndef GC_BENCH
# define GC_BENCH 0
#endif

#if GC_BENCH
# define GC_BENCH_INC(counter) GC_G(counter)++
# define GC_BENCH_DEC(counter) GC_G(counter)--
# define GC_BENCH_PEAK(peak, counter) do {		\
		if (GC_G(counter) > GC_G(peak)) {		\
			GC_G(peak) = GC_G(counter);			\
		}										\
	} while (0)
#else
# define GC_BENCH_INC(counter)
# define GC_BENCH_DEC(counter)
# define GC_BENCH_PEAK(peak, counter)
#endif

#define GC_COLOR  0xc000

#define GC_BLACK  0x0000
#define GC_WHITE  0x8000
#define GC_GREY   0x4000
#define GC_PURPLE 0xc000

#define GC_ADDRESS(v) \
	((v) & ~GC_COLOR)
#define GC_INFO_GET_COLOR(v) \
	(((zend_uintptr_t)(v)) & GC_COLOR)
#define GC_INFO_SET_ADDRESS(v, a) \
	do {(v) = ((v) & GC_COLOR) | (a);} while (0)
#define GC_INFO_SET_COLOR(v, c) \
	do {(v) = ((v) & ~GC_COLOR) | (c);} while (0)
#define GC_INFO_SET_BLACK(v) \
	do {(v) = (v) & ~GC_COLOR;} while (0)
#define GC_INFO_SET_PURPLE(v) \
	do {(v) = (v) | GC_COLOR;} while (0)

typedef struct _gc_root_buffer {
	zend_refcounted          *ref;
	struct _gc_root_buffer   *next;     /* double-linked list               */
	struct _gc_root_buffer   *prev;
	uint32_t                 refcount;
} gc_root_buffer;

#define GC_NUM_ADDITIONAL_ENTRIES \
	((4096 - ZEND_MM_OVERHEAD - sizeof(void*) * 2) / sizeof(gc_root_buffer))

typedef struct _gc_additional_bufer gc_additional_buffer;

struct _gc_additional_bufer {
	uint32_t              used;
	gc_additional_buffer *next;
	gc_root_buffer        buf[GC_NUM_ADDITIONAL_ENTRIES];
};

typedef struct _zend_gc_globals {
	zend_bool         gc_enabled;
	zend_bool         gc_active;
	zend_bool         gc_full;

	gc_root_buffer   *buf;				/* preallocated arrays of buffers   */
	gc_root_buffer    roots;			/* list of possible roots of cycles */
	gc_root_buffer   *unused;			/* list of unused buffers           */
	gc_root_buffer   *first_unused;		/* pointer to first unused buffer   */
	gc_root_buffer   *last_unused;		/* pointer to last unused buffer    */

	gc_root_buffer    to_free;			/* list to free                     */
	gc_root_buffer   *next_to_free;

	uint32_t gc_runs;
	uint32_t collected;

#if GC_BENCH
	uint32_t root_buf_length;
	uint32_t root_buf_peak;
	uint32_t zval_possible_root;
	uint32_t zval_buffered;
	uint32_t zval_remove_from_buffer;
	uint32_t zval_marked_grey;
#endif

	gc_additional_buffer *additional_buffer;

} zend_gc_globals;

#ifdef ZTS
BEGIN_EXTERN_C()
ZEND_API extern int gc_globals_id;
END_EXTERN_C()
#define GC_G(v) ZEND_TSRMG(gc_globals_id, zend_gc_globals *, v)
#else
#define GC_G(v) (gc_globals.v)
extern ZEND_API zend_gc_globals gc_globals;
#endif

BEGIN_EXTERN_C()
ZEND_API extern int (*gc_collect_cycles)(void);

ZEND_API void ZEND_FASTCALL gc_possible_root(zend_refcounted *ref);
ZEND_API void ZEND_FASTCALL gc_remove_from_buffer(zend_refcounted *ref);
ZEND_API void gc_globals_ctor(void);
ZEND_API void gc_globals_dtor(void);
ZEND_API void gc_init(void);
ZEND_API void gc_reset(void);

/* The default implementation of the gc_collect_cycles callback. */
ZEND_API int  zend_gc_collect_cycles(void);
END_EXTERN_C()

#define GC_REMOVE_FROM_BUFFER(p) do { \
		zend_refcounted *_p = (zend_refcounted*)(p); \
		if (GC_ADDRESS(GC_INFO(_p))) { \
			gc_remove_from_buffer(_p); \
		} \
	} while (0)

#define GC_MAY_LEAK(ref) \
	((GC_TYPE_INFO(ref) & \
		(GC_INFO_MASK | (GC_COLLECTABLE << GC_FLAGS_SHIFT))) == \
	(GC_COLLECTABLE << GC_FLAGS_SHIFT))

static zend_always_inline void gc_check_possible_root(zend_refcounted *ref)
{
	if (GC_TYPE(ref) == IS_REFERENCE) {
		zval *zv = &((zend_reference*)ref)->val;

		if (!Z_REFCOUNTED_P(zv)) {
			return;
		}
		ref = Z_COUNTED_P(zv);
	}
	if (UNEXPECTED(GC_MAY_LEAK(ref))) {
		gc_possible_root(ref);
	}
}

#endif /* ZEND_GC_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/Zend/zend_smart_string_public.h000064400000003022151730542040013474 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 7                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2018 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Sascha Schumann <sascha@schumann.cx>                         |
   |         Xinchen Hui <laruence@php.net>                               |
   +----------------------------------------------------------------------+
 */

/* $Id$ */

#ifndef PHP_SMART_STRING_PUBLIC_H
#define PHP_SMART_STRING_PUBLIC_H

#include <sys/types.h>

typedef struct {
	char *c;
	size_t len;
	size_t a;
} smart_string;

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/Zend/zend_objects_API.h000064400000010041151730542040011543 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_objects_API.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef ZEND_OBJECTS_API_H
#define ZEND_OBJECTS_API_H

#include "zend.h"

typedef void (*zend_objects_store_dtor_t)(void *object, zend_object_handle handle TSRMLS_DC);
typedef void (*zend_objects_free_object_storage_t)(void *object TSRMLS_DC);
typedef void (*zend_objects_store_clone_t)(void *object, void **object_clone TSRMLS_DC);

typedef struct _zend_object_store_bucket {
	zend_bool destructor_called;
	zend_bool valid;
	union _store_bucket {
		struct _store_object {
			void *object;
			zend_objects_store_dtor_t dtor;
			zend_objects_free_object_storage_t free_storage;
			zend_objects_store_clone_t clone;
			zend_uint refcount;
		} obj;
		struct {
			int next;
		} free_list;
	} bucket;
} zend_object_store_bucket;

typedef struct _zend_objects_store {
	zend_object_store_bucket *object_buckets;
	zend_uint top;
	zend_uint size;
	int free_list_head;
} zend_objects_store;

/* Global store handling functions */
BEGIN_EXTERN_C()
ZEND_API void zend_objects_store_init(zend_objects_store *objects, zend_uint init_size);
ZEND_API void zend_objects_store_call_destructors(zend_objects_store *objects TSRMLS_DC);
ZEND_API void zend_objects_store_mark_destructed(zend_objects_store *objects TSRMLS_DC);
ZEND_API void zend_objects_store_destroy(zend_objects_store *objects);

/* Store API functions */
ZEND_API zend_object_handle zend_objects_store_put(void *object, zend_objects_store_dtor_t dtor, zend_objects_free_object_storage_t storage, zend_objects_store_clone_t clone TSRMLS_DC);

ZEND_API void zend_objects_store_add_ref(zval *object TSRMLS_DC);
ZEND_API void zend_objects_store_del_ref(zval *object TSRMLS_DC);
ZEND_API void zend_objects_store_add_ref_by_handle(zend_object_handle handle TSRMLS_DC);
ZEND_API void zend_objects_store_del_ref_by_handle(zend_object_handle handle TSRMLS_DC);
ZEND_API zend_uint zend_objects_store_get_refcount(zval *object TSRMLS_DC);
ZEND_API zend_object_value zend_objects_store_clone_obj(zval *object TSRMLS_DC);
ZEND_API void *zend_object_store_get_object(zval *object TSRMLS_DC);
ZEND_API void *zend_object_store_get_object_by_handle(zend_object_handle handle TSRMLS_DC);
/* See comment in zend_objects_API.c before you use this */
ZEND_API void zend_object_store_set_object(zval *zobject, void *object TSRMLS_DC);
ZEND_API void zend_object_store_ctor_failed(zval *zobject TSRMLS_DC);

ZEND_API void zend_objects_store_free_object_storage(zend_objects_store *objects TSRMLS_DC);

#define ZEND_OBJECTS_STORE_HANDLERS zend_objects_store_add_ref, zend_objects_store_del_ref, zend_objects_store_clone_obj

ZEND_API zval *zend_object_create_proxy(zval *object, zval *member TSRMLS_DC);

ZEND_API zend_object_handlers *zend_get_std_object_handlers(void);
END_EXTERN_C()

#endif /* ZEND_OBJECTS_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/ext/mbstring/oniguruma/php_onig_compat.h000064400000000555151731375700015323 0ustar00#ifndef _PHP_MBREGEX_COMPAT_H
#define _PHP_MBREGEX_COMPAT_H

#define re_pattern_buffer           php_mb_re_pattern_buffer
#define regex_t                     php_mb_regex_t
#define re_registers                php_mb_re_registers

#ifdef HAVE_STDARG_H
#ifndef HAVE_STDARG_PROTOTYPES
#define HAVE_STDARG_PROTOTYPES 1
#endif
#endif

#endif /* _PHP_MBREGEX_COMPAT_H */
php/ext/apc/apc_serializer.h000064400000006435151731375720012066 0ustar00/*
  +----------------------------------------------------------------------+
  | APC                                                                  |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2011 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt.                                 |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Authors: Gopal Vijayaraghavan <gopalv@php.net>                       |
  +----------------------------------------------------------------------+

 */

/* $Id: $ */

#ifndef APC_SERIALIZER_H
#define APC_SERIALIZER_H

/* this is a shipped .h file, do not include any other header in this file */
#define APC_SERIALIZER_NAME(module) module##_apc_serializer
#define APC_UNSERIALIZER_NAME(module) module##_apc_unserializer

#define APC_SERIALIZER_ARGS unsigned char **buf, size_t *buf_len, const zval *value, void *config TSRMLS_DC
#define APC_UNSERIALIZER_ARGS zval **value, unsigned char *buf, size_t buf_len, void *config TSRMLS_DC

typedef int (*apc_serialize_t)(APC_SERIALIZER_ARGS);
typedef int (*apc_unserialize_t)(APC_UNSERIALIZER_ARGS);

typedef int (*apc_register_serializer_t)(const char* name,
                                        apc_serialize_t serialize,
                                        apc_unserialize_t unserialize,
                                        void *config TSRMLS_DC);

/*
 * ABI version for constant hooks. Increment this any time you make any changes
 * to any function in this file.
 */
#define APC_SERIALIZER_ABI "0"
#define APC_SERIALIZER_CONSTANT "\000apc_register_serializer-" APC_SERIALIZER_ABI

#if !defined(APC_UNUSED)
# if defined(__GNUC__)
#  define APC_UNUSED __attribute__((unused))
# else
# define APC_UNUSED
# endif
#endif

static APC_UNUSED int apc_register_serializer(const char* name,
                                    apc_serialize_t serialize,
                                    apc_unserialize_t unserialize,
                                    void *config TSRMLS_DC)
{
    zval apc_magic_constant;
    int retval = 0;

    /* zend_get_constant will return 1 on success, otherwise apc_magic_constant wouldn't be touched at all */
    if (zend_get_constant(APC_SERIALIZER_CONSTANT, sizeof(APC_SERIALIZER_CONSTANT)-1, &apc_magic_constant TSRMLS_CC)) {
        apc_register_serializer_t register_func = (apc_register_serializer_t)(Z_LVAL(apc_magic_constant));
        if(register_func) {
            retval = register_func(name, serialize, unserialize, NULL TSRMLS_CC);
        }
        zval_dtor(&apc_magic_constant);
    }

    return retval;
}

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker
 * vim<600: expandtab sw=4 ts=4 sts=4
 */
php/ext/spl/spl_sxe.h000064400000002755151731375730010604 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Marcus Boerger <helly@php.net>                              |
   +----------------------------------------------------------------------+
 */

/* $Id: spl_sxe.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef SPL_SXE_H
#define SPL_SXE_H

#include "php.h"
#include "php_spl.h"

extern zend_class_entry *spl_ce_SimpleXMLIterator;

SPL_API PHP_MINIT_FUNCTION(spl_sxe);

#endif /* SPL_SXE_H */

/*
 * Local Variables:
 * c-basic-offset: 4
 * tab-width: 4
 * End:
 * vim600: fdm=marker
 * vim: noet sw=4 ts=4
 */
php/ext/hash/php_hash_types.h000064400000004227151731375750012270 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Michael Wallner <mike@php.net>                               |
   +----------------------------------------------------------------------+
*/

/* $Id: php_hash_types.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_HASH_TYPES_H
#define PHP_HASH_TYPES_H

#ifdef HAVE_CONFIG_H
#include "config.h"
#else
#ifndef PHP_WIN32
#include "php_config.h"
#endif
#endif

#ifndef PHP_WIN32
#if SIZEOF_LONG == 8
#define L64(x) x
typedef unsigned long php_hash_uint64;
#if SIZEOF_INT == 4
typedef unsigned int php_hash_uint32;
#elif SIZEOF_SHORT == 4
typedef unsigned short php_hash_uint32;
#else
#error "Need a 32bit integer type"
#endif
#elif SIZEOF_LONG_LONG == 8
#define L64(x) x##LL
typedef unsigned long long php_hash_uint64;
#if SIZEOF_INT == 4
typedef unsigned int php_hash_uint32;
#elif SIZEOF_LONG == 4
typedef unsigned long php_hash_uint32;
#else
#error "Need a 32bit integer type"
#endif
#else
#error "Need a 64bit integer type"
#endif
#else
#define L64(x) x##i64
typedef unsigned __int64 php_hash_uint64;
typedef unsigned __int32 php_hash_uint32;
#endif

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
php/ext/date/lib/timelib_structs.h000064400000013445151731375770013232 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Derick Rethans <derick@derickrethans.nl>                    |
   +----------------------------------------------------------------------+
 */

/* $Id: timelib_structs.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef __TIMELIB_STRUCTS_H__
#define __TIMELIB_STRUCTS_H__

#include "timelib_config.h"

#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif

#if defined(HAVE_INTTYPES_H)
#include <inttypes.h>
#elif defined(HAVE_STDINT_H)
#include <stdint.h>
#endif

#ifndef HAVE_INT32_T
# if SIZEOF_INT == 4
typedef int int32_t;
# elif SIZEOF_LONG == 4
typedef long int int32_t;
# endif
#endif

#ifndef HAVE_UINT32_T
# if SIZEOF_INT == 4
typedef unsigned int uint32_t;
# elif SIZEOF_LONG == 4
typedef unsigned long int uint32_t;
# endif
#endif

#include <stdio.h>

#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif

#ifdef HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif

#if defined(_MSC_VER)
typedef unsigned __int64 timelib_ull;
typedef __int64 timelib_sll;
#else
typedef unsigned long long timelib_ull;
typedef signed long long timelib_sll;
#endif

#if defined(_MSC_VER)
#define int32_t __int32
#define uint32_t unsigned __int32
#endif

#if defined(_MSC_VER)
#define TIMELIB_LL_CONST(n) n ## i64
#else
#define TIMELIB_LL_CONST(n) n ## ll
#endif


typedef struct ttinfo
{
	int32_t      offset;
	int          isdst;
	unsigned int abbr_idx;

	unsigned int isstdcnt;
	unsigned int isgmtcnt;
} ttinfo;

typedef struct tlinfo
{
	int32_t  trans;
	int32_t  offset;
} tlinfo;

typedef struct timelib_tzinfo
{
	char    *name;
	uint32_t ttisgmtcnt;
	uint32_t ttisstdcnt;
	uint32_t leapcnt;
	uint32_t timecnt;
	uint32_t typecnt;
	uint32_t charcnt;

	int32_t *trans;
	unsigned char *trans_idx;

	ttinfo  *type;
	char    *timezone_abbr;

	tlinfo  *leap_times;
} timelib_tzinfo;

typedef struct timelib_rel_time {
	timelib_sll y, m, d; /* Years, Months and Days */
	timelib_sll h, i, s; /* Hours, mInutes and Seconds */

	int weekday; /* Stores the day in 'next monday' */
	int weekday_behavior; /* 0: the current day should *not* be counted when advancing forwards; 1: the current day *should* be counted */
} timelib_rel_time;

typedef struct timelib_time_offset {
	int32_t      offset;
	unsigned int leap_secs;
	unsigned int is_dst;
	char        *abbr;
	timelib_sll  transistion_time;
} timelib_time_offset;

typedef struct timelib_special {
	unsigned int type;
	timelib_sll amount;
} timelib_special;

typedef struct timelib_time {
	timelib_sll      y, m, d;     /* Year, Month, Day */
	timelib_sll      h, i, s;     /* Hour, mInute, Second */
	double           f;           /* Fraction */
	int              z;           /* GMT offset in minutes */
	char            *tz_abbr;     /* Timezone abbreviation (display only) */
	timelib_tzinfo  *tz_info;     /* Timezone structure */
	signed int       dst;         /* Flag if we were parsing a DST zone */
	timelib_rel_time relative;
	timelib_special  special;

	timelib_sll      sse;         /* Seconds since epoch */

	unsigned int   have_time, have_date, have_zone, have_relative, have_weekday_relative, have_special_relative, have_weeknr_day;

	unsigned int   sse_uptodate; /* !0 if the sse member is up to date with the date/time members */
	unsigned int   tim_uptodate; /* !0 if the date/time members are up to date with the sse member */
	unsigned int   is_localtime; /*  1 if the current struct represents localtime, 0 if it is in GMT */
	unsigned int   zone_type;    /*  1 time offset,
	                              *  3 TimeZone identifier,
	                              *  2 TimeZone abbreviation */
} timelib_time;

typedef struct timelib_error_message {
	int         position;
	char        character;
	char       *message;
} timelib_error_message;

typedef struct timelib_error_container {
	int                           warning_count;
	struct timelib_error_message *warning_messages;
	int                           error_count;
	struct timelib_error_message *error_messages;
} timelib_error_container;

typedef struct _timelib_tz_lookup_table {
	char       *name;
	int         type;
	int         gmtoffset;
	char       *full_tz_name;
} timelib_tz_lookup_table;

typedef struct _timelib_tzdb_index_entry {
	char *id;
	unsigned int pos;
} timelib_tzdb_index_entry;

typedef struct _timelib_tzdb {
	char                           *version;
	int                             index_size;
	const timelib_tzdb_index_entry *index;
	const unsigned char            *data;
} timelib_tzdb;

#define TIMELIB_ZONETYPE_OFFSET 1
#define TIMELIB_ZONETYPE_ABBR   2
#define TIMELIB_ZONETYPE_ID     3

#define SECS_PER_ERA   TIMELIB_LL_CONST(12622780800)
#define SECS_PER_DAY   86400
#define DAYS_PER_YEAR    365
#define DAYS_PER_LYEAR   366
/* 400*365 days + 97 leap days */
#define DAYS_PER_LYEAR_PERIOD 146097
#define YEARS_PER_LYEAR_PERIOD 400

#define timelib_is_leap(y) ((y) % 4 == 0 && ((y) % 100 != 0 || (y) % 400 == 0))

#define DEBUG(s)  if (0) { s }

#endif
php/ext/gd/gdttf.h000064400000000712151731375770010026 0ustar00/* $Id: gdttf.h 20492 2000-02-26 03:20:55Z zeev $ */

#ifdef _OSD_POSIX
#ifndef APACHE
#error On this EBCDIC platform, PHP is only supported as an Apache module.
#else /*APACHE*/
#ifndef CHARSET_EBCDIC
#define CHARSET_EBCDIC /* this machine uses EBCDIC, not ASCII! */
#endif
#include "ebcdic.h"
#endif /*APACHE*/
#endif /*_OSD_POSIX*/

char * gdttf(gdImage *im, int *brect, int fg, char *fontname,
    double ptsize, double angle, int x, int y, char *str);

php/ext/sqlite/libsqlite/src/sqlite.h000064400000113565151731376020013705 0ustar00/*
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the SQLite library
** presents to client programs.
**
** @(#) $Id: sqlite.h.in 195361 2005-09-07 15:11:33Z iliaa $
*/
#ifndef _SQLITE_H_
#define _SQLITE_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** Make sure we can call this stuff from C++.
*/
#ifdef __cplusplus
extern "C" {
#endif

/*
** The version of the SQLite library.
*/
#ifdef SQLITE_VERSION
# undef SQLITE_VERSION
#else
# define SQLITE_VERSION         "2.8.17"
#endif

/*
** The version string is also compiled into the library so that a program
** can check to make sure that the lib*.a file and the *.h file are from
** the same version.
*/
extern const char sqlite_version[];

/*
** The SQLITE_UTF8 macro is defined if the library expects to see
** UTF-8 encoded data.  The SQLITE_ISO8859 macro is defined if the
** iso8859 encoded should be used.
*/
#define SQLITE_UTF8 1

/*
** The following constant holds one of two strings, "UTF-8" or "iso8859",
** depending on which character encoding the SQLite library expects to
** see.  The character encoding makes a difference for the LIKE and GLOB
** operators and for the LENGTH() and SUBSTR() functions.
*/
extern const char sqlite_encoding[];

/*
** Each open sqlite database is represented by an instance of the
** following opaque structure.
*/
typedef struct sqlite sqlite;

/*
** A function to open a new sqlite database.  
**
** If the database does not exist and mode indicates write
** permission, then a new database is created.  If the database
** does not exist and mode does not indicate write permission,
** then the open fails, an error message generated (if errmsg!=0)
** and the function returns 0.
** 
** If mode does not indicates user write permission, then the 
** database is opened read-only.
**
** The Truth:  As currently implemented, all databases are opened
** for writing all the time.  Maybe someday we will provide the
** ability to open a database readonly.  The mode parameters is
** provided in anticipation of that enhancement.
*/
sqlite *sqlite_open(const char *filename, int mode, char **errmsg);

/*
** A function to close the database.
**
** Call this function with a pointer to a structure that was previously
** returned from sqlite_open() and the corresponding database will by closed.
*/
void sqlite_close(sqlite *);

/*
** The type for a callback function.
*/
typedef int (*sqlite_callback)(void*,int,char**, char**);

/*
** A function to executes one or more statements of SQL.
**
** If one or more of the SQL statements are queries, then
** the callback function specified by the 3rd parameter is
** invoked once for each row of the query result.  This callback
** should normally return 0.  If the callback returns a non-zero
** value then the query is aborted, all subsequent SQL statements
** are skipped and the sqlite_exec() function returns the SQLITE_ABORT.
**
** The 4th parameter is an arbitrary pointer that is passed
** to the callback function as its first parameter.
**
** The 2nd parameter to the callback function is the number of
** columns in the query result.  The 3rd parameter to the callback
** is an array of strings holding the values for each column.
** The 4th parameter to the callback is an array of strings holding
** the names of each column.
**
** The callback function may be NULL, even for queries.  A NULL
** callback is not an error.  It just means that no callback
** will be invoked.
**
** If an error occurs while parsing or evaluating the SQL (but
** not while executing the callback) then an appropriate error
** message is written into memory obtained from malloc() and
** *errmsg is made to point to that message.  The calling function
** is responsible for freeing the memory that holds the error
** message.   Use sqlite_freemem() for this.  If errmsg==NULL,
** then no error message is ever written.
**
** The return value is is SQLITE_OK if there are no errors and
** some other return code if there is an error.  The particular
** return value depends on the type of error. 
**
** If the query could not be executed because a database file is
** locked or busy, then this function returns SQLITE_BUSY.  (This
** behavior can be modified somewhat using the sqlite_busy_handler()
** and sqlite_busy_timeout() functions below.)
*/
int sqlite_exec(
  sqlite*,                      /* An open database */
  const char *sql,              /* SQL to be executed */
  sqlite_callback,              /* Callback function */
  void *,                       /* 1st argument to callback function */
  char **errmsg                 /* Error msg written here */
);

/*
** Return values for sqlite_exec() and sqlite_step()
*/
#define SQLITE_OK           0   /* Successful result */
#define SQLITE_ERROR        1   /* SQL error or missing database */
#define SQLITE_INTERNAL     2   /* An internal logic error in SQLite */
#define SQLITE_PERM         3   /* Access permission denied */
#define SQLITE_ABORT        4   /* Callback routine requested an abort */
#define SQLITE_BUSY         5   /* The database file is locked */
#define SQLITE_LOCKED       6   /* A table in the database is locked */
#define SQLITE_NOMEM        7   /* A malloc() failed */
#define SQLITE_READONLY     8   /* Attempt to write a readonly database */
#define SQLITE_INTERRUPT    9   /* Operation terminated by sqlite_interrupt() */
#define SQLITE_IOERR       10   /* Some kind of disk I/O error occurred */
#define SQLITE_CORRUPT     11   /* The database disk image is malformed */
#define SQLITE_NOTFOUND    12   /* (Internal Only) Table or record not found */
#define SQLITE_FULL        13   /* Insertion failed because database is full */
#define SQLITE_CANTOPEN    14   /* Unable to open the database file */
#define SQLITE_PROTOCOL    15   /* Database lock protocol error */
#define SQLITE_EMPTY       16   /* (Internal Only) Database table is empty */
#define SQLITE_SCHEMA      17   /* The database schema changed */
#define SQLITE_TOOBIG      18   /* Too much data for one row of a table */
#define SQLITE_CONSTRAINT  19   /* Abort due to contraint violation */
#define SQLITE_MISMATCH    20   /* Data type mismatch */
#define SQLITE_MISUSE      21   /* Library used incorrectly */
#define SQLITE_NOLFS       22   /* Uses OS features not supported on host */
#define SQLITE_AUTH        23   /* Authorization denied */
#define SQLITE_FORMAT      24   /* Auxiliary database format error */
#define SQLITE_RANGE       25   /* 2nd parameter to sqlite_bind out of range */
#define SQLITE_NOTADB      26   /* File opened that is not a database file */
#define SQLITE_ROW         100  /* sqlite_step() has another row ready */
#define SQLITE_DONE        101  /* sqlite_step() has finished executing */

/*
** Each entry in an SQLite table has a unique integer key.  (The key is
** the value of the INTEGER PRIMARY KEY column if there is such a column,
** otherwise the key is generated at random.  The unique key is always
** available as the ROWID, OID, or _ROWID_ column.)  The following routine
** returns the integer key of the most recent insert in the database.
**
** This function is similar to the mysql_insert_id() function from MySQL.
*/
int sqlite_last_insert_rowid(sqlite*);

/*
** This function returns the number of database rows that were changed
** (or inserted or deleted) by the most recent called sqlite_exec().
**
** All changes are counted, even if they were later undone by a
** ROLLBACK or ABORT.  Except, changes associated with creating and
** dropping tables are not counted.
**
** If a callback invokes sqlite_exec() recursively, then the changes
** in the inner, recursive call are counted together with the changes
** in the outer call.
**
** SQLite implements the command "DELETE FROM table" without a WHERE clause
** by dropping and recreating the table.  (This is much faster than going
** through and deleting individual elements form the table.)  Because of
** this optimization, the change count for "DELETE FROM table" will be
** zero regardless of the number of elements that were originally in the
** table. To get an accurate count of the number of rows deleted, use
** "DELETE FROM table WHERE 1" instead.
*/
int sqlite_changes(sqlite*);

/*
** This function returns the number of database rows that were changed
** by the last INSERT, UPDATE, or DELETE statment executed by sqlite_exec(),
** or by the last VM to run to completion. The change count is not updated
** by SQL statements other than INSERT, UPDATE or DELETE.
**
** Changes are counted, even if they are later undone by a ROLLBACK or
** ABORT. Changes associated with trigger programs that execute as a
** result of the INSERT, UPDATE, or DELETE statement are not counted.
**
** If a callback invokes sqlite_exec() recursively, then the changes
** in the inner, recursive call are counted together with the changes
** in the outer call.
**
** SQLite implements the command "DELETE FROM table" without a WHERE clause
** by dropping and recreating the table.  (This is much faster than going
** through and deleting individual elements form the table.)  Because of
** this optimization, the change count for "DELETE FROM table" will be
** zero regardless of the number of elements that were originally in the
** table. To get an accurate count of the number of rows deleted, use
** "DELETE FROM table WHERE 1" instead.
**
******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
*/
int sqlite_last_statement_changes(sqlite*);

/* If the parameter to this routine is one of the return value constants
** defined above, then this routine returns a constant text string which
** descripts (in English) the meaning of the return value.
*/
const char *sqlite_error_string(int);
#define sqliteErrStr sqlite_error_string  /* Legacy. Do not use in new code. */

/* This function causes any pending database operation to abort and
** return at its earliest opportunity.  This routine is typically
** called in response to a user action such as pressing "Cancel"
** or Ctrl-C where the user wants a long query operation to halt
** immediately.
*/
void sqlite_interrupt(sqlite*);


/* This function returns true if the given input string comprises
** one or more complete SQL statements.
**
** The algorithm is simple.  If the last token other than spaces
** and comments is a semicolon, then return true.  otherwise return
** false.
*/
int sqlite_complete(const char *sql);

/*
** This routine identifies a callback function that is invoked
** whenever an attempt is made to open a database table that is
** currently locked by another process or thread.  If the busy callback
** is NULL, then sqlite_exec() returns SQLITE_BUSY immediately if
** it finds a locked table.  If the busy callback is not NULL, then
** sqlite_exec() invokes the callback with three arguments.  The
** second argument is the name of the locked table and the third
** argument is the number of times the table has been busy.  If the
** busy callback returns 0, then sqlite_exec() immediately returns
** SQLITE_BUSY.  If the callback returns non-zero, then sqlite_exec()
** tries to open the table again and the cycle repeats.
**
** The default busy callback is NULL.
**
** Sqlite is re-entrant, so the busy handler may start a new query. 
** (It is not clear why anyone would every want to do this, but it
** is allowed, in theory.)  But the busy handler may not close the
** database.  Closing the database from a busy handler will delete 
** data structures out from under the executing query and will 
** probably result in a coredump.
*/
void sqlite_busy_handler(sqlite*, int(*)(void*,const char*,int), void*);

/*
** This routine sets a busy handler that sleeps for a while when a
** table is locked.  The handler will sleep multiple times until 
** at least "ms" milleseconds of sleeping have been done.  After
** "ms" milleseconds of sleeping, the handler returns 0 which
** causes sqlite_exec() to return SQLITE_BUSY.
**
** Calling this routine with an argument less than or equal to zero
** turns off all busy handlers.
*/
void sqlite_busy_timeout(sqlite*, int ms);

/*
** This next routine is really just a wrapper around sqlite_exec().
** Instead of invoking a user-supplied callback for each row of the
** result, this routine remembers each row of the result in memory
** obtained from malloc(), then returns all of the result after the
** query has finished. 
**
** As an example, suppose the query result where this table:
**
**        Name        | Age
**        -----------------------
**        Alice       | 43
**        Bob         | 28
**        Cindy       | 21
**
** If the 3rd argument were &azResult then after the function returns
** azResult will contain the following data:
**
**        azResult[0] = "Name";
**        azResult[1] = "Age";
**        azResult[2] = "Alice";
**        azResult[3] = "43";
**        azResult[4] = "Bob";
**        azResult[5] = "28";
**        azResult[6] = "Cindy";
**        azResult[7] = "21";
**
** Notice that there is an extra row of data containing the column
** headers.  But the *nrow return value is still 3.  *ncolumn is
** set to 2.  In general, the number of values inserted into azResult
** will be ((*nrow) + 1)*(*ncolumn).
**
** After the calling function has finished using the result, it should 
** pass the result data pointer to sqlite_free_table() in order to 
** release the memory that was malloc-ed.  Because of the way the 
** malloc() happens, the calling function must not try to call 
** malloc() directly.  Only sqlite_free_table() is able to release 
** the memory properly and safely.
**
** The return value of this routine is the same as from sqlite_exec().
*/
int sqlite_get_table(
  sqlite*,               /* An open database */
  const char *sql,       /* SQL to be executed */
  char ***resultp,       /* Result written to a char *[]  that this points to */
  int *nrow,             /* Number of result rows written here */
  int *ncolumn,          /* Number of result columns written here */
  char **errmsg          /* Error msg written here */
);

/*
** Call this routine to free the memory that sqlite_get_table() allocated.
*/
void sqlite_free_table(char **result);

/*
** The following routines are wrappers around sqlite_exec() and
** sqlite_get_table().  The only difference between the routines that
** follow and the originals is that the second argument to the 
** routines that follow is really a printf()-style format
** string describing the SQL to be executed.  Arguments to the format
** string appear at the end of the argument list.
**
** All of the usual printf formatting options apply.  In addition, there
** is a "%q" option.  %q works like %s in that it substitutes a null-terminated
** string from the argument list.  But %q also doubles every '\'' character.
** %q is designed for use inside a string literal.  By doubling each '\''
** character it escapes that character and allows it to be inserted into
** the string.
**
** For example, so some string variable contains text as follows:
**
**      char *zText = "It's a happy day!";
**
** We can use this text in an SQL statement as follows:
**
**      sqlite_exec_printf(db, "INSERT INTO table VALUES('%q')",
**          callback1, 0, 0, zText);
**
** Because the %q format string is used, the '\'' character in zText
** is escaped and the SQL generated is as follows:
**
**      INSERT INTO table1 VALUES('It''s a happy day!')
**
** This is correct.  Had we used %s instead of %q, the generated SQL
** would have looked like this:
**
**      INSERT INTO table1 VALUES('It's a happy day!');
**
** This second example is an SQL syntax error.  As a general rule you
** should always use %q instead of %s when inserting text into a string 
** literal.
*/
int sqlite_exec_printf(
  sqlite*,                      /* An open database */
  const char *sqlFormat,        /* printf-style format string for the SQL */
  sqlite_callback,              /* Callback function */
  void *,                       /* 1st argument to callback function */
  char **errmsg,                /* Error msg written here */
  ...                           /* Arguments to the format string. */
);
int sqlite_exec_vprintf(
  sqlite*,                      /* An open database */
  const char *sqlFormat,        /* printf-style format string for the SQL */
  sqlite_callback,              /* Callback function */
  void *,                       /* 1st argument to callback function */
  char **errmsg,                /* Error msg written here */
  va_list ap                    /* Arguments to the format string. */
);
int sqlite_get_table_printf(
  sqlite*,               /* An open database */
  const char *sqlFormat, /* printf-style format string for the SQL */
  char ***resultp,       /* Result written to a char *[]  that this points to */
  int *nrow,             /* Number of result rows written here */
  int *ncolumn,          /* Number of result columns written here */
  char **errmsg,         /* Error msg written here */
  ...                    /* Arguments to the format string */
);
int sqlite_get_table_vprintf(
  sqlite*,               /* An open database */
  const char *sqlFormat, /* printf-style format string for the SQL */
  char ***resultp,       /* Result written to a char *[]  that this points to */
  int *nrow,             /* Number of result rows written here */
  int *ncolumn,          /* Number of result columns written here */
  char **errmsg,         /* Error msg written here */
  va_list ap             /* Arguments to the format string */
);
char *sqlite_mprintf(const char*,...);
char *sqlite_vmprintf(const char*, va_list);

/*
** Windows systems should call this routine to free memory that
** is returned in the in the errmsg parameter of sqlite_open() when
** SQLite is a DLL.  For some reason, it does not work to call free()
** directly.
*/
void sqlite_freemem(void *p);

/*
** Windows systems need functions to call to return the sqlite_version
** and sqlite_encoding strings.
*/
const char *sqlite_libversion(void);
const char *sqlite_libencoding(void);

/*
** A pointer to the following structure is used to communicate with
** the implementations of user-defined functions.
*/
typedef struct sqlite_func sqlite_func;

/*
** Use the following routines to create new user-defined functions.  See
** the documentation for details.
*/
int sqlite_create_function(
  sqlite*,                  /* Database where the new function is registered */
  const char *zName,        /* Name of the new function */
  int nArg,                 /* Number of arguments.  -1 means any number */
  void (*xFunc)(sqlite_func*,int,const char**),  /* C code to implement */
  void *pUserData           /* Available via the sqlite_user_data() call */
);
int sqlite_create_aggregate(
  sqlite*,                  /* Database where the new function is registered */
  const char *zName,        /* Name of the function */
  int nArg,                 /* Number of arguments */
  void (*xStep)(sqlite_func*,int,const char**), /* Called for each row */
  void (*xFinalize)(sqlite_func*),       /* Called once to get final result */
  void *pUserData           /* Available via the sqlite_user_data() call */
);

/*
** Use the following routine to define the datatype returned by a
** user-defined function.  The second argument can be one of the
** constants SQLITE_NUMERIC, SQLITE_TEXT, or SQLITE_ARGS or it
** can be an integer greater than or equal to zero.  When the datatype
** parameter is non-negative, the type of the result will be the
** same as the datatype-th argument.  If datatype==SQLITE_NUMERIC
** then the result is always numeric.  If datatype==SQLITE_TEXT then
** the result is always text.  If datatype==SQLITE_ARGS then the result
** is numeric if any argument is numeric and is text otherwise.
*/
int sqlite_function_type(
  sqlite *db,               /* The database there the function is registered */
  const char *zName,        /* Name of the function */
  int datatype              /* The datatype for this function */
);
#define SQLITE_NUMERIC     (-1)
/* #define SQLITE_TEXT     (-2)  // See below */
#define SQLITE_ARGS        (-3)

/*
** SQLite version 3 defines SQLITE_TEXT differently.  To allow both
** version 2 and version 3 to be included, undefine them both if a
** conflict is seen.  Define SQLITE2_TEXT to be the version 2 value.
*/
#ifdef SQLITE_TEXT
# undef SQLITE_TEXT
#else
# define SQLITE_TEXT     (-2)
#endif
#define SQLITE2_TEXT     (-2)



/*
** The user function implementations call one of the following four routines
** in order to return their results.  The first parameter to each of these
** routines is a copy of the first argument to xFunc() or xFinialize().
** The second parameter to these routines is the result to be returned.
** A NULL can be passed as the second parameter to sqlite_set_result_string()
** in order to return a NULL result.
**
** The 3rd argument to _string and _error is the number of characters to
** take from the string.  If this argument is negative, then all characters
** up to and including the first '\000' are used.
**
** The sqlite_set_result_string() function allocates a buffer to hold the
** result and returns a pointer to this buffer.  The calling routine
** (that is, the implmentation of a user function) can alter the content
** of this buffer if desired.
*/
char *sqlite_set_result_string(sqlite_func*,const char*,int);
void sqlite_set_result_int(sqlite_func*,int);
void sqlite_set_result_double(sqlite_func*,double);
void sqlite_set_result_error(sqlite_func*,const char*,int);

/*
** The pUserData parameter to the sqlite_create_function() and
** sqlite_create_aggregate() routines used to register user functions
** is available to the implementation of the function using this
** call.
*/
void *sqlite_user_data(sqlite_func*);

/*
** Aggregate functions use the following routine to allocate
** a structure for storing their state.  The first time this routine
** is called for a particular aggregate, a new structure of size nBytes
** is allocated, zeroed, and returned.  On subsequent calls (for the
** same aggregate instance) the same buffer is returned.  The implementation
** of the aggregate can use the returned buffer to accumulate data.
**
** The buffer allocated is freed automatically be SQLite.
*/
void *sqlite_aggregate_context(sqlite_func*, int nBytes);

/*
** The next routine returns the number of calls to xStep for a particular
** aggregate function instance.  The current call to xStep counts so this
** routine always returns at least 1.
*/
int sqlite_aggregate_count(sqlite_func*);

/*
** This routine registers a callback with the SQLite library.  The
** callback is invoked (at compile-time, not at run-time) for each
** attempt to access a column of a table in the database.  The callback
** returns SQLITE_OK if access is allowed, SQLITE_DENY if the entire
** SQL statement should be aborted with an error and SQLITE_IGNORE
** if the column should be treated as a NULL value.
*/
int sqlite_set_authorizer(
  sqlite*,
  int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
  void *pUserData
);

/*
** The second parameter to the access authorization function above will
** be one of the values below.  These values signify what kind of operation
** is to be authorized.  The 3rd and 4th parameters to the authorization
** function will be parameters or NULL depending on which of the following
** codes is used as the second parameter.  The 5th parameter is the name
** of the database ("main", "temp", etc.) if applicable.  The 6th parameter
** is the name of the inner-most trigger or view that is responsible for
** the access attempt or NULL if this access attempt is directly from 
** input SQL code.
**
**                                          Arg-3           Arg-4
*/
#define SQLITE_COPY                  0   /* Table Name      File Name       */
#define SQLITE_CREATE_INDEX          1   /* Index Name      Table Name      */
#define SQLITE_CREATE_TABLE          2   /* Table Name      NULL            */
#define SQLITE_CREATE_TEMP_INDEX     3   /* Index Name      Table Name      */
#define SQLITE_CREATE_TEMP_TABLE     4   /* Table Name      NULL            */
#define SQLITE_CREATE_TEMP_TRIGGER   5   /* Trigger Name    Table Name      */
#define SQLITE_CREATE_TEMP_VIEW      6   /* View Name       NULL            */
#define SQLITE_CREATE_TRIGGER        7   /* Trigger Name    Table Name      */
#define SQLITE_CREATE_VIEW           8   /* View Name       NULL            */
#define SQLITE_DELETE                9   /* Table Name      NULL            */
#define SQLITE_DROP_INDEX           10   /* Index Name      Table Name      */
#define SQLITE_DROP_TABLE           11   /* Table Name      NULL            */
#define SQLITE_DROP_TEMP_INDEX      12   /* Index Name      Table Name      */
#define SQLITE_DROP_TEMP_TABLE      13   /* Table Name      NULL            */
#define SQLITE_DROP_TEMP_TRIGGER    14   /* Trigger Name    Table Name      */
#define SQLITE_DROP_TEMP_VIEW       15   /* View Name       NULL            */
#define SQLITE_DROP_TRIGGER         16   /* Trigger Name    Table Name      */
#define SQLITE_DROP_VIEW            17   /* View Name       NULL            */
#define SQLITE_INSERT               18   /* Table Name      NULL            */
#define SQLITE_PRAGMA               19   /* Pragma Name     1st arg or NULL */
#define SQLITE_READ                 20   /* Table Name      Column Name     */
#define SQLITE_SELECT               21   /* NULL            NULL            */
#define SQLITE_TRANSACTION          22   /* NULL            NULL            */
#define SQLITE_UPDATE               23   /* Table Name      Column Name     */
#define SQLITE_ATTACH               24   /* Filename        NULL            */
#define SQLITE_DETACH               25   /* Database Name   NULL            */


/*
** The return value of the authorization function should be one of the
** following constants:
*/
/* #define SQLITE_OK  0   // Allow access (This is actually defined above) */
#define SQLITE_DENY   1   /* Abort the SQL statement with an error */
#define SQLITE_IGNORE 2   /* Don't allow access, but don't generate an error */

/*
** Register a function that is called at every invocation of sqlite_exec()
** or sqlite_compile().  This function can be used (for example) to generate
** a log file of all SQL executed against a database.
*/
void *sqlite_trace(sqlite*, void(*xTrace)(void*,const char*), void*);

/*** The Callback-Free API
** 
** The following routines implement a new way to access SQLite that does not
** involve the use of callbacks.
**
** An sqlite_vm is an opaque object that represents a single SQL statement
** that is ready to be executed.
*/
typedef struct sqlite_vm sqlite_vm;

/*
** To execute an SQLite query without the use of callbacks, you first have
** to compile the SQL using this routine.  The 1st parameter "db" is a pointer
** to an sqlite object obtained from sqlite_open().  The 2nd parameter
** "zSql" is the text of the SQL to be compiled.   The remaining parameters
** are all outputs.
**
** *pzTail is made to point to the first character past the end of the first
** SQL statement in zSql.  This routine only compiles the first statement
** in zSql, so *pzTail is left pointing to what remains uncompiled.
**
** *ppVm is left pointing to a "virtual machine" that can be used to execute
** the compiled statement.  Or if there is an error, *ppVm may be set to NULL.
** If the input text contained no SQL (if the input is and empty string or
** a comment) then *ppVm is set to NULL.
**
** If any errors are detected during compilation, an error message is written
** into space obtained from malloc() and *pzErrMsg is made to point to that
** error message.  The calling routine is responsible for freeing the text
** of this message when it has finished with it.  Use sqlite_freemem() to
** free the message.  pzErrMsg may be NULL in which case no error message
** will be generated.
**
** On success, SQLITE_OK is returned.  Otherwise and error code is returned.
*/
int sqlite_compile(
  sqlite *db,                   /* The open database */
  const char *zSql,             /* SQL statement to be compiled */
  const char **pzTail,          /* OUT: uncompiled tail of zSql */
  sqlite_vm **ppVm,             /* OUT: the virtual machine to execute zSql */
  char **pzErrmsg               /* OUT: Error message. */
);

/*
** After an SQL statement has been compiled, it is handed to this routine
** to be executed.  This routine executes the statement as far as it can
** go then returns.  The return value will be one of SQLITE_DONE,
** SQLITE_ERROR, SQLITE_BUSY, SQLITE_ROW, or SQLITE_MISUSE.
**
** SQLITE_DONE means that the execute of the SQL statement is complete
** an no errors have occurred.  sqlite_step() should not be called again
** for the same virtual machine.  *pN is set to the number of columns in
** the result set and *pazColName is set to an array of strings that
** describe the column names and datatypes.  The name of the i-th column
** is (*pazColName)[i] and the datatype of the i-th column is
** (*pazColName)[i+*pN].  *pazValue is set to NULL.
**
** SQLITE_ERROR means that the virtual machine encountered a run-time
** error.  sqlite_step() should not be called again for the same
** virtual machine.  *pN is set to 0 and *pazColName and *pazValue are set
** to NULL.  Use sqlite_finalize() to obtain the specific error code
** and the error message text for the error.
**
** SQLITE_BUSY means that an attempt to open the database failed because
** another thread or process is holding a lock.  The calling routine
** can try again to open the database by calling sqlite_step() again.
** The return code will only be SQLITE_BUSY if no busy handler is registered
** using the sqlite_busy_handler() or sqlite_busy_timeout() routines.  If
** a busy handler callback has been registered but returns 0, then this
** routine will return SQLITE_ERROR and sqltie_finalize() will return
** SQLITE_BUSY when it is called.
**
** SQLITE_ROW means that a single row of the result is now available.
** The data is contained in *pazValue.  The value of the i-th column is
** (*azValue)[i].  *pN and *pazColName are set as described in SQLITE_DONE.
** Invoke sqlite_step() again to advance to the next row.
**
** SQLITE_MISUSE is returned if sqlite_step() is called incorrectly.
** For example, if you call sqlite_step() after the virtual machine
** has halted (after a prior call to sqlite_step() has returned SQLITE_DONE)
** or if you call sqlite_step() with an incorrectly initialized virtual
** machine or a virtual machine that has been deleted or that is associated
** with an sqlite structure that has been closed.
*/
int sqlite_step(
  sqlite_vm *pVm,              /* The virtual machine to execute */
  int *pN,                     /* OUT: Number of columns in result */
  const char ***pazValue,      /* OUT: Column data */
  const char ***pazColName     /* OUT: Column names and datatypes */
);

/*
** This routine is called to delete a virtual machine after it has finished
** executing.  The return value is the result code.  SQLITE_OK is returned
** if the statement executed successfully and some other value is returned if
** there was any kind of error.  If an error occurred and pzErrMsg is not
** NULL, then an error message is written into memory obtained from malloc()
** and *pzErrMsg is made to point to that error message.  The calling routine
** should use sqlite_freemem() to delete this message when it has finished
** with it.
**
** This routine can be called at any point during the execution of the
** virtual machine.  If the virtual machine has not completed execution
** when this routine is called, that is like encountering an error or
** an interrupt.  (See sqlite_interrupt().)  Incomplete updates may be
** rolled back and transactions cancelled,  depending on the circumstances,
** and the result code returned will be SQLITE_ABORT.
*/
int sqlite_finalize(sqlite_vm*, char **pzErrMsg);

/*
** This routine deletes the virtual machine, writes any error message to
** *pzErrMsg and returns an SQLite return code in the same way as the
** sqlite_finalize() function.
**
** Additionally, if ppVm is not NULL, *ppVm is left pointing to a new virtual
** machine loaded with the compiled version of the original query ready for
** execution.
**
** If sqlite_reset() returns SQLITE_SCHEMA, then *ppVm is set to NULL.
**
******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
*/
int sqlite_reset(sqlite_vm*, char **pzErrMsg);

/*
** If the SQL that was handed to sqlite_compile contains variables that
** are represeted in the SQL text by a question mark ('?').  This routine
** is used to assign values to those variables.
**
** The first parameter is a virtual machine obtained from sqlite_compile().
** The 2nd "idx" parameter determines which variable in the SQL statement
** to bind the value to.  The left most '?' is 1.  The 3rd parameter is
** the value to assign to that variable.  The 4th parameter is the number
** of bytes in the value, including the terminating \000 for strings.
** Finally, the 5th "copy" parameter is TRUE if SQLite should make its
** own private copy of this value, or false if the space that the 3rd
** parameter points to will be unchanging and can be used directly by
** SQLite.
**
** Unbound variables are treated as having a value of NULL.  To explicitly
** set a variable to NULL, call this routine with the 3rd parameter as a
** NULL pointer.
**
** If the 4th "len" parameter is -1, then strlen() is used to find the
** length.
**
** This routine can only be called immediately after sqlite_compile()
** or sqlite_reset() and before any calls to sqlite_step().
**
******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
*/
int sqlite_bind(sqlite_vm*, int idx, const char *value, int len, int copy);

/*
** This routine configures a callback function - the progress callback - that
** is invoked periodically during long running calls to sqlite_exec(),
** sqlite_step() and sqlite_get_table(). An example use for this API is to keep
** a GUI updated during a large query.
**
** The progress callback is invoked once for every N virtual machine opcodes,
** where N is the second argument to this function. The progress callback
** itself is identified by the third argument to this function. The fourth
** argument to this function is a void pointer passed to the progress callback
** function each time it is invoked.
**
** If a call to sqlite_exec(), sqlite_step() or sqlite_get_table() results 
** in less than N opcodes being executed, then the progress callback is not
** invoked.
** 
** Calling this routine overwrites any previously installed progress callback.
** To remove the progress callback altogether, pass NULL as the third
** argument to this function.
**
** If the progress callback returns a result other than 0, then the current 
** query is immediately terminated and any database changes rolled back. If the
** query was part of a larger transaction, then the transaction is not rolled
** back and remains active. The sqlite_exec() call returns SQLITE_ABORT. 
**
******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
*/
void sqlite_progress_handler(sqlite*, int, int(*)(void*), void*);

/*
** Register a callback function to be invoked whenever a new transaction
** is committed.  The pArg argument is passed through to the callback.
** callback.  If the callback function returns non-zero, then the commit
** is converted into a rollback.
**
** If another function was previously registered, its pArg value is returned.
** Otherwise NULL is returned.
**
** Registering a NULL function disables the callback.
**
******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
*/
void *sqlite_commit_hook(sqlite*, int(*)(void*), void*);

/*
** Open an encrypted SQLite database.  If pKey==0 or nKey==0, this routine
** is the same as sqlite_open().
**
** The code to implement this API is not available in the public release
** of SQLite.
*/
sqlite *sqlite_open_encrypted(
  const char *zFilename,   /* Name of the encrypted database */
  const void *pKey,        /* Pointer to the key */
  int nKey,                /* Number of bytes in the key */
  int *pErrcode,           /* Write error code here */
  char **pzErrmsg          /* Write error message here */
);

/*
** Change the key on an open database.  If the current database is not
** encrypted, this routine will encrypt it.  If pNew==0 or nNew==0, the
** database is decrypted.
**
** The code to implement this API is not available in the public release
** of SQLite.
*/
int sqlite_rekey(
  sqlite *db,                    /* Database to be rekeyed */
  const void *pKey, int nKey     /* The new key */
);

/*
** Encode a binary buffer "in" of size n bytes so that it contains
** no instances of characters '\'' or '\000'.  The output is 
** null-terminated and can be used as a string value in an INSERT
** or UPDATE statement.  Use sqlite_decode_binary() to convert the
** string back into its original binary.
**
** The result is written into a preallocated output buffer "out".
** "out" must be able to hold at least 2 +(257*n)/254 bytes.
** In other words, the output will be expanded by as much as 3
** bytes for every 254 bytes of input plus 2 bytes of fixed overhead.
** (This is approximately 2 + 1.0118*n or about a 1.2% size increase.)
**
** The return value is the number of characters in the encoded
** string, excluding the "\000" terminator.
**
** If out==NULL then no output is generated but the routine still returns
** the number of characters that would have been generated if out had
** not been NULL.
*/
int sqlite_encode_binary(const unsigned char *in, int n, unsigned char *out);

/*
** Decode the string "in" into binary data and write it into "out".
** This routine reverses the encoding created by sqlite_encode_binary().
** The output will always be a few bytes less than the input.  The number
** of bytes of output is returned.  If the input is not a well-formed
** encoding, -1 is returned.
**
** The "in" and "out" parameters may point to the same buffer in order
** to decode a string in place.
*/
int sqlite_decode_binary(const unsigned char *in, unsigned char *out);

#ifdef __cplusplus
}  /* End of the 'extern "C"' block */
#endif

#endif /* _SQLITE_H_ */
php/ext/standard/reg.h000064400000003502151731376020010666 0ustar00/* 
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Rasmus Lerdorf <rasmus@lerdorf.on.ca>                        |
   +----------------------------------------------------------------------+
*/


/* $Id: reg.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef REG_H
#define REG_H

PHPAPI char *php_reg_replace(const char *pattern, const char *replace, const char *string, int icase, int extended);

PHP_FUNCTION(ereg);
PHP_FUNCTION(eregi);
PHP_FUNCTION(eregi_replace);
PHP_FUNCTION(ereg_replace);
PHP_FUNCTION(split);
PHP_FUNCTION(spliti);
PHPAPI PHP_FUNCTION(sql_regcase);

ZEND_BEGIN_MODULE_GLOBALS(reg)
	HashTable ht_rc;
	unsigned int lru_counter;
ZEND_END_MODULE_GLOBALS(reg)

PHP_MINIT_FUNCTION(regex);
PHP_MSHUTDOWN_FUNCTION(regex);
PHP_MINFO_FUNCTION(regex);


#ifdef ZTS
#define REG(v) TSRMG(reg_globals_id, zend_reg_globals *, v)
#else
#define REG(v) (reg_globals.v)
#endif

#endif /* REG_H */
php/ext/standard/php_smart_str_public.h000064400000002546151731376030014344 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Sascha Schumann <sascha@schumann.cx>                         |
   +----------------------------------------------------------------------+
 */

/* $Id: php_smart_str_public.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_SMART_STR_PUBLIC_H
#define PHP_SMART_STR_PUBLIC_H

#include <sys/types.h>

typedef struct {
	char *c;
	size_t len;
	size_t a;
} smart_str;

#endif
php/ext/standard/php_smart_str.h000064400000014673151731376060013015 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Sascha Schumann <sascha@schumann.cx>                         |
   +----------------------------------------------------------------------+
 */

/* $Id: php_smart_str.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_SMART_STR_H
#define PHP_SMART_STR_H

#include "php_smart_str_public.h"

#include <stdlib.h>
#ifndef SMART_STR_USE_REALLOC
#include <zend.h>
#endif

#define smart_str_0(x) do {											\
	if ((x)->c) {													\
		(x)->c[(x)->len] = '\0';									\
	}																\
} while (0)

#ifndef SMART_STR_PREALLOC
#define SMART_STR_PREALLOC 128
#endif

#ifndef SMART_STR_START_SIZE
#define SMART_STR_START_SIZE 78
#endif

#ifdef SMART_STR_USE_REALLOC
#define SMART_STR_REALLOC(a,b,c) realloc((a),(b))
#else
#define SMART_STR_REALLOC(a,b,c) perealloc((a),(b),(c))
#endif

#define SMART_STR_DO_REALLOC(d, what) \
	(d)->c = SMART_STR_REALLOC((d)->c, (d)->a + 1, (what))

#define smart_str_alloc4(d, n, what, newlen) do {					\
	if (!(d)->c) {													\
		(d)->len = 0;												\
		newlen = (n);												\
		(d)->a = newlen < SMART_STR_START_SIZE 						\
				? SMART_STR_START_SIZE 								\
				: newlen + SMART_STR_PREALLOC;						\
		SMART_STR_DO_REALLOC(d, what);								\
	} else {														\
		newlen = (d)->len + (n);									\
		if (newlen >= (d)->a) {										\
			(d)->a = newlen + SMART_STR_PREALLOC;					\
			SMART_STR_DO_REALLOC(d, what);							\
		}															\
	}																\
} while (0)

#define smart_str_alloc(d, n, what) \
	smart_str_alloc4((d), (n), (what), newlen)

/* wrapper */

#define smart_str_appends_ex(dest, src, what) \
	smart_str_appendl_ex((dest), (src), strlen(src), (what))
#define smart_str_appends(dest, src) \
	smart_str_appendl((dest), (src), strlen(src))

#define smart_str_appendc(dest, c) \
	smart_str_appendc_ex((dest), (c), 0)
#define smart_str_free(s) \
	smart_str_free_ex((s), 0)
#define smart_str_appendl(dest, src, len) \
	smart_str_appendl_ex((dest), (src), (len), 0)
#define smart_str_append(dest, src) \
	smart_str_append_ex((dest), (src), 0)
#define smart_str_append_long(dest, val) \
	smart_str_append_long_ex((dest), (val), 0)
#define smart_str_append_off_t(dest, val) \
	smart_str_append_off_t_ex((dest), (val), 0)
#define smart_str_append_unsigned(dest, val) \
	smart_str_append_unsigned_ex((dest), (val), 0)

#define smart_str_appendc_ex(dest, ch, what) do {					\
	register size_t __nl;											\
	smart_str_alloc4((dest), 1, (what), __nl);						\
	(dest)->len = __nl;												\
	((unsigned char *) (dest)->c)[(dest)->len - 1] = (ch);			\
} while (0)

#define smart_str_free_ex(s, what) do {								\
	smart_str *__s = (smart_str *) (s);								\
	if (__s->c) {													\
		pefree(__s->c, what);										\
		__s->c = NULL;												\
	}																\
	__s->a = __s->len = 0;											\
} while (0)

#define smart_str_appendl_ex(dest, src, nlen, what) do {			\
	register size_t __nl;											\
	smart_str *__dest = (smart_str *) (dest);						\
																	\
	smart_str_alloc4(__dest, (nlen), (what), __nl);					\
	memcpy(__dest->c + __dest->len, (src), (nlen));					\
	__dest->len = __nl;												\
} while (0)

/* input: buf points to the END of the buffer */
#define smart_str_print_unsigned4(buf, num, vartype, result) do {	\
	char *__p = (buf);												\
	vartype __num = (num);											\
	*__p = '\0';													\
	do {															\
		*--__p = (char) (__num % 10) + '0';							\
		__num /= 10;												\
	} while (__num > 0);											\
	result = __p;													\
} while (0)

/* buf points to the END of the buffer */
#define smart_str_print_long4(buf, num, vartype, result) do {	\
	if (num < 0) {													\
		/* this might cause problems when dealing with LONG_MIN		\
		   and machines which don't support long long.  Works		\
		   flawlessly on 32bit x86 */								\
		smart_str_print_unsigned4((buf), -(num), vartype, (result));	\
		*--(result) = '-';											\
	} else {														\
		smart_str_print_unsigned4((buf), (num), vartype, (result));	\
	}																\
} while (0)

/*
 * these could be replaced using a braced-group inside an expression
 * for GCC compatible compilers, e.g.
 *
 * #define f(..) ({char *r;..;__r;})
 */  
 
static inline char *smart_str_print_long(char *buf, long num) {
	char *r; 
	smart_str_print_long4(buf, num, unsigned long, r); 
	return r;
}

static inline char *smart_str_print_unsigned(char *buf, long num) {
	char *r; 
	smart_str_print_unsigned4(buf, num, unsigned long, r); 
	return r;
}

#define smart_str_append_generic_ex(dest, num, type, vartype, func) do {	\
	char __b[32];															\
	char *__t;																\
   	smart_str_print##func##4 (__b + sizeof(__b) - 1, (num), vartype, __t);	\
	smart_str_appendl_ex((dest), __t, __b + sizeof(__b) - 1 - __t, (type));	\
} while (0)
	
#define smart_str_append_unsigned_ex(dest, num, type) \
	smart_str_append_generic_ex((dest), (num), (type), unsigned long, _unsigned)

#define smart_str_append_long_ex(dest, num, type) \
	smart_str_append_generic_ex((dest), (num), (type), unsigned long, _long)

#define smart_str_append_off_t_ex(dest, num, type) \
	smart_str_append_generic_ex((dest), (num), (type), off_t, _long)

#define smart_str_append_ex(dest, src, what) \
	smart_str_appendl_ex((dest), ((smart_str *)(src))->c, \
		((smart_str *)(src))->len, (what));


#define smart_str_setl(dest, src, nlen) do {						\
	(dest)->len = (nlen);											\
	(dest)->a = (nlen) + 1;											\
	(dest)->c = (char *) (src);										\
} while (0)

#define smart_str_sets(dest, src) \
	smart_str_setl((dest), (src), strlen(src));

#endif
php/ext/igbinary/src/php5/igbinary.h000064400000005144151731376100013367 0ustar00/*
  +----------------------------------------------------------------------+
  | See COPYING file for further copyright information                   |
  +----------------------------------------------------------------------+
  | Author: Oleg Grenrus <oleg.grenrus@dynamoid.com>                     |
  | See CREDITS for contributors                                         |
  +----------------------------------------------------------------------+
*/

#ifndef IGBINARY_H
#define IGBINARY_H
#ifdef PHP_WIN32
# include "win32/php_stdint.h"
#else
# include <stdint.h>
#endif

/* Forward declarations */
struct zval;

/* Constants / macro constants */
/** Binary protocol version of igbinary. */
#define IGBINARY_FORMAT_VERSION 0x00000002

#define PHP_IGBINARY_VERSION "2.0.8"

/* Macros */
#ifdef PHP_WIN32
#	if defined(IGBINARY_EXPORTS) || (!defined(COMPILE_DL_IGBINARY))
#		define IGBINARY_API __declspec(dllexport)
#	elif defined(COMPILE_DL_IGBINARY)
#		define IGBINARY_API __declspec(dllimport)
#	else
#		define IGBINARY_API /* nothing special */
#	endif
#elif defined(__GNUC__) && __GNUC__ >= 4
#	define IGBINARY_API __attribute__ ((visibility("default")))
#else
#	define IGBINARY_API /* nothing special */
#endif

/** Struct that contains pointers to memory allocation and deallocation functions.
 * @see igbinary_serialize_data
 */
struct igbinary_memory_manager {
	void *(*alloc)(size_t size, void *context);
	void *(*realloc)(void *ptr, size_t new_size, void *context);
	void (*free)(void *ptr, void *context);
	void *context;
};

/** Serialize zval.
 * Return buffer is allocated by this function with emalloc.
 * @param[out] ret Return buffer
 * @param[out] ret_len Size of return buffer
 * @param[in] z Variable to be serialized
 * @return 0 on success, 1 elsewhere.
 */
IGBINARY_API int igbinary_serialize(uint8_t **ret, size_t *ret_len, zval *z TSRMLS_DC);

/** Serialize zval.
 * Return buffer is allocated by this function with emalloc.
 * @param[out] ret Return buffer
 * @param[out] ret_len Size of return buffer
 * @param[in] z Variable to be serialized
 * @param[in] memory_manager Pointer to the structure that contains memory allocation functions.
 * @return 0 on success, 1 elsewhere.
 */
IGBINARY_API int igbinary_serialize_ex(uint8_t **ret, size_t *ret_len, zval *z, struct igbinary_memory_manager *memory_manager TSRMLS_DC);

/** Unserialize to zval.
 * @param[in] buf Buffer with serialized data.
 * @param[in] buf_len Buffer length.
 * @param[out] z Unserialized zval
 * @return 0 on success, 1 elsewhere.
 */
IGBINARY_API int igbinary_unserialize(const uint8_t *buf, size_t buf_len, zval **z TSRMLS_DC);

#endif /* IGBINARY_H */
php/ext/igbinary/src/php5/php_igbinary.h000064400000004546151731376110014244 0ustar00/*
  +----------------------------------------------------------------------+
  | See COPYING file for further copyright information                   |
  +----------------------------------------------------------------------+
  | Author: Oleg Grenrus <oleg.grenrus@dynamoid.com>                     |
  | See CREDITS for contributors                                         |
  +----------------------------------------------------------------------+
*/

#ifndef PHP_IGBINARY_H
#define PHP_IGBINARY_H

#include "php.h"

/** Module entry of igbinary. */
extern zend_module_entry igbinary_module_entry;
#define phpext_igbinary_ptr &igbinary_module_entry

#ifdef PHP_WIN32
#define PHP_IGBINARY_API __declspec(dllexport)
#else
#define PHP_IGBINARY_API
#endif

ZEND_BEGIN_MODULE_GLOBALS(igbinary)
	zend_bool compact_strings;
ZEND_END_MODULE_GLOBALS(igbinary)

#ifdef ZTS
#include "TSRM.h"
#endif

#include "ext/standard/php_smart_str.h"

/** Module init function. */
PHP_MINIT_FUNCTION(igbinary);

/** Module shutdown function. */
PHP_MSHUTDOWN_FUNCTION(igbinary);

/** Request init function. */
PHP_RINIT_FUNCTION(igbinary);

/** Request shutdown function. */
PHP_RSHUTDOWN_FUNCTION(igbinary);

/** Module info function for phpinfo(). */
PHP_MINFO_FUNCTION(igbinary);

/** string igbinary_serialize(mixed value).
 * Returns the binary serialized value.
 */
PHP_FUNCTION(igbinary_serialize);

/** mixed igbinary_unserialize(string data).
 * Unserializes the given inputstring (value).
 */
PHP_FUNCTION(igbinary_unserialize);

#ifdef ZTS
#define IGBINARY_G(v) TSRMG(igbinary_globals_id, zend_igbinary_globals *, v)
#else
#define IGBINARY_G(v) (igbinary_globals.v)
#endif

/** Backport macros from php 5.3 */
#ifndef Z_ISREF_P
#define Z_ISREF_P(pz)                  PZVAL_IS_REF(pz)
#endif

#ifndef Z_ISREF_PP
#define Z_ISREF_PP(ppz)                Z_ISREF_P(*(ppz))
#endif

#ifndef Z_SET_ISREF_TO_P
#define Z_SET_ISREF_TO_P(pz, isref)    (Z_ISREF_P(pz) = (isref))
#endif

#ifndef Z_SET_ISREF_TO_PP
#define Z_SET_ISREF_TO_PP(ppz, isref)  Z_SET_ISREF_TO_P(*(ppz), isref)
#endif

#ifndef Z_ADDREF_P
#define Z_ADDREF_P(pz)                 ZVAL_ADDREF(pz)
#endif

#ifndef Z_ADDREF_PP
#define Z_ADDREF_PP(ppz)               Z_ADDREF_P(*(ppz))
#endif

#endif /* PHP_IGBINARY_H */

/*
 * Local variables:
 * tab-width: 2
 * c-basic-offset: 0
 * End:
 * vim600: noet sw=2 ts=2 fdm=marker
 * vim<600: noet sw=2 ts=2
 */
php/main/config.w32.h000064400000014065151731376120010323 0ustar00/*
	Build Configuration for Win32.
	This has only been tested with MS VisualC++ 6 (and later).

	$Id: config.w32.h 239522 2007-07-11 17:36:56Z johannes $
*/

/* Default PHP / PEAR directories */
#define CONFIGURATION_FILE_PATH "php.ini"
#define PEAR_INSTALLDIR "c:\\php5\\pear"
#define PHP_BINDIR "c:\\php5"
#define PHP_CONFIG_FILE_PATH (getenv("SystemRoot"))?getenv("SystemRoot"):""
#define PHP_CONFIG_FILE_SCAN_DIR ""
#define PHP_DATADIR "c:\\php5"
#define PHP_EXTENSION_DIR "c:\\php5"
#define PHP_INCLUDE_PATH	".;c:\\php5\\pear"
#define PHP_LIBDIR "c:\\php5"
#define PHP_LOCALSTATEDIR "c:\\php5"
#define PHP_PREFIX "c:\\php5"
#define PHP_SYSCONFDIR "c:\\php5"

/* Enable / Disable BCMATH extension (default: enabled) */
#define HAVE_BCMATH 1

/* Enable / Disable crypt() function (default: enabled) */
#define HAVE_CRYPT 1
#define PHP_STD_DES_CRYPT 1
#define PHP_EXT_DES_CRYPT 0
#define PHP_MD5_CRYPT 1
#define PHP_BLOWFISH_CRYPT 0

/* Enable / Disable CALENDAR extension (default: enabled) */
#define HAVE_CALENDAR 1

/* Enable / Disable CTYPE extension (default: enabled) */
#define HAVE_CTYPE 1

/* Enable / Disable FTP extension (default: enabled) */
#define HAVE_FTP 1

/* Enable / Disable MBSTRING extension (default: disabled) */
/* #define HAVE_MBSTRING 0 */ 
/* #define HAVE_MBREGEX  0 */ 
/* #define HAVE_MBSTR_CN 0 */ 
/* #define HAVE_MBSTR_JA 0 */ 
/* #define HAVE_MBSTR_KR 0 */
/* #define HAVE_MBSTR_RU 0 */
/* #define HAVE_MBSTR_TW 0 */ 

/* If you have the .Net SDK in your include path, define this
 * to compile .Net support into your COM extension. */
#define HAVE_MSCOREE_H 0

/* Enable / Disable ODBC extension (default: enabled) */
#define HAVE_UODBC 1

/* Enable / Disable PCRE extension (default: enabled) */
#define HAVE_BUNDLED_PCRE	1
#define HAVE_PCRE 1

/* Enable / Disable SESSION extension (default: enabled) */
#define HAVE_PHP_SESSION 1

/* Enable / Disable TOKENIZER extension (default: enabled) */
#define HAVE_TOKENIZER 1

/* Enable / Disable WDDX extension (default: enabled) */
#define HAVE_WDDX 1

/* Enable / Disable XML extensions (default: enabled) */
#define HAVE_LIBXML 1
#define HAVE_DOM 1
#define HAVE_SIMPLEXML 1
#define HAVE_XML 1
#define HAVE_XMLREADER 1
#define HAVE_XMLWRITER 1
#define HAVE_LIBXML_PARSER_H 1

/* Enable / Disable ZLIB extension (default: enabled) */
#define HAVE_ZLIB 1
#define HAVE_ZLIB_H 1

/* Enable / Disable SQLite extension (default: enabled) */
#define HAVE_SQLITE 1

/* PHP Runtime Configuration */
#define FORCE_CGI_REDIRECT 1
#define PHP_URL_FOPEN 1
#define PHP_SAFE_MODE 0
#define MAGIC_QUOTES 0
#define USE_CONFIG_FILE 1
#define DEFAULT_SHORT_OPEN_TAG "1"
#define ENABLE_PATHINFO_CHECK 1

/* Platform-Specific Configuration. Should not be changed. */
#define PHP_SIGCHILD 0
#define HAVE_LIBBIND 1
#define HAVE_GETSERVBYNAME 1
#define HAVE_GETSERVBYPORT 1
#define HAVE_GETPROTOBYNAME 1
#define HAVE_GETPROTOBYNUMBER 1
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#define HAVE_ERRMSG_H 0
#undef HAVE_ADABAS
#undef HAVE_SOLID
#undef HAVE_LINK
#undef HAVE_SYMLINK

/* its in win32/time.c */
#define HAVE_USLEEP 1

#define HAVE_GETCWD 1
#define HAVE_POSIX_READDIR_R 1
#define NEED_ISBLANK 1
#define DISCARD_PATH 0
#undef HAVE_SETITIMER
#undef HAVE_IODBC
#define HAVE_LIBDL 1
#define HAVE_GETTIMEOFDAY 1
#define HAVE_PUTENV 1
#define HAVE_LIMITS_H 1
#define HAVE_TZSET 1
#define HAVE_TZNAME 1
#undef HAVE_FLOCK
#define HAVE_ALLOCA 1
#undef HAVE_SYS_TIME_H
#define HAVE_SIGNAL_H 1
#undef HAVE_ST_BLKSIZE
#undef HAVE_ST_BLOCKS
#define HAVE_ST_RDEV 1
#define HAVE_UTIME_NULL 1
#define HAVE_VPRINTF 1
#define STDC_HEADERS 1
#define REGEX 1
#define HSREGEX 1
#define HAVE_GCVT 1
#define HAVE_GETLOGIN 1
#define HAVE_GETTIMEOFDAY 1
#define HAVE_MEMCPY 1
#define HAVE_MEMMOVE 1
#define HAVE_PUTENV 1
#define HAVE_REGCOMP 1
#define HAVE_SETLOCALE 1
#define HAVE_LOCALECONV 1
#define HAVE_LOCALE_H 1
#ifndef HAVE_LIBBIND
#define HAVE_SETVBUF 1
#endif
#define HAVE_SHUTDOWN 1
#define HAVE_SNPRINTF 1
#define HAVE_VSNPRINTF 1
#define HAVE_STRCASECMP 1
#define HAVE_STRDUP 1
#define HAVE_STRERROR 1
#define HAVE_STRSTR 1
#define HAVE_TEMPNAM 1
#define HAVE_UTIME 1
#undef HAVE_DIRENT_H
#define HAVE_ASSERT_H 1
#define HAVE_FCNTL_H 1
#define HAVE_GRP_H 0
#undef HAVE_PWD_H
#define HAVE_STRING_H 1
#undef HAVE_SYS_FILE_H
#undef HAVE_SYS_SOCKET_H
#undef HAVE_SYS_WAIT_H
#define HAVE_SYSLOG_H 1
#undef HAVE_UNISTD_H
#define HAVE_LIBDL 1
#define HAVE_LIBM 1
#define HAVE_CUSERID 0
#undef HAVE_RINT
#define HAVE_STRFTIME 1
/* int and long are stll 32bit in 64bit compiles */
#define SIZEOF_INT 4
#define SIZEOF_LONG 4
/* MSVC.6/NET don't allow 'long long' or know 'intmax_t' */
#define SIZEOF_LONG_LONG_INT 0
#define SIZEOF_LONG_LONG 8 /* defined as __int64 */
#define SIZEOF_INTMAX_T 0
#define ssize_t SSIZE_T
#ifdef _WIN64
# define SIZEOF_SIZE_T 8
# define SIZEOF_PTRDIFF_T 8
#else
# define SIZEOF_SIZE_T 4
# define SIZEOF_PTRDIFF_T 4
#endif
#define HAVE_GLOB
#define PHP_SHLIB_SUFFIX "dll"
#define HAVE_SQLDATASOURCES
#define POSIX_MALLOC_THRESHOLD 10

/*
 * defining HAVE_SOCKLEN_T prevents PHP from building with the latest platform SDK...
 * #define HAVE_SOCKLEN_T
 */

/* Win32 supports strcoll */
#define HAVE_STRCOLL 1

/* Win32 support proc_open */
#define PHP_CAN_SUPPORT_PROC_OPEN 1

#define HAVE_MBLEN

#undef HAVE_ATOF_ACCEPTS_NAN
#undef HAVE_ATOF_ACCEPTS_INF
#define HAVE_HUGE_VAL_NAN 1

/* vs.net 2005 has a 64-bit time_t.  This will likely break
 * 3rdParty libs that were built with older compilers; switch
 * back to 32-bit */
#define _USE_32BIT_TIME_T 1
#define HAVE_STDLIB_H 1
/* have the arpa\nameser.h header file */
#define HAVE_ARPA_NAMESER_H 1

/* undefined */
#define PHP_FASTCGI 1

/* Have COM_DOTNET support */
#define HAVE_COM_DOTNET 1

/* Have date/time support */
#define HAVE_DATE 1

/* GD support */
#define HAVE_LIBGD 1
/* undefined */
#define HAVE_HASH_EXT 1

/* Define if iconv extension is enabled */
#define HAVE_ICONV 1

/* Define if libiconv is available */
#define HAVE_LIBICONV 1

/* Which iconv implementation to use */
#define PHP_ICONV_IMPL "\"libiconv\""

/* Whether iconv supports errno or not */
#define ICONV_SUPPORTS_ERRNO 1

/* SPL support */
#define HAVE_SPL 1
php/main/php3_compat.h000064400000011010151731376130010645 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 5                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2010 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author:                                                              |
  +----------------------------------------------------------------------+
*/

/* $Id: php3_compat.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP3_COMPAT_H
#define PHP3_COMPAT_H

typedef zval pval;

#define pval_copy_constructor zval_copy_ctor
#define pval_destructor	zval_dtor

#define _php3_hash_init zend_hash_init
#define _php3_hash_destroy zend_hash_destroy

#define _php3_hash_clean zend_hash_clean

#define _php3_hash_add_or_update zend_hash_add_or_update
#define _php3_hash_add zend_hash_add
#define _php3_hash_update zend_hash_update

#define _php3_hash_quick_add_or_update zend_hash_quick_add_or_update
#define _php3_hash_quick_add zend_hash_quick_add
#define _php3_hash_quick_update zend_hash_quick_update

#define _php3_hash_index_update_or_next_insert zend_hash_index_update_or_next_insert
#define _php3_hash_index_update zend_hash_index_update
#define _php3_hash_next_index_insert zend_hash_next_index_insert

#define _php3_hash_pointer_update zend_hash_pointer_update

#define _php3_hash_pointer_index_update_or_next_insert zend_hash_pointer_index_update_or_next_insert
#define _php3_hash_pointer_index_update zend_hash_pointer_index_update
#define _php3_hash_next_index_pointer_update zend_hash_next_index_pointer_update
#define _php3_hash_next_index_pointer_insert zend_hash_next_index_pointer_insert

#define _php3_hash_del_key_or_index zend_hash_del_key_or_index
#define _php3_hash_del zend_hash_del
#define _php3_hash_index_del zend_hash_index_del

#define _php3_hash_find zend_hash_find
#define _php3_hash_quick_find zend_hash_quick_find
#define _php3_hash_index_find zend_hash_index_find

#define _php3_hash_exists zend_hash_exists
#define _php3_hash_index_exists zend_hash_index_exists
#define _php3_hash_is_pointer zend_hash_is_pointer
#define _php3_hash_index_is_pointer zend_hash_index_is_pointer
#define _php3_hash_next_free_element zend_hash_next_free_element

#define _php3_hash_move_forward zend_hash_move_forward
#define _php3_hash_move_backwards zend_hash_move_backwards
#define _php3_hash_get_current_key zend_hash_get_current_key
#define _php3_hash_get_current_data zend_hash_get_current_data
#define _php3_hash_internal_pointer_reset zend_hash_internal_pointer_reset
#define _php3_hash_internal_pointer_end zend_hash_internal_pointer_end

#define _php3_hash_copy zend_hash_copy
#define _php3_hash_merge zend_hash_merge
#define _php3_hash_sort zend_hash_sort
#define _php3_hash_minmax zend_hash_minmax

#define _php3_hash_num_elements zend_hash_num_elements

#define _php3_hash_apply zend_hash_apply
#define _php3_hash_apply_with_argument zend_hash_apply_with_argument


#define php3_error php_error

#define php3_printf php_printf
#define _php3_sprintf php_sprintf



#define php3_module_entry zend_module_entry

#define php3_strndup		zend_strndup
#define php3_str_tolower	zend_str_tolower
#define php3_binary_strcmp	zend_binary_strcmp


#define php3_list_insert	zend_list_insert
#define php3_list_find		zend_list_find
#define php3_list_delete	zend_list_delete

#define php3_plist_insert	zend_plist_insert
#define php3_plist_find		zend_plist_find
#define php3_plist_delete	zend_plist_delete

#define zend_print_pval		zend_print_zval
#define zend_print_pval_r	zend_print_zval_r


#define function_entry		zend_function_entry

#define _php3_addslashes	php_addslashes
#define _php3_stripslashes	php_stripslashes
#define php3_dl             php_dl

#define getParameters		zend_get_parameters
#define getParametersArray	zend_get_parameters_array

#define list_entry			zend_rsrc_list_entry

#endif							/* PHP3_COMPAT_H */
php/main/win95nt.h000064400000005167151731376140007766 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 5                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2010 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author:                                                              |
  +----------------------------------------------------------------------+
*/

/* $Id: win95nt.h 293036 2010-01-03 09:23:27Z sebastian $ */

/* Defines and types for Windows 95/NT */
#define HAVE_DECLARED_TIMEZONE
#define WIN32_LEAN_AND_MEAN
#include <io.h>
#include <malloc.h>
#include <direct.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <sys/types.h>
typedef int uid_t;
typedef int gid_t;
typedef char * caddr_t;
#define lstat(x, y) stat(x, y)
#define		_IFIFO	0010000	/* fifo */
#define		_IFBLK	0060000	/* block special */
#define		_IFLNK	0120000	/* symbolic link */
#define S_IFIFO		_IFIFO
#define S_IFBLK		_IFBLK
#define	S_IFLNK		_IFLNK
#ifndef S_ISREG 
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#endif
#define chdir(path) _chdir(path)
#define mkdir(a, b)	_mkdir(a)
#define rmdir(a)	_rmdir(a)
#define getpid		_getpid
#define php_sleep(t)	Sleep(t*1000)
#ifndef getcwd
# define getcwd(a, b)		_getcwd(a, b)
#endif
#define off_t		_off_t
typedef unsigned int uint;
typedef unsigned long ulong;
#if !NSAPI
typedef long pid_t;
#endif

/* missing in vc5 math.h */
#define M_PI             3.14159265358979323846
#define M_TWOPI         (M_PI * 2.0)
#define M_PI_2           1.57079632679489661923
#ifndef M_PI_4
#define M_PI_4           0.78539816339744830962
#endif

#if !defined(PHP_DEBUG)
#ifdef inline
#undef inline
#endif
#define inline  __inline
#endif

/* General Windows stuff */
#define WINDOWS 1

/* Prevent use of VC5 OpenFile function */
#define NOOPENFILE

/* sendmail is built-in */
#ifdef PHP_PROG_SENDMAIL
#undef PHP_PROG_SENDMAIL
#define PHP_PROG_SENDMAIL "Built in mailer"
#endif
php/main/php_logos.h000064400000003066151731376140010437 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 5                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2010 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author:                                                              |
  +----------------------------------------------------------------------+
*/

/* $Id: php_logos.h 293036 2010-01-03 09:23:27Z sebastian $ */


#ifndef _PHP_LOGOS_H
#define _PHP_LOGOS_H

BEGIN_EXTERN_C()
PHPAPI int php_register_info_logo(char *logo_string, const char *mimetype, const unsigned char *data, int size);
PHPAPI int php_unregister_info_logo(char *logo_string);
END_EXTERN_C()

int php_init_info_logos(void);
int php_shutdown_info_logos(void);
int php_info_logos(const char *logo_string TSRMLS_DC);

#endif /* _PHP_LOGOS_H */
php/main/safe_mode.h000064400000003436151731376140010370 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 5                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2010 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author:                                                              |
  +----------------------------------------------------------------------+
*/

/* $Id: safe_mode.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef SAFE_MODE_H
#define SAFE_MODE_H

/* mode's for php_checkuid() */
#define CHECKUID_DISALLOW_FILE_NOT_EXISTS 0
#define CHECKUID_ALLOW_FILE_NOT_EXISTS 1
#define CHECKUID_CHECK_FILE_AND_DIR 2
#define CHECKUID_ALLOW_ONLY_DIR 3
#define CHECKUID_CHECK_MODE_PARAM 4
#define CHECKUID_ALLOW_ONLY_FILE 5

/* flags for php_checkuid_ex() */
#define CHECKUID_NO_ERRORS	0x01

BEGIN_EXTERN_C()
PHPAPI int php_checkuid(const char *filename, const char *fopen_mode, int mode);
PHPAPI int php_checkuid_ex(const char *filename, const char *fopen_mode, int mode, int flags);
PHPAPI char *php_get_current_user(void);
END_EXTERN_C()

#endif
php/main/php_regex.h000064400000004037151731376150010426 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 5                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2010 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author:                                                              |
  +----------------------------------------------------------------------+
*/

/* $Id: php_regex.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef PHP_REGEX_H
#define PHP_REGEX_H

/*
 * REGEX means:
 * 0.. system regex
 * 1.. bundled regex
 */

#if REGEX
/* get aliases */
#include "regex/regex_extra.h"
#include "regex/regex.h"

/* get rid of aliases */
#define PHP_NO_ALIASES
#include "regex/regex_extra.h"
#undef PHP_NO_ALIASES

#undef _PCREPOSIX_H
#define _PCREPOSIX_H 1

#ifndef _REGEX_H
#define _REGEX_H 1				/* this should stop Apache from loading the system version of regex.h */
#endif
#ifndef _REGEX_H_
#define _REGEX_H_ 1
#endif
#ifndef _RX_H
#define _RX_H 1				  	/* Try defining these for Linux to	*/
#endif
#ifndef __REGEXP_LIBRARY_H__
#define __REGEXP_LIBRARY_H__ 1 	/* avoid Apache including regex.h	*/
#endif
#ifndef _H_REGEX
#define _H_REGEX 1              /* This one is for AIX */
#endif
#elif REGEX == 0
#include <regex.h>
#ifndef _REGEX_H_
#define _REGEX_H_ 1
#endif
#endif

#endif /* PHP_REGEX_H */
php/main/logos.h000064400000062032151731376150007567 0ustar00/*
  +----------------------------------------------------------------------+
  | PHP Version 5                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2010 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author:                                                              |
  +----------------------------------------------------------------------+
*/

/* $Id: logos.h 293036 2010-01-03 09:23:27Z sebastian $ */

#define CONTEXT_TYPE_IMAGE_GIF "Content-Type: image/gif"

static const unsigned char zend_logo[] = {
	 71,  73,  70,  56,  57,  97, 113,   0,  72,   0, 
	213,   0,   0,  13,  13,  14,   1,   3,   6,   2, 
	  5,   9,  46,  68,  94,  21,  29,  39,   5,  15, 
	 26,   4,  10,  17,  29,  43,  58,   0,   1,   2, 
	  9,  25,  42,  38, 105, 171,  24,  67, 109,  13, 
	 36,  59,  10,  27,  45,   9,  25,  41,  35,  96, 
	157,  32,  87, 142,  29,  79, 130,  26,  70, 114, 
	 20,  54,  87,  29,  77, 124,  10,  26,  42,  34, 
	 88, 141,  10,  24,  38,  11,  26,  41,   1,   2, 
	  3,  55,  80, 105,  45,  63,  81,  49,  53,  57, 
	  5,  15,  24,   9,  26,  42,  30,  85, 138,  33, 
	 92, 149,  26,  73, 117,  10,  28,  45,  32,  89, 
	142,  30,  84, 134,  26,  72, 115,  15,  42,  67, 
	 23,  62,  99,  12,  32,  51,   7,  21,  33,   9, 
	 26,  41,   8,  23,  35,   7,  25,  37,  51,  58, 
	 63,   2,   4,   5,  25,  26,  26,  49,  50,  50, 
	255, 102,   0, 255, 255, 255, 204, 204, 204, 199, 
	199, 199, 191, 191, 191, 171, 171, 171, 146, 146, 
	146, 115, 115, 115,  85,  85,  85,  60,  60,  60, 
	 55,  55,  55,  38,  38,  38,   7,   7,   7,   3, 
	  3,   3,   0,   0,   0,  44,   0,   0,   0,   0, 
	113,   0,  72,   0,   0,   6, 255, 192, 153, 112, 
	 72,  44,  26, 143, 200, 164, 114, 121, 252,  49, 
	159, 208, 168, 148, 248, 171,  58, 167, 210, 171, 
	208, 170, 197, 122, 191,  70, 109,  23, 140, 236, 
	138, 201, 232, 239, 121, 102, 221, 186, 217, 219, 
	171,  83,  46, 110,  15, 207, 235, 180, 190, 124, 
	135, 187, 229, 127, 127, 128, 112, 121, 108, 118, 
	132, 123, 137,  77, 118, 120, 136, 115, 109, 117, 
	 85, 126, 147, 147, 128,  99, 138, 137,  99, 107, 
	146, 146, 148, 133, 159, 125, 136, 152, 163, 151, 
	135, 121, 144,  84, 157,  92, 169, 157, 111, 163, 
	175, 176,  83, 151, 177, 180, 181, 161, 182, 184, 
	185, 186, 187, 188, 189,  67,  54,  56,  58,  56, 
	 53, 190, 197,  88,  55,  57,  60,  63,   2,  43, 
	  2,  56, 198, 208,  74, 192,  58,   0,  63,   5, 
	 12,  11,  35,  35,  12,  47, 209, 222,  67,  53, 
	201, 203,  34,  19,  20, 218, 231,  37,  63,  54, 
	223, 222,  60,   2, 216, 231, 241, 231, 206,  76, 
	193,  55, 236, 176,  63,  39, 242, 252,  35,  40, 
	 58,  75, 114,   8,  40, 240, 227,  25,  62,  76, 
	 60,  24, 244, 147,  55, 161, 202,  11,  24,  57, 
	134,  17, 201, 241,  99, 130, 191, 130,   7,  21, 
	225,  48, 176,  48,  30, 137,   5,  11,  38,  48, 
	 88,  81,   5, 198,  51, 138,  22, 181,  53,  52, 
	152,  49, 141, 141,  31, 230,  58,  46,  60, 129, 
	194,  74, 202, 115,  43,  91, 234,   1, 112,  83, 
	102,  63, 255,  18,  38, 122, 226, 252, 145,  67, 
	 39, 153,  26,  47,  68, 248,  92, 186, 176,  97, 
	 81, 163,  88, 108, 188,  48,  80, 130, 169,  85, 
	134,  68, 161,  74, 177,   1, 160,   0, 137, 171, 
	 96, 135,  62, 213, 186, 132, 171, 215, 176, 104, 
	 71,  52, 188,  71,  54,   9, 210, 179, 105, 195, 
	166,  99, 219, 214, 198,  58,  34,  48,  12, 124, 
	213,  38, 163, 175, 223, 191,  50,  22, 132, 216, 
	139, 182, 132,   0,  30, 196, 250, 218,  37,  70, 
	198, 198, 141, 199, 144,  31, 223, 253, 114, 163, 
	 10,   0,  97, 192, 126, 100,  59,   7,  24, 176, 
	 10,  20, 229, 210, 146,  48, 128,  88,  72, 223, 
	 28,  57,  38, 111, 197,  17, 163, 181, 235, 215, 
	 58, 116,  68, 100,  60,   5, 134, 136,  18,  19, 
	 80,  24, 168, 162,  48,  94,  95,  21,   6,  82, 
	168,  80, 209, 215, 128,   1,  20,  39,   8,  95, 
	 37,  81, 160, 180, 105,  25, 177, 233,  62,   1, 
	246, 186, 186, 245,  24, 209, 177,  84, 140,  71, 
	 97, 130, 114, 109,  33,  76,  48, 152, 176, 192, 
	111, 135,  20, 222, 211,  54, 167,  61, 163, 111, 
	246,  39,  55, 174, 203, 175, 254,  30,  74, 229, 
	152,  62,  73, 132,  24,  60, 162,  47, 131,  14, 
	 12, 132, 224, 155,  95, 130, 145, 208,  89, 129, 
	 40, 116, 211,  25,  12,  58,  72, 135,  68, 124, 
	214, 197,  38, 161,  14, 243,  73, 200, 222,  18, 
	 27, 161, 213, 215,   4, 159,  37, 199, 255,  25, 
	 96,  12, 116, 230, 223,   9,  11, 252,  32, 226, 
	 11,  13,  74,  35, 223, 132,  19, 174,  24,  27, 
	 75,  76, 192, 128,  66,  88, 126, 161, 160,  66, 
	122, 124, 201, 112,   2,   3, 195, 125,  54,  65, 
	 95,  29,   4,  87, 227,   9, 126, 233, 192,   3, 
	 12, 125, 161, 232, 160,  93, 207, 184, 200,  98, 
	139,  17,  74,  24, 197, 118,  96, 249,   7, 160, 
	128,  31, 242,  72,  30,  72,  33, 244, 149,   2, 
	122, 229, 201,   0, 224, 105,  60,  52, 216,  23, 
	131,  14, 226,  96, 194,   1,  78,  74, 152, 195, 
	 13, 196, 208, 192,  90, 148, 177, 217,   7,  83, 
	149,  50, 112, 136, 220,  94,  34,  22, 216, 159, 
	 12, 195, 101, 227,  37, 113,  50, 192,   0,   3, 
	156, 238, 165,  72, 196,  11,  21, 178, 184, 228, 
	117,  19,  66, 145, 225,  85,  53, 222,  72, 152, 
	136,  42, 152,  32, 224, 111,  42,   8,  10,  40, 
	161, 101, 222,  96,  67,  95,  61,  40,  58,   3, 
	 13,  55,  24, 112, 221, 101,  19, 226,  64, 131, 
	 17,  54,  64,  42, 229,  19,  50, 226, 249,  95, 
	128, 127, 238,  23, 166, 113, 194, 105, 250, 103, 
	160, 191,  18,  90, 232,  13,  59,   0, 249, 130, 
	168,  56, 160, 198, 195,  10, 214, 161, 144,   1, 
	131, 245,  21,   1,  33, 125, 177, 141, 181,   4, 
	149,  76, 137, 232,  23,   3,  38, 132,   9, 216, 
	  9,  93, 126, 234, 105, 160,  34,  94, 208, 129, 
	 14,   7, 152, 112, 255,   2,   4,  40,  84,  80, 
	157,   8,  30, 176, 154, 195, 133,  68, 200, 250, 
	 34, 124, 119, 102, 171, 109, 113, 157, 142,  16, 
	238, 111, 160, 113,  58, 110, 167,  38, 252, 213, 
	192, 193,  12,  72,  32, 193,   3,  15, 128, 192, 
	128,   7, 175, 121,  32,  66,   7, 101, 230, 240, 
	 42,  18,  53, 216, 171, 131, 106,  73, 224,  32, 
	  0,  88, 221, 217, 216, 227, 200, 190, 234,  39, 
	210, 112,  12,  36,  23, 158, 175, 254, 154, 160, 
	105,   9,   5, 236,  88, 129,   7,  41,  83, 240, 
	 65, 195,  32,  56, 236, 128, 107,  14,  36, 208, 
	 64,  10,  24,  41, 161, 177, 181,  74,  84, 182, 
	194,   4,  85,  45, 181, 239, 134,  11, 236, 165, 
	 31, 151,  95, 233, 199, 223,   8,  82,  27,  40, 
	  3,   9,  39, 144,  56,  24,   4,  92, 119,  61, 
	129,   3,  96, 135, 221, 128,   8,  12,   0,  64, 
	239,  47,  26,  59,  88,  52,  53, 227, 132, 182, 
	208, 210, 128, 178,  76, 163,  12,  46, 135, 208, 
	245, 221,  92,   3,  21,  54, 216,   9, 152, 208, 
	 48,  64,  72,  12, 237, 197,  52,   0, 152, 208, 
	209, 111, 193, 141, 204, 239, 102, 104,  45,  96, 
	128,   9,  20, 224,  45, 249, 215,  97,  51, 240, 
	  1,   8,  10, 152,  80,  20,  14,  56, 208, 213, 
	 38, 199, 181, 245, 214, 207, 111,  96, 130,   4, 
	146,  72, 114, 135,  69, 194,  10,  38,  64,   0, 
	130, 228, 120,  71, 240, 181,   8, 145,  67, 240, 
	255, 128,   2,  44, 164,   0,  26,   2,  66, 180, 
	  9, 163,  23,  56,  20, 112, 184, 184, 242, 232, 
	119, 224, 212, 127,  18,  56, 152,  95,  14, 252, 
	  8,  88, 129, 120, 255,  37, 216, 205,  17,  68, 
	160, 192,   3,  24, 212,  64, 131, 198,  58,  92, 
	 12,  70, 101, 223, 125,   8, 172,  60, 218, 166, 
	252, 149, 136,  41, 251,  21,  64, 249, 201, 117, 
	221,  89, 202, 151, 131, 112, 251,   9, 211, 194, 
	 54, 161, 218,  88, 212, 128, 237, 128, 207,  35, 
	 15, 164, 144, 125,  65,  78, 141, 206,   3, 164, 
	  0, 245,  69,   0,  34, 248,  95,  10, 134,  68, 
	  2,   8, 244, 101,  71,  97,   3,  77, 237,  70, 
	240,   0,  18, 248, 110,  15,  58,  80,  10,  63, 
	 48,  37,  55,  47, 129, 169, 128,  86,  10, 152, 
	 12, 132,  19, 166,   2,  36, 112, 132,  31,  20, 
	 83, 128,  28,  40,   3,   6,  52, 207, 116,  91, 
	227, 218,   3, 218,  68,  52,  50, 224,  32,  95, 
	228, 147,   1, 175, 134, 211,  65, 226,  13, 138, 
	116, 222, 249,  77,   1,  10,  38,   3,   7,  52, 
	160,  47,  96,  91,   0,  11,  83, 224, 128,  62, 
	197, 176, 107,  32, 224, 222, 217, 192, 240, 130, 
	 25, 109,  16, 133,  91, 242, 159,  15,  63,  37, 
	176,  63,  25,  64,   0,  68, 108, 128,   7, 144, 
	232,   0,  37, 146,  81,  68,  14, 208,  20,  20, 
	163,  72, 167, 216, 128,  14,  85, 201,  66, 205, 
	155, 110, 224,  61,  37, 220, 255,  16,  63, 226, 
	235, 215, 135, 194,   5,  44,  78, 249,   5,  61, 
	 86, 251,  65,   5,  36, 208,  23,  15,  52, 177, 
	136, 101, 100,  97,  18, 195, 197, 171,  52, 218, 
	205, 117,  51, 108, 163, 169, 132,  16, 171,  54, 
	118, 174, 142,  69,  48,  75, 248, 224,  22, 162, 
	 45, 146, 171,  51,   8, 160, 221,  25,  17, 105, 
	 70,  82,  90, 237,  91, 131, 137, 164,  37, 137, 
	 80,  73, 238, 221,  11,  86,  93,   9,  95, 242, 
	180, 101, 128,  46,  10, 236, 148, 126, 177,   6, 
	  5,  70, 153,  68,  69,  38,  18,   2, 255,  42, 
	 34, 104,  34, 160,  74, 106,   9,  99,   8, 245, 
	 51, 230, 147, 126,  55, 131,  26, 196, 178,  35, 
	225,  25, 153,  52, 131,  82,  55, 240,  84,  19, 
	107,  60, 234,  11,   0,  12,  16,   1,  16, 148, 
	160, 110,  43, 123, 100,  56, 243,  22,   2, 145, 
	128,  45, 101,  16, 152,  15, 118,  44,  54, 131, 
	100, 218, 239,  73, 111,  58,  66,  13, 120,   0, 
	151, 133,  60, 205, 116, 248,  20,  12,   5, 246, 
	227,  52, 126, 106, 195, 120,  50,  56, 146,   1, 
	 46, 247,   1, 126,  86, 141, 156,  79, 132, 192, 
	 61,  67, 240,   1, 117, 182,   6,  85, 141,  90, 
	 38, 232, 134, 176,  17,  89, 198, 165,  35, 134, 
	 17,  70,  14,  92,  32,  63, 134, 141, 224, 117, 
	176,  11, 105, 215,  44, 232, 208, 136, 178,  72, 
	 34, 118, 212, 203,  69, 173, 226, 148,  26, 216, 
	133,   7, 255,  39,  80, 192,   4, 102,  42, 191, 
	 17, 136,  52, 164,  37, 109, 211, 253,  48, 137, 
	 49, 122,  90, 116, 165, 255, 100,  64,  86,  40, 
	 74, 128,  22,   0, 224,   6,  48, 152, 128,   2, 
	 64, 122, 211, 187, 229,  84, 153, 142, 226, 169, 
	 18, 230,  41, 128, 164,   1, 149,  31,  37,  98, 
	166,  93, 134, 192, 129, 133,  49, 181, 169,  36, 
	125, 234, 147,  36,  68,  71,  47,  80, 213, 170, 
	252,  32,  79,  92, 232, 177,   4,  14,  80,  32, 
	103,  77, 229, 218,  83, 177,  51, 214,   6,  73, 
	 53,  10, 103, 237,  71,  67, 126,  96,   0, 164, 
	133,  69,   4, 128, 147, 134,  15,  72, 240,  85, 
	174, 229, 236, 176, 175, 203, 105,  93, 223, 116, 
	215,  41, 228,  53,  30,  43, 177,  65,  14,  94, 
	 80, 133,  21, 160,  64,  93,  75, 153,   0,   0, 
	158, 224, 130,  19,  60, 224, 110,  57,  99, 216, 
	237,  74,   0, 130,   8, 120, 192,   3,  99, 243, 
	192,  97, 234,  58, 161, 120,  42, 226, 177, 106, 
	  9,  26,  37,  57, 167, 131,  23,   8, 207,  39, 
	 20, 248,   1, 254, 136,  80,   3,  20,  44,  21, 
	180,  32,  32,  79,   4,  80,  16, 128,  11,  64, 
	 64,   4,  34,  80,  65,   7,  94,  80,  38, 214, 
	202, 102, 183, 105, 168,   1,  12, 170,  26, 219, 
	 26,  34,  19, 135,  29,  41, 128, 117, 137, 128, 
	  3,   9, 252, 214, 176,  15,  24,  64,  15,  56, 
	247,  12,  24, 168,  75,   4,   6,   0, 135, 192, 
	 14, 156, 139,  82,  90,   8, 164,  38, 219,  29, 
	  2,  79, 150, 194,   0,  24,  44,  97,   7,  22, 
	184,  29, 195,  58, 106, 223,  58, 230, 160, 156, 
	 68,  89, 108,  89, 115, 145,   3, 147,  48,  33, 
	131,  50,  89,   0,   3,   4,  16,  95,  33, 220, 
	224,   5,  26,  64, 193,  91, 111, 167,  57,  35, 
	132,  35,  53, 148, 116,  12, 100, 166, 248,  13, 
	143, 241, 163,  59,  34,  16, 192,  15, 120, 208, 
	222,  36, 208, 192,  49,  63, 216, 192,   9,  36, 
	192, 128, 137, 114, 152,  44,  47, 217, 140, 130, 
	  9, 114,  25,  28,  76, 148,   9, 162,   2, 128, 
	141, 219,  50,   5, 122, 134, 120, 196, 174, 141, 
	 46, 143, 167,  96, 131,  23, 221, 120, 200,  72, 
	214,  74,  16,   0,   0,  59  }; 

static const unsigned char php_logo[] = {
	 71,  73,  70,  56,  57,  97, 120,   0,  67,   0, 
	230, 106,   0, 127, 130, 184,  57,  55,  71,  40, 
	 37,  42, 204, 205, 226, 161, 164, 203, 211, 213, 
	231, 178, 180, 212,  67,  66,  88, 131, 134, 185, 
	130, 131, 179,  82,  82, 114, 144, 146, 194, 194, 
	196, 222, 170, 172, 208,  76,  75,  99,  91,  92, 
	131, 221, 222, 236,  59,  56,  60, 110, 113, 165, 
	106, 109, 157,  97,  99, 141, 117, 121, 177, 123, 
	126, 181, 229, 230, 240, 153, 156, 198, 140, 141, 
	193, 185, 186, 217, 107, 107, 146,  78,  78, 107, 
	113, 116, 169, 122, 122, 163, 136, 139, 189, 114, 
	116, 163, 116, 115, 152, 142, 144, 193,  90,  91, 
	126, 226, 227, 239, 123, 125, 173, 164, 165, 208, 
	109, 112, 162, 114, 118, 172, 149, 150, 200, 187, 
	189, 217, 116, 120, 174, 133, 136, 187, 146, 149, 
	195, 216, 217, 234, 146, 146, 196, 100, 102, 146, 
	107, 110, 159, 165, 168, 206, 148, 150, 197,  46, 
	 43,  47,  83,  81, 104, 179, 180, 215, 108, 106, 
	140,  92,  91, 118, 138, 141, 191, 102, 104, 150, 
	104, 106, 154, 156, 159, 200,  49,  46,  57, 174, 
	176, 211, 156, 156, 205,  85,  86, 120, 158, 161, 
	202, 150, 153, 197, 129, 130, 175, 103, 105, 151, 
	 63,  61,  80, 188, 190, 218,  94,  96, 137, 152, 
	153, 200, 140, 142, 191, 137, 138, 186,  87,  88, 
	124, 182, 183, 215, 213, 215, 232,  34,  30,  32, 
	108, 111, 158, 206, 208, 228, 191, 192, 220, 119, 
	123, 180, 118, 120, 167,  95,  94, 125, 153, 153, 
	204, 110, 111, 152, 115, 119, 174,  34,  30,  31, 
	255, 255, 255, 144, 142, 143,  89,  86,  87, 199, 
	198, 199, 238, 238, 245, 213, 212, 213, 246, 246, 
	250, 130, 128, 129, 172, 170, 171, 116, 114, 115, 
	241, 240, 241, 158, 156, 157, 227, 226, 227,  75, 
	 72,  73, 185, 184, 185, 103, 100, 101, 137, 137, 
	182,   0, 255,   0,  71,  70,  95, 223, 224, 237, 
	155, 156, 204, 105, 107, 156, 111, 115, 167, 140, 
	140, 186, 184, 185, 217, 184, 186, 215, 154, 155, 
	204, 167, 170, 207, 219, 220, 235, 154, 156, 201, 
	102, 100, 132, 104, 103, 137, 167, 168, 210, 110, 
	112, 160, 139, 139, 185, 198, 199, 224, 199, 201, 
	225, 105, 108, 156, 151, 152, 203,  33, 249,   4, 
	  1,   0,   0, 106,   0,  44,   0,   0,   0,   0, 
	120,   0,  67,   0,   0,   7, 255, 128, 106, 130, 
	131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 
	141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 
	151, 150, 109,  63, 109, 115, 152, 158, 159, 160, 
	 63, 121, 121,  54,  62,  26, 113,  76,  26,  26, 
	 76,   6,  62,  62,  13,  50,   4,  65,  60,  24, 
	 66,  45,  11,  73,  34,  57,  31,  25,  57,  34, 
	 47,  41, 160, 194, 161,  13,  26,  12, 125,  77, 
	  5,  80,  80,   3, 125, 124,  12,  81,  81,  42, 
	114, 172, 175, 116, 177, 179,  66,  51,  45, 186, 
	 31,   8,   0,  22,  22,  21,  87,  40,  37,  22, 
	  9,  25, 193, 195, 235, 140,  38, 113, 124,  46, 
	108, 108,  16,  16, 117,  46, 201,   3, 212,  50, 
	179,  34,  31, 254,  44,   0,  17,   8,   4,  64, 
	176, 224,  55, 130, 225, 164, 172,  64, 241,  70, 
	194,   9,  63,  59, 158,  76,  25, 146, 132, 157, 
	 69,  53,  65, 108,  12,  96,  67, 226, 130,  71, 
	 18,  36, 242,  53,  16, 178,  64, 138, 201, 147, 
	 40,  83, 170,  92, 121, 114,  92,   7,   9,  19, 
	118, 232, 128,  65, 225,   8,   5,  43,  67,  68, 
	 92, 196,  20, 132,   9,  20, 142,  30,  47, 184, 
	 48,  66, 167,   5, 203, 163,  72, 147, 162, 188, 
	242,  38,   6, 140,  35,  71,  30, 140,  88, 114, 
	196, 131, 206, 157, 144, 126, 104, 116,   1, 129, 
	 35,   4,  35,   4,  88,  40,  29,  75,  54, 233, 
	149,  19,  58,  30,  44,   1, 162,  64, 193, 136, 
	 41,  51, 255, 176,  46,  50, 161, 161,  64,  19, 
	 23, 117,  10,  24,  72,  82, 182, 175,  95, 164, 
	 29,  96,  44,  81, 192, 129, 131,   3,  60,   9, 
	228,  26, 202,  19, 101,   0, 148,   2,   3, 124, 
	228, 248, 187, 114,   1, 134, 203, 152,  49, 124, 
	160, 156, 244,  13,   5,   5,  14, 214, 172,  81, 
	224,  65, 177, 154,  60,  70, 248, 244,  25, 192, 
	100,   6, 231, 149,  31, 178, 112, 153,  77, 155, 
	 75, 151, 215,  74, 221,  44,  89, 115, 224, 128, 
	131,  16,  59, 221,  69,  97, 192, 160,   1,   2, 
	220,  43,  49, 112, 193, 194, 188, 185, 153, 219, 
	200, 147, 118, 216,  93, 164, 200, 154, 210, 195, 
	126, 248, 144,  99,  68,   5,  15,  11, 209,  87, 
	170,  32, 211, 188, 185, 152,   2, 225, 149,  94, 
	121, 112,  32,  64,   0,  14, 112,  64, 153,  48, 
	192,  68,  14,   1,   0, 233,  87,  22,  16,  83, 
	158,  57,  25,  21, 249,  41, 245, 134,   2, 238, 
	245, 112,   7,  38, 115, 208, 225, 131,   1,  50, 
	 28,  23, 160,  74,  93, 152, 209,  31,  22,  92, 
	 16, 240, 160,  82,  49, 172, 209,  67,  15,   7, 
	236,  81, 201,  15,  50,  52, 208,  64,  73,  23, 
	166,   4,  64,  22,  19,  98, 145, 197, 102,  37, 
	 38, 245,  64,   0,  27,   2,  39,  73,  27,   4, 
	236, 227,  96, 139,  39,  41,  55, 161,  25,  95, 
	224, 168, 148,  31,  69, 208,  64,   3,  21, 145, 
	216,  17,   4,   1,  51, 128, 135, 212, 255,   7, 
	153,  53, 217,  36, 139,  71, 169,  16, 198, 132, 
	 98,  92, 208,  36, 137,  44,  49, 233, 228, 150, 
	248, 141, 133, 130,   3,  52,   8,  80, 195,  35, 
	 72,  96,  16,   4, 148,  71, 125, 240,  69,  22, 
	108, 182, 233, 230, 155,  89, 116,  81,  64,   3, 
	 93, 162,  84,   0,  24,  19, 146,   1, 103, 155, 
	 23,  12,  96, 225,  73,  11, 236,  41,  40, 155, 
	 93,  12, 208, 128,  82,  64,   8,  32, 128,   3, 
	141, 204,  32,   4,   6,  98,  41,  69, 192, 114, 
	 41,  86, 106,   6,  24,  92, 124,   1,  32,  74, 
	 93, 108,  81, 105, 138,  52, 108, 161,  69,  25, 
	 93, 144, 104, 192, 148, 159,  78, 184,   5,  24, 
	 94, 116, 113,  40,  82,  35,   8, 224,   4, 163, 
	138, 108,  35, 196, 141,  73, 141, 151, 234, 167, 
	 91, 120,   1,  65, 151,  39, 238, 250,  41,  24, 
	 99,  96,  32, 197,   0, 120,  10, 171, 106,  25, 
	  3,  36,  53, 130,  19,  78, 224, 144,  72,  10, 
	 34, 180, 128, 102,  82,  16, 240, 167, 108, 138, 
	 97,  64,  96,  18,   6,  94, 108, 155,  34,  26, 
	183,  93, 224, 169, 184, 229, 209, 224,  69, 179, 
	 72, 173,   1,  45, 118, 133, 252, 225, 203, 100, 
	101, 125,  33,  33, 186, 253, 121,   1, 160, 148, 
	248, 230, 219,   0, 138, 253,  54,  71,  67,  25, 
	127,  30,  21, 128,  19,   2,  44,  96,  72,  63, 
	244, 146,  21,  91, 192, 229, 109, 209, 227, 157, 
	 16,  51, 167, 197, 255,   5, 225,  86, 140, 133, 
	 24, 208,  29, 213, 129, 172,  99,  18, 146,   2, 
	  2,  31, 212,  57, 214, 164,  59, 194,  57, 198, 
	 25, 218,  78, 232,   5,   1, 157,  78, 200, 197, 
	155,  99, 112, 129,  70, 138,  90, 100, 129, 106, 
	196, 112, 150, 113, 198, 185,  19, 150, 129,  37, 
	 75,  10,  64, 155,   6,  33, 222, 224,  58, 150, 
	174, 253, 137, 225,  45,  74,  11,  52, 208,   5, 
	121,  19, 106, 193,   0, 192, 253, 173, 136,  18, 
	  6,  13, 124,  17,  65, 213,  89, 104,  81,  53, 
	187, 128,  26, 240,  69, 178, 253, 133,  97, 128, 
	 82,  52, 204,  58, 200,  31,   0,  32, 160, 100, 
	 89, 217, 230, 185, 169, 137,  89, 124, 221, 116, 
	 22,  25, 151, 199, 227,  74,  16,   0, 221,  92, 
	206, 130,  51, 119, 198, 218,  42, 125,  48,   6, 
	206, 119,  31, 181,   4, 180,  10, 171,  33, 130, 
	  5,  38, 147, 101, 175, 204,   5, 167,  20, 184, 
	170,  58,  83, 249, 116,  74,  49, 247, 119,  70, 
	 22,  52,   4, 109, 236,  74, 161, 151, 167,  69, 
	227,  44, 117,   0, 237,  13, 130, 176, 144,  80, 
	 95,  15,  79,  56, 198, 181,  39, 109, 222,  31, 
	 26,  89, 160, 221, 220, 127,  42,   5,  27, 116, 
	 25,  19, 210, 144, 197,  81, 169,  15, 206,  58, 
	 75,  69, 184, 173,  70,  56, 115, 147, 133, 114, 
	127,  17, 244, 200, 210, 229, 253,  17, 142, 185, 
	 74, 224,  22, 159, 197,  25, 170,  94, 112,  20, 
	255, 214, 229,   1, 175,  20,   7,  78, 244,  32, 
	 72,   5, 148,  49,  93,  30,  26, 159, 167,  84, 
	123, 218, 228,  55, 119, 187,  74, 252, 246, 183, 
	 69, 216,  99, 179, 132,   1, 241, 219,  83,  10, 
	  5, 160,  37, 136,  21,  80, 166, 110, 217,  91, 
	158,  73,  12,   0, 190, 160, 245, 173,  57, 213, 
	211, 143, 239, 152,   3, 134,  44,  20,  14,  11, 
	135,  99,   9,   3, 168, 214, 159, 251,   9, 144, 
	128,  41, 184,   2, 251, 252, 130, 189, 242,  84, 
	136,  37, 201,  99,  78,   4,  58, 183, 187, 248, 
	157,  36, 133,  88,   8,   3, 233,  76, 183,  18, 
	  0, 120, 109,  66, 228,  34, 203,   0, 157,  32, 
	  8,  20,  24, 176,  47, 194, 235,  32, 238, 142, 
	 69, 169, 236, 245, 174, 106, 203,  11,  98, 121, 
	188,   0, 192, 116,  29,  79,  63,  28,  44,  79, 
	 24,  20, 184, 146,  29,  10, 162,   3,  40,  24, 
	 33,  89, 116,  68, 189,  39, 162, 228,   3,   5, 
	240,  66, 233, 250,  67, 131,  49, 124, 225, 130, 
	 39,  76,  73, 247,  38, 244, 189, 240, 113,  15, 
	  2,  98, 156,  80, 245,  42, 119,  20,  43, 170, 
	 97,  33,  90,  92,  90,  20, 153,  67,  46,  21, 
	248,  81,   5,  16, 232, 194,  24, 180,  48,  70, 
	209,  13, 160, 126, 204, 241,  32,  74, 242, 199, 
	 51, 177, 101, 175,  11, 127,   4, 100,  23, 202, 
	224,  72, 153,  81, 113,  37, 232,  83, 223, 243, 
	 58, 112, 133, 190, 236,  71, 255,  85,  90,   8, 
	101,  40, 197, 112, 175,  20, 137, 225,  11,   4, 
	120, 160,  10, 189, 104, 167,   9,  98, 161, 130, 
	 23,  20, 149,  40, 181,  64, 202,  97, 137, 175, 
	 44, 205, 163, 213,   7, 222, 208, 129, 190,  68, 
	 72,  99, 104, 248, 194,   2,  78, 133,  67,  23, 
	154, 196,  92,  19, 146,  97,  33,   3, 118, 202, 
	161,  73, 231, 117, 130,  72, 129,   4, 222, 240, 
	 67, 165,  40, 177,  95, 205,  60, 150,  43, 173, 
	182,  18,  68,  98, 129, 137,  26,   3, 131,  48, 
	251, 242,  56,  39,  68, 238, 121,  18, 232, 229, 
	 88, 214, 216,  47,  26, 156,  97, 156,  82,  64, 
	102, 127, 184, 240, 170, 173, 169, 146,  57, 109, 
	 12,  88,   4, 206, 112,   1, 103, 178, 205, 121, 
	130, 120, 193,   9,  36, 208,  73, 165,  48,  82, 
	 92, 102,  32, 195,  24,   6,  80, 167,  25, 118, 
	208, 159, 196, 212,  31, 255, 240, 101,   6,  25, 
	 50, 128, 142,  73,  41, 154,  19, 142,  70, 136, 
	 33, 156, 224,  13,  99, 161, 152, 254, 102,  57, 
	 75,  50, 112,  97,  12, 133,  66,  83, 160,  72, 
	 26,  74,  86, 158,  68,   5,  92,  96, 233, 232, 
	 46,  40,   6, 150, 134, 210, 164,  40, 101, 192, 
	 16, 165,   3,  50,  67, 164, 224,   4,  39,  80, 
	 39,  82,  96, 200, 133,  11, 208, 131,  30,   5, 
	248,  35,   1, 252, 105,  18,  64,  30, 245, 168, 
	153,   3, 212,   0, 158,  74, 143,  67,  46, 147, 
	 57,  94, 255,  48, 234,  81, 147, 234,  71,   2, 
	236, 116,  44,   7,  75, 216,  33, 146,  16, 131, 
	 19, 160,   0,  41, 215,  76,  36,  83, 125,  36, 
	133,   5,  52, 177,  60,  89, 192,  40, 114, 220, 
	229,   4, 120,  25,  34,   1, 101,  45, 104, 114, 
	238, 185,  66, 182, 178, 164,   1,  13, 140,  88, 
	199, 242,  83,  78, 105,  41, 162,   4, 121, 101, 
	201,  65, 249, 104,  76, 191,  74, 129,   1, 149, 
	108,  14,  24, 208,  19, 160, 114, 210, 106,  17, 
	136,  53, 171,   4, 171, 198,   0, 199, 170,  68, 
	119,  82, 188,  36, 101,  52, 122,  89,  70, 148, 
	 96,   2,  49, 232,  64,  30, 165,  64, 212, 122, 
	122, 214,  36, 121, 115, 217, 233, 162, 211, 129, 
	  3,  64, 171, 180, 141,  72,   0, 106,  37, 160, 
	197, 180,  98,  97,  12, 107, 245, 209,   2,  22, 
	199,  70, 185, 250, 133,   8,  61, 128, 150,  97, 
	 35, 161, 132,  39,  76,  64, 179,  82, 248, 223, 
	 22, 166,  75,  93, 222, 189, 214, 158, 212, 165, 
	 46,  24,   6, 251,  26,   5, 200,  74,   0,  50, 
	154, 196,  11,  64, 224, 135,  24, 240,  22,   0, 
	  5, 160,  42,  61,  16, 119,  93,  41, 160,  87, 
	189,  16, 112,  45, 101, 136, 112,  48,  39,  68, 
	128, 163, 150,  72, 128,  27,  80, 251, 134, 213, 
	182, 215, 175,  39, 176, 173, 114,  65, 241, 130, 
	 41, 248,   1, 181, 170, 253, 175,  95,  81, 192, 
	  1,  89,  57, 161,   8, 248,   5, 133, 255,  18, 
	244, 224, 134,   3, 247,  87, 193,  37,  58, 193, 
	 26,  28, 220, 131, 240, 178, 131,   5,  20,  62, 
	176,   4, 206, 138, 225, 240,  28, 225,   0, 138, 
	 18,  64,  15,  96, 167,  24,  22, 128,  96,   7, 
	110, 112,  67,  12, 168,  89,  98, 202, 248, 129, 
	  3,   1,   8, 147,   0,   2, 192,  98, 211,   8, 
	 34,   9,  37,  32, 194,  14,  96,  60,   1,  26, 
	215,  56,  41,  19,  32,  80,  15, 132,  36,  38, 
	187, 250, 120,  16,  41,  72, 128,  30, 116,  64, 
	  4,  33, 187,  33, 168, 254, 197, 240,  27, 142, 
	128, 227,  13,  45, 185,   8, 120, 120, 193, 147, 
	 23, 241,   2,  41, 235, 224, 204, 103, 222, 193, 
	 71,  73, 124, 221,  29,  28,  65,   1, 237, 129, 
	209, 134,  14, 112,   3,  15, 141, 249,  17,  47, 
	 64, 192,  20, 136,   0, 131,  62, 251, 153,   8, 
	126, 248, 168,  80, 243,  51,   1,  34,  60,   0, 
	 52, 213, 113, 143, 162, 113,  16,   2,  59, 223, 
	153,  18,  34,  24, 194, 158,  41,  64, 233,  74, 
	 83, 250,   8, 125, 174, 112, 160, 223, 192, 105, 
	 78,  75, 224, 211, 159,   6,  42,  80, 137, 112, 
	105, 182, 136, 166,  55,   7, 168,  78,  17,   2, 
	112,   0,  28, 108,  32,  49, 143,  22,  70,  10, 
	 62,  80,   2,  16,  88,   1,  42,  80, 121, 128, 
	174, 119,  61, 149,  37, 172,   5,   8, 108, 105, 
	 11,  97,  10,  99, 152, 208, 156, 186,  55,  69, 
	 80,   0,  21, 110,  56,  48,   4,  49, 199,  90, 
	 49,  41,  80,   2,   2,  60, 224, 129,  13, 108, 
	 32,  45, 190,   6, 118, 176, 219,  66, 108, 195, 
	112, 128,  10,  35,  24, 129,  21, 172,  80, 130, 
	102,  63, 251, 220, 139,  16,  65,  26,  16, 112, 
	 21, 116, 187, 251, 221, 240, 142, 119, 188,   3, 
	  1,   0,  59,   0 };
php/regex/regex2.h000064400000012640151731376150010026 0ustar00/*
 * First, the stuff that ends up in the outside-world include file
 = #ifdef WIN32
 = #define API_EXPORT(type)    __declspec(dllexport) type __stdcall
 = #else
 = #define API_EXPORT(type)    type
 = #endif
 =
 = typedef off_t regoff_t;
 = typedef struct {
 = 	int re_magic;
 = 	size_t re_nsub;		// number of parenthesized subexpressions
 = 	const unsigned char *re_endp;	// end pointer for REG_PEND
 = 	struct re_guts *re_g;	// none of your business :-)
 = } regex_t;
 = typedef struct {
 = 	regoff_t rm_so;		// start of match
 = 	regoff_t rm_eo;		// end of match
 = } regmatch_t;
 */
/*
 * internals of regex_t
 */
#define	MAGIC1	((('r'^0200)<<8) | 'e')

/*
 * The internal representation is a *strip*, a sequence of
 * operators ending with an endmarker.  (Some terminology etc. is a
 * historical relic of earlier versions which used multiple strips.)
 * Certain oddities in the representation are there to permit running
 * the machinery backwards; in particular, any deviation from sequential
 * flow must be marked at both its source and its destination.  Some
 * fine points:
 *
 * - OPLUS_ and O_PLUS are *inside* the loop they create.
 * - OQUEST_ and O_QUEST are *outside* the bypass they create.
 * - OCH_ and O_CH are *outside* the multi-way branch they create, while
 *   OOR1 and OOR2 are respectively the end and the beginning of one of
 *   the branches.  Note that there is an implicit OOR2 following OCH_
 *   and an implicit OOR1 preceding O_CH.
 *
 * In state representations, an operator's bit is on to signify a state
 * immediately *preceding* "execution" of that operator.
 */
typedef long sop;		/* strip operator */
typedef long sopno;
#define	OPRMASK	0x7c000000
#define	OPDMASK	0x03ffffff
#define	OPSHIFT	(26)
#define	OP(n)	((n)&OPRMASK)
#define	OPND(n)	((n)&OPDMASK)
#define	SOP(op, opnd)	((op)|(opnd))
/* operators			   meaning	operand			*/
/*						(back, fwd are offsets)	*/
#define	OEND	(1<<OPSHIFT)	/* endmarker	-			*/
#define	OCHAR	(2<<OPSHIFT)	/* character	unsigned char		*/
#define	OBOL	(3<<OPSHIFT)	/* left anchor	-			*/
#define	OEOL	(4<<OPSHIFT)	/* right anchor	-			*/
#define	OANY	(5<<OPSHIFT)	/* .		-			*/
#define	OANYOF	(6<<OPSHIFT)	/* [...]	set number		*/
#define	OBACK_	(7<<OPSHIFT)	/* begin \d	paren number		*/
#define	O_BACK	(8<<OPSHIFT)	/* end \d	paren number		*/
#define	OPLUS_	(9<<OPSHIFT)	/* + prefix	fwd to suffix		*/
#define	O_PLUS	(10<<OPSHIFT)	/* + suffix	back to prefix		*/
#define	OQUEST_	(11<<OPSHIFT)	/* ? prefix	fwd to suffix		*/
#define	O_QUEST	(12<<OPSHIFT)	/* ? suffix	back to prefix		*/
#define	OLPAREN	(13<<OPSHIFT)	/* (		fwd to )		*/
#define	ORPAREN	(14<<OPSHIFT)	/* )		back to (		*/
#define	OCH_	(15<<OPSHIFT)	/* begin choice	fwd to OOR2		*/
#define	OOR1	(16<<OPSHIFT)	/* | pt. 1	back to OOR1 or OCH_	*/
#define	OOR2	(17<<OPSHIFT)	/* | pt. 2	fwd to OOR2 or O_CH	*/
#define	O_CH	(18<<OPSHIFT)	/* end choice	back to OOR1		*/
#define	OBOW	(19<<OPSHIFT)	/* begin word	-			*/
#define	OEOW	(20<<OPSHIFT)	/* end word	-			*/

/*
 * Structure for [] character-set representation.  Character sets are
 * done as bit vectors, grouped 8 to a byte vector for compactness.
 * The individual set therefore has both a pointer to the byte vector
 * and a mask to pick out the relevant bit of each byte.  A hash code
 * simplifies testing whether two sets could be identical.
 *
 * This will get trickier for multicharacter collating elements.  As
 * preliminary hooks for dealing with such things, we also carry along
 * a string of multi-character elements, and decide the size of the
 * vectors at run time.
 */
typedef struct {
	uch *ptr;		/* -> uch [csetsize] */
	uch mask;		/* bit within array */
	uch hash;		/* hash code */
	size_t smultis;
	unsigned char *multis;		/* -> char[smulti]  ab\0cd\0ef\0\0 */
} cset;
/* note that CHadd and CHsub are unsafe, and CHIN doesn't yield 0/1 */
#define	CHadd(cs, c)	((cs)->ptr[(uch)(c)] |= (cs)->mask, (cs)->hash += (c))
#define	CHsub(cs, c)	((cs)->ptr[(uch)(c)] &= ~(cs)->mask, (cs)->hash -= (c))
#define	CHIN(cs, c)	((cs)->ptr[(uch)(c)] & (cs)->mask)
#define	MCadd(p, cs, cp)	mcadd(p, cs, cp)	/* regcomp() internal fns */
#define	MCsub(p, cs, cp)	mcsub(p, cs, cp)
#define	MCin(p, cs, cp)	mcin(p, cs, cp)

/* stuff for character categories */
typedef unsigned char cat_t;

/*
 * main compiled-expression structure
 */
struct re_guts {
	int magic;
#		define	MAGIC2	((('R'^0200)<<8)|'E')
	sop *strip;		/* malloced area for strip */
	int csetsize;		/* number of bits in a cset vector */
	int ncsets;		/* number of csets in use */
	cset *sets;		/* -> cset [ncsets] */
	uch *setbits;		/* -> uch[csetsize][ncsets/CHAR_BIT] */
	int cflags;		/* copy of regcomp() cflags argument */
	sopno nstates;		/* = number of sops */
	sopno firststate;	/* the initial OEND (normally 0) */
	sopno laststate;	/* the final OEND */
	int iflags;		/* internal flags */
#		define	USEBOL	01	/* used ^ */
#		define	USEEOL	02	/* used $ */
#		define	BAD	04	/* something wrong */
	int nbol;		/* number of ^ used */
	int neol;		/* number of $ used */
	int ncategories;	/* how many character categories */
	cat_t *categories;	/* ->catspace[-UCHAR_MIN] */
	unsigned char *must;		/* match must contain this string */
	int mlen;		/* length of must */
	size_t nsub;		/* copy of re_nsub */
	int backrefs;		/* does it use back references? */
	sopno nplus;		/* how deep does it nest +s? */
	/* catspace must be last */
	cat_t catspace[1];	/* actually [NC] */
};

/* misc utilities */
#define	OUT	(UCHAR_MAX+1)	/* a non-character value */
#define	ISWORD(c)	(isalnum(c) || (c) == '_')
php/regex/utils.h000064400000001017151731376150007766 0ustar00/* utility definitions */

#include "regex_extra.h"

#ifdef _POSIX2_RE_DUP_MAX
#define	DUPMAX	_POSIX2_RE_DUP_MAX
#else
#define	DUPMAX	255
#endif
#define	INFINITY	(DUPMAX + 1)
#define	NC		(CHAR_MAX - CHAR_MIN + 1)
typedef unsigned char uch;

/* switch off assertions (if not already off) if no REDEBUG */
#ifndef REDEBUG
#ifndef NDEBUG
#define	NDEBUG	/* no assertions please */
#endif
#endif
#include <assert.h>

/* for old systems with bcopy() but no memmove() */
#ifdef USEBCOPY
#define	memmove(d, s, c)	bcopy(s, d, c)
#endif
php/regex/cname.h000064400000004012151731376160007710 0ustar00/* character-name table */
static struct cname {
	char *name;
	char code;
} cnames[] = {
	{"NUL",	'\0'},
	{"SOH",	'\001'},
	{"STX",	'\002'},
	{"ETX",	'\003'},
	{"EOT",	'\004'},
	{"ENQ",	'\005'},
	{"ACK",	'\006'},
	{"BEL",	'\007'},
	{"alert",	'\007'},
	{"BS",		'\010'},
	{"backspace",	'\b'},
	{"HT",		'\011'},
	{"tab",		'\t'},
	{"LF",		'\012'},
	{"newline",	'\n'},
	{"VT",		'\013'},
	{"vertical-tab",	'\v'},
	{"FF",		'\014'},
	{"form-feed",	'\f'},
	{"CR",		'\015'},
	{"carriage-return",	'\r'},
	{"SO",	'\016'},
	{"SI",	'\017'},
	{"DLE",	'\020'},
	{"DC1",	'\021'},
	{"DC2",	'\022'},
	{"DC3",	'\023'},
	{"DC4",	'\024'},
	{"NAK",	'\025'},
	{"SYN",	'\026'},
	{"ETB",	'\027'},
	{"CAN",	'\030'},
	{"EM",	'\031'},
	{"SUB",	'\032'},
	{"ESC",	'\033'},
	{"IS4",	'\034'},
	{"FS",	'\034'},
	{"IS3",	'\035'},
	{"GS",	'\035'},
	{"IS2",	'\036'},
	{"RS",	'\036'},
	{"IS1",	'\037'},
	{"US",	'\037'},
	{"space",		' '},
	{"exclamation-mark",	'!'},
	{"quotation-mark",	'"'},
	{"number-sign",		'#'},
	{"dollar-sign",		'$'},
	{"percent-sign",		'%'},
	{"ampersand",		'&'},
	{"apostrophe",		'\''},
	{"left-parenthesis",	'('},
	{"right-parenthesis",	')'},
	{"asterisk",	'*'},
	{"plus-sign",	'+'},
	{"comma",	','},
	{"hyphen",	'-'},
	{"hyphen-minus",	'-'},
	{"period",	'.'},
	{"full-stop",	'.'},
	{"slash",	'/'},
	{"solidus",	'/'},
	{"zero",		'0'},
	{"one",		'1'},
	{"two",		'2'},
	{"three",	'3'},
	{"four",		'4'},
	{"five",		'5'},
	{"six",		'6'},
	{"seven",	'7'},
	{"eight",	'8'},
	{"nine",		'9'},
	{"colon",	':'},
	{"semicolon",	';'},
	{"less-than-sign",	'<'},
	{"equals-sign",		'='},
	{"greater-than-sign",	'>'},
	{"question-mark",	'?'},
	{"commercial-at",	'@'},
	{"left-square-bracket",	'['},
	{"backslash",		'\\'},
	{"reverse-solidus",	'\\'},
	{"right-square-bracket",	']'},
	{"circumflex",		'^'},
	{"circumflex-accent",	'^'},
	{"underscore",		'_'},
	{"low-line",		'_'},
	{"grave-accent",		'`'},
	{"left-brace",		'{'},
	{"left-curly-bracket",	'{'},
	{"vertical-line",	'|'},
	{"right-brace",		'}'},
	{"right-curly-bracket",	'}'},
	{"tilde",		'~'},
	{"DEL",	'\177'},
	{NULL,	0},
};
php/regex/regex.h000064400000004003151731376160007737 0ustar00#ifndef _HSREGEX_H_
#define _HSREGEX_H_
#ifndef _HSREGEX_H
#define	_HSREGEX_H	/* never again */
/* ========= begin header generated by ././mkh ========= */
#ifdef __cplusplus
extern "C" {
#endif

/* === regex2.h === */
#ifdef WIN32
#define API_EXPORT(type)    __declspec(dllexport) type __stdcall
#else
#define API_EXPORT(type)    type
#endif

typedef off_t regoff_t;
typedef struct {
	int re_magic;
	size_t re_nsub;		/* number of parenthesized subexpressions */
	const char *re_endp;	/* end pointer for REG_PEND */
	struct re_guts *re_g;	/* none of your business :-) */
} regex_t;
typedef struct {
	regoff_t rm_so;		/* start of match */
	regoff_t rm_eo;		/* end of match */
} regmatch_t;


/* === regcomp.c === */
API_EXPORT(int) regcomp(regex_t *, const char *, int);
#define	REG_BASIC	0000
#define	REG_EXTENDED	0001
#define	REG_ICASE	0002
#define	REG_NOSUB	0004
#define	REG_NEWLINE	0010
#define	REG_NOSPEC	0020
#define	REG_PEND	0040
#define	REG_DUMP	0200


/* === regerror.c === */
#define	REG_OKAY	 0
#define	REG_NOMATCH	 1
#define	REG_BADPAT	 2
#define	REG_ECOLLATE	 3
#define	REG_ECTYPE	 4
#define	REG_EESCAPE	 5
#define	REG_ESUBREG	 6
#define	REG_EBRACK	 7
#define	REG_EPAREN	 8
#define	REG_EBRACE	 9
#define	REG_BADBR	10
#define	REG_ERANGE	11
#define	REG_ESPACE	12
#define	REG_BADRPT	13
#define	REG_EMPTY	14
#define	REG_ASSERT	15
#define	REG_INVARG	16
#define	REG_ATOI	255	/* convert name to number (!) */
#define	REG_ITOA	0400	/* convert number to name (!) */
API_EXPORT(size_t) regerror(int, const regex_t *, char *, size_t);


/* === regexec.c === */
API_EXPORT(int) regexec(const regex_t *, const char *, size_t, regmatch_t [], int);
#define	REG_NOTBOL	00001
#define	REG_NOTEOL	00002
#define	REG_STARTEND	00004
#define	REG_TRACE	00400	/* tracing of execution */
#define	REG_LARGE	01000	/* force large representation */
#define	REG_BACKR	02000	/* force use of backref code */


/* === regfree.c === */
API_EXPORT(void) regfree(regex_t *);

#ifdef __cplusplus
}
#endif
/* ========= end header generated by ././mkh ========= */
#endif
#endif
php/regex/cclass.h000064400000001710151731376170010100 0ustar00/* character-class table */
static struct cclass {
	unsigned char *name;
	unsigned char *chars;
	unsigned char *multis;
} cclasses[] = {
	{"alnum",	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",				""},
	{"alpha",	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
					""},
	{"blank",	" \t",		""},
	{"cntrl",	"\007\b\t\n\v\f\r\1\2\3\4\5\6\16\17\20\21\22\23\24\
\25\26\27\30\31\32\33\34\35\36\37\177",	""},
	{"digit",	"0123456789",	""},
	{"graph",	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\
0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
					""},
	{"lower",	"abcdefghijklmnopqrstuvwxyz",
					""},
	{"print",	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\
0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ ",
					""},
	{"punct",	"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
					""},
	{"space",	"\t\n\v\f\r ",	""},
	{"upper",	"ABCDEFGHIJKLMNOPQRSTUVWXYZ",
					""},
	{"xdigit",	"0123456789ABCDEFabcdef",
					""},
	{NULL,		0,		""}
};
php/regex/regex_extra.h000064400000000573151731376170011153 0ustar00/* do not frame this - we must be able to include this file multiple times */

#undef regexec
#undef regerror
#undef regfree
#undef regcomp

#if (defined(REGEX) && REGEX == 1) || (!defined(REGEX))

#ifndef PHP_WIN32

#ifndef PHP_NO_ALIASES

#define regexec php_regexec
#define regerror php_regerror
#define regfree php_regfree
#define regcomp php_regcomp

#endif

#endif

#endif
php/TSRM/tsrm_virtual_cwd.h000064400000025004151731376170011675 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Sascha Schumann <sascha@schumann.cx>                        |
   +----------------------------------------------------------------------+
*/

/* $Id: tsrm_virtual_cwd.h 293036 2010-01-03 09:23:27Z sebastian $ */

#ifndef VIRTUAL_CWD_H
#define VIRTUAL_CWD_H

#include "TSRM.h"
#include "tsrm_config_common.h"

#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>

#ifdef HAVE_UTIME_H
#include <utime.h>
#endif

#ifdef HAVE_STDARG_H
#include <stdarg.h>
#endif

#ifdef ZTS
#define VIRTUAL_DIR
#endif

#ifndef TSRM_WIN32
#include <unistd.h>
#else
#include <direct.h>
#endif

#if defined(__osf__) || defined(_AIX)
#include <errno.h>
#endif

#ifdef TSRM_WIN32
#include "readdir.h"
#include <sys/utime.h>
/* mode_t isn't defined on Windows */
typedef unsigned short mode_t;

#define DEFAULT_SLASH '\\'
#define DEFAULT_DIR_SEPARATOR	';'
#define IS_SLASH(c)	((c) == '/' || (c) == '\\')
#define IS_SLASH_P(c)	(*(c) == '/' || \
        (*(c) == '\\' && !IsDBCSLeadByte(*(c-1))))

/* COPY_WHEN_ABSOLUTE is 2 under Win32 because by chance both regular absolute paths
   in the file system and UNC paths need copying of two characters */
#define COPY_WHEN_ABSOLUTE(path) 2
#define IS_UNC_PATH(path, len) \
	(len >= 2 && IS_SLASH(path[0]) && IS_SLASH(path[1]))
#define IS_ABSOLUTE_PATH(path, len) \
	(len >= 2 && ((isalpha(path[0]) && path[1] == ':') || IS_UNC_PATH(path, len)))

#elif defined(NETWARE)
#ifdef HAVE_DIRENT_H
#include <dirent.h>
#endif

#define DEFAULT_SLASH '/'
#define DEFAULT_DIR_SEPARATOR	';'
#define IS_SLASH(c)	((c) == '/' || (c) == '\\')
#define IS_SLASH_P(c)	IS_SLASH(*(c))
/* Colon indicates volume name, either first character should be forward slash or backward slash */
#define IS_ABSOLUTE_PATH(path, len) \
    ((strchr(path, ':') != NULL) || ((len >= 1) && ((path[0] == '/') || (path[0] == '\\'))))

#else
#ifdef HAVE_DIRENT_H
#include <dirent.h>
#endif

#define DEFAULT_SLASH '/'

#ifdef __riscos__
#define DEFAULT_DIR_SEPARATOR  ';'
#else
#define DEFAULT_DIR_SEPARATOR  ':'
#endif

#define IS_SLASH(c)	((c) == '/')
#define IS_SLASH_P(c)	(*(c) == '/')

#endif


#ifndef COPY_WHEN_ABSOLUTE
#define COPY_WHEN_ABSOLUTE(path) 0
#endif

#ifndef IS_ABSOLUTE_PATH	
#define IS_ABSOLUTE_PATH(path, len) \
	(IS_SLASH(path[0]))
#endif

#ifdef TSRM_EXPORTS
#define CWD_EXPORTS
#endif

#ifdef TSRM_WIN32
#       ifdef CWD_EXPORTS
#       define CWD_API __declspec(dllexport)
#       else
#       define CWD_API __declspec(dllimport)
#       endif
#else
#define CWD_API
#endif

#ifdef TSRM_WIN32
CWD_API int php_sys_stat(const char *path, struct stat *buf);
#else
# define php_sys_stat stat
#endif

typedef struct _cwd_state {
	char *cwd;
	int cwd_length;
} cwd_state;

typedef int (*verify_path_func)(const cwd_state *);

CWD_API void virtual_cwd_startup(void);
CWD_API void virtual_cwd_shutdown(void);
CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC);
CWD_API char *virtual_getcwd(char *buf, size_t size TSRMLS_DC);
CWD_API int virtual_chdir(const char *path TSRMLS_DC);
CWD_API int virtual_chdir_file(const char *path, int (*p_chdir)(const char *path TSRMLS_DC) TSRMLS_DC);
CWD_API int virtual_filepath(const char *path, char **filepath TSRMLS_DC);
CWD_API int virtual_filepath_ex(const char *path, char **filepath, verify_path_func verify_path TSRMLS_DC);
CWD_API char *virtual_realpath(const char *path, char *real_path TSRMLS_DC);
CWD_API FILE *virtual_fopen(const char *path, const char *mode TSRMLS_DC);
CWD_API int virtual_open(const char *path TSRMLS_DC, int flags, ...);
CWD_API int virtual_creat(const char *path, mode_t mode TSRMLS_DC);
CWD_API int virtual_rename(char *oldname, char *newname TSRMLS_DC);
CWD_API int virtual_stat(const char *path, struct stat *buf TSRMLS_DC);
#if !defined(TSRM_WIN32)
CWD_API int virtual_lstat(const char *path, struct stat *buf TSRMLS_DC);
#endif
CWD_API int virtual_unlink(const char *path TSRMLS_DC);
CWD_API int virtual_mkdir(const char *pathname, mode_t mode TSRMLS_DC);
CWD_API int virtual_rmdir(const char *pathname TSRMLS_DC);
CWD_API DIR *virtual_opendir(const char *pathname TSRMLS_DC);
CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC);
CWD_API int virtual_access(const char *pathname, int mode TSRMLS_DC);
#if defined(TSRM_WIN32)
/* these are not defined in win32 headers */
#ifndef W_OK
#define W_OK 0x02
#endif
#ifndef R_OK
#define R_OK 0x04
#endif
#ifndef X_OK
#define X_OK 0x01
#endif
#ifndef F_OK
#define F_OK 0x00
#endif
#endif

#if HAVE_UTIME
CWD_API int virtual_utime(const char *filename, struct utimbuf *buf TSRMLS_DC);
#endif
CWD_API int virtual_chmod(const char *filename, mode_t mode TSRMLS_DC);
#if !defined(TSRM_WIN32) && !defined(NETWARE)
CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group, int link TSRMLS_DC);
#endif

/* One of the following constants must be used as the last argument 
   in virtual_file_ex() call. */

#define CWD_EXPAND   0 /* expand "." and ".." but dont resolve symlinks      */
#define CWD_FILEPATH 1 /* resolve symlinks if file is exist otherwise expand */
#define CWD_REALPATH 2 /* call realpath(), resolve symlinks. File must exist */

CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func verify_path, int use_realpath);

CWD_API char *tsrm_realpath(const char *path, char *real_path TSRMLS_DC);

#define REALPATH_CACHE_TTL  (2*60) /* 2 minutes */
#define REALPATH_CACHE_SIZE 0      /* disabled while php.ini isn't loaded */

typedef struct _realpath_cache_bucket {
	unsigned long                  key;
	char                          *path;
	int                            path_len;
	char                          *realpath;
	int                            realpath_len;
	time_t                         expires;
	struct _realpath_cache_bucket *next;	
} realpath_cache_bucket;

typedef struct _virtual_cwd_globals {
	cwd_state cwd;
	long                   realpath_cache_size;
	long                   realpath_cache_size_limit;
	long                   realpath_cache_ttl;
	realpath_cache_bucket *realpath_cache[1024];
} virtual_cwd_globals;

#ifdef ZTS
extern ts_rsrc_id cwd_globals_id;
# define CWDG(v) TSRMG(cwd_globals_id, virtual_cwd_globals *, v)
#else
extern virtual_cwd_globals cwd_globals;
# define CWDG(v) (cwd_globals.v)
#endif

CWD_API void realpath_cache_clean(TSRMLS_D);
CWD_API void realpath_cache_del(const char *path, int path_len TSRMLS_DC);

/* The actual macros to be used in programs using TSRM
 * If the program defines VIRTUAL_DIR it will use the
 * virtual_* functions 
 */

#ifdef VIRTUAL_DIR

#define VCWD_GETCWD(buff, size) virtual_getcwd(buff, size TSRMLS_CC)
#define VCWD_FOPEN(path, mode) virtual_fopen(path, mode TSRMLS_CC)
/* Because open() has two modes, we have to macros to replace it */
#define VCWD_OPEN(path, flags) virtual_open(path TSRMLS_CC, flags)
#define VCWD_OPEN_MODE(path, flags, mode) virtual_open(path TSRMLS_CC, flags, mode)
#define VCWD_CREAT(path, mode) virtual_creat(path, mode TSRMLS_CC)
#define VCWD_CHDIR(path) virtual_chdir(path TSRMLS_CC)
#define VCWD_CHDIR_FILE(path) virtual_chdir_file(path, virtual_chdir TSRMLS_CC)
#define VCWD_GETWD(buf)
#define VCWD_REALPATH(path, real_path) virtual_realpath(path, real_path TSRMLS_CC)
#define VCWD_RENAME(oldname, newname) virtual_rename(oldname, newname TSRMLS_CC)
#define VCWD_STAT(path, buff) virtual_stat(path, buff TSRMLS_CC)
#if !defined(TSRM_WIN32)
#define VCWD_LSTAT(path, buff) virtual_lstat(path, buff TSRMLS_CC)
#endif
#define VCWD_UNLINK(path) virtual_unlink(path TSRMLS_CC)
#define VCWD_MKDIR(pathname, mode) virtual_mkdir(pathname, mode TSRMLS_CC)
#define VCWD_RMDIR(pathname) virtual_rmdir(pathname TSRMLS_CC)
#define VCWD_OPENDIR(pathname) virtual_opendir(pathname TSRMLS_CC)
#define VCWD_POPEN(command, type) virtual_popen(command, type TSRMLS_CC)
#define VCWD_ACCESS(pathname, mode) virtual_access(pathname, mode TSRMLS_CC)
#if HAVE_UTIME
#define VCWD_UTIME(path, time) virtual_utime(path, time TSRMLS_CC)
#endif
#define VCWD_CHMOD(path, mode) virtual_chmod(path, mode TSRMLS_CC)
#if !defined(TSRM_WIN32) && !defined(NETWARE)
#define VCWD_CHOWN(path, owner, group) virtual_chown(path, owner, group, 0 TSRMLS_CC)
#if HAVE_LCHOWN
#define VCWD_LCHOWN(path, owner, group) virtual_chown(path, owner, group, 1 TSRMLS_CC)
#endif
#endif

#else

#define VCWD_GETCWD(buff, size) getcwd(buff, size)
#define VCWD_FOPEN(path, mode)  fopen(path, mode)
#define VCWD_OPEN(path, flags) open(path, flags)
#define VCWD_OPEN_MODE(path, flags, mode)	open(path, flags, mode)
#define VCWD_CREAT(path, mode) creat(path, mode)
#define VCWD_RENAME(oldname, newname) rename(oldname, newname)
#define VCWD_CHDIR(path) chdir(path)
#define VCWD_CHDIR_FILE(path) virtual_chdir_file(path, chdir)
#define VCWD_GETWD(buf) getwd(buf)
#define VCWD_STAT(path, buff) php_sys_stat(path, buff)
#define VCWD_LSTAT(path, buff) lstat(path, buff)
#define VCWD_UNLINK(path) unlink(path)
#define VCWD_MKDIR(pathname, mode) mkdir(pathname, mode)
#define VCWD_RMDIR(pathname) rmdir(pathname)
#define VCWD_OPENDIR(pathname) opendir(pathname)
#define VCWD_POPEN(command, type) popen(command, type)
#if defined(TSRM_WIN32)
#define VCWD_ACCESS(pathname, mode) tsrm_win32_access(pathname, mode)
#else
#define VCWD_ACCESS(pathname, mode) access(pathname, mode)
#endif

#define VCWD_REALPATH(path, real_path) tsrm_realpath(path, real_path TSRMLS_CC)

#if HAVE_UTIME
#define VCWD_UTIME(path, time) utime(path, time)
#endif
#define VCWD_CHMOD(path, mode) chmod(path, mode)
#if !defined(TSRM_WIN32) && !defined(NETWARE)
#define VCWD_CHOWN(path, owner, group) chown(path, owner, group)
#if HAVE_LCHOWN
#define VCWD_LCHOWN(path, owner, group) lchown(path, owner, group)
#endif
#endif

#endif

#endif /* VIRTUAL_CWD_H */
php/TSRM/acconfig.h000064400000000020151731376170010045 0ustar00#undef PTHREADS
php/TSRM/tsrm_nw.h000064400000002550151731376200007771 0ustar00/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2010 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Venkat Raghavan S <rvenkat@novell.com>                      |
   |          Anantha Kesari H Y <hyanantha@novell.com>                   |
   +----------------------------------------------------------------------+
*/


#ifndef TSRM_NW_H
#define TSRM_NW_H

#include "TSRM.h"

TSRM_API FILE* popen(const char *command, const char *type);
TSRM_API int pclose(FILE* stream);

#endif
php/Zend/zend_fast_cache.h000064400000010123151731376210011507 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        | 
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_fast_cache.h 293155 2010-01-05 20:46:53Z sebastian $ */
#if 0
#ifndef ZEND_FAST_CACHE_H
#define ZEND_FAST_CACHE_H

#ifndef ZEND_ENABLE_FAST_CACHE
# if ZEND_DEBUG
# define ZEND_ENABLE_FAST_CACHE 0
# else
# define ZEND_ENABLE_FAST_CACHE 0
# endif
#endif

typedef struct _zend_fast_cache_list_entry {
	struct _zend_fast_cache_list_entry *next;
} zend_fast_cache_list_entry;

#define MAX_FAST_CACHE_TYPES	4


#define ZVAL_CACHE_LIST			0
#define HASHTABLE_CACHE_LIST	1

#if ZEND_ENABLE_FAST_CACHE


#include "zend_globals.h"
#include "zend_globals_macros.h"
#include "zend_alloc.h"


#if ZEND_DEBUG
# define RECORD_ZVAL_CACHE_HIT(fc_type)		AG(fast_cache_stats)[fc_type][1]++;
# define RECORD_ZVAL_CACHE_MISS(fc_type)	AG(fast_cache_stats)[fc_type][0]++;
#else
# define RECORD_ZVAL_CACHE_HIT(fc_type)
# define RECORD_ZVAL_CACHE_MISS(fc_type)
#endif


#define ZEND_FAST_ALLOC(p, type, fc_type)								\
	{																\
		TSRMLS_FETCH();												\
																	\
		if (((p) = (type *) AG(fast_cache_list_head)[fc_type])) {	\
			AG(fast_cache_list_head)[fc_type] = ((zend_fast_cache_list_entry *) AG(fast_cache_list_head)[fc_type])->next;	\
			RECORD_ZVAL_CACHE_HIT(fc_type);							\
		} else {													\
			(p) = (type *) emalloc(sizeof(type));					\
			RECORD_ZVAL_CACHE_MISS(fc_type);						\
		}															\
	}


#define ZEND_FAST_FREE(p, fc_type)										\
	{																\
		TSRMLS_FETCH();												\
																	\
		((zend_fast_cache_list_entry *) (p))->next = (zend_fast_cache_list_entry *) AG(fast_cache_list_head)[fc_type];	\
		AG(fast_cache_list_head)[fc_type] = (zend_fast_cache_list_entry *) (p);			\
	}

#define ZEND_FAST_ALLOC_REL(p, type, fc_type)	\
	ZEND_FAST_ALLOC(p, type, fc_type)

#define ZEND_FAST_FREE_REL(p, fc_type)	\
	ZEND_FAST_FREE(p, fc_type)


#else /* !ZEND_ENABLE_FAST_CACHE */

#define ZEND_FAST_ALLOC(p, type, fc_type)	\
	(p) = (type *) emalloc(sizeof(type))

#define ZEND_FAST_FREE(p, fc_type)	\
	efree(p)

#define ZEND_FAST_ALLOC_REL(p, type, fc_type)	\
	(p) = (type *) emalloc_rel(sizeof(type))

#define ZEND_FAST_FREE_REL(p, fc_type)	\
	efree_rel(p)

#endif /* ZEND_ENABLE_FAST_CACHE */



/* fast cache for zval's */
#define ALLOC_ZVAL(z)	\
	ZEND_FAST_ALLOC(z, zval, ZVAL_CACHE_LIST)

#define FREE_ZVAL(z)	\
	ZEND_FAST_FREE(z, ZVAL_CACHE_LIST)

#define ALLOC_ZVAL_REL(z)	\
	ZEND_FAST_ALLOC_REL(z, zval, ZVAL_CACHE_LIST)

#define FREE_ZVAL_REL(z)	\
	ZEND_FAST_FREE_REL(z, ZVAL_CACHE_LIST)

/* fast cache for HashTables */
#define ALLOC_HASHTABLE(ht)	\
	ZEND_FAST_ALLOC(ht, HashTable, HASHTABLE_CACHE_LIST)

#define FREE_HASHTABLE(ht)	\
	ZEND_FAST_FREE(ht, HASHTABLE_CACHE_LIST)

#define ALLOC_HASHTABLE_REL(ht)	\
	ZEND_FAST_ALLOC_REL(ht, HashTable, HASHTABLE_CACHE_LIST)

#define FREE_HASHTABLE_REL(ht)	\
	ZEND_FAST_FREE_REL(ht, HASHTABLE_CACHE_LIST)

#endif /* ZEND_FAST_CACHE_H */
#endif
/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/acconfig.h000064400000006333151731376220010171 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: acconfig.h 293155 2010-01-05 20:46:53Z sebastian $ */

#define ZEND_API
#define ZEND_DLEXPORT
#define ZEND_DLIMPORT

@TOP@

#undef uint
#undef ulong

/* Define if you want to enable memory limit support */
#define MEMORY_LIMIT 0

@BOTTOM@

#ifndef ZEND_ACCONFIG_H_NO_C_PROTOS

#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif

#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif

#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif

#ifdef HAVE_IEEEFP_H
# include <ieeefp.h>
#endif

#ifdef HAVE_STRING_H
# include <string.h>
#else
# include <strings.h>
#endif

#if ZEND_BROKEN_SPRINTF
int zend_sprintf(char *buffer, const char *format, ...);
#else
# define zend_sprintf sprintf
#endif

#include <math.h>

/* To enable the is_nan, is_infinite and is_finite PHP functions */
#ifdef NETWARE
	#define HAVE_ISNAN 1
	#define HAVE_ISINF 1
	#define HAVE_ISFINITE 1
#endif

#ifndef zend_isnan
#ifdef HAVE_ISNAN
#define zend_isnan(a) isnan(a)
#elif defined(HAVE_FPCLASS)
#define zend_isnan(a) ((fpclass(a) == FP_SNAN) || (fpclass(a) == FP_QNAN))
#else
#define zend_isnan(a) 0
#endif
#endif

#ifdef HAVE_ISINF
#define zend_isinf(a) isinf(a)
#elif defined(INFINITY)
/* Might not work, but is required by ISO C99 */
#define zend_isinf(a) (((a)==INFINITY)?1:0)
#elif defined(HAVE_FPCLASS)
#define zend_isinf(a) ((fpclass(a) == FP_PINF) || (fpclass(a) == FP_NINF))
#else
#define zend_isinf(a) 0
#endif

#ifdef HAVE_FINITE
#define zend_finite(a) finite(a)
#elif defined(HAVE_ISFINITE) || defined(isfinite)
#define zend_finite(a) isfinite(a)
#elif defined(fpclassify)
#define zend_finite(a) ((fpclassify((a))!=FP_INFINITE&&fpclassify((a))!=FP_NAN)?1:0)
#else
#define zend_finite(a) (zend_isnan(a) ? 0 : zend_isinf(a) ? 0 : 1)
#endif

#endif /* ifndef ZEND_ACCONFIG_H_NO_C_PROTOS */

#ifdef NETWARE
#ifdef USE_WINSOCK
#/*This detection against winsock is of no use*/ undef HAVE_SOCKLEN_T
#/*This detection against winsock is of no use*/ undef HAVE_SYS_SOCKET_H
#endif
#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_indent.h000064400000002764151731376220010725 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        | 
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_indent.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef ZEND_INDENT_H
#define ZEND_INDENT_H

BEGIN_EXTERN_C()
ZEND_API void zend_indent(void);
END_EXTERN_C()

#endif /* ZEND_INDENT_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_static_allocator.h000064400000003601151731376220012762 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_static_allocator.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef ZEND_STATIC_ALLOCATOR_H
#define ZEND_STATIC_ALLOCATOR_H

#define ALLOCATOR_BLOCK_SIZE 400000

/* Temporary */
typedef unsigned int zend_uint;
#define emalloc(s) malloc(s)
#define efree(p) free(p)

typedef struct _Block {
	char *bp;
	char *pos;
	char *end;
} Block;

typedef struct _StaticAllocator {
	Block *Blocks;
	zend_uint num_blocks;
	zend_uint current_block;
} StaticAllocator;

void static_allocator_init(StaticAllocator *sa);
char *static_allocator_allocate(StaticAllocator *sa, zend_uint size);
void static_allocator_destroy(StaticAllocator *sa);

#endif /* ZEND_STATIC_ALLOCATOR_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_qsort.h000064400000002753151731376220010612 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        | 
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Sterling Hughes <sterling@php.net>                          |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_qsort.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef ZEND_QSORT_H
#define ZEND_QSORT_H

BEGIN_EXTERN_C()
ZEND_API void zend_qsort(void *base, size_t nmemb, size_t siz, compare_func_t compare TSRMLS_DC);
END_EXTERN_C()

#endif       /* ZEND_QSORT_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/zend_dynamic_array.h000064400000003657151731376230012271 0ustar00/*
   +----------------------------------------------------------------------+
   | Zend Engine                                                          |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.00 of the Zend license,     |
   | that is bundled with this package in the file LICENSE, and is        | 
   | available through the world-wide-web at the following url:           |
   | http://www.zend.com/license/2_00.txt.                                |
   | If you did not receive a copy of the Zend license and are unable to  |
   | obtain it through the world-wide-web, please send a note to          |
   | license@zend.com so we can mail you a copy immediately.              |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   +----------------------------------------------------------------------+
*/

/* $Id: zend_dynamic_array.h 293155 2010-01-05 20:46:53Z sebastian $ */

#ifndef ZEND_DYNAMIC_ARRAY_H
#define ZEND_DYNAMIC_ARRAY_H

typedef struct _dynamic_array {
	char *array;
	unsigned int element_size;
	unsigned int last_used;
	unsigned int allocated;
} dynamic_array;

BEGIN_EXTERN_C()
ZEND_API int zend_dynamic_array_init(dynamic_array *da, unsigned int element_size, unsigned int size);
ZEND_API void *zend_dynamic_array_push(dynamic_array *da);
ZEND_API void *zend_dynamic_array_pop(dynamic_array *da);
ZEND_API void *zend_dynamic_array_get_element(dynamic_array *da, unsigned int index);
END_EXTERN_C()

#endif /* ZEND_DYNAMIC_ARRAY_H */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */
php/Zend/FlexLexer.h000064400000013042151731376250010314 0ustar00// $Header$

// FlexLexer.h -- define interfaces for lexical analyzer classes generated
//		  by flex

// Copyright (c) 1993 The Regents of the University of California.
// All rights reserved.
//
// This code is derived from software contributed to Berkeley by
// Kent Williams and Tom Epperly.
//
// Redistribution and use in source and binary forms with or without
// modification are permitted provided that: (1) source distributions retain
// this entire copyright notice and comment, and (2) distributions including
// binaries display the following acknowledgement:  ``This product includes
// software developed by the University of California, Berkeley and its
// contributors'' in the documentation or other materials provided with the
// distribution and in all advertising materials mentioning features or use
// of this software.  Neither the name of the University nor the names of
// its contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.

// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

// This file defines FlexLexer, an abstract class which specifies the
// external interface provided to flex C++ lexer objects, and yyFlexLexer,
// which defines a particular lexer class.
//
// If you want to create multiple lexer classes, you use the -P flag
// to rename each yyFlexLexer to some other xxFlexLexer.  You then
// include <FlexLexer.h> in your other sources once per lexer class:
//
//	#undef yyFlexLexer
//	#define yyFlexLexer xxFlexLexer
//	#include <FlexLexer.h>
//
//	#undef yyFlexLexer
//	#define yyFlexLexer zzFlexLexer
//	#include <FlexLexer.h>
//	...

#ifndef FLEXLEXER_H
// Never included before - need to define base class.
#define FLEXLEXER_H
#include <iostream.h>

extern "C++" {

struct yy_buffer_state;
typedef int yy_state_type;

class FlexLexer {
public:
	virtual ~FlexLexer()	{ }

	const char* YYText()	{ return yytext; }
	int YYLeng()		{ return yyleng; }

	virtual void
		yy_switch_to_buffer( struct yy_buffer_state* new_buffer ) = 0;
	virtual struct yy_buffer_state*
		yy_create_buffer( istream* s, int size ) = 0;
	virtual void yy_delete_buffer( struct yy_buffer_state* b ) = 0;
	virtual void yyrestart( istream* s ) = 0;

	virtual int yylex() = 0;

	// Call yylex with new input/output sources.
	int yylex( istream* new_in, ostream* new_out = 0 )
		{
		switch_streams( new_in, new_out );
		return yylex();
		}

	// Switch to new input/output streams.  A nil stream pointer
	// indicates "keep the current one".
	virtual void switch_streams( istream* new_in = 0,
					ostream* new_out = 0 ) = 0;

	int lineno() const		{ return yylineno; }

	int debug() const		{ return yy_flex_debug; }
	void set_debug( int flag )	{ yy_flex_debug = flag; }

protected:
	char* yytext;
	int yyleng;
	int yylineno;		// only maintained if you use %option yylineno
	int yy_flex_debug;	// only has effect with -d or "%option debug"
};

}
#endif

#if defined(yyFlexLexer) || ! defined(yyFlexLexerOnce)
// Either this is the first time through (yyFlexLexerOnce not defined),
// or this is a repeated include to define a different flavor of
// yyFlexLexer, as discussed in the flex man page.
#define yyFlexLexerOnce

class yyFlexLexer : public FlexLexer {
public:
	// arg_yyin and arg_yyout default to the cin and cout, but we
	// only make that assignment when initializing in yylex().
	yyFlexLexer( istream* arg_yyin = 0, ostream* arg_yyout = 0 );

	virtual ~yyFlexLexer();

	void yy_switch_to_buffer( struct yy_buffer_state* new_buffer );
	struct yy_buffer_state* yy_create_buffer( istream* s, int size );
	void yy_delete_buffer( struct yy_buffer_state* b );
	void yyrestart( istream* s );

	virtual int yylex();
	virtual void switch_streams( istream* new_in, ostream* new_out );

protected:
	virtual int LexerInput( char* buf, int max_size );
	virtual void LexerOutput( const char* buf, int size );
	virtual void LexerError( const char* msg );

	void yyunput( int c, char* buf_ptr );
	int yyinput();

	void yy_load_buffer_state();
	void yy_init_buffer( struct yy_buffer_state* b, istream* s );
	void yy_flush_buffer( struct yy_buffer_state* b );

	int yy_start_stack_ptr;
	int yy_start_stack_depth;
	int* yy_start_stack;

	void yy_push_state( int new_state );
	void yy_pop_state();
	int yy_top_state();

	yy_state_type yy_get_previous_state();
	yy_state_type yy_try_NUL_trans( yy_state_type current_state );
	int yy_get_next_buffer();

	istream* yyin;	// input source for default LexerInput
	ostream* yyout;	// output sink for default LexerOutput

	struct yy_buffer_state* yy_current_buffer;

	// yy_hold_char holds the character lost when yytext is formed.
	char yy_hold_char;

	// Number of characters read into yy_ch_buf.
	int yy_n_chars;

	// Points to current character in buffer.
	char* yy_c_buf_p;

	int yy_init;		// whether we need to initialize
	int yy_start;		// start state number

	// Flag which is used to allow yywrap()'s to do buffer switches
	// instead of setting up a fresh yyin.  A bit of a hack ...
	int yy_did_buffer_switch_on_eof;

	// The following are not always needed, but may be depending
	// on use of certain flex features (like REJECT or yymore()).

	yy_state_type yy_last_accepting_state;
	char* yy_last_accepting_cpos;

	yy_state_type* yy_state_buf;
	yy_state_type* yy_state_ptr;

	char* yy_full_match;
	int* yy_full_state;
	int yy_full_lp;

	int yy_lp;
	int yy_looking_for_trail_begin;

	int yy_more_flag;
	int yy_more_len;
	int yy_more_offset;
	int yy_prev_more_offset;
};

#endif
ruby/subst.h000064400000001446151732674110007052 0ustar00#ifndef RUBY_SUBST_H                                 /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_SUBST_H 1
/**
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 */

#undef snprintf
#undef vsnprintf
#define snprintf ruby_snprintf
#define vsnprintf ruby_vsnprintf

#ifdef BROKEN_CLOSE
#undef getpeername
#define getpeername ruby_getpeername
#undef getsockname
#define getsockname ruby_getsockname
#undef shutdown
#define shutdown ruby_shutdown
#undef close
#define close ruby_close
#endif
#endif
ruby/intern.h000064400000004465151732674120007216 0ustar00#ifndef RUBY_INTERN_H                                /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_INTERN_H 1
/**
 * @file
 * @author     $Author$
 * @date       Thu Jun 10 14:22:17 JST 1993
 * @copyright  Copyright (C) 1993-2007 Yukihiro Matsumoto
 * @copyright  Copyright (C) 2000  Network Applied Communication Laboratory, Inc.
 * @copyright  Copyright (C) 2000  Information-technology Promotion Agency, Japan
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 */
#include "ruby/internal/config.h"
#include "ruby/defines.h"

#include <stdarg.h>

#include "ruby/st.h"

/*
 * Functions and variables that are used by more than one source file of
 * the kernel.
 */

#include "ruby/internal/intern/array.h"
#include "ruby/internal/intern/bignum.h"
#include "ruby/internal/intern/class.h"
#include "ruby/internal/intern/compar.h"
#include "ruby/internal/intern/complex.h"
#include "ruby/internal/intern/cont.h"
#include "ruby/internal/intern/dir.h"
#include "ruby/internal/intern/enum.h"
#include "ruby/internal/intern/enumerator.h"
#include "ruby/internal/intern/error.h"
#include "ruby/internal/intern/eval.h"
#include "ruby/internal/intern/file.h"
#include "ruby/internal/intern/hash.h"
#include "ruby/internal/intern/io.h"
#include "ruby/internal/intern/load.h"
#include "ruby/internal/intern/marshal.h"
#include "ruby/internal/intern/numeric.h"
#include "ruby/internal/intern/object.h"
#include "ruby/internal/intern/parse.h"
#include "ruby/internal/intern/proc.h"
#include "ruby/internal/intern/process.h"
#include "ruby/internal/intern/random.h"
#include "ruby/internal/intern/range.h"
#include "ruby/internal/intern/rational.h"
#include "ruby/internal/intern/re.h"
#include "ruby/internal/intern/ruby.h"
#include "ruby/internal/intern/select.h"
#include "ruby/internal/intern/signal.h"
#include "ruby/internal/intern/sprintf.h"
#include "ruby/internal/intern/string.h"
#include "ruby/internal/intern/struct.h"
#include "ruby/internal/intern/thread.h"
#include "ruby/internal/intern/time.h"
#include "ruby/internal/intern/variable.h"
#include "ruby/internal/intern/vm.h"

#endif /* RUBY_INTERN_H */
ruby/io.h000064400000111521151732674120006316 0ustar00#ifndef RUBY_IO_H                                    /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_IO_H 1
/**
 * @file
 * @author     $Author$
 * @date       Fri Nov 12 16:47:09 JST 1993
 * @copyright  Copyright (C) 1993-2007 Yukihiro Matsumoto
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 */
#include "ruby/internal/config.h"

#include <stdio.h>
#include "ruby/encoding.h"

#if defined(HAVE_STDIO_EXT_H)
#include <stdio_ext.h>
#endif

#include <errno.h>

/** @cond INTERNAL_MACRO */
#if defined(HAVE_POLL)
#  ifdef _AIX
#    define reqevents events
#    define rtnevents revents
#  endif
#  include <poll.h>
#  ifdef _AIX
#    undef reqevents
#    undef rtnevents
#    undef events
#    undef revents
#  endif
#  define RB_WAITFD_IN  POLLIN
#  if defined(POLLPRI)
#    define RB_WAITFD_PRI POLLPRI
#  else
#    define RB_WAITFD_PRI 0
#  endif
#  define RB_WAITFD_OUT POLLOUT
#else
#  define RB_WAITFD_IN  0x001
#  define RB_WAITFD_PRI 0x002
#  define RB_WAITFD_OUT 0x004
#endif
/** @endcond */

#include "ruby/internal/attr/const.h"
#include "ruby/internal/attr/packed_struct.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"

// IO#wait, IO#wait_readable, IO#wait_writable, IO#wait_priority are defined by this implementation.
#define RUBY_IO_WAIT_METHODS

// Used as the default timeout argument to `rb_io_wait` to use the `IO#timeout` value.
#define RUBY_IO_TIMEOUT_DEFAULT Qnil

RBIMPL_SYMBOL_EXPORT_BEGIN()

struct stat;
struct timeval;

/**
 * Indicates that a timeout has occurred while performing an IO operation.
 */
RUBY_EXTERN VALUE rb_eIOTimeoutError;

/**
 * Type of events that an IO can wait.
 *
 * @internal
 *
 * This is visible from extension libraries because `io/wait` wants it.
 */
enum rb_io_event {
    RUBY_IO_READABLE = RB_WAITFD_IN,  /**< `IO::READABLE` */
    RUBY_IO_WRITABLE = RB_WAITFD_OUT, /**< `IO::WRITABLE` */
    RUBY_IO_PRIORITY = RB_WAITFD_PRI, /**< `IO::PRIORITY` */
};

typedef enum rb_io_event rb_io_event_t;

/**
 * IO  buffers.   This  is  an implementation  detail  of  ::rb_io_t::wbuf  and
 * ::rb_io_t::rbuf.  People don't manipulate it directly.
 */
RBIMPL_ATTR_PACKED_STRUCT_UNALIGNED_BEGIN()
struct rb_io_internal_buffer {

    /** Pointer to the underlying memory region, of at least `capa` bytes. */
    char *ptr;                  /* off + len <= capa */

    /** Offset inside of `ptr`. */
    int off;

    /** Length of the buffer. */
    int len;

    /** Designed capacity of the buffer. */
    int capa;
} RBIMPL_ATTR_PACKED_STRUCT_UNALIGNED_END();

/** @alias{rb_io_buffer_t} */
typedef struct rb_io_internal_buffer rb_io_buffer_t;

/** Decomposed encoding flags (e.g. `"enc:enc2""`). */
/*
 * enc  enc2 read action                      write action
 * NULL NULL force_encoding(default_external) write the byte sequence of str
 * e1   NULL force_encoding(e1)               convert str.encoding to e1
 * e1   e2   convert from e2 to e1            convert str.encoding to e2
 */
struct rb_io_encoding {
    /** Internal encoding. */
    rb_encoding *enc;
    /** External encoding. */
    rb_encoding *enc2;
    /**
     * Flags.
     *
     * @see enum ::ruby_econv_flag_type
     */
    int ecflags;
    /**
     * Flags as Ruby hash.
     *
     * @internal
     *
     * This is set.  But used from nowhere maybe?
     */
    VALUE ecopts;
};

#ifndef HAVE_RB_IO_T
#define HAVE_RB_IO_T 1
/** Ruby's IO, metadata and buffers. */
struct rb_io {
    /** The IO's Ruby level counterpart. */
    RBIMPL_ATTR_DEPRECATED(("with no replacement"))
    VALUE self;

    /** stdio ptr for read/write, if available. */
    RBIMPL_ATTR_DEPRECATED(("with no replacement"))
    FILE *stdio_file;

    /** file descriptor. */
    RBIMPL_ATTR_DEPRECATED(("rb_io_descriptor"))
    int fd;

    /** mode flags: FMODE_XXXs */
    RBIMPL_ATTR_DEPRECATED(("rb_io_mode"))
    int mode;

    /** child's pid (for pipes) */
    RBIMPL_ATTR_DEPRECATED(("with no replacement"))
    rb_pid_t pid;

    /** number of lines read */
    RBIMPL_ATTR_DEPRECATED(("with no replacement"))
    int lineno;

    /** pathname for file */
    RBIMPL_ATTR_DEPRECATED(("rb_io_path"))
    VALUE pathv;

    /** finalize proc */
    RBIMPL_ATTR_DEPRECATED(("with no replacement"))
    void (*finalize)(struct rb_io*,int);

    /** Write buffer. */
    RBIMPL_ATTR_DEPRECATED(("with no replacement"))
    rb_io_buffer_t wbuf;

    /**
     * (Byte)  read   buffer.   Note  also   that  there  is  a   field  called
     * ::rb_io_t::cbuf, which also concerns read IO.
     */
    RBIMPL_ATTR_DEPRECATED(("with no replacement"))
    rb_io_buffer_t rbuf;

    /**
     * Duplex IO object, if set.
     *
     * @see rb_io_set_write_io()
     */
    RBIMPL_ATTR_DEPRECATED(("rb_io_get_write_io"))
    VALUE tied_io_for_writing;

    RBIMPL_ATTR_DEPRECATED(("with no replacement"))
    struct rb_io_encoding encs; /**< Decomposed encoding flags. */

    /** Encoding converter used when reading from this IO. */
    RBIMPL_ATTR_DEPRECATED(("with no replacement"))
    rb_econv_t *readconv;

    /**
     * rb_io_ungetc()  destination.   This  buffer   is  read  before  checking
     * ::rb_io_t::rbuf
     */
    RBIMPL_ATTR_DEPRECATED(("with no replacement"))
    rb_io_buffer_t cbuf;

    /** Encoding converter used when writing to this IO. */
    RBIMPL_ATTR_DEPRECATED(("with no replacement"))
    rb_econv_t *writeconv;

    /**
     * This is, when set, an instance  of ::rb_cString which holds the "common"
     * encoding.   Write  conversion  can  convert strings  twice...   In  case
     * conversion from encoding  X to encoding Y does not  exist, Ruby finds an
     * encoding Z that bridges the two, so that X to Z to Y conversion happens.
     */
    RBIMPL_ATTR_DEPRECATED(("with no replacement"))
    VALUE writeconv_asciicompat;

    /** Whether ::rb_io_t::writeconv is already set up. */
    RBIMPL_ATTR_DEPRECATED(("with no replacement"))
    int writeconv_initialized;

    /**
     * Value   of    ::rb_io_t::rb_io_enc_t::ecflags   stored    right   before
     * initialising ::rb_io_t::writeconv.
     */
    RBIMPL_ATTR_DEPRECATED(("with no replacement"))
    int writeconv_pre_ecflags;

    /**
     * Value of ::rb_io_t::rb_io_enc_t::ecopts stored right before initialising
     * ::rb_io_t::writeconv.
     */
    RBIMPL_ATTR_DEPRECATED(("with no replacement"))
    VALUE writeconv_pre_ecopts;

    /**
     * This is a Ruby  level mutex.  It avoids multiple threads  to write to an
     * IO at  once; helps  for instance rb_io_puts()  to ensure  newlines right
     * next to its arguments.
     *
     * This of course doesn't help inter-process IO interleaves, though.
     */
    RBIMPL_ATTR_DEPRECATED(("with no replacement"))
    VALUE write_lock;

    /**
     * The timeout associated with this IO when performing blocking operations.
     */
    RBIMPL_ATTR_DEPRECATED(("rb_io_timeout/rb_io_set_timeout"))
    VALUE timeout;
};
#endif

typedef struct rb_io rb_io_t;

/** @alias{rb_io_enc_t} */
typedef struct rb_io_encoding rb_io_enc_t;

/**
 * @name Possible flags for ::rb_io_t::mode
 *
 * @{
 */

/** The IO is opened for reading. */
#define FMODE_READABLE              0x00000001

/** The IO is opened for writing. */
#define FMODE_WRITABLE              0x00000002

/** The IO is opened for both read/write. */
#define FMODE_READWRITE             (FMODE_READABLE|FMODE_WRITABLE)

/**
 * The IO  is in "binary  mode".  This  is not what  everything rb_io_binmode()
 * concerns.  This low-level flag is to stop CR <-> CRLF conversions that would
 * happen in the underlying operating system.
 *
 * Setting this  one and #FMODE_TEXTMODE at  the same time is  a contradiction.
 * Setting this one and #ECONV_NEWLINE_DECORATOR_MASK  at the same time is also
 * a contradiction.
 */
#define FMODE_BINMODE               0x00000004

/**
 * The  IO  is in  "sync  mode".   All output  is  immediately  flushed to  the
 * underlying operating system then.  Can  be set via rb_io_synchronized(), but
 * there is no way except calling `IO#sync=` to reset.
 */
#define FMODE_SYNC                  0x00000008

/**
 * The IO  is a TTY.  What  is a TTY and  what isn't depends on  the underlying
 * operating system's `isatty(3)` output.  You cannot change this.
 */
#define FMODE_TTY                   0x00000010

/**
 * Ruby eventually  detects that the IO  is bidirectional.  For instance  a TTY
 * has such  property.  There are  several other  things known to  be duplexed.
 * Additionally you  (extension library  authors) can  also implement  your own
 * bidirectional IO subclasses.  One of such example is `Socket`.
 */
#define FMODE_DUPLEX                0x00000020

/**
 * The IO is opened  for appending.  This mode always writes at  the end of the
 * IO.  Ruby manages  this flag for record but basically  the logic behind this
 * mode is at the underlying operating system.  We almost do nothing.
 */
#define FMODE_APPEND                0x00000040

/**
 * The IO is  opened for creating.  This makes sense  only when the destination
 * file does  not exist at  the time  the IO object  was created.  This  is the
 * default mode  for writing,  but you  can pass `"r+"`  to `IO.open`  etc., to
 * reroute this creation.
 */
#define FMODE_CREATE                0x00000080
/* #define FMODE_NOREVLOOKUP        0x00000100 */

/**
 * This flag amends the effect of #FMODE_CREATE,  so that if there already is a
 * file at the given path the operation fails.  Using this you can be sure that
 * the file you get is a fresh new one.
 */
#define FMODE_EXCL                  0x00000400

/**
 * This flag amends the effect of #FMODE_CREATE,  so that if there already is a
 * file at the given path it gets truncated.
 */
#define FMODE_TRUNC                 0x00000800

/**
 * The IO is in "text mode".  On  systems where such mode make sense, this flag
 * changes  the way  the  IO handles  the  contents.  On  POSIX  systems it  is
 * basically  a no-op,  but with  this  flag set  you can  optionally let  Ruby
 * manually convert newlines, unlike when in binary mode:
 *
 * ```ruby
 * IO.open("/p/a/t/h", "wt", crlf_newline: true) # "wb" is NG.
 * ```
 *
 * Setting this one and #FMODE_BINMODE at the same time is a contradiction.
 */
#define FMODE_TEXTMODE              0x00001000
/**
 * This flag means that an IO object is wrapping an "external" file descriptor,
 * which is owned by something outside the Ruby interpreter (usually a C extension).
 * Ruby will not close this file when the IO object is garbage collected.
 * If this flag is set, then IO#autoclose? is false, and vice-versa.
 *
 * This flag was previously called FMODE_PREP internally.
 */
#define FMODE_EXTERNAL              0x00010000

/* #define FMODE_SIGNAL_ON_EPIPE    0x00020000 */

/**
 * This flag amends the  encoding of the IO so that the BOM  of the contents of
 * the IO takes effect.
 */
#define FMODE_SETENC_BY_BOM         0x00100000
/* #define FMODE_UNIX                  0x00200000 */
/* #define FMODE_INET                  0x00400000 */
/* #define FMODE_INET6                 0x00800000 */

/** @} */

/**
 * Allocate a new IO object, with the given file descriptor.
 */
VALUE rb_io_open_descriptor(VALUE klass, int descriptor, int mode, VALUE path, VALUE timeout, struct rb_io_encoding *encoding);

/**
 * Returns whether or not the underlying IO is closed.
 *
 * @return Whether the underlying IO is closed.
 */
VALUE rb_io_closed_p(VALUE io);

/**
 * Queries the underlying IO pointer.
 *
 * @param[in]   obj              An IO object.
 * @param[out]  fp               A variable of type ::rb_io_t.
 * @exception   rb_eFrozenError  `obj` is frozen.
 * @exception   rb_eIOError      `obj` is closed.
 * @post        `fp` holds `obj`'s underlying IO.
 */
#define RB_IO_POINTER(obj,fp) rb_io_check_closed((fp) = RFILE(rb_io_taint_check(obj))->fptr)

/**
 * This is  an old name  of #RB_IO_POINTER.  Not sure  if we want  to deprecate
 * this macro.  There still are tons of usages out there in the wild.
 */
#define GetOpenFile RB_IO_POINTER

/**
 * Fills an IO object.  This makes the best sense when called from inside of an
 * `#initialize`  method  of  a  3rd  party  extension  library  that  inherits
 * ::rb_cIO.
 *
 * If the passed  IO is already opened  for something it first  closes that and
 * opens a new one instead.
 *
 * @param[out]  obj              An IO object to fill in.
 * @param[out]  fp               A variable of type ::rb_io_t.
 * @exception   rb_eTypeError    `obj` is not ::RUBY_T_FILE.
 * @post        `fp` holds `obj`'s underlying IO.
 */
#define RB_IO_OPEN(obj, fp) do {\
    (fp) = rb_io_make_open_file(obj);\
} while (0)

/**
 * This is an old  name of #RB_IO_OPEN.  Not sure if we  want to deprecate this
 * macro.  There still are usages out there in the wild.
 */
#define MakeOpenFile RB_IO_OPEN

/**
 * @private
 *
 * This  is an  implementation  detail  of #RB_IO_OPEN.   People  don't use  it
 * directly.
 *
 * @param[out]  obj              An IO object to fill in.
 * @exception   rb_eTypeError    `obj` is not ::RUBY_T_FILE.
 * @return      `obj`'s backend IO.
 * @post        `obj` is initialised.
 */
rb_io_t *rb_io_make_open_file(VALUE obj);

/**
 * Finds or creates  a stdio's file structure  from a Ruby's one.   This can be
 * handy if you want to call an external API that accepts `FILE *`.
 *
 * @note  Note however, that `FILE`s can  have their own buffer.  Mixing Ruby's
 *        and stdio's file are basically dangerous.  Use with care.
 *
 * @param[in,out]  fptr  Target IO.
 * @return         A stdio's file, created if absent.
 * @post           `fptr` has its corresponding stdio's file.
 *
 * @internal
 *
 * We had rich support  for `FILE` before!  In the days  of 1.8.x ::rb_io_t was
 * like this:
 *
 * ```CXX
 * typedef struct rb_io {
 *     FILE *f;                    // stdio ptr for read/write
 *     FILE *f2;                   // additional ptr for rw pipes
 *     int mode;                   // mode flags
 *     int pid;                    // child's pid (for pipes)
 *     int lineno;                 // number of lines read
 *     char *path;                 // pathname for file
 *     void (*finalize) _((struct rb_io*,int)); // finalize proc
 * } rb_io_t;
 *```
 *
 * But we  eventually abandoned this layout.   It was too difficult.   We could
 * not have fine-grained control over the `f` field.
 *
 * - `FILE` tends  to be  an opaque  struct.  It does  not interface  well with
 *   `select(2)` etc.   This makes  IO multiplexing  quite hard.   Using stdio,
 *   there is arguably no portable way to know if `fwrite(3)` blocks.
 *
 * - Nonblocking  mode,  which   is  another  core  concept   that  enables  IO
 *   multiplexing, does not interface with stdio routines at all.
 *
 * - Detection of duplexed IO is also hard for the same reason.
 *
 * - `feof(3)` is not portable.
 *   https://mail.python.org/pipermail/python-dev/2001-January/011390.html
 *
 * - Solaris was a thing  back then.  They could not have  more than 256 `FILE`
 *   structures  at  a  time.   Their   file  descriptors  ware  stored  in  an
 *   `unsigned char`.
 *
 * - It is next to impossible to avoid  SEGV, especially when a thread tries to
 *   `ungetc(3)`-ing from a `FILE` which is `fread(3)`-ed by another one.
 *
 * In short, it is a bad idea to let someone else manage IO buffers, especially
 * someone  you cannot  control.   This still  applies  to extension  libraries
 * methinks.  Ruby doesn't prevent you from  shooting yourself in the foot, but
 * consider yourself warned here.
 */
FILE *rb_io_stdio_file(rb_io_t *fptr);

/**
 * Identical to rb_io_stdio_file(), except it takes file descriptors instead of
 * Ruby's  IO.   It  can  also  be  seen  as  a  compatibility  layer  to  wrap
 * `fdopen(3)`.   Nowadays  all  supporting systems,  including  Windows,  have
 * `fdopen`.  Why not use them.
 *
 * @param[in]  fd                   A file descriptor.
 * @param[in]  modestr              C string, something like `"r+"`.
 * @exception  rb_eSystemCallError  `fdopen` failed for some reason.
 * @return     A stdio's file associated with `fd`.
 * @note       Interpretation of `modestr` depends  on the underlying operating
 *             system.  On  glibc you might  be able  to pass e.g.  `"rm"`, but
 *             that's an extension to POSIX.
 */
FILE *rb_fdopen(int fd, const char *modestr);

/**
 * Maps  a file  mode  string (that  rb_file_open() takes)  into  a mixture  of
 * `FMODE_`        flags.         This       for        instance        returns
 * `FMODE_WRITABLE | FMODE_TRUNC | FMODE_CREATE | FMODE_EXCL` for `"wx"`.
 *
 * @note  You cannot pass this return value to OS provided `open(2)` etc.
 *
 * @param[in]  modestr       File mode, in C's string.
 * @exception  rb_eArgError  `modestr` is broken.
 * @return     A set of flags.
 *
 * @internal
 *
 * rb_io_modestr_fmode() is not a pure function because it raises.
 */
int rb_io_modestr_fmode(const char *modestr);

/**
 * Identical  to rb_io_modestr_fmode(),  except it  returns a  mixture of  `O_`
 * flags.  This for instance returns `O_WRONLY | O_TRUNC | O_CREAT | O_EXCL` for
 * `"wx"`.
 *
 * @param[in]  modestr       File mode, in C's string.
 * @exception  rb_eArgError  `modestr` is broken.
 * @return     A set of flags.
 *
 * @internal
 *
 * rb_io_modestr_oflags() is not a pure function because it raises.
 */
int rb_io_modestr_oflags(const char *modestr);

RBIMPL_ATTR_CONST()
/**
 * Converts an  oflags (that rb_io_modestr_oflags()  returns) to a  fmode (that
 * rb_io_mode_flags() returns).  This is a purely functional operation.
 *
 * @param[in]  oflags  A set of `O_` flags.
 * @return     Corresponding set of `FMODE_` flags.
 */
int rb_io_oflags_fmode(int oflags);

/**
 * Asserts that an IO is opened for writing.
 *
 * @param[in]  fptr         An IO you want to write to.
 * @exception  rb_eIOError  `fptr` is not for writing.
 * @post       Upon successful return `fptr` is ready for writing.
 *
 * @internal
 *
 * The parameter must have been `const rb_io_t *`.
 */
void rb_io_check_writable(rb_io_t *fptr);

/** @alias{rb_io_check_byte_readable} */
void rb_io_check_readable(rb_io_t *fptr);

/**
 * Asserts that an  IO is opened for character-based reading.   A character can
 * be  wider than  a  byte.  Because  of  this  we have  to  buffer reads  from
 * descriptors.  This fiction checks if that is possible.
 *
 * @param[in]  fptr         An IO you want to read characters from.
 * @exception  rb_eIOError  `fptr` is not for reading.
 * @post       Upon successful return `fptr` is ready for reading characters.
 *
 * @internal
 *
 * Unlike  rb_io_check_writable() the  parameter cannot  be `const  rb_io_t *`.
 * Behind the scene this operation flushes  its write buffers.  This is because
 * of OpenSSL.  They mandate this way.
 *
 * @see  "Can I use OpenSSL's SSL library with non-blocking I/O?"
 *        https://www.openssl.org/docs/faq.html
 */
void rb_io_check_char_readable(rb_io_t *fptr);

/**
 * Asserts  that  an IO  is  opened  for  byte-based reading.   Byte-based  and
 * character-based reading operations cannot be mixed at a time.
 *
 * @param[in]  fptr         An IO you want to read characters from.
 * @exception  rb_eIOError  `fptr` is not for reading.
 * @post       Upon successful return `fptr` is ready for reading bytes.
 */
void rb_io_check_byte_readable(rb_io_t *fptr);

/**
 * Destroys the given IO.  Any pending operations are flushed.
 *
 * @note  It makes no sense to call this function from anywhere outside of your
 *        class' ::rb_data_type_struct::dfree.
 *
 * @param[out]  fptr  IO to close.
 * @post        `fptr` is no longer a valid pointer.
 */
int rb_io_fptr_finalize(rb_io_t *fptr);

/**
 * Sets #FMODE_SYNC.
 *
 * @note  There is no way for C extensions to undo this operation.
 *
 * @param[out]  fptr         IO to set the flag.
 * @exception   rb_eIOError  `fptr` is not opened.
 * @post        `fptr` is in sync mode.
 */
void rb_io_synchronized(rb_io_t *fptr);

/**
 * Asserts that the passed IO is initialised.
 *
 * @param[in]  fptr         IO that you expect be initialised.
 * @exception  rb_eIOError  `fptr` is not initialised.
 * @post       `fptr` is initialised.
 */
void rb_io_check_initialized(rb_io_t *fptr);

/**
 * This badly named function asserts that the passed IO is _open_.
 *
 * @param[in]  fptr         An IO
 * @exception  rb_eIOError  `fptr` is closed.
 * @post       `fptr` is open.
 */
void rb_io_check_closed(rb_io_t *fptr);

/**
 * Identical  to rb_io_check_io(),  except it  raises exceptions  on conversion
 * failures.
 *
 * @param[in]  io             Target object.
 * @exception  rb_eTypeError  No implicit conversion to IO.
 * @return     Return value of `obj.to_io`.
 * @see        rb_str_to_str
 * @see        rb_ary_to_ary
 */
VALUE rb_io_get_io(VALUE io);

/**
 * Try converting an object to its  IO representation using its `to_io` method,
 * if any.  If there is no such thing, returns ::RUBY_Qnil.
 *
 * @param[in]  io             Arbitrary ruby object to convert.
 * @exception  rb_eTypeError  `obj.to_io` returned something non-IO.
 * @retval     RUBY_Qnil      No conversion from `obj` to IO defined.
 * @retval     otherwise      Converted IO representation of `obj`.
 * @see        rb_check_array_type
 * @see        rb_check_string_type
 * @see        rb_check_hash_type
 */
VALUE rb_io_check_io(VALUE io);

/**
 * Queries the tied IO  for writing.  An IO can be  duplexed.  Fine.  The thing
 * is,  that characteristics  could  sometimes be  achieved  by the  underlying
 * operating  system (for  instance  a  socket's duplexity  is  by nature)  but
 * sometimes  by us.   Notable example  is a  bidirectional pipe.   Suppose you
 * have:
 *
 * ```ruby
 * fp = IO.popen("-", "r+")
 * ```
 *
 * This pipe  is duplexed (the  `"r+"`).  You can  both read from/write  to it.
 * However your operating system may  or may not implement bidirectional pipes.
 * FreeBSD is one  of such operating systems  known to have one;  OTOH Linux is
 * known  to lack  such  things.   So to  achieve  maximum portability,  Ruby's
 * bidirectional pipes are done  purely in user land.  A pipe  in ruby can have
 * multiple file descriptors; one for reading  and the other for writing.  This
 * API  is to  obtain the  IO port  which corresponds  to the  passed one,  for
 * writing.
 *
 * @param[in]  io  An IO.
 * @return     Its tied IO for writing, if any, or `io` itself otherwise.
 */
VALUE rb_io_get_write_io(VALUE io);

/**
 * Assigns the tied IO for writing.   See rb_io_get_write_io() for what a "tied
 * IO for writing" is.
 *
 * @param[out]  io         An IO.
 * @param[in]   w          Another IO.
 * @retval      RUBY_Qnil  There was no tied IO for writing for `io`.
 * @retval      otherwise  The IO formerly tied to `io`.
 * @post        `io` ties `w` for writing.
 *
 * @internal
 *
 * @shyouhei doesn't  think there is any  needs of this function  for 3rd party
 * extension libraries.
 */
VALUE rb_io_set_write_io(VALUE io, VALUE w);

/**
 * Instructs the OS to put its internal file structure into "nonblocking mode".
 * This is  an in-Kernel concept.   Reading from/writing  to that file  using C
 * function calls would return  -1 with errno set.  However when  it comes to a
 * ruby program,  we hide that error  behind our `IO#read` method.   Ruby level
 * `IO#read` blocks  regardless of this flag.   If you want to  avoid blocking,
 * you should consider using methods like `IO#readpartial`.
 *
 * ```ruby
 * require 'io/nonblock'
 * STDIN.nonblock = true
 * STDIN.gets # blocks.
 * ```
 *
 * As of  writing there is  a room  of this API  in Fiber schedulers.   A Fiber
 * scheduler could be written in a  way its behaviour depends on this property.
 * You  need an  in-depth  understanding  of how  schedulers  work to  properly
 * leverage this, though.
 *
 * @note  Note   however  that   nonblocking-ness  propagates   across  process
 *        boundaries.  You must  really carefully watch your  step when turning
 *        for  instance `stderr`  into nonblock  mode  (it tends  to be  shared
 *        across many  processes).  Also  it is  a complete  disaster to  mix a
 *        nonblocking file and stdio, and `stderr` tends to be under control of
 *        stdio in other processes.
 *
 * @param[out]  fptr  An IO that is to ne nonblocking.
 * @post        Descriptor that `fptr` describes is under nonblocking mode.
 *
 * @internal
 *
 * There  is  `O_NONBLOCK` but  not  `FMODE_NONBLOCK`.   You cannot  atomically
 * create a nonblocking file descriptor using our API.
 */
void rb_io_set_nonblock(rb_io_t *fptr);

/**
 * Returns the path for the given IO.
 *
 */
VALUE rb_io_path(VALUE io);

/**
 * Returns an integer representing the numeric file descriptor for
 * <em>io</em>.
 *
 * @param[in]   io         An IO.
 * @retval      int        A file descriptor.
 */
int rb_io_descriptor(VALUE io);

/**
 * Get the mode of the IO.
 *
 */
int rb_io_mode(VALUE io);

/**
 * This function  breaks down the  option hash that `IO#initialize`  takes into
 * components.   This is  an implementation  detail of  rb_io_extract_modeenc()
 * today.  People prefer that API instead.
 *
 * @param[in]   opt            The hash to decompose.
 * @param[out]  enc_p          Return value buffer.
 * @param[out]  enc2_p         Return value buffer.
 * @param[out]  fmode_p        Return value buffer.
 * @exception   rb_eTypeError  `opt` is broken.
 * @exception   rb_eArgError   Specified encoding does not exist.
 * @retval      1              Components got extracted.
 * @retval      0              Otherwise.
 * @post        `enc_p` is the specified internal encoding.
 * @post        `enc2_p` is the specified external encoding.
 * @post        `fmode_p` is the specified set of `FMODE_` modes.
 */
int rb_io_extract_encoding_option(VALUE opt, rb_encoding **enc_p, rb_encoding **enc2_p, int *fmode_p);

/**
 * This    function    can   be    seen    as    an   extended    version    of
 * rb_io_extract_encoding_option() that  not only concerns the  option hash but
 * also mode string and so on.  This should be mixed with rb_scan_args() like:
 *
 * ```CXX
 * // This method mimics File.new
 * static VALUE
 * your_method(int argc, const VALUE *argv, VALUE self)
 * {
 *     VALUE       f; // file name
 *     VALUE       m; // open mode
 *     VALUE       p; // permission (O_CREAT)
 *     VALUE       k; // keywords
 *     rb_io_enc_t c; // converter
 *     int         oflags;
 *     int         fmode;
 *
 *     int n = rb_scan_args(argc, argv, "12:", &f, &m, &p, &k);
 *     rb_io_extract_modeenc(&m, &p, k, &oflags, &fmode, &c);
 *
 *     // Every local variables declared so far has been properly filled here.
 *    ...
 * }
 * ```
 *
 * @param[in,out]  vmode_p        Pointer to a mode object.
 * @param[in,out]  vperm_p        Pointer to a permission object.
 * @param[in]      opthash        Keyword arguments
 * @param[out]     oflags_p       `O_` flags return buffer.
 * @param[out]     fmode_p        `FMODE_` flags return buffer.
 * @param[out]     convconfig_p   Encoding config return buffer.
 * @exception      rb_eTypeError  Unexpected object (e.g. Time) passed.
 * @exception      rb_eArgError   Contradiction inside of params.
 * @post           `*vmode_p` is a mode object (filled if any).
 * @post           `*vperm_p` is a permission object (filled if any).
 * @post           `*oflags_p` is filled with `O_` flags.
 * @post           `*fmode_p` is filled with `FMODE_` flags.
 * @post           `*convconfig_p` is filled with conversion instructions.
 *
 * @internal
 *
 * ```rbs
 * class File
 *   def initialize: (
 *     (String | int)      path,
 *     ?(String | int)      fmode,
 *     ?(String | int)      perm,
 *     ?mode:              (String | int),
 *     ?flags:             int,
 *     ?external_encoding: (Encoding | String),
 *     ?internal_encoding: (Encoding | String),
 *     ?encoding:          String,
 *     ?textmode:          bool,
 *     ?binmode:           bool,
 *     ?autoclose:         bool,
 *     ?invalid:           :replace,
 *     ?undef:             :replace,
 *     ?replace:           String,
 *     ?fallback:          (Hash | Proc | Method),
 *     ?xml:               (:text | :attr),
 *     ?crlf_newline:      bool,
 *     ?cr_newline:        bool,
 *     ?universal_newline: bool
 *   ) -> void
 * ```
 */
void rb_io_extract_modeenc(VALUE *vmode_p, VALUE *vperm_p, VALUE opthash, int *oflags_p, int *fmode_p, rb_io_enc_t *convconfig_p);

/* :TODO: can this function be __attribute__((warn_unused_result)) or not? */
/**
 * Buffered write to the passed IO.
 *
 * @param[out]  io                   Destination IO.
 * @param[in]   buf                  Contents to go to `io`.
 * @param[in]   size                 Number of bytes of `buf`.
 * @exception   rb_eFrozenError      `io` is frozen.
 * @exception   rb_eIOError          `io` is not open for writing.
 * @exception   rb_eSystemCallError  `writev(2)` failed for some reason.
 * @retval      -1                   Write failed.
 * @retval      otherwise            Number of bytes actually written.
 * @post        `buf` is written to `io`.
 * @note        Partial write  is a thing.   It is a  failure not to  check the
 *              return value.
 */
ssize_t rb_io_bufwrite(VALUE io, const void *buf, size_t size);

//RBIMPL_ATTR_DEPRECATED(("use rb_io_maybe_wait_readable"))
/**
 * Blocks until the passed file descriptor gets readable.
 *
 * @deprecated  We now prefer rb_io_maybe_wait_readable() over this one.
 * @param[in]   fd           The file descriptor to wait.
 * @exception   rb_eIOError  Bad file descriptor.
 * @return      0 or 1 (meaning unclear).
 * @post        `fd` is ready for reading.
 */
int rb_io_wait_readable(int fd);

//RBIMPL_ATTR_DEPRECATED(("use rb_io_maybe_wait_writable"))
/**
 * Blocks until the passed file descriptor gets writable.
 *
 * @deprecated  We now prefer rb_io_maybe_wait_writable() over this one.
 * @param[in]   fd           The file descriptor to wait.
 * @exception   rb_eIOError  Bad file descriptor.
 * @return      0 or 1 (meaning unclear).
 */
int rb_io_wait_writable(int fd);

//RBIMPL_ATTR_DEPRECATED(("use rb_io_wait"))
/**
 * Blocks until the passed file descriptor is ready for the passed events.
 *
 * @deprecated     We now prefer rb_io_maybe_wait() over this one.
 * @param[in]      fd           The file descriptor to wait.
 * @param[in]      events       A set of enum ::rb_io_event_t.
 * @param[in,out]  tv           Timeout.
 * @retval         0            Operation timed out.
 * @retval         -1           `select(2)` failed for some reason.
 * @retval         otherwise    A set of enum ::rb_io_event_t.
 * @note           Depending on your  operating system `tv` might  or might not
 *                 be  updated (POSIX  permits both).   Portable programs  must
 *                 have no assumptions.
 */
int rb_wait_for_single_fd(int fd, int events, struct timeval *tv);

/**
 * Get the timeout associated with the specified io object.
 *
 * @param[in]  io                   An IO object.
 * @retval     RUBY_Qnil            There is no associated timeout.
 * @retval     Otherwise            The timeout value.
 */
VALUE rb_io_timeout(VALUE io);

/**
 * Set the timeout associated with the specified io object. This timeout is
 * used as a best effort timeout to prevent operations from blocking forever.
 *
 * @param[in]  io                   An IO object.
 * @param[in]  timeout              A timeout value. Must respond to #to_f.
 * @
 */
VALUE rb_io_set_timeout(VALUE io, VALUE timeout);

/**
 * Blocks until  the passed IO  is ready for  the passed events.   The "events"
 * here is  a Ruby level  integer, which is  an OR-ed value  of `IO::READABLE`,
 * `IO::WRITable`, and `IO::PRIORITY`.
 *
 * If timeout is `Qnil`, it will use the default timeout as given by
 * `rb_io_timeout(io)`.
 *
 * @param[in]  io                   An IO object to wait.
 * @param[in]  events               See above.
 * @param[in]  timeout              Time, or numeric seconds since UNIX epoch.
 *                                  If Qnil, use the default timeout. If Qfalse
 *                                  or Qundef, wait forever.
 * @exception  rb_eIOError          `io` is not open.
 * @exception  rb_eRangeError       `timeout` is out of range.
 * @exception  rb_eSystemCallError  `select(2)` failed for some reason.
 * @retval     RUBY_Qfalse          Operation timed out.
 * @retval     Otherwise            Actual events reached.
 */
VALUE rb_io_wait(VALUE io, VALUE events, VALUE timeout);

/**
 * Identical to rb_io_wait()  except it additionally takes  previous errno.  If
 * the  passed errno  indicates  for instance  `EINTR`,  this function  returns
 * immediately.  This is expected to be called in a loop.
 *
 * ```CXX
 * while (true) {
 *
 *     ... // Your interesting operation here
 *         // `errno` could be updated
 *
 *     rb_io_maybe_wait(errno, io, ev, Qnil);
 * }
 * ```
 *
 * On timeout, ::RUBY_Qfalse is returned. Unless you are specifically handling
 * the timeouts, you should typically raise ::rb_eIOTimeoutError in this case.
 *
 * @param[in]  error                System errno.
 * @param[in]  io                   An IO object to wait.
 * @param[in]  events               An integer set of interests.
 * @param[in]  timeout              Time, or numeric seconds since UNIX epoch.
 * @exception  rb_eIOError          `io` is not open.
 * @exception  rb_eRangeError       `timeout` is out of range.
 * @exception  rb_eSystemCallError  `select(2)` failed for some reason.
 * @retval     RUBY_Qfalse          Operation timed out.
 * @retval     RUBY_Qnil            Operation failed for some other reason (errno).
 * @retval     Otherwise            Actual events reached.
 *
 */
VALUE rb_io_maybe_wait(int error, VALUE io, VALUE events, VALUE timeout);

/**
 * Blocks until the passed IO is ready for reading, if that makes sense for the
 * passed  errno.  This  is  a  special case  of  rb_io_maybe_wait() that is
 * only concerned with reading and handles the timeout.
 *
 * If you do not want the default timeout handling, consider using
 * ::rb_io_maybe_wait directly.
 *
 * @param[in]  error                System errno.
 * @param[in]  io                   An IO object to wait.
 * @param[in]  timeout              Time, or numeric seconds since UNIX epoch.
 * @exception  rb_eIOError          `io` is not open.
 * @exception  rb_eRangeError       `timeout` is out of range.
 * @exception  rb_eSystemCallError  `select(2)` failed for some reason.
 * @exception  rb_eIOTimeoutError   The wait operation timed out.
 * @retval     Otherwise            Always returns ::RUBY_IO_READABLE.
 */
int rb_io_maybe_wait_readable(int error, VALUE io, VALUE timeout);

/**
 * Blocks until the passed IO is ready for writing, if that makes sense for the
 * passed  errno.  This  is  a  special case  of  rb_io_maybe_wait() that is
 * only concerned with writing, and handles the timeout.
 *
 * If you do not want the default timeout handling, consider using
 * ::rb_io_maybe_wait directly.
 *
 * @param[in]  error                System errno.
 * @param[in]  io                   An IO object to wait.
 * @param[in]  timeout              Time, or numeric seconds since UNIX epoch.
 * @exception  rb_eIOError          `io` is not open.
 * @exception  rb_eRangeError       `timeout` is out of range.
 * @exception  rb_eSystemCallError  `select(2)` failed for some reason.
 * @exception  rb_eIOTimeoutError   The wait operation timed out.
 * @retval     Otherwise            Always returns ::RUBY_IO_WRITABLE.
 */
int rb_io_maybe_wait_writable(int error, VALUE io, VALUE timeout);

/** @cond INTERNAL_MACRO */
/* compatibility for ruby 1.8 and older */
#define rb_io_mode_flags(modestr) [<"rb_io_mode_flags() is obsolete; use rb_io_modestr_fmode()">]
#define rb_io_modenum_flags(oflags) [<"rb_io_modenum_flags() is obsolete; use rb_io_oflags_fmode()">]
/** @endcond */

/**
 * @deprecated  This function  once was a thing  in the old days,  but makes no
 *              sense   any   longer   today.   Exists   here   for   backwards
 *              compatibility only.  You can safely forget about it.
 *
 * @param[in]   obj              Object in question.
 * @exception   rb_eFrozenError  obj is frozen.
 * @return      The passed `obj`
 */
VALUE rb_io_taint_check(VALUE obj);

RBIMPL_ATTR_NORETURN()
/**
 * Utility function to raise ::rb_eEOFError.
 *
 * @exception  rb_eEOFError  End of file situation.
 * @note       It never returns.
 */
void rb_eof_error(void);

/**
 * Blocks until there is a pending read  in the passed IO.  If there already is
 * it just returns.
 *
 * @param[out]  fptr  An IO to wait for reading.
 * @post        The are bytes to be read.
 */
void rb_io_read_check(rb_io_t *fptr);

RBIMPL_ATTR_PURE()
/**
 * Queries if the  passed IO has any pending  reads.  Unlike rb_io_read_check()
 * this doesn't block; has no side effects.
 *
 * @param[in]  fptr  An IO which can have pending reads.
 * @retval     0     The IO is empty.
 * @retval     1     There is something buffered.
 */
int rb_io_read_pending(rb_io_t *fptr);

/**
 * Constructs an instance of ::rb_cStat from the passed information.
 *
 * @param[in]  st  A stat.
 * @return     Allocated new instance of ::rb_cStat.
 */
VALUE rb_stat_new(const struct stat *st);

/* gc.c */

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RUBY_IO_H */
ruby/memory_view.h000064400000025436151732674120010262 0ustar00#ifndef RUBY_MEMORY_VIEW_H                           /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_MEMORY_VIEW_H 1
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @brief      Memory View.
 */

#include "ruby/internal/config.h"

#ifdef STDC_HEADERS
# include <stddef.h>                       /* size_t */
#endif

#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>                    /* ssize_t */
#endif

#include "ruby/internal/attr/pure.h"       /* RBIMPL_ATTR_PURE */
#include "ruby/internal/core/rtypeddata.h" /* rb_data_type_t */
#include "ruby/internal/dllexport.h"       /* RUBY_EXTERN */
#include "ruby/internal/stdbool.h"         /* bool */
#include "ruby/internal/value.h"           /* VALUE */

/**
 * Flags passed to rb_memory_view_get(), then to ::rb_memory_view_get_func_t.
 */
enum ruby_memory_view_flags {
    RUBY_MEMORY_VIEW_SIMPLE            = 0,
    RUBY_MEMORY_VIEW_WRITABLE          = (1<<0),
    RUBY_MEMORY_VIEW_FORMAT            = (1<<1),
    RUBY_MEMORY_VIEW_MULTI_DIMENSIONAL = (1<<2),
    RUBY_MEMORY_VIEW_STRIDES           = (1<<3) | RUBY_MEMORY_VIEW_MULTI_DIMENSIONAL,
    RUBY_MEMORY_VIEW_ROW_MAJOR         = (1<<4) | RUBY_MEMORY_VIEW_STRIDES,
    RUBY_MEMORY_VIEW_COLUMN_MAJOR      = (1<<5) | RUBY_MEMORY_VIEW_STRIDES,
    RUBY_MEMORY_VIEW_ANY_CONTIGUOUS    = RUBY_MEMORY_VIEW_ROW_MAJOR | RUBY_MEMORY_VIEW_COLUMN_MAJOR,
    RUBY_MEMORY_VIEW_INDIRECT          = (1<<6) | RUBY_MEMORY_VIEW_STRIDES,
};

/** Memory view component metadata. */
typedef struct {
    /** @see ::rb_memory_view_t::format */
    char format;

    /** :FIXME: what is a "native" size is unclear. */
    bool native_size_p;

    /** Endian of the component */
    bool little_endian_p;

    /** The component's offset. */
    size_t offset;

    /** The component's size. */
    size_t size;

    /**
     * How many numbers of components are there. For instance "CCC"'s repeat is
     * 3.
     */
    size_t repeat;
} rb_memory_view_item_component_t;

/**
 * A MemoryView  structure, `rb_memory_view_t`, is used  for exporting objects'
 * MemoryView.
 *
 * This structure contains  the reference of the object, which  is the owner of
 * the MemoryView, the pointer to the head of exported memory, and the metadata
 * that  describes the  structure of  the  memory.  The  metadata can  describe
 * multidimensional arrays with strides.
 */
typedef struct {
    /**
     * The original object that has the memory exported via this memory view.
     */
    VALUE obj;

    /** The pointer to the exported memory. */
    void *data;

    /** The number of bytes in data. */
    ssize_t byte_size;

    /** true for readonly memory, false for writable memory. */
    bool readonly;

    /**
     * A string to describe the format of an element, or NULL for unsigned bytes.
     * The format string is a sequence of the following pack-template specifiers:
     *
     *   c, C, s, s!, S, S!, n, v, i, i!, I, I!, l, l!, L, L!,
     *   N, V, f, e, g, q, q!, Q, Q!, d, E, G, j, J, x
     *
     * For example, "dd" for an element that consists of two double values,
     * and "CCC" for an element that consists of three bytes, such as
     * an RGB color triplet.
     *
     * Also, the value endianness can be explicitly specified by '<' or '>'
     * following a value type specifier.
     *
     * The items are packed contiguously.  When you emulate the alignment of
     * structure members, put '|' at the beginning of the format string,
     * like "|iqc".  On x86_64 Linux ABI, the size of the item by this format
     * is 24 bytes instead of 13 bytes.
     */
    const char *format;

    /**
     * The number of bytes in each element.
     * item_size should equal to rb_memory_view_item_size_from_format(format). */
    ssize_t item_size;

    /** Description of each components. */
    struct {
        /**
         * The array of rb_memory_view_item_component_t that describes the
         * item structure.  rb_memory_view_prepare_item_desc and
         * rb_memory_view_get_item allocate this memory if needed,
         * and rb_memory_view_release frees it. */
        const rb_memory_view_item_component_t *components;

        /** The number of components in an item. */
        size_t length;
    } item_desc;

    /** The number of dimension. */
    ssize_t ndim;

    /**
     * ndim size array indicating the number of elements in each dimension.
     * This can be NULL when ndim == 1. */
    const ssize_t *shape;

    /**
     * ndim size array indicating the number of bytes to skip to go to the
     * next element in each dimension. */
    const ssize_t *strides;

    /**
     * The offset in each dimension when this memory view exposes a nested array.
     * Or, NULL when this memory view exposes a flat array. */
    const ssize_t *sub_offsets;

    /** The private data for managing this exported memory */
    void *private_data;

    /** DO NOT TOUCH THIS: The memory view entry for the internal use */
    const struct rb_memory_view_entry *_memory_view_entry;
} rb_memory_view_t;

/** Type of function of ::rb_memory_view_entry_t::get_func. */
typedef bool (* rb_memory_view_get_func_t)(VALUE obj, rb_memory_view_t *view, int flags);

/** Type of function of ::rb_memory_view_entry_t::release_func. */
typedef bool (* rb_memory_view_release_func_t)(VALUE obj, rb_memory_view_t *view);

/** Type of function of ::rb_memory_view_entry_t::available_p_func. */
typedef bool (* rb_memory_view_available_p_func_t)(VALUE obj);

/** Operations applied to a specific kind of a memory view. */
typedef struct rb_memory_view_entry {
    /**
     * Exports a memory view from a Ruby object.
     */
    rb_memory_view_get_func_t get_func;

    /**
     * Releases   a   memory  view   that   was   previously  generated   using
     * ::rb_memory_view_entry_t::get_func.
     */
    rb_memory_view_release_func_t release_func;

    /**
     * Queries if an object understands memory view protocol.
     */
    rb_memory_view_available_p_func_t available_p_func;
} rb_memory_view_entry_t;

RBIMPL_SYMBOL_EXPORT_BEGIN()

/* memory_view.c */

/**
 * Associates the passed class with the  passed memory view entry.  This has to
 * be called before actually creating a memory view from an instance.
 */
bool rb_memory_view_register(VALUE klass, const rb_memory_view_entry_t *entry);

RBIMPL_ATTR_PURE()
/**
 * Return `true` if the data in the MemoryView `view` is row-major contiguous.
 *
 * Return `false` otherwise.
 */
bool rb_memory_view_is_row_major_contiguous(const rb_memory_view_t *view);

RBIMPL_ATTR_PURE()
/**
 * Return  `true`  if  the  data  in  the  MemoryView  `view`  is  column-major
 * contiguous.
 *
 * Return `false` otherwise.
 */
bool rb_memory_view_is_column_major_contiguous(const rb_memory_view_t *view);

RBIMPL_ATTR_NOALIAS()
/**
 * Fill the  `strides` array  with byte-Strides  of a  contiguous array  of the
 * given shape with the given element size.
 */
void rb_memory_view_fill_contiguous_strides(const ssize_t ndim, const ssize_t item_size, const ssize_t *const shape, const bool row_major_p, ssize_t *const strides);

RBIMPL_ATTR_NOALIAS()
/**
 * Fill the members of `view` as an 1-dimensional byte array.
 */
bool rb_memory_view_init_as_byte_array(rb_memory_view_t *view, VALUE obj, void *data, const ssize_t len, const bool readonly);

/**
 * Deconstructs    the     passed    format    string,    as     describe    in
 * ::rb_memory_view_t::format.
 */
ssize_t rb_memory_view_parse_item_format(const char *format,
                                         rb_memory_view_item_component_t **members,
                                         size_t *n_members, const char **err);

/**
 * Calculate the number of bytes occupied by an element.
 *
 * When the calculation  fails, the failed location in `format`  is stored into
 * `err`, and returns `-1`.
 */
ssize_t rb_memory_view_item_size_from_format(const char *format, const char **err);

/**
 * Calculate the location of the item indicated by the given `indices`.
 *
 * The length of `indices` must equal to `view->ndim`.
 *
 * This function initializes `view->item_desc` if needed.
 */
void *rb_memory_view_get_item_pointer(rb_memory_view_t *view, const ssize_t *indices);

/**
 * Return a value that consists of item members.
 *
 * When an item is a single member, the return value is a single value.
 *
 * When an item consists of multiple members, an array will be returned.
 */
VALUE rb_memory_view_extract_item_members(const void *ptr, const rb_memory_view_item_component_t *members, const size_t n_members);

/** Fill the `item_desc` member of `view`. */
void rb_memory_view_prepare_item_desc(rb_memory_view_t *view);

/** * Return a value that consists of item members in the given memory view. */
VALUE rb_memory_view_get_item(rb_memory_view_t *view, const ssize_t *indices);

/**
 * Return  `true` if  `obj` supports  to export  a MemoryView.   Return `false`
 * otherwise.
 *
 * If   this  function   returns   `true`,  it   doesn't   mean  the   function
 * `rb_memory_view_get` will succeed.
 */
bool rb_memory_view_available_p(VALUE obj);

/**
 * If the given  `obj` supports to export a MemoryView  that conforms the given
 * `flags`, this function fills `view` by the information of the MemoryView and
 * returns `true`.  In this case, the reference count of `obj` is increased.
 *
 * If the  given combination of `obj`  and `flags` cannot export  a MemoryView,
 * this function returns `false`. The content  of `view` is not touched in this
 * case.
 *
 * The exported  MemoryView must  be released by  `rb_memory_view_release` when
 * the MemoryView is no longer needed.
 */
bool rb_memory_view_get(VALUE obj, rb_memory_view_t* memory_view, int flags);

/**
 * Release the  given MemoryView  `view` and decrement  the reference  count of
 * `memory_view->obj`.
 *
 * Consumers must call  this function when the MemoryView is  no longer needed.
 * Missing to call this function leads memory leak.
 */
bool rb_memory_view_release(rb_memory_view_t* memory_view);

/* for testing */
/** @cond INTERNAL_MACRO */
RUBY_EXTERN VALUE rb_memory_view_exported_object_registry;
RUBY_EXTERN const rb_data_type_t rb_memory_view_exported_object_registry_data_type;
/** @endcond */

RBIMPL_SYMBOL_EXPORT_END()

RBIMPL_ATTR_PURE()
/**
 * Return  `true`  if  the  data  in the  MemoryView  `view`  is  row-major  or
 * column-major contiguous.
 *
 * Return `false` otherwise.
 */
static inline bool
rb_memory_view_is_contiguous(const rb_memory_view_t *view)
{
    if (rb_memory_view_is_row_major_contiguous(view)) {
        return true;
    }
    else if (rb_memory_view_is_column_major_contiguous(view)) {
        return true;
    }
    else {
        return false;
    }
}

#endif /* RUBY_BUFFER_H */
ruby/thread_native.h000064400000015262151732674120010531 0ustar00#ifndef RUBY_THREAD_NATIVE_H                         /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_THREAD_NATIVE_H 1
/**
 * @file
 * @author     $Author: ko1 $
 * @date       Wed May 14 19:37:31 2014
 * @copyright  Copyright (C) 2014 Yukihiro Matsumoto
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 *
 * This file contains wrapper APIs for native thread primitives
 * which Ruby interpreter uses.
 *
 * Now, we only support pthread and Windows threads.
 *
 * If you want to use Ruby's Mutex and so on to synchronize Ruby Threads,
 * please use Mutex directly.
 */

#if defined(_WIN32)
#include <windows.h>
typedef HANDLE rb_nativethread_id_t;

typedef union rb_thread_lock_union {
    HANDLE mutex;
    CRITICAL_SECTION crit;
} rb_nativethread_lock_t;

struct rb_thread_cond_struct {
    struct cond_event_entry *next;
    struct cond_event_entry *prev;
};

typedef struct rb_thread_cond_struct rb_nativethread_cond_t;

#elif defined(HAVE_PTHREAD_H)

#include <pthread.h>
typedef pthread_t rb_nativethread_id_t;
typedef pthread_mutex_t rb_nativethread_lock_t;
typedef pthread_cond_t rb_nativethread_cond_t;

#elif defined(__wasi__) // no-thread platforms

typedef struct rb_nativethread_id_t *rb_nativethread_id_t;
typedef struct rb_nativethread_lock_t *rb_nativethread_lock_t;
typedef struct rb_nativethread_cond_t *rb_nativethread_cond_t;

#elif defined(__DOXYGEN__)

/** Opaque type that holds an ID of a native thread. */
struct rb_nativethread_id_t;

/** Opaque type that holds a lock. */
struct rb_nativethread_lock_t;

/** Opaque type that holds a condition variable. */
struct rb_nativethread_cond_t;

#else
#error "unsupported thread type"

#endif

RBIMPL_SYMBOL_EXPORT_BEGIN()

/**
 * Queries the ID of the native thread that is calling this function.
 *
 * @return The caller thread's native ID.
 */
rb_nativethread_id_t rb_nativethread_self(void);

/**
 * Fills the passed lock with an initial value.
 *
 * @param[out]  lock  A mutex to initialise.
 * @post        `lock` is updated to its initial state.
 *
 * @internal
 *
 * There is no data structure that  analogous to pthread_once_t in ruby.  It is
 * pretty  much tricky  (if  not  impossible) to  properly  initialise a  mutex
 * exactly once.
 */
void rb_nativethread_lock_initialize(rb_nativethread_lock_t *lock);

/**
 * Destroys the passed mutex.
 *
 * @param[out]  lock  A mutex to kill.
 * @post        `lock` is no longer eligible for other functions.
 *
 * @internal
 *
 * It  is  an  undefined  behaviour  (see  `pthread_mutex_destroy(3posix)`)  to
 * destroy a locked  mutex.  So it has  to be unlocked.  But  an unlocked mutex
 * can of course  be locked by another thread.  That's  the ultimate reason why
 * we do mutex.   There is an inevitable race condition  here.  2017 edition of
 * IEEE 1003.1 issue 7 says in its  rationale that "care must be taken".  Care?
 * How?
 *
 * @shyouhei thinks that POSIX is broken by design.
 */
void rb_nativethread_lock_destroy(rb_nativethread_lock_t *lock);

/**
 * Blocks until the current thread obtains a lock.
 *
 * @param[out]  lock  A mutex to lock.
 * @post        `lock` is owned by the current native thread.
 */
void rb_nativethread_lock_lock(rb_nativethread_lock_t *lock);

/**
 * Releases a lock.
 *
 * @param[out]  lock  A mutex to unlock.
 * @pre         `lock` is owned by the current native thread.
 * @post        `lock` is not owned by the current native thread.
 */
void rb_nativethread_lock_unlock(rb_nativethread_lock_t *lock);

/** @alias{rb_nativethread_lock_lock} */
void rb_native_mutex_lock(rb_nativethread_lock_t *lock);

/**
 * Identical  to  rb_native_mutex_lock(),  except  it  doesn't  block  in  case
 * rb_native_mutex_lock() would.
 *
 * @param[out]  lock   A mutex to lock.
 * @retval      0      `lock` is successfully owned by the current thread.
 * @retval      EBUSY  `lock` is owned by someone else.
 */
int  rb_native_mutex_trylock(rb_nativethread_lock_t *lock);

/** @alias{rb_nativethread_lock_unlock} */
void rb_native_mutex_unlock(rb_nativethread_lock_t *lock);

/** @alias{rb_nativethread_lock_initialize} */
void rb_native_mutex_initialize(rb_nativethread_lock_t *lock);

/** @alias{rb_nativethread_lock_destroy} */
void rb_native_mutex_destroy(rb_nativethread_lock_t *lock);

/**
 * Signals a condition variable.
 *
 * @param[out]  cond  A condition variable to ping.
 * @post        More than one threads waiting for `cond` gets signalled.
 * @note        This  function   can  spuriously  wake  multiple   threads  up.
 *              `pthread_cond_signal(3posix)` says  it can even  be "impossible
 *              to avoid  the unblocking of more  than one thread blocked  on a
 *              condition variable".  Just brace spurious wakeups.
 */
void rb_native_cond_signal(rb_nativethread_cond_t *cond);

/**
 * Signals a condition variable.
 *
 * @param[out]  cond  A condition variable to ping.
 * @post        All threads waiting for `cond` gets signalled.
 */
void rb_native_cond_broadcast(rb_nativethread_cond_t *cond);

/**
 * Waits for the passed condition variable to be signalled.
 *
 * @param[out]  cond   A condition variable to wait.
 * @param[out]  mutex  A mutex.
 * @pre         `mutex` is owned by the current thread.
 * @post        `mutex` is owned by the current thread.
 * @note        This can wake up spuriously.
 */
void rb_native_cond_wait(rb_nativethread_cond_t *cond, rb_nativethread_lock_t *mutex);

/**
 * Identical to rb_native_cond_wait(), except  it additionally takes timeout in
 * msec resolution.  Timeouts can be detected by catching exceptions.
 *
 * @param[out]  cond                 A condition variable to wait.
 * @param[out]  mutex                A mutex.
 * @param[in]   msec                 Timeout.
 * @exception   rb_eSystemCallError  `Errno::ETIMEDOUT` for timeout.
 * @pre         `mutex` is owned by the current thread.
 * @post        `mutex` is owned by the current thread.
 * @note        This can wake up spuriously.
 */
void rb_native_cond_timedwait(rb_nativethread_cond_t *cond, rb_nativethread_lock_t *mutex, unsigned long msec);

/**
 * Fills the passed condition variable with an initial value.
 *
 * @param[out]  cond  A condition variable to initialise.
 * @post        `cond` is updated to its initial state.
 */
void rb_native_cond_initialize(rb_nativethread_cond_t *cond);

/**
 * Destroys the passed condition variable.
 *
 * @param[out]  cond  A condition variable to kill.
 * @post        `cond` is no longer eligible for other functions.
 */
void rb_native_cond_destroy(rb_nativethread_cond_t *cond);

RBIMPL_SYMBOL_EXPORT_END()
#endif
ruby/util.h000064400000021111151732674120006657 0ustar00#ifndef RUBY_UTIL_H                                  /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_UTIL_H 1
/**
 * @file
 * @author     $Author$
 * @date       Thu Mar  9 11:55:53 JST 1995
 * @copyright  Copyright (C) 1993-2007 Yukihiro Matsumoto
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    DO NOT ADD RANDOM GARBAGES IN  THIS FILE!  Contents of this file
 *             reside here for historical reasons.  Find a right place for your
 *             API!
 */
#include "ruby/internal/config.h"

#ifdef STDC_HEADERS
# include <stddef.h>                       /* size_t */
#endif

#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>                    /* ssize_t */
#endif

#include "ruby/internal/attr/noalias.h"
#include "ruby/internal/attr/nodiscard.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/restrict.h"
#include "ruby/internal/attr/returns_nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/defines.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/** an approximation of ceil(n * log10(2)), up to 1,048,576 (1<<20)
 * without overflow within 32-bit calculation
 */
#define DECIMAL_SIZE_OF_BITS(n) (((n) * 3010 + 9998) / 9999)

/** an approximation of decimal representation size for n-bytes */
#define DECIMAL_SIZE_OF_BYTES(n) DECIMAL_SIZE_OF_BITS((n) * CHAR_BIT)

/**
 * An approximation of decimal representation size. `expr` may be a
 * type name
 */
#define DECIMAL_SIZE_OF(expr) DECIMAL_SIZE_OF_BYTES(sizeof(expr))

/**
 * Character to  number mapping  like `'a'`  -> `10`, `'b'`  -> `11`  etc.  For
 * punctuation etc.,  the value is  -1.  "36"  terminology comes from  the fact
 * that this is the table behind `str.to_i(36)`.
 */
RUBY_EXTERN const signed char ruby_digit36_to_number_table[];

/**
 * Characters that Ruby accepts as hexadecimal digits.  This is `/\h/` expanded
 * into an array.
 */
RUBY_EXTERN const char ruby_hexdigits[];

/**
 * Scans the passed string, assuming the  string is a textual representation of
 * an  integer.  Stops  when encountering  something non-digit  for the  passed
 * base.
 *
 * @note        This does not understand minus sign.
 * @note        This does not understand e.g. `0x` prefix.
 * @note        It is a failure to pass `0` to `base`, unlike ruby_strtoul().
 * @param[in]   str       Target string of digits to interpret.
 * @param[in]   len       Number of bytes of `str`, or -1 to detect `NUL`.
 * @param[in]   base      Base, `2` to `36` inclusive.
 * @param[out]  retlen    Return value buffer.
 * @param[out]  overflow  Return value buffer.
 * @return      Interpreted numeric representation of `str`.
 * @post        `retlen` is the number of bytes scanned so far.
 * @post       `overflow` is  set to  true if  the string  represents something
 *              bigger than  `ULONG_MAX`.  Something meaningful  still returns;
 *              which is the designed belabour of C's unsigned arithmetic.
 */
unsigned long ruby_scan_digits(const char *str, ssize_t len, int base, size_t *retlen, int *overflow);

/** @old{ruby_scan_oct} */
#define scan_oct(s,l,e) ((int)ruby_scan_oct((s),(l),(e)))

RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL(())
/**
 * Interprets  the passed  string as  an  octal unsigned  integer.  Stops  when
 * encounters something not understood.
 *
 * @param[in]   str       C string to scan.
 * @param[in]   len       Length of `str`.
 * @param[out]  consumed  Return value buffer.
 * @return      Parsed integer.
 * @post        `ret` is the number of characters read.
 *
 * @internal
 *
 * No consideration  is made  for integer  overflows.  As  the return  value is
 * unsigned this function  has fully defined behaviour, but you  cannot know if
 * there was an integer wrap-around or not.
 */
unsigned long ruby_scan_oct(const char *str, size_t len, size_t *consumed);

/** @old{ruby_scan_hex} */
#define scan_hex(s,l,e) ((int)ruby_scan_hex((s),(l),(e)))

RBIMPL_ATTR_NONNULL(())
/**
 * Interprets the  passed string  a hexadecimal  unsigned integer.   Stops when
 * encounters something not understood.
 *
 * @param[in]   str  C string to scan.
 * @param[in]   len  Length of `str`.
 * @param[out]  ret  Return value buffer.
 * @return      Parsed integer.
 * @post        `ret` is the number of characters read.
 *
 * @internal
 *
 * No consideration  is made  for integer  overflows.  As  the return  value is
 * unsigned this function  has fully defined behaviour, but you  cannot know if
 * there was an integer wrap-around or not.
 */
unsigned long ruby_scan_hex(const char *str, size_t len, size_t *ret);

/**
 * Reentrant implementation of  quick sort.  If your  system provides something
 * (like  C11 qsort_s),  this is  a thin  wrapper of  that routine.   Otherwise
 * resorts to our own version.
 */
#ifdef HAVE_GNU_QSORT_R
# define ruby_qsort qsort_r
#else
void ruby_qsort(void *, const size_t, const size_t,
                int (*)(const void *, const void *, void *), void *);
#endif

RBIMPL_ATTR_NONNULL((1))
/**
 * Sets  an environment  variable.   In case  of  POSIX this  is  a wrapper  of
 * `setenv(3)`.  But there are systems which lack one.  We try hard emulating.
 *
 * @param[in]  key                  An environment variable.
 * @param[in]  val                  A value to be associated with `key`, or 0.
 * @exception  rb_eSystemCallError  `setenv(3)` failed for some reason.
 * @post       Environment variable  `key` is created if  necessary.  Its value
 *             is updated to be `val`.
 */
void ruby_setenv(const char *key, const char *val);

RBIMPL_ATTR_NONNULL(())
/**
 * Deletes the passed environment variable, if any.
 *
 * @param[in]  key                  An environment variable.
 * @exception  rb_eSystemCallError  `unsetenv(3)` failed for some reason.
 * @post       Environment variable `key` does not exist.
 */
void ruby_unsetenv(const char *key);

RBIMPL_ATTR_NODISCARD()
RBIMPL_ATTR_RESTRICT()
RBIMPL_ATTR_RETURNS_NONNULL()
RBIMPL_ATTR_NONNULL(())
/**
 * This is our  own version of `strdup(3)` that uses  ruby_xmalloc() instead of
 * system malloc (benefits our GC).
 *
 * @param[in]  str  Target C string to duplicate.
 * @return     An allocated C string holding the identical contents.
 * @note       Return value must be discarded using ruby_xfree().
 */
char *ruby_strdup(const char *str);

#undef strdup
/**
 * @alias{ruby_strdup}
 *
 * @internal
 *
 * @shyouhei doesn't  think it  is a wise  idea.  ruby_strdup()'s  return value
 * must be passed to ruby_xfree(), but this macro makes it almost impossible.
 */
#define strdup(s) ruby_strdup(s)

RBIMPL_ATTR_NODISCARD()
RBIMPL_ATTR_RESTRICT()
RBIMPL_ATTR_RETURNS_NONNULL()
/**
 * This is our  own version of `getcwd(3)` that uses  ruby_xmalloc() instead of
 * system malloc (benefits our GC).
 *
 * @return     An allocated C string holding the process working directory.
 * @note       Return value must be discarded using ruby_xfree().
 */
char *ruby_getcwd(void);

RBIMPL_ATTR_NONNULL((1))
/**
 * Our own locale-insensitive  version of `strtod(3)`.  The  conversion is done
 * as if the current locale is set  to the "C" locale, no matter actual runtime
 * locale settings.
 *
 * @param[in]   str     Decimal  or hexadecimal  representation  of a  floating
 *                      point number.
 * @param[out]  endptr  NULL, or an arbitrary pointer (overwritten on return).
 * @return      Converted number.
 * @post        If `endptr` is not NULL, it  is updated to point the first such
 *              byte where conversion failed.
 * @note        This function sets `errno` on failure.
 *                - `ERANGE`: Converted integer is out of range of `double`.
 * @see         William  D.   Clinger,  "How  to Read  Floating  Point  Numbers
 *              Accurately" in Proc.  ACM SIGPLAN '90, pp.  92-101.
 *              https://doi.org/10.1145/93542.93557
 */
double ruby_strtod(const char *str, char **endptr);

#undef strtod
/** @alias{ruby_strtod} */
#define strtod(s,e) ruby_strtod((s),(e))

RBIMPL_ATTR_NONNULL((2))
/**
 * Scans the  passed string, with calling  the callback function every  time it
 * encounters a  "word".  A word  here is a  series of characters  separated by
 * either a space (of IEEE 1003.1 section 7.3.1.1), or a `','`.
 *
 * @param[in]      str   Target string to split into each words.
 * @param[in]      func  Callback function.
 * @param[in,out]  argv  Passed as-is to `func`.
 */
void ruby_each_words(const char *str, void (*func)(const char *word, int len, void *argv), void *argv);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RUBY_UTIL_H */
ruby/debug.h000064400000072443151732674120007006 0ustar00#ifndef RB_DEBUG_H                                   /*-*-C++-*-vi:se ft=cpp:*/
#define RB_DEBUG_H 1
/**
 * @file
 * @author     $Author: ko1 $
 * @date       Tue Nov 20 20:35:08 2012
 * @copyright  Copyright (C) 2012 Yukihiro Matsumoto
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 */
#include "ruby/internal/attr/deprecated.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/returns_nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/event.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/* Note: This file contains experimental APIs. */
/* APIs can be replaced at Ruby 2.0.1 or later */

/**
 * @name Frame-profiling APIs
 *
 * @{
 */

RBIMPL_ATTR_NONNULL((3))
/**
 * Queries mysterious "frame"s of the given range.
 *
 * The returned values are opaque backtrace  pointers, which you are allowed to
 * issue a very  limited set of operations listed below.   Don't call arbitrary
 * ruby methods.
 *
 * @param[in]   start  Start position (0 means the topmost).
 * @param[in]   limit  Number objects of `buff`.
 * @param[out]  buff   Return buffer.
 * @param[out]  lines  Return buffer.
 * @return      Number of objects filled into `buff`.
 * @post        `buff` is filled with backtrace pointers.
 * @post        `lines` is filled with `__LINE__` of each backtraces.
 *
 * @internal
 *
 * @shyouhei  doesn't  like  this  abuse  of  ::VALUE.   It  should  have  been
 * `const struct rb_callable_method_entry_struct *`.
 */
int rb_profile_frames(int start, int limit, VALUE *buff, int *lines);

/**
 * Queries mysterious "frame"s of the given range.
 *
 * A per-thread version of rb_profile_frames().
 * Arguments and return values are the same with rb_profile_frames() with the
 * exception of the first argument _thread_, which accepts the Thread to be
 * profiled/queried.
 *
 * @param[in]   thread The Ruby Thread to be profiled.
 * @param[in]   start  Start position (0 means the topmost).
 * @param[in]   limit  Number objects of `buff`.
 * @param[out]  buff   Return buffer.
 * @param[out]  lines  Return buffer.
 * @return      Number of objects filled into `buff`.
 * @post        `buff` is filled with backtrace pointers.
 * @post        `lines` is filled with `__LINE__` of each backtraces.
 */
int rb_profile_thread_frames(VALUE thread, int start, int limit, VALUE *buff, int *lines);

/**
 * Queries the path of the passed backtrace.
 *
 * @param[in]  frame      What rb_profile_frames() returned.
 * @retval     RUBY_Qnil  The frame is implemented in C etc.
 * @retval     otherwise  Where `frame` is running.
 */
VALUE rb_profile_frame_path(VALUE frame);

/**
 * Identical  to  rb_profile_frame_path(),  except   it  tries  to  expand  the
 * returning  path.   In case  the  path  is  `require`-d from  something  else
 * rb_profile_frame_path() can return relative paths.   This one tries to avoid
 * that.
 *
 * @param[in]  frame      What rb_profile_frames() returned.
 * @retval     "<cfunc>"  The frame is in C.
 * @retval     RUBY_Qnil  Can't infer real path (inside of `eval` etc.).
 * @retval     otherwise  Where `frame` is running.
 */
VALUE rb_profile_frame_absolute_path(VALUE frame);

/**
 * Queries human-readable "label" string.  This is `"<main>"` for the toplevel,
 * `"<compiled>"` for evaluated  ones, method name for methods,  class name for
 * classes.
 *
 * @param[in]  frame         What rb_profile_frames() returned.
 * @retval     RUBY_Qnil     Can't infer the label (C etc.).
 * @retval     "<main>"      The frame is global toplevel.
 * @retval     "<compiled>"  The frame is dynamic.
 * @retval     otherwise     Label of the frame.
 */
VALUE rb_profile_frame_label(VALUE frame);

/**
 * Identical  to rb_profile_frame_label(),  except  it does  not "qualify"  the
 * result.  Consider the following backtrace:
 *
 * ```ruby
 * def bar
 *   caller_locations
 * end
 *
 * def foo
 *   [1].map { bar }.first
 * end
 *
 * obj = foo.first
 * obj.label      # => "block in foo"
 * obj.base_label # => "foo"
 * ```
 *
 * @param[in]  frame         What rb_profile_frames() returned.
 * @retval     RUBY_Qnil     Can't infer the label (C etc.).
 * @retval     "<main>"      The frame is global toplevel.
 * @retval     "<compiled>"  The frame is dynamic.
 * @retval     otherwise     Base label of the frame.
 */
VALUE rb_profile_frame_base_label(VALUE frame);

/**
 * Identical to rb_profile_frame_label(), except it returns a qualified result.
 *
 * @param[in]  frame         What rb_profile_frames() returned.
 * @retval     RUBY_Qnil     Can't infer the label (C etc.).
 * @retval     "<main>"      The frame is global toplevel.
 * @retval     "<compiled>"  The frame is dynamic.
 * @retval     otherwise     Qualified label of the frame.
 *
 * @internal
 *
 * As  of writing  there is  no way  to obtain  this return  value from  a Ruby
 * script.  This may change  in future (it took 8 years  and still no progress,
 * though).
 */
VALUE rb_profile_frame_full_label(VALUE frame);

/**
 * Queries the first  line of the method  of the passed frame  pointer.  Can be
 * handy when for instance a debugger want to display the frame in question.
 *
 * @param[in]  frame      What rb_profile_frames() returned.
 * @retval     RUBY_Qnil  Can't infer the line (C etc.).
 * @retval     otherwise  Line number of the method in question.
 */
VALUE rb_profile_frame_first_lineno(VALUE frame);

/**
 * Queries the class path of the method that the passed frame represents.
 *
 * @param[in]  frame      What rb_profile_frames() returned.
 * @retval     RUBY_Qnil  Can't infer the class (global toplevel etc.).
 * @retval     otherwise  Class path as in rb_class_path().
 */
VALUE rb_profile_frame_classpath(VALUE frame);

/**
 * Queries if the method of the passed frame is a singleton class.
 *
 * @param[in]  frame        What rb_profile_frames() returned.
 * @retval     RUBY_Qtrue   It is a singleton method.
 * @retval     RUBY_Qfalse  Otherwise (normal method/non-method).
 */
VALUE rb_profile_frame_singleton_method_p(VALUE frame);

/**
 * Queries the name of the method of the passed frame.
 *
 * @param[in]  frame      What rb_profile_frames() returned.
 * @retval     RUBY_Qnil  The frame in question is not a method.
 * @retval     otherwise  Name of the method of the frame.
 */
VALUE rb_profile_frame_method_name(VALUE frame);

/**
 * Identical  to  rb_profile_frame_method_name(),  except  it  "qualifies"  the
 * return value with its defining class.
 *
 * @param[in]  frame      What rb_profile_frames() returned.
 * @retval     RUBY_Qnil  The frame in question is not a method.
 * @retval     otherwise  Qualified name of the method of the frame.
 */
VALUE rb_profile_frame_qualified_method_name(VALUE frame);

/** @} */

/**
 * @name Debug inspector APIs
 *
 * @{
 */

/** Opaque struct representing a debug inspector. */
typedef struct rb_debug_inspector_struct rb_debug_inspector_t;

/**
 * Type  of   the  callback   function  passed   to  rb_debug_inspector_open().
 * Inspection  shall happen  only inside  of  them.  The  passed pointers  gets
 * invalidated once after the callback returns.
 *
 * @param[in]      dc    A debug context.
 * @param[in,out]  data  What was passed to rb_debug_inspector_open().
 * @return         What would be the return value of rb_debug_inspector_open().
 */
typedef VALUE (*rb_debug_inspector_func_t)(const rb_debug_inspector_t *dc, void *data);

/**
 * Prepares, executes, then cleans up a debug session.
 *
 * @param[in]      func  A callback to run inside of a debug session.
 * @param[in,out]  data  Passed as-is to `func`.
 * @return         What was returned from `func`.
 */
VALUE rb_debug_inspector_open(rb_debug_inspector_func_t func, void *data);

/**
 * Queries  the backtrace  object  of the  context.   This is  as  if you  call
 * `caller_locations` at the point of debugger.
 *
 * @param[in]  dc  A debug context.
 * @return     An array  of `Thread::Backtrace::Location` which  represents the
 *             current point of execution at `dc`.

 */
VALUE rb_debug_inspector_backtrace_locations(const rb_debug_inspector_t *dc);

/**
 * Queries the current receiver of the passed context's upper frame.
 *
 * @param[in]  dc           A debug context.
 * @param[in]  index        Index of the frame from top to bottom.
 * @exception  rb_eArgError `index` out of range.
 * @return     The current receiver at `index`-th frame.
 */
VALUE rb_debug_inspector_frame_self_get(const rb_debug_inspector_t *dc, long index);

/**
 * Queries the current class of the passed context's upper frame.
 *
 * @param[in]  dc           A debug context.
 * @param[in]  index        Index of the frame from top to bottom.
 * @exception  rb_eArgError `index` out of range.
 * @return     The current class at `index`-th frame.
 */
VALUE rb_debug_inspector_frame_class_get(const rb_debug_inspector_t *dc, long index);

/**
 * Queries the binding of the passed context's upper frame.
 *
 * @param[in]  dc           A debug context.
 * @param[in]  index        Index of the frame from top to bottom.
 * @exception  rb_eArgError `index` out of range.
 * @return     The binding at `index`-th frame.
 */
VALUE rb_debug_inspector_frame_binding_get(const rb_debug_inspector_t *dc, long index);

/**
 * Queries the instruction sequence of the passed context's upper frame.
 *
 * @param[in]  dc           A debug context.
 * @param[in]  index        Index of the frame from top to bottom.
 * @exception  rb_eArgError `index` out of range.
 * @retval     RUBY_Qnil    `index`-th frame is not in Ruby (C etc.).
 * @retval     otherwise    An instance  of `RubyVM::InstructionSequence` which
 *                          represents the  instruction sequence  at `index`-th
 *                          frame.
 */
VALUE rb_debug_inspector_frame_iseq_get(const rb_debug_inspector_t *dc, long index);

/**
 * Queries the depth of the passed context's upper frame.
 *
 * Note that the depth is not same as the frame index because debug_inspector
 * skips some special frames but the depth counts all frames.
 *
 * @param[in]  dc           A debug context.
 * @param[in]  index        Index of the frame from top to bottom.
 * @exception  rb_eArgError `index` out of range.
 * @retval     The depth at `index`-th frame in Integer.
 */
VALUE rb_debug_inspector_frame_depth(const rb_debug_inspector_t *dc, long index);

// A macro to recognize `rb_debug_inspector_frame_depth()` is available or not
#define RB_DEBUG_INSPECTOR_FRAME_DEPTH(dc, index) rb_debug_inspector_frame_depth(dc, index)

/**
 * Return current frmae depth.
 *
 * @retval     The depth of the current frame in Integer.
 */
VALUE rb_debug_inspector_current_depth(void);

/** @} */

/**
 * @name Old style set_trace_func APIs
 *
 * @{
 */

/* duplicated def of include/ruby/ruby.h */
#include "ruby/internal/event.h"

/**
 * Identical to  rb_remove_event_hook(), except it additionally  takes the data
 * argument.  This extra  argument is the same as  that of rb_add_event_hook(),
 * and this function removes the hook which matches both arguments at once.
 *
 * @param[in]  func  A callback.
 * @param[in]  data  What to be passed to `func`.
 * @return     Number of deleted event hooks.
 * @note       As  multiple  events can  share  the  same  `func` it  is  quite
 *             possible for the return value to become more than one.
 */
int rb_remove_event_hook_with_data(rb_event_hook_func_t func, VALUE data);

/**
 * Identical to rb_add_event_hook(), except its effect is limited to the passed
 * thread.  Other threads are not affected by this.
 *
 * @param[in]  thval          An instance of ::rb_cThread.
 * @param[in]  func           A callback.
 * @param[in]  events         A set of events that `func` should run.
 * @param[in]  data           Passed as-is to `func`.
 * @exception  rb_eTypeError  `thval` is not a thread.
 */
void rb_thread_add_event_hook(VALUE thval, rb_event_hook_func_t func, rb_event_flag_t events, VALUE data);

/**
 * Identical to  rb_remove_event_hook(), except it additionally  takes a thread
 * argument.     This   extra    argument   is    the   same    as   that    of
 * rb_thread_add_event_hook(), and this function removes the hook which matches
 * both arguments at once.
 *
 * @param[in]  thval          An instance of ::rb_cThread.
 * @param[in]  func           A callback.
 * @exception  rb_eTypeError  `thval` is not a thread.
 * @return     Number of deleted event hooks.
 * @note       As  multiple  events can  share  the  same  `func` it  is  quite
 *             possible for the return value to become more than one.
 */
int rb_thread_remove_event_hook(VALUE thval, rb_event_hook_func_t func);

/**
 * Identical to rb_thread_remove_event_hook(), except it additionally takes the
 * data  argument.    It  can  also   be  seen   as  a  routine   identical  to
 * rb_remove_event_hook_with_data(), except  it additionally takes  the thread.
 * This function deletes hooks that satisfy all three criteria.
 *
 * @param[in]  thval          An instance of ::rb_cThread.
 * @param[in]  func           A callback.
 * @param[in]  data           What to be passed to `func`.
 * @exception  rb_eTypeError  `thval` is not a thread.
 * @return     Number of deleted event hooks.
 * @note       As  multiple  events can  share  the  same  `func` it  is  quite
 *             possible for the return value to become more than one.
 */
int rb_thread_remove_event_hook_with_data(VALUE thval, rb_event_hook_func_t func, VALUE data);

/** @} */

/**
 * @name TracePoint APIs
 *
 * @{
 */

/**
 * Creates a  tracepoint by  registering a  callback function  for one  or more
 * tracepoint   events.  Once   the  tracepoint   is  created,   you  can   use
 * rb_tracepoint_enable to enable the tracepoint.
 *
 * @param[in]      target_thread_not_supported_yet  Meant   for   picking   the
 *                         thread  in which  the tracepoint  is to  be created.
 *                         However,   current    implementation   ignore   this
 *                         parameter,  tracepoint is  created for  all threads.
 *                         Simply specify Qnil.
 * @param[in]      events  Event(s) to listen to.
 * @param[in]      func    A callback function.
 * @param[in,out]  data    Void  pointer that  will be  passed to  the callback
 *                         function.
 *
 * When the callback function is called, it will be passed 2 parameters:
 *   1. `VALUE  tpval` -  the TracePoint  object from which  trace args  can be
 *      extracted.
 *   1. `void  *data` -  A void  pointer which  helps to  share scope  with the
 *      callback function.
 *
 * It is important to note that you cannot register callbacks for normal events
 * and internal events simultaneously because  they are different purpose.  You
 * can use  any Ruby APIs  (calling methods and so  on) on normal  event hooks.
 * However, in  internal events,  you can  not use any  Ruby APIs  (even object
 * creations).   This is  why we  can't specify  internal events  by TracePoint
 * directly.  Limitations are MRI version specific.
 *
 * Example:
 *
 * ```CXX
 * rb_tracepoint_new(
 *     Qnil,
 *     RUBY_INTERNAL_EVENT_NEWOBJ | RUBY_INTERNAL_EVENT_FREEOBJ,
 *     obj_event_i,
 *     data);
 * ```
 *
 * In this  example, a callback  function `obj_event_i` will be  registered for
 * internal           events          #RUBY_INTERNAL_EVENT_NEWOBJ           and
 * #RUBY_INTERNAL_EVENT_FREEOBJ.
 */
VALUE rb_tracepoint_new(VALUE target_thread_not_supported_yet, rb_event_flag_t events, void (*func)(VALUE, void *), void *data);

/**
 * Starts (enables) trace(s) defined by the passed object.  A TracePoint object
 * does not immediately  take effect on creation.  You have  to explicitly call
 * this API.
 *
 * @param[in]  tpval         An instance of TracePoint.
 * @exception  rb_eArgError  A trace is already running.
 * @return     Undefined value.  Forget this.  It should have returned `void`.
 * @post       Trace(s) defined by `tpval` start.
 */
VALUE rb_tracepoint_enable(VALUE tpval);

/**
 * Stops (disables) an already running instance of TracePoint.
 *
 * @param[in]  tpval  An instance of TracePoint.
 * @return     Undefined value.  Forget this.  It should have returned `void`.
 * @post       Trace(s) defined by `tpval` stop.
 */
VALUE rb_tracepoint_disable(VALUE tpval);

/**
 * Queries if the passed TracePoint is up and running.
 *
 * @param[in]  tpval        An instance of TracePoint.
 * @retval     RUBY_Qtrue   It is.
 * @retval     RUBY_Qfalse  It isn't.
 */
VALUE rb_tracepoint_enabled_p(VALUE tpval);

/**
 * Type  that  represents  a  specific  trace  event.   Roughly  resembles  the
 * tracepoint object that is passed to the block of `TracePoint.new`:
 *
 * ```ruby
 * TracePoint.new(*events) do |obj|
 *   ...                    # ^^^^^  Resembles this object.
 * end
 * ```
 */
typedef struct rb_trace_arg_struct rb_trace_arg_t;

RBIMPL_ATTR_RETURNS_NONNULL()
/**
 * Queries the current event of the passed tracepoint.
 *
 * @param[in]  tpval             An instance of TracePoint.
 * @exception  rb_eRuntimeError  `tpval` is disabled.
 * @return     The current event.
 *
 * @internal
 *
 * `tpval` is  a fake.  There is  only one instance of  ::rb_trace_arg_t at one
 * time.  This function just returns that global variable.
 */
rb_trace_arg_t *rb_tracearg_from_tracepoint(VALUE tpval);

RBIMPL_ATTR_NONNULL(())
/**
 * Queries the event of the passed trace.
 *
 * @param[in]  trace_arg  A trace instance.
 * @return     Its event.
 */
rb_event_flag_t rb_tracearg_event_flag(rb_trace_arg_t *trace_arg);

RBIMPL_ATTR_NONNULL(())
/**
 * Identical to  rb_tracearg_event_flag(), except  it returns  the name  of the
 * event in Ruby's symbol.
 *
 * @param[in]  trace_arg  A trace instance.
 * @return     Its event, in Ruby level Symbol object.
 */
VALUE rb_tracearg_event(rb_trace_arg_t *trace_arg);

RBIMPL_ATTR_NONNULL(())
/**
 * Queries the line of the point where the trace is at.
 *
 * @param[in]  trace_arg  A trace instance.
 * @retval     0          The trace is not at Ruby frame.
 * @return     otherwise  Its line number.
 */
VALUE rb_tracearg_lineno(rb_trace_arg_t *trace_arg);

RBIMPL_ATTR_NONNULL(())
/**
 * Queries the file name of the point where the trace is at.
 *
 * @param[in]  trace_arg  A trace instance.
 * @retval     RUBY_Qnil  The trace is not at Ruby frame.
 * @retval     otherwise  Its path.
 */
VALUE rb_tracearg_path(rb_trace_arg_t *trace_arg);

RBIMPL_ATTR_NONNULL(())
/**
 * Queries the method name of the point where the trace is at.
 *
 * @param[in]  trace_arg  A trace instance.
 * @retval     RUBY_Qnil  There is no method.
 * @retval     otherwise  Its method name, in Ruby level Symbol.
 */
VALUE rb_tracearg_method_id(rb_trace_arg_t *trace_arg);

RBIMPL_ATTR_NONNULL(())
/**
 * Identical  to  rb_tracearg_method_id(), except  it  returns  callee id  like
 * rb_frame_callee().
 *
 * @param[in]  trace_arg  A trace instance.
 * @retval     RUBY_Qnil  There is no method.
 * @retval     otherwise  Its method name, in Ruby level Symbol.
 */
VALUE rb_tracearg_callee_id(rb_trace_arg_t *trace_arg);

RBIMPL_ATTR_NONNULL(())
/**
 * Queries the class that defines the method that the passed trace is at.  This
 * can be different from the class of rb_tracearg_self()'s return value because
 * of inheritance(s).
 *
 * @param[in]  trace_arg  A trace instance.
 * @retval     RUBY_Qnil  There is no method.
 * @retval     otherwise  Its method's class.
 */
VALUE rb_tracearg_defined_class(rb_trace_arg_t *trace_arg);

RBIMPL_ATTR_NONNULL(())
/**
 * Creates a binding object of the point where the trace is at.
 *
 * @param[in]  trace_arg  A trace instance.
 * @retval     RUBY_Qnil  The point has no binding.
 * @retval     otherwise  Its binding.
 *
 * @internal
 *
 * @shyouhei  has  no  idea  on  which situation  shall  this  function  return
 * ::RUBY_Qnil.
 */
VALUE rb_tracearg_binding(rb_trace_arg_t *trace_arg);

RBIMPL_ATTR_NONNULL(())
/**
 * Queries the receiver of the point trace is at.
 *
 * @param[in]  trace_arg  A trace instance.
 * @return     Its receiver.
 */
VALUE rb_tracearg_self(rb_trace_arg_t *trace_arg);

RBIMPL_ATTR_NONNULL(())
/**
 * Queries the return value that the trace represents.
 *
 * @param[in]  trace_arg         A trace instance.
 * @exception  rb_eRuntimeError  The tracing event is not return-related.
 * @return     The return value.
 */
VALUE rb_tracearg_return_value(rb_trace_arg_t *trace_arg);

RBIMPL_ATTR_NONNULL(())
/**
 * Queries the raised exception that the trace represents.
 *
 * @param[in]  trace_arg         A trace instance.
 * @exception  rb_eRuntimeError  The tracing event is not exception-related.
 * @return     The raised exception.
 */
VALUE rb_tracearg_raised_exception(rb_trace_arg_t *trace_arg);

RBIMPL_ATTR_NONNULL(())
/**
 * Queries the allocated/deallocated object that the trace represents.
 *
 * @param[in]  trace_arg         A trace instance.
 * @exception  rb_eRuntimeError  The tracing event is not GC-related.
 * @return     The allocated/deallocated object.
 */
VALUE rb_tracearg_object(rb_trace_arg_t *trace_arg);


/** @} */

/**
 * @name Postponed Job API
 *
 * @{
 */

/*
 * Postponed Job API
 *
 * This API is designed to be called from contexts where it is not safe to run Ruby
 * code (e.g. because they do not hold the GVL or because GC is in progress), and
 * defer a callback to run in a context where it _is_ safe. The primary intended
 * users of this API is for sampling profilers like the "stackprof" gem; these work
 * by scheduling the periodic delivery of a SIGPROF signal, and inside the C-level
 * signal handler, deferring a job to collect a Ruby backtrace when it is next safe
 * to do so.
 *
 * Ruby maintains a small, fixed-size postponed job table. An extension using this
 * API should first call `rb_postponed_job_preregister` to register a callback
 * function in this table and obtain a handle of type `rb_postponed_job_handle_t`
 * to it. Subsequently, the callback can be triggered  by calling
 * `rb_postponed_job_trigger` with that handle, or the `data` associated with the
 * callback function can be changed by calling `rb_postponed_job_preregister` again.
 *
 * Because the postponed job table is quite small (it only has 32 entries on most
 * common systems), extensions should generally only preregister one or two `func`
 * values.
 *
 * Historically, this API provided two functions `rb_postponed_job_register` and
 * `rb_postponed_job_register_one`, which claimed to be fully async-signal-safe and
 * would call back the provided `func` and `data` at an appropriate time. However,
 * these functions were subject to race conditions which could cause crashes when
 * racing with Ruby's internal use of them. These two functions are still present,
 * but are marked as deprecated and have slightly changed semantics:
 *
 * * rb_postponed_job_register now works like rb_postponed_job_register_one i.e.
 *   `func` will only be executed at most one time each time Ruby checks for
 *   interrupts, no matter how many times it is registered
 * * They are also called with the last `data` to be registered, not the first
 *   (which is how rb_postponed_job_register_one previously worked)
 */


/**
 * Type of postponed jobs.
 *
 * @param[in,out]  arg What was passed to `rb_postponed_job_preregister`
 */
typedef void (*rb_postponed_job_func_t)(void *arg);

/**
 * The type of a handle returned from `rb_postponed_job_preregister` and
 * passed to `rb_postponed_job_trigger`
 */
typedef unsigned int rb_postponed_job_handle_t;
#define POSTPONED_JOB_HANDLE_INVALID ((rb_postponed_job_handle_t)UINT_MAX)

/**
 * Pre-registers a func in Ruby's postponed job preregistration table,
 * returning an opaque handle which can be used to trigger the job later. Generally,
 * this function will be called during the initialization routine of an extension.
 *
 * The returned handle can be used later to call `rb_postponed_job_trigger`. This will
 * cause Ruby to call back into the registered `func` with `data` at a later time, in
 * a context where the GVL is held and it is safe to perform Ruby allocations.
 *
 * If the given `func` was already pre-registered, this function will overwrite the
 * stored data with the newly passed data, and return the same handle instance as
 * was previously returned.
 *
 * If this function is called concurrently with the same `func`, then the stored data
 * could be the value from either call (but will definitely be one of them).
 *
 * If this function is called to update the data concurrently with a call to
 * `rb_postponed_job_trigger` on the same handle, it's undefined whether `func` will
 * be called with the old data or the new data.
 *
 * Although the current implementation of this function is in fact async-signal-safe and
 * has defined semantics when called concurrently on the same `func`, a future Ruby
 * version might require that this method be called under the GVL; thus, programs which
 * aim to be forward-compatible should call this method whilst holding the GVL.
 *
 * @param[in]   flags       Unused and ignored
 * @param[in]   func        The function to be pre-registered
 * @param[in]   data        The data to be pre-registered
 * @retval      POSTPONED_JOB_HANDLE_INVALID    The job table is full; this registration
 *                          did not succeed and no further registration will do so for
 *                          the lifetime of the program.
 * @retval      otherwise   A handle which can be passed to `rb_postponed_job_trigger`
 */
rb_postponed_job_handle_t rb_postponed_job_preregister(unsigned int flags, rb_postponed_job_func_t func, void *data);

/**
 * Triggers a pre-registered job registered with rb_postponed_job_preregister,
 * scheduling it for execution the next time the Ruby VM checks for interrupts.
 * The context in which the job is called in holds the GVL and is safe to perform
 * Ruby allocations within (i.e. it is not during GC).
 *
 * This method is async-signal-safe and can be called from any thread, at any
 * time, including in signal handlers.
 *
 * If this method is called multiple times, Ruby will coalesce this into only
 * one call to the job the next time it checks for interrupts.
 *
 * @params[in]  h   A handle returned from rb_postponed_job_preregister
 */
void rb_postponed_job_trigger(rb_postponed_job_handle_t h);

/**
 * Schedules the given `func` to be called with `data` when Ruby next checks for
 * interrupts. If this function is called multiple times in between Ruby checking
 * for interrupts, then `func` will be called only once with the `data` value from
 * the first call to this function.
 *
 * Like `rb_postponed_job_trigger`, the context in which the job is called
 * holds the GVL and can allocate Ruby objects.
 *
 * This method essentially has the same semantics as:
 *
 * ```
 *   rb_postponed_job_trigger(rb_postponed_job_preregister(func, data));
 * ```
 *
 * @note    Previous versions of Ruby promised that the (`func`, `data`) pairs would
 *          be executed as many times as they were registered with this function; in
 *          reality this was always subject to race conditions and this function no
 *          longer provides this guarantee. Instead, multiple calls to this function
 *          can be coalesced into a single execution of the passed `func`, with the
 *          most recent `data` registered at that time passed in.
 *
 * @deprecated  This interface implies that arbitrarily many `func`'s can be enqueued
 *              over the lifetime of the program, whilst in reality the registration
 *              slots for postponed jobs are a finite resource. This is made clearer
 *              by the `rb_postponed_job_preregister` and `rb_postponed_job_trigger`
 *              functions, and a future version of Ruby might delete this function.
 *
 * @param[in]      flags      Unused and ignored.
 * @param[in]      func       Job body.
 * @param[in,out]  data       Passed as-is to `func`.
 * @retval         0          Postponed job registration table is full. Failed.
 * @retval         1          Registration succeeded.
 * @post           The passed job will run on the next interrupt check.
 */
 RBIMPL_ATTR_DEPRECATED(("use rb_postponed_job_preregister and rb_postponed_job_trigger"))
int rb_postponed_job_register(unsigned int flags, rb_postponed_job_func_t func, void *data);

/**
 * Identical to `rb_postponed_job_register`
 *
 * @deprecated  This is deprecated for the same reason as `rb_postponed_job_register`
 *
 * @param[in]      flags      Unused and ignored.
 * @param[in]      func       Job body.
 * @param[in,out]  data       Passed as-is to `func`.
 * @retval         0          Postponed job registration table is full. Failed.
 * @retval         1          Registration succeeded.
 * @post           The passed job will run on the next interrupt check.
 */
 RBIMPL_ATTR_DEPRECATED(("use rb_postponed_job_preregister and rb_postponed_job_trigger"))
int rb_postponed_job_register_one(unsigned int flags, rb_postponed_job_func_t func, void *data);

/** @} */

/**
 * @cond INTERNAL_MACRO
 *
 * Anything  after this  are  intentionally left  undocumented,  to honour  the
 * comment below.
 */

/* undocumented advanced tracing APIs */

typedef enum {
    RUBY_EVENT_HOOK_FLAG_SAFE    = 0x01,
    RUBY_EVENT_HOOK_FLAG_DELETED = 0x02,
    RUBY_EVENT_HOOK_FLAG_RAW_ARG = 0x04
} rb_event_hook_flag_t;

void rb_add_event_hook2(rb_event_hook_func_t func, rb_event_flag_t events, VALUE data, rb_event_hook_flag_t hook_flag);
void rb_thread_add_event_hook2(VALUE thval, rb_event_hook_func_t func, rb_event_flag_t events, VALUE data, rb_event_hook_flag_t hook_flag);

/** @endcond */

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RUBY_DEBUG_H */
ruby/version.h000064400000011413151732674130007374 0ustar00#ifndef RUBY_VERSION_H                               /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_VERSION_H 1
/**
 * @file
 * @author     $Author$
 * @date       Wed May 13 12:56:56 JST 2009
 * @copyright  Copyright (C) 1993-2009 Yukihiro Matsumoto
 * @copyright  Copyright (C) 2000  Network Applied Communication Laboratory, Inc.
 * @copyright  Copyright (C) 2000  Information-technology Promotion Agency, Japan
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 *
 * This file contains only
 * - never-changeable information, and
 * - interfaces accessible from extension libraries.
 *
 * Never try to check RUBY_VERSION_CODE etc in extension libraries,
 * check the features with mkmf.rb instead.
 */

/**
 * @name The origin.
 *
 * These information never change.  Just written here to remember.
 *
 * @{
 */

/** Author of this project. */
#define RUBY_AUTHOR "Yukihiro Matsumoto"

/** Ruby's birth year. */
#define RUBY_BIRTH_YEAR 1993

/** Ruby's birth month. */
#define RUBY_BIRTH_MONTH 2

/** Ruby's birth day. */
#define RUBY_BIRTH_DAY 24

/** @} */

/**
 * @name The API version.
 *
 * API version  is different from  binary version.   These numbers are  for API
 * stability.  When you  have distinct API versions x and  y, you cannot expect
 * codes targeted to x also works for y.
 *
 * However   let   us  repeat   here   that   it's   a   BAD  idea   to   check
 * #RUBY_API_VERSION_CODE form extension libraries.  Different API versions are
 * just different.  There is no such thing like upper compatibility.
 *
 * @{
 */

/**
 * Major version.  This  digit changes sometimes for various  reasons, but that
 * doesn't mean a total rewrite.  Practically  when it comes to API versioning,
 * major and minor version changes are equally catastrophic.
 */
#define RUBY_API_VERSION_MAJOR 3

/**
 * Minor  version.   As of  writing  this  version changes  annually.   Greater
 * version doesn't mean "better"; they just mean years passed.
 */
#define RUBY_API_VERSION_MINOR 4

/**
 * Teeny version.  This digit  is kind of reserved these days.   Kept 0 for the
 * entire 2.x era.  Waiting for future uses.
 */
#define RUBY_API_VERSION_TEENY 0

/**
 * This macro is API versions encoded into a C integer.
 *
 * @note  Use mkmf.
 * @note  Don't rely on it.
 */
#define RUBY_API_VERSION_CODE (RUBY_API_VERSION_MAJOR*10000+RUBY_API_VERSION_MINOR*100+RUBY_API_VERSION_TEENY)

/** @} */

#ifdef RUBY_EXTERN
/* Internal note: this file could be included from verconf.mk _before_
 * generating config.h, on Windows.  The #ifdef above is to trick such
 * situation. */
RBIMPL_SYMBOL_EXPORT_BEGIN()

/**
 * @name Interfaces from extension libraries.
 *
 * Before using these infos, think thrice whether they are really
 * necessary or not, and if the answer was yes, think twice a week
 * later again.
 *
 * @{
 */

/** API versions, in { major, minor, teeny } order.  */
RUBY_EXTERN const int ruby_api_version[3];

/**
 * Stringised version.
 *
 * @note  This is  the runtime version, not  the API version.  For  instance it
 *        was `"2.5.9"` when ::ruby_api_version was `{ 2, 5, 0 }`.
 */
RUBY_EXTERN const char ruby_version[];

/** Date of release, in a C string. */
RUBY_EXTERN const char ruby_release_date[];

/**
 * Target platform identifier, in a C string.
 *
 * @note  Seasoned  UNIX   programmers  should   beware  that   this  "platform
 *        identifier"  is  our invention;  not  always  identical to  so-called
 *        target triplets  that GNU systems  use.  For instance  on @shyouhei's
 *        machine, ::ruby_platform is `"x64_64-linux"` while its target triplet
 *        is `x86_64-pc-linux-gnu`.
 * @note  Note also that we support Windows.
 */
RUBY_EXTERN const char ruby_platform[];

/**
 * This  is a  monotonic  increasing integer  that  describes specific  "patch"
 * level.  You can know the exact changeset your binary is running by this info
 * (and ::ruby_version), unless  this is -1.  -1 means there  is no release yet
 * for the version; ruby is actively developed. 0 means the initial GA version.
 */
RUBY_EXTERN const int  ruby_patchlevel;

/**
 * This is what `ruby -v` prints to the standard error.  Something like:
 * `"ruby 2.5.9p229 (2021-04-05 revision 67829) [x86_64-linux]"`. This doesn't
 * include runtime options like a JIT being enabled.
 */
RUBY_EXTERN const char ruby_description[];

/** Copyright notice. */
RUBY_EXTERN const char ruby_copyright[];

/**
 * This  is just  `"ruby"`  for  us.  But  different  implementations can  have
 * different strings here.
 */
RUBY_EXTERN const char ruby_engine[];

/** @} */

RBIMPL_SYMBOL_EXPORT_END()
#endif

#endif
ruby/thread.h000064400000030445151732674130007164 0ustar00#ifndef RUBY_THREAD_H                                /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_THREAD_H 1
/**
 * @file
 * @author     $Author: matz $
 * @date       Tue Jul 10 17:35:43 JST 2012
 * @copyright  Copyright (C) 2007 Yukihiro Matsumoto
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 */
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/intern/thread.h" /* rb_unblock_function_t */
#include "ruby/internal/dllexport.h"

/**
 * @name Flags for rb_nogvl()
 *
 * @{
 */

/**
 * Passing  this  flag to  rb_nogvl()  prevents  it from  checking  interrupts.
 * Interrupts  can  impact  your  program negatively.   For  instance  consider
 * following callback function:
 *
 * ```CXX
 * static inline int fd; // set elsewhere.
 * static inline auto callback(auto buf) {
 *   auto tmp = ruby_xmalloc(BUFSIZ);
 *   auto ret = ruby_xmalloc(sizeof(ssize_t));  // (a)
 *   auto n = read(fd, tmp, BUFSIZ);            // (b)
 *   memcpy(buf, tmp, n);                       // (c)
 *   memcpy(ret, n, sizeof(n));
 *   ruby_xfree(tmp);
 *   return ret;
 * }
 * ```
 *
 * Here, if it gets interrupted at (a)  or (b), `read(2)` is cancelled and this
 * function leaks memory (which is not a good thing of course, but...).  But if
 * it gets interrupted at (c), where `read(2)` is already done, interruption is
 * way more catastrophic because what was read gets lost.  To reroute this kind
 * of problem you should set this flag.  And check interrupts elsewhere at your
 * own risk.
 */
#define RB_NOGVL_INTR_FAIL       (0x1)

/**
 * Passing  this  flag   to  rb_nogvl()  indicates  that  the   passed  UBF  is
 * async-signal-safe.   An UBF  could  be  async safe,  and  that makes  things
 * simpler.   However async  unsafe UBFs  are just  okay.  If  unsure, you  can
 * safely leave it unspecified.
 *
 * @internal
 *
 * This makes sense only in case of POSIX threads.
 */
#define RB_NOGVL_UBF_ASYNC_SAFE  (0x2)

/**
 * Passing  this  flag   to  rb_nogvl()  indicates  that  the   passed function
 * is safe to offload to a background thread or work pool. In other words, the
 * function is safe to run using a fiber scheduler's `blocking_operation_wait`.
 * hook.
 *
 * If your function depends on thread-local storage, or thread-specific data
 * operations/data structures, you should not set this flag, as
 * these operations may behave differently (or fail) when run in a different
 * thread/context (e.g. unlocking a mutex).
 */
#define RB_NOGVL_OFFLOAD_SAFE  (0x4)

/** @} */

RBIMPL_SYMBOL_EXPORT_BEGIN()

RBIMPL_ATTR_NONNULL((1))
/**
 * (Re-)acquires the GVL.   This manoeuvre makes it possible  for an out-of-GVL
 * routine to one-shot call a ruby method.
 *
 * What this function does:
 *
 *  1. Blocks until it acquires the GVL.
 *  2. Calls the passed function.
 *  3. Releases the GVL.
 *  4. Returns what was returned form the passed function.
 *
 * @param[in]      func   What to call with GVL.
 * @param[in,out]  data1  Passed as-is to `func`.
 * @return         What was returned from `func`.
 * @warning        `func` must not return a Ruby object.  If it did such return
 *                 value would escape from GC's scope; would not be marked.
 * @warning        Global escapes from this  function just yield whatever fatal
 *                 undefined behaviours.   You must make sure  that `func` does
 *                 not   raise,   by   properly   rescuing   everything   using
 *                 e.g. rb_protect().
 * @warning        You  cannot convert  a non-Ruby  thread into  a Ruby  thread
 *                 using this API.  This function  makes sense only from inside
 *                 of a rb_thread_call_without_gvl()'s callback.
 */
void *rb_thread_call_with_gvl(void *(*func)(void *), void *data1);

RBIMPL_ATTR_NONNULL((1))
/**
 * Allows the passed function to run in parallel with other Ruby threads.
 *
 * What this function does:
 *
 *  1. Checks (and handles) pending interrupts.
 *  2. Releases the GVL. (Others can run here in parallel...)
 *  3. Calls the passed function.
 *  4. Blocks until it re-acquires the GVL.
 *  5. Checks interrupts that happened between 2 to 4.
 *
 * In case  other threads  interfaced with  this thread  using rb_thread_kill()
 * etc., the  passed UBF  is additionally called.   See ::rb_unblock_function_t
 * for details.
 *
 * Unlike rb_thread_call_without_gvl2()  this function  also reacts  to signals
 * etc.
 *
 * @param[in]      func   A function to call without GVL.
 * @param[in,out]  data1  Passed as-is to `func`.
 * @param[in]      ubf    An UBF to cancel `func`.
 * @param[in,out]  data2  Passed as-is to `ubf`.
 * @return         What `func` returned, or 0 in case `ubf` cancelled `func`.
 * @warning        You cannot use  most of Ruby C APIs like  calling methods or
 *                 raising exceptions from  any of the functions  passed to it.
 *                 If that  is dead necessary use  rb_thread_call_with_gvl() to
 *                 re-acquire the GVL.
 * @warning        In short, this API is difficult.  @ko1 recommends you to use
 *                 other ways if any.  We lack experiences to use this API.  If
 *                 you  find any  corner cases  etc., please  report it  to the
 *                 devs.
 * @warning        Releasing and re-acquiring the GVL are expensive operations.
 *                 For a short-running `func`, it  might be faster to just call
 *                 `func` with blocking everything  else.  Be sure to benchmark
 *                 your code to see if it is actually worth releasing the GVL.
 */
void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
                                 rb_unblock_function_t *ubf, void *data2);

RBIMPL_ATTR_NONNULL((1))
/**
 * Identical to rb_thread_call_without_gvl(), except it does not interface with
 * signals etc.  As described in  #RB_NOGVL_INTR_FAIL, interrupts can hurt you.
 * In case this function detects an interrupt, it returns immediately.  You can
 * record progress  of your  callback and  check it  after returning  from this
 * function.
 *
 * What this function does:
 *
 *  1. Checks for pending interrupts and if any, just returns.
 *  2. Releases the GVL. (Others can run here in parallel...)
 *  3. Calls the passed function.
 *  4. Blocks until it re-acquires the GVL.
 *
 * @param[in]      func   A function to call without GVL.
 * @param[in,out]  data1  Passed as-is to `func`.
 * @param[in]      ubf    An UBF to cancel `func`.
 * @param[in,out]  data2  Passed as-is to `ubf`.
 * @return         What `func` returned, or 0 in case `func` did not return.
 */
void *rb_thread_call_without_gvl2(void *(*func)(void *), void *data1,
                                  rb_unblock_function_t *ubf, void *data2);

/*
 * XXX: unstable/unapproved - out-of-tree code should NOT not depend
 * on this until it hits Ruby 2.6.1
 */

RBIMPL_ATTR_NONNULL((1))
/**
 * Identical  to  rb_thread_call_without_gvl(),  except it  additionally  takes
 * "flags" that change the behaviour.
 *
 * @param[in]      func   A function to call without GVL.
 * @param[in,out]  data1  Passed as-is to `func`.
 * @param[in]      ubf    An UBF to cancel `func`.
 * @param[in,out]  data2  Passed as-is to `ubf`.
 * @param[in]      flags  Flags.
 * @return         What `func` returned, or 0 in case `func` did not return.
 */
void *rb_nogvl(void *(*func)(void *), void *data1,
               rb_unblock_function_t *ubf, void *data2,
               int flags);

/**
 * @private
 *
 * @deprecated  This macro once was a thing in the old days, but makes no sense
 *              any  longer today.   Exists  here  for backwards  compatibility
 *              only.  You can safely forget about it.
 */
#define RUBY_CALL_WO_GVL_FLAG_SKIP_CHECK_INTS_AFTER 0x01

/**
 * @private
 * @deprecated  It seems even in the old days it made no sense...?
 */
#define RUBY_CALL_WO_GVL_FLAG_SKIP_CHECK_INTS_

/**
 * Declare the current Ruby thread should acquire a dedicated
 * native thread on M:N thread scheduler.
 *
 * If a C extension (or a library which the extension relies on) should
 * keep to run on a native thread (e.g. using thread-local-storage),
 * this function allocates a dedicated native thread for the thread.
 *
 * @return `false` if the thread already running on a dedicated native
 *         thread. Otherwise `true`.
 */
bool rb_thread_lock_native_thread(void);

/**
 * Triggered when a new thread is started.
 *
 * @note       The callback will be called *without* the GVL held.
 */
#define RUBY_INTERNAL_THREAD_EVENT_STARTED    1 << 0

/**
* Triggered when a thread attempt to acquire the GVL.
*
* @note       The callback will be called *without* the GVL held.
*/
#define RUBY_INTERNAL_THREAD_EVENT_READY      1 << 1 /** acquiring GVL */

/**
 * Triggered when a thread successfully acquired the GVL.
 *
 * @note       The callback will be called *with* the GVL held.
 */
#define RUBY_INTERNAL_THREAD_EVENT_RESUMED    1 << 2 /** acquired GVL */

/**
 * Triggered when a thread released the GVL.
 *
 * @note       The callback will be called *without* the GVL held.
 */
#define RUBY_INTERNAL_THREAD_EVENT_SUSPENDED  1 << 3 /** released GVL */

/**
 * Triggered when a thread exits.
 *
 * @note       The callback will be called *without* the GVL held.
 */
#define RUBY_INTERNAL_THREAD_EVENT_EXITED     1 << 4 /** thread terminated */

#define RUBY_INTERNAL_THREAD_EVENT_MASK       0xff /** All Thread events */

typedef struct rb_internal_thread_event_data {
   VALUE thread;
} rb_internal_thread_event_data_t;

typedef void (*rb_internal_thread_event_callback)(rb_event_flag_t event,
              const rb_internal_thread_event_data_t *event_data,
              void *user_data);
typedef struct rb_internal_thread_event_hook rb_internal_thread_event_hook_t;

/**
 * Registers a thread event hook function.
 *
 * @param[in]  func    A callback.
 * @param[in]  events  A set of events that `func` should run.
 * @param[in]  data    Passed as-is to `func`.
 * @return     An opaque pointer to the hook, to unregister it later.
 * @note       This functionality is a noop on Windows and WebAssembly.
 * @note       The callback will be called without the GVL held, except for the
 *             RESUMED event.
 * @note       Callbacks are not guaranteed to be executed on the native threads
 *             that corresponds to the Ruby thread. To identify which Ruby thread
 *             the event refers to, you must use `event_data->thread`.
 * @warning    This function MUST not be called from a thread event callback.
 */
rb_internal_thread_event_hook_t *rb_internal_thread_add_event_hook(
        rb_internal_thread_event_callback func, rb_event_flag_t events,
        void *data);


/**
 * Unregister the passed hook.
 *
 * @param[in]  hook.  The hook to unregister.
 * @return     Whether the hook was found and unregistered.
 * @note       This functionality is a noop on Windows and WebAssembly.
 * @warning    This function MUST not be called from a thread event callback.
*/
bool rb_internal_thread_remove_event_hook(
        rb_internal_thread_event_hook_t * hook);


typedef int rb_internal_thread_specific_key_t;
#define RB_INTERNAL_THREAD_SPECIFIC_KEY_MAX 8
/**
 * Create a key to store thread specific data.
 *
 * These APIs are designed for tools using
 * rb_internal_thread_event_hook APIs.
 *
 * Note that only `RB_INTERNAL_THREAD_SPECIFIC_KEY_MAX` keys
 * can be created. raises `ThreadError` if exceeded.
 *
 * Usage:
 *   // at initialize time:
 *   int tool_key; // gvar
 *   Init_tool() {
 *     tool_key = rb_internal_thread_specific_key_create();
 *   }
 *
 *   // at any timing:
 *   rb_internal_thread_specific_set(thread, tool_key, per_thread_data);
 *   ...
 *   per_thread_data = rb_internal_thread_specific_get(thread, tool_key);
 */
rb_internal_thread_specific_key_t rb_internal_thread_specific_key_create(void);

/**
 * Get thread and tool specific data.
 *
 * This function is async signal safe and thread safe.
 */
void *rb_internal_thread_specific_get(VALUE thread_val, rb_internal_thread_specific_key_t key);

/**
 * Set thread and tool specific data.
 *
 * This function is async signal safe and thread safe.
 */
void rb_internal_thread_specific_set(VALUE thread_val, rb_internal_thread_specific_key_t key, void *data);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RUBY_THREAD_H */
ruby/backward/cxxanyargs.hpp000064400000074055151732674130012227 0ustar00#ifndef RUBY_BACKWARD_CXXANYARGS_HPP                       //-*-C++-*-vi:ft=cpp
#define RUBY_BACKWARD_CXXANYARGS_HPP
/// @file
/// @author     @shyouhei
/// @copyright  This  file  is  a  part   of  the  programming  language  Ruby.
///             Permission  is hereby  granted, to  either redistribute  and/or
///             modify this file, provided that the conditions mentioned in the
///             file COPYING are met.  Consult the file for details.
/// @note       DO NOT  MODERNISE THIS FILE!   As the  file name implies  it is
///             meant to  be a backwards  compatibility shim.  Please  stick to
///             C++ 98 and never use newer features, like `constexpr`.
/// @brief      Provides old prototypes for C++ programs.
#include "ruby/internal/config.h"
#include "ruby/internal/intern/class.h"
#include "ruby/internal/intern/cont.h"
#include "ruby/internal/intern/hash.h"
#include "ruby/internal/intern/proc.h"
#include "ruby/internal/intern/thread.h"
#include "ruby/internal/intern/variable.h"
#include "ruby/internal/intern/vm.h"
#include "ruby/internal/iterator.h"
#include "ruby/internal/method.h"
#include "ruby/internal/value.h"
#include "ruby/internal/variable.h"
#include "ruby/backward/2/stdarg.h"
#include "ruby/st.h"

extern "C++" {

#ifdef HAVE_NULLPTR
#include <cstddef>
#endif

/// @brief  The main namespace.
/// @note   The name  "ruby" might  already be  taken, but that  must not  be a
///         problem because namespaces are allowed to reopen.
namespace ruby {

/// Backwards compatibility layer.
namespace backward {

/// Provides ANYARGS  deprecation warnings.   In C, ANYARGS  means there  is no
/// function prototype.  Literally  anything, even including nothing,  can be a
/// valid ANYARGS.   So passing a  correctly prototyped function pointer  to an
/// ANYARGS-ed  function  parameter is  valid,  at  the  same time  passing  an
/// ANYARGS-ed function pointer to a  granular typed function parameter is also
/// valid.  However on the other hand in C++, ANYARGS doesn't actually mean any
/// number of arguments.   C++'s ANYARGS means _variadic_  number of arguments.
/// This is incompatible with ordinal, correct function prototypes.
///
/// Luckily, function  prototypes being distinct  each other means they  can be
/// overloaded.  We can provide a compatibility layer for older Ruby APIs which
/// used to have ANYARGS.  This namespace includes such attempts.
namespace cxxanyargs {

typedef VALUE type(ANYARGS);      ///< ANYARGS-ed function type.
typedef void void_type(ANYARGS);  ///< ANYARGS-ed function type, void variant.
typedef int int_type(ANYARGS);    ///< ANYARGS-ed function type, int variant.
typedef VALUE onearg_type(VALUE); ///< Single-argumented function type.

/// @name Hooking global variables
/// @{

RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
/// @brief       Define a function-backended global variable.
/// @param[in]   q  Name of the variable.
/// @param[in]   w  Getter function.
/// @param[in]   e  Setter function.
/// @note        Both functions can be nullptr.
/// @see         rb_define_hooked_variable()
/// @deprecated  Use granular typed overload instead.
inline void
rb_define_virtual_variable(const char *q, type *w, void_type *e)
{
    rb_gvar_getter_t *r = reinterpret_cast<rb_gvar_getter_t*>(w);
    rb_gvar_setter_t *t = reinterpret_cast<rb_gvar_setter_t*>(e);
    ::rb_define_virtual_variable(q, r, t);
}

RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
inline void
rb_define_virtual_variable(const char *q, rb_gvar_getter_t *w, void_type *e)
{
    rb_gvar_setter_t *t = reinterpret_cast<rb_gvar_setter_t*>(e);
    ::rb_define_virtual_variable(q, w, t);
}

RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
inline void
rb_define_virtual_variable(const char *q, type *w, rb_gvar_setter_t *e)
{
    rb_gvar_getter_t *r = reinterpret_cast<rb_gvar_getter_t*>(w);
    ::rb_define_virtual_variable(q, r, e);
}

#ifdef HAVE_NULLPTR
inline void
rb_define_virtual_variable(const char *q, rb_gvar_getter_t *w, std::nullptr_t e)
{
    ::rb_define_virtual_variable(q, w, e);
}

RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
inline void
rb_define_virtual_variable(const char *q, type *w, std::nullptr_t e)
{
    rb_gvar_getter_t *r = reinterpret_cast<rb_gvar_getter_t *>(w);
    ::rb_define_virtual_variable(q, r, e);
}

inline void
rb_define_virtual_variable(const char *q, std::nullptr_t w, rb_gvar_setter_t *e)
{
    ::rb_define_virtual_variable(q, w, e);
}

RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
inline void
rb_define_virtual_variable(const char *q, std::nullptr_t w, void_type *e)
{
    rb_gvar_setter_t *r = reinterpret_cast<rb_gvar_setter_t *>(e);
    ::rb_define_virtual_variable(q, w, r);
}
#endif

RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
/// @brief       Define a function-backended global variable.
/// @param[in]   q  Name of the variable.
/// @param[in]   w  Variable storage.
/// @param[in]   e  Getter function.
/// @param[in]   r  Setter function.
/// @note        Both functions can be nullptr.
/// @see         rb_define_virtual_variable()
/// @deprecated  Use granular typed overload instead.
inline void
rb_define_hooked_variable(const char *q, VALUE *w, type *e, void_type *r)
{
    rb_gvar_getter_t *t = reinterpret_cast<rb_gvar_getter_t*>(e);
    rb_gvar_setter_t *y = reinterpret_cast<rb_gvar_setter_t*>(r);
    ::rb_define_hooked_variable(q, w, t, y);
}

RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
inline void
rb_define_hooked_variable(const char *q, VALUE *w, rb_gvar_getter_t *e, void_type *r)
{
    rb_gvar_setter_t *y = reinterpret_cast<rb_gvar_setter_t*>(r);
    ::rb_define_hooked_variable(q, w, e, y);
}

RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
inline void
rb_define_hooked_variable(const char *q, VALUE *w, type *e, rb_gvar_setter_t *r)
{
    rb_gvar_getter_t *t = reinterpret_cast<rb_gvar_getter_t*>(e);
    ::rb_define_hooked_variable(q, w, t, r);
}

#ifdef HAVE_NULLPTR
inline void
rb_define_hooked_variable(const char *q, VALUE *w, rb_gvar_getter_t *e, std::nullptr_t r)
{
    ::rb_define_hooked_variable(q, w, e, r);
}

RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
inline void
rb_define_hooked_variable(const char *q, VALUE *w, type *e, std::nullptr_t r)
{
    rb_gvar_getter_t *y = reinterpret_cast<rb_gvar_getter_t *>(e);
    ::rb_define_hooked_variable(q, w, y, r);
}

inline void
rb_define_hooked_variable(const char *q, VALUE *w, std::nullptr_t e, rb_gvar_setter_t *r)
{
    ::rb_define_hooked_variable(q, w, e, r);
}

RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
inline void
rb_define_hooked_variable(const char *q, VALUE *w, std::nullptr_t e, void_type *r)
{
    rb_gvar_setter_t *y = reinterpret_cast<rb_gvar_setter_t *>(r);
    ::rb_define_hooked_variable(q, w, e, y);
}
#endif

/// @}
/// @name Exceptions and tag jumps
/// @{

// RUBY_CXX_DEPRECATED("by rb_block_call since 1.9")
RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
/// @brief       Old way to implement iterators.
/// @param[in]   q  A function that can yield.
/// @param[in]   w  Passed to `q`.
/// @param[in]   e  What is to be yielded.
/// @param[in]   r  Passed to `e`.
/// @return      The return value of `q`.
/// @note        `e` can be nullptr.
/// @deprecated  This function is obsoleted since  long before 2.x era.  Do not
///              use it any longer.  rb_block_call() is provided instead.
inline VALUE
rb_iterate(onearg_type *q, VALUE w, type *e, VALUE r)
{
    rb_block_call_func_t t = reinterpret_cast<rb_block_call_func_t>(e);
    return backward::rb_iterate_deprecated(q, w, t, r);
}

#ifdef HAVE_NULLPTR
RUBY_CXX_DEPRECATED("by rb_block_call since 1.9")
inline VALUE
rb_iterate(onearg_type *q, VALUE w, std::nullptr_t e, VALUE r)
{
    return backward::rb_iterate_deprecated(q, w, e, r);
}
#endif

RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
/// @brief       Call a method with a block.
/// @param[in]   q  The self.
/// @param[in]   w  The method.
/// @param[in]   e  The # of elems of `r`
/// @param[in]   r  The arguments.
/// @param[in]   t  What is to be yielded.
/// @param[in]   y  Passed to `t`
/// @return      Return value of `q#w(*r,&t)`
/// @note        't' can be nullptr.
/// @deprecated  Use granular typed overload instead.
inline VALUE
rb_block_call(VALUE q, ID w, int e, const VALUE *r, type *t, VALUE y)
{
    rb_block_call_func_t u = reinterpret_cast<rb_block_call_func_t>(t);
    return ::rb_block_call(q, w, e, r, u, y);
}

#ifdef HAVE_NULLPTR
inline VALUE
rb_block_call(VALUE q, ID w, int e, const VALUE *r, std::nullptr_t t, VALUE y)
{
    return ::rb_block_call(q, w, e, r, t, y);
}
#endif

RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
/// @brief       An equivalent of `rescue` clause.
/// @param[in]   q  A function that can raise.
/// @param[in]   w  Passed to `q`.
/// @param[in]   e  A function that cleans-up.
/// @param[in]   r  Passed to `e`.
/// @return      The return value of `q` if  no exception occurs, or the return
///              value of `e` if otherwise.
/// @note        `e` can be nullptr.
/// @see         rb_ensure()
/// @see         rb_rescue2()
/// @see         rb_protect()
/// @deprecated  Use granular typed overload instead.
inline VALUE
rb_rescue(type *q, VALUE w, type *e, VALUE r)
{
    typedef VALUE func1_t(VALUE);
    typedef VALUE func2_t(VALUE, VALUE);
    func1_t *t = reinterpret_cast<func1_t*>(q);
    func2_t *y = reinterpret_cast<func2_t*>(e);
    return ::rb_rescue(t, w, y, r);
}

RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
/// @brief       An equivalent of `rescue` clause.
/// @param[in]   q    A function that can raise.
/// @param[in]   w    Passed to `q`.
/// @param[in]   e    A function that cleans-up.
/// @param[in]   r    Passed to `e`.
/// @param[in]   ...  0-terminated list of subclass of @ref rb_eException.
/// @return      The return value of `q` if  no exception occurs, or the return
///              value of `e` if otherwise.
/// @note        `e` can be nullptr.
/// @see         rb_ensure()
/// @see         rb_rescue()
/// @see         rb_protect()
/// @deprecated  Use granular typed overload instead.
inline VALUE
rb_rescue2(type *q, VALUE w, type *e, VALUE r, ...)
{
    typedef VALUE func1_t(VALUE);
    typedef VALUE func2_t(VALUE, VALUE);
    func1_t *t = reinterpret_cast<func1_t*>(q);
    func2_t *y = reinterpret_cast<func2_t*>(e);
    va_list ap;
    va_start(ap, r);
    VALUE ret = ::rb_vrescue2(t, w, y, r, ap);
    va_end(ap);
    return ret;
}

RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
/// @brief       An equivalent of `ensure` clause.
/// @param[in]   q  A function that can raise.
/// @param[in]   w  Passed to `q`.
/// @param[in]   e  A function that ensures.
/// @param[in]   r  Passed to `e`.
/// @return      The return value of `q`.
/// @note        It makes no sense to pass nullptr to `e`.
/// @see         rb_rescue()
/// @see         rb_rescue2()
/// @see         rb_protect()
/// @deprecated  Use granular typed overload instead.
inline VALUE
rb_ensure(type *q, VALUE w, type *e, VALUE r)
{
    typedef VALUE func1_t(VALUE);
    func1_t *t = reinterpret_cast<func1_t*>(q);
    func1_t *y = reinterpret_cast<func1_t*>(e);
    return ::rb_ensure(t, w, y, r);
}

RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
/// @brief       An equivalent of `Kernel#catch`.
/// @param[in]   q  The "tag" string.
/// @param[in]   w  A function that can throw.
/// @param[in]   e  Passed to `w`.
/// @return      What was thrown.
/// @note        `q` can be a nullptr but makes no sense to pass nullptr to`w`.
/// @see         rb_block_call()
/// @see         rb_protect()
/// @see         rb_rb_catch_obj()
/// @see         rb_rescue()
/// @deprecated  Use granular typed overload instead.
inline VALUE
rb_catch(const char *q, type *w, VALUE e)
{
    rb_block_call_func_t r = reinterpret_cast<rb_block_call_func_t>(w);
    return ::rb_catch(q, r, e);
}

#ifdef HAVE_NULLPTR
inline VALUE
rb_catch(const char *q, std::nullptr_t w, VALUE e)
{
    return ::rb_catch(q, w, e);
}
#endif

RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
/// @brief       An equivalent of `Kernel#catch`.
/// @param[in]   q  The "tag" object.
/// @param[in]   w  A function that can throw.
/// @param[in]   e  Passed to `w`.
/// @return      What was thrown.
/// @note        It makes no sense to pass nullptr to`w`.
/// @see         rb_block_call()
/// @see         rb_protect()
/// @see         rb_rb_catch_obj()
/// @see         rb_rescue()
/// @deprecated  Use granular typed overload instead.
inline VALUE
rb_catch_obj(VALUE q, type *w, VALUE e)
{
    rb_block_call_func_t r = reinterpret_cast<rb_block_call_func_t>(w);
    return ::rb_catch_obj(q, r, e);
}

/// @}
/// @name Procs, Fibers and Threads
/// @{

RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
/// @brief       Creates a rb_cFiber instance.
/// @param[in]   q  The fiber body.
/// @param[in]   w  Passed to `q`.
/// @return      What was allocated.
/// @note        It makes no sense to pass nullptr to`q`.
/// @see         rb_proc_new()
/// @see         rb_thread_create()
/// @deprecated  Use granular typed overload instead.
inline VALUE
rb_fiber_new(type *q, VALUE w)
{
    rb_block_call_func_t e = reinterpret_cast<rb_block_call_func_t>(q);
    return ::rb_fiber_new(e, w);
}

RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
/// @brief       Creates a @ref rb_cProc instance.
/// @param[in]   q  The proc body.
/// @param[in]   w  Passed to `q`.
/// @return      What was allocated.
/// @note        It makes no sense to pass nullptr to`q`.
/// @see         rb_fiber_new()
/// @see         rb_thread_create()
/// @deprecated  Use granular typed overload instead.
inline VALUE
rb_proc_new(type *q, VALUE w)
{
    rb_block_call_func_t e = reinterpret_cast<rb_block_call_func_t>(q);
    return ::rb_proc_new(e, w);
}

RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
/// @brief       Creates a @ref rb_cThread instance.
/// @param[in]   q  The thread body.
/// @param[in]   w  Passed to `q`.
/// @return      What was allocated.
/// @note        It makes no sense to pass nullptr to`q`.
/// @see         rb_proc_new()
/// @see         rb_fiber_new()
/// @deprecated  Use granular typed overload instead.
inline VALUE
rb_thread_create(type *q, void *w)
{
    typedef VALUE ptr_t(void*);
    ptr_t *e = reinterpret_cast<ptr_t*>(q);
    return ::rb_thread_create(e, w);
}

/// @}
/// @name Hash and st_table
/// @{

RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
/// @brief       Iteration over the given table.
/// @param[in]   q  A table to scan.
/// @param[in]   w  A function to iterate.
/// @param[in]   e  Passed to `w`.
/// @retval      0  Always returns 0.
/// @note        It makes no sense to pass nullptr to`w`.
/// @see         st_foreach_check()
/// @see         rb_hash_foreach()
/// @deprecated  Use granular typed overload instead.
inline int
st_foreach(st_table *q, int_type *w, st_data_t e)
{
    st_foreach_callback_func *r =
        reinterpret_cast<st_foreach_callback_func*>(w);
    return ::st_foreach(q, r, e);
}

RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
/// @brief       Iteration over the given table.
/// @param[in]   q  A table to scan.
/// @param[in]   w  A function to iterate.
/// @param[in]   e  Passed to `w`.
/// @retval      0  Successful end of iteration.
/// @retval      1  Element removed during traversing.
/// @note        It makes no sense to pass nullptr to`w`.
/// @see         st_foreach()
/// @deprecated  Use granular typed overload instead.
inline int
st_foreach_check(st_table *q, int_type *w, st_data_t e, st_data_t)
{
    st_foreach_check_callback_func *t =
        reinterpret_cast<st_foreach_check_callback_func*>(w);
    return ::st_foreach_check(q, t, e, 0);
}

RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
/// @brief       Iteration over the given table.
/// @param[in]   q  A table to scan.
/// @param[in]   w  A function to iterate.
/// @param[in]   e  Passed to `w`.
/// @note        It makes no sense to pass nullptr to`w`.
/// @see         st_foreach_check()
/// @deprecated  Use granular typed overload instead.
inline void
st_foreach_safe(st_table *q, int_type *w, st_data_t e)
{
    st_foreach_callback_func *r =
        reinterpret_cast<st_foreach_callback_func*>(w);
    ::st_foreach_safe(q, r, e);
}

RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
/// @brief       Iteration over the given hash.
/// @param[in]   q  A hash to scan.
/// @param[in]   w  A function to iterate.
/// @param[in]   e  Passed to `w`.
/// @note        It makes no sense to pass nullptr to`w`.
/// @see         st_foreach()
/// @deprecated  Use granular typed overload instead.
inline void
rb_hash_foreach(VALUE q, int_type *w, VALUE e)
{
    st_foreach_callback_func *r =
        reinterpret_cast<st_foreach_callback_func*>(w);
    ::rb_hash_foreach(q, r, e);
}

RUBY_CXX_DEPRECATED("Use of ANYARGS in this function is deprecated")
/// @brief       Iteration over each instance variable of the object.
/// @param[in]   q  An object.
/// @param[in]   w  A function to iterate.
/// @param[in]   e  Passed to `w`.
/// @note        It makes no sense to pass nullptr to`w`.
/// @see         st_foreach()
/// @deprecated  Use granular typed overload instead.
inline void
rb_ivar_foreach(VALUE q, int_type *w, VALUE e)
{
    st_foreach_callback_func *r =
        reinterpret_cast<st_foreach_callback_func*>(w);
    ::rb_ivar_foreach(q, r, e);
}

/// @}

/// Driver for *_define_method.  ::rb_define_method function for instance takes
/// a  pointer to  ANYARGS-ed  functions,  which in  fact  varies 18  different
/// prototypes.  We  still need to  preserve ANYARGS  for storages but  why not
/// check  the consistencies  if  possible.   In C++  a  function  has its  own
/// prototype, which  is a compile-time  constant (static type) by  nature.  We
/// can list  up all the  possible input types  and provide warnings  for other
/// cases.  This is such attempt.
namespace define_method {

/// Type of ::rb_f_notimplement().
typedef VALUE notimpl_type(int, const VALUE *, VALUE, VALUE);

/// @brief   Template metaprogramming to generate function prototypes.
/// @tparam  T  Type of method id (`ID` or `const char*` in practice).
/// @tparam  F  Definition driver e.g. ::rb_define_method.
template<typename T, void (*F)(VALUE klass, T mid, type *func, int arity)>
struct driver {

    /// @brief      Defines a method
    /// @tparam     N  Arity of the function.
    /// @tparam     U  The function in question
    template<int N, typename U>
    struct engine {

        /* :TODO: Following deprecation attribute renders tons of warnings (one
         * per  every  method  definitions),  which  is  annoying.   Of  course
         * annoyance is the  core feature of deprecation  warnings...  But that
         * could be  too much,  especially when the  warnings happen  inside of
         * machine-generated programs.   And SWIG  is known  to do  such thing.
         * The new  (granular) API was  introduced in  API version 2.7.   As of
         * this writing the  version is 2.8.  Let's warn this  later, some time
         * during 3.x.   Hopefully codes in  old (ANYARGS-ed) format  should be
         * less than now. */
#if (RUBY_API_VERSION_MAJOR * 100 + RUBY_API_VERSION_MINOR) >= 301
        RUBY_CXX_DEPRECATED("use of ANYARGS is deprecated")
#endif
        /// @copydoc define(VALUE klass, T mid, U func)
        /// @deprecated  Pass correctly typed function instead.
        static inline void
        define(VALUE klass, T mid, type func)
        {
            F(klass, mid, func, N);
        }

        /// @brief      Defines klass#mid as func, whose arity is N.
        /// @param[in]  klass  Where the method lives.
        /// @param[in]  mid    Name of the method to define.
        /// @param[in]  func   Function that implements klass#mid.
        static inline void
        define(VALUE klass, T mid, U func)
        {
            F(klass, mid, reinterpret_cast<type *>(func), N);
        }

        /// @copydoc define(VALUE klass, T mid, U func)
        static inline void
        define(VALUE klass, T mid, notimpl_type func)
        {
            F(klass, mid, reinterpret_cast<type *>(func), N);
        }
    };

    /// @cond INTERNAL_MACRO
    template<int N, bool = false> struct specific : public engine<N, type *> {};
    template<bool b> struct specific<15, b> : public engine<15, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
    template<bool b> struct specific<14, b> : public engine<14, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
    template<bool b> struct specific<13, b> : public engine<13, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
    template<bool b> struct specific<12, b> : public engine<12, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
    template<bool b> struct specific<11, b> : public engine<11, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
    template<bool b> struct specific<10, b> : public engine<10, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
    template<bool b> struct specific< 9, b> : public engine< 9, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
    template<bool b> struct specific< 8, b> : public engine< 8, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
    template<bool b> struct specific< 7, b> : public engine< 7, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
    template<bool b> struct specific< 6, b> : public engine< 6, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
    template<bool b> struct specific< 5, b> : public engine< 5, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
    template<bool b> struct specific< 4, b> : public engine< 4, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE)> {};
    template<bool b> struct specific< 3, b> : public engine< 3, VALUE(*)(VALUE, VALUE, VALUE, VALUE)> {};
    template<bool b> struct specific< 2, b> : public engine< 2, VALUE(*)(VALUE, VALUE, VALUE)> {};
    template<bool b> struct specific< 1, b> : public engine< 1, VALUE(*)(VALUE, VALUE)> {};
    template<bool b> struct specific< 0, b> : public engine< 0, VALUE(*)(VALUE)> {};
    template<bool b> struct specific<-1, b> : public engine<-1, VALUE(*)(int argc, VALUE *argv, VALUE self)> {
        using engine<-1, VALUE(*)(int argc, VALUE *argv, VALUE self)>::define;
        static inline void define(VALUE c, T m, VALUE(*f)(int argc, const VALUE *argv, VALUE self)) { F(c, m, reinterpret_cast<type *>(f), -1); }
    };
    template<bool b> struct specific<-2, b> : public engine<-2, VALUE(*)(VALUE, VALUE)> {};
    /// @endcond
};

/* We could perhaps merge this struct into the one above using variadic
 * template parameters if we could assume C++11, but sadly we cannot. */
/// @copydoc ruby::backward::cxxanyargs::define_method::driver
template<typename T, void (*F)(T mid, type func, int arity)>
struct driver0 {

    /// @brief      Defines a method
    /// @tparam     N  Arity of the function.
    /// @tparam     U  The function in question
    template<int N, typename U>
    struct engine {
        RUBY_CXX_DEPRECATED("use of ANYARGS is deprecated")
        /// @copydoc define(T mid, U func)
        /// @deprecated  Pass correctly typed function instead.
        static inline void
        define(T mid, type func)
        {
            F(mid, func, N);
        }

        /// @brief      Defines Kernel#mid as func, whose arity is N.
        /// @param[in]  mid    Name of the method to define.
        /// @param[in]  func   Function that implements klass#mid.
        static inline void
        define(T mid, U func)
        {
            F(mid, reinterpret_cast<type *>(func), N);
        }

        /// @copydoc define(T mid, U func)
        /// @deprecated  Pass correctly typed function instead.
        static inline void
        define(T mid, notimpl_type func)
        {
            F(mid, reinterpret_cast<type *>(func), N);
        }
    };

    /// @cond INTERNAL_MACRO
    template<int N, bool = false> struct specific : public engine<N, type *> {};
    template<bool b> struct specific<15, b> : public engine<15, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
    template<bool b> struct specific<14, b> : public engine<14, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
    template<bool b> struct specific<13, b> : public engine<13, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
    template<bool b> struct specific<12, b> : public engine<12, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
    template<bool b> struct specific<11, b> : public engine<11, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
    template<bool b> struct specific<10, b> : public engine<10, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
    template<bool b> struct specific< 9, b> : public engine< 9, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
    template<bool b> struct specific< 8, b> : public engine< 8, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
    template<bool b> struct specific< 7, b> : public engine< 7, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
    template<bool b> struct specific< 6, b> : public engine< 6, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
    template<bool b> struct specific< 5, b> : public engine< 5, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE)> {};
    template<bool b> struct specific< 4, b> : public engine< 4, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE)> {};
    template<bool b> struct specific< 3, b> : public engine< 3, VALUE(*)(VALUE, VALUE, VALUE, VALUE)> {};
    template<bool b> struct specific< 2, b> : public engine< 2, VALUE(*)(VALUE, VALUE, VALUE)> {};
    template<bool b> struct specific< 1, b> : public engine< 1, VALUE(*)(VALUE, VALUE)> {};
    template<bool b> struct specific< 0, b> : public engine< 0, VALUE(*)(VALUE)> {};
    template<bool b> struct specific<-1, b> : public engine<-1, VALUE(*)(int argc, VALUE *argv, VALUE self)> {
        using engine<-1, VALUE(*)(int argc, VALUE *argv, VALUE self)>::define;
        static inline void define(T m, VALUE(*f)(int argc, const VALUE *argv, VALUE self)) { F(m, reinterpret_cast<type *>(f), -1); }
    };
    template<bool b> struct specific<-2, b> : public engine<-2, VALUE(*)(VALUE, VALUE)> {};
    /// @endcond
};

struct rb_define_method           : public driver <const char *, ::rb_define_method> {};           ///< Dispatches appropriate driver for ::rb_define_method.
struct rb_define_method_id        : public driver <ID,           ::rb_define_method_id> {};        ///< Dispatches appropriate driver for ::rb_define_method_id.
struct rb_define_private_method   : public driver <const char *, ::rb_define_private_method> {};   ///< Dispatches appropriate driver for ::rb_define_private_method.
struct rb_define_protected_method : public driver <const char *, ::rb_define_protected_method> {}; ///< Dispatches appropriate driver for ::rb_define_protected_method.
struct rb_define_singleton_method : public driver <const char *, ::rb_define_singleton_method> {}; ///< Dispatches appropriate driver for ::rb_define_singleton_method.
struct rb_define_module_function  : public driver <const char *, ::rb_define_module_function> {};  ///< Dispatches appropriate driver for ::rb_define_module_function.
struct rb_define_global_function  : public driver0<const char *, ::rb_define_global_function> {};  ///< Dispatches appropriate driver for ::rb_define_global_function.

/// @brief        Defines klass\#mid.
/// @param        klass  Where the method lives.
/// @copydetails  #rb_define_global_function(mid, func, arity)
#define rb_define_method(klass, mid, func, arity)           ::ruby::backward::cxxanyargs::define_method::rb_define_method::specific<arity>::define(klass, mid, func)

/// @copydoc #rb_define_method(klass, mid, func, arity)
#define rb_define_method_id(klass, mid, func, arity)        ::ruby::backward::cxxanyargs::define_method::rb_define_method_id::specific<arity>::define(klass, mid, func)

/// @brief        Defines klass\#mid and makes it private.
/// @copydetails  #rb_define_method(klass, mid, func, arity)
#define rb_define_private_method(klass, mid, func, arity)   ::ruby::backward::cxxanyargs::define_method::rb_define_private_method::specific<arity>::define(klass, mid, func)

/// @brief        Defines klass\#mid and makes it protected.
/// @copydetails  #rb_define_method
#define rb_define_protected_method(klass, mid, func, arity) ::ruby::backward::cxxanyargs::define_method::rb_define_protected_method::specific<arity>::define(klass, mid, func)

/// @brief        Defines klass.mid.(klass, mid, func, arity)
/// @copydetails  #rb_define_method
#define rb_define_singleton_method(klass, mid, func, arity) ::ruby::backward::cxxanyargs::define_method::rb_define_singleton_method::specific<arity>::define(klass, mid, func)

/// @brief        Defines klass\#mid and makes it a module function.
/// @copydetails  #rb_define_method(klass, mid, func, arity)
#define rb_define_module_function(klass, mid, func, arity)  ::ruby::backward::cxxanyargs::define_method::rb_define_module_function::specific<arity>::define(klass, mid, func)

/// @brief Defines ::rb_mKernel \#mid.
/// @param mid    Name of the defining method.
/// @param func   Implementation of \#mid.
/// @param arity  Arity of \#mid.
#define rb_define_global_function(mid, func, arity)         ::ruby::backward::cxxanyargs::define_method::rb_define_global_function::specific<arity>::define(mid, func)

}}}}}

using namespace ruby::backward::cxxanyargs;
#endif // RUBY_BACKWARD_CXXANYARGS_HPP
ruby/backward/2/r_cast.h000064400000003170151732674130011102 0ustar00#ifndef RUBY_BACKWARD2_R_CAST_H                      /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_BACKWARD2_R_CAST_H
/**
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines old R_CAST
 *
 * Nobody is actively using this macro.
 */
#define R_CAST(st)   (struct st*)
#define RMOVED(obj)  (R_CAST(RMoved)(obj))

#if defined(__GNUC__)
# warning R_CAST and RMOVED are deprecated
#elif defined(_MSC_VER)
# pragma message("warning: R_CAST and RMOVED are deprecated")
#endif
#endif /* RUBY_BACKWARD2_R_CAST_H */
ruby/backward/2/rmodule.h000064400000003631151732674130011300 0ustar00#ifndef RUBY_BACKWARD2_RMODULE_H                     /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_BACKWARD2_RMODULE_H
/**
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Orphan macros.
 *
 * These macros  seems broken since at  least 2011. Nobody (except  ruby itself
 * who is implementing the internals) could have used those macros for a while.
 * Kept public as-is here to keep some theoretical backwards compatibility.
 */
#define RMODULE_IV_TBL(m) RCLASS_IV_TBL(m)
#define RMODULE_CONST_TBL(m) RCLASS_CONST_TBL(m)
#define RMODULE_M_TBL(m) RCLASS_M_TBL(m)
#define RMODULE_SUPER(m) RCLASS_SUPER(m)

#if defined(__GNUC__)
# warning RMODULE_* macros are deprecated
#elif defined(_MSC_VER)
# pragma message("warning: RMODULE_* macros are deprecated")
#endif
#endif /* RUBY_BACKWARD2_RMODULE_H */
ruby/backward/2/long_long.h000064400000005720151732674130011610 0ustar00#ifndef RUBY_BACKWARD2_LONG_LONG_H                   /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_BACKWARD2_LONG_LONG_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines old #LONG_LONG
 *
 * No  known  compiler   that  can  compile  today's  ruby   lacks  long  long.
 * Historically MSVC was  one of such compiler, but it  implemented long long a
 * while  ago  (some  time  back  in  2013).   The  macros  are  for  backwards
 * compatibility only.
 */
#include "ruby/internal/config.h"
#include "ruby/internal/has/warning.h"
#include "ruby/internal/warning_push.h"

#if defined(__DOXYGEN__)
# /** @cond INTERNAL_MACRO */
# define HAVE_LONG_LONG 1
# define HAVE_TRUE_LONG_LONG 1
# /** @endcond */
# /** @deprecated  Just use `long long` directly. */
# define LONG_LONG long long.

#elif RBIMPL_HAS_WARNING("-Wc++11-long-long")
# define HAVE_TRUE_LONG_LONG 1
# define LONG_LONG                           \
    RBIMPL_WARNING_PUSH()                     \
    RBIMPL_WARNING_IGNORED(-Wc++11-long-long) \
    long long                                \
    RBIMPL_WARNING_POP()

#elif RBIMPL_HAS_WARNING("-Wlong-long")
# define HAVE_TRUE_LONG_LONG 1
# define LONG_LONG                     \
    RBIMPL_WARNING_PUSH()               \
    RBIMPL_WARNING_IGNORED(-Wlong-long) \
    long long                          \
    RBIMPL_WARNING_POP()

#elif defined(HAVE_LONG_LONG)
# define HAVE_TRUE_LONG_LONG 1
# define LONG_LONG long long

#elif SIZEOF___INT64 > 0
# define HAVE_LONG_LONG 1
# define LONG_LONG __int64
# undef SIZEOF_LONG_LONG
# define SIZEOF_LONG_LONG SIZEOF___INT64

#else
# error Hello!  Ruby developers believe this message must not happen.
# error If you encounter this message, can you file a bug report?
# error Remember to attach a detailed description of your environment.
# error Thank you!
#endif

#endif /* RBIMPL_BACKWARD2_LONG_LONG_H */
ruby/backward/2/gcc_version_since.h000064400000003555151732674130013320 0ustar00#ifndef RUBY_BACKWARD2_GCC_VERSION_SINCE_H           /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_BACKWARD2_GCC_VERSION_SINCE_H
/**
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines old GCC_VERSION_SINCE
 */
#include "ruby/internal/compiler_since.h"

#ifndef GCC_VERSION_SINCE
#define GCC_VERSION_SINCE(x, y, z) RBIMPL_COMPILER_SINCE(GCC, (x), (y), (z))
#endif

#ifndef GCC_VERSION_BEFORE
#define GCC_VERSION_BEFORE(x, y, z) \
     (RBIMPL_COMPILER_BEFORE(GCC, (x), (y), (z)) || \
     (RBIMPL_COMPILER_IS(GCC)                    && \
    ((RBIMPL_COMPILER_VERSION_MAJOR == (x))      && \
    ((RBIMPL_COMPILER_VERSION_MINOR == (y))      && \
     (RBIMPL_COMPILER_VERSION_PATCH == (z))))))
#endif

#endif /* RUBY_BACKWARD2_GCC_VERSION_SINCE_H */
ruby/backward/2/stdalign.h000064400000003127151732674140011437 0ustar00#ifndef RUBY_BACKWARD2_STDALIGN_H                    /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_BACKWARD2_STDALIGN_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RUBY_ALIGNAS / #RUBY_ALIGNOF
 */
#include "ruby/internal/stdalign.h"

#undef RUBY_ALIGNAS
#undef RUBY_ALIGNOF
#define RUBY_ALIGNAS RBIMPL_ALIGNAS /**< @copydoc RBIMPL_ALIGNAS */
#define RUBY_ALIGNOF RBIMPL_ALIGNOF /**< @copydoc RBIMPL_ALIGNOF */

#endif /* RUBY_BACKWARD2_STDALIGN_H */
ruby/backward/2/limits.h000064400000005763151732674140011143 0ustar00#ifndef RUBY_BACKWARD2_LIMITS_H                      /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_BACKWARD2_LIMITS_H
/**
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Historical shim for `<limits.h>`.
 *
 * The macros in this header file are obsolescent.  Does anyone really need our
 * own definition of `CHAR_BIT` today?
 */
#include "ruby/internal/config.h"

#ifdef HAVE_LIMITS_H
# include <limits.h>
#endif

#include "ruby/backward/2/long_long.h"

#ifndef LONG_MAX
# /* assuming 32bit(2's complement) long */
# define LONG_MAX 2147483647L
#endif

#ifndef LONG_MIN
# define LONG_MIN (-LONG_MAX-1)
#endif

#ifndef CHAR_BIT
# define CHAR_BIT 8
#endif

#ifdef LLONG_MAX
# /* Take that. */
#elif defined(LONG_LONG_MAX)
# define LLONG_MAX  LONG_LONG_MAX
#elif defined(_I64_MAX)
# define LLONG_MAX _I64_MAX
#else
# /* assuming 64bit(2's complement) long long */
# define LLONG_MAX 9223372036854775807LL
#endif

#ifdef LLONG_MIN
# /* Take that. */
#elif defined(LONG_LONG_MIN)
# define LLONG_MIN  LONG_LONG_MIN
#elif defined(_I64_MAX)
# define LLONG_MIN _I64_MIN
#else
# define LLONG_MIN (-LLONG_MAX-1)
#endif

#ifdef SIZE_MAX
# /* Take that. */
#elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG
# define SIZE_MAX ULLONG_MAX
# define SIZE_MIN ULLONG_MIN
#elif SIZEOF_SIZE_T == SIZEOF_LONG
# define SIZE_MAX ULONG_MAX
# define SIZE_MIN ULONG_MIN
#elif SIZEOF_SIZE_T == SIZEOF_INT
# define SIZE_MAX UINT_MAX
# define SIZE_MIN UINT_MIN
#else
# define SIZE_MAX USHRT_MAX
# define SIZE_MIN USHRT_MIN
#endif

#ifdef SSIZE_MAX
# /* Take that. */
#elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG
# define SSIZE_MAX LLONG_MAX
# define SSIZE_MIN LLONG_MIN
#elif SIZEOF_SIZE_T == SIZEOF_LONG
# define SSIZE_MAX LONG_MAX
# define SSIZE_MIN LONG_MIN
#elif SIZEOF_SIZE_T == SIZEOF_INT
# define SSIZE_MAX INT_MAX
# define SSIZE_MIN INT_MIN
#else
# define SSIZE_MAX SHRT_MAX
# define SSIZE_MIN SHRT_MIN
#endif

#endif /* RUBY_BACKWARD2_LIMITS_H */
ruby/backward/2/inttypes.h000064400000010046151732674140011507 0ustar00#ifndef RUBY_BACKWARD2_INTTYPES_H                    /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_BACKWARD2_INTTYPES_H
/**
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      C99 shim for `<inttypes.h>`
 */
#include "ruby/internal/config.h"      /* PRI_LL_PREFIX etc. are here */

#ifdef HAVE_INTTYPES_H
# include <inttypes.h>
#endif

#include "ruby/internal/value.h"       /* PRI_VALUE_PREFIX is here. */

#ifndef PRI_INT_PREFIX
# define PRI_INT_PREFIX ""
#endif

#ifndef PRI_LONG_PREFIX
# define PRI_LONG_PREFIX "l"
#endif

#ifndef PRI_SHORT_PREFIX
# define PRI_SHORT_PREFIX "h"
#endif

#ifdef PRI_64_PREFIX
# /* Take that. */
#elif SIZEOF_LONG == 8
# define PRI_64_PREFIX PRI_LONG_PREFIX
#elif SIZEOF_LONG_LONG == 8
# define PRI_64_PREFIX PRI_LL_PREFIX
#endif

#ifndef PRIdPTR
# define PRIdPTR PRI_PTR_PREFIX"d"
# define PRIiPTR PRI_PTR_PREFIX"i"
# define PRIoPTR PRI_PTR_PREFIX"o"
# define PRIuPTR PRI_PTR_PREFIX"u"
# define PRIxPTR PRI_PTR_PREFIX"x"
# define PRIXPTR PRI_PTR_PREFIX"X"
#endif

#ifndef RUBY_PRI_VALUE_MARK
# define RUBY_PRI_VALUE_MARK "\v"
#endif

#if defined PRIdPTR && !defined PRI_VALUE_PREFIX
# define PRIdVALUE PRIdPTR
# define PRIoVALUE PRIoPTR
# define PRIuVALUE PRIuPTR
# define PRIxVALUE PRIxPTR
# define PRIXVALUE PRIXPTR
# define PRIsVALUE PRIiPTR"" RUBY_PRI_VALUE_MARK
#else
# define PRIdVALUE PRI_VALUE_PREFIX"d"
# define PRIoVALUE PRI_VALUE_PREFIX"o"
# define PRIuVALUE PRI_VALUE_PREFIX"u"
# define PRIxVALUE PRI_VALUE_PREFIX"x"
# define PRIXVALUE PRI_VALUE_PREFIX"X"
# define PRIsVALUE PRI_VALUE_PREFIX"i" RUBY_PRI_VALUE_MARK
#endif

#ifndef PRI_VALUE_PREFIX
# define PRI_VALUE_PREFIX ""
#endif

#ifdef PRI_TIMET_PREFIX
# /* Take that. */
#elif SIZEOF_TIME_T == SIZEOF_INT
# define PRI_TIMET_PREFIX
#elif SIZEOF_TIME_T == SIZEOF_LONG
# define PRI_TIMET_PREFIX "l"
#elif SIZEOF_TIME_T == SIZEOF_LONG_LONG
# define PRI_TIMET_PREFIX PRI_LL_PREFIX
#endif

#ifdef PRI_PTRDIFF_PREFIX
# /* Take that. */
#elif SIZEOF_PTRDIFF_T == SIZEOF_INT
# define PRI_PTRDIFF_PREFIX ""
#elif SIZEOF_PTRDIFF_T == SIZEOF_LONG
# define PRI_PTRDIFF_PREFIX "l"
#elif SIZEOF_PTRDIFF_T == SIZEOF_LONG_LONG
# define PRI_PTRDIFF_PREFIX PRI_LL_PREFIX
#endif

#ifndef PRIdPTRDIFF
# define PRIdPTRDIFF PRI_PTRDIFF_PREFIX"d"
# define PRIiPTRDIFF PRI_PTRDIFF_PREFIX"i"
# define PRIoPTRDIFF PRI_PTRDIFF_PREFIX"o"
# define PRIuPTRDIFF PRI_PTRDIFF_PREFIX"u"
# define PRIxPTRDIFF PRI_PTRDIFF_PREFIX"x"
# define PRIXPTRDIFF PRI_PTRDIFF_PREFIX"X"
#endif

#ifdef PRI_SIZE_PREFIX
# /* Take that. */
#elif SIZEOF_SIZE_T == SIZEOF_INT
# define PRI_SIZE_PREFIX ""
#elif SIZEOF_SIZE_T == SIZEOF_LONG
# define PRI_SIZE_PREFIX "l"
#elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG
# define PRI_SIZE_PREFIX PRI_LL_PREFIX
#endif

#ifndef PRIdSIZE
# define PRIdSIZE PRI_SIZE_PREFIX"d"
# define PRIiSIZE PRI_SIZE_PREFIX"i"
# define PRIoSIZE PRI_SIZE_PREFIX"o"
# define PRIuSIZE PRI_SIZE_PREFIX"u"
# define PRIxSIZE PRI_SIZE_PREFIX"x"
# define PRIXSIZE PRI_SIZE_PREFIX"X"
#endif

#endif /* RUBY_BACKWARD2_INTTYPES_H */
ruby/backward/2/assume.h000064400000005005151732674140011124 0ustar00#ifndef RUBY_BACKWARD2_ASSUME_H                      /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_BACKWARD2_ASSUME_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #ASSUME / #RB_LIKELY / #UNREACHABLE
 */
#include "ruby/internal/config.h"
#include "ruby/internal/assume.h"
#include "ruby/internal/has/builtin.h"

#define ASSUME             RBIMPL_ASSUME             /**< @old{RBIMPL_ASSUME} */
#define UNREACHABLE        RBIMPL_UNREACHABLE()      /**< @old{RBIMPL_UNREACHABLE} */
#define UNREACHABLE_RETURN RBIMPL_UNREACHABLE_RETURN /**< @old{RBIMPL_UNREACHABLE_RETURN} */

/* likely */
#if RBIMPL_HAS_BUILTIN(__builtin_expect)
/**
 * Asserts that the given Boolean expression likely holds.
 *
 * @param  x  An expression that likely holds.
 *
 * @note  Consider this macro carefully.  It has been here since when CPUs were
 *        like  babies,  but  contemporary  processors are  beasts.   They  are
 *        smarter than  mare mortals like  us today.  Their  branch predictions
 *        highly expectedly outperform your use of this macro.
 */
# define RB_LIKELY(x)   (__builtin_expect(!!(x), 1))

/**
 * Asserts that the given Boolean expression likely doesn't hold.
 *
 * @param  x  An expression that likely doesn't hold.
 */
# define RB_UNLIKELY(x) (__builtin_expect(!!(x), 0))
#else
# define RB_LIKELY(x)   (x)
# define RB_UNLIKELY(x) (x)
#endif

#endif /* RUBY_BACKWARD2_ASSUME_H */
ruby/backward/2/stdarg.h000064400000004606151732674140011121 0ustar00#ifndef RUBY_BACKWARD2_STDARG_H                      /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_BACKWARD2_STDARG_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines old #_
 *
 * Nobody should  ever use these  macros any  longer.  No known  compilers lack
 * prototypes today.  It's 21st century.  Just forget them.
 */

#undef _
/**
 * @deprecated  Nobody practically needs this macro any longer.
 * @brief       This was a transition path from K&R to ANSI.
 */
#ifdef HAVE_PROTOTYPES
# define _(args) args
#else
# define _(args) ()
#endif

#undef __
/**
 * @deprecated  Nobody practically needs this macro any longer.
 * @brief       This was a transition path from K&R to ANSI.
 */
#ifdef HAVE_STDARG_PROTOTYPES
# define __(args) args
#else
# define __(args) ()
#endif

/**
 * Functions  declared using  this  macro take  arbitrary arguments,  including
 * void.
 *
 * ```CXX
 * void func(ANYARGS);
 * ```
 *
 * This  was a  necessary  evil when  there  was no  such  thing like  function
 * overloading.  But it  is the 21st century today.  People  generally need not
 * use this.  Just use a granular typed function.
 *
 * @see ruby::backward::cxxanyargs
 */
#ifdef __cplusplus
#define ANYARGS ...
#else
#define ANYARGS
#endif

#endif /* RUBY_BACKWARD2_STDARG_H */
ruby/backward/2/attributes.h000064400000012616151732674140012023 0ustar00#ifndef RUBY_BACKWARD2_ATTRIBUTES_H                  /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_BACKWARD2_ATTRIBUTES_H
/**
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Various attribute-related macros.
 *
 * ### Q&A ###
 *
 * - Q: Why  are the  macros defined  in this  header file  so inconsistent  in
 *      style?
 *
 * - A: Don't know.   Don't blame me.  Backward compatibility is  the key here.
 *      I'm just preserving what they have been.
 */
#include "ruby/internal/config.h"
#include "ruby/internal/attr/alloc_size.h"
#include "ruby/internal/attr/cold.h"
#include "ruby/internal/attr/const.h"
#include "ruby/internal/attr/deprecated.h"
#include "ruby/internal/attr/error.h"
#include "ruby/internal/attr/forceinline.h"
#include "ruby/internal/attr/format.h"
#include "ruby/internal/attr/maybe_unused.h"
#include "ruby/internal/attr/noinline.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/attr/packed_struct.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/attr/restrict.h"
#include "ruby/internal/attr/returns_nonnull.h"
#include "ruby/internal/attr/warning.h"
#include "ruby/internal/has/attribute.h"

/* function attributes */
#undef CONSTFUNC
#define CONSTFUNC(x) RBIMPL_ATTR_CONST() x

#undef PUREFUNC
#define PUREFUNC(x) RBIMPL_ATTR_PURE() x

#undef DEPRECATED
#define DEPRECATED(x) RBIMPL_ATTR_DEPRECATED(("")) x

#undef DEPRECATED_BY
#define DEPRECATED_BY(n,x) RBIMPL_ATTR_DEPRECATED(("by: " # n)) x

#undef DEPRECATED_TYPE
#if defined(__GNUC__)
# define DEPRECATED_TYPE(mesg, decl)                      \
    _Pragma("message \"DEPRECATED_TYPE is deprecated\""); \
    decl RBIMPL_ATTR_DEPRECATED(mseg)
#elif defined(_MSC_VER)
# pragma deprecated(DEPRECATED_TYPE)
# define DEPRECATED_TYPE(mesg, decl)                              \
    __pragma(message(__FILE__"("STRINGIZE(__LINE__)"): warning: " \
                     "DEPRECATED_TYPE is deprecated"))            \
    decl RBIMPL_ATTR_DEPRECATED(mseg)
#else
# define DEPRECATED_TYPE(mesg, decl)                    \
    <-<-"DEPRECATED_TYPE is deprecated"->->
#endif

#undef RUBY_CXX_DEPRECATED
#define RUBY_CXX_DEPRECATED(mseg) RBIMPL_ATTR_DEPRECATED((mseg))

#undef NOINLINE
#define NOINLINE(x) RBIMPL_ATTR_NOINLINE() x

#undef ALWAYS_INLINE
#define ALWAYS_INLINE(x) RBIMPL_ATTR_FORCEINLINE() x

#undef ERRORFUNC
#define ERRORFUNC(mesg, x) RBIMPL_ATTR_ERROR(mesg) x
#if RBIMPL_HAS_ATTRIBUTE(error)
# define HAVE_ATTRIBUTE_ERRORFUNC 1
#endif

#undef WARNINGFUNC
#define WARNINGFUNC(mesg, x) RBIMPL_ATTR_WARNING(mesg) x
#if RBIMPL_HAS_ATTRIBUTE(warning)
# define HAVE_ATTRIBUTE_WARNINGFUNC 1
#endif

/*
  cold attribute for code layout improvements
  RUBY_FUNC_ATTRIBUTE not used because MSVC does not like nested func macros
 */
#undef COLDFUNC
#define COLDFUNC RBIMPL_ATTR_COLD()

#define PRINTF_ARGS(decl, string_index, first_to_check) \
    RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, (string_index), (first_to_check)) \
    decl

#undef RUBY_ATTR_ALLOC_SIZE
#define RUBY_ATTR_ALLOC_SIZE RBIMPL_ATTR_ALLOC_SIZE

#undef RUBY_ATTR_MALLOC
#define RUBY_ATTR_MALLOC RBIMPL_ATTR_RESTRICT()

#undef RUBY_ATTR_RETURNS_NONNULL
#define RUBY_ATTR_RETURNS_NONNULL RBIMPL_ATTR_RETURNS_NONNULL()

#ifndef FUNC_MINIMIZED
#define FUNC_MINIMIZED(x) x
#endif

#ifndef FUNC_UNOPTIMIZED
#define FUNC_UNOPTIMIZED(x) x
#endif

#ifndef RUBY_ALIAS_FUNCTION_TYPE
#define RUBY_ALIAS_FUNCTION_TYPE(type, prot, name, args) \
    FUNC_MINIMIZED(type prot) {return (type)name args;}
#endif

#ifndef RUBY_ALIAS_FUNCTION_VOID
#define RUBY_ALIAS_FUNCTION_VOID(prot, name, args) \
    FUNC_MINIMIZED(void prot) {name args;}
#endif

#ifndef RUBY_ALIAS_FUNCTION
#define RUBY_ALIAS_FUNCTION(prot, name, args) \
    RUBY_ALIAS_FUNCTION_TYPE(VALUE, prot, name, args)
#endif

#undef RUBY_FUNC_NONNULL
#define RUBY_FUNC_NONNULL(n, x) RBIMPL_ATTR_NONNULL(n) x

#undef  NORETURN
#define NORETURN(x) RBIMPL_ATTR_NORETURN() x
#define NORETURN_STYLE_NEW

#undef PACKED_STRUCT
#define PACKED_STRUCT(x) \
    RBIMPL_ATTR_PACKED_STRUCT_BEGIN() x RBIMPL_ATTR_PACKED_STRUCT_END()

#undef PACKED_STRUCT_UNALIGNED
#define PACKED_STRUCT_UNALIGNED(x) \
    RBIMPL_ATTR_PACKED_STRUCT_UNALIGNED_BEGIN() x \
    RBIMPL_ATTR_PACKED_STRUCT_UNALIGNED_END()

#undef RB_UNUSED_VAR
#define RB_UNUSED_VAR(x) x RBIMPL_ATTR_MAYBE_UNUSED()

#endif /* RUBY_BACKWARD2_ATTRIBUTES_H */
ruby/backward/2/bool.h000064400000003051151732674140010561 0ustar00#ifndef RUBY_BACKWARD2_BOOL_H                        /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_BACKWARD2_BOOL_H
/**
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines old TRUE / FALSE
 */
#include "ruby/internal/stdbool.h"

#ifndef FALSE
# define FALSE false
#elif FALSE
# error FALSE must be false
#endif

#ifndef TRUE
# define TRUE true
#elif ! TRUE
# error TRUE must be true
#endif

#endif /* RUBY_BACKWARD2_BOOL_H */
ruby/re.h000064400000015222151732674140006320 0ustar00#ifndef RUBY_RE_H                                    /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_RE_H 1
/**
 * @file
 * @author     $Author$
 * @date       Thu Sep 30 14:18:32 JST 1993
 * @copyright  Copyright (C) 1993-2007 Yukihiro Matsumoto
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 */
#include "ruby/internal/config.h"

#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif

#include <stdio.h>

#include "ruby/onigmo.h"
#include "ruby/regex.h"
#include "ruby/internal/core/rmatch.h"
#include "ruby/internal/dllexport.h"

struct re_registers;            /* Defined in onigmo.h */

RBIMPL_SYMBOL_EXPORT_BEGIN()

/**
 * Creates a  new instance of  ::rb_cRegexp.  It can  be seen as  a specialised
 * version of rb_reg_new_str() where it does not take options.
 *
 * @param[in]  str  Source code in String.
 * @return     Allocated new instance of ::rb_cRegexp.
 */
VALUE rb_reg_regcomp(VALUE str);

/**
 * Runs  the  passed  regular  expression   over  the  passed  string.   Unlike
 * rb_reg_search()  this function  also  takes position  and  direction of  the
 * search, which make  it possible for this  function to run from  in middle of
 * the string.
 *
 * @param[in]  re               Regular expression to execute.
 * @param[in]  str              Target string to search.
 * @param[in]  pos              Offset in `str` to start searching, in bytes.
 * @param[in]  dir              `pos`' direction; 0  means left-to-right, 1 for
 *                              the opposite.
 * @exception  rb_eArgError     `re` is broken.
 * @exception  rb_eRegexpError  `re` is malformed.
 * @retval     -1               Match failed.
 * @retval     otherwise        Offset of first such byte where match happened.
 * @post       `Regexp.last_match` is updated.
 * @post       `$&`, `$~`, etc., are updated.
 *
 * @internal
 *
 * Distinction  between raising  ::rb_eArgError  and  ::rb_eRegexpError is  not
 * obvious, at least to @shyouhei.
 */
long rb_reg_search(VALUE re, VALUE str, long pos, int dir);

/**
 * Substitution.  This  is basically the implementation  of `String#sub`.  Also
 * `String#gsub` repeatedly calls this function.
 *
 * @param[in]  repl  Replacement string, e.g. `"\\1\\2"`
 * @param[in]  src   Source string, to be replaced.
 * @param[in]  regs  Matched data generated by applying `rexp` to `src`.
 * @param[in]  rexp  Regular expression.
 * @return     A substituted string.
 *
 * @internal
 *
 * This  function does  not  check for  encoding compatibility.   `String#sub!`
 * etc. employ their own checker.
 *
 * `regs` should  have been `const  struct re_registers  *` because it  is read
 * only.  Kept as-is for compatibility.
 */
VALUE rb_reg_regsub(VALUE repl, VALUE src, struct re_registers *regs, VALUE rexp);

/**
 * Tell us if this is a wrong idea,  but it seems this function has no usage at
 * all.  Just remains here for theoretical backwards compatibility.
 *
 * @param[in]  re               Regular expression to execute.
 * @param[in]  str              Target string to search.
 * @param[in]  pos              Offset in `str` to start searching, in bytes.
 * @param[in]  dir              `pos`' direction; 0  means left-to-right, 1 for
 *                              the opposite.
 * @return     Adjusted nearest  offset to  `pos` inside of  `str`, where  is a
 *             character boundary.
 *
 */
long rb_reg_adjust_startpos(VALUE re, VALUE str, long pos, int dir);

/**
 * Escapes  any  characters  that  would  have special  meaning  in  a  regular
 * expression.
 *
 * @param[in]  str  Target string to escape.
 * @return     A copy of `str` whose contents are escaped.
 */
VALUE rb_reg_quote(VALUE str);

/**
 * Exercises  various  checks  and  preprocesses  so  that  the  given  regular
 * expression can be applied to the given string.  The preprocess here includes
 * (but not limited to) for instance encoding conversion.
 *
 * @param[in]  re                  Target regular expression.
 * @param[in]  str                 What `re` is about to run on.
 * @exception  rb_eArgError        `re` does not fit for `str`.
 * @exception  rb_eEncCompatError  `re` and `str` are incompatible.
 * @exception  rb_eRegexpError     `re` is malformed.
 * @return     A preprocessesed pattern buffer ready to be applied to `str`.
 * @note       The return value is manages by our GC.  Don't free.
 *
 * @internal
 *
 * The  return  type,  `regex_t  *`, is  defined  in  `<ruby/onigmo.h>`,  _and_
 * _conflicts_ with POSIX's  `<regex.h>`.  We can no longer  save the situation
 * at this point.  Just don't mix the two.
 */
regex_t *rb_reg_prepare_re(VALUE re, VALUE str);

/**
 * Runs a regular expression match using function `match`. Performs preparation,
 * error handling, and memory cleanup.
 *
 * @param[in]  re                  Target regular expression.
 * @param[in]  str                 What `re` is about to run on.
 * @param[in]  match               The function to run to match `str` against `re`.
 * @param[in]  args                Pointer to arguments to pass into `match`.
 * @param[out] regs                Registers on a successful match.
 * @exception  rb_eArgError        `re` does not fit for `str`.
 * @exception  rb_eEncCompatError  `re` and `str` are incompatible.
 * @exception  rb_eRegexpError     `re` is malformed.
 * @return     Match position on a successful match, `ONIG_MISMATCH` otherwise.
 *
 * @internal
 *
 * The type `regex_t  *` is  defined  in  `<ruby/onigmo.h>`,  _and_
 * _conflicts_ with POSIX's  `<regex.h>`.  We can no longer  save the situation
 * at this point.  Just don't mix the two.
 */
OnigPosition rb_reg_onig_match(VALUE re, VALUE str,
                               OnigPosition (*match)(regex_t *reg, VALUE str, struct re_registers *regs, void *args),
                               void *args, struct re_registers *regs);

/**
 * Duplicates a match data.  This  is roughly the same as `onig_region_copy()`,
 * except it tries to GC when there is not enough memory.
 *
 * @param[out]  dst             Target registers to fill.
 * @param[in]   src             Source registers to duplicate.
 * @exception   rb_eNoMemError  Not enough memory.
 * @retval      0               Successful
 * @retval      ONIGERR_MEMORY  Not enough memory, even after GC (unlikely).
 * @post        `dst` has identical contents to `src`.
 *
 * @internal
 *
 * It seems this function is here for `ext/strscan` and nothing else.
 */
int rb_reg_region_copy(struct re_registers *dst, const struct re_registers *src);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RUBY_RE_H */
ruby/oniguruma.h000064400000000406151732674140007716 0ustar00#ifndef ONIGURUMA_H
#define ONIGURUMA_H
#include "onigmo.h"
#define ONIGURUMA
#define ONIGURUMA_VERSION_MAJOR ONIGMO_VERSION_MAJOR
#define ONIGURUMA_VERSION_MINOR ONIGMO_VERSION_MINOR
#define ONIGURUMA_VERSION_TEENY ONIGMO_VERSION_TEENY
#endif /* ONIGURUMA_H */
ruby/digest.h000064400000006147151732674140007177 0ustar00/************************************************

  digest.h - header file for ruby digest modules

  $Author$
  created at: Fri May 25 08:54:56 JST 2001


  Copyright (C) 2001-2006 Akinori MUSHA

  $RoughId: digest.h,v 1.3 2001/07/13 15:38:27 knu Exp $
  $Id$

************************************************/

#include "ruby.h"

#define RUBY_DIGEST_API_VERSION	3

typedef int (*rb_digest_hash_init_func_t)(void *);
typedef void (*rb_digest_hash_update_func_t)(void *, unsigned char *, size_t);
typedef int (*rb_digest_hash_finish_func_t)(void *, unsigned char *);

typedef struct {
    int api_version;
    size_t digest_len;
    size_t block_len;
    size_t ctx_size;
    rb_digest_hash_init_func_t init_func;
    rb_digest_hash_update_func_t update_func;
    rb_digest_hash_finish_func_t finish_func;
} rb_digest_metadata_t;

#define DEFINE_UPDATE_FUNC_FOR_UINT(name) \
void \
rb_digest_##name##_update(void *ctx, unsigned char *ptr, size_t size) \
{ \
    const unsigned int stride = 16384; \
 \
    for (; size > stride; size -= stride, ptr += stride) { \
        name##_Update(ctx, ptr, stride); \
    } \
    /* Since size <= stride, size should fit into an unsigned int */ \
    if (size > 0) name##_Update(ctx, ptr, (unsigned int)size); \
}

#define DEFINE_FINISH_FUNC_FROM_FINAL(name) \
int \
rb_digest_##name##_finish(void *ctx, unsigned char *ptr) \
{ \
    return name##_Final(ptr, ctx); \
}

static inline VALUE
rb_digest_namespace(void)
{
    rb_require("digest");
    return rb_path2class("Digest");
}

static inline ID
rb_id_metadata(void)
{
    return rb_intern_const("metadata");
}

#if !defined(HAVE_RB_EXT_RESOLVE_SYMBOL)
#elif !defined(RUBY_UNTYPED_DATA_WARNING)
# error RUBY_UNTYPED_DATA_WARNING is not defined
#elif RUBY_UNTYPED_DATA_WARNING
/* rb_ext_resolve_symbol() has been defined since Ruby 3.3, but digest
 * bundled with 3.3 didn't use it. */
# define DIGEST_USE_RB_EXT_RESOLVE_SYMBOL 1
#endif

static inline VALUE
rb_digest_make_metadata(const rb_digest_metadata_t *meta)
{
#if defined(EXTSTATIC) && EXTSTATIC
    /* The extension is built as a static library, so safe to refer to
     * rb_digest_wrap_metadata directly. */
    extern VALUE rb_digest_wrap_metadata(const rb_digest_metadata_t *meta);
    return rb_digest_wrap_metadata(meta);
#else
    /* The extension is built as a shared library, so we can't refer
     * to rb_digest_wrap_metadata directly. */
# ifdef DIGEST_USE_RB_EXT_RESOLVE_SYMBOL
    /* If rb_ext_resolve_symbol() is available, use it to get the address of
     * rb_digest_wrap_metadata. */
    typedef VALUE (*wrapper_func_type)(const rb_digest_metadata_t *meta);
    static wrapper_func_type wrapper;
    if (!wrapper) {
        wrapper = (wrapper_func_type)(uintptr_t)
            rb_ext_resolve_symbol("digest.so", "rb_digest_wrap_metadata");
        if (!wrapper) rb_raise(rb_eLoadError, "rb_digest_wrap_metadata not found");
    }
    return wrapper(meta);
# else
    /* If rb_ext_resolve_symbol() is not available, keep using untyped
     * data. */
# undef RUBY_UNTYPED_DATA_WARNING
# define RUBY_UNTYPED_DATA_WARNING 0
    return rb_obj_freeze(Data_Wrap_Struct(0, 0, 0, (void *)meta));
# endif
#endif
}
ruby/defines.h000064400000005406151732674140007332 0ustar00#ifndef RUBY_DEFINES_H                               /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_DEFINES_H 1
/**
 * @file
 * @author     $Author$
 * @date       Wed May 18 00:21:44 JST 1994
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 */

#include "ruby/internal/config.h"

/* AC_INCLUDES_DEFAULT */
#include <stdio.h>

#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif

#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif

#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# ifdef HAVE_STDLIB_H
#  include <stdlib.h>
# endif
#endif

#ifdef HAVE_STRING_H
# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
#  include <memory.h>
# endif
# include <string.h>
#endif

#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif

#ifdef HAVE_INTTYPES_H
# include <inttypes.h>
#endif

#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif

#ifdef HAVE_STDALIGN_H
# include <stdalign.h>
#endif

#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif

#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
#endif

#ifdef RUBY_USE_SETJMPEX
# include <setjmpex.h>
#endif

#include "ruby/internal/dllexport.h"
#include "ruby/internal/xmalloc.h"
#include "ruby/backward/2/assume.h"
#include "ruby/backward/2/attributes.h"
#include "ruby/backward/2/bool.h"
#include "ruby/backward/2/long_long.h"
#include "ruby/backward/2/stdalign.h"
#include "ruby/backward/2/stdarg.h"
#include "ruby/internal/dosish.h"
#include "ruby/missing.h"

/**
 * Asserts that the compilation unit includes  Ruby's CAPI.  This has been here
 * since the very beginning (at least since version 0.49).
 */
#define RUBY

#ifdef __GNUC__
# /** This is expanded to nothing for non-GCC compilers. */
# define RB_GNUC_EXTENSION __extension__
# /** This is expanded to the passed token for non-GCC compilers. */
# define RB_GNUC_EXTENSION_BLOCK(x) __extension__ ({ x; })
#else
# define RB_GNUC_EXTENSION
# define RB_GNUC_EXTENSION_BLOCK(x) (x)
#endif

/** @cond INTERNAL_MACRO */

/* :FIXME:  Can someone  tell us  why is  this macro  defined here?   @shyouhei
 * thinks this  is a  truly internal  macro but cannot  move around  because he
 * doesn't understand the reason of this arrangement. */
#ifndef RUBY_MBCHAR_MAXSIZE
# define RUBY_MBCHAR_MAXSIZE INT_MAX
# /* MB_CUR_MAX will not work well in C locale */
#endif

#if defined(__sparc)
RBIMPL_SYMBOL_EXPORT_BEGIN()
void rb_sparc_flush_register_windows(void);
RBIMPL_SYMBOL_EXPORT_END()
# define FLUSH_REGISTER_WINDOWS rb_sparc_flush_register_windows()
#else
# define FLUSH_REGISTER_WINDOWS ((void)0)
#endif
/** @endcond */
#endif /* RUBY_DEFINES_H */
ruby/vm.h000064400000004400151732674140006330 0ustar00#ifndef RUBY_VM_H                                    /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_VM_H 1
/**
 * @file
 * @author     $Author$
 * @date       Sat May 31 15:17:36 2008
 * @copyright  Copyright (C) 2008 Yukihiro Matsumoto
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 *
 * We  planned to  have multiple  VMs  run side-by-side.   The API  here was  a
 * preparation of that feature.  The topic branch was eventually abandoned, and
 * we now have Ractor.  This file is kind of obsolescent.
 */
#include "ruby/internal/dllexport.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/**
 * The opaque struct to hold VM internals.  Its fields are intentionally hidden
 * from extension libraries because it changes drastically time to time.
 */
typedef struct rb_vm_struct ruby_vm_t;

/**
 * Destructs the  passed VM.   You don't  have to call  this API  directly now,
 * because there is  no way to create one.   There is only one VM  at one time.
 * ruby_stop() should just suffice.
 */
int ruby_vm_destruct(ruby_vm_t *vm);

/**
 * ruby_vm_at_exit registers a function _func_ to be invoked when a VM
 * passed away.  Functions registered this way runs in reverse order
 * of registration, just like END {} block does.  The difference is
 * its timing to be triggered. ruby_vm_at_exit functions runs when a
 * VM _passed_ _away_, while END {} blocks runs just _before_ a VM
 * _is_ _passing_ _away_.
 *
 * You cannot register a function to another VM than where you are in.
 * So where to register is intuitive, omitted.  OTOH the argument
 * _func_ cannot know which VM it is in because at the time of
 * invocation, the VM has already died and there is no execution
 * context.  The VM itself is passed as the first argument to it.
 *
 * @param[in] func the function to register.
 */
void ruby_vm_at_exit(void(*func)(ruby_vm_t *));

/**
 * Returns whether the Ruby VM will free all memory at shutdown.
 *
 * @return true if free-at-exit is enabled, false otherwise.
 */
bool ruby_free_at_exit_p(void);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RUBY_VM_H */
ruby/config.h000064400000034431151732674140007162 0ustar00#ifndef INCLUDE_RUBY_CONFIG_H
#define INCLUDE_RUBY_CONFIG_H 1
/* confdefs.h */
#define STDC_HEADERS 1
#define HAVE_SYS_TYPES_H 1
#define HAVE_SYS_STAT_H 1
#define HAVE_STDLIB_H 1
#define HAVE_STRING_H 1
#define HAVE_MEMORY_H 1
#define HAVE_STRINGS_H 1
#define HAVE_INTTYPES_H 1
#define HAVE_STDINT_H 1
#define HAVE_UNISTD_H 1
#define __EXTENSIONS__ 1
#define _ALL_SOURCE 1
#define _GNU_SOURCE 1
#define _POSIX_PTHREAD_SEMANTICS 1
#define _TANDEM_SOURCE 1
#define RUBY_SYMBOL_EXPORT_BEGIN _Pragma("GCC visibility push(default)")
#define RUBY_SYMBOL_EXPORT_END _Pragma("GCC visibility pop")
#define HAVE_STMT_AND_DECL_IN_EXPR 1
#define HAVE_PTHREAD_H 1
#define _REENTRANT 1
#define _THREAD_SAFE 1
#define HAVE_LIBPTHREAD 1
#define THREAD_IMPL_H "thread_pthread.h"
#define THREAD_IMPL_SRC "thread_pthread.c"
#define HAVE_LIBCRYPT 1
#define HAVE_LIBDL 1
#define HAVE_DIRENT_H 1
#define HAVE__BOOL 1
#define HAVE_STDBOOL_H 1
#define HAVE_SYS_WAIT_H 1
#define HAVE_GRP_H 1
#define HAVE_FCNTL_H 1
#define HAVE_FLOAT_H 1
#define HAVE_LANGINFO_H 1
#define HAVE_LIMITS_H 1
#define HAVE_LOCALE_H 1
#define HAVE_MALLOC_H 1
#define HAVE_PWD_H 1
#define HAVE_SANITIZER_ASAN_INTERFACE_H 1
#define HAVE_STDALIGN_H 1
#define HAVE_STDIO_H 1
#define HAVE_SYS_EVENTFD_H 1
#define HAVE_SYS_FCNTL_H 1
#define HAVE_SYS_FILE_H 1
#define HAVE_SYS_IOCTL_H 1
#define HAVE_SYS_PARAM_H 1
#define HAVE_SYS_PRCTL_H 1
#define HAVE_SYS_RANDOM_H 1
#define HAVE_SYS_RESOURCE_H 1
#define HAVE_SYS_SELECT_H 1
#define HAVE_SYS_SENDFILE_H 1
#define HAVE_SYS_SOCKET_H 1
#define HAVE_SYS_SYSCALL_H 1
#define HAVE_SYS_SYSMACROS_H 1
#define HAVE_SYS_TIME_H 1
#define HAVE_SYS_TIMES_H 1
#define HAVE_SYS_UIO_H 1
#define HAVE_SYSCALL_H 1
#define HAVE_TIME_H 1
#define HAVE_UCONTEXT_H 1
#define HAVE_UTIME_H 1
#define HAVE_SYS_EPOLL_H 1
#define HAVE_STDATOMIC_H 1
#define HAVE_X86INTRIN_H 1
#if defined(__x86_64__)
#define HAVE_X86INTRIN_H 1
#endif
#define HAVE_GMP_H 1
#define HAVE_LIBGMP 1
#define HAVE_TYPEOF 1
#define restrict __restrict
#define HAVE_LONG_LONG 1
#define HAVE_OFF_T 1
#define SIZEOF_INT 4
#define SIZEOF_SHORT 2
#define SIZEOF_LONG 8
#define SIZEOF_LONG_LONG 8
#define SIZEOF___INT64 0
#define SIZEOF___INT128 16
#define SIZEOF_OFF_T 8
#define SIZEOF_VOIDP 8
#define SIZEOF_FLOAT 4
#define SIZEOF_DOUBLE 8
#define SIZEOF_TIME_T 8
#define SIZEOF_CLOCK_T 8
#define RBIMPL_ATTR_PACKED_STRUCT_BEGIN()
#define RBIMPL_ATTR_PACKED_STRUCT_END() __attribute__((packed))
#define USE_UNALIGNED_MEMBER_ACCESS 1
#define PRI_LL_PREFIX "ll"
#define HAVE_PID_T 1
#define rb_pid_t pid_t
#define SIGNEDNESS_OF_PID_T -1
#define PIDT2NUM(v) INT2NUM(v)
#define NUM2PIDT(v) NUM2INT(v)
#define PRI_PIDT_PREFIX PRI_INT_PREFIX
#define HAVE_UID_T 1
#define rb_uid_t uid_t
#define SIGNEDNESS_OF_UID_T +1
#define UIDT2NUM(v) UINT2NUM(v)
#define NUM2UIDT(v) NUM2UINT(v)
#define PRI_UIDT_PREFIX PRI_INT_PREFIX
#define HAVE_GID_T 1
#define rb_gid_t gid_t
#define SIGNEDNESS_OF_GID_T +1
#define GIDT2NUM(v) UINT2NUM(v)
#define NUM2GIDT(v) NUM2UINT(v)
#define PRI_GIDT_PREFIX PRI_INT_PREFIX
#define HAVE_TIME_T 1
#define rb_time_t time_t
#define SIGNEDNESS_OF_TIME_T -1
#define TIMET2NUM(v) LONG2NUM(v)
#define NUM2TIMET(v) NUM2LONG(v)
#define PRI_TIMET_PREFIX PRI_LONG_PREFIX
#define HAVE_DEV_T 1
#define rb_dev_t dev_t
#define SIGNEDNESS_OF_DEV_T +1
#define DEVT2NUM(v) ULONG2NUM(v)
#define NUM2DEVT(v) NUM2ULONG(v)
#define PRI_DEVT_PREFIX PRI_LONG_PREFIX
#define HAVE_MODE_T 1
#define rb_mode_t mode_t
#define SIGNEDNESS_OF_MODE_T +1
#define MODET2NUM(v) UINT2NUM(v)
#define NUM2MODET(v) NUM2UINT(v)
#define PRI_MODET_PREFIX PRI_INT_PREFIX
#define HAVE_RLIM_T 1
#define rb_rlim_t rlim_t
#define SIGNEDNESS_OF_RLIM_T +1
#define RLIM2NUM(v) ULONG2NUM(v)
#define NUM2RLIM(v) NUM2ULONG(v)
#define PRI_RLIM_PREFIX PRI_LONG_PREFIX
#define HAVE_OFF_T 1
#define rb_off_t off_t
#define SIGNEDNESS_OF_OFF_T -1
#define OFFT2NUM(v) LONG2NUM(v)
#define NUM2OFFT(v) NUM2LONG(v)
#define PRI_OFFT_PREFIX PRI_LONG_PREFIX
#define HAVE_CLOCKID_T 1
#define rb_clockid_t clockid_t
#define SIGNEDNESS_OF_CLOCKID_T -1
#define CLOCKID2NUM(v) INT2NUM(v)
#define NUM2CLOCKID(v) NUM2INT(v)
#define PRI_CLOCKID_PREFIX PRI_INT_PREFIX
#define HAVE_VA_ARGS_MACRO 1
#define HAVE__ALIGNOF 1
#define CONSTFUNC(x) __attribute__ ((__const__)) x
#define PUREFUNC(x) __attribute__ ((__pure__)) x
#define NORETURN(x) __attribute__ ((__noreturn__)) x
#define DEPRECATED(x) __attribute__ ((__deprecated__)) x
#define DEPRECATED_BY(n,x) __attribute__ ((__deprecated__("by "#n))) x
#define NOINLINE(x) __attribute__ ((__noinline__)) x
#define ALWAYS_INLINE(x) __attribute__ ((__always_inline__)) x
#define NO_SANITIZE(san, x) __attribute__ ((__no_sanitize__(san))) x
#define NO_SANITIZE_ADDRESS(x) __attribute__ ((__no_sanitize_address__)) x
#define NO_ADDRESS_SAFETY_ANALYSIS(x) __attribute__ ((__no_address_safety_analysis__)) x
#define WARN_UNUSED_RESULT(x) __attribute__ ((__warn_unused_result__)) x
#define MAYBE_UNUSED(x) __attribute__ ((__unused__)) x
#define ERRORFUNC(mesg,x) __attribute__ ((__error__ mesg)) x
#define WARNINGFUNC(mesg,x) __attribute__ ((__warning__ mesg)) x
#define WEAK(x) __attribute__ ((__weak__)) x
#define HAVE_FUNC_WEAK 1
#define RUBY_CXX_DEPRECATED(msg) __attribute__((__deprecated__(msg)))
#define HAVE_NULLPTR 1
#define FUNC_UNOPTIMIZED(x) __attribute__ ((__optimize__("O0"))) x
#define FUNC_MINIMIZED(x) __attribute__ ((__optimize__("-Os","-fomit-frame-pointer"))) x
#define HAVE_ATTRIBUTE_FUNCTION_ALIAS 1
#define RUBY_ALIAS_FUNCTION_TYPE(type, prot, name, args) type prot __attribute__((alias(#name)));
#define RUBY_ALIAS_FUNCTION_VOID(prot, name, args) RUBY_ALIAS_FUNCTION_TYPE(void, prot, name, args)
#define HAVE_GCC_ATOMIC_BUILTINS 1
#define HAVE_GCC_SYNC_BUILTINS 1
#define HAVE___BUILTIN_UNREACHABLE 1
#define RUBY_FUNC_EXPORTED __attribute__ ((__visibility__("default"))) extern
#define RUBY_FUNC_NONNULL(n,x) __attribute__ ((__nonnull__(n))) x
#define RUBY_FUNCTION_NAME_STRING __func__
#define ENUM_OVER_INT 1
#define HAVE_DECL_SYS_NERR 1
#define HAVE_DECL_GETENV 1
#define SIZEOF_SIZE_T 8
#define SIZEOF_PTRDIFF_T 8
#define SIZEOF_DEV_T 8
#define PRI_SIZE_PREFIX "z"
#define PRI_PTRDIFF_PREFIX "t"
#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
#define HAVE_STRUCT_STAT_ST_BLOCKS 1
#define HAVE_STRUCT_STAT_ST_RDEV 1
#define SIZEOF_STRUCT_STAT_ST_SIZE SIZEOF_OFF_T
#define SIZEOF_STRUCT_STAT_ST_BLOCKS SIZEOF_OFF_T
#define SIZEOF_STRUCT_STAT_ST_INO SIZEOF_LONG
#define SIZEOF_STRUCT_STAT_ST_DEV SIZEOF_DEV_T
#define SIZEOF_STRUCT_STAT_ST_RDEV SIZEOF_DEV_T
#define HAVE_STRUCT_STAT_ST_ATIM 1
#define HAVE_STRUCT_STAT_ST_MTIM 1
#define HAVE_STRUCT_STAT_ST_CTIM 1
#define HAVE_STRUCT_STATX_STX_BTIME 1
#define HAVE_STRUCT_TIMEVAL 1
#define SIZEOF_STRUCT_TIMEVAL_TV_SEC SIZEOF_TIME_T
#define HAVE_STRUCT_TIMESPEC 1
#define HAVE_STRUCT_TIMEZONE 1
#define HAVE_RB_FD_INIT 1
#define HAVE_INT8_T 1
#define SIZEOF_INT8_T 1
#define HAVE_UINT8_T 1
#define SIZEOF_UINT8_T 1
#define HAVE_INT16_T 1
#define SIZEOF_INT16_T 2
#define HAVE_UINT16_T 1
#define SIZEOF_UINT16_T 2
#define HAVE_INT32_T 1
#define SIZEOF_INT32_T 4
#define HAVE_UINT32_T 1
#define SIZEOF_UINT32_T 4
#define HAVE_INT64_T 1
#define SIZEOF_INT64_T 8
#define HAVE_UINT64_T 1
#define SIZEOF_UINT64_T 8
#define HAVE_INT128_T 1
#define int128_t __int128
#define SIZEOF_INT128_T SIZEOF___INT128
#define HAVE_UINT128_T 1
#define uint128_t unsigned __int128
#define SIZEOF_UINT128_T SIZEOF___INT128
#define HAVE_INTPTR_T 1
#define SIZEOF_INTPTR_T 8
#define HAVE_UINTPTR_T 1
#define SIZEOF_UINTPTR_T 8
#define HAVE_SSIZE_T 1
#define SIZEOF_SSIZE_T 8
#define STACK_END_ADDRESS __libc_stack_end
#define GETGROUPS_T gid_t
#define HAVE_ALLOCA_H 1
#define HAVE_ALLOCA 1
#define HAVE_DUP 1
#define HAVE_DUP2 1
#define HAVE_ACOSH 1
#define HAVE_CBRT 1
#define HAVE_CRYPT 1
#define HAVE_ERF 1
#define HAVE_EXPLICIT_BZERO 1
#define HAVE_FFS 1
#define HAVE_FLOCK 1
#define HAVE_HYPOT 1
#define HAVE_LGAMMA_R 1
#define HAVE_MEMMOVE 1
#define HAVE_NAN 1
#define HAVE_NEXTAFTER 1
#define HAVE_STRCHR 1
#define HAVE_STRERROR 1
#define HAVE_STRSTR 1
#define HAVE_TGAMMA 1
#define HAVE_ISFINITE 1
#define SPT_TYPE SPT_REUSEARGV
#define HAVE_SIGNBIT 1
#define HAVE_FORK 1
#define HAVE_VFORK 1
#define HAVE_WORKING_VFORK 1
#define HAVE_WORKING_FORK 1
#define HAVE__LONGJMP 1
#define HAVE_ATAN2L 1
#define HAVE_ATAN2F 1
#define HAVE_DECL_ATOMIC_SIGNAL_FENCE 1
#define HAVE_CHMOD 1
#define HAVE_CHOWN 1
#define HAVE_CHROOT 1
#define HAVE_CLOCK_GETTIME 1
#define HAVE_COPY_FILE_RANGE 1
#define HAVE_COSH 1
#define HAVE_CRYPT_R 1
#define HAVE_DIRFD 1
#define HAVE_DL_ITERATE_PHDR 1
#define HAVE_DLOPEN 1
#define HAVE_DLADDR 1
#define HAVE_DUP3 1
#define HAVE_EACCESS 1
#define HAVE_ENDGRENT 1
#define HAVE_EVENTFD 1
#define HAVE_EXECL 1
#define HAVE_EXECLE 1
#define HAVE_EXECV 1
#define HAVE_EXECVE 1
#define HAVE_FCHDIR 1
#define HAVE_FCHMOD 1
#define HAVE_FCHOWN 1
#define HAVE_FCNTL 1
#define HAVE_FDATASYNC 1
#define HAVE_FDOPENDIR 1
#define HAVE_FMOD 1
#define HAVE_FSTATAT 1
#define HAVE_FSYNC 1
#define HAVE_FTRUNCATE 1
#define HAVE_FTRUNCATE64 1
#define HAVE_GETCWD 1
#define HAVE_GETEGID 1
#define HAVE_GETENTROPY 1
#define HAVE_GETEUID 1
#define HAVE_GETGID 1
#define HAVE_GETGRNAM 1
#define HAVE_GETGRNAM_R 1
#define HAVE_GETGROUPS 1
#define HAVE_GETLOGIN 1
#define HAVE_GETLOGIN_R 1
#define HAVE_GETPGID 1
#define HAVE_GETPGRP 1
#define HAVE_GETPPID 1
#define HAVE_GETPRIORITY 1
#define HAVE_GETPWNAM 1
#define HAVE_GETPWNAM_R 1
#define HAVE_GETPWUID 1
#define HAVE_GETPWUID_R 1
#define HAVE_GETRANDOM 1
#define HAVE_GETRESGID 1
#define HAVE_GETRESUID 1
#define HAVE_GETRLIMIT 1
#define HAVE_GETSID 1
#define HAVE_GETTIMEOFDAY 1
#define HAVE_GETUID 1
#define HAVE_GMTIME_R 1
#define HAVE_INITGROUPS 1
#define HAVE_IOCTL 1
#define HAVE_KILL 1
#define HAVE_KILLPG 1
#define HAVE_LCHOWN 1
#define HAVE_LINK 1
#define HAVE_LLABS 1
#define HAVE_LOCKF 1
#define HAVE_LOG2 1
#define HAVE_LSTAT 1
#define HAVE_LUTIMES 1
#define HAVE_MALLOC_USABLE_SIZE 1
#define HAVE_MALLOC_TRIM 1
#define HAVE_MBLEN 1
#define HAVE_MEMALIGN 1
#define HAVE_WRITEV 1
#define HAVE_MEMRCHR 1
#define HAVE_MEMMEM 1
#define HAVE_MKFIFO 1
#define HAVE_MKNOD 1
#define HAVE_MKTIME 1
#define HAVE_MMAP 1
#define HAVE_MREMAP 1
#define HAVE_OPENAT 1
#define HAVE_PCLOSE 1
#define HAVE_PIPE 1
#define HAVE_PIPE2 1
#define HAVE_POLL 1
#define HAVE_POPEN 1
#define HAVE_POSIX_FADVISE 1
#define HAVE_POSIX_MADVISE 1
#define HAVE_POSIX_MEMALIGN 1
#define HAVE_PPOLL 1
#define HAVE_PREAD 1
#define HAVE_PWRITE 1
#define HAVE_QSORT_R 1
#define HAVE_READLINK 1
#define HAVE_REALPATH 1
#define HAVE_ROUND 1
#define HAVE_SCHED_GETAFFINITY 1
#define HAVE_SEEKDIR 1
#define HAVE_SENDFILE 1
#define HAVE_SETEGID 1
#define HAVE_SETENV 1
#define HAVE_SETEUID 1
#define HAVE_SETGID 1
#define HAVE_SETGROUPS 1
#define HAVE_SETPGID 1
#define HAVE_SETPGRP 1
#define HAVE_SETREGID 1
#define HAVE_SETRESGID 1
#define HAVE_SETRESUID 1
#define HAVE_SETREUID 1
#define HAVE_SETRLIMIT 1
#define HAVE_SETSID 1
#define HAVE_SETUID 1
#define HAVE_SHUTDOWN 1
#define HAVE_SIGACTION 1
#define HAVE_SIGALTSTACK 1
#define HAVE_SIGPROCMASK 1
#define HAVE_SINH 1
#define HAVE_SNPRINTF 1
#define HAVE_SYMLINK 1
#define HAVE_SYSCALL 1
#define HAVE_SYSCONF 1
#define HAVE_SYSTEM 1
#define HAVE_TANH 1
#define HAVE_TELLDIR 1
#define HAVE_TIMEGM 1
#define HAVE_TIMES 1
#define HAVE_TRUNCATE 1
#define HAVE_TRUNCATE64 1
#define HAVE_TZSET 1
#define HAVE_UMASK 1
#define HAVE_UNSETENV 1
#define HAVE_UTIMENSAT 1
#define HAVE_UTIMES 1
#define HAVE_WAIT4 1
#define HAVE_WAITPID 1
#define HAVE_STATX 1
#define HAVE_CRYPT_H 1
#define HAVE_STRUCT_CRYPT_DATA_INITIALIZED 1
#define HAVE_BUILTIN___BUILTIN_ALLOCA_WITH_ALIGN 1
#define HAVE_BUILTIN___BUILTIN_ASSUME_ALIGNED 1
#define HAVE_BUILTIN___BUILTIN_BSWAP16 1
#define HAVE_BUILTIN___BUILTIN_BSWAP32 1
#define HAVE_BUILTIN___BUILTIN_BSWAP64 1
#define HAVE_BUILTIN___BUILTIN_POPCOUNT 1
#define HAVE_BUILTIN___BUILTIN_POPCOUNTLL 1
#define HAVE_BUILTIN___BUILTIN_CLZ 1
#define HAVE_BUILTIN___BUILTIN_CLZL 1
#define HAVE_BUILTIN___BUILTIN_CLZLL 1
#define HAVE_BUILTIN___BUILTIN_CTZ 1
#define HAVE_BUILTIN___BUILTIN_CTZLL 1
#define HAVE_BUILTIN___BUILTIN_CONSTANT_P 1
#define HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR 1
#define HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P 1
#define HAVE_BUILTIN___BUILTIN_TYPES_COMPATIBLE_P 1
#define HAVE_BUILTIN___BUILTIN_TRAP 1
#define HAVE_BUILTIN___BUILTIN_EXPECT 1
#define HAVE_BUILTIN___BUILTIN_ADD_OVERFLOW 1
#define HAVE_BUILTIN___BUILTIN_ADD_OVERFLOW_P 1
#define USE___BUILTIN_ADD_OVERFLOW_LONG_LONG 1
#define HAVE_BUILTIN___BUILTIN_SUB_OVERFLOW 1
#define HAVE_BUILTIN___BUILTIN_SUB_OVERFLOW_P 1
#define USE___BUILTIN_SUB_OVERFLOW_LONG_LONG 1
#define HAVE_BUILTIN___BUILTIN_MUL_OVERFLOW 1
#define HAVE_BUILTIN___BUILTIN_MUL_OVERFLOW_P 1
#define USE___BUILTIN_MUL_OVERFLOW_LONG_LONG 1
#define HAVE_GNU_QSORT_R 1
#define ATAN2_INF_C99 1
#define HAVE_CLOCK_GETRES 1
#define HAVE_LIBRT 1
#define HAVE_LIBRT 1
#define HAVE_TIMER_CREATE 1
#define HAVE_TIMER_SETTIME 1
#define HAVE_STRUCT_TM_TM_ZONE 1
#define HAVE_TM_ZONE 1
#define HAVE_STRUCT_TM_TM_GMTOFF 1
#define HAVE_DAYLIGHT 1
#define NEGATIVE_TIME_T 1
#define POSIX_SIGNAL 1
#define HAVE_SIG_T 1
#define RSHIFT(x,y) ((x)>>(int)(y))
#define USE_COPY_FILE_RANGE 1
#define HAVE__SC_CLK_TCK 1
#define STACK_GROW_DIRECTION -1
#define COROUTINE_H "coroutine/amd64/Context.h"
#define HAVE_SCHED_YIELD 1
#define HAVE_PTHREAD_ATTR_SETINHERITSCHED 1
#define HAVE_PTHREAD_ATTR_GETSTACK 1
#define HAVE_PTHREAD_ATTR_GETGUARDSIZE 1
#define HAVE_PTHREAD_CONDATTR_SETCLOCK 1
#define HAVE_PTHREAD_SETNAME_NP 1
#define HAVE_PTHREAD_SIGMASK 1
#define HAVE_PTHREAD_GETATTR_NP 1
#define SET_CURRENT_THREAD_NAME(name) pthread_setname_np(pthread_self(), name)
#define SET_ANOTHER_THREAD_NAME(thid,name) pthread_setname_np(thid, name)
#define RB_THREAD_LOCAL_SPECIFIER _Thread_local
#define DEFINE_MCONTEXT_PTR(mc, uc) mcontext_t *mc = &(uc)->uc_mcontext
#define HAVE_GETCONTEXT 1
#define HAVE_SETCONTEXT 1
#define HAVE_SYS_USER_H 1
#define HAVE_CONST_PAGE_SIZE 0
#define IOCTL_REQ_TYPE unsigned long
#define NUM2IOCTLREQ(num) NUM2ULONG(num)
#define USE_ELF 1
#define HAVE_ELF_H 1
#define HAVE_LIBZ 1
#define HAVE_BACKTRACE 1
#define DLEXT_MAXLEN 3
#define DLEXT ".so"
#define SOEXT ".so"
#define ENABLE_MULTIARCH 1
#define LIBDIR_BASENAME "lib64"
#define HAVE__SETJMP 1
#define RUBY_SETJMP(env) _setjmp((env))
#define RUBY_LONGJMP(env,val) _longjmp((env),val)
#define RUBY_JMP_BUF jmp_buf
#define USE_MODULAR_GC 0
#define USE_YJIT 0
#define USE_RJIT 1
#define RUBY_LIB_VERSION_BLANK 1
#define RUBY_PLATFORM "x86_64-linux"
#define RB_DEFAULT_PARSER RB_DEFAULT_PARSER_PRISM
#endif /* INCLUDE_RUBY_CONFIG_H */
ruby/missing.h000064400000015261151732674140007366 0ustar00#ifndef RUBY_MISSING_H                               /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_MISSING_H 1
/**
 * @author     $Author$
 * @date       Sat May 11 23:46:03 JST 2002
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @brief      Prototype for *.c in ./missing, and for missing timeval struct.
 */
#include "ruby/internal/config.h"

#ifdef STDC_HEADERS
# include <stddef.h>
#endif

#if defined(__cplusplus)
# include <cmath>
#else
# include <math.h> /* for INFINITY and NAN */
#endif

#ifdef RUBY_ALTERNATIVE_MALLOC_HEADER
# include RUBY_ALTERNATIVE_MALLOC_HEADER
#endif

#if defined(HAVE_TIME_H)
# include <time.h>
#endif

#if defined(HAVE_SYS_TIME_H)
# include <sys/time.h>
#endif

#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif

#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif

#ifdef HAVE_STDIO_H
# include <stdio.h>
#endif

#ifdef HAVE_IEEEFP_H
# include <ieeefp.h>
#endif

#include "ruby/internal/dllexport.h"
#include "ruby/internal/attr/format.h"

#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif
#ifndef M_PI_2
# define M_PI_2 (M_PI/2)
#endif

#if !defined(HAVE_STRUCT_TIMEVAL)
struct timeval {
    time_t tv_sec;	/* seconds */
    long tv_usec;	/* microseconds */
};
#endif /* HAVE_STRUCT_TIMEVAL */

#if !defined(HAVE_STRUCT_TIMESPEC)
/* :BEWARE: @shyouhei warns that  IT IS A WRONG IDEA to  define our own version
 * of struct timespec here.  `clock_gettime` is  a system call, and your kernel
 * could expect  something other  than just `long`  (results stack  smashing if
 * that happens).  See also https://ewontfix.com/19/ */
struct timespec {
    time_t tv_sec;	/* seconds */
    long tv_nsec;	/* nanoseconds */
};
#endif

#if !defined(HAVE_STRUCT_TIMEZONE)
struct timezone {
    int tz_minuteswest;
    int tz_dsttime;
};
#endif

RBIMPL_SYMBOL_EXPORT_BEGIN()

#ifndef HAVE_ACOSH
RUBY_EXTERN double acosh(double);
RUBY_EXTERN double asinh(double);
RUBY_EXTERN double atanh(double);
#endif

#ifndef HAVE_CRYPT
RUBY_EXTERN char *crypt(const char *, const char *);
#endif

#ifndef HAVE_EACCESS
RUBY_EXTERN int eaccess(const char*, int);
#endif

#ifndef HAVE_ROUND
RUBY_EXTERN double round(double);	/* numeric.c */
#endif

#ifndef HAVE_FLOCK
RUBY_EXTERN int flock(int, int);
#endif

/*
#ifndef HAVE_FREXP
RUBY_EXTERN double frexp(double, int *);
#endif
*/

#ifndef HAVE_HYPOT
RUBY_EXTERN double hypot(double, double);
#endif

#ifndef HAVE_ERF
RUBY_EXTERN double erf(double);
RUBY_EXTERN double erfc(double);
#endif

#ifndef HAVE_TGAMMA
RUBY_EXTERN double tgamma(double);
#endif

#ifndef HAVE_LGAMMA_R
RUBY_EXTERN double lgamma_r(double, int *);
#endif

#ifndef HAVE_CBRT
RUBY_EXTERN double cbrt(double);
#endif

#if !defined(INFINITY) || !defined(NAN)
union bytesequence4_or_float {
  unsigned char bytesequence[4];
  float float_value;
};
#endif

#ifndef INFINITY
/** @internal */
RUBY_EXTERN const union bytesequence4_or_float rb_infinity;
# define INFINITY (rb_infinity.float_value)
# define USE_RB_INFINITY 1
#endif

#ifndef NAN
/** @internal */
RUBY_EXTERN const union bytesequence4_or_float rb_nan;
# define NAN (rb_nan.float_value)
# define USE_RB_NAN 1
#endif

#ifndef HUGE_VAL
# define HUGE_VAL ((double)INFINITY)
#endif

#ifndef HAVE_FINITE
# define HAVE_FINITE 1
# define finite(x) isfinite(x)
#endif

#ifndef HAVE_NAN
RUBY_EXTERN double nan(const char *);
#endif

#ifndef HAVE_NEXTAFTER
RUBY_EXTERN double nextafter(double x, double y);
#endif

/*
#ifndef HAVE_MEMCMP
RUBY_EXTERN int memcmp(const void *, const void *, size_t);
#endif
*/

#ifndef HAVE_MEMMOVE
RUBY_EXTERN void *memmove(void *, const void *, size_t);
#endif

/*
#ifndef HAVE_MODF
RUBY_EXTERN double modf(double, double *);
#endif
*/

#ifndef HAVE_STRCHR
RUBY_EXTERN char *strchr(const char *, int);
RUBY_EXTERN char *strrchr(const char *, int);
#endif

#ifndef HAVE_STRERROR
RUBY_EXTERN char *strerror(int);
#endif

#ifndef HAVE_STRSTR
RUBY_EXTERN char *strstr(const char *, const char *);
#endif

#ifndef HAVE_STRLCPY
RUBY_EXTERN size_t strlcpy(char *, const char*, size_t);
#endif

#ifndef HAVE_STRLCAT
RUBY_EXTERN size_t strlcat(char *, const char*, size_t);
#endif

#ifndef HAVE_FFS
RUBY_EXTERN int ffs(int);
#endif

#ifdef BROKEN_CLOSE
# include <sys/types.h>
# include <sys/socket.h>
RUBY_EXTERN int ruby_getpeername(int, struct sockaddr *, socklen_t *);
RUBY_EXTERN int ruby_getsockname(int, struct sockaddr *, socklen_t *);
RUBY_EXTERN int ruby_shutdown(int, int);
RUBY_EXTERN int ruby_close(int);
#endif

#ifndef HAVE_SETPROCTITLE
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 1, 2)
RUBY_EXTERN void setproctitle(const char *fmt, ...);
#endif

#ifdef HAVE_EXPLICIT_BZERO
# /* Take that. */
#elif defined(SecureZeroMemory)
# define explicit_bzero(b, len) SecureZeroMemory(b, len)
#else
RUBY_EXTERN void explicit_bzero(void *b, size_t len);
#endif

#ifndef HAVE_TZSET
RUBY_EXTERN void tzset(void);
#endif

#ifndef HAVE_POSIX_MADVISE
RUBY_EXTERN int posix_madvise(void *, size_t, int);
#endif

#ifndef HAVE_GETEUID
RUBY_EXTERN rb_uid_t geteuid(void);
#endif

#ifndef HAVE_GETUID
RUBY_EXTERN rb_uid_t getuid(void);
#endif

#ifndef HAVE_GETEGID
RUBY_EXTERN rb_gid_t getegid(void);
#endif

#ifndef HAVE_GETGID
RUBY_EXTERN rb_gid_t getgid(void);
#endif

#ifndef HAVE_GETLOGIN
RUBY_EXTERN char *getlogin(void);
#endif

#ifndef HAVE_GETPPID
RUBY_EXTERN rb_pid_t getppid(void);
#endif

#ifndef HAVE_UMASK
RUBY_EXTERN rb_mode_t umask(rb_mode_t);
#endif

#ifndef HAVE_CHMOD
RUBY_EXTERN int chmod(const char *, rb_mode_t);
#endif

#ifndef HAVE_CHOWN
RUBY_EXTERN int chown(const char *, rb_uid_t, rb_gid_t);
#endif

#ifndef HAVE_PCLOSE
RUBY_EXTERN int pclose(FILE *);
#endif

#ifndef HAVE_POPEN
RUBY_EXTERN FILE *popen(const char *, const char *);
#endif

#ifndef HAVE_PIPE
RUBY_EXTERN int pipe(int [2]);
#endif

#ifndef HAVE_DUP
RUBY_EXTERN int dup(int);
#endif

#ifndef HAVE_DUP2
RUBY_EXTERN int dup2(int, int);
#endif

#ifndef HAVE_KILL
RUBY_EXTERN int kill(rb_pid_t, int);
#endif

#ifndef HAVE_EXECL
RUBY_EXTERN int execl(const char *, const char *, ...);
#endif

#ifndef HAVE_EXECLE
RUBY_EXTERN int execle(const char *, const char *, ...);
#endif

#ifndef HAVE_EXECV
RUBY_EXTERN int execv(const char *, char *const []);
#endif

#ifndef HAVE_EXECVE
RUBY_EXTERN int execve(const char *, char *const [], char *const []);
#endif

#ifndef HAVE_SHUTDOWN
RUBY_EXTERN int shutdown(int, int);
#endif

#ifndef HAVE_SYSTEM
RUBY_EXTERN int system(const char *);
#endif

#ifndef WNOHANG
# define WNOHANG 0
#endif

#ifndef HAVE_WAITPID
# define HAVE_WAITPID 1
RUBY_EXTERN rb_pid_t waitpid(rb_pid_t, int *, int);
#endif

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RUBY_MISSING_H */
ruby/onigmo.h000064400000127627151732674140007217 0ustar00#ifndef ONIGMO_H
#define ONIGMO_H
/**********************************************************************
  onigmo.h - Onigmo (Oniguruma-mod) (regular expression library)
**********************************************************************/
/*-
 * Copyright (c) 2002-2009  K.Kosako  <sndgk393 AT ybb DOT ne DOT jp>
 * Copyright (c) 2011-2017  K.Takata  <kentkt AT csc DOT jp>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifdef __cplusplus
extern "C" {
# if 0
} /* satisfy cc-mode */
# endif
#endif

#define ONIGMO_VERSION_MAJOR   6
#define ONIGMO_VERSION_MINOR   1
#define ONIGMO_VERSION_TEENY   3

#ifndef ONIG_EXTERN
# ifdef RUBY_EXTERN
#  define ONIG_EXTERN   RUBY_EXTERN
# else
#  if defined(_WIN32) && !defined(__GNUC__)
#   if defined(EXPORT) || defined(RUBY_EXPORT)
#    define ONIG_EXTERN   extern __declspec(dllexport)
#   else
#    define ONIG_EXTERN   extern __declspec(dllimport)
#   endif
#  endif
# endif
#endif

#ifndef ONIG_EXTERN
# define ONIG_EXTERN   extern
#endif

#ifndef RUBY
# ifndef RUBY_SYMBOL_EXPORT_BEGIN
#  define RUBY_SYMBOL_EXPORT_BEGIN
#  define RUBY_SYMBOL_EXPORT_END
# endif
#endif

RUBY_SYMBOL_EXPORT_BEGIN

#include <stddef.h>		/* for size_t */

/* PART: character encoding */

#ifndef ONIG_ESCAPE_UCHAR_COLLISION
# define UChar OnigUChar
#endif

typedef unsigned char  OnigUChar;
typedef unsigned int   OnigCodePoint;
typedef unsigned int   OnigCtype;
typedef size_t         OnigDistance;
typedef ptrdiff_t      OnigPosition;

#define ONIG_INFINITE_DISTANCE  ~((OnigDistance )0)

/*
 * Onig casefold/case mapping flags and related definitions
 *
 * Subfields (starting with 0 at LSB):
 *   0-2: Code point count in casefold.h
 *   3-12: Index into SpecialCaseMapping array in casefold.h
 *   13-22: Case folding/mapping flags
 */
typedef unsigned int OnigCaseFoldType; /* case fold flag */

ONIG_EXTERN OnigCaseFoldType OnigDefaultCaseFoldFlag;

/* bits for actual code point count; 3 bits is more than enough, currently only 2 used */
#define OnigCodePointMaskWidth    3
#define OnigCodePointMask     ((1<<OnigCodePointMaskWidth)-1)
#define OnigCodePointCount(n) ((n)&OnigCodePointMask)
#define OnigCaseFoldFlags(n) ((n)&~OnigCodePointMask)

/* #define ONIGENC_CASE_FOLD_HIRAGANA_KATAKANA  (1<<1) */ /* no longer usable with these values! */
/* #define ONIGENC_CASE_FOLD_KATAKANA_WIDTH     (1<<2) */ /* no longer usable with these values! */

/* bits for index into table with separate titlecase mappings */
/* 10 bits provide 1024 values */
#define OnigSpecialIndexShift 3
#define OnigSpecialIndexWidth 10

#define ONIGENC_CASE_UPCASE                     (1<<13) /* has/needs uppercase mapping */
#define ONIGENC_CASE_DOWNCASE                   (1<<14) /* has/needs lowercase mapping */
#define ONIGENC_CASE_TITLECASE                  (1<<15) /* has/needs (special) titlecase mapping */
#define ONIGENC_CASE_SPECIAL_OFFSET             3       /* offset in bits from ONIGENC_CASE to ONIGENC_CASE_SPECIAL */
#define ONIGENC_CASE_UP_SPECIAL                 (1<<16) /* has special upcase mapping */
#define ONIGENC_CASE_DOWN_SPECIAL               (1<<17) /* has special downcase mapping */
#define ONIGENC_CASE_MODIFIED                   (1<<18) /* data has been modified */
#define ONIGENC_CASE_FOLD                       (1<<19) /* has/needs case folding */

#define ONIGENC_CASE_FOLD_TURKISH_AZERI         (1<<20) /* needs mapping specific to Turkic languages; better not change original value! */

#define ONIGENC_CASE_FOLD_LITHUANIAN            (1<<21) /* needs Lithuanian-specific mapping */
#define ONIGENC_CASE_ASCII_ONLY                 (1<<22) /* only modify ASCII range */
#define ONIGENC_CASE_IS_TITLECASE               (1<<23) /* character itself is already titlecase */

#define INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR   (1<<30) /* better not change original value! */

#define ONIGENC_CASE_FOLD_MIN      INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR
#define ONIGENC_CASE_FOLD_DEFAULT  OnigDefaultCaseFoldFlag


#define ONIGENC_MAX_COMP_CASE_FOLD_CODE_LEN       3
#define ONIGENC_GET_CASE_FOLD_CODES_MAX_NUM      13
/* 13 => Unicode:0x1ffc */

/* code range */
#define ONIGENC_CODE_RANGE_NUM(range)     ((int )range[0])
#define ONIGENC_CODE_RANGE_FROM(range,i)  range[((i)*2) + 1]
#define ONIGENC_CODE_RANGE_TO(range,i)    range[((i)*2) + 2]

typedef struct {
  int byte_len;  /* argument(original) character(s) byte length */
  int code_len;  /* number of code */
  OnigCodePoint code[ONIGENC_MAX_COMP_CASE_FOLD_CODE_LEN];
} OnigCaseFoldCodeItem;

typedef struct {
  OnigCodePoint esc;
  OnigCodePoint anychar;
  OnigCodePoint anytime;
  OnigCodePoint zero_or_one_time;
  OnigCodePoint one_or_more_time;
  OnigCodePoint anychar_anytime;
} OnigMetaCharTableType;

typedef int (*OnigApplyAllCaseFoldFunc)(OnigCodePoint from, OnigCodePoint* to, int to_len, void* arg);

typedef struct OnigEncodingTypeST {
  int    (*precise_mbc_enc_len)(const OnigUChar* p,const OnigUChar* e, const struct OnigEncodingTypeST* enc);
  const char*   name;
  int           max_enc_len;
  int           min_enc_len;
  int    (*is_mbc_newline)(const OnigUChar* p, const OnigUChar* end, const struct OnigEncodingTypeST* enc);
  OnigCodePoint (*mbc_to_code)(const OnigUChar* p, const OnigUChar* end, const struct OnigEncodingTypeST* enc);
  int    (*code_to_mbclen)(OnigCodePoint code, const struct OnigEncodingTypeST* enc);
  int    (*code_to_mbc)(OnigCodePoint code, OnigUChar *buf, const struct OnigEncodingTypeST* enc);
  int    (*mbc_case_fold)(OnigCaseFoldType flag, const OnigUChar** pp, const OnigUChar* end, OnigUChar* to, const struct OnigEncodingTypeST* enc);
  int    (*apply_all_case_fold)(OnigCaseFoldType flag, OnigApplyAllCaseFoldFunc f, void* arg, const struct OnigEncodingTypeST* enc);
  int    (*get_case_fold_codes_by_str)(OnigCaseFoldType flag, const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem acs[], const struct OnigEncodingTypeST* enc);
  int    (*property_name_to_ctype)(const struct OnigEncodingTypeST* enc, const OnigUChar* p, const OnigUChar* end);
  int    (*is_code_ctype)(OnigCodePoint code, OnigCtype ctype, const struct OnigEncodingTypeST* enc);
  int    (*get_ctype_code_range)(OnigCtype ctype, OnigCodePoint* sb_out, const OnigCodePoint* ranges[], const struct OnigEncodingTypeST* enc);
  OnigUChar* (*left_adjust_char_head)(const OnigUChar* start, const OnigUChar* p, const OnigUChar* end, const struct OnigEncodingTypeST* enc);
  int    (*is_allowed_reverse_match)(const OnigUChar* p, const OnigUChar* end, const struct OnigEncodingTypeST* enc);
  int    (*case_map)(OnigCaseFoldType* flagP, const OnigUChar** pp, const OnigUChar* end, OnigUChar* to, OnigUChar* to_end, const struct OnigEncodingTypeST* enc);
  int ruby_encoding_index;
  unsigned int  flags;
} OnigEncodingType;

typedef const OnigEncodingType* OnigEncoding;

ONIG_EXTERN const OnigEncodingType OnigEncodingASCII;
#ifndef RUBY
ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_1;
ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_2;
ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_3;
ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_4;
ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_5;
ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_6;
ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_7;
ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_8;
ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_9;
ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_10;
ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_11;
ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_13;
ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_14;
ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_15;
ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_16;
ONIG_EXTERN const OnigEncodingType OnigEncodingUTF_8;
ONIG_EXTERN const OnigEncodingType OnigEncodingUTF_16BE;
ONIG_EXTERN const OnigEncodingType OnigEncodingUTF_16LE;
ONIG_EXTERN const OnigEncodingType OnigEncodingUTF_32BE;
ONIG_EXTERN const OnigEncodingType OnigEncodingUTF_32LE;
ONIG_EXTERN const OnigEncodingType OnigEncodingEUC_JP;
ONIG_EXTERN const OnigEncodingType OnigEncodingEUC_TW;
ONIG_EXTERN const OnigEncodingType OnigEncodingEUC_KR;
ONIG_EXTERN const OnigEncodingType OnigEncodingEUC_CN;
ONIG_EXTERN const OnigEncodingType OnigEncodingShift_JIS;
ONIG_EXTERN const OnigEncodingType OnigEncodingWindows_31J;
/* ONIG_EXTERN const OnigEncodingType OnigEncodingKOI8; */
ONIG_EXTERN const OnigEncodingType OnigEncodingKOI8_R;
ONIG_EXTERN const OnigEncodingType OnigEncodingKOI8_U;
ONIG_EXTERN const OnigEncodingType OnigEncodingWindows_1250;
ONIG_EXTERN const OnigEncodingType OnigEncodingWindows_1251;
ONIG_EXTERN const OnigEncodingType OnigEncodingWindows_1252;
ONIG_EXTERN const OnigEncodingType OnigEncodingWindows_1253;
ONIG_EXTERN const OnigEncodingType OnigEncodingWindows_1254;
ONIG_EXTERN const OnigEncodingType OnigEncodingWindows_1257;
ONIG_EXTERN const OnigEncodingType OnigEncodingBIG5;
ONIG_EXTERN const OnigEncodingType OnigEncodingGB18030;
#endif /* RUBY */

#define ONIG_ENCODING_ASCII        (&OnigEncodingASCII)
#ifndef RUBY
# define ONIG_ENCODING_ISO_8859_1   (&OnigEncodingISO_8859_1)
# define ONIG_ENCODING_ISO_8859_2   (&OnigEncodingISO_8859_2)
# define ONIG_ENCODING_ISO_8859_3   (&OnigEncodingISO_8859_3)
# define ONIG_ENCODING_ISO_8859_4   (&OnigEncodingISO_8859_4)
# define ONIG_ENCODING_ISO_8859_5   (&OnigEncodingISO_8859_5)
# define ONIG_ENCODING_ISO_8859_6   (&OnigEncodingISO_8859_6)
# define ONIG_ENCODING_ISO_8859_7   (&OnigEncodingISO_8859_7)
# define ONIG_ENCODING_ISO_8859_8   (&OnigEncodingISO_8859_8)
# define ONIG_ENCODING_ISO_8859_9   (&OnigEncodingISO_8859_9)
# define ONIG_ENCODING_ISO_8859_10  (&OnigEncodingISO_8859_10)
# define ONIG_ENCODING_ISO_8859_11  (&OnigEncodingISO_8859_11)
# define ONIG_ENCODING_ISO_8859_13  (&OnigEncodingISO_8859_13)
# define ONIG_ENCODING_ISO_8859_14  (&OnigEncodingISO_8859_14)
# define ONIG_ENCODING_ISO_8859_15  (&OnigEncodingISO_8859_15)
# define ONIG_ENCODING_ISO_8859_16  (&OnigEncodingISO_8859_16)
# define ONIG_ENCODING_UTF_8        (&OnigEncodingUTF_8)
# define ONIG_ENCODING_UTF_16BE     (&OnigEncodingUTF_16BE)
# define ONIG_ENCODING_UTF_16LE     (&OnigEncodingUTF_16LE)
# define ONIG_ENCODING_UTF_32BE     (&OnigEncodingUTF_32BE)
# define ONIG_ENCODING_UTF_32LE     (&OnigEncodingUTF_32LE)
# define ONIG_ENCODING_EUC_JP       (&OnigEncodingEUC_JP)
# define ONIG_ENCODING_EUC_TW       (&OnigEncodingEUC_TW)
# define ONIG_ENCODING_EUC_KR       (&OnigEncodingEUC_KR)
# define ONIG_ENCODING_EUC_CN       (&OnigEncodingEUC_CN)
# define ONIG_ENCODING_SHIFT_JIS    (&OnigEncodingShift_JIS)
# define ONIG_ENCODING_WINDOWS_31J  (&OnigEncodingWindows_31J)
/* # define ONIG_ENCODING_KOI8         (&OnigEncodingKOI8) */
# define ONIG_ENCODING_KOI8_R       (&OnigEncodingKOI8_R)
# define ONIG_ENCODING_KOI8_U       (&OnigEncodingKOI8_U)
# define ONIG_ENCODING_WINDOWS_1250 (&OnigEncodingWindows_1250)
# define ONIG_ENCODING_WINDOWS_1251 (&OnigEncodingWindows_1251)
# define ONIG_ENCODING_WINDOWS_1252 (&OnigEncodingWindows_1252)
# define ONIG_ENCODING_WINDOWS_1253 (&OnigEncodingWindows_1253)
# define ONIG_ENCODING_WINDOWS_1254 (&OnigEncodingWindows_1254)
# define ONIG_ENCODING_WINDOWS_1257 (&OnigEncodingWindows_1257)
# define ONIG_ENCODING_BIG5         (&OnigEncodingBIG5)
# define ONIG_ENCODING_GB18030      (&OnigEncodingGB18030)

/* old names */
# define ONIG_ENCODING_SJIS         ONIG_ENCODING_SHIFT_JIS
# define ONIG_ENCODING_CP932        ONIG_ENCODING_WINDOWS_31J
# define ONIG_ENCODING_CP1250       ONIG_ENCODING_WINDOWS_1250
# define ONIG_ENCODING_CP1251       ONIG_ENCODING_WINDOWS_1251
# define ONIG_ENCODING_CP1252       ONIG_ENCODING_WINDOWS_1252
# define ONIG_ENCODING_CP1253       ONIG_ENCODING_WINDOWS_1253
# define ONIG_ENCODING_CP1254       ONIG_ENCODING_WINDOWS_1254
# define ONIG_ENCODING_CP1257       ONIG_ENCODING_WINDOWS_1257
# define ONIG_ENCODING_UTF8         ONIG_ENCODING_UTF_8
# define ONIG_ENCODING_UTF16_BE     ONIG_ENCODING_UTF_16BE
# define ONIG_ENCODING_UTF16_LE     ONIG_ENCODING_UTF_16LE
# define ONIG_ENCODING_UTF32_BE     ONIG_ENCODING_UTF_32BE
# define ONIG_ENCODING_UTF32_LE     ONIG_ENCODING_UTF_32LE
#endif /* RUBY */

#define ONIG_ENCODING_UNDEF    ((OnigEncoding )0)

/* this declaration needs to be here because it is used in string.c in Ruby */
ONIG_EXTERN
int onigenc_ascii_only_case_map(OnigCaseFoldType* flagP, const OnigUChar** pp, const OnigUChar* end, OnigUChar* to, OnigUChar* to_end, const struct OnigEncodingTypeST* enc);


/* work size */
#define ONIGENC_CODE_TO_MBC_MAXLEN       7
#define ONIGENC_MBC_CASE_FOLD_MAXLEN    18
/* 18: 6(max-byte) * 3(case-fold chars) */

/* character types */
#define ONIGENC_CTYPE_NEWLINE   0
#define ONIGENC_CTYPE_ALPHA     1
#define ONIGENC_CTYPE_BLANK     2
#define ONIGENC_CTYPE_CNTRL     3
#define ONIGENC_CTYPE_DIGIT     4
#define ONIGENC_CTYPE_GRAPH     5
#define ONIGENC_CTYPE_LOWER     6
#define ONIGENC_CTYPE_PRINT     7
#define ONIGENC_CTYPE_PUNCT     8
#define ONIGENC_CTYPE_SPACE     9
#define ONIGENC_CTYPE_UPPER    10
#define ONIGENC_CTYPE_XDIGIT   11
#define ONIGENC_CTYPE_WORD     12
#define ONIGENC_CTYPE_ALNUM    13  /* alpha || digit */
#define ONIGENC_CTYPE_ASCII    14
#define ONIGENC_MAX_STD_CTYPE  ONIGENC_CTYPE_ASCII

/* flags */
#define ONIGENC_FLAG_NONE       0U
#define ONIGENC_FLAG_UNICODE    1U

#define onig_enc_len(enc,p,e)          ONIGENC_MBC_ENC_LEN(enc, p, e)

#define ONIGENC_IS_UNDEF(enc)          ((enc) == ONIG_ENCODING_UNDEF)
#define ONIGENC_IS_SINGLEBYTE(enc)     (ONIGENC_MBC_MAXLEN(enc) == 1)
#define ONIGENC_IS_MBC_HEAD(enc,p,e)   (ONIGENC_MBC_ENC_LEN(enc,p,e) != 1)
#define ONIGENC_IS_MBC_ASCII(p)           (*(p)   < 128)
#define ONIGENC_IS_CODE_ASCII(code)       ((code) < 128)
#define ONIGENC_IS_MBC_WORD(enc,s,end) \
   ONIGENC_IS_CODE_WORD(enc,ONIGENC_MBC_TO_CODE(enc,s,end))
#define ONIGENC_IS_MBC_ASCII_WORD(enc,s,end) \
   onigenc_ascii_is_code_ctype( \
	ONIGENC_MBC_TO_CODE(enc,s,end),ONIGENC_CTYPE_WORD,enc)
#define ONIGENC_IS_UNICODE(enc)        ((enc)->flags & ONIGENC_FLAG_UNICODE)


#define ONIGENC_NAME(enc)                      ((enc)->name)

#define ONIGENC_MBC_CASE_FOLD(enc,flag,pp,end,buf) \
  (enc)->mbc_case_fold(flag,(const OnigUChar** )pp,end,buf,enc)
#define ONIGENC_IS_ALLOWED_REVERSE_MATCH(enc,s,end) \
        (enc)->is_allowed_reverse_match(s,end,enc)
#define ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc,start,s,end) \
        (enc)->left_adjust_char_head(start, s, end, enc)
#define ONIGENC_APPLY_ALL_CASE_FOLD(enc,case_fold_flag,f,arg) \
        (enc)->apply_all_case_fold(case_fold_flag,f,arg,enc)
#define ONIGENC_GET_CASE_FOLD_CODES_BY_STR(enc,case_fold_flag,p,end,acs) \
       (enc)->get_case_fold_codes_by_str(case_fold_flag,p,end,acs,enc)
#define ONIGENC_STEP_BACK(enc,start,s,end,n) \
        onigenc_step_back((enc),(start),(s),(end),(n))

#define ONIGENC_CONSTRUCT_MBCLEN_CHARFOUND(n)   (n)
#define ONIGENC_MBCLEN_CHARFOUND_P(r)           (0 < (r))
#define ONIGENC_MBCLEN_CHARFOUND_LEN(r)         (r)

#define ONIGENC_CONSTRUCT_MBCLEN_INVALID()      (-1)
#define ONIGENC_MBCLEN_INVALID_P(r)             ((r) == -1)

#define ONIGENC_CONSTRUCT_MBCLEN_NEEDMORE(n)    (-1-(n))
#define ONIGENC_MBCLEN_NEEDMORE_P(r)            ((r) < -1)
#define ONIGENC_MBCLEN_NEEDMORE_LEN(r)          (-1-(r))

#define ONIGENC_PRECISE_MBC_ENC_LEN(enc,p,e)   (enc)->precise_mbc_enc_len(p,e,enc)

ONIG_EXTERN
int onigenc_mbclen(const OnigUChar* p,const OnigUChar* e, const struct OnigEncodingTypeST* enc);

#define ONIGENC_MBC_ENC_LEN(enc,p,e)           onigenc_mbclen(p,e,enc)
#define ONIGENC_MBC_MAXLEN(enc)               ((enc)->max_enc_len)
#define ONIGENC_MBC_MAXLEN_DIST(enc)           ONIGENC_MBC_MAXLEN(enc)
#define ONIGENC_MBC_MINLEN(enc)               ((enc)->min_enc_len)
#define ONIGENC_IS_MBC_NEWLINE(enc,p,end)      (enc)->is_mbc_newline((p),(end),enc)
#define ONIGENC_MBC_TO_CODE(enc,p,end)         (enc)->mbc_to_code((p),(end),enc)
#define ONIGENC_CODE_TO_MBCLEN(enc,code)       (enc)->code_to_mbclen(code,enc)
#define ONIGENC_CODE_TO_MBC(enc,code,buf)      (enc)->code_to_mbc(code,buf,enc)
#define ONIGENC_PROPERTY_NAME_TO_CTYPE(enc,p,end) \
  (enc)->property_name_to_ctype(enc,p,end)

#define ONIGENC_IS_CODE_CTYPE(enc,code,ctype)  (enc)->is_code_ctype(code,ctype,enc)

#define ONIGENC_IS_CODE_NEWLINE(enc,code) \
        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_NEWLINE)
#define ONIGENC_IS_CODE_GRAPH(enc,code) \
        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_GRAPH)
#define ONIGENC_IS_CODE_PRINT(enc,code) \
        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_PRINT)
#define ONIGENC_IS_CODE_ALNUM(enc,code) \
        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_ALNUM)
#define ONIGENC_IS_CODE_ALPHA(enc,code) \
        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_ALPHA)
#define ONIGENC_IS_CODE_LOWER(enc,code) \
        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_LOWER)
#define ONIGENC_IS_CODE_UPPER(enc,code) \
        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_UPPER)
#define ONIGENC_IS_CODE_CNTRL(enc,code) \
        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_CNTRL)
#define ONIGENC_IS_CODE_PUNCT(enc,code) \
        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_PUNCT)
#define ONIGENC_IS_CODE_SPACE(enc,code) \
        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_SPACE)
#define ONIGENC_IS_CODE_BLANK(enc,code) \
        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_BLANK)
#define ONIGENC_IS_CODE_DIGIT(enc,code) \
        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_DIGIT)
#define ONIGENC_IS_CODE_XDIGIT(enc,code) \
        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_XDIGIT)
#define ONIGENC_IS_CODE_WORD(enc,code) \
        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_WORD)

#define ONIGENC_GET_CTYPE_CODE_RANGE(enc,ctype,sbout,ranges) \
        (enc)->get_ctype_code_range(ctype,sbout,ranges,enc)

ONIG_EXTERN
OnigUChar* onigenc_step_back(OnigEncoding enc, const OnigUChar* start, const OnigUChar* s, const OnigUChar* end, int n);


/* encoding API */
ONIG_EXTERN
int onigenc_init(void);
ONIG_EXTERN
int onigenc_set_default_encoding(OnigEncoding enc);
ONIG_EXTERN
OnigEncoding onigenc_get_default_encoding(void);
ONIG_EXTERN
OnigUChar* onigenc_get_right_adjust_char_head_with_prev(OnigEncoding enc, const OnigUChar* start, const OnigUChar* s, const OnigUChar* end, const OnigUChar** prev);
ONIG_EXTERN
OnigUChar* onigenc_get_prev_char_head(OnigEncoding enc, const OnigUChar* start, const OnigUChar* s, const OnigUChar* end);
ONIG_EXTERN
OnigUChar* onigenc_get_left_adjust_char_head(OnigEncoding enc, const OnigUChar* start, const OnigUChar* s, const OnigUChar* end);
ONIG_EXTERN
OnigUChar* onigenc_get_right_adjust_char_head(OnigEncoding enc, const OnigUChar* start, const OnigUChar* s, const OnigUChar* end);
ONIG_EXTERN
int onigenc_strlen(OnigEncoding enc, const OnigUChar* p, const OnigUChar* end);
ONIG_EXTERN
int onigenc_strlen_null(OnigEncoding enc, const OnigUChar* p);
ONIG_EXTERN
int onigenc_str_bytelen_null(OnigEncoding enc, const OnigUChar* p);



/* PART: regular expression */

/* config parameters */
#define ONIG_NREGION                          4
#define ONIG_MAX_CAPTURE_GROUP_NUM         32767
#define ONIG_MAX_BACKREF_NUM                1000
#define ONIG_MAX_REPEAT_NUM               100000
#define ONIG_MAX_MULTI_BYTE_RANGES_NUM     10000
/* constants */
#define ONIG_MAX_ERROR_MESSAGE_LEN            90

typedef unsigned int        OnigOptionType;

#define ONIG_OPTION_DEFAULT            ONIG_OPTION_NONE

/* options */
#define ONIG_OPTION_NONE                 0U
#define ONIG_OPTION_IGNORECASE           1U
#define ONIG_OPTION_EXTEND               (ONIG_OPTION_IGNORECASE         << 1)
#define ONIG_OPTION_MULTILINE            (ONIG_OPTION_EXTEND             << 1)
#define ONIG_OPTION_DOTALL                ONIG_OPTION_MULTILINE
#define ONIG_OPTION_SINGLELINE           (ONIG_OPTION_MULTILINE          << 1)
#define ONIG_OPTION_FIND_LONGEST         (ONIG_OPTION_SINGLELINE         << 1)
#define ONIG_OPTION_FIND_NOT_EMPTY       (ONIG_OPTION_FIND_LONGEST       << 1)
#define ONIG_OPTION_NEGATE_SINGLELINE    (ONIG_OPTION_FIND_NOT_EMPTY     << 1)
#define ONIG_OPTION_DONT_CAPTURE_GROUP   (ONIG_OPTION_NEGATE_SINGLELINE  << 1)
#define ONIG_OPTION_CAPTURE_GROUP        (ONIG_OPTION_DONT_CAPTURE_GROUP << 1)
/* options (search time) */
#define ONIG_OPTION_NOTBOL               (ONIG_OPTION_CAPTURE_GROUP << 1)
#define ONIG_OPTION_NOTEOL               (ONIG_OPTION_NOTBOL << 1)
#define ONIG_OPTION_NOTBOS               (ONIG_OPTION_NOTEOL << 1)
#define ONIG_OPTION_NOTEOS               (ONIG_OPTION_NOTBOS << 1)
/* options (ctype range) */
#define ONIG_OPTION_ASCII_RANGE          (ONIG_OPTION_NOTEOS << 1)
#define ONIG_OPTION_POSIX_BRACKET_ALL_RANGE (ONIG_OPTION_ASCII_RANGE << 1)
#define ONIG_OPTION_WORD_BOUND_ALL_RANGE    (ONIG_OPTION_POSIX_BRACKET_ALL_RANGE << 1)
/* options (newline) */
#define ONIG_OPTION_NEWLINE_CRLF         (ONIG_OPTION_WORD_BOUND_ALL_RANGE << 1)
#define ONIG_OPTION_MAXBIT               ONIG_OPTION_NEWLINE_CRLF  /* limit */

#define ONIG_OPTION_ON(options,regopt)      ((options) |= (regopt))
#define ONIG_OPTION_OFF(options,regopt)     ((options) &= ~(regopt))
#define ONIG_IS_OPTION_ON(options,option)   ((options) & (option))

/* syntax */
typedef struct {
  unsigned int   op;
  unsigned int   op2;
  unsigned int   behavior;
  OnigOptionType options;   /* default option */
  OnigMetaCharTableType meta_char_table;
} OnigSyntaxType;

ONIG_EXTERN const OnigSyntaxType OnigSyntaxASIS;
ONIG_EXTERN const OnigSyntaxType OnigSyntaxPosixBasic;
ONIG_EXTERN const OnigSyntaxType OnigSyntaxPosixExtended;
ONIG_EXTERN const OnigSyntaxType OnigSyntaxEmacs;
ONIG_EXTERN const OnigSyntaxType OnigSyntaxGrep;
ONIG_EXTERN const OnigSyntaxType OnigSyntaxGnuRegex;
ONIG_EXTERN const OnigSyntaxType OnigSyntaxJava;
ONIG_EXTERN const OnigSyntaxType OnigSyntaxPerl58;
ONIG_EXTERN const OnigSyntaxType OnigSyntaxPerl58_NG;
ONIG_EXTERN const OnigSyntaxType OnigSyntaxPerl;
ONIG_EXTERN const OnigSyntaxType OnigSyntaxRuby;
ONIG_EXTERN const OnigSyntaxType OnigSyntaxPython;

/* predefined syntaxes (see regsyntax.c) */
#define ONIG_SYNTAX_ASIS               (&OnigSyntaxASIS)
#define ONIG_SYNTAX_POSIX_BASIC        (&OnigSyntaxPosixBasic)
#define ONIG_SYNTAX_POSIX_EXTENDED     (&OnigSyntaxPosixExtended)
#define ONIG_SYNTAX_EMACS              (&OnigSyntaxEmacs)
#define ONIG_SYNTAX_GREP               (&OnigSyntaxGrep)
#define ONIG_SYNTAX_GNU_REGEX          (&OnigSyntaxGnuRegex)
#define ONIG_SYNTAX_JAVA               (&OnigSyntaxJava)
#define ONIG_SYNTAX_PERL58             (&OnigSyntaxPerl58)
#define ONIG_SYNTAX_PERL58_NG          (&OnigSyntaxPerl58_NG)
#define ONIG_SYNTAX_PERL               (&OnigSyntaxPerl)
#define ONIG_SYNTAX_RUBY               (&OnigSyntaxRuby)
#define ONIG_SYNTAX_PYTHON             (&OnigSyntaxPython)

/* default syntax */
ONIG_EXTERN const OnigSyntaxType*   OnigDefaultSyntax;
#define ONIG_SYNTAX_DEFAULT   OnigDefaultSyntax

/* syntax (operators) */
#define ONIG_SYN_OP_VARIABLE_META_CHARACTERS    (1U<<0)
#define ONIG_SYN_OP_DOT_ANYCHAR                 (1U<<1)   /* . */
#define ONIG_SYN_OP_ASTERISK_ZERO_INF           (1U<<2)   /* * */
#define ONIG_SYN_OP_ESC_ASTERISK_ZERO_INF       (1U<<3)
#define ONIG_SYN_OP_PLUS_ONE_INF                (1U<<4)   /* + */
#define ONIG_SYN_OP_ESC_PLUS_ONE_INF            (1U<<5)
#define ONIG_SYN_OP_QMARK_ZERO_ONE              (1U<<6)   /* ? */
#define ONIG_SYN_OP_ESC_QMARK_ZERO_ONE          (1U<<7)
#define ONIG_SYN_OP_BRACE_INTERVAL              (1U<<8)   /* {lower,upper} */
#define ONIG_SYN_OP_ESC_BRACE_INTERVAL          (1U<<9)   /* \{lower,upper\} */
#define ONIG_SYN_OP_VBAR_ALT                    (1U<<10)   /* | */
#define ONIG_SYN_OP_ESC_VBAR_ALT                (1U<<11)  /* \| */
#define ONIG_SYN_OP_LPAREN_SUBEXP               (1U<<12)  /* (...)   */
#define ONIG_SYN_OP_ESC_LPAREN_SUBEXP           (1U<<13)  /* \(...\) */
#define ONIG_SYN_OP_ESC_AZ_BUF_ANCHOR           (1U<<14)  /* \A, \Z, \z */
#define ONIG_SYN_OP_ESC_CAPITAL_G_BEGIN_ANCHOR  (1U<<15)  /* \G     */
#define ONIG_SYN_OP_DECIMAL_BACKREF             (1U<<16)  /* \num   */
#define ONIG_SYN_OP_BRACKET_CC                  (1U<<17)  /* [...]  */
#define ONIG_SYN_OP_ESC_W_WORD                  (1U<<18)  /* \w, \W */
#define ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END     (1U<<19)  /* \<. \> */
#define ONIG_SYN_OP_ESC_B_WORD_BOUND            (1U<<20)  /* \b, \B */
#define ONIG_SYN_OP_ESC_S_WHITE_SPACE           (1U<<21)  /* \s, \S */
#define ONIG_SYN_OP_ESC_D_DIGIT                 (1U<<22)  /* \d, \D */
#define ONIG_SYN_OP_LINE_ANCHOR                 (1U<<23)  /* ^, $   */
#define ONIG_SYN_OP_POSIX_BRACKET               (1U<<24)  /* [:xxxx:] */
#define ONIG_SYN_OP_QMARK_NON_GREEDY            (1U<<25)  /* ??,*?,+?,{n,m}? */
#define ONIG_SYN_OP_ESC_CONTROL_CHARS           (1U<<26)  /* \n,\r,\t,\a ... */
#define ONIG_SYN_OP_ESC_C_CONTROL               (1U<<27)  /* \cx  */
#define ONIG_SYN_OP_ESC_OCTAL3                  (1U<<28)  /* \OOO */
#define ONIG_SYN_OP_ESC_X_HEX2                  (1U<<29)  /* \xHH */
#define ONIG_SYN_OP_ESC_X_BRACE_HEX8            (1U<<30)  /* \x{7HHHHHHH} */
#define ONIG_SYN_OP_ESC_O_BRACE_OCTAL           (1U<<31)  /* \o{OOO} */

#define ONIG_SYN_OP2_ESC_CAPITAL_Q_QUOTE        (1U<<0)  /* \Q...\E */
#define ONIG_SYN_OP2_QMARK_GROUP_EFFECT         (1U<<1)  /* (?...) */
#define ONIG_SYN_OP2_OPTION_PERL                (1U<<2)  /* (?imsxadlu), (?-imsx), (?^imsxalu) */
#define ONIG_SYN_OP2_OPTION_RUBY                (1U<<3)  /* (?imxadu), (?-imx)  */
#define ONIG_SYN_OP2_PLUS_POSSESSIVE_REPEAT     (1U<<4)  /* ?+,*+,++ */
#define ONIG_SYN_OP2_PLUS_POSSESSIVE_INTERVAL   (1U<<5)  /* {n,m}+   */
#define ONIG_SYN_OP2_CCLASS_SET_OP              (1U<<6)  /* [...&&..[..]..] */
#define ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP       (1U<<7)  /* (?<name>...) */
#define ONIG_SYN_OP2_ESC_K_NAMED_BACKREF        (1U<<8)  /* \k<name> */
#define ONIG_SYN_OP2_ESC_G_SUBEXP_CALL          (1U<<9)  /* \g<name>, \g<n> */
#define ONIG_SYN_OP2_ATMARK_CAPTURE_HISTORY     (1U<<10) /* (?@..),(?@<x>..) */
#define ONIG_SYN_OP2_ESC_CAPITAL_C_BAR_CONTROL  (1U<<11) /* \C-x */
#define ONIG_SYN_OP2_ESC_CAPITAL_M_BAR_META     (1U<<12) /* \M-x */
#define ONIG_SYN_OP2_ESC_V_VTAB                 (1U<<13) /* \v as VTAB */
#define ONIG_SYN_OP2_ESC_U_HEX4                 (1U<<14) /* \uHHHH */
#define ONIG_SYN_OP2_ESC_GNU_BUF_ANCHOR         (1U<<15) /* \`, \' */
#define ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY  (1U<<16) /* \p{...}, \P{...} */
#define ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT (1U<<17) /* \p{^..}, \P{^..} */
/* #define ONIG_SYN_OP2_CHAR_PROPERTY_PREFIX_IS (1U<<18) */
#define ONIG_SYN_OP2_ESC_H_XDIGIT               (1U<<19) /* \h, \H */
#define ONIG_SYN_OP2_INEFFECTIVE_ESCAPE         (1U<<20) /* \ */
#define ONIG_SYN_OP2_ESC_CAPITAL_R_LINEBREAK    (1U<<21) /* \R as (?>\x0D\x0A|[\x0A-\x0D\x{85}\x{2028}\x{2029}]) */
#define ONIG_SYN_OP2_ESC_CAPITAL_X_EXTENDED_GRAPHEME_CLUSTER (1U<<22) /* \X */
#define ONIG_SYN_OP2_ESC_V_VERTICAL_WHITESPACE   (1U<<23) /* \v, \V -- Perl */ /* NOTIMPL */
#define ONIG_SYN_OP2_ESC_H_HORIZONTAL_WHITESPACE (1U<<24) /* \h, \H -- Perl */ /* NOTIMPL */
#define ONIG_SYN_OP2_ESC_CAPITAL_K_KEEP         (1U<<25) /* \K */
#define ONIG_SYN_OP2_ESC_G_BRACE_BACKREF        (1U<<26) /* \g{name}, \g{n} */
#define ONIG_SYN_OP2_QMARK_SUBEXP_CALL          (1U<<27) /* (?&name), (?n), (?R), (?0) */
#define ONIG_SYN_OP2_QMARK_VBAR_BRANCH_RESET    (1U<<28) /* (?|...) */         /* NOTIMPL */
#define ONIG_SYN_OP2_QMARK_LPAREN_CONDITION     (1U<<29) /* (?(cond)yes...|no...) */
#define ONIG_SYN_OP2_QMARK_CAPITAL_P_NAMED_GROUP (1U<<30) /* (?P<name>...), (?P=name), (?P>name) -- Python/PCRE */
#define ONIG_SYN_OP2_QMARK_TILDE_ABSENT         (1U<<31) /* (?~...) */
/* #define ONIG_SYN_OP2_OPTION_JAVA                (1U<<xx) */ /* (?idmsux), (?-idmsux) */ /* NOTIMPL */

/* syntax (behavior) */
#define ONIG_SYN_CONTEXT_INDEP_ANCHORS           (1U<<31) /* not implemented */
#define ONIG_SYN_CONTEXT_INDEP_REPEAT_OPS        (1U<<0)  /* ?, *, +, {n,m} */
#define ONIG_SYN_CONTEXT_INVALID_REPEAT_OPS      (1U<<1)  /* error or ignore */
#define ONIG_SYN_ALLOW_UNMATCHED_CLOSE_SUBEXP    (1U<<2)  /* ...)... */
#define ONIG_SYN_ALLOW_INVALID_INTERVAL          (1U<<3)  /* {??? */
#define ONIG_SYN_ALLOW_INTERVAL_LOW_ABBREV       (1U<<4)  /* {,n} => {0,n} */
#define ONIG_SYN_STRICT_CHECK_BACKREF            (1U<<5)  /* /(\1)/,/\1()/ ..*/
#define ONIG_SYN_DIFFERENT_LEN_ALT_LOOK_BEHIND   (1U<<6)  /* (?<=a|bc) */
#define ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP        (1U<<7)  /* see doc/RE */
#define ONIG_SYN_ALLOW_MULTIPLEX_DEFINITION_NAME (1U<<8)  /* (?<x>)(?<x>) */
#define ONIG_SYN_FIXED_INTERVAL_IS_GREEDY_ONLY   (1U<<9)  /* a{n}?=(?:a{n})? */
#define ONIG_SYN_ALLOW_MULTIPLEX_DEFINITION_NAME_CALL (1U<<10)  /* (?<x>)(?<x>)(?&x) */
#define ONIG_SYN_USE_LEFT_MOST_NAMED_GROUP       (1U<<11) /* (?<x>)(?<x>)\k<x> */

/* syntax (behavior) in char class [...] */
#define ONIG_SYN_NOT_NEWLINE_IN_NEGATIVE_CC      (1U<<20) /* [^...] */
#define ONIG_SYN_BACKSLASH_ESCAPE_IN_CC          (1U<<21) /* [..\w..] etc.. */
#define ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC         (1U<<22)
#define ONIG_SYN_ALLOW_DOUBLE_RANGE_OP_IN_CC     (1U<<23) /* [0-9-a]=[0-9\-a] */
/* syntax (behavior) warning */
#define ONIG_SYN_WARN_CC_OP_NOT_ESCAPED          (1U<<24) /* [,-,] */
#define ONIG_SYN_WARN_REDUNDANT_NESTED_REPEAT    (1U<<25) /* (?:a*)+ */
#define ONIG_SYN_WARN_CC_DUP                     (1U<<26) /* [aa] */

/* meta character specifiers (onig_set_meta_char()) */
#define ONIG_META_CHAR_ESCAPE               0
#define ONIG_META_CHAR_ANYCHAR              1
#define ONIG_META_CHAR_ANYTIME              2
#define ONIG_META_CHAR_ZERO_OR_ONE_TIME     3
#define ONIG_META_CHAR_ONE_OR_MORE_TIME     4
#define ONIG_META_CHAR_ANYCHAR_ANYTIME      5

#define ONIG_INEFFECTIVE_META_CHAR          0

/* error codes */
#define ONIG_IS_PATTERN_ERROR(ecode)   ((ecode) <= -100 && (ecode) > -1000)
/* normal return */
#define ONIG_NORMAL                                            0
#define ONIG_MISMATCH                                         -1
#define ONIG_NO_SUPPORT_CONFIG                                -2

/* internal error */
#define ONIGERR_MEMORY                                         -5
#define ONIGERR_TYPE_BUG                                       -6
#define ONIGERR_PARSER_BUG                                    -11
#define ONIGERR_STACK_BUG                                     -12
#define ONIGERR_UNDEFINED_BYTECODE                            -13
#define ONIGERR_UNEXPECTED_BYTECODE                           -14
#define ONIGERR_MATCH_STACK_LIMIT_OVER                        -15
#define ONIGERR_PARSE_DEPTH_LIMIT_OVER                        -16
#define ONIGERR_DEFAULT_ENCODING_IS_NOT_SET                   -21
#define ONIGERR_SPECIFIED_ENCODING_CANT_CONVERT_TO_WIDE_CHAR  -22
#define ONIGERR_TIMEOUT                                       -23
/* general error */
#define ONIGERR_INVALID_ARGUMENT                              -30
/* syntax error */
#define ONIGERR_END_PATTERN_AT_LEFT_BRACE                    -100
#define ONIGERR_END_PATTERN_AT_LEFT_BRACKET                  -101
#define ONIGERR_EMPTY_CHAR_CLASS                             -102
#define ONIGERR_PREMATURE_END_OF_CHAR_CLASS                  -103
#define ONIGERR_END_PATTERN_AT_ESCAPE                        -104
#define ONIGERR_END_PATTERN_AT_META                          -105
#define ONIGERR_END_PATTERN_AT_CONTROL                       -106
#define ONIGERR_META_CODE_SYNTAX                             -108
#define ONIGERR_CONTROL_CODE_SYNTAX                          -109
#define ONIGERR_CHAR_CLASS_VALUE_AT_END_OF_RANGE             -110
#define ONIGERR_CHAR_CLASS_VALUE_AT_START_OF_RANGE           -111
#define ONIGERR_UNMATCHED_RANGE_SPECIFIER_IN_CHAR_CLASS      -112
#define ONIGERR_TARGET_OF_REPEAT_OPERATOR_NOT_SPECIFIED      -113
#define ONIGERR_TARGET_OF_REPEAT_OPERATOR_INVALID            -114
#define ONIGERR_NESTED_REPEAT_OPERATOR                       -115
#define ONIGERR_UNMATCHED_CLOSE_PARENTHESIS                  -116
#define ONIGERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS       -117
#define ONIGERR_END_PATTERN_IN_GROUP                         -118
#define ONIGERR_UNDEFINED_GROUP_OPTION                       -119
#define ONIGERR_INVALID_POSIX_BRACKET_TYPE                   -121
#define ONIGERR_INVALID_LOOK_BEHIND_PATTERN                  -122
#define ONIGERR_INVALID_REPEAT_RANGE_PATTERN                 -123
#define ONIGERR_INVALID_CONDITION_PATTERN                    -124
/* values error (syntax error) */
#define ONIGERR_TOO_BIG_NUMBER                               -200
#define ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE              -201
#define ONIGERR_UPPER_SMALLER_THAN_LOWER_IN_REPEAT_RANGE     -202
#define ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS                    -203
#define ONIGERR_MISMATCH_CODE_LENGTH_IN_CLASS_RANGE          -204
#define ONIGERR_TOO_MANY_MULTI_BYTE_RANGES                   -205
#define ONIGERR_TOO_SHORT_MULTI_BYTE_STRING                  -206
#define ONIGERR_TOO_BIG_BACKREF_NUMBER                       -207
#define ONIGERR_INVALID_BACKREF                              -208
#define ONIGERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED         -209
#define ONIGERR_TOO_MANY_CAPTURE_GROUPS                      -210
#define ONIGERR_TOO_SHORT_DIGITS                             -211
#define ONIGERR_TOO_LONG_WIDE_CHAR_VALUE                     -212
#define ONIGERR_EMPTY_GROUP_NAME                             -214
#define ONIGERR_INVALID_GROUP_NAME                           -215
#define ONIGERR_INVALID_CHAR_IN_GROUP_NAME                   -216
#define ONIGERR_UNDEFINED_NAME_REFERENCE                     -217
#define ONIGERR_UNDEFINED_GROUP_REFERENCE                    -218
#define ONIGERR_MULTIPLEX_DEFINED_NAME                       -219
#define ONIGERR_MULTIPLEX_DEFINITION_NAME_CALL               -220
#define ONIGERR_NEVER_ENDING_RECURSION                       -221
#define ONIGERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY        -222
#define ONIGERR_INVALID_CHAR_PROPERTY_NAME                   -223
#define ONIGERR_INVALID_CODE_POINT_VALUE                     -400
#define ONIGERR_INVALID_WIDE_CHAR_VALUE                      -400
#define ONIGERR_TOO_BIG_WIDE_CHAR_VALUE                      -401
#define ONIGERR_NOT_SUPPORTED_ENCODING_COMBINATION           -402
#define ONIGERR_INVALID_COMBINATION_OF_OPTIONS               -403

/* errors related to thread */
/* #define ONIGERR_OVER_THREAD_PASS_LIMIT_COUNT                -1001 */


/* must be smaller than BIT_STATUS_BITS_NUM (unsigned int * 8) */
#define ONIG_MAX_CAPTURE_HISTORY_GROUP   31
#define ONIG_IS_CAPTURE_HISTORY_GROUP(r, i) \
  ((i) <= ONIG_MAX_CAPTURE_HISTORY_GROUP && (r)->list && (r)->list[i])

#ifdef USE_CAPTURE_HISTORY
typedef struct OnigCaptureTreeNodeStruct {
  int group;   /* group number */
  OnigPosition beg;
  OnigPosition end;
  int allocated;
  int num_childs;
  struct OnigCaptureTreeNodeStruct** childs;
} OnigCaptureTreeNode;
#endif

/* match result region type */
struct re_registers {
  int  allocated;
  int  num_regs;
  OnigPosition* beg;
  OnigPosition* end;
#ifdef USE_CAPTURE_HISTORY
  /* extended */
  OnigCaptureTreeNode* history_root;  /* capture history tree root */
#endif
};

/* capture tree traverse */
#define ONIG_TRAVERSE_CALLBACK_AT_FIRST   1
#define ONIG_TRAVERSE_CALLBACK_AT_LAST    2
#define ONIG_TRAVERSE_CALLBACK_AT_BOTH \
  ( ONIG_TRAVERSE_CALLBACK_AT_FIRST | ONIG_TRAVERSE_CALLBACK_AT_LAST )


#define ONIG_REGION_NOTPOS            -1

typedef struct re_registers   OnigRegion;

typedef struct {
  OnigEncoding enc;
  OnigUChar* par;
  OnigUChar* par_end;
} OnigErrorInfo;

typedef struct {
  int lower;
  int upper;
} OnigRepeatRange;

typedef void (*OnigWarnFunc)(const char* s);
extern void onig_null_warn(const char* s);
#define ONIG_NULL_WARN       onig_null_warn

#define ONIG_CHAR_TABLE_SIZE   256

typedef struct re_pattern_buffer {
  /* common members of BBuf(bytes-buffer) */
  unsigned char* p;         /* compiled pattern */
  unsigned int used;        /* used space for p */
  unsigned int alloc;       /* allocated space for p */

  int num_mem;                   /* used memory(...) num counted from 1 */
  int num_repeat;                /* OP_REPEAT/OP_REPEAT_NG id-counter */
  int num_null_check;            /* OP_NULL_CHECK_START/END id counter */
  int num_comb_exp_check;        /* combination explosion check */
  int num_call;                  /* number of subexp call */
  unsigned int capture_history;  /* (?@...) flag (1-31) */
  unsigned int bt_mem_start;     /* need backtrack flag */
  unsigned int bt_mem_end;       /* need backtrack flag */
  int stack_pop_level;
  int repeat_range_alloc;

  OnigOptionType    options;

  OnigRepeatRange* repeat_range;

  OnigEncoding      enc;
  const OnigSyntaxType* syntax;
  void*             name_table;
  OnigCaseFoldType  case_fold_flag;

  /* optimization info (string search, char-map and anchors) */
  int            optimize;          /* optimize flag */
  int            threshold_len;     /* search str-length for apply optimize */
  int            anchor;            /* BEGIN_BUF, BEGIN_POS, (SEMI_)END_BUF */
  OnigDistance   anchor_dmin;       /* (SEMI_)END_BUF anchor distance */
  OnigDistance   anchor_dmax;       /* (SEMI_)END_BUF anchor distance */
  int            sub_anchor;        /* start-anchor for exact or map */
  unsigned char *exact;
  unsigned char *exact_end;
  unsigned char  map[ONIG_CHAR_TABLE_SIZE]; /* used as BM skip or char-map */
  int           *int_map;                   /* BM skip for exact_len > 255 */
  int           *int_map_backward;          /* BM skip for backward search */
  OnigDistance   dmin;                      /* min-distance of exact or map */
  OnigDistance   dmax;                      /* max-distance of exact or map */

  /* rb_hrtime_t from hrtime.h */
#ifdef MY_RUBY_BUILD_MAY_TIME_TRAVEL
  int128_t timelimit;
#else
  uint64_t timelimit;
#endif

  /* regex_t link chain */
  struct re_pattern_buffer* chain;  /* escape compile-conflict */
} OnigRegexType;

typedef OnigRegexType*  OnigRegex;

#ifndef ONIG_ESCAPE_REGEX_T_COLLISION
typedef OnigRegexType  regex_t;
#endif


typedef struct {
  int             num_of_elements;
  OnigEncoding    pattern_enc;
  OnigEncoding    target_enc;
  const OnigSyntaxType* syntax;
  OnigOptionType  option;
  OnigCaseFoldType   case_fold_flag;
} OnigCompileInfo;

/* Oniguruma Native API */
ONIG_EXTERN
int onig_initialize(OnigEncoding encodings[], int n);
ONIG_EXTERN
int onig_init(void);
ONIG_EXTERN
int onig_error_code_to_str(OnigUChar* s, OnigPosition err_code, ...);
ONIG_EXTERN
void onig_set_warn_func(OnigWarnFunc f);
ONIG_EXTERN
void onig_set_verb_warn_func(OnigWarnFunc f);
ONIG_EXTERN
int onig_new(OnigRegex*, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigOptionType option, OnigEncoding enc, const OnigSyntaxType* syntax, OnigErrorInfo* einfo);
ONIG_EXTERN
int onig_reg_init(OnigRegex reg, OnigOptionType option, OnigCaseFoldType case_fold_flag, OnigEncoding enc, const OnigSyntaxType* syntax);
ONIG_EXTERN
int onig_new_without_alloc(OnigRegex, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigOptionType option, OnigEncoding enc, const OnigSyntaxType* syntax, OnigErrorInfo* einfo);
ONIG_EXTERN
int onig_new_deluxe(OnigRegex* reg, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigCompileInfo* ci, OnigErrorInfo* einfo);
ONIG_EXTERN
void onig_free(OnigRegex);
ONIG_EXTERN
void onig_free_body(OnigRegex);
ONIG_EXTERN
int onig_reg_copy(OnigRegex* reg, OnigRegex orig_reg);
ONIG_EXTERN
OnigPosition onig_scan(OnigRegex reg, const OnigUChar* str, const OnigUChar* end, OnigRegion* region, OnigOptionType option, int (*scan_callback)(OnigPosition, OnigPosition, OnigRegion*, void*), void* callback_arg);
ONIG_EXTERN
OnigPosition onig_search(OnigRegex, const OnigUChar* str, const OnigUChar* end, const OnigUChar* start, const OnigUChar* range, OnigRegion* region, OnigOptionType option);
ONIG_EXTERN
OnigPosition onig_search_gpos(OnigRegex, const OnigUChar* str, const OnigUChar* end, const OnigUChar* global_pos, const OnigUChar* start, const OnigUChar* range, OnigRegion* region, OnigOptionType option);
ONIG_EXTERN
OnigPosition onig_match(OnigRegex, const OnigUChar* str, const OnigUChar* end, const OnigUChar* at, OnigRegion* region, OnigOptionType option);
ONIG_EXTERN
int onig_check_linear_time(OnigRegex reg);
ONIG_EXTERN
OnigRegion* onig_region_new(void);
ONIG_EXTERN
void onig_region_init(OnigRegion* region);
ONIG_EXTERN
void onig_region_free(OnigRegion* region, int free_self);
ONIG_EXTERN
void onig_region_copy(OnigRegion* to, const OnigRegion* from);
ONIG_EXTERN
void onig_region_clear(OnigRegion* region);
ONIG_EXTERN
int onig_region_resize(OnigRegion* region, int n);
ONIG_EXTERN
int onig_region_set(OnigRegion* region, int at, int beg, int end);
ONIG_EXTERN
int onig_name_to_group_numbers(OnigRegex reg, const OnigUChar* name, const OnigUChar* name_end, int** nums);
ONIG_EXTERN
int onig_name_to_backref_number(OnigRegex reg, const OnigUChar* name, const OnigUChar* name_end, const OnigRegion *region);
ONIG_EXTERN
int onig_foreach_name(OnigRegex reg, int (*func)(const OnigUChar*, const OnigUChar*,int,int*,OnigRegex,void*), void* arg);
ONIG_EXTERN
int onig_number_of_names(const OnigRegexType *reg);
ONIG_EXTERN
int onig_number_of_captures(const OnigRegexType *reg);
ONIG_EXTERN
int onig_number_of_capture_histories(const OnigRegexType *reg);
#ifdef USE_CAPTURE_HISTORY
ONIG_EXTERN
OnigCaptureTreeNode* onig_get_capture_tree(OnigRegion* region);
#endif
ONIG_EXTERN
int onig_capture_tree_traverse(OnigRegion* region, int at, int(*callback_func)(int,OnigPosition,OnigPosition,int,int,void*), void* arg);
ONIG_EXTERN
int onig_noname_group_capture_is_active(const OnigRegexType *reg);
ONIG_EXTERN
OnigEncoding onig_get_encoding(const OnigRegexType *reg);
ONIG_EXTERN
OnigOptionType onig_get_options(const OnigRegexType *reg);
ONIG_EXTERN
OnigCaseFoldType onig_get_case_fold_flag(const OnigRegexType *reg);
ONIG_EXTERN
const OnigSyntaxType* onig_get_syntax(const OnigRegexType *reg);
ONIG_EXTERN
int onig_set_default_syntax(const OnigSyntaxType* syntax);
ONIG_EXTERN
void onig_copy_syntax(OnigSyntaxType* to, const OnigSyntaxType* from);
ONIG_EXTERN
unsigned int onig_get_syntax_op(const OnigSyntaxType* syntax);
ONIG_EXTERN
unsigned int onig_get_syntax_op2(const OnigSyntaxType* syntax);
ONIG_EXTERN
unsigned int onig_get_syntax_behavior(const OnigSyntaxType* syntax);
ONIG_EXTERN
OnigOptionType onig_get_syntax_options(const OnigSyntaxType* syntax);
ONIG_EXTERN
void onig_set_syntax_op(OnigSyntaxType* syntax, unsigned int op);
ONIG_EXTERN
void onig_set_syntax_op2(OnigSyntaxType* syntax, unsigned int op2);
ONIG_EXTERN
void onig_set_syntax_behavior(OnigSyntaxType* syntax, unsigned int behavior);
ONIG_EXTERN
void onig_set_syntax_options(OnigSyntaxType* syntax, OnigOptionType options);
ONIG_EXTERN
int onig_set_meta_char(OnigSyntaxType* syntax, unsigned int what, OnigCodePoint code);
ONIG_EXTERN
void onig_copy_encoding(OnigEncodingType *to, OnigEncoding from);
ONIG_EXTERN
OnigCaseFoldType onig_get_default_case_fold_flag(void);
ONIG_EXTERN
int onig_set_default_case_fold_flag(OnigCaseFoldType case_fold_flag);
ONIG_EXTERN
unsigned int onig_get_match_stack_limit_size(void);
ONIG_EXTERN
int onig_set_match_stack_limit_size(unsigned int size);
ONIG_EXTERN
unsigned int onig_get_parse_depth_limit(void);
ONIG_EXTERN
int onig_set_parse_depth_limit(unsigned int depth);
ONIG_EXTERN
int onig_end(void);
ONIG_EXTERN
const char* onig_version(void);
ONIG_EXTERN
const char* onig_copyright(void);

RUBY_SYMBOL_EXPORT_END

#ifdef __cplusplus
# if 0
{ /* satisfy cc-mode */
# endif
}
#endif

#endif /* ONIGMO_H */
ruby/regex.h000064400000001763151732674140007031 0ustar00#ifndef ONIGURUMA_REGEX_H                            /*-*-C++-*-vi:se ft=cpp:*/
#define ONIGURUMA_REGEX_H 1
/**
 * @author     $Author$
 * @copyright  Copyright (C) 1993-2007 Yukihiro Matsumoto
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 */
#if defined(__cplusplus)
extern "C" {
#if 0
} /* satisfy cc-mode */
#endif
#endif

#ifdef RUBY
#include "ruby/oniguruma.h"
#else
#include "oniguruma.h"
#endif

RUBY_SYMBOL_EXPORT_BEGIN

#ifndef ONIG_RUBY_M17N

ONIG_EXTERN OnigEncoding    OnigEncDefaultCharEncoding;

#define mbclen(p,e,enc)  rb_enc_mbclen((p),(e),(enc))

#endif /* ifndef ONIG_RUBY_M17N */

RUBY_SYMBOL_EXPORT_END

#if defined(__cplusplus)
#if 0
{ /* satisfy cc-mode */
#endif
}  /* extern "C" { */
#endif

#endif /* ONIGURUMA_REGEX_H */
ruby/encoding.h000064400000002440151732674140007476 0ustar00#ifndef RUBY_ENCODING_H                              /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_ENCODING_H 1
/**
 * @file
 * @author     $Author: matz $
 * @date       Thu May 24 11:49:41 JST 2007
 * @copyright  Copyright (C) 2007 Yukihiro Matsumoto
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @brief      Encoding relates APIs.
 *
 * These APIs are mainly for  implementing encodings themselves.  Encodings are
 * built on  top of  Ruby's core  CAPIs.  Though not  prohibited, there  can be
 * relatively less rooms for things in  this header file be useful when writing
 * an extension library.
 */
#include "ruby/ruby.h"

#include "ruby/internal/encoding/coderange.h"
#include "ruby/internal/encoding/ctype.h"
#include "ruby/internal/encoding/encoding.h"
#include "ruby/internal/encoding/pathname.h"
#include "ruby/internal/encoding/re.h"
#include "ruby/internal/encoding/sprintf.h"
#include "ruby/internal/encoding/string.h"
#include "ruby/internal/encoding/symbol.h"
#include "ruby/internal/encoding/transcode.h"

#endif /* RUBY_ENCODING_H */
ruby/ractor.h000064400000021332151732674140007203 0ustar00#ifndef RUBY_RACTOR_H                                /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_RACTOR_H 1

/**
 * @file
 * @author Koichi Sasada
 * @date Tue Nov 17 16:39:15 2020
 * @copyright Copyright (C) 2020 Yukihiro Matsumoto
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 */
#include "internal/dllexport.h"      /* RUBY_EXTERN is here */
#include "internal/fl_type.h"        /* FL_TEST_RAW is here */
#include "internal/special_consts.h" /* RB_SPECIAL_CONSTS_P is here */
#include "internal/stdbool.h"        /* bool is here */
#include "internal/value.h"          /* VALUE is here */

/** Type that defines a ractor-local storage. */
struct rb_ractor_local_storage_type {

    /**
     * A function to mark a ractor-local storage.
     *
     * @param[out]  ptr  A ractor-local storage.
     * @post        Ruby objects inside of `ptr` are marked.
     */
    void (*mark)(void *ptr);

    /**
     * A function to destruct a ractor-local storage.
     *
     * @param[out]  ptr  A ractor-local storage.
     * @post        `ptr` is not a valid pointer.
     */
    void (*free)(void *ptr);
    // TODO: update
};

/** (Opaque) struct that holds a ractor-local storage key. */
typedef struct rb_ractor_local_key_struct *rb_ractor_local_key_t;

RBIMPL_SYMBOL_EXPORT_BEGIN()

/**
 * `Ractor` class.
 *
 * @ingroup object
 */
RUBY_EXTERN VALUE rb_cRactor;

/**
 * Queries  the standard  input  of the  current Ractor  that  is calling  this
 * function.
 *
 * @return  An IO.
 * @note    This can be different from the process-global one.
 */
VALUE rb_ractor_stdin(void);

/**
 * Queries  the standard  output of  the current  Ractor that  is calling  this
 * function.
 *
 * @return  An IO.
 * @note    This can be different from the process-global one.
 */
VALUE rb_ractor_stdout(void);

/**
 * Queries  the standard  error  of the  current Ractor  that  is calling  this
 * function.
 *
 * @return  An IO.
 * @note    This can be different from the process-global one.
 */
VALUE rb_ractor_stderr(void);

/**
 * Assigns an  IO to  the standard  input of  the Ractor  that is  calling this
 * function.
 *
 * @param[in]  io  An IO.
 * @post       `io` is the standard input of the current ractor.
 * @post       In case the  calling Ractor is the main Ractor,  it also updates
 *             the process global ::rb_stdin.
 */
void rb_ractor_stdin_set(VALUE io);

/**
 * Assigns an  IO to  the standard output  of the Ractor  that is  calling this
 * function.
 *
 * @param[in]  io  An IO.
 * @post       `io` is the standard input of the current ractor.
 * @post       In case the  calling Ractor is the main Ractor,  it also updates
 *             the process global ::rb_stdout.
 */
void rb_ractor_stdout_set(VALUE io);

/**
 * Assigns an  IO to  the standard  error of  the Ractor  that is  calling this
 * function.
 *
 * @param[in]  io  An IO.
 * @post       `io` is the standard input of the current ractor.
 * @post       In case the  calling Ractor is the main Ractor,  it also updates
 *             the process global ::rb_stderr.
 */
void rb_ractor_stderr_set(VALUE io);

/**
 * Issues a new key.
 *
 * @return  A newly  issued ractor-local storage  key.  Keys issued  using this
 *          key can be associated to a Ruby object per Ractor.
 */
rb_ractor_local_key_t rb_ractor_local_storage_value_newkey(void);

/**
 * Queries the key.
 *
 * @param[in]  key        A ractor-local storage key to lookup.
 * @retval     RUBY_Qnil  No such key.
 * @retval     otherwise  A value corresponds to `key` in the current Ractor.
 * @note       This  cannot distinguish  between a  nonexistent key  and a  key
 *             exists and corresponds to ::RUBY_Qnil.
 */
VALUE rb_ractor_local_storage_value(rb_ractor_local_key_t key);

/**
 * Queries the key.
 *
 * @param[in]   key    A ractor-local storage key to lookup.
 * @param[out]  val    Return value buffer.
 * @retval      false  `key` not found.
 * @retval      true   `key` found.
 * @post        `val` is updated so that it  has the value corresponds to `key`
 *              in the current Ractor.
 */
bool rb_ractor_local_storage_value_lookup(rb_ractor_local_key_t key, VALUE *val);

/**
 * Associates the passed value to the passed key.
 *
 * @param[in]  key  A ractor-local storage key.
 * @param[in]  val  Arbitrary ruby object.
 * @post       `val` corresponds to `key` in the current Ractor.
 */
void  rb_ractor_local_storage_value_set(rb_ractor_local_key_t key, VALUE val);

/**
 * A type of ractor-local storage that destructs itself using ::ruby_xfree.
 *
 * @internal
 *
 * Why  it is  visible from  3rd party  extension libraries  is not  obvious to
 * @shyouhei.
 */
RUBY_EXTERN const struct rb_ractor_local_storage_type rb_ractor_local_storage_type_free;

/** @alias{rb_ractor_local_storage_type_free} */
#define RB_RACTOR_LOCAL_STORAGE_TYPE_FREE (&rb_ractor_local_storage_type_free)

/**
 * Extended version of rb_ractor_local_storage_value_newkey().  It additionally
 * takes the type of the issuing key.
 *
 * @param[in]  type  How  the  value associated  with  the  issuing key  should
 *                   behave.
 * @return     A newly issued ractor-local storage key, of type `type`.
 */
rb_ractor_local_key_t rb_ractor_local_storage_ptr_newkey(const struct rb_ractor_local_storage_type *type);

/**
 * Identical to rb_ractor_local_storage_value() except the return type.
 *
 * @param[in]  key        A ractor-local storage key to lookup.
 * @retval     NULL       No such key.
 * @retval     otherwise  A value corresponds to `key` in the current Ractor.
 */
void *rb_ractor_local_storage_ptr(rb_ractor_local_key_t key);

/**
 * Identical to rb_ractor_local_storage_value_set() except the parameter type.
 *
 * @param[in]  key  A ractor-local storage key.
 * @param[in]  ptr  A pointer that conforms `key`'s type.
 * @post       `ptr` corresponds to `key` in the current Ractor.
 */
void  rb_ractor_local_storage_ptr_set(rb_ractor_local_key_t key, void *ptr);

/**
 * Destructively  transforms the  passed object  so that  multiple Ractors  can
 * share it.  What is a shareable object  and what is not is a nuanced concept,
 * and @ko1  says the definition  can still change.  However  extension library
 * authors might interest to learn how to use #RUBY_TYPED_FROZEN_SHAREABLE.
 *
 * @param[out]  obj              Arbitrary ruby object to modify.
 * @exception   rb_eRactorError  Ractors cannot share `obj` by nature.
 * @return      Passed `obj`.
 * @post        Multiple Ractors can share `obj`.
 *
 * @internal
 *
 * In case an exception is raised, `obj` remains in an intermediate state where
 * some of its part is frozen and others  are not.  @shyouhei is not sure if it
 * is  either  an intended  behaviour,  current  implementation limitation,  or
 * simply a bug.  Note also that there is no way to "melt" a frozen object.
 */
VALUE rb_ractor_make_shareable(VALUE obj);

/**
 * Identical to rb_ractor_make_shareable(), except it  returns a (deep) copy of
 * the passed one instead of modifying it in-place.
 *
 * @param[in]   obj              Arbitrary ruby object to duplicate.
 * @exception   rb_eRactorError  Ractors cannot share `obj` by nature.
 * @return      A deep copy of `obj` which is sharable among Ractors.
 */
VALUE rb_ractor_make_shareable_copy(VALUE obj);

RBIMPL_SYMBOL_EXPORT_END()

/**
 * Queries if the passed object has  previously classified as shareable or not.
 * This  doesn't mean  anything in  practice...  Objects  can be  shared later.
 * Always use rb_ractor_shareable_p() instead.
 *
 * @param[in]  obj                Object in question.
 * @retval     RUBY_FL_SHAREABLE  It once was shareable before.
 * @retval     0                  Otherwise.
 */
#define RB_OBJ_SHAREABLE_P(obj) FL_TEST_RAW((obj), RUBY_FL_SHAREABLE)

/**
 * Queries if multiple Ractors can share the passed object or not.  Ractors run
 * without protecting  each other.  Sharing  an object among them  is basically
 * dangerous,  disabled  by  default.   However  there  are  objects  that  are
 * extremely  carefully implemented  to be  Ractor-safe; for  instance integers
 * have such property.  This function can classify that.
 *
 * @param[in]   obj    Arbitrary ruby object.
 * @retval      true   `obj` is capable of shared across ractors.
 * @retval      false  `obj` cannot travel across ractor boundaries.
 */
static inline bool
rb_ractor_shareable_p(VALUE obj)
{
    bool rb_ractor_shareable_p_continue(VALUE obj);

    if (RB_SPECIAL_CONST_P(obj)) {
        return true;
    }
    else if (RB_OBJ_SHAREABLE_P(obj)) {
        return true;
    }
    else {
        return rb_ractor_shareable_p_continue(obj);
    }
}

#endif /* RUBY_RACTOR_H */
ruby/atomic.h000064400000067176151732674140007205 0ustar00#ifndef RUBY_ATOMIC_H                                /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_ATOMIC_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Atomic operations
 *
 * Basically, if  we could assume  either C11 or  C++11, these macros  are just
 * redundant.  Sadly we cannot.  We have to do them ourselves.
 */

#include "ruby/internal/config.h"

#ifdef STDC_HEADERS
# include <stddef.h>            /* size_t */
#endif

#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>         /* ssize_t */
#endif

#if RBIMPL_COMPILER_SINCE(MSVC, 13, 0, 0)
# pragma intrinsic(_InterlockedOr)
#elif defined(__sun) && defined(HAVE_ATOMIC_H)
# include <atomic.h>
#endif

#include "ruby/assert.h"
#include "ruby/backward/2/limits.h"
#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/attr/noalias.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/compiler_since.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/value.h"
#include "ruby/internal/static_assert.h"
#include "ruby/internal/stdbool.h"

/*
 * Asserts that  your environment supports  more than one atomic  types.  These
 * days systems tend to have such property  (C11 was a standard of decades ago,
 * right?) but we still support older ones.
 */
#if defined(__DOXYGEN__) || defined(HAVE_GCC_ATOMIC_BUILTINS) || defined(HAVE_GCC_SYNC_BUILTINS)
# define RUBY_ATOMIC_GENERIC_MACRO 1
#endif

/**
 * Type  that  is eligible  for  atomic  operations.   Depending on  your  host
 * platform you might have  more than one such type, but we  choose one of them
 * anyways.
 */
#if defined(__DOXYGEN__)
using rb_atomic_t = std::atomic<unsigned>;
#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
typedef unsigned int rb_atomic_t;
#elif defined(HAVE_GCC_SYNC_BUILTINS)
typedef unsigned int rb_atomic_t;
#elif defined(_WIN32)
# include <winsock2.h>       // to prevent macro redefinitions
# include <windows.h>        // for `LONG` and `Interlocked` functions
typedef LONG rb_atomic_t;
#elif defined(__sun) && defined(HAVE_ATOMIC_H)
typedef unsigned int rb_atomic_t;
#else
# error No atomic operation found
#endif

/**
 * Atomically replaces the  value pointed by `var` with the  result of addition
 * of `val` to the old value of `var`.
 *
 * @param   var  A variable of ::rb_atomic_t.
 * @param   val  Value to add.
 * @return  What was stored in `var` before the addition.
 * @post    `var` holds `var + val`.
 */
#define RUBY_ATOMIC_FETCH_ADD(var, val) rbimpl_atomic_fetch_add(&(var), (val))

/**
 * Atomically  replaces  the  value  pointed   by  `var`  with  the  result  of
 * subtraction of `val` to the old value of `var`.
 *
 * @param   var  A variable of ::rb_atomic_t.
 * @param   val  Value to subtract.
 * @return  What was stored in `var` before the subtraction.
 * @post    `var` holds `var - val`.
 */
#define RUBY_ATOMIC_FETCH_SUB(var, val) rbimpl_atomic_fetch_sub(&(var), (val))

/**
 * Atomically  replaces  the  value  pointed   by  `var`  with  the  result  of
 * bitwise OR between `val` and the old value of `var`.
 *
 * @param   var   A variable of ::rb_atomic_t.
 * @param   val   Value to mix.
 * @return  void
 * @post    `var` holds `var | val`.
 * @note    For portability, this macro can return void.
 */
#define RUBY_ATOMIC_OR(var, val) rbimpl_atomic_or(&(var), (val))

/**
 * Atomically replaces the value pointed by  `var` with `val`.  This is just an
 * assignment, but you can additionally know the previous value.
 *
 * @param   var   A variable of ::rb_atomic_t.
 * @param   val   Value to set.
 * @return  What was stored in `var` before the assignment.
 * @post    `var` holds `val`.
 */
#define RUBY_ATOMIC_EXCHANGE(var, val) rbimpl_atomic_exchange(&(var), (val))

/**
 * Atomic compare-and-swap.   This stores  `val` to  `var` if  and only  if the
 * assignment changes  the value of `var`  from `oldval` to `newval`.   You can
 * detect whether the assignment happened or not using the return value.
 *
 * @param   var        A variable of ::rb_atomic_t.
 * @param   oldval     Expected value of `var` before the assignment.
 * @param   newval     What you want to store at `var`.
 * @retval  oldval     Successful assignment (`var` is now `newval`).
 * @retval  otherwise  Something else is at `var`; not updated.
 */
#define RUBY_ATOMIC_CAS(var, oldval, newval) \
    rbimpl_atomic_cas(&(var), (oldval), (newval))

/**
 * Atomic load. This loads `var` with an atomic intrinsic and returns
 * its value.
 *
 * @param var  A variable of ::rb_atomic_t
 * @return     What was stored in `var`j
 */
#define RUBY_ATOMIC_LOAD(var) rbimpl_atomic_load(&(var))

/**
 * Identical to #RUBY_ATOMIC_EXCHANGE, except for the return type.
 *
 * @param   var   A variable of ::rb_atomic_t.
 * @param   val   Value to set.
 * @return  void
 * @post    `var` holds `val`.
 */
#define RUBY_ATOMIC_SET(var, val) rbimpl_atomic_set(&(var), (val))

/**
 * Identical to #RUBY_ATOMIC_FETCH_ADD, except for the return type.
 *
 * @param   var  A variable of ::rb_atomic_t.
 * @param   val  Value to add.
 * @return  void
 * @post    `var` holds `var + val`.
 */
#define RUBY_ATOMIC_ADD(var, val) rbimpl_atomic_add(&(var), (val))

/**
 * Identical to #RUBY_ATOMIC_FETCH_SUB, except for the return type.
 *
 * @param   var  A variable of ::rb_atomic_t.
 * @param   val  Value to subtract.
 * @return  void
 * @post    `var` holds `var - val`.
 */
#define RUBY_ATOMIC_SUB(var, val) rbimpl_atomic_sub(&(var), (val))

/**
 * Atomically increments the value pointed by `var`.
 *
 * @param   var  A variable of ::rb_atomic_t.
 * @return  void
 * @post    `var` holds `var + 1`.
 */
#define RUBY_ATOMIC_INC(var) rbimpl_atomic_inc(&(var))

/**
 * Atomically decrements the value pointed by `var`.
 *
 * @param   var  A variable of ::rb_atomic_t.
 * @return  void
 * @post    `var` holds `var - 1`.
 */
#define RUBY_ATOMIC_DEC(var) rbimpl_atomic_dec(&(var))

/**
 * Identical to #RUBY_ATOMIC_INC,  except it expects its  argument is `size_t`.
 * There are cases where ::rb_atomic_t is  32bit while `size_t` is 64bit.  This
 * should be used for size related operations to support such platforms.
 *
 * @param   var  A variable of `size_t`.
 * @return  void
 * @post    `var` holds `var + 1`.
 */
#define RUBY_ATOMIC_SIZE_INC(var) rbimpl_atomic_size_inc(&(var))

/**
 * Identical to #RUBY_ATOMIC_DEC,  except it expects its  argument is `size_t`.
 * There are cases where ::rb_atomic_t is  32bit while `size_t` is 64bit.  This
 * should be used for size related operations to support such platforms.
 *
 * @param   var  A variable of `size_t`.
 * @return  void
 * @post    `var` holds `var - 1`.
 */
#define RUBY_ATOMIC_SIZE_DEC(var) rbimpl_atomic_size_dec(&(var))

/**
 * Identical  to #RUBY_ATOMIC_EXCHANGE,  except  it expects  its arguments  are
 * `size_t`.  There  are cases where  ::rb_atomic_t is 32bit while  `size_t` is
 * 64bit.  This  should be  used for  size related  operations to  support such
 * platforms.
 *
 * @param   var  A variable of `size_t`.
 * @param   val   Value to set.
 * @return  What was stored in `var` before the assignment.
 * @post    `var` holds `val`.
 */
#define RUBY_ATOMIC_SIZE_EXCHANGE(var, val) \
    rbimpl_atomic_size_exchange(&(var), (val))

/**
 * Identical to #RUBY_ATOMIC_CAS, except it expects its arguments are `size_t`.
 * There are cases where ::rb_atomic_t is 32bit while `size_t` is 64bit.  This
 * should be used for size related operations to support such platforms.
 *
 * @param   var        A variable of `size_t`.
 * @param   oldval     Expected value of `var` before the assignment.
 * @param   newval     What you want to store at `var`.
 * @retval  oldval     Successful assignment (`var` is now `newval`).
 * @retval  otherwise  Something else is at `var`; not updated.
 */
#define RUBY_ATOMIC_SIZE_CAS(var, oldval, newval) \
    rbimpl_atomic_size_cas(&(var), (oldval), (newval))

/**
 * Identical to #RUBY_ATOMIC_ADD, except it expects its arguments are `size_t`.
 * There are cases where ::rb_atomic_t is 32bit while `size_t` is 64bit.  This
 * should be used for size related operations to support such platforms.
 *
 * @param   var  A variable of `size_t`.
 * @param   val  Value to add.
 * @return  void
 * @post    `var` holds `var + val`.
 */
#define RUBY_ATOMIC_SIZE_ADD(var, val) rbimpl_atomic_size_add(&(var), (val))

/**
 * Identical to #RUBY_ATOMIC_SUB, except it expects its arguments are `size_t`.
 * There are cases where ::rb_atomic_t is 32bit while `size_t` is 64bit.  This
 * should be used for size related operations to support such platforms.
 *
 * @param   var  A variable of `size_t`.
 * @param   val  Value to subtract.
 * @return  void
 * @post    `var` holds `var - val`.
 */
#define RUBY_ATOMIC_SIZE_SUB(var, val) rbimpl_atomic_size_sub(&(var), (val))

/**
 * Identical  to #RUBY_ATOMIC_EXCHANGE,  except  it expects  its arguments  are
 * `void*`.   There are  cases where  ::rb_atomic_t is  32bit while  `void*` is
 * 64bit.  This should  be used for pointer related operations  to support such
 * platforms.
 *
 * @param   var  A variable of `void *`.
 * @param   val   Value to set.
 * @return  What was stored in `var` before the assignment.
 * @post    `var` holds `val`.
 *
 * @internal
 *
 * :FIXME: this `(void*)` cast is evil!  However `void*` is incompatible with
 * some pointers, most notably function pointers.
 */
#define RUBY_ATOMIC_PTR_EXCHANGE(var, val) \
    RBIMPL_CAST(rbimpl_atomic_ptr_exchange((void **)&(var), (void *)val))

/**
 * Identical to #RUBY_ATOMIC_LOAD, except it expects its arguments are `void*`.
 * There are cases where ::rb_atomic_t is 32bit while `void*` is 64bit.  This
 * should be used for size related operations to support such platforms.
 *
 * @param   var        A variable of `void*`
 * @return             The value of `var` (without tearing)
 */
#define RUBY_ATOMIC_PTR_LOAD(var) \
    RBIMPL_CAST(rbimpl_atomic_ptr_load((void **)&var))

/**
 * Identical to #RUBY_ATOMIC_CAS, except it expects its arguments are `void*`.
 * There are cases where ::rb_atomic_t is 32bit while `void*` is 64bit.  This
 * should be used for size related operations to support such platforms.
 *
 * @param   var        A variable of `void*`.
 * @param   oldval     Expected value of `var` before the assignment.
 * @param   newval     What you want to store at `var`.
 * @retval  oldval     Successful assignment (`var` is now `newval`).
 * @retval  otherwise  Something else is at `var`; not updated.
 */
#define RUBY_ATOMIC_PTR_CAS(var, oldval, newval) \
    RBIMPL_CAST(rbimpl_atomic_ptr_cas((void **)&(var), (void *)(oldval), (void *)(newval)))

/**
 * Identical  to #RUBY_ATOMIC_EXCHANGE,  except  it expects  its arguments  are
 * ::VALUE.   There are  cases where  ::rb_atomic_t is  32bit while  ::VALUE is
 * 64bit.  This should  be used for pointer related operations  to support such
 * platforms.
 *
 * @param   var  A variable of ::VALUE.
 * @param   val   Value to set.
 * @return  What was stored in `var` before the assignment.
 * @post    `var` holds `val`.
 */
#define RUBY_ATOMIC_VALUE_EXCHANGE(var, val) \
    rbimpl_atomic_value_exchange(&(var), (val))

/**
 * Identical to #RUBY_ATOMIC_CAS, except it  expects its arguments are ::VALUE.
 * There are cases  where ::rb_atomic_t is 32bit while ::VALUE  is 64bit.  This
 * should be used for size related operations to support such platforms.
 *
 * @param   var        A variable of `void*`.
 * @param   oldval     Expected value of `var` before the assignment.
 * @param   newval     What you want to store at `var`.
 * @retval  oldval     Successful assignment (`var` is now `newval`).
 * @retval  otherwise  Something else is at `var`; not updated.
 */
#define RUBY_ATOMIC_VALUE_CAS(var, oldval, newval) \
    rbimpl_atomic_value_cas(&(var), (oldval), (newval))

/** @cond INTERNAL_MACRO */
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline rb_atomic_t
rbimpl_atomic_fetch_add(volatile rb_atomic_t *ptr, rb_atomic_t val)
{
#if 0

#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
    return __atomic_fetch_add(ptr, val, __ATOMIC_SEQ_CST);

#elif defined(HAVE_GCC_SYNC_BUILTINS)
    return __sync_fetch_and_add(ptr, val);

#elif defined(_WIN32)
    return InterlockedExchangeAdd(ptr, val);

#elif defined(__sun) && defined(HAVE_ATOMIC_H)
    /*
     * `atomic_add_int_nv` takes its second argument as `int`!  Meanwhile our
     * `rb_atomic_t` is unsigned.  We cannot pass `val` as-is.  We have to
     * manually check integer overflow.
     */
    RBIMPL_ASSERT_OR_ASSUME(val <= INT_MAX);
    return atomic_add_int_nv(ptr, val) - val;

#else
# error Unsupported platform.
#endif
}

RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline void
rbimpl_atomic_add(volatile rb_atomic_t *ptr, rb_atomic_t val)
{
#if 0

#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
    /*
     * GCC on amd64 is smart enough to detect this `__atomic_add_fetch`'s
     * return value is not used, then compiles it into single `LOCK ADD`
     * instruction.
     */
    __atomic_add_fetch(ptr, val, __ATOMIC_SEQ_CST);

#elif defined(HAVE_GCC_SYNC_BUILTINS)
    __sync_add_and_fetch(ptr, val);

#elif defined(_WIN32)
    /*
     * `InterlockedExchangeAdd` is `LOCK XADD`.  It seems there also is
     * `_InterlockedAdd` intrinsic in ARM Windows but not for x86?  Sticking to
     * `InterlockedExchangeAdd` for better portability.
     */
    InterlockedExchangeAdd(ptr, val);

#elif defined(__sun) && defined(HAVE_ATOMIC_H)
    /* Ditto for `atomic_add_int_nv`. */
    RBIMPL_ASSERT_OR_ASSUME(val <= INT_MAX);
    atomic_add_int(ptr, val);

#else
# error Unsupported platform.
#endif
}

RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline void
rbimpl_atomic_size_add(volatile size_t *ptr, size_t val)
{
#if 0

#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
    __atomic_add_fetch(ptr, val, __ATOMIC_SEQ_CST);

#elif defined(HAVE_GCC_SYNC_BUILTINS)
    __sync_add_and_fetch(ptr, val);

#elif defined(_WIN64)
    /* Ditto for `InterlockeExchangedAdd`. */
    InterlockedExchangeAdd64(ptr, val);

#elif defined(__sun) && defined(HAVE_ATOMIC_H) && (defined(_LP64) || defined(_I32LPx))
    /* Ditto for `atomic_add_int_nv`. */
    RBIMPL_ASSERT_OR_ASSUME(val <= LONG_MAX);
    atomic_add_long(ptr, val);

#else
    RBIMPL_STATIC_ASSERT(size_of_rb_atomic_t, sizeof *ptr == sizeof(rb_atomic_t));

    volatile rb_atomic_t *const tmp = RBIMPL_CAST((volatile rb_atomic_t *)ptr);
    rbimpl_atomic_add(tmp, val);

#endif
}

RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline void
rbimpl_atomic_inc(volatile rb_atomic_t *ptr)
{
#if 0

#elif defined(HAVE_GCC_ATOMIC_BUILTINS) || defined(HAVE_GCC_SYNC_BUILTINS)
    rbimpl_atomic_add(ptr, 1);

#elif defined(_WIN32)
    InterlockedIncrement(ptr);

#elif defined(__sun) && defined(HAVE_ATOMIC_H)
    atomic_inc_uint(ptr);

#else
    rbimpl_atomic_add(ptr, 1);

#endif
}

RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline void
rbimpl_atomic_size_inc(volatile size_t *ptr)
{
#if 0

#elif defined(HAVE_GCC_ATOMIC_BUILTINS) || defined(HAVE_GCC_SYNC_BUILTINS)
    rbimpl_atomic_size_add(ptr, 1);

#elif defined(_WIN64)
    InterlockedIncrement64(ptr);

#elif defined(__sun) && defined(HAVE_ATOMIC_H) && (defined(_LP64) || defined(_I32LPx))
    atomic_inc_ulong(ptr);

#else
    RBIMPL_STATIC_ASSERT(size_of_size_t, sizeof *ptr == sizeof(rb_atomic_t));

    rbimpl_atomic_size_add(ptr, 1);

#endif
}

RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline rb_atomic_t
rbimpl_atomic_fetch_sub(volatile rb_atomic_t *ptr, rb_atomic_t val)
{
#if 0

#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
    return __atomic_fetch_sub(ptr, val, __ATOMIC_SEQ_CST);

#elif defined(HAVE_GCC_SYNC_BUILTINS)
    return __sync_fetch_and_sub(ptr, val);

#elif defined(_WIN32)
    /* rb_atomic_t is signed here! Safe to do `-val`. */
    return InterlockedExchangeAdd(ptr, -val);

#elif defined(__sun) && defined(HAVE_ATOMIC_H)
    /* Ditto for `rbimpl_atomic_fetch_add`. */
    const signed neg = -1;
    RBIMPL_ASSERT_OR_ASSUME(val <= INT_MAX);
    return atomic_add_int_nv(ptr, neg * val) + val;

#else
# error Unsupported platform.
#endif
}

RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline void
rbimpl_atomic_sub(volatile rb_atomic_t *ptr, rb_atomic_t val)
{
#if 0

#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
    __atomic_sub_fetch(ptr, val, __ATOMIC_SEQ_CST);

#elif defined(HAVE_GCC_SYNC_BUILTINS)
    __sync_sub_and_fetch(ptr, val);

#elif defined(_WIN32)
    InterlockedExchangeAdd(ptr, -val);

#elif defined(__sun) && defined(HAVE_ATOMIC_H)
    const signed neg = -1;
    RBIMPL_ASSERT_OR_ASSUME(val <= INT_MAX);
    atomic_add_int(ptr, neg * val);

#else
# error Unsupported platform.
#endif
}

RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline void
rbimpl_atomic_size_sub(volatile size_t *ptr, size_t val)
{
#if 0

#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
    __atomic_sub_fetch(ptr, val, __ATOMIC_SEQ_CST);

#elif defined(HAVE_GCC_SYNC_BUILTINS)
    __sync_sub_and_fetch(ptr, val);

#elif defined(_WIN64)
    const ssize_t neg = -1;
    InterlockedExchangeAdd64(ptr, neg * val);

#elif defined(__sun) && defined(HAVE_ATOMIC_H) && (defined(_LP64) || defined(_I32LPx))
    const signed neg = -1;
    RBIMPL_ASSERT_OR_ASSUME(val <= LONG_MAX);
    atomic_add_long(ptr, neg * val);

#else
    RBIMPL_STATIC_ASSERT(size_of_rb_atomic_t, sizeof *ptr == sizeof(rb_atomic_t));

    volatile rb_atomic_t *const tmp = RBIMPL_CAST((volatile rb_atomic_t *)ptr);
    rbimpl_atomic_sub(tmp, val);

#endif
}

RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline void
rbimpl_atomic_dec(volatile rb_atomic_t *ptr)
{
#if 0

#elif defined(HAVE_GCC_ATOMIC_BUILTINS) || defined(HAVE_GCC_SYNC_BUILTINS)
    rbimpl_atomic_sub(ptr, 1);

#elif defined(_WIN32)
    InterlockedDecrement(ptr);

#elif defined(__sun) && defined(HAVE_ATOMIC_H)
    atomic_dec_uint(ptr);

#else
    rbimpl_atomic_sub(ptr, 1);

#endif
}

RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline void
rbimpl_atomic_size_dec(volatile size_t *ptr)
{
#if 0

#elif defined(HAVE_GCC_ATOMIC_BUILTINS) || defined(HAVE_GCC_SYNC_BUILTINS)
    rbimpl_atomic_size_sub(ptr, 1);

#elif defined(_WIN64)
    InterlockedDecrement64(ptr);

#elif defined(__sun) && defined(HAVE_ATOMIC_H) && (defined(_LP64) || defined(_I32LPx))
    atomic_dec_ulong(ptr);

#else
    RBIMPL_STATIC_ASSERT(size_of_size_t, sizeof *ptr == sizeof(rb_atomic_t));

    rbimpl_atomic_size_sub(ptr, 1);

#endif
}

RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline void
rbimpl_atomic_or(volatile rb_atomic_t *ptr, rb_atomic_t val)
{
#if 0

#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
    __atomic_or_fetch(ptr, val, __ATOMIC_SEQ_CST);

#elif defined(HAVE_GCC_SYNC_BUILTINS)
    __sync_or_and_fetch(ptr, val);

#elif RBIMPL_COMPILER_SINCE(MSVC, 13, 0, 0)
    _InterlockedOr(ptr, val);

#elif defined(_WIN32) && defined(__GNUC__)
    /* This was for old MinGW.  Maybe not needed any longer? */
    __asm__(
        "lock\n\t"
        "orl\t%1, %0"
        : "=m"(ptr)
        : "Ir"(val));

#elif defined(_WIN32) && defined(_M_IX86)
    __asm mov eax, ptr;
    __asm mov ecx, val;
    __asm lock or [eax], ecx;

#elif defined(__sun) && defined(HAVE_ATOMIC_H)
    atomic_or_uint(ptr, val);

#else
# error Unsupported platform.
#endif
}

/* Nobody uses this but for theoretical backwards compatibility... */
#if RBIMPL_COMPILER_BEFORE(MSVC, 13, 0, 0)
static inline rb_atomic_t
rb_w32_atomic_or(volatile rb_atomic_t *var, rb_atomic_t val)
{
    return rbimpl_atomic_or(var, val);
}
#endif

RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline rb_atomic_t
rbimpl_atomic_exchange(volatile rb_atomic_t *ptr, rb_atomic_t val)
{
#if 0

#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
    return __atomic_exchange_n(ptr, val, __ATOMIC_SEQ_CST);

#elif defined(HAVE_GCC_SYNC_BUILTINS)
    return __sync_lock_test_and_set(ptr, val);

#elif defined(_WIN32)
    return InterlockedExchange(ptr, val);

#elif defined(__sun) && defined(HAVE_ATOMIC_H)
    return atomic_swap_uint(ptr, val);

#else
# error Unsupported platform.
#endif
}

RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline size_t
rbimpl_atomic_size_exchange(volatile size_t *ptr, size_t val)
{
#if 0

#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
    return __atomic_exchange_n(ptr, val, __ATOMIC_SEQ_CST);

#elif defined(HAVE_GCC_SYNC_BUILTINS)
    return __sync_lock_test_and_set(ptr, val);

#elif defined(_WIN64)
    return InterlockedExchange64(ptr, val);

#elif defined(__sun) && defined(HAVE_ATOMIC_H) && (defined(_LP64) || defined(_I32LPx))
    return atomic_swap_ulong(ptr, val);

#else
    RBIMPL_STATIC_ASSERT(size_of_size_t, sizeof *ptr == sizeof(rb_atomic_t));

    volatile rb_atomic_t *const tmp = RBIMPL_CAST((volatile rb_atomic_t *)ptr);
    const rb_atomic_t ret = rbimpl_atomic_exchange(tmp, val);
    return RBIMPL_CAST((size_t)ret);

#endif
}

RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline void *
rbimpl_atomic_ptr_exchange(void *volatile *ptr, const void *val)
{
#if 0

#elif defined(InterlockedExchangePointer)
    /* const_cast */
    PVOID *pptr = RBIMPL_CAST((PVOID *)ptr);
    PVOID pval = RBIMPL_CAST((PVOID)val);
    return InterlockedExchangePointer(pptr, pval);

#elif defined(__sun) && defined(HAVE_ATOMIC_H)
    return atomic_swap_ptr(ptr, RBIMPL_CAST((void *)val));

#else
    RBIMPL_STATIC_ASSERT(sizeof_voidp, sizeof *ptr == sizeof(size_t));

    const size_t sval = RBIMPL_CAST((size_t)val);
    volatile size_t *const sptr = RBIMPL_CAST((volatile size_t *)ptr);
    const size_t sret = rbimpl_atomic_size_exchange(sptr, sval);
    return RBIMPL_CAST((void *)sret);

#endif
}

RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline VALUE
rbimpl_atomic_value_exchange(volatile VALUE *ptr, VALUE val)
{
    RBIMPL_STATIC_ASSERT(sizeof_value, sizeof *ptr == sizeof(size_t));

    const size_t sval = RBIMPL_CAST((size_t)val);
    volatile size_t *const sptr = RBIMPL_CAST((volatile size_t *)ptr);
    const size_t sret = rbimpl_atomic_size_exchange(sptr, sval);
    return RBIMPL_CAST((VALUE)sret);
}

RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline rb_atomic_t
rbimpl_atomic_load(volatile rb_atomic_t *ptr)
{
#if 0

#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
    return __atomic_load_n(ptr, __ATOMIC_SEQ_CST);
#else
    return rbimpl_atomic_fetch_add(ptr, 0);
#endif
}

RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline void
rbimpl_atomic_set(volatile rb_atomic_t *ptr, rb_atomic_t val)
{
#if 0

#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
    __atomic_store_n(ptr, val, __ATOMIC_SEQ_CST);

#else
    /* Maybe std::atomic<rb_atomic_t>::store can be faster? */
    rbimpl_atomic_exchange(ptr, val);

#endif
}

RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline rb_atomic_t
rbimpl_atomic_cas(volatile rb_atomic_t *ptr, rb_atomic_t oldval, rb_atomic_t newval)
{
#if 0

#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
    __atomic_compare_exchange_n(
        ptr, &oldval, newval, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
    return oldval;

#elif defined(HAVE_GCC_SYNC_BUILTINS)
    return __sync_val_compare_and_swap(ptr, oldval, newval);

#elif RBIMPL_COMPILER_SINCE(MSVC, 13, 0, 0)
    return InterlockedCompareExchange(ptr, newval, oldval);

#elif defined(_WIN32)
    PVOID *pptr = RBIMPL_CAST((PVOID *)ptr);
    PVOID pold = RBIMPL_CAST((PVOID)oldval);
    PVOID pnew = RBIMPL_CAST((PVOID)newval);
    PVOID pret = InterlockedCompareExchange(pptr, pnew, pold);
    return RBIMPL_CAST((rb_atomic_t)pret);

#elif defined(__sun) && defined(HAVE_ATOMIC_H)
    return atomic_cas_uint(ptr, oldval, newval);

#else
# error Unsupported platform.
#endif
}

/* Nobody uses this but for theoretical backwards compatibility... */
#if RBIMPL_COMPILER_BEFORE(MSVC, 13, 0, 0)
static inline rb_atomic_t
rb_w32_atomic_cas(volatile rb_atomic_t *var, rb_atomic_t oldval, rb_atomic_t newval)
{
    return rbimpl_atomic_cas(var, oldval, newval);
}
#endif

RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline size_t
rbimpl_atomic_size_cas(volatile size_t *ptr, size_t oldval, size_t newval)
{
#if 0

#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
    __atomic_compare_exchange_n(
        ptr, &oldval, newval, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
    return oldval;

#elif defined(HAVE_GCC_SYNC_BUILTINS)
    return __sync_val_compare_and_swap(ptr, oldval, newval);

#elif defined(_WIN64)
    return InterlockedCompareExchange64(ptr, newval, oldval);

#elif defined(__sun) && defined(HAVE_ATOMIC_H) && (defined(_LP64) || defined(_I32LPx))
    return atomic_cas_ulong(ptr, oldval, newval);

#else
    RBIMPL_STATIC_ASSERT(size_of_size_t, sizeof *ptr == sizeof(rb_atomic_t));

    volatile rb_atomic_t *tmp = RBIMPL_CAST((volatile rb_atomic_t *)ptr);
    return rbimpl_atomic_cas(tmp, oldval, newval);

#endif
}

RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline void *
rbimpl_atomic_ptr_cas(void **ptr, const void *oldval, const void *newval)
{
#if 0

#elif defined(InterlockedExchangePointer)
    /* ... Can we say that InterlockedCompareExchangePtr surly exists when
     * InterlockedExchangePointer is defined?  Seems so but...?*/
    PVOID *pptr = RBIMPL_CAST((PVOID *)ptr);
    PVOID pold = RBIMPL_CAST((PVOID)oldval);
    PVOID pnew = RBIMPL_CAST((PVOID)newval);
    return InterlockedCompareExchangePointer(pptr, pnew, pold);

#elif defined(__sun) && defined(HAVE_ATOMIC_H)
    void *pold = RBIMPL_CAST((void *)oldval);
    void *pnew = RBIMPL_CAST((void *)newval);
    return atomic_cas_ptr(ptr, pold, pnew);


#else
    RBIMPL_STATIC_ASSERT(sizeof_voidp, sizeof *ptr == sizeof(size_t));

    const size_t snew = RBIMPL_CAST((size_t)newval);
    const size_t sold = RBIMPL_CAST((size_t)oldval);
    volatile size_t *const sptr = RBIMPL_CAST((volatile size_t *)ptr);
    const size_t sret = rbimpl_atomic_size_cas(sptr, sold, snew);
    return RBIMPL_CAST((void *)sret);

#endif
}

RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline void *
rbimpl_atomic_ptr_load(void **ptr)
{
#if 0

#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
    return __atomic_load_n(ptr, __ATOMIC_SEQ_CST);
#else
    void *val = *ptr;
    return rbimpl_atomic_ptr_cas(ptr, val, val);
#endif
}

RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
static inline VALUE
rbimpl_atomic_value_cas(volatile VALUE *ptr, VALUE oldval, VALUE newval)
{
    RBIMPL_STATIC_ASSERT(sizeof_value, sizeof *ptr == sizeof(size_t));

    const size_t snew = RBIMPL_CAST((size_t)newval);
    const size_t sold = RBIMPL_CAST((size_t)oldval);
    volatile size_t *const sptr = RBIMPL_CAST((volatile size_t *)ptr);
    const size_t sret = rbimpl_atomic_size_cas(sptr, sold, snew);
    return RBIMPL_CAST((VALUE)sret);
}
/** @endcond */
#endif /* RUBY_ATOMIC_H */
ruby/internal/constant_p.h000064400000003547151732674140011705 0ustar00#ifndef RBIMPL_CONSTANT_P_H                          /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_CONSTANT_P_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_CONSTANT_P.
 *
 * Note that __builtin_constant_p can be applicable inside of inline functions,
 * according to GCC manual.  Clang lacks that feature, though.
 *
 * @see https://bugs.llvm.org/show_bug.cgi?id=4898
 * @see https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
 */
#include "ruby/internal/has/builtin.h"

/** Wraps (or simulates) `__builtin_constant_p` */
#if RBIMPL_HAS_BUILTIN(__builtin_constant_p)
# define RBIMPL_CONSTANT_P(expr) __builtin_constant_p(expr)
#else
# define RBIMPL_CONSTANT_P(expr) 0
#endif

#endif /* RBIMPL_CONSTANT_P_H */
ruby/internal/scan_args.h000064400000044753151732674140011501 0ustar00#ifndef RBIMPL_SCAN_ARGS_H                           /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_SCAN_ARGS_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Compile-time static implementation of ::rb_scan_args().
 *
 * This  is a  beast.  It  statically analyses  the argument  spec string,  and
 * expands the assignment of variables into dedicated codes.
 */
#include "ruby/assert.h"
#include "ruby/internal/attr/diagnose_if.h"
#include "ruby/internal/attr/error.h"
#include "ruby/internal/attr/forceinline.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/config.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/has/attribute.h"
#include "ruby/internal/intern/array.h" /* rb_ary_new_from_values */
#include "ruby/internal/intern/error.h" /* rb_error_arity */
#include "ruby/internal/intern/hash.h"  /* rb_hash_dup */
#include "ruby/internal/intern/proc.h"  /* rb_block_proc */
#include "ruby/internal/iterator.h"     /* rb_block_given_p / rb_keyword_given_p */
#include "ruby/internal/static_assert.h"
#include "ruby/internal/stdbool.h"
#include "ruby/internal/value.h"

/**
 * @name Possible values that you should pass to rb_scan_args_kw().
 * @{
 */

/** Same behaviour as rb_scan_args(). */
#define RB_SCAN_ARGS_PASS_CALLED_KEYWORDS 0

/** The final argument should be a hash treated as keywords.*/
#define RB_SCAN_ARGS_KEYWORDS 1

/**
 * Treat a  final argument as  keywords if  it is a  hash, and not  as keywords
 * otherwise.
 */
#define RB_SCAN_ARGS_LAST_HASH_KEYWORDS 3

/** @} */

/**
 * @name Possible values that you should pass to rb_funcallv_kw().
 * @{
 */

/** Do not pass keywords. */
#define RB_NO_KEYWORDS 0

/** Pass keywords, final argument should be a hash of keywords. */
#define RB_PASS_KEYWORDS 1

/**
 * Pass keywords if current method is called with keywords, useful for argument
 * delegation
 */
#define RB_PASS_CALLED_KEYWORDS !!rb_keyword_given_p()

/** @} */

/**
 * @private
 *
 * @deprecated  This macro once was a thing in the old days, but makes no sense
 *              any  longer today.   Exists  here  for backwards  compatibility
 *              only.  You can safely forget about it.
 */
#define HAVE_RB_SCAN_ARGS_OPTIONAL_HASH 1

RBIMPL_SYMBOL_EXPORT_BEGIN()
RBIMPL_ATTR_NONNULL((2, 3))
/**
 * Retrieves argument from argc and  argv to given ::VALUE references according
 * to the format string.  The format can be described in ABNF as follows:
 *
 * ```
 * scan-arg-spec  := param-arg-spec [keyword-arg-spec] [block-arg-spec]
 *
 * param-arg-spec        := pre-arg-spec [post-arg-spec] / post-arg-spec /
 *                          pre-opt-post-arg-spec
 * pre-arg-spec          := num-of-leading-mandatory-args
 *                          [num-of-optional-args]
 * post-arg-spec         := sym-for-variable-length-args
 *                          [num-of-trailing-mandatory-args]
 * pre-opt-post-arg-spec := num-of-leading-mandatory-args num-of-optional-args
 *                          num-of-trailing-mandatory-args
 * keyword-arg-spec      := sym-for-keyword-arg
 * block-arg-spec        := sym-for-block-arg
 *
 * num-of-leading-mandatory-args  := DIGIT ; The number of leading mandatory
 *                                         ; arguments
 * num-of-optional-args           := DIGIT ; The number of optional arguments
 * sym-for-variable-length-args   := "*"   ; Indicates that variable length
 *                                         ;  arguments are captured as a ruby
 *                                         ; array
 * num-of-trailing-mandatory-args := DIGIT ; The number of trailing mandatory
 *                                         ; arguments
 * sym-for-keyword-arg            := ":"   ; Indicates that keyword argument
 *                                         ; captured as a hash.
 *                                         ; If keyword arguments are not
 *                                         ; provided, returns nil.
 * sym-for-block-arg              := "&"   ; Indicates that an iterator block
 *                                         ; should be captured if given
 * ```
 *
 * For example, "12" means that the  method requires at least one argument, and
 * at  most receives  three (1+2)  arguments.  So,  the format  string must  be
 * followed by three variable references, which  are to be assigned to captured
 * arguments.  For omitted arguments, variables are set to ::RUBY_Qnil.  `NULL`
 * can be put  in place of a variable reference,  which means the corresponding
 * captured argument(s) should be just dropped.
 *
 * The number of  given arguments, excluding an option hash  or iterator block,
 * is returned.
 *
 * @param[in]   argc          Length of `argv`.
 * @param[in]   argv          Pointer to the arguments to parse.
 * @param[in]   fmt           Format, in the language described above.
 * @param[out]  ...           Variables to fill in.
 * @exception   rb_eFatal     Malformed `fmt`.
 * @exception   rb_eArgError  Arity mismatch.
 * @return      Actually parsed number of given arguments.
 * @post        Each  values  passed to  `argv`  is  filled into  the  variadic
 *              arguments, according to the format.
 */
int rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...);

RBIMPL_ATTR_NONNULL((3, 4))
/**
 * Identical to rb_scan_args(), except it also accepts `kw_splat`.
 *
 * @param[in]   kw_splat      How to understand the keyword arguments.
 *   - RB_SCAN_ARGS_PASS_CALLED_KEYWORDS: Same behaviour as rb_scan_args().
 *   - RB_SCAN_ARGS_KEYWORDS:             The final argument is a kwarg.
 *   - RB_SCAN_ARGS_LAST_HASH_KEYWORDS:   The final argument is a kwarg, iff it
 *                                        is a hash.
 * @param[in]   argc          Length of `argv`.
 * @param[in]   argv          Pointer to the arguments to parse.
 * @param[in]   fmt           Format, in the language described above.
 * @param[out]  ...           Variables to fill in.
 * @exception   rb_eFatal     Malformed `fmt`.
 * @exception   rb_eArgError  Arity mismatch.
 * @return      Actually parsed number of given arguments.
 * @post        Each  values  passed to  `argv`  is  filled into  the  variadic
 *              arguments, according to the format.
 */
int rb_scan_args_kw(int kw_splat, int argc, const VALUE *argv, const char *fmt, ...);

RBIMPL_ATTR_ERROR(("bad scan arg format"))
/**
 * @private
 *
 * This is  an implementation  detail of rb_scan_args().   People don't  use it
 * directly.
 */
void rb_scan_args_bad_format(const char*);

RBIMPL_ATTR_ERROR(("variable argument length doesn't match"))
/**
 * @private
 *
 * This is  an implementation  detail of rb_scan_args().   People don't  use it
 * directly.
 */
void rb_scan_args_length_mismatch(const char*,int);

RBIMPL_SYMBOL_EXPORT_END()

/** @cond INTERNAL_MACRO */

/* If we could use constexpr the following macros could be inline functions
 * ... but sadly we cannot. */

#define rb_scan_args_isdigit(c) (RBIMPL_CAST((unsigned char)((c)-'0'))<10)

#define rb_scan_args_count_end(fmt, ofs, vari) \
    ((fmt)[ofs] ? -1 : (vari))

#define rb_scan_args_count_block(fmt, ofs, vari) \
    ((fmt)[ofs]!='&' ? \
     rb_scan_args_count_end(fmt, ofs, vari) : \
     rb_scan_args_count_end(fmt, (ofs)+1, (vari)+1))

#define rb_scan_args_count_hash(fmt, ofs, vari) \
    ((fmt)[ofs]!=':' ? \
     rb_scan_args_count_block(fmt, ofs, vari) : \
     rb_scan_args_count_block(fmt, (ofs)+1, (vari)+1))

#define rb_scan_args_count_trail(fmt, ofs, vari) \
    (!rb_scan_args_isdigit((fmt)[ofs]) ? \
     rb_scan_args_count_hash(fmt, ofs, vari) : \
     rb_scan_args_count_hash(fmt, (ofs)+1, (vari)+((fmt)[ofs]-'0')))

#define rb_scan_args_count_var(fmt, ofs, vari) \
    ((fmt)[ofs]!='*' ? \
     rb_scan_args_count_trail(fmt, ofs, vari) : \
     rb_scan_args_count_trail(fmt, (ofs)+1, (vari)+1))

#define rb_scan_args_count_opt(fmt, ofs, vari) \
    (!rb_scan_args_isdigit((fmt)[ofs]) ? \
     rb_scan_args_count_var(fmt, ofs, vari) : \
     rb_scan_args_count_var(fmt, (ofs)+1, (vari)+(fmt)[ofs]-'0'))

#define rb_scan_args_count_lead(fmt, ofs, vari) \
    (!rb_scan_args_isdigit((fmt)[ofs]) ? \
     rb_scan_args_count_var(fmt, ofs, vari) : \
     rb_scan_args_count_opt(fmt, (ofs)+1, (vari)+(fmt)[ofs]-'0'))

#define rb_scan_args_count(fmt) rb_scan_args_count_lead(fmt, 0, 0)

#if RBIMPL_HAS_ATTRIBUTE(diagnose_if)
# /* Assertions done in the attribute. */
# define rb_scan_args_verify(fmt, varc) RBIMPL_ASSERT_NOTHING
#else
# /* At  one sight  it _seems_  the expressions  below could  be written  using
#  * static  assertions.  The  reality is  no, they  don't.  Because  fmt is  a
#  * string literal,  any operations  against fmt  cannot produce  the "integer
#  * constant  expression"s,  as  defined  in  ISO/IEC  9899:2018  section  6.6
#  * paragraph #6.  Static assertions need such integer constant expressions as
#  * defined in ISO/IEC 9899:2018 section 6.7.10 paragraph #3.
#  *
#  * GCC nonetheless constant-folds this into a no-op, though. */
# define rb_scan_args_verify(fmt, varc) \
    (sizeof(char[1-2*(rb_scan_args_count(fmt)<0)])!=1 ? \
     rb_scan_args_bad_format(fmt) : \
     sizeof(char[1-2*(rb_scan_args_count(fmt)!=(varc))])!=1 ? \
     rb_scan_args_length_mismatch(fmt, varc) : \
     RBIMPL_ASSERT_NOTHING)
#endif

static inline bool
rb_scan_args_keyword_p(int kw_flag, VALUE last)
{
    switch (kw_flag) {
      case RB_SCAN_ARGS_PASS_CALLED_KEYWORDS:
        return !! rb_keyword_given_p();
      case RB_SCAN_ARGS_KEYWORDS:
        return true;
      case RB_SCAN_ARGS_LAST_HASH_KEYWORDS:
        return RB_TYPE_P(last, T_HASH);
      default:
        return false;
    }
}

RBIMPL_ATTR_FORCEINLINE()
static bool
rb_scan_args_lead_p(const char *fmt)
{
    return rb_scan_args_isdigit(fmt[0]);
}

RBIMPL_ATTR_FORCEINLINE()
static int
rb_scan_args_n_lead(const char *fmt)
{
    return (rb_scan_args_lead_p(fmt) ? fmt[0]-'0' : 0);
}

RBIMPL_ATTR_FORCEINLINE()
static bool
rb_scan_args_opt_p(const char *fmt)
{
    return (rb_scan_args_lead_p(fmt) && rb_scan_args_isdigit(fmt[1]));
}

RBIMPL_ATTR_FORCEINLINE()
static int
rb_scan_args_n_opt(const char *fmt)
{
    return (rb_scan_args_opt_p(fmt) ? fmt[1]-'0' : 0);
}

RBIMPL_ATTR_FORCEINLINE()
static int
rb_scan_args_var_idx(const char *fmt)
{
    return (!rb_scan_args_lead_p(fmt) ? 0 : !rb_scan_args_isdigit(fmt[1]) ? 1 : 2);
}

RBIMPL_ATTR_FORCEINLINE()
static bool
rb_scan_args_f_var(const char *fmt)
{
    return (fmt[rb_scan_args_var_idx(fmt)]=='*');
}

RBIMPL_ATTR_FORCEINLINE()
static int
rb_scan_args_trail_idx(const char *fmt)
{
    const int idx = rb_scan_args_var_idx(fmt);
    return idx+(fmt[idx]=='*');
}

RBIMPL_ATTR_FORCEINLINE()
static int
rb_scan_args_n_trail(const char *fmt)
{
    const int idx = rb_scan_args_trail_idx(fmt);
    return (rb_scan_args_isdigit(fmt[idx]) ? fmt[idx]-'0' : 0);
}

RBIMPL_ATTR_FORCEINLINE()
static int
rb_scan_args_hash_idx(const char *fmt)
{
    const int idx = rb_scan_args_trail_idx(fmt);
    return idx+rb_scan_args_isdigit(fmt[idx]);
}

RBIMPL_ATTR_FORCEINLINE()
static bool
rb_scan_args_f_hash(const char *fmt)
{
    return (fmt[rb_scan_args_hash_idx(fmt)]==':');
}

RBIMPL_ATTR_FORCEINLINE()
static int
rb_scan_args_block_idx(const char *fmt)
{
    const int idx = rb_scan_args_hash_idx(fmt);
    return idx+(fmt[idx]==':');
}

RBIMPL_ATTR_FORCEINLINE()
static bool
rb_scan_args_f_block(const char *fmt)
{
    return (fmt[rb_scan_args_block_idx(fmt)]=='&');
}

# if 0
RBIMPL_ATTR_FORCEINLINE()
static int
rb_scan_args_end_idx(const char *fmt)
{
    const int idx = rb_scan_args_block_idx(fmt);
    return idx+(fmt[idx]=='&');
}
# endif

/* NOTE: Use `char *fmt` instead of `const char *fmt` because of clang's bug*/
/* https://bugs.llvm.org/show_bug.cgi?id=38095 */
# define rb_scan_args0(argc, argv, fmt, varc, vars) \
    rb_scan_args_set(RB_SCAN_ARGS_PASS_CALLED_KEYWORDS, argc, argv, \
                     rb_scan_args_n_lead(fmt), \
                     rb_scan_args_n_opt(fmt), \
                     rb_scan_args_n_trail(fmt), \
                     rb_scan_args_f_var(fmt), \
                     rb_scan_args_f_hash(fmt), \
                     rb_scan_args_f_block(fmt), \
                     (rb_scan_args_verify(fmt, varc), vars), (char *)fmt, varc)
# define rb_scan_args_kw0(kw_flag, argc, argv, fmt, varc, vars) \
    rb_scan_args_set(kw_flag, argc, argv, \
                     rb_scan_args_n_lead(fmt), \
                     rb_scan_args_n_opt(fmt), \
                     rb_scan_args_n_trail(fmt), \
                     rb_scan_args_f_var(fmt), \
                     rb_scan_args_f_hash(fmt), \
                     rb_scan_args_f_block(fmt), \
                     (rb_scan_args_verify(fmt, varc), vars), (char *)fmt, varc)

RBIMPL_ATTR_FORCEINLINE()
static int
rb_scan_args_set(int kw_flag, int argc, const VALUE *argv,
                 int n_lead, int n_opt, int n_trail,
                 bool f_var, bool f_hash, bool f_block,
                 VALUE *vars[], RB_UNUSED_VAR(const char *fmt), RB_UNUSED_VAR(int varc))
    RBIMPL_ATTR_DIAGNOSE_IF(rb_scan_args_count(fmt) <  0,    "bad scan arg format",                    "error")
    RBIMPL_ATTR_DIAGNOSE_IF(rb_scan_args_count(fmt) != varc, "variable argument length doesn't match", "error")
{
    int i, argi = 0, vari = 0;
    VALUE *var, hash = Qnil;
#define rb_scan_args_next_param() vars[vari++]
    const int n_mand = n_lead + n_trail;

    /* capture an option hash - phase 1: pop from the argv */
    if (f_hash && argc > 0) {
        VALUE last = argv[argc - 1];
        if (rb_scan_args_keyword_p(kw_flag, last)) {
            hash = rb_hash_dup(last);
            argc--;
        }
    }

    if (argc < n_mand) {
        goto argc_error;
    }

    /* capture leading mandatory arguments */
    for (i = 0; i < n_lead; i++) {
        var = rb_scan_args_next_param();
        if (var) *var = argv[argi];
        argi++;
    }

    /* capture optional arguments */
    for (i = 0; i < n_opt; i++) {
        var = rb_scan_args_next_param();
        if (argi < argc - n_trail) {
            if (var) *var = argv[argi];
            argi++;
        }
        else {
            if (var) *var = Qnil;
        }
    }

    /* capture variable length arguments */
    if (f_var) {
        int n_var = argc - argi - n_trail;

        var = rb_scan_args_next_param();
        if (0 < n_var) {
            if (var) *var = rb_ary_new_from_values(n_var, &argv[argi]);
            argi += n_var;
        }
        else {
            if (var) *var = rb_ary_new();
        }
    }

    /* capture trailing mandatory arguments */
    for (i = 0; i < n_trail; i++) {
        var = rb_scan_args_next_param();
        if (var) *var = argv[argi];
        argi++;
    }

    /* capture an option hash - phase 2: assignment */
    if (f_hash) {
        var = rb_scan_args_next_param();
        if (var) *var = hash;
    }

    /* capture iterator block */
    if (f_block) {
        var = rb_scan_args_next_param();
        if (rb_block_given_p()) {
            *var = rb_block_proc();
        }
        else {
            *var = Qnil;
        }
    }

    if (argi == argc) {
        return argc;
    }

  argc_error:
    rb_error_arity(argc, n_mand, f_var ? UNLIMITED_ARGUMENTS : n_mand + n_opt);
    UNREACHABLE_RETURN(-1);
#undef rb_scan_args_next_param
}

/** @endcond */

#if defined(__DOXYGEN__)
# /* don't bother */

#elif ! defined(HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P)
# /* skip */

#elif ! defined(HAVE_VA_ARGS_MACRO)
# /* skip */

#elif ! defined(__OPTIMIZE__)
# /* skip */

#elif defined(HAVE___VA_OPT__)
# define rb_scan_args(argc, argvp, fmt, ...)                  \
    __builtin_choose_expr(                                    \
        __builtin_constant_p(fmt),                            \
        rb_scan_args0(                                        \
            argc, argvp, fmt,                                 \
            (sizeof((VALUE*[]){__VA_ARGS__})/sizeof(VALUE*)), \
            ((VALUE*[]){__VA_ARGS__})),                       \
        (rb_scan_args)(argc, argvp, fmt __VA_OPT__(, __VA_ARGS__)))
# define rb_scan_args_kw(kw_flag, argc, argvp, fmt, ...)      \
    __builtin_choose_expr(                                    \
        __builtin_constant_p(fmt),                            \
        rb_scan_args_kw0(                                     \
            kw_flag, argc, argvp, fmt,                        \
            (sizeof((VALUE*[]){__VA_ARGS__})/sizeof(VALUE*)), \
            ((VALUE*[]){__VA_ARGS__})),                       \
        (rb_scan_args_kw)(kw_flag, argc, argvp, fmt __VA_OPT__(, __VA_ARGS__)))

#elif defined(__STRICT_ANSI__)
# /* skip */

#elif defined(__GNUC__)
# define rb_scan_args(argc, argvp, fmt, ...)                  \
    __builtin_choose_expr(                                    \
        __builtin_constant_p(fmt),                            \
        rb_scan_args0(                                        \
            argc, argvp, fmt,                                 \
            (sizeof((VALUE*[]){__VA_ARGS__})/sizeof(VALUE*)), \
            ((VALUE*[]){__VA_ARGS__})),                       \
        (rb_scan_args)(argc, argvp, fmt, __VA_ARGS__))
# define rb_scan_args_kw(kw_flag, argc, argvp, fmt, ...)      \
    __builtin_choose_expr(                                    \
        __builtin_constant_p(fmt),                            \
        rb_scan_args_kw0(                                     \
            kw_flag, argc, argvp, fmt,                        \
            (sizeof((VALUE*[]){__VA_ARGS__})/sizeof(VALUE*)), \
            ((VALUE*[]){__VA_ARGS__})),                       \
        (rb_scan_args_kw)(kw_flag, argc, argvp, fmt, __VA_ARGS__ /**/))
#endif

#endif /* RBIMPL_SCAN_ARGS_H */
ruby/internal/has/c_attribute.h000064400000004360151732674140012607 0ustar00#ifndef RBIMPL_HAS_C_ATTRIBUTE_H                     /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_HAS_C_ATTRIBUTE_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_HAS_C_ATTRIBUTE.
 */

#include "ruby/internal/has/extension.h"
#include "ruby/internal/has/warning.h"

/** Wraps (or simulates) `__has_c_attribute`. */
#if defined(__cplusplus)
# /* Makes no sense. */
# define RBIMPL_HAS_C_ATTRIBUTE(_) 0

#elif RBIMPL_HAS_EXTENSION(c_attributes)
# /* Hmm.  It  seems Clang 17 has  this macro defined even  when -std=c99 mode,
#  * _and_ fails  to compile complaining  that attributes are C2X  feature.  We
#  * need to work around this nonsense. */
# define RBIMPL_HAS_C_ATTRIBUTE(_) __has_c_attribute(_)

#elif RBIMPL_HAS_WARNING("-Wc2x-extensions")
# define RBIMPL_HAS_C_ATTRIBUTE(_) 0

#elif defined(__has_c_attribute)
# define RBIMPL_HAS_C_ATTRIBUTE(_) __has_c_attribute(_)

#else
# /* As  of writing  everything  that lacks  __has_c_attribute also  completely
#  * lacks C2x attributes as well.  Might change in future? */
# define RBIMPL_HAS_C_ATTRIBUTE(_) 0
#endif

#endif /* RBIMPL_HAS_C_ATTRIBUTE_H */
ruby/internal/has/cpp_attribute.h000064400000010701151732674140013143 0ustar00#ifndef RBIMPL_HAS_CPP_ATTRIBUTE_H                   /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_HAS_CPP_ATTRIBUTE_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_HAS_CPP_ATTRIBUTE.
 */
#include "ruby/internal/compiler_is.h"
#include "ruby/internal/compiler_since.h"

/** @cond INTERNAL_MACRO */
#if RBIMPL_COMPILER_IS(SunPro)
# /* Oracle Developer Studio 12.5's C++  preprocessor is reportedly broken.  We
#  * could simulate  __has_cpp_attribute like below,  but don't know  the exact
#  * list of which version supported which attribute.  Just kill everything for
#  * now.  If you can please :FIXME: */
# /* https://unicode-org.atlassian.net/browse/ICU-12893 */
# /* https://github.com/boostorg/config/pull/95 */
# define RBIMPL_HAS_CPP_ATTRIBUTE0(_) 0

#elif defined(__has_cpp_attribute)
# define RBIMPL_HAS_CPP_ATTRIBUTE0(_) __has_cpp_attribute(_)

#elif RBIMPL_COMPILER_IS(MSVC)
# /* MSVC has  never updated  its __cplusplus  since forever  (unless specified
#  * explicitly by a compiler flag).   They also lack __has_cpp_attribute until
#  * 2019.  However, they do have attributes since 2015 or so. */
# /* https://docs.microsoft.com/en-us/cpp/overview/visual-cpp-language-conformance */
# define RBIMPL_HAS_CPP_ATTRIBUTE0(_) (RBIMPL_HAS_CPP_ATTRIBUTE_ ## _)
# define RBIMPL_HAS_CPP_ATTRIBUTE_noreturn           200809 * RBIMPL_COMPILER_SINCE(MSVC, 19, 00, 0)
# define RBIMPL_HAS_CPP_ATTRIBUTE_carries_dependency 200809 * RBIMPL_COMPILER_SINCE(MSVC, 19, 00, 0)
# define RBIMPL_HAS_CPP_ATTRIBUTE_deprecated         201309 * RBIMPL_COMPILER_SINCE(MSVC, 19, 10, 0)
# define RBIMPL_HAS_CPP_ATTRIBUTE_fallthrough        201603 * RBIMPL_COMPILER_SINCE(MSVC, 19, 10, 0)
# define RBIMPL_HAS_CPP_ATTRIBUTE_maybe_unused       201603 * RBIMPL_COMPILER_SINCE(MSVC, 19, 11, 0)
# define RBIMPL_HAS_CPP_ATTRIBUTE_nodiscard          201603 * RBIMPL_COMPILER_SINCE(MSVC, 19, 11, 0)

#elif RBIMPL_COMPILER_BEFORE(Clang, 3, 6, 0)
# /* Clang  3.6.0  introduced  __has_cpp_attribute.  Prior  to  that  following
#  * attributes were already there. */
# /* https://clang.llvm.org/cxx_status.html */
# define RBIMPL_HAS_CPP_ATTRIBUTE0(_) (RBIMPL_HAS_CPP_ATTRIBUTE_ ## _)
# define RBIMPL_HAS_CPP_ATTRIBUTE_noreturn           200809 * RBIMPL_COMPILER_SINCE(Clang, 3, 3, 0)
# define RBIMPL_HAS_CPP_ATTRIBUTE_deprecated         201309 * RBIMPL_COMPILER_SINCE(Clang, 3, 4, 0)

#elif RBIMPL_COMPILER_BEFORE(GCC, 5, 0, 0)
# /* GCC 5+ have __has_cpp_attribute, while 4.x had following attributes. */
# /* https://gcc.gnu.org/projects/cxx-status.html */
# define RBIMPL_HAS_CPP_ATTRIBUTE0(_) (RBIMPL_HAS_CPP_ATTRIBUTE_ ## _)
# define RBIMPL_HAS_CPP_ATTRIBUTE_noreturn           200809 * RBIMPL_COMPILER_SINCE(GCC, 4, 8, 0)
# define RBIMPL_HAS_CPP_ATTRIBUTE_deprecated         201309 * RBIMPL_COMPILER_SINCE(GCC, 4, 9, 0)

#else
# /* :FIXME:
#  * Candidate compilers to list here:
#  * - icpc: They have __INTEL_CXX11_MODE__.
#  */
# define RBIMPL_HAS_CPP_ATTRIBUTE0(_) 0
#endif
/** @endcond */

/** Wraps (or simulates) `__has_cpp_attribute`. */
#if ! defined(__cplusplus)
# /* Makes no sense. */
# define RBIMPL_HAS_CPP_ATTRIBUTE(_) 0
#else
# /* GCC needs workarounds.  See https://gcc.godbolt.org/z/jdz3pa */
# define RBIMPL_HAS_CPP_ATTRIBUTE(_) \
    ((RBIMPL_HAS_CPP_ATTRIBUTE0(_) <= __cplusplus) ? RBIMPL_HAS_CPP_ATTRIBUTE0(_) : 0)
#endif

#endif /* RBIMPL_HAS_CPP_ATTRIBUTE_H */
ruby/internal/has/extension.h000064400000003242151732674140012314 0ustar00#ifndef RBIMPL_HAS_EXTENSION_H                       /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_HAS_EXTENSION_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_HAS_EXTENSION.
 */
#include "ruby/internal/has/feature.h"

/** Wraps (or simulates) `__has_extension`. */
#if defined(__has_extension)
# define RBIMPL_HAS_EXTENSION(_) __has_extension(_)
#else
# /* Pre-3.0 clang had __has_feature but not __has_extension. */
# define RBIMPL_HAS_EXTENSION(_) RBIMPL_HAS_FEATURE(_)
#endif

#endif /* RBIMPL_HAS_EXTENSION_H */
ruby/internal/has/attribute.h000064400000020510151732674140012300 0ustar00#ifndef RBIMPL_HAS_ATTRIBUTE_H                       /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_HAS_ATTRIBUTE_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_HAS_ATTRIBUTE.
 */
#include "ruby/internal/config.h"
#include "ruby/internal/compiler_since.h"

#if defined(__has_attribute)
# if __has_attribute(pure) || RBIMPL_COMPILER_IS(GCC)
#  /* FreeBSD's   <sys/cdefs.h>   defines   its   own   *broken*   version   of
#   * __has_attribute.   Cygwin copied  that  content  to be  a  victim of  the
#   * broken-ness.  We don't take them into account. */
#  define RBIMPL_HAVE___HAS_ATTRIBUTE 1
# endif
#endif

/** Wraps (or simulates) `__has_attribute`. */
#if defined(RBIMPL_HAVE___HAS_ATTRIBUTE)
# define RBIMPL_HAS_ATTRIBUTE(_) __has_attribute(_)

#elif RBIMPL_COMPILER_IS(GCC)
# /* GCC  <= 4  lack __has_attribute  predefined macro,  while have  attributes
#  * themselves.  We can simulate the macro like the following: */
# define RBIMPL_HAS_ATTRIBUTE(_) (RBIMPL_HAS_ATTRIBUTE_ ## _)
# define RBIMPL_HAS_ATTRIBUTE_aligned                    RBIMPL_COMPILER_SINCE(GCC, 0, 0, 0)
# define RBIMPL_HAS_ATTRIBUTE_alloc_size                 RBIMPL_COMPILER_SINCE(GCC, 4, 3, 0)
# define RBIMPL_HAS_ATTRIBUTE_artificial                 RBIMPL_COMPILER_SINCE(GCC, 4, 3, 0)
# define RBIMPL_HAS_ATTRIBUTE_always_inline              RBIMPL_COMPILER_SINCE(GCC, 3, 1, 0)
# define RBIMPL_HAS_ATTRIBUTE_cdecl                      RBIMPL_COMPILER_SINCE(GCC, 0, 0, 0)
# define RBIMPL_HAS_ATTRIBUTE_cold                       RBIMPL_COMPILER_SINCE(GCC, 4, 3, 0)
# define RBIMPL_HAS_ATTRIBUTE_const                      RBIMPL_COMPILER_SINCE(GCC, 2, 6, 0)
# define RBIMPL_HAS_ATTRIBUTE_deprecated                 RBIMPL_COMPILER_SINCE(GCC, 3, 1, 0)
# define RBIMPL_HAS_ATTRIBUTE_dllexport                  RBIMPL_COMPILER_SINCE(GCC, 0, 0, 0)
# define RBIMPL_HAS_ATTRIBUTE_dllimport                  RBIMPL_COMPILER_SINCE(GCC, 0, 0, 0)
# define RBIMPL_HAS_ATTRIBUTE_error                      RBIMPL_COMPILER_SINCE(GCC, 4, 3, 0)
# define RBIMPL_HAS_ATTRIBUTE_format                     RBIMPL_COMPILER_SINCE(GCC, 0, 0, 0)
# define RBIMPL_HAS_ATTRIBUTE_hot                        RBIMPL_COMPILER_SINCE(GCC, 4, 3, 0)
# define RBIMPL_HAS_ATTRIBUTE_leaf                       RBIMPL_COMPILER_SINCE(GCC, 4, 6, 0)
# define RBIMPL_HAS_ATTRIBUTE_malloc                     RBIMPL_COMPILER_SINCE(GCC, 3, 0, 0)
# define RBIMPL_HAS_ATTRIBUTE_no_address_safety_analysis RBIMPL_COMPILER_SINCE(GCC, 4, 8, 0)
# define RBIMPL_HAS_ATTRIBUTE_no_sanitize_address        RBIMPL_COMPILER_SINCE(GCC, 4, 8, 0)
# define RBIMPL_HAS_ATTRIBUTE_no_sanitize_undefined      RBIMPL_COMPILER_SINCE(GCC, 4, 9, 0)
# define RBIMPL_HAS_ATTRIBUTE_noinline                   RBIMPL_COMPILER_SINCE(GCC, 3, 1, 0)
# define RBIMPL_HAS_ATTRIBUTE_nonnull                    RBIMPL_COMPILER_SINCE(GCC, 3, 3, 0)
# define RBIMPL_HAS_ATTRIBUTE_noreturn                   RBIMPL_COMPILER_SINCE(GCC, 2, 5, 0)
# define RBIMPL_HAS_ATTRIBUTE_nothrow                    RBIMPL_COMPILER_SINCE(GCC, 3, 3, 0)
# define RBIMPL_HAS_ATTRIBUTE_pure                       RBIMPL_COMPILER_SINCE(GCC, 2,96, 0)
# define RBIMPL_HAS_ATTRIBUTE_returns_nonnull            RBIMPL_COMPILER_SINCE(GCC, 4, 9, 0)
# define RBIMPL_HAS_ATTRIBUTE_returns_twice              RBIMPL_COMPILER_SINCE(GCC, 4, 1, 0)
# define RBIMPL_HAS_ATTRIBUTE_stdcall                    RBIMPL_COMPILER_SINCE(GCC, 0, 0, 0)
# define RBIMPL_HAS_ATTRIBUTE_unused                     RBIMPL_COMPILER_SINCE(GCC, 0, 0, 0)
# define RBIMPL_HAS_ATTRIBUTE_visibility                 RBIMPL_COMPILER_SINCE(GCC, 3, 3, 0)
# define RBIMPL_HAS_ATTRIBUTE_warn_unused_result         RBIMPL_COMPILER_SINCE(GCC, 3, 4, 0)
# define RBIMPL_HAS_ATTRIBUTE_warning                    RBIMPL_COMPILER_SINCE(GCC, 4, 3, 0)
# define RBIMPL_HAS_ATTRIBUTE_weak                       RBIMPL_COMPILER_SINCE(GCC, 0, 0, 0)
# /* Note that "0, 0, 0" might be inaccurate. */

#elif RBIMPL_COMPILER_IS(SunPro)
# /* Oracle Solaris Studio 12.4 (cc version 5.11) introduced __has_attribute.
#  * Before that, following attributes were available. */
# /* See https://docs.oracle.com/cd/F24633_01/index.html */
# define RBIMPL_HAS_ATTRIBUTE(_) (RBIMPL_HAS_ATTRIBUTE_ ## _)
# define RBIMPL_HAS_ATTRIBUTE_alias                      RBIMPL_COMPILER_SINCE(SunPro, 5,  9, 0)
# define RBIMPL_HAS_ATTRIBUTE_aligned                    RBIMPL_COMPILER_SINCE(SunPro, 5,  9, 0)
# define RBIMPL_HAS_ATTRIBUTE_always_inline              RBIMPL_COMPILER_SINCE(SunPro, 5, 10, 0)
# define RBIMPL_HAS_ATTRIBUTE_const                      RBIMPL_COMPILER_SINCE(SunPro, 5,  9, 0)
# define RBIMPL_HAS_ATTRIBUTE_constructor                RBIMPL_COMPILER_SINCE(SunPro, 5,  9, 0)
# define RBIMPL_HAS_ATTRIBUTE_destructor                 RBIMPL_COMPILER_SINCE(SunPro, 5,  9, 0)
# define RBIMPL_HAS_ATTRIBUTE_malloc                     RBIMPL_COMPILER_SINCE(SunPro, 5,  9, 0)
# define RBIMPL_HAS_ATTRIBUTE_noinline                   RBIMPL_COMPILER_SINCE(SunPro, 5,  9, 0)
# define RBIMPL_HAS_ATTRIBUTE_noreturn                   RBIMPL_COMPILER_SINCE(SunPro, 5,  9, 0)
# define RBIMPL_HAS_ATTRIBUTE_packed                     RBIMPL_COMPILER_SINCE(SunPro, 5,  9, 0)
# define RBIMPL_HAS_ATTRIBUTE_pure                       RBIMPL_COMPILER_SINCE(SunPro, 5,  9, 0)
# define RBIMPL_HAS_ATTRIBUTE_returns_twice              RBIMPL_COMPILER_SINCE(SunPro, 5, 10, 0)
# define RBIMPL_HAS_ATTRIBUTE_vector_size                RBIMPL_COMPILER_SINCE(SunPro, 5, 10, 0)
# define RBIMPL_HAS_ATTRIBUTE_visibility                 RBIMPL_COMPILER_SINCE(SunPro, 5,  9, 0)
# define RBIMPL_HAS_ATTRIBUTE_weak                       RBIMPL_COMPILER_SINCE(SunPro, 5,  9, 0)

#elif defined (_MSC_VER)
# define RBIMPL_HAS_ATTRIBUTE(_) 0
# /* Fallback below doesn't work: see win32/Makefile.sub */

#else
# /* Take config.h definition when available. */
# define RBIMPL_HAS_ATTRIBUTE(_) ((RBIMPL_HAS_ATTRIBUTE_ ## _)+0)
# ifdef ALWAYS_INLINE
#  define RBIMPL_HAS_ATTRIBUTE_always_inline 1
# endif
# ifdef FUNC_CDECL
#  define RBIMPL_HAS_ATTRIBUTE_cdecl 1
# endif
# ifdef CONSTFUNC
#  define RBIMPL_HAS_ATTRIBUTE_const 1
# endif
# ifdef DEPRECATED
#  define RBIMPL_HAS_ATTRIBUTE_deprecated 1
# endif
# ifdef ERRORFUNC
#  define RBIMPL_HAS_ATTRIBUTE_error 1
# endif
# ifdef FUNC_FASTCALL
#  define RBIMPL_HAS_ATTRIBUTE_fastcall 1
# endif
# ifdef PUREFUNC
#  define RBIMPL_HAS_ATTRIBUTE_pure 1
# endif
# ifdef NO_ADDRESS_SAFETY_ANALYSIS
#  define RBIMPL_HAS_ATTRIBUTE_no_address_safety_analysis 1
# endif
# ifdef NO_SANITIZE
#  define RBIMPL_HAS_ATTRIBUTE_no_sanitize 1
# endif
# ifdef NO_SANITIZE_ADDRESS
#  define RBIMPL_HAS_ATTRIBUTE_no_sanitize_address 1
# endif
# ifdef NOINLINE
#  define RBIMPL_HAS_ATTRIBUTE_noinline 1
# endif
# ifdef RBIMPL_FUNC_NONNULL
#  define RBIMPL_HAS_ATTRIBUTE_nonnull 1
# endif
# ifdef NORETURN
#  define RBIMPL_HAS_ATTRIBUTE_noreturn 1
# endif
# ifdef FUNC_OPTIMIZED
#  define RBIMPL_HAS_ATTRIBUTE_optimize 1
# endif
# ifdef FUNC_STDCALL
#  define RBIMPL_HAS_ATTRIBUTE_stdcall 1
# endif
# ifdef MAYBE_UNUSED
#  define RBIMPL_HAS_ATTRIBUTE_unused 1
# endif
# ifdef WARN_UNUSED_RESULT
#  define RBIMPL_HAS_ATTRIBUTE_warn_unused_result 1
# endif
# ifdef WARNINGFUNC
#  define RBIMPL_HAS_ATTRIBUTE_warning 1
# endif
# ifdef WEAK
#  define RBIMPL_HAS_ATTRIBUTE_weak 1
# endif
#endif

#endif /* RBIMPL_HAS_ATTRIBUTE_H */
ruby/internal/has/warning.h000064400000003026151732674140011745 0ustar00#ifndef RBIMPL_HAS_WARNING_H                         /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_HAS_WARNING_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_HAS_WARNING.
 */

/** Wraps (or simulates) `__has_warning`. */
#if defined(__has_warning)
# define RBIMPL_HAS_WARNING(_) __has_warning(_)
#else
# define RBIMPL_HAS_WARNING(_) 0
#endif

#endif /* RBIMPL_HAS_WARNING_H */
ruby/internal/has/builtin.h000064400000016746151732674140011763 0ustar00#ifndef RBIMPL_HAS_BUILTIN_H                         /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_HAS_BUILTIN_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_HAS_BUILTIN.
 */
#include "ruby/internal/config.h"
#include "ruby/internal/compiler_since.h"

#if defined(__has_builtin)
# if RBIMPL_COMPILER_IS(Intel)
#  /* :TODO: Intel  C Compiler  has __has_builtin (since  19.1 maybe?),  and is
#   * reportedly  broken.  We  have to  skip them.   However the  situation can
#   * change.  They might improve someday.  We need to revisit here later. */
# elif RBIMPL_COMPILER_IS(GCC) && ! __has_builtin(__builtin_alloca)
#  /* FreeBSD's   <sys/cdefs.h>   defines   its   own   *broken*   version   of
#   * __has_builtin.   Cygwin  copied  that  content  to be  a  victim  of  the
#   * broken-ness.  We don't take them into account. */
# else
#  define RBIMPL_HAVE___HAS_BUILTIN 1
# endif
#endif

/** Wraps (or simulates) `__has_builtin`. */
#if defined(RBIMPL_HAVE___HAS_BUILTIN)
# define RBIMPL_HAS_BUILTIN(_) __has_builtin(_)

#elif RBIMPL_COMPILER_IS(GCC)
# /* :FIXME: Historically  GCC has had  tons of builtins, but  it implemented
#  * __has_builtin  only  since  GCC  10.   This section  can  be  made  more
#  * granular. */
# /* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970 */
# define RBIMPL_HAS_BUILTIN(_) (RBIMPL_HAS_BUILTIN_ ## _)
# define RBIMPL_HAS_BUILTIN___builtin_add_overflow      RBIMPL_COMPILER_SINCE(GCC, 5, 1, 0)
# define RBIMPL_HAS_BUILTIN___builtin_add_overflow_p    RBIMPL_COMPILER_SINCE(GCC, 7, 0, 0)
# define RBIMPL_HAS_BUILTIN___builtin_alloca            RBIMPL_COMPILER_SINCE(GCC, 0, 0, 0)
# define RBIMPL_HAS_BUILTIN___builtin_alloca_with_align RBIMPL_COMPILER_SINCE(GCC, 6, 1, 0)
# define RBIMPL_HAS_BUILTIN___builtin_assume            0
# /* See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52624 for bswap16. */
# define RBIMPL_HAS_BUILTIN___builtin_bswap16           RBIMPL_COMPILER_SINCE(GCC, 4, 8, 0)
#ifndef __OpenBSD__
# define RBIMPL_HAS_BUILTIN___builtin_bswap32           RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
# define RBIMPL_HAS_BUILTIN___builtin_bswap64           RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
#endif
# define RBIMPL_HAS_BUILTIN___builtin_clz               RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
# define RBIMPL_HAS_BUILTIN___builtin_clzl              RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
# define RBIMPL_HAS_BUILTIN___builtin_clzll             RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
# define RBIMPL_HAS_BUILTIN___builtin_constant_p        RBIMPL_COMPILER_SINCE(GCC, 2,95, 3)
# define RBIMPL_HAS_BUILTIN___builtin_ctz               RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
# define RBIMPL_HAS_BUILTIN___builtin_ctzl              RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
# define RBIMPL_HAS_BUILTIN___builtin_ctzll             RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
# define RBIMPL_HAS_BUILTIN___builtin_expect            RBIMPL_COMPILER_SINCE(GCC, 3, 0, 0)
# define RBIMPL_HAS_BUILTIN___builtin_mul_overflow      RBIMPL_COMPILER_SINCE(GCC, 5, 1, 0)
# define RBIMPL_HAS_BUILTIN___builtin_mul_overflow_p    RBIMPL_COMPILER_SINCE(GCC, 7, 0, 0)
# define RBIMPL_HAS_BUILTIN___builtin_popcount          RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
# define RBIMPL_HAS_BUILTIN___builtin_popcountl         RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
# define RBIMPL_HAS_BUILTIN___builtin_popcountll        RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
# define RBIMPL_HAS_BUILTIN___builtin_rotateleft32      0
# define RBIMPL_HAS_BUILTIN___builtin_rotateleft64      0
# define RBIMPL_HAS_BUILTIN___builtin_rotateright32     0
# define RBIMPL_HAS_BUILTIN___builtin_rotateright64     0
# define RBIMPL_HAS_BUILTIN___builtin_sub_overflow      RBIMPL_COMPILER_SINCE(GCC, 5, 1, 0)
# define RBIMPL_HAS_BUILTIN___builtin_sub_overflow_p    RBIMPL_COMPILER_SINCE(GCC, 7, 0, 0)
# define RBIMPL_HAS_BUILTIN___builtin_unreachable       RBIMPL_COMPILER_SINCE(GCC, 4, 5, 0)
# /* Note that "0, 0, 0" might be inaccurate. */

#else
# /* Take config.h definition when available */
# define RBIMPL_HAS_BUILTIN(_) ((RBIMPL_HAS_BUILTIN_ ## _)+0)
# define RBIMPL_HAS_BUILTIN___builtin_add_overflow      HAVE_BUILTIN___BUILTIN_ADD_OVERFLOW
# define RBIMPL_HAS_BUILTIN___builtin_add_overflow_p    HAVE_BUILTIN___BUILTIN_ADD_OVERFLOW_P
# define RBIMPL_HAS_BUILTIN___builtin_alloca            0
# define RBIMPL_HAS_BUILTIN___builtin_alloca_with_align HAVE_BUILTIN___BUILTIN_ALLOCA_WITH_ALIGN
# define RBIMPL_HAS_BUILTIN___builtin_assume            0
# define RBIMPL_HAS_BUILTIN___builtin_assume_aligned    HAVE_BUILTIN___BUILTIN_ASSUME_ALIGNED
# define RBIMPL_HAS_BUILTIN___builtin_bswap16           HAVE_BUILTIN___BUILTIN_BSWAP16
# define RBIMPL_HAS_BUILTIN___builtin_bswap32           HAVE_BUILTIN___BUILTIN_BSWAP32
# define RBIMPL_HAS_BUILTIN___builtin_bswap64           HAVE_BUILTIN___BUILTIN_BSWAP64
# define RBIMPL_HAS_BUILTIN___builtin_clz               HAVE_BUILTIN___BUILTIN_CLZ
# define RBIMPL_HAS_BUILTIN___builtin_clzl              HAVE_BUILTIN___BUILTIN_CLZL
# define RBIMPL_HAS_BUILTIN___builtin_clzll             HAVE_BUILTIN___BUILTIN_CLZLL
# define RBIMPL_HAS_BUILTIN___builtin_constant_p        HAVE_BUILTIN___BUILTIN_CONSTANT_P
# define RBIMPL_HAS_BUILTIN___builtin_ctz               HAVE_BUILTIN___BUILTIN_CTZ
# define RBIMPL_HAS_BUILTIN___builtin_ctzl              0
# define RBIMPL_HAS_BUILTIN___builtin_ctzll             HAVE_BUILTIN___BUILTIN_CTZLL
# define RBIMPL_HAS_BUILTIN___builtin_expect            HAVE_BUILTIN___BUILTIN_EXPECT
# define RBIMPL_HAS_BUILTIN___builtin_mul_overflow      HAVE_BUILTIN___BUILTIN_MUL_OVERFLOW
# define RBIMPL_HAS_BUILTIN___builtin_mul_overflow_p    HAVE_BUILTIN___BUILTIN_MUL_OVERFLOW_P
# define RBIMPL_HAS_BUILTIN___builtin_popcount          HAVE_BUILTIN___BUILTIN_POPCOUNT
# define RBIMPL_HAS_BUILTIN___builtin_popcountl         0
# define RBIMPL_HAS_BUILTIN___builtin_rotateleft32      0
# define RBIMPL_HAS_BUILTIN___builtin_rotateleft64      0
# define RBIMPL_HAS_BUILTIN___builtin_rotateright32     0
# define RBIMPL_HAS_BUILTIN___builtin_rotateright64     0
# define RBIMPL_HAS_BUILTIN___builtin_popcountll        HAVE_BUILTIN___BUILTIN_POPCOUNTLL
# define RBIMPL_HAS_BUILTIN___builtin_sub_overflow      HAVE_BUILTIN___BUILTIN_SUB_OVERFLOW
# define RBIMPL_HAS_BUILTIN___builtin_sub_overflow_p    HAVE_BUILTIN___BUILTIN_SUB_OVERFLOW_P
# if defined(HAVE___BUILTIN_UNREACHABLE)
#  define RBIMPL_HAS_BUILTIN___builtin_unreachable 1
# else
#  define RBIMPL_HAS_BUILTIN___builtin_unreachable 0
# endif
#endif

#endif /* RBIMPL_HAS_BUILTIN_H */
ruby/internal/has/feature.h000064400000003026151732674140011733 0ustar00#ifndef RBIMPL_HAS_FEATURE_H                         /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_HAS_FEATURE_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_HAS_FEATURE.
 */

/** Wraps (or simulates) `__has_feature`. */
#if defined(__has_feature)
# define RBIMPL_HAS_FEATURE(_) __has_feature(_)
#else
# define RBIMPL_HAS_FEATURE(_) 0
#endif

#endif /* RBIMPL_HAS_FEATURE_H */
ruby/internal/has/declspec_attribute.h000064400000005371151732674140014152 0ustar00#ifndef RBIMPL_HAS_DECLSPEC_ATTRIBUTE_H              /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_HAS_DECLSPEC_ATTRIBUTE.
 */
#include "ruby/internal/compiler_since.h"

/** Wraps (or simulates) `__has_declspec_attribute`. */
#if defined(__has_declspec_attribute)
# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE(_) __has_declspec_attribute(_)
#else
# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE(_) (RBIMPL_HAS_DECLSPEC_ATTRIBUTE_ ## _)
# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_align       RBIMPL_COMPILER_SINCE(MSVC, 8, 0, 0)
# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_deprecated  RBIMPL_COMPILER_SINCE(MSVC,13, 0, 0)
# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_dllexport   RBIMPL_COMPILER_SINCE(MSVC, 8, 0, 0)
# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_dllimport   RBIMPL_COMPILER_SINCE(MSVC, 8, 0, 0)
# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_empty_bases RBIMPL_COMPILER_SINCE(MSVC,19, 0, 23918)
# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_noalias     RBIMPL_COMPILER_SINCE(MSVC, 8, 0, 0)
# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_noinline    RBIMPL_COMPILER_SINCE(MSVC,13, 0, 0)
# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_noreturn    RBIMPL_COMPILER_SINCE(MSVC,11, 0, 0)
# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_nothrow     RBIMPL_COMPILER_SINCE(MSVC, 8, 0, 0)
# define RBIMPL_HAS_DECLSPEC_ATTRIBUTE_restrict    RBIMPL_COMPILER_SINCE(MSVC,14, 0, 0)
# /* Note that "8, 0, 0" might be inaccurate. */
# if ! defined(__cplusplus)
#  /* Clang has this in both C/C++, but MSVC has this in C++ only.*/
#  undef RBIMPL_HAS_DECLSPEC_ATTRIBUTE_nothrow
# endif
#endif

#endif /* RBIMPL_HAS_DECLSPEC_ATTRIBUTE_H */
ruby/internal/compiler_is.h000064400000004071151732674140012033 0ustar00#ifndef RBIMPL_COMPILER_IS_H                         /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_COMPILER_IS_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_COMPILER_IS.
 */

/**
 * @brief   Checks if the compiler is of given brand.
 * @param   cc     Compiler brand, like `MSVC`.
 * @retval  true   It is.
 * @retval  false  It isn't.
 */
#define RBIMPL_COMPILER_IS(cc) RBIMPL_COMPILER_IS_ ## cc

#include "ruby/internal/compiler_is/apple.h"
#include "ruby/internal/compiler_is/clang.h"
#include "ruby/internal/compiler_is/gcc.h"
#include "ruby/internal/compiler_is/intel.h"
#include "ruby/internal/compiler_is/msvc.h"
#include "ruby/internal/compiler_is/sunpro.h"
/* :TODO: Other possible compilers to support:
 *
 * - IBM  XL: recent  XL are  clang-backended  so some  tweaks like  we do  for
 *   Apple's might be needed.
 *
 * - ARM's armclang: ditto, it can be clang-backended.  */

#endif /* RBIMPL_COMPILER_IS_H */
ruby/internal/module.h000064400000016165151732674140011022 0ustar00#ifndef RBIMPL_MODULE_H                              /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_MODULE_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Creation and modification of Ruby modules.
 */
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"

/**
 * @defgroup  class  Classes and their hierarchy.
 *
 * @par Terminology
 *   - class: same as in Ruby.
 *   - singleton class: class for a particular object.
 *   - eigenclass: = singleton class
 *   - metaclass: class of a class.  Metaclass is a kind of singleton class.
 *   - metametaclass: class of a metaclass.
 *   - meta^(n)-class: class of a meta^(n-1)-class.
 *   - attached object: A singleton class knows its unique instance.
 *     The instance is called the attached object for the singleton class.
 * @{
 */

RBIMPL_SYMBOL_EXPORT_BEGIN()

RBIMPL_ATTR_NONNULL(())
/**
 * Defines a top-level class.
 *
 * @param[in]  name           Name of the class.
 * @param[in]  super          A class from which the new class will derive.
 * @exception  rb_eTypeError  The constant name `name` is already taken but the
 *                            constant is not a class.
 * @exception  rb_eTypeError  The class  is already  defined but the  class can
 *                            not  be reopened  because its  superclass is  not
 *                            `super`.
 * @exception  rb_eArgError   `super` is NULL.
 * @return     The created class.
 * @post       Top-level constant named `name` refers the returned class.
 * @note       If a class named `name` is already defined and its superclass is
 *             `super`, the function just returns the defined class.
 * @note       The GC does not collect nor move classes returned by this
 *             function. They are immortal.
 *
 * @internal
 *
 * There are classes without names, but you  can't pass NULL here.  You have to
 * use other ways to create one.
 */
VALUE rb_define_class(const char *name, VALUE super);

RBIMPL_ATTR_NONNULL(())
/**
 * Defines a top-level module.
 *
 * @param[in]  name           Name of the module.
 * @exception  rb_eTypeError  The constant name `name` is already taken but the
 *                            constant is not a module.
 * @return     The created module.
 * @post       Top-level constant named `name` refers the returned module.
 * @note       The GC does not collect nor move modules returned by this
 *             function. They are immortal.
 *
 * @internal
 *
 * There are modules without names, but you  can't pass NULL here.  You have to
 * use other ways to create one.
 */
VALUE rb_define_module(const char *name);

RBIMPL_ATTR_NONNULL(())
/**
 * Defines a class under the namespace of `outer`.
 *
 * @param[out]  outer          A class which contains the new class.
 * @param[in]   name           Name of the new class
 * @param[in]   super          A class from which the new class will derive.
 *                             0 means ::rb_cObject.
 * @exception   rb_eTypeError  The constant  name `name`  is already  taken but
 *                             the constant is not a class.
 * @exception   rb_eTypeError  The class  is already defined but  the class can
 *                             not be  reopened because  its superclass  is not
 *                             `super`.
 * @exception   rb_eArgError   `super` is NULL.
 * @return      The created class.
 * @post        `outer::name` refers the returned class.
 * @note        If a class  named `name` is already defined  and its superclass
 *              is `super`, the function just returns the defined class.
 * @note        The GC does not collect nor move classes returned by this
 *              function. They are immortal.
 */
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super);

RBIMPL_ATTR_NONNULL(())
/**
 * Defines a module under the namespace of `outer`.
 *
 * @param[out]  outer          A class which contains the new module.
 * @param[in]   name           Name of the new module
 * @exception   rb_eTypeError  The constant  name `name`  is already  taken but
 *                             the constant is not a class.
 * @return      The created module.
 * @post        `outer::name` refers the returned module.
 * @note        The GC does not collect nor move modules returned by this
 *              function. They are immortal.
 */
VALUE rb_define_module_under(VALUE outer, const char *name);

/**
 * Includes a module to a class.
 *
 * @param[out]  klass         Inclusion destination.
 * @param[in]   module        Inclusion source.
 * @exception   rb_eArgError  Cyclic inclusion.
 *
 * @internal
 *
 * :FIXME: @shyouhei suspects this function  lacks assertion that the arguments
 * being modules...  Could silently SEGV if non-module was passed?
 */
void rb_include_module(VALUE klass, VALUE module);

/**
 * Extend the object with the module.
 *
 * @warning     This    is   the    same    as   `Module#extend_object`,    not
 *              `Object#extend`!  These  two methods are very  similar, but not
 *              identical.  The difference is the hook.  `Module#extend_object`
 *              does not invoke `Module#extended`, while `Object#extend` does.
 * @param[out]  obj  Object to extend.
 * @param[in]   mod  Module of extension.
 */
void rb_extend_object(VALUE obj, VALUE mod);

/**
 * Identical to rb_include_module(), except it  "prepends" the passed module to
 * the klass,  instead of  includes.  This affects  how `super`  resolves.  For
 * instance:
 *
 * ```ruby
 * class  Q;                def foo;      "<q/>"       end end
 * module W;                def foo; "<w>#{super}</w>" end end
 * class  E < Q; include W; def foo; "<e>#{super}</e>" end end
 * class  R < Q; prepend W; def foo; "<r>#{super}</r>" end end
 *
 * E.new.foo # => "<e><w><q/></w></e>"
 * r.new.foo # => "<W><r><q/></r></w>"
 * ```
 *
 * @param[out]  klass         Target class to modify.
 * @param[in]   module        Module to prepend.
 * @exception   rb_eArgError  Cyclic inclusion.
 */
void rb_prepend_module(VALUE klass, VALUE module);

/** @} */

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_MODULE_H */
ruby/internal/stdbool.h000064400000003305151732674140011173 0ustar00#ifndef RBIMPL_STDBOOL_H                             /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_STDBOOL_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      C99 shim for <stdbool.h>
 */
#include "ruby/internal/config.h"

#if defined(__bool_true_false_are_defined)
# /* Take that. */

#elif defined(__cplusplus)
# /* bool is a keyword in C++. */
# ifndef __bool_true_false_are_defined
#  define __bool_true_false_are_defined
# endif

#else
# /* Take stdbool.h definition. It exists since GCC 3.0 and VS 2015. */
# include <stdbool.h>
#endif

#endif /* RBIMPL_STDBOOL_H */
ruby/internal/ctype.h000064400000055071151732674140010660 0ustar00#ifndef RBIMPL_CTYPE_H                               /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_CTYPE_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Our own, locale independent, character handling routines.
 */
#include "ruby/internal/config.h"

#ifdef STDC_HEADERS
# include <ctype.h>
#endif

#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/attr/const.h"
#include "ruby/internal/attr/constexpr.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"

/**
 * @name Old character classification macros
 *
 * What  is this  #ISPRINT  business?   Well, according  to  our  VCS and  some
 * internet surfing, it appears that the initial intent of these macros were to
 * mimic codes appear  in common in several GNU projects.   As far as @shyouhei
 * detects they  seem to originate GNU  regex (that standalone one  rather than
 * Gnulib or Glibc), and at least date back to 1995.
 *
 * Let me lawfully quote from a GNU coreutils commit
 * https://git.savannah.gnu.org/cgit/coreutils.git/commit/?id=49803907f5dbd7646184a8912c9db9b09dcd0f22
 *
 *   > Jim Meyering writes:
 *   >
 *   > "... Some ctype macros are valid only for character codes that
 *   > isascii says are ASCII (SGI's IRIX-4.0.5 is one such system --when
 *   > using /bin/cc or gcc but without giving an ansi option).  So, all
 *   > ctype uses should be through macros like ISPRINT...  If
 *   > STDC_HEADERS is defined, then autoconf has verified that the ctype
 *   > macros don't need to be guarded with references to isascii. ...
 *   > Defining isascii to 1 should let any compiler worth its salt
 *   > eliminate the && through constant folding."
 *   >
 *   > Bruno Haible adds:
 *   >
 *   > "... Furthermore, isupper(c) etc. have an undefined result if c is
 *   > outside the range -1 <= c <= 255. One is tempted to write isupper(c)
 *   > with c being of type `char', but this is wrong if c is an 8-bit
 *   > character >= 128 which gets sign-extended to a negative value.
 *   > The macro ISUPPER protects against this as well."
 *
 * So the intent  was to reroute old problematic systems  that no longer exist.
 * At the same time the problems described  above no longer hurt us, because we
 * decided to completely  avoid using system-provided isupper  etc. to reinvent
 * the wheel.  These macros are entirely legacy; please ignore them.
 *
 * But let me also  put stress that GNU people are wise;  they use those macros
 * only inside of  their own implementations and never let  them be public.  On
 * the other hand ruby has thoughtlessly publicised them to 3rd party libraries
 * since its beginning, which is a very bad idea.  These macros are too easy to
 * get conflicted with definitions elsewhere.
 *
 * New programs should stick to the `rb_` prefixed names.
 *
 * @note  It seems we just mimic the API.  We do not share their implementation
 *        with GPL-ed programs.
 *
 * @{
 */
#ifndef ISPRINT
# define ISASCII  rb_isascii    /**< @old{rb_isascii}*/
# define ISPRINT  rb_isprint    /**< @old{rb_isprint}*/
# define ISGRAPH  rb_isgraph    /**< @old{rb_isgraph}*/
# define ISSPACE  rb_isspace    /**< @old{rb_isspace}*/
# define ISUPPER  rb_isupper    /**< @old{rb_isupper}*/
# define ISLOWER  rb_islower    /**< @old{rb_islower}*/
# define ISALNUM  rb_isalnum    /**< @old{rb_isalnum}*/
# define ISALPHA  rb_isalpha    /**< @old{rb_isalpha}*/
# define ISDIGIT  rb_isdigit    /**< @old{rb_isdigit}*/
# define ISXDIGIT rb_isxdigit   /**< @old{rb_isxdigit}*/
# define ISBLANK  rb_isblank    /**< @old{rb_isblank}*/
# define ISCNTRL  rb_iscntrl    /**< @old{rb_iscntrl}*/
# define ISPUNCT  rb_ispunct    /**< @old{rb_ispunct}*/
#endif

#define TOUPPER     rb_toupper    /**< @old{rb_toupper}*/
#define TOLOWER     rb_tolower    /**< @old{rb_tolower}*/
#define STRCASECMP  st_locale_insensitive_strcasecmp  /**< @old{st_locale_insensitive_strcasecmp}*/
#define STRNCASECMP st_locale_insensitive_strncasecmp /**< @old{st_locale_insensitive_strncasecmp}*/
#define STRTOUL     ruby_strtoul  /**< @old{ruby_strtoul}*/

/** @} */

RBIMPL_SYMBOL_EXPORT_BEGIN()
/** @name locale insensitive functions
 *  @{
 */

/* In descriptions below, `the POSIX Locale` and `the "C" locale` are tactfully
 * used as to whether the described function mimics POSIX or C99. */

RBIMPL_ATTR_NONNULL(())
/**
 * Our  own locale-insensitive  version  of `strcasecmp(3)`.   The "case"  here
 * always means that of the POSIX  Locale.  It doesn't depend on runtime locale
 * settings.
 *
 * @param[in]  s1  Comparison LHS.
 * @param[in]  s2  Comparison RHS.
 * @retval     -1  `s1` is "less" than `s2`.
 * @retval      0  Both strings converted into lowercase would be identical.
 * @retval      1  `s1` is "greater" than `s2`.
 * @note       Not only  does this function  works under the POSIX  Locale, but
 *             also assumes its  execution character set be what  ruby calls an
 *             ASCII-compatible  character  set;  which does  not  include  for
 *             instance EBCDIC or UTF-16LE.
 */
int st_locale_insensitive_strcasecmp(const char *s1, const char *s2);

RBIMPL_ATTR_NONNULL(())
/**
 * Our  own locale-insensitive  version of  `strcnasecmp(3)`.  The  "case" here
 * always means that of the POSIX  Locale.  It doesn't depend on runtime locale
 * settings.
 *
 * @param[in]  s1  Comparison LHS.
 * @param[in]  s2  Comparison RHS.
 * @param[in]  n   Comparison shall stop after first `n` bytes are scanned.
 * @retval     -1  `s1` is "less" than `s2`.
 * @retval      0  Both strings converted into lowercase would be identical.
 * @retval      1  `s1` is "greater" than `s2`.
 * @note       Not only  does this function  works under the POSIX  Locale, but
 *             also assumes its  execution character set be what  ruby calls an
 *             ASCII-compatible  character  set;  which does  not  include  for
 *             instance EBCDIC or UTF-16LE.
 * @warning    This function is _not_ timing safe.
 */
int st_locale_insensitive_strncasecmp(const char *s1, const char *s2, size_t n);

RBIMPL_ATTR_NONNULL((1))
/**
 * Our own locale-insensitive version of  `strtoul(3)`.  The conversion is done
 * as if the current locale is set  to the "C" locale, no matter actual runtime
 * locale settings.
 *
 * @note        This is needed because  `strtoul("i", 0, 36)` would return zero
 *              if it is locale sensitive and the current locale is `tr_TR`.
 * @param[in]   str     String of digits,  optionally preceded with whitespaces
 *                      (ignored) and optionally `+` or `-` sign.
 * @param[out]  endptr  NULL, or an arbitrary pointer (overwritten on return).
 * @param[in]   base    `2` to  `36` inclusive for  each base, or  special case
 *                      `0` to detect the base from the contents of the string.
 * @return      Converted integer, casted to unsigned long.
 * @post        If `endptr` is not NULL, it  is updated to point the first such
 *              byte where conversion failed.
 * @note        This function sets `errno` on failure.
 *                - `EINVAL`: Passed `base` is out of range.
 *                - `ERANGE`: Converted integer is out of range of `long`.
 * @warning     As far as @shyouhei reads ISO/IEC 9899:2018 section 7.22.1.4, a
 *              conforming  `strtoul`  implementation   shall  render  `ERANGE`
 *              whenever  it  finds  the  input string  represents  a  negative
 *              integer.  Such thing can never be representable using `unsigned
 *              long`.   However  this  implementation  does  not  honour  that
 *              language.   It just  casts such  negative value  to the  return
 *              type, resulting a very big  return value.  This behaviour is at
 *              least questionable.  But  we can no longer change  that at this
 *              point.
 * @note        Not only  does this  function works under  the "C"  locale, but
 *              also assumes its execution character  set be what ruby calls an
 *              ASCII-compatible  character set;  which  does  not include  for
 *              instance EBCDIC or UTF-16LE.
 */
unsigned long ruby_strtoul(const char *str, char **endptr, int base);
RBIMPL_SYMBOL_EXPORT_END()

/*
 * We are making  the functions below to return `int`  instead of `bool`.  They
 * have been as such since their birth at 5f237d79033b2109afb768bc889611fa9630.
 */

RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Our own locale-insensitive version of `isascii(3)`.
 *
 * @param[in]  c      Byte in question to query.
 * @retval     false  `c` is out of range of ASCII character set.
 * @retval     true   Yes it is.
 * @warning    `c` is  an int.  This  means that when  you pass a  `char` value
 *             here, it  experiences "integer promotion" as  defined in ISO/IEC
 *             9899:2018 section 6.3.1.1 paragraph 1.
 */
static inline int
rb_isascii(int c)
{
    return '\0' <= c && c <= '\x7f';
}

RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Our own locale-insensitive version of `isupper(3)`.
 *
 * @param[in]  c      Byte in question to query.
 * @retval     true   `c`  is  listed  in IEEE 1003.1 section 7.3.1.1 "upper".
 * @retval     false  Anything else.
 * @note       Not only  does this function  works under the POSIX  Locale, but
 *             also assumes its  execution character set be what  ruby calls an
 *             ASCII-compatible  character  set;  which does  not  include  for
 *             instance EBCDIC or UTF-16LE.
 * @warning    `c` is  an int.  This  means that when  you pass a  `char` value
 *             here, it  experiences "integer promotion" as  defined in ISO/IEC
 *             9899:2018 section 6.3.1.1 paragraph 1.
 */
static inline int
rb_isupper(int c)
{
    return 'A' <= c && c <= 'Z';
}

RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Our own locale-insensitive version of `islower(3)`.
 *
 * @param[in]  c      Byte in question to query.
 * @retval     true   `c`  is  listed  in IEEE 1003.1 section 7.3.1.1 "lower".
 * @retval     false  Anything else.
 * @note       Not only  does this function  works under the POSIX  Locale, but
 *             also assumes its  execution character set be what  ruby calls an
 *             ASCII-compatible  character  set;  which does  not  include  for
 *             instance EBCDIC or UTF-16LE.
 * @warning    `c` is  an int.  This  means that when  you pass a  `char` value
 *             here, it  experiences "integer promotion" as  defined in ISO/IEC
 *             9899:2018 section 6.3.1.1 paragraph 1.
 */
static inline int
rb_islower(int c)
{
    return 'a' <= c && c <= 'z';
}

RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Our own locale-insensitive version of `isalpha(3)`.
 *
 * @param[in]  c      Byte in question to query.
 * @retval     true   `c`  is  listed in  either  IEEE  1003.1 section  7.3.1.1
 *                    "upper" or "lower".
 * @retval     false  Anything else.
 * @note       Not only  does this function  works under the POSIX  Locale, but
 *             also assumes its  execution character set be what  ruby calls an
 *             ASCII-compatible  character  set;  which does  not  include  for
 *             instance EBCDIC or UTF-16LE.
 * @warning    `c` is  an int.  This  means that when  you pass a  `char` value
 *             here, it  experiences "integer promotion" as  defined in ISO/IEC
 *             9899:2018 section 6.3.1.1 paragraph 1.
 */
static inline int
rb_isalpha(int c)
{
    return rb_isupper(c) || rb_islower(c);
}

RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Our own locale-insensitive version of `isdigit(3)`.
 *
 * @param[in]  c      Byte in question to query.
 * @retval     true   `c`  is  listed  in IEEE 1003.1 section 7.3.1.1 "digit".
 * @retval     false  Anything else.
 * @note       Not only  does this function  works under the POSIX  Locale, but
 *             also assumes its  execution character set be what  ruby calls an
 *             ASCII-compatible  character  set;  which does  not  include  for
 *             instance EBCDIC or UTF-16LE.
 * @warning    `c` is  an int.  This  means that when  you pass a  `char` value
 *             here, it  experiences "integer promotion" as  defined in ISO/IEC
 *             9899:2018 section 6.3.1.1 paragraph 1.
 */
static inline int
rb_isdigit(int c)
{
    return '0' <= c && c <= '9';
}

RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Our own locale-insensitive version of `isalnum(3)`.
 *
 * @param[in]  c      Byte in question to query.
 * @retval     true   `c`  is  listed in  either  IEEE  1003.1 section  7.3.1.1
 *                    "upper", "lower", or "digit".
 * @retval     false  Anything else.
 * @note       Not only  does this function  works under the POSIX  Locale, but
 *             also assumes its  execution character set be what  ruby calls an
 *             ASCII-compatible  character  set;  which does  not  include  for
 *             instance EBCDIC or UTF-16LE.
 * @warning    `c` is  an int.  This  means that when  you pass a  `char` value
 *             here, it  experiences "integer promotion" as  defined in ISO/IEC
 *             9899:2018 section 6.3.1.1 paragraph 1.
 */
static inline int
rb_isalnum(int c)
{
    return rb_isalpha(c) || rb_isdigit(c);
}

RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Our own locale-insensitive version of `isxdigit(3)`.
 *
 * @param[in]  c      Byte in question to query.
 * @retval     true   `c`  is  listed  in IEEE 1003.1 section 7.3.1.1 "xdigit".
 * @retval     false  Anything else.
 * @note       Not only  does this function  works under the POSIX  Locale, but
 *             also assumes its  execution character set be what  ruby calls an
 *             ASCII-compatible  character  set;  which does  not  include  for
 *             instance EBCDIC or UTF-16LE.
 * @warning    `c` is  an int.  This  means that when  you pass a  `char` value
 *             here, it  experiences "integer promotion" as  defined in ISO/IEC
 *             9899:2018 section 6.3.1.1 paragraph 1.
 */
static inline int
rb_isxdigit(int c)
{
    return rb_isdigit(c) || ('A' <= c && c <= 'F') || ('a' <= c && c <= 'f');
}

RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Our own locale-insensitive version of `isblank(3)`.
 *
 * @param[in]  c      Byte in question to query.
 * @retval     true   `c`  is  listed  in IEEE 1003.1 section 7.3.1.1 "blank".
 * @retval     false  Anything else.
 * @note       Not only  does this function  works under the POSIX  Locale, but
 *             also assumes its  execution character set be what  ruby calls an
 *             ASCII-compatible  character  set;  which does  not  include  for
 *             instance EBCDIC or UTF-16LE.
 * @warning    `c` is  an int.  This  means that when  you pass a  `char` value
 *             here, it  experiences "integer promotion" as  defined in ISO/IEC
 *             9899:2018 section 6.3.1.1 paragraph 1.
 */
static inline int
rb_isblank(int c)
{
    return c == ' ' || c == '\t';
}

RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Our own locale-insensitive version of `isspace(3)`.
 *
 * @param[in]  c      Byte in question to query.
 * @retval     true   `c`  is  listed  in IEEE 1003.1 section 7.3.1.1 "space".
 * @retval     false  Anything else.
 * @note       Not only  does this function  works under the POSIX  Locale, but
 *             also assumes its  execution character set be what  ruby calls an
 *             ASCII-compatible  character  set;  which does  not  include  for
 *             instance EBCDIC or UTF-16LE.
 * @warning    `c` is  an int.  This  means that when  you pass a  `char` value
 *             here, it  experiences "integer promotion" as  defined in ISO/IEC
 *             9899:2018 section 6.3.1.1 paragraph 1.
 */
static inline int
rb_isspace(int c)
{
    return c == ' ' || ('\t' <= c && c <= '\r');
}

RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Our own locale-insensitive version of `iscntrl(3)`.
 *
 * @param[in]  c      Byte in question to query.
 * @retval     true   `c`  is  listed  in IEEE 1003.1 section 7.3.1.1 "cntrl".
 * @retval     false  Anything else.
 * @note       Not only  does this function  works under the POSIX  Locale, but
 *             also assumes its  execution character set be what  ruby calls an
 *             ASCII-compatible  character  set;  which does  not  include  for
 *             instance EBCDIC or UTF-16LE.
 * @warning    `c` is  an int.  This  means that when  you pass a  `char` value
 *             here, it  experiences "integer promotion" as  defined in ISO/IEC
 *             9899:2018 section 6.3.1.1 paragraph 1.
 */
static inline int
rb_iscntrl(int c)
{
    return ('\0' <= c && c < ' ') || c == '\x7f';
}

RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Identical to rb_isgraph(), except it also returns true for `' '`.
 *
 * @param[in]  c      Byte in question to query.
 * @retval     true   `c`  is  listed in  either  IEEE  1003.1 section  7.3.1.1
 *                    "upper", "lower", "digit", "punct", or a `' '`.
 * @retval     false  Anything else.
 * @note       Not only  does this function  works under the POSIX  Locale, but
 *             also assumes its  execution character set be what  ruby calls an
 *             ASCII-compatible  character  set;  which does  not  include  for
 *             instance EBCDIC or UTF-16LE.
 * @warning    `c` is  an int.  This  means that when  you pass a  `char` value
 *             here, it  experiences "integer promotion" as  defined in ISO/IEC
 *             9899:2018 section 6.3.1.1 paragraph 1.
 */
static inline int
rb_isprint(int c)
{
    return ' ' <= c && c <= '\x7e';
}

RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Our own locale-insensitive version of `ispunct(3)`.
 *
 * @param[in]  c      Byte in question to query.
 * @retval     true   `c`  is  listed  in IEEE 1003.1 section 7.3.1.1 "punct".
 * @retval     false  Anything else.
 * @note       Not only  does this function  works under the POSIX  Locale, but
 *             also assumes its  execution character set be what  ruby calls an
 *             ASCII-compatible  character  set;  which does  not  include  for
 *             instance EBCDIC or UTF-16LE.
 * @warning    `c` is  an int.  This  means that when  you pass a  `char` value
 *             here, it  experiences "integer promotion" as  defined in ISO/IEC
 *             9899:2018 section 6.3.1.1 paragraph 1.
 */
static inline int
rb_ispunct(int c)
{
    return !rb_isalnum(c);
}

RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Our own locale-insensitive version of `isgraph(3)`.
 *
 * @param[in]  c      Byte in question to query.
 * @retval     true   `c`  is  listed in  either  IEEE  1003.1 section  7.3.1.1
 *                    "upper", "lower", "digit", or "punct".
 * @retval     false  Anything else.
 * @note       Not only  does this function  works under the POSIX  Locale, but
 *             also assumes its  execution character set be what  ruby calls an
 *             ASCII-compatible  character  set;  which does  not  include  for
 *             instance EBCDIC or UTF-16LE.
 * @warning    `c` is  an int.  This  means that when  you pass a  `char` value
 *             here, it  experiences "integer promotion" as  defined in ISO/IEC
 *             9899:2018 section 6.3.1.1 paragraph 1.
 */
static inline int
rb_isgraph(int c)
{
    return '!' <= c && c <= '\x7e';
}

RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Our own locale-insensitive version of `tolower(3)`.
 *
 * @param[in]  c          Byte in question to convert.
 * @retval     c          The  byte is  not listed  in in  IEEE 1003.1  section
 *                        7.3.1.1 "upper".
 * @retval     otherwise  Byte converted  using the map defined  in IEEE 1003.1
 *                        section 7.3.1 "tolower".
 * @note       Not only  does this function  works under the POSIX  Locale, but
 *             also assumes its  execution character set be what  ruby calls an
 *             ASCII-compatible  character  set;  which does  not  include  for
 *             instance EBCDIC or UTF-16LE.
 * @warning    `c` is  an int.  This  means that when  you pass a  `char` value
 *             here, it  experiences "integer promotion" as  defined in ISO/IEC
 *             9899:2018 section 6.3.1.1 paragraph 1.
 */
static inline int
rb_tolower(int c)
{
    return rb_isupper(c) ? (c|0x20) : c;
}

RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Our own locale-insensitive version of `toupper(3)`.
 *
 * @param[in]  c          Byte in question to convert.
 * @retval     c          The  byte is  not listed  in in  IEEE 1003.1  section
 *                        7.3.1.1 "lower".
 * @retval     otherwise  Byte converted  using the map defined  in IEEE 1003.1
 *                        section 7.3.1 "toupper".
 * @note       Not only  does this function  works under the POSIX  Locale, but
 *             also assumes its  execution character set be what  ruby calls an
 *             ASCII-compatible  character  set;  which does  not  include  for
 *             instance EBCDIC or UTF-16LE.
 * @warning    `c` is  an int.  This  means that when  you pass a  `char` value
 *             here, it  experiences "integer promotion" as  defined in ISO/IEC
 *             9899:2018 section 6.3.1.1 paragraph 1.
 */
static inline int
rb_toupper(int c)
{
    return rb_islower(c) ? (c&0x5f) : c;
}

/** @} */
#endif /* RBIMPL_CTYPE_H */
ruby/internal/cast.h000064400000004432151732674140010461 0ustar00#ifndef RBIMPL_CAST_H                                /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_CAST_H
/**
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines RBIMPL_CAST.
 *
 * This casting macro makes sense only inside  of other macros that are part of
 * public headers.  They could be used  from C++, and C-style casts could issue
 * warnings.  Ruby internals are pure C so they should not bother.
 */
#include "ruby/internal/compiler_since.h"
#include "ruby/internal/has/warning.h"
#include "ruby/internal/warning_push.h"

#if ! defined(__cplusplus)
# define RBIMPL_CAST(expr) (expr)

#elif RBIMPL_COMPILER_SINCE(GCC, 4, 6, 0)
# /* g++ has -Wold-style-cast since 1997 or so, but its _Pragma is broken. */
# /* See https://gcc.godbolt.org/z/XWhU6J */
# define RBIMPL_CAST(expr) (expr)
# pragma GCC diagnostic ignored "-Wold-style-cast"

#elif RBIMPL_HAS_WARNING("-Wold-style-cast")
# define RBIMPL_CAST(expr)                   \
    RBIMPL_WARNING_PUSH()                    \
    RBIMPL_WARNING_IGNORED(-Wold-style-cast) \
    (expr)                                  \
    RBIMPL_WARNING_POP()

#else
# define RBIMPL_CAST(expr) (expr)
#endif

#endif /* RBIMPL_CAST_H */
ruby/internal/fl_type.h000064400000101603151732674150011170 0ustar00#ifndef RBIMPL_FL_TYPE_H                             /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_FL_TYPE_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines enum ::ruby_fl_type.
 */
#include "ruby/internal/config.h"      /* for ENUM_OVER_INT */
#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/attr/deprecated.h"
#include "ruby/internal/attr/flag_enum.h"
#include "ruby/internal/attr/forceinline.h"
#include "ruby/internal/attr/noalias.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/compiler_since.h"
#include "ruby/internal/core/rbasic.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/has/extension.h"
#include "ruby/internal/special_consts.h"
#include "ruby/internal/stdbool.h"
#include "ruby/internal/value.h"
#include "ruby/internal/value_type.h"
#include "ruby/assert.h"
#include "ruby/defines.h"

/** @cond INTERNAL_MACRO */
#if RBIMPL_HAS_EXTENSION(enumerator_attributes)
# define RBIMPL_HAVE_ENUM_ATTRIBUTE 1
#elif RBIMPL_COMPILER_SINCE(GCC, 6, 0, 0)
# define RBIMPL_HAVE_ENUM_ATTRIBUTE 1
#endif

#ifdef ENUM_OVER_INT
# define RBIMPL_WIDER_ENUM 1
#elif SIZEOF_INT * CHAR_BIT > 12+19+1
# define RBIMPL_WIDER_ENUM 1
#else
# define RBIMPL_WIDER_ENUM 0
#endif
/** @endcond */

#define FL_SINGLETON    RBIMPL_CAST((VALUE)RUBY_FL_SINGLETON)            /**< @old{RUBY_FL_SINGLETON} */
#define FL_WB_PROTECTED RBIMPL_CAST((VALUE)RUBY_FL_WB_PROTECTED)         /**< @old{RUBY_FL_WB_PROTECTED} */
#define FL_PROMOTED     RBIMPL_CAST((VALUE)RUBY_FL_PROMOTED)             /**< @old{RUBY_FL_PROMOTED} */
#define FL_FINALIZE     RBIMPL_CAST((VALUE)RUBY_FL_FINALIZE)             /**< @old{RUBY_FL_FINALIZE} */
#define FL_TAINT        RBIMPL_CAST((VALUE)RUBY_FL_TAINT)                /**< @old{RUBY_FL_TAINT} */
#define FL_SHAREABLE    RBIMPL_CAST((VALUE)RUBY_FL_SHAREABLE)            /**< @old{RUBY_FL_SHAREABLE} */
#define FL_UNTRUSTED    RBIMPL_CAST((VALUE)RUBY_FL_UNTRUSTED)            /**< @old{RUBY_FL_UNTRUSTED} */
#define FL_SEEN_OBJ_ID  RBIMPL_CAST((VALUE)RUBY_FL_SEEN_OBJ_ID)          /**< @old{RUBY_FL_SEEN_OBJ_ID} */
#define FL_EXIVAR       RBIMPL_CAST((VALUE)RUBY_FL_EXIVAR)               /**< @old{RUBY_FL_EXIVAR} */
#define FL_FREEZE       RBIMPL_CAST((VALUE)RUBY_FL_FREEZE)               /**< @old{RUBY_FL_FREEZE} */

#define FL_USHIFT       RBIMPL_CAST((VALUE)RUBY_FL_USHIFT)               /**< @old{RUBY_FL_USHIFT} */

#define FL_USER0        RBIMPL_CAST((VALUE)RUBY_FL_USER0)                /**< @old{RUBY_FL_USER0} */
#define FL_USER1        RBIMPL_CAST((VALUE)RUBY_FL_USER1)                /**< @old{RUBY_FL_USER1} */
#define FL_USER2        RBIMPL_CAST((VALUE)RUBY_FL_USER2)                /**< @old{RUBY_FL_USER2} */
#define FL_USER3        RBIMPL_CAST((VALUE)RUBY_FL_USER3)                /**< @old{RUBY_FL_USER3} */
#define FL_USER4        RBIMPL_CAST((VALUE)RUBY_FL_USER4)                /**< @old{RUBY_FL_USER4} */
#define FL_USER5        RBIMPL_CAST((VALUE)RUBY_FL_USER5)                /**< @old{RUBY_FL_USER5} */
#define FL_USER6        RBIMPL_CAST((VALUE)RUBY_FL_USER6)                /**< @old{RUBY_FL_USER6} */
#define FL_USER7        RBIMPL_CAST((VALUE)RUBY_FL_USER7)                /**< @old{RUBY_FL_USER7} */
#define FL_USER8        RBIMPL_CAST((VALUE)RUBY_FL_USER8)                /**< @old{RUBY_FL_USER8} */
#define FL_USER9        RBIMPL_CAST((VALUE)RUBY_FL_USER9)                /**< @old{RUBY_FL_USER9} */
#define FL_USER10       RBIMPL_CAST((VALUE)RUBY_FL_USER10)               /**< @old{RUBY_FL_USER10} */
#define FL_USER11       RBIMPL_CAST((VALUE)RUBY_FL_USER11)               /**< @old{RUBY_FL_USER11} */
#define FL_USER12       RBIMPL_CAST((VALUE)RUBY_FL_USER12)               /**< @old{RUBY_FL_USER12} */
#define FL_USER13       RBIMPL_CAST((VALUE)RUBY_FL_USER13)               /**< @old{RUBY_FL_USER13} */
#define FL_USER14       RBIMPL_CAST((VALUE)RUBY_FL_USER14)               /**< @old{RUBY_FL_USER14} */
#define FL_USER15       RBIMPL_CAST((VALUE)RUBY_FL_USER15)               /**< @old{RUBY_FL_USER15} */
#define FL_USER16       RBIMPL_CAST((VALUE)RUBY_FL_USER16)               /**< @old{RUBY_FL_USER16} */
#define FL_USER17       RBIMPL_CAST((VALUE)RUBY_FL_USER17)               /**< @old{RUBY_FL_USER17} */
#define FL_USER18       RBIMPL_CAST((VALUE)RUBY_FL_USER18)               /**< @old{RUBY_FL_USER18} */
#define FL_USER19       RBIMPL_CAST((VALUE)(unsigned int)RUBY_FL_USER19) /**< @old{RUBY_FL_USER19} */

#define ELTS_SHARED          RUBY_ELTS_SHARED     /**< @old{RUBY_ELTS_SHARED} */
#define RB_OBJ_FREEZE        rb_obj_freeze_inline /**< @alias{rb_obj_freeze_inline} */

/** @cond INTERNAL_MACRO */
#define RUBY_ELTS_SHARED     RUBY_ELTS_SHARED
#define RB_FL_ABLE           RB_FL_ABLE
#define RB_FL_ALL            RB_FL_ALL
#define RB_FL_ALL_RAW        RB_FL_ALL_RAW
#define RB_FL_ANY            RB_FL_ANY
#define RB_FL_ANY_RAW        RB_FL_ANY_RAW
#define RB_FL_REVERSE        RB_FL_REVERSE
#define RB_FL_REVERSE_RAW    RB_FL_REVERSE_RAW
#define RB_FL_SET            RB_FL_SET
#define RB_FL_SET_RAW        RB_FL_SET_RAW
#define RB_FL_TEST           RB_FL_TEST
#define RB_FL_TEST_RAW       RB_FL_TEST_RAW
#define RB_FL_UNSET          RB_FL_UNSET
#define RB_FL_UNSET_RAW      RB_FL_UNSET_RAW
#define RB_OBJ_FREEZE_RAW    RB_OBJ_FREEZE_RAW
#define RB_OBJ_FROZEN        RB_OBJ_FROZEN
#define RB_OBJ_FROZEN_RAW    RB_OBJ_FROZEN_RAW
#define RB_OBJ_UNTRUST       RB_OBJ_TAINT
#define RB_OBJ_UNTRUSTED     RB_OBJ_TAINTED
/** @endcond */

/**
 * @defgroup deprecated_macros Deprecated macro APIs
 * @{
 * These macros are deprecated.  Prefer their `RB_`-prefixed versions.
 */
#define FL_ABLE         RB_FL_ABLE         /**< @old{RB_FL_ABLE} */
#define FL_ALL          RB_FL_ALL          /**< @old{RB_FL_ALL} */
#define FL_ALL_RAW      RB_FL_ALL_RAW      /**< @old{RB_FL_ALL_RAW} */
#define FL_ANY          RB_FL_ANY          /**< @old{RB_FL_ANY} */
#define FL_ANY_RAW      RB_FL_ANY_RAW      /**< @old{RB_FL_ANY_RAW} */
#define FL_REVERSE      RB_FL_REVERSE      /**< @old{RB_FL_REVERSE} */
#define FL_REVERSE_RAW  RB_FL_REVERSE_RAW  /**< @old{RB_FL_REVERSE_RAW} */
#define FL_SET          RB_FL_SET          /**< @old{RB_FL_SET} */
#define FL_SET_RAW      RB_FL_SET_RAW      /**< @old{RB_FL_SET_RAW} */
#define FL_TEST         RB_FL_TEST         /**< @old{RB_FL_TEST} */
#define FL_TEST_RAW     RB_FL_TEST_RAW     /**< @old{RB_FL_TEST_RAW} */
#define FL_UNSET        RB_FL_UNSET        /**< @old{RB_FL_UNSET} */
#define FL_UNSET_RAW    RB_FL_UNSET_RAW    /**< @old{RB_FL_UNSET_RAW} */
#define OBJ_FREEZE      RB_OBJ_FREEZE      /**< @old{RB_OBJ_FREEZE} */
#define OBJ_FREEZE_RAW  RB_OBJ_FREEZE_RAW  /**< @old{RB_OBJ_FREEZE_RAW} */
#define OBJ_FROZEN      RB_OBJ_FROZEN      /**< @old{RB_OBJ_FROZEN} */
#define OBJ_FROZEN_RAW  RB_OBJ_FROZEN_RAW  /**< @old{RB_OBJ_FROZEN_RAW} */
#define OBJ_INFECT      RB_OBJ_INFECT      /**< @old{RB_OBJ_INFECT} */
#define OBJ_INFECT_RAW  RB_OBJ_INFECT_RAW  /**< @old{RB_OBJ_INFECT_RAW} */
#define OBJ_TAINT       RB_OBJ_TAINT       /**< @old{RB_OBJ_TAINT} */
#define OBJ_TAINTABLE   RB_OBJ_TAINTABLE   /**< @old{RB_OBJ_TAINT_RAW} */
#define OBJ_TAINTED     RB_OBJ_TAINTED     /**< @old{RB_OBJ_TAINTED} */
#define OBJ_TAINTED_RAW RB_OBJ_TAINTED_RAW /**< @old{RB_OBJ_TAINTED_RAW} */
#define OBJ_TAINT_RAW   RB_OBJ_TAINT_RAW   /**< @old{RB_OBJ_TAINT_RAW} */
#define OBJ_UNTRUST     RB_OBJ_UNTRUST     /**< @old{RB_OBJ_TAINT} */
#define OBJ_UNTRUSTED   RB_OBJ_UNTRUSTED   /**< @old{RB_OBJ_TAINTED} */
/** @} */

/**
 * This is an enum because GDB wants it (rather than a macro).  People need not
 * bother.
 */
enum ruby_fl_ushift {
    /**
     * Number of bits in ::ruby_fl_type that  are _not_ open to users.  This is
     * an implementation detail.  Please ignore.
     */
    RUBY_FL_USHIFT = 12
};

/* > The expression that defines the value  of an enumeration constant shall be
 * > an integer constant expression that has a value representable as an `int`.
 *
 * -- ISO/IEC 9899:2018 section 6.7.2.2
 *
 * So ENUM_OVER_INT  situation is an  extension to the standard.   Note however
 * that we do not support 16 bit `int` environment. */
RB_GNUC_EXTENSION
/**
 * The  flags.  Each  ruby objects  have their  own characteristics  apart from
 * their  classes.  For  instance whether  an object  is frozen  or not  is not
 * controlled by its class.  This is the type that represents such properties.
 *
 * @note  About the `FL_USER` terminology: the "user" here does not necessarily
 *        mean only  you.  For  instance struct  ::RString instances  use these
 *        bits to cache their encodings  etc.  Devs discussed about this topic,
 *        reached their  consensus that  ::RUBY_T_DATA is  the only  valid data
 *        structure that  can use these  bits; other data  structures including
 *        ::RUBY_T_OBJECT  use these  bits  for their  own  purpose.  See  also
 *        https://bugs.ruby-lang.org/issues/18059
 */
enum
RBIMPL_ATTR_FLAG_ENUM()
ruby_fl_type {

    /**
     * @deprecated  This flag once was a thing  back in the old days, but makes
     *              no  sense  any longer  today.   Exists  here for  backwards
     *              compatibility only.  You can safely forget about it.
     *
     * @internal
     *
     * The reality is our GC no  longer remembers write barriers inside of each
     * objects, to use  dedicated bitmap instead.  But this flag  is still used
     * internally.   The  current  usages  of this  flag  should  be  something
     * different, which is unclear to @shyouhei.
     */
    RUBY_FL_WB_PROTECTED = (1<<5),

    /**
     * Ruby objects are "generational".  There are young objects & old objects.
     * Young objects are prone to die & monitored relatively extensively by the
     * garbage collector.  Old objects tend to live longer & are monitored less
     * frequently.  When an object survives a GC, its age is incremented.  When
     * age is equal to RVALUE_OLD_AGE, the object becomes Old. This flag is set
     * when an object becomes old, and is used by the write barrier to check if
     * an old object should be considered for marking more frequently  - as old
     * objects that have references added between major GCs need to be remarked
     * to prevent the referred object being mistakenly swept.
     *
     * @internal
     *
     * But honestly, @shyouhei  doesn't think this flag should  be visible from
     * 3rd parties.  It must be an implementation detail that they should never
     * know.  Might better be hidden.
     */
    RUBY_FL_PROMOTED    = (1<<5),

    /**
     * This flag is no longer in use
     *
     * @internal
     */
    RUBY_FL_UNUSED6    = (1<<6),

    /**
     * This flag has  something to do with finalisers.  A  ruby object can have
     * its finaliser,  which is another  object that evaluates when  the target
     * object is about  to die.  This flag  is used to denote that  there is an
     * attached finaliser.
     *
     * @internal
     *
     * But honestly, @shyouhei  doesn't think this flag should  be visible from
     * 3rd parties.  It must be an implementation detail that they should never
     * know.  Might better be hidden.
     */
    RUBY_FL_FINALIZE     = (1<<7),

    /**
     * @deprecated  This flag once was a thing  back in the old days, but makes
     *              no  sense  any longer  today.   Exists  here for  backwards
     *              compatibility only.  You can safely forget about it.
     */
    RUBY_FL_TAINT

#if defined(RBIMPL_HAVE_ENUM_ATTRIBUTE)
    RBIMPL_ATTR_DEPRECATED(("taintedness turned out to be a wrong idea."))
#elif defined(_MSC_VER)
# pragma deprecated(RUBY_FL_TAINT)
#endif

                         = 0,

    /**
     * This flag has something to do with Ractor.  Multiple Ractors run without
     * protecting each  other.  Sharing an  object among Ractors  are basically
     * dangerous,  disabled by  default.   This  flag is  used  to bypass  that
     * restriction.  Of  course, you have  to manually prevent  race conditions
     * then.
     *
     * This flag  needs deep  understanding of multithreaded  programming.  You
     * would better not use it.
     */
    RUBY_FL_SHAREABLE    = (1<<8),

    /**
     * @deprecated  This flag once was a thing  back in the old days, but makes
     *              no  sense  any longer  today.   Exists  here for  backwards
     *              compatibility only.  You can safely forget about it.
     */
    RUBY_FL_UNTRUSTED

#if defined(RBIMPL_HAVE_ENUM_ATTRIBUTE)
    RBIMPL_ATTR_DEPRECATED(("trustedness turned out to be a wrong idea."))
#elif defined(_MSC_VER)
# pragma deprecated(RUBY_FL_UNTRUSTED)
#endif

                         = 0,

    /**
     * This flag has something to do with  object IDs.  Unlike in the old days,
     * an object's object  ID (that a user can  query using `Object#object_id`)
     * is no longer its physical address represented using Ruby level integers.
     * It is  now a  monotonic-increasing integer  unrelated to  the underlying
     * memory arrangement.  Object IDs are assigned when necessary; objects are
     * born without one,  and will eventually have such  property when queried.
     * The interpreter has to manage which one is which.  This is the flag that
     * helps the  management.  Objects  with this  flag set  are the  ones with
     * object IDs assigned.
     *
     * @internal
     *
     * But honestly, @shyouhei  doesn't think this flag should  be visible from
     * 3rd parties.  It must be an implementation detail that they should never
     * know.  Might better be hidden.
     */
    RUBY_FL_SEEN_OBJ_ID  = (1<<9),

    /**
     * This flag has something to do with instance variables.  3rd parties need
     * not  know, but  there are  several ways  to store  an object's  instance
     * variables.   Objects  with this  flag  use  so-called "generic"  backend
     * storage.  This  distinction is purely an  implementation detail.  People
     * need not be aware of this working behind-the-scene.
     *
     * @internal
     *
     * As of writing everything except ::RObject and RModule use this scheme.
     */
    RUBY_FL_EXIVAR       = (1<<10),

    /**
     * This flag has something to do with data immutability.  When this flag is
     * set an object  is considered "frozen".  No modification  are expected to
     * happen beyond  that point  for the  particular object.   Immutability is
     * basically considered to be a  good property these days.  Library authors
     * are expected to obey.  Test this bit before you touch a data structure.
     *
     * @see rb_check_frozen()
     */
    RUBY_FL_FREEZE       = (1<<11),

/** (@shyouhei doesn't know how to excude this macro from doxygen). */
#define RBIMPL_FL_USER_N(n) RUBY_FL_USER##n = (1<<(RUBY_FL_USHIFT+n))
    RBIMPL_FL_USER_N(0),  /**< User-defined flag. */
    RBIMPL_FL_USER_N(1),  /**< User-defined flag. */
    RBIMPL_FL_USER_N(2),  /**< User-defined flag. */
    RBIMPL_FL_USER_N(3),  /**< User-defined flag. */
    RBIMPL_FL_USER_N(4),  /**< User-defined flag. */
    RBIMPL_FL_USER_N(5),  /**< User-defined flag. */
    RBIMPL_FL_USER_N(6),  /**< User-defined flag. */
    RBIMPL_FL_USER_N(7),  /**< User-defined flag. */
    RBIMPL_FL_USER_N(8),  /**< User-defined flag. */
    RBIMPL_FL_USER_N(9),  /**< User-defined flag. */
    RBIMPL_FL_USER_N(10), /**< User-defined flag. */
    RBIMPL_FL_USER_N(11), /**< User-defined flag. */
    RBIMPL_FL_USER_N(12), /**< User-defined flag. */
    RBIMPL_FL_USER_N(13), /**< User-defined flag. */
    RBIMPL_FL_USER_N(14), /**< User-defined flag. */
    RBIMPL_FL_USER_N(15), /**< User-defined flag. */
    RBIMPL_FL_USER_N(16), /**< User-defined flag. */
    RBIMPL_FL_USER_N(17), /**< User-defined flag. */
    RBIMPL_FL_USER_N(18), /**< User-defined flag. */
#ifdef ENUM_OVER_INT
    RBIMPL_FL_USER_N(19), /**< User-defined flag. */
#else
# define RUBY_FL_USER19 (RBIMPL_VALUE_ONE<<(RUBY_FL_USHIFT+19))
#endif
#undef RBIMPL_FL_USER_N
#undef RBIMPL_WIDER_ENUM

    /**
     * This flag  has something to  do with  data structures.  Over  time, ruby
     * evolved to reduce  memory footprints.  One of such  attempt is so-called
     * copy-on-write, which  delays duplication  of resources  until ultimately
     * necessary.   Some  data  structures  share  this  scheme.   For  example
     * multiple  instances  of struct  ::RArray  could  point identical  memory
     * region  in common,  as  long as  they don't  differ.   As people  favour
     * immutable style  of programming than  before, this situation  is getting
     * more and more common.  Because such "shared" memory regions have nuanced
     * ownership by nature,  each structures need special care  for them.  This
     * flag is used to distinguish such shared constructs.
     *
     * @internal
     *
     * But honestly, @shyouhei  doesn't think this flag should  be visible from
     * 3rd parties.  It must be an implementation detail that they should never
     * know.  Might better be hidden.
     */
    RUBY_ELTS_SHARED  = RUBY_FL_USER0,

    /**
     * This flag has something to do with an object's class.  There are kind of
     * classes  called  "singleton  class",  each of  which  have  exactly  one
     * instance.  What is interesting about  singleton classes is that they are
     * created _after_ their instance were instantiated, like this:
     *
     * ```ruby
     * foo = Object.new          # foo is an instance of Object...
     * bar = foo.singleton_class # foo is now an instance of bar.
     * ```
     *
     * Here as you see  `bar` is a singleton class of  `foo`, which is injected
     * into  `foo`'s inheritance  tree in  a different  statement (==  distinct
     * sequence point).   In order to  achieve this property  singleton classes
     * are  special-cased in  the  interpreter.   There is  one  bit flag  that
     * distinguishes if a class is a singleton class or not, and this is it.
     *
     * @internal
     *
     * But honestly, @shyouhei  doesn't think this flag should  be visible from
     * 3rd parties.  It must be an implementation detail that they should never
     * know.  Might better be hidden.
     */
    RUBY_FL_SINGLETON = RUBY_FL_USER1,
};

enum {
    /**
     * @deprecated  This flag once was a thing  back in the old days, but makes
     *              no  sense  any longer  today.   Exists  here for  backwards
     *              compatibility only.  You can safely forget about it.
     */
    RUBY_FL_DUPPED

#if defined(RBIMPL_HAVE_ENUM_ATTRIBUTE)
    RBIMPL_ATTR_DEPRECATED(("It seems there is no actual usage of this enum."))
#elif defined(_MSC_VER)
# pragma deprecated(RUBY_FL_DUPPED)
#endif

    = (int)RUBY_T_MASK | (int)RUBY_FL_EXIVAR
};

#undef RBIMPL_HAVE_ENUM_ATTRIBUTE

RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
 * This is an  implementation detail of #RB_OBJ_FREEZE().  People  don't use it
 * directly.
 *
 * @param[out]  klass  A singleton class.
 * @post        `klass` gets frozen.
 */
void rb_freeze_singleton_class(VALUE klass);
RBIMPL_SYMBOL_EXPORT_END()

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_FORCEINLINE()
/**
 * Checks  if the  object is  flaggable.  There  are some  special cases  (most
 * notably ::RUBY_Qfalse) where appending a flag  to an object is not possible.
 * This function can detect that.
 *
 * @param[in]  obj    Object in question
 * @retval     true   It is flaggable.
 * @retval     false  No it isn't.
 */
static bool
RB_FL_ABLE(VALUE obj)
{
    if (RB_SPECIAL_CONST_P(obj)) {
        return false;
    }
    else if (RB_TYPE_P(obj, RUBY_T_NODE)) {
        return false;
    }
    else {
        return true;
    }
}

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
 * This is an implementation detail of  RB_FL_TEST().  3rd parties need not use
 * this.  Just always use RB_FL_TEST().
 *
 * @param[in]  obj    Object in question.
 * @param[in]  flags  A set of enum ::ruby_fl_type.
 * @pre        The object must not be an enum ::ruby_special_consts.
 * @return     `obj`'s flags, masked by `flags`.
 */
static inline VALUE
RB_FL_TEST_RAW(VALUE obj, VALUE flags)
{
    RBIMPL_ASSERT_OR_ASSUME(RB_FL_ABLE(obj));
    return RBASIC(obj)->flags & flags;
}

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Tests if the given  flag(s) are set or not.  You can  pass multiple flags at
 * once:
 *
 * ```CXX
 * auto obj = rb_eval_string("...");
 * if (RB_FL_TEST(obj, RUBY_FL_FREEZE | RUBY_FL_SHAREABLE)) {
 *     printf("Ractor ready!\n");
 * }
 * ```
 *
 * @param[in]  obj    Object in question.
 * @param[in]  flags  A set of enum ::ruby_fl_type.
 * @return     `obj`'s flags, masked by `flags`.
 * @note       It  is intentional  for this  function to  return ::VALUE.   The
 *             return value could be passed to RB_FL_STE() etc.
 */
static inline VALUE
RB_FL_TEST(VALUE obj, VALUE flags)
{
    if (RB_FL_ABLE(obj)) {
        return RB_FL_TEST_RAW(obj, flags);
    }
    else {
        return RBIMPL_VALUE_NULL;
    }
}

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
 * This is an  implementation detail of RB_FL_ANY().  3rd parties  need not use
 * this.  Just always use RB_FL_ANY().
 *
 * @param[in]  obj    Object in question.
 * @param[in]  flags  A set of enum ::ruby_fl_type.
 * @retval     true   The object has any of the flags set.
 * @retval     false  No it doesn't at all.
 * @pre        The object must not be an enum ::ruby_special_consts.
 */
static inline bool
RB_FL_ANY_RAW(VALUE obj, VALUE flags)
{
    return RB_FL_TEST_RAW(obj, flags);
}

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Identical to RB_FL_TEST(), except it returns bool.
 *
 * @param[in]  obj    Object in question.
 * @param[in]  flags  A set of enum ::ruby_fl_type.
 * @retval     true   The object has any of the flags set.
 * @retval     false  No it doesn't at all.
 */
static inline bool
RB_FL_ANY(VALUE obj, VALUE flags)
{
    return RB_FL_TEST(obj, flags);
}

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
 * This is an  implementation detail of RB_FL_ALL().  3rd parties  need not use
 * this.  Just always use RB_FL_ALL().
 *
 * @param[in]  obj    Object in question.
 * @param[in]  flags  A set of enum ::ruby_fl_type.
 * @retval     true   The object has all of the flags set.
 * @retval     false  The object lacks any of the flags.
 * @pre        The object must not be an enum ::ruby_special_consts.
 */
static inline bool
RB_FL_ALL_RAW(VALUE obj, VALUE flags)
{
    return RB_FL_TEST_RAW(obj, flags) == flags;
}

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Identical to RB_FL_ANY(), except it mandates all passed flags be set.
 *
 * @param[in]  obj    Object in question.
 * @param[in]  flags  A set of enum ::ruby_fl_type.
 * @retval     true   The object has all of the flags set.
 * @retval     false  The object lacks any of the flags.
 */
static inline bool
RB_FL_ALL(VALUE obj, VALUE flags)
{
    return RB_FL_TEST(obj, flags) == flags;
}

RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_ARTIFICIAL()
/**
 * @private
 *
 * This is an  implementation detail of RB_FL_SET().  3rd parties  need not use
 * this.  Just always use RB_FL_SET().
 *
 * @param[out]  obj    Object in question.
 * @param[in]   flags  A set of enum ::ruby_fl_type.
 * @post        `obj` has `flags` set.
 *
 * @internal
 *
 * This  is  function  is  here  to  annotate  a  part  of  RB_FL_SET_RAW()  as
 * `__declspec(noalias)`.
 */
static inline void
rbimpl_fl_set_raw_raw(struct RBasic *obj, VALUE flags)
{
    obj->flags |= flags;
}

RBIMPL_ATTR_ARTIFICIAL()
/**
 * This is an  implementation detail of RB_FL_SET().  3rd parties  need not use
 * this.  Just always use RB_FL_SET().
 *
 * @param[out]  obj    Object in question.
 * @param[in]   flags  A set of enum ::ruby_fl_type.
 * @post        `obj` has `flags` set.
 */
static inline void
RB_FL_SET_RAW(VALUE obj, VALUE flags)
{
    RBIMPL_ASSERT_OR_ASSUME(RB_FL_ABLE(obj));
    rbimpl_fl_set_raw_raw(RBASIC(obj), flags);
}

RBIMPL_ATTR_ARTIFICIAL()
/**
 * Sets the given flag(s).
 *
 * ```CXX
 * auto v = rb_eval_string("...");
 * RB_FL_SET(v, RUBY_FL_FREEZE);
 * ```
 *
 * @param[out]  obj    Object in question.
 * @param[in]   flags  A set of enum ::ruby_fl_type.
 * @post        `obj` has `flags` set.
 */
static inline void
RB_FL_SET(VALUE obj, VALUE flags)
{
    if (RB_FL_ABLE(obj)) {
        RB_FL_SET_RAW(obj, flags);
    }
}

RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_ARTIFICIAL()
/**
 * @private
 *
 * This is an implementation detail of RB_FL_UNSET().  3rd parties need not use
 * this.  Just always use RB_FL_UNSET().
 *
 * @param[out]  obj    Object in question.
 * @param[in]   flags  A set of enum ::ruby_fl_type.
 * @post        `obj` has `flags` cleared.
 *
 * @internal
 *
 * This  is  function is  here  to  annotate  a  part of  RB_FL_UNSET_RAW()  as
 * `__declspec(noalias)`.
 */
static inline void
rbimpl_fl_unset_raw_raw(struct RBasic *obj, VALUE flags)
{
    obj->flags &= ~flags;
}

RBIMPL_ATTR_ARTIFICIAL()
/**
 * This is an implementation detail of RB_FL_UNSET().  3rd parties need not use
 * this.  Just always use RB_FL_UNSET().
 *
 * @param[out]  obj    Object in question.
 * @param[in]   flags  A set of enum ::ruby_fl_type.
 * @post        `obj` has `flags` cleared.
 */
static inline void
RB_FL_UNSET_RAW(VALUE obj, VALUE flags)
{
    RBIMPL_ASSERT_OR_ASSUME(RB_FL_ABLE(obj));
    rbimpl_fl_unset_raw_raw(RBASIC(obj), flags);
}

RBIMPL_ATTR_ARTIFICIAL()
/**
 * Clears the given flag(s).
 *
 * @param[out]  obj    Object in question.
 * @param[in]   flags  A set of enum ::ruby_fl_type.
 * @post        `obj` has `flags` cleard.
 */
static inline void
RB_FL_UNSET(VALUE obj, VALUE flags)
{
    if (RB_FL_ABLE(obj)) {
        RB_FL_UNSET_RAW(obj, flags);
    }
}

RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_ARTIFICIAL()
/**
 * @private
 *
 * This is an  implementation detail of RB_FL_REVERSE().  3rd  parties need not
 * use this.  Just always use RB_FL_REVERSE().
 *
 * @param[out]  obj    Object in question.
 * @param[in]   flags  A set of enum ::ruby_fl_type.
 * @post        `obj` has `flags` reversed.
 *
 * @internal
 *
 * This  is function  is  here to  annotate a  part  of RB_FL_REVERSE_RAW()  as
 * `__declspec(noalias)`.
 */
static inline void
rbimpl_fl_reverse_raw_raw(struct RBasic *obj, VALUE flags)
{
    obj->flags ^= flags;
}

RBIMPL_ATTR_ARTIFICIAL()
/**
 * This is an  implementation detail of RB_FL_REVERSE().  3rd  parties need not
 * use this.  Just always use RB_FL_REVERSE().
 *
 * @param[out]  obj    Object in question.
 * @param[in]   flags  A set of enum ::ruby_fl_type.
 * @post        `obj` has `flags` cleared.
 */
static inline void
RB_FL_REVERSE_RAW(VALUE obj, VALUE flags)
{
    RBIMPL_ASSERT_OR_ASSUME(RB_FL_ABLE(obj));
    rbimpl_fl_reverse_raw_raw(RBASIC(obj), flags);
}

RBIMPL_ATTR_ARTIFICIAL()
/**
 * Reverses the flags.  This function is here mainly for symmetry on set/unset.
 * Rarely used in practice.
 *
 * @param[out]  obj    Object in question.
 * @param[in]   flags  A set of enum ::ruby_fl_type.
 * @post        `obj` has `flags` reversed.
 */
static inline void
RB_FL_REVERSE(VALUE obj, VALUE flags)
{
    if (RB_FL_ABLE(obj)) {
        RB_FL_REVERSE_RAW(obj, flags);
    }
}

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_DEPRECATED(("taintedness turned out to be a wrong idea."))
/**
 * @deprecated  This function  once was a thing  in the old days,  but makes no
 *              sense   any   longer   today.   Exists   here   for   backwards
 *              compatibility only.  You can safely forget about it.
 *
 * @param[in]   obj  Object in question.
 * @return      false always.
 */
static inline bool
RB_OBJ_TAINTABLE(VALUE obj)
{
    (void)obj;
    return false;
}

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_DEPRECATED(("taintedness turned out to be a wrong idea."))
/**
 * @deprecated  This function  once was a thing  in the old days,  but makes no
 *              sense   any   longer   today.   Exists   here   for   backwards
 *              compatibility only.  You can safely forget about it.
 *
 * @param[in]   obj  Object in question.
 * @return      false always.
 */
static inline VALUE
RB_OBJ_TAINTED_RAW(VALUE obj)
{
    (void)obj;
    return false;
}

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_DEPRECATED(("taintedness turned out to be a wrong idea."))
/**
 * @deprecated  This function  once was a thing  in the old days,  but makes no
 *              sense   any   longer   today.   Exists   here   for   backwards
 *              compatibility only.  You can safely forget about it.
 *
 * @param[in]   obj  Object in question.
 * @return      false always.
 */
static inline bool
RB_OBJ_TAINTED(VALUE obj)
{
    (void)obj;
    return false;
}

RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_DEPRECATED(("taintedness turned out to be a wrong idea."))
/**
 * @deprecated  This function  once was a thing  in the old days,  but makes no
 *              sense   any   longer   today.   Exists   here   for   backwards
 *              compatibility only.  You can safely forget about it.
 *
 * @param[in]   obj  Object in question.
 */
static inline void
RB_OBJ_TAINT_RAW(VALUE obj)
{
    (void)obj;
    return;
}

RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_DEPRECATED(("taintedness turned out to be a wrong idea."))
/**
 * @deprecated  This function  once was a thing  in the old days,  but makes no
 *              sense   any   longer   today.   Exists   here   for   backwards
 *              compatibility only.  You can safely forget about it.
 *
 * @param[in]   obj  Object in question.
 */
static inline void
RB_OBJ_TAINT(VALUE obj)
{
    (void)obj;
    return;
}

RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_DEPRECATED(("taintedness turned out to be a wrong idea."))
/**
 * @deprecated  This function  once was a thing  in the old days,  but makes no
 *              sense   any   longer   today.   Exists   here   for   backwards
 *              compatibility only.  You can safely forget about it.
 *
 * @param[in]   dst  Victim object.
 * @param[in]   src  Infectant object.
 */
static inline void
RB_OBJ_INFECT_RAW(VALUE dst, VALUE src)
{
    (void)dst;
    (void)src;
    return;
}

RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_DEPRECATED(("taintedness turned out to be a wrong idea."))
/**
 * @deprecated  This function  once was a thing  in the old days,  but makes no
 *              sense   any   longer   today.   Exists   here   for   backwards
 *              compatibility only.  You can safely forget about it.
 *
 * @param[in]   dst  Victim object.
 * @param[in]   src  Infectant object.
 */
static inline void
RB_OBJ_INFECT(VALUE dst, VALUE src)
{
    (void)dst;
    (void)src;
    return;
}

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
 * This is an  implementation detail of RB_OBJ_FROZEN().  3rd  parties need not
 * use this.  Just always use RB_OBJ_FROZEN().
 *
 * @param[in]  obj             Object in question.
 * @retval     RUBY_FL_FREEZE  Yes it is.
 * @retval     0               No it isn't.
 *
 * @internal
 *
 * It is intentional  not to return bool  here.  There is a place  in ruby core
 * (namely `class.c:singleton_class_of()`) where return  value of this function
 * is passed to RB_FL_SET_RAW().
 */
static inline VALUE
RB_OBJ_FROZEN_RAW(VALUE obj)
{
    return RB_FL_TEST_RAW(obj, RUBY_FL_FREEZE);
}

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Checks if an object is frozen.
 *
 * @param[in]  obj    Object in question.
 * @retval     true   Yes it is.
 * @retval     false  No it isn't.
 */
static inline bool
RB_OBJ_FROZEN(VALUE obj)
{
    if (! RB_FL_ABLE(obj)) {
        return true;
    }
    else {
        return RB_OBJ_FROZEN_RAW(obj);
    }
}

RUBY_SYMBOL_EXPORT_BEGIN
/**
 * Prevents further modifications to the given object.  ::rb_eFrozenError shall
 * be raised if modification is attempted.
 *
 * @param[out]  x               Object in question.
 * @exception   rb_eNoMemError  Failed   to   allocate memory  for  the  frozen
 *                              representation of the object.
 */
void rb_obj_freeze_inline(VALUE obj);
RUBY_SYMBOL_EXPORT_END

RBIMPL_ATTR_ARTIFICIAL()
/**
 * This is an  implementation detail of RB_OBJ_FREEZE().  3rd  parties need not
 * use this.  Just always use RB_OBJ_FREEZE().
 *
 * @param[out]  obj  Object in question.
 */
static inline void
RB_OBJ_FREEZE_RAW(VALUE obj)
{
    rb_obj_freeze_inline(obj);
}

#endif /* RBIMPL_FL_TYPE_H */
ruby/internal/core.h000064400000003522151732674150010457 0ustar00#ifndef RBIMPL_CORE_H                                /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_CORE_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Core data structures, definitions and manipulations.
 */
#include "ruby/internal/core/rarray.h"
#include "ruby/internal/core/rbasic.h"
#include "ruby/internal/core/rbignum.h"
#include "ruby/internal/core/rclass.h"
#include "ruby/internal/core/rdata.h"
#include "ruby/internal/core/rfile.h"
#include "ruby/internal/core/rhash.h"
#include "ruby/internal/core/robject.h"
#include "ruby/internal/core/rregexp.h"
#include "ruby/internal/core/rstring.h"
#include "ruby/internal/core/rstruct.h"
#include "ruby/internal/core/rtypeddata.h"
#endif /* RBIMPL_CORE_H */
ruby/internal/compiler_since.h000064400000005337151732674150012530 0ustar00#ifndef RBIMPL_COMPILER_SINCE_H                      /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_COMPILER_SINCE_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_COMPILER_SINCE.
 */
#include "ruby/internal/compiler_is.h"

/**
 * @brief   Checks if the compiler is of given brand and is newer than or equal
 *          to the passed version.
 * @param   cc     Compiler brand, like `MSVC`.
 * @param   x      Major version.
 * @param   y      Minor version.
 * @param   z      Patchlevel.
 * @retval  true   cc >= x.y.z.
 * @retval  false  otherwise.
 */
#define RBIMPL_COMPILER_SINCE(cc, x, y, z)     \
     (RBIMPL_COMPILER_IS(cc)                && \
    ((RBIMPL_COMPILER_VERSION_MAJOR >  (x)) || \
    ((RBIMPL_COMPILER_VERSION_MAJOR == (x)) && \
    ((RBIMPL_COMPILER_VERSION_MINOR >  (y)) || \
    ((RBIMPL_COMPILER_VERSION_MINOR == (y)) && \
     (RBIMPL_COMPILER_VERSION_PATCH >= (z)))))))

/**
 * @brief   Checks if  the compiler  is of  given brand and  is older  than the
 *          passed version.
 * @param   cc     Compiler brand, like `MSVC`.
 * @param   x      Major version.
 * @param   y      Minor version.
 * @param   z      Patchlevel.
 * @retval  true   cc < x.y.z.
 * @retval  false  otherwise.
 */
#define RBIMPL_COMPILER_BEFORE(cc, x, y, z)    \
     (RBIMPL_COMPILER_IS(cc)                && \
    ((RBIMPL_COMPILER_VERSION_MAJOR <  (x)) || \
    ((RBIMPL_COMPILER_VERSION_MAJOR == (x)) && \
    ((RBIMPL_COMPILER_VERSION_MINOR <  (y)) || \
    ((RBIMPL_COMPILER_VERSION_MINOR == (y)) && \
     (RBIMPL_COMPILER_VERSION_PATCH <  (z)))))))

#endif /* RBIMPL_COMPILER_SINCE_H */
ruby/internal/event.h000064400000014326151732674150010654 0ustar00#ifndef RBIMPL_EVENT_H                               /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_EVENT_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Debugging and tracing APIs.
 */
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"

#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif

/* These macros are not enums because they are wider than int.*/

/**
 * @name Traditional set_trace_func events
 *
 * @{
 */
#define RUBY_EVENT_NONE      0x0000 /**< No events. */
#define RUBY_EVENT_LINE      0x0001 /**< Encountered a new line. */
#define RUBY_EVENT_CLASS     0x0002 /**< Encountered a new class. */
#define RUBY_EVENT_END       0x0004 /**< Encountered an end of a class clause. */
#define RUBY_EVENT_CALL      0x0008 /**< A method, written in Ruby, is called. */
#define RUBY_EVENT_RETURN    0x0010 /**< Encountered a `return` statement. */
#define RUBY_EVENT_C_CALL    0x0020 /**< A method, written in C, is called. */
#define RUBY_EVENT_C_RETURN  0x0040 /**< Return from a method, written in C. */
#define RUBY_EVENT_RAISE     0x0080 /**< Encountered a `raise` statement. */
#define RUBY_EVENT_ALL       0x00ff /**< Bitmask of traditional events. */

/** @} */

/**
 * @name TracePoint extended events
 *
 * @{
 */
#define RUBY_EVENT_B_CALL            0x0100 /**< Encountered an `yield` statement. */
#define RUBY_EVENT_B_RETURN          0x0200 /**< Encountered a `next` statement. */
#define RUBY_EVENT_THREAD_BEGIN      0x0400 /**< Encountered a new thread. */
#define RUBY_EVENT_THREAD_END        0x0800 /**< Encountered an end of a thread. */
#define RUBY_EVENT_FIBER_SWITCH      0x1000 /**< Encountered a `Fiber#yield`. */
#define RUBY_EVENT_SCRIPT_COMPILED   0x2000 /**< Encountered an `eval`. */
#define RUBY_EVENT_RESCUE            0x4000 /**< Encountered a `rescue` statement. */
#define RUBY_EVENT_TRACEPOINT_ALL    0xffff /**< Bitmask of extended events. */

/** @} */

/**
 * @name Special events
 *
 * @internal
 *
 * These bits are actually used internally.  See vm_core.h if you are curious.
 *
 * @endinternal
 *
 * @{
 */
#define RUBY_EVENT_RESERVED_FOR_INTERNAL_USE 0x030000 /**< Opaque bits. */

/** @} */

/**
 * @name Internal events
 *
 * @shyouhei's understanding  is that some  of them are visible  from extension
 * libraries because  of `ext/objspace`.   But it  seems that  doesn't describe
 * everything?  The ultimate reason why they are here remains unclear.
 *
 * @{
 */
#define RUBY_INTERNAL_EVENT_SWITCH          0x040000 /**< Thread switched. */
#define RUBY_EVENT_SWITCH                   0x040000 /**< @old{RUBY_INTERNAL_EVENT_SWITCH} */
                                         /* 0x080000 */
#define RUBY_INTERNAL_EVENT_NEWOBJ          0x100000 /**< Object allocated. */
#define RUBY_INTERNAL_EVENT_FREEOBJ         0x200000 /**< Object swept. */
#define RUBY_INTERNAL_EVENT_GC_START        0x400000 /**< GC started. */
#define RUBY_INTERNAL_EVENT_GC_END_MARK     0x800000 /**< GC ended mark phase. */
#define RUBY_INTERNAL_EVENT_GC_END_SWEEP   0x1000000 /**< GC ended sweep phase. */
#define RUBY_INTERNAL_EVENT_GC_ENTER       0x2000000 /**< `gc_enter()` is called. */
#define RUBY_INTERNAL_EVENT_GC_EXIT        0x4000000 /**< `gc_exit()` is called. */
#define RUBY_INTERNAL_EVENT_OBJSPACE_MASK  0x7f00000 /**< Bitmask of GC events. */
#define RUBY_INTERNAL_EVENT_MASK          0xffff0000 /**< Bitmask of internal events. */

/** @} */

/**
 * Represents event(s).  As the name implies events are bit flags.
 */
typedef uint32_t rb_event_flag_t;

/**
 * Type of event hooks.  When an  event happens registered functions are kicked
 * with appropriate parameters.
 *
 * @param[in]  evflag  The kind of event that happened.
 * @param[in]  data    The `data` passed to rb_add_event_hook().
 * @param[in]  self    Current receiver.
 * @param[in]  mid     Name of the current method.
 * @param[in]  klass   Current class.
 */
typedef void (*rb_event_hook_func_t)(rb_event_flag_t evflag, VALUE data, VALUE self, ID mid, VALUE klass);

/**
 * @private
 *
 * @deprecated  This macro once was a thing in the old days, but makes no sense
 *              any  longer today.   Exists  here  for backwards  compatibility
 *              only.  You can safely forget about it.
 */
#define RB_EVENT_HOOKS_HAVE_CALLBACK_DATA 1

RBIMPL_SYMBOL_EXPORT_BEGIN()

/**
 * Registers an event hook function.
 *
 * @param[in]  func    A callback.
 * @param[in]  events  A set of events that `func` should run.
 * @param[in]  data    Passed as-is to `func`.
 */
void rb_add_event_hook(rb_event_hook_func_t func, rb_event_flag_t events, VALUE data);

/**
 * Removes the passed function from the list of event hooks.
 *
 * @param[in]  func  A callback.
 * @return     Number of deleted event hooks.
 * @note       As  multiple  events can  share  the  same  `func` it  is  quite
 *             possible for the return value to become more than one.
 *
 * @internal
 *
 * @shyouhei doesn't know if this is an  Easter egg or an official feature, but
 * you can pass 0 to the argument.  That effectively swipes everything out from
 * the hook list.
 */
int rb_remove_event_hook(rb_event_hook_func_t func);
RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_EVENT_H */
ruby/internal/value.h000064400000010410151732674150010635 0ustar00#ifndef RBIMPL_VALUE_H                               /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_VALUE_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines ::VALUE and ::ID.
 */
#include "ruby/internal/static_assert.h"
#include "ruby/backward/2/long_long.h"
#include "ruby/backward/2/limits.h"

#if defined(__DOXYGEN__)

/**
 * Type that represents a Ruby object.  It is an unsigned integer of some kind,
 * depending on platforms.
 *
 * ```CXX
 * VALUE value = rb_eval_string("ARGF.readlines.map.with_index");
 * ```
 *
 * @warning  ::VALUE is not a pointer.
 * @warning  ::VALUE can be wider than `long`.
 */
typedef uintptr_t VALUE;

/**
 * Type that represents a Ruby identifier such as a variable name.
 *
 * ```CXX
 * ID method = rb_intern("method");
 * VALUE result = rb_funcall(obj, method, 0);
 * ```
 *
 * @note  ::rb_cSymbol is a Ruby-level data type for the same thing.
 */
typedef uintptr_t ID;

/**
 * A signed integer type that has the same width with ::VALUE.
 *
 * @internal
 *
 * @shyouhei wonders: is it guaranteed  that `uintptr_t` and `intptr_t` are the
 * same width?  As far as I read ISO/IEC 9899:2018 section 7.20.1.4 paragraph 1
 * no such description is given... or defined elsewhere?
 */
typedef intptr_t SIGNED_VALUE;

/**
 * Identical to  `sizeof(VALUE)`, except it  is a macro  that can also  be used
 * inside of preprocessor directives such as `#if`.  Handy on occasions.
 */
#define SIZEOF_VALUE SIZEOF_UINTPTR_T

/**
 * @private
 *
 * A compile-time constant of type ::VALUE whose value is 0.
 */
#define RBIMPL_VALUE_NULL UINTPTR_C(0)

/**
 * @private
 *
 * A compile-time constant of type ::VALUE whose value is 1.
 */
#define RBIMPL_VALUE_ONE  UINTPTR_C(1)

/**
 * @private
 *
 * Maximum possible value that a ::VALUE can take.
 */
#define RBIMPL_VALUE_FULL UINTPTR_MAX

#elif defined HAVE_UINTPTR_T && 0
typedef uintptr_t VALUE;
typedef uintptr_t ID;
# define SIGNED_VALUE intptr_t
# define SIZEOF_VALUE SIZEOF_UINTPTR_T
# undef PRI_VALUE_PREFIX
# define RBIMPL_VALUE_NULL UINTPTR_C(0)
# define RBIMPL_VALUE_ONE  UINTPTR_C(1)
# define RBIMPL_VALUE_FULL UINTPTR_MAX

#elif SIZEOF_LONG == SIZEOF_VOIDP
typedef unsigned long VALUE;
typedef unsigned long ID;
# define SIGNED_VALUE long
# define SIZEOF_VALUE SIZEOF_LONG
# define PRI_VALUE_PREFIX "l"
# define RBIMPL_VALUE_NULL 0UL
# define RBIMPL_VALUE_ONE  1UL
# define RBIMPL_VALUE_FULL ULONG_MAX

#elif SIZEOF_LONG_LONG == SIZEOF_VOIDP
typedef unsigned LONG_LONG VALUE;
typedef unsigned LONG_LONG ID;
# define SIGNED_VALUE LONG_LONG
# define LONG_LONG_VALUE 1
# define SIZEOF_VALUE SIZEOF_LONG_LONG
# define PRI_VALUE_PREFIX PRI_LL_PREFIX
# define RBIMPL_VALUE_NULL 0ULL
# define RBIMPL_VALUE_ONE  1ULL
# define RBIMPL_VALUE_FULL ULLONG_MAX

#else
# error ---->> ruby requires sizeof(void*) == sizeof(long) or sizeof(LONG_LONG) to be compiled. <<----
#endif

/** @cond INTERNAL_MACRO */
RBIMPL_STATIC_ASSERT(sizeof_int, SIZEOF_INT == sizeof(int));
RBIMPL_STATIC_ASSERT(sizeof_long, SIZEOF_LONG == sizeof(long));
RBIMPL_STATIC_ASSERT(sizeof_long_long, SIZEOF_LONG_LONG == sizeof(LONG_LONG));
RBIMPL_STATIC_ASSERT(sizeof_voidp, SIZEOF_VOIDP == sizeof(void *));
/** @endcond */
#endif /* RBIMPL_VALUE_H */
ruby/internal/gc.h000064400000070105151732674150010121 0ustar00#ifndef RBIMPL_GC_H                                  /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_GC_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Registering values to the GC.
 */
#include "ruby/internal/config.h"

#ifdef STDC_HEADERS
# include <stddef.h>                       /* size_t */
#endif

#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>                    /* ssize_t */
#endif

#include "ruby/assert.h"
#include "ruby/internal/attr/cold.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/attr/maybe_unused.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/special_consts.h"
#include "ruby/internal/stdbool.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

#define RUBY_REF_EDGE(s, p) offsetof(s, p)
#define RUBY_REFS_LIST_PTR(l) (RUBY_DATA_FUNC)(uintptr_t)(l)
#define RUBY_REF_END SIZE_MAX
#define RUBY_REFERENCES(t) static const size_t t[]
#define RUBY_REFERENCES_START(t) RUBY_REFERENCES(t) = {
#define RUBY_REFERENCES_END RUBY_REF_END, };

/* gc.c */

RBIMPL_ATTR_COLD()
RBIMPL_ATTR_NORETURN()
/**
 * Triggers out-of-memory error.  If  possible it raises ::rb_eNoMemError.  But
 * because  we are  running out  of  memory that  is not  always doable.   This
 * function tries hard to show something, but ultimately can die silently.
 *
 * @exception  rb_eNoMemError  Raises it if possible.
 */
void rb_memerror(void);

RBIMPL_ATTR_PURE()
/**
 * Queries if the GC is busy.
 *
 * @retval  0  It isn't.
 * @retval  1  It is.
 */
int rb_during_gc(void);

RBIMPL_ATTR_NONNULL((1))
/**
 * Marks  objects between  the two  pointers.  This  is one  of the  GC utility
 * functions    that   you    can    call   when    you    design   your    own
 * ::rb_data_type_struct::dmark.
 *
 * @pre         Continuous memory region  from `start` to `end`  shall be fully
 *              addressable.
 * @param[out]  start  Pointer to an array of objects.
 * @param[out]  end    Pointer that terminates the array of objects.
 * @post        Objects from `start` (included) to `end` (excluded) are marked.
 *
 * @internal
 *
 * `end` can be NULL...  But that just results in no-op.
 */
void rb_gc_mark_locations(const VALUE *start, const VALUE *end);

/**
 * Identical to  rb_mark_hash(), except it marks  only values of the  table and
 * leave  their  associated keys  unmarked.  This  is  one  of the  GC  utility
 * functions    that   you    can    call   when    you    design   your    own
 * ::rb_data_type_struct::dmark.
 *
 * @warning    Of course it can break GC.  Leave it unused if unsure.
 * @param[in]  tbl  A table to mark.
 * @post       Values stored in `tbl` are marked.
 */
void rb_mark_tbl(struct st_table *tbl);

/**
 * Identical    to   rb_mark_tbl(),    except    it    marks   objects    using
 * rb_gc_mark_movable().  This is one of the  GC utility functions that you can
 * call when you design your own ::rb_data_type_struct::dmark.
 *
 * @warning    Of course it can break GC.  Leave it unused if unsure.
 * @param[in]  tbl  A table to mark.
 * @post       Values stored in `tbl` are marked.
 */
void rb_mark_tbl_no_pin(struct st_table *tbl);

/**
 * Identical to  rb_mark_hash(), except  it marks  only keys  of the  table and
 * leave  their associated  values unmarked.   This is  one of  the GC  utility
 * functions    that   you    can    call   when    you    design   your    own
 * ::rb_data_type_struct::dmark.
 *
 * @warning    Of course it can break GC.  Leave it unused if unsure.
 * @param[in]  tbl  A table to mark.
 * @post       Keys stored in `tbl` are marked.
 */
void rb_mark_set(struct st_table *tbl);

/**
 * Marks keys and values  associated inside of the given table.  This is one of
 * the  GC  utility functions  that  you  can call  when  you  design your  own
 * ::rb_data_type_struct::dmark.
 *
 * @param[in]  tbl  A table to mark.
 * @post       Objects stored in `tbl` are marked.
 */
void rb_mark_hash(struct st_table *tbl);

/**
 * Updates  references  inside  of  tables.   After  you  marked  values  using
 * rb_mark_tbl_no_pin(), the  objects inside  of the table  could of  course be
 * moved.  This function is to fixup  those references.  You can call this from
 * your ::rb_data_type_struct::dcompact.
 *
 * @param[out]  ptr  A table that potentially includes moved references.
 * @post        Moved references, if any, are corrected.
 */
void rb_gc_update_tbl_refs(st_table *ptr);

/**
 * Identical  to  rb_gc_mark(),  except  it   allows  the  passed  value  be  a
 * non-object.  For instance  pointers to different type of  memory regions are
 * allowed here.   Such values  are silently  ignored.  This is  one of  the GC
 * utility   functions  that   you  can   call   when  you   design  your   own
 * ::rb_data_type_struct::dmark.
 *
 * @param[out]  obj  A possible object.
 * @post        `obj` is marked, if possible.
 */
void rb_gc_mark_maybe(VALUE obj);

/**
 * Marks an object.  This is one of  the GC utility functions that you can call
 * when you design your own ::rb_data_type_struct::dmark.
 *
 * @param[out]  obj  Arbitrary Ruby object.
 * @post        `obj` is marked.
 */
void rb_gc_mark(VALUE obj);

/**
 * Maybe this  is the only  function provided for  C extensions to  control the
 * pinning of objects, so  let us describe it in detail.   These days Ruby's GC
 * is copying.  As far as an object's physical address is guaranteed unused, it
 * can move  around the object space.   Our GC engine rearranges  these objects
 * after it  reclaims unreachable objects  from our  object space, so  that the
 * space  is   compact  (improves  memory   locality).   This  is   called  the
 * "compaction" phase, and works  well most of the time... as  far as there are
 * no C  extensions.  C  extensions complicate the  scenario because  Ruby core
 * cannot detect  any use  of the  physical address  of an  object inside  of C
 * functions.  In order to prevent  memory corruptions, objects observable from
 * C extensions are "pinned"; they stick to where they are born until they die,
 * just in  case any C  extensions touch their  raw pointers.  This  variant of
 * scheme  is   called  "Mostly-Copying"  garbage  collector.    Authors  of  C
 * extensions,  however,   can  extremely   carefully  write  them   to  become
 * compaction-aware.  To do so avoid referring  to a Ruby object from inside of
 * your struct  in the  first place.   But if  that is  not possible,  use this
 * function  from your  ::rb_data_type_struct::dmark  then.   This way  objects
 * marked using it are  considered movable.  If you chose this  way you have to
 * manually fix up locations of such moved pointers using rb_gc_location().
 *
 * @see  Bartlett,  Joel  F.,  "Compacting Garbage  Collection  with  Ambiguous
 *       Roots",  ACM  SIGPLAN  Lisp  Pointers  Volume  1  Issue  6  pp.  3-12,
 *       April-May-June, 1988. https://doi.org/10.1145/1317224.1317225
 *
 * @param[in]  obj  Object that is movable.
 * @post       Values stored in `tbl` are marked.
 */
void rb_gc_mark_movable(VALUE obj);

/**
 * Finds a new "location" of an object.   An object can be moved on compaction.
 * This function projects  its new abode, or just returns  the passed object if
 * not moved.  This is  one of the GC utility functions that  you can call when
 * you design your own ::rb_data_type_struct::dcompact.
 *
 * @param[in]  obj  An object, possibly already moved to somewhere else.
 * @return     An object, which holds the current contents of former `obj`.
 */
VALUE rb_gc_location(VALUE obj);

/**
 * Triggers a GC process.  This was the only  GC entry point that we had at the
 * beginning.  Over time our GC evolved.  Now what this function does is just a
 * very  simplified  variation  of  the  entire GC  algorithms.   A  series  of
 * procedures kicked by this API is called a "full" GC.
 *
 *   - It immediately scans the entire object space to sort the dead.
 *   - It immediately reclaims any single dead bodies to reuse later.
 *
 * It is worth  noting that the procedures above do  not include evaluations of
 * finalisers.  They run later.
 *
 * @internal
 *
 * Finalisers   are   deferred   until   we   can   handle   interrupts.    See
 * `rb_postponed_job_flush` in vm_trace.c.
 *
 * Of course there are  GC that are not "full".  For instance  this one and the
 * GC  which  runs when  we  are  running out  of  memory  are different.   See
 * `gc_profile_record_flag` defined in gc.c for the kinds of GC.
 *
 * In spite of the name this is not  what everything that a GC can trigger.  As
 * of writing  it seems this  function does  not trigger compaction.   But this
 * might change in future.
 */
void rb_gc(void);

/**
 * Copy&paste an object's finaliser to another.   This is one of the GC utility
 * functions  that you  can call  when you  design your  own `initialize_copy`,
 * `initialize_dup`, `initialize_clone`.
 *
 * @param[out]  dst  Destination object.
 * @param[in]   src  Source object.
 * @post        `dst` and `src` share the same finaliser.
 *
 * @internal
 *
 * But isn't it  easier for you to call super,  and let `Object#initialize_copy`
 * call this function instead?
 */
void rb_gc_copy_finalizer(VALUE dst, VALUE src);

/**
 * (Re-) enables GC.  This makes sense only after you called rb_gc_disable().
 *
 * @retval  RUBY_Qtrue   GC was disabled before.
 * @retval  RUBY_Qfalse  GC was enabled before.
 * @post    GC is enabled.
 *
 * @internal
 *
 * This is  one of  such exceptional  functions that does  not raise  both Ruby
 * exceptions and C++ exceptions.
 */
VALUE rb_gc_enable(void);

/**
 * Disables GC.   This prevents automatic GC  runs when the process  is running
 * out of memory.  Such situations shall result in rb_memerror().  However this
 * does not  prevent users from  manually invoking rb_gc().  That  should work.
 * People  abused this  by disabling  GC  at the  beginning of  an event  loop,
 * process events without GC overheads,  then manually force reclaiming garbage
 * at the bottom of the loop.  However  because our GC is now much smarter than
 * just calling rb_gc(), this technique is proven to be sub-optimal these days.
 * It  is  believed that  there  is  currently  practically  no needs  of  this
 * function.
 *
 * @retval  RUBY_Qtrue   GC was disabled before.
 * @retval  RUBY_Qfalse  GC was enabled before.
 * @post    GC is disabled.
 */
VALUE rb_gc_disable(void);

/**
 * Identical to rb_gc(), except the return value.
 *
 * @return  Always returns ::RUBY_Qnil.
 */
VALUE rb_gc_start(void);

/**
 * Assigns a finaliser for an object.  Each objects can have objects (typically
 * blocks)  that run  immediately  after  that object  dies.   They are  called
 * finalisers of an object.  This function associates a finaliser object with a
 * target object.
 *
 * @note  Note that finalisers run _after_  the object they finalise dies.  You
 *        cannot for instance call its methods.
 * @note  If  your finaliser  references the  object it  finalises that  object
 *        loses any chance to become  a garbage; effectively leaks memory until
 *        the end of the process.
 *
 * @param[in]  obj               Target to finalise.
 * @param[in]  block             Something `call`able.
 * @exception  rb_eRuntimeError  Somehow `obj` cannot have finalisers.
 * @exception  rb_eFrozenError   `obj` is frozen.
 * @exception  rb_eArgError      `block` doesn't respond to `call`.
 * @return     The passed `block`.
 * @post       `block` runs after `obj` dies.
 */
VALUE rb_define_finalizer(VALUE obj, VALUE block);

/**
 * Modifies the object so  that it has no finalisers at  all.  This function is
 * mainly provided for symmetry.  No practical usages can be thought of.
 *
 * @param[out]  obj               Object to clear its finalisers.
 * @exception   rb_eFrozenError  `obj` is frozen.
 * @return      The passed `obj`.
 * @post        `obj` has no finalisers.
 * @note        There is no way to undefine  a specific part of many finalisers
 *              that `obj` could have.  All you can do is to clear them all.
 */
VALUE rb_undefine_finalizer(VALUE obj);

/**
 * Identical to rb_gc_stat(), with "count" parameter.
 *
 * @return  Lifetime total number of runs of GC.
 */
size_t rb_gc_count(void);

/**
 * Obtains various GC  related profiles.  The parameter can be  either a Symbol
 * or a  Hash.  If  a Hash is  passed, it is  filled with  everything currently
 * available.  If a Symbol is passed just that portion is returned.
 *
 * Possible  variations of  keys  you  can pass  here  change  from version  to
 * version.  You can  get the list of  known keys by passing an  empty hash and
 * let it be filled.
 *
 * @param[in,out]  key_or_buf       A Symbol, or a Hash.
 * @exception      rb_eTypeError    Neither Symbol nor Hash.
 * @exception      rb_eFrozenError  Frozen hash is passed.
 * @return         In  case a  Hash  is  passed it  returns  0.  Otherwise  the
 *                 profile value associated with the given key is returned.
 * @post           In case a Hash is passed it is filled with values.
 */
size_t rb_gc_stat(VALUE key_or_buf);

/**
 * Obtains various  info regarding the most  recent GC run.  This  includes for
 * instance the reason  of the GC.  The  parameter can be either a  Symbol or a
 * Hash.   If  a  Hash  is  passed, it  is  filled  with  everything  currently
 * available.  If a Symbol is passed just that portion is returned.
 *
 * Possible  variations of  keys  you  can pass  here  change  from version  to
 * version.  You can  get the list of  known keys by passing an  empty hash and
 * let it be filled.
 *
 * @param[in,out]  key_or_buf       A Symbol, or a Hash.
 * @exception      rb_eTypeError    Neither Symbol nor Hash.
 * @exception      rb_eFrozenError  Frozen hash is passed.
 * @return         In case  a Hash is  passed it returns that  hash.  Otherwise
 *                 the profile value associated with the given key is returned.
 * @post           In case a Hash is passed it is filled with values.
 */
VALUE rb_gc_latest_gc_info(VALUE key_or_buf);

/**
 * Informs that  there are  external memory  usages.  Our GC  runs when  we are
 * running out of memory.  The amount of memory, however, can increase/decrease
 * behind-the-scene.  For  instance DLLs can allocate  memories using `mmap(2)`
 * etc, which  are opaque to  us.  Registering such external  allocations using
 * this function enables  proper detection of how much memories  an object used
 * as a whole.  That will trigger GCs  more often than it would otherwise.  You
 * can  also  pass  negative  numbers  here, to  indicate  that  such  external
 * allocations are gone.
 *
 * @param[in]  diff  Amount of memory increased(+)/decreased(-).
 */
void rb_gc_adjust_memory_usage(ssize_t diff);

/**
 * Inform the garbage  collector that the global or static  variable pointed by
 * `valptr` stores  a live  Ruby object  that should not  be moved.   Note that
 * extensions  should use  this API  on  global constants  instead of  assuming
 * constants defined  in Ruby are  always alive.   Ruby code can  remove global
 * constants.
 *
 * Because this  registration itself has  a possibility  to trigger a  GC, this
 * function  must be  called  before any  GC-able objects  is  assigned to  the
 * address pointed by `valptr`.
 */
void rb_gc_register_address(VALUE *valptr);

/**
 * An alias for `rb_gc_register_address()`.
 */
void rb_global_variable(VALUE *);

/**
 * Inform the garbage collector that a pointer previously passed to
 * `rb_gc_register_address()` no longer points to a live Ruby object.
 */
void rb_gc_unregister_address(VALUE *valptr);

/**
 * Inform the garbage collector that `object` is a live Ruby object that should
 * not be moved.
 *
 * See also: rb_gc_register_address()
 */
void rb_gc_register_mark_object(VALUE object);

RBIMPL_SYMBOL_EXPORT_END()

/**
 * @private
 *
 * @deprecated  This macro once was a thing in the old days, but makes no sense
 *              any  longer today.   Exists  here  for backwards  compatibility
 *              only.  You can safely forget about it.
 */
#undef USE_RGENGC
#define USE_RGENGC 1

/**
 * @deprecated  This macro seems  broken.  Setting this to  anything other than
 *              zero just doesn't compile.  We need to KonMari.
 */
#ifndef USE_RGENGC_LOGGING_WB_UNPROTECT
# define USE_RGENGC_LOGGING_WB_UNPROTECT 0
#endif

/**
 * @private
 *
 * This  is   a  compile-time   flag  to   enable/disable  write   barrier  for
 * struct ::RArray.  It has to be set  at the time ruby itself compiles.  Makes
 * no sense for 3rd parties.
 */
#ifndef RGENGC_WB_PROTECTED_ARRAY
# define RGENGC_WB_PROTECTED_ARRAY 1
#endif

/**
 * @private
 *
 * This  is   a  compile-time   flag  to   enable/disable  write   barrier  for
 * struct ::RHash.  It has  to be set at the time  ruby itself compiles.  Makes
 * no sense for 3rd parties.
 */
#ifndef RGENGC_WB_PROTECTED_HASH
# define RGENGC_WB_PROTECTED_HASH 1
#endif

/**
 * @private
 *
 * This  is   a  compile-time   flag  to   enable/disable  write   barrier  for
 * struct ::RStruct.  It has to be set at the time ruby itself compiles.  Makes
 * no sense for 3rd parties.
 */
#ifndef RGENGC_WB_PROTECTED_STRUCT
# define RGENGC_WB_PROTECTED_STRUCT 1
#endif

/**
 * @private
 *
 * This  is   a  compile-time   flag  to   enable/disable  write   barrier  for
 * struct ::RString.  It has to be set at the time ruby itself compiles.  Makes
 * no sense for 3rd parties.
 */
#ifndef RGENGC_WB_PROTECTED_STRING
# define RGENGC_WB_PROTECTED_STRING 1
#endif

/**
 * @private
 *
 * This  is   a  compile-time   flag  to   enable/disable  write   barrier  for
 * struct ::RObject.  It has to be set at the time ruby itself compiles.  Makes
 * no sense for 3rd parties.
 */
#ifndef RGENGC_WB_PROTECTED_OBJECT
# define RGENGC_WB_PROTECTED_OBJECT 1
#endif

/**
 * @private
 *
 * This  is   a  compile-time   flag  to   enable/disable  write   barrier  for
 * struct ::RRegexp.  It has to be set at the time ruby itself compiles.  Makes
 * no sense for 3rd parties.
 */
#ifndef RGENGC_WB_PROTECTED_REGEXP
# define RGENGC_WB_PROTECTED_REGEXP 1
#endif

/**
 * @private
 *
 * This  is   a  compile-time   flag  to   enable/disable  write   barrier  for
 * struct ::RMatch.  It has to be set at the time ruby itself compiles.  Makes
 * no sense for 3rd parties.
 */
#ifndef RGENGC_WB_PROTECTED_MATCH
# define RGENGC_WB_PROTECTED_MATCH 1
#endif

/**
 * @private
 *
 * This  is   a  compile-time   flag  to   enable/disable  write   barrier  for
 * struct ::RClass.  It has to be set  at the time ruby itself compiles.  Makes
 * no sense for 3rd parties.
 */
#ifndef RGENGC_WB_PROTECTED_CLASS
# define RGENGC_WB_PROTECTED_CLASS 1
#endif

/**
 * @private
 *
 * This  is   a  compile-time   flag  to   enable/disable  write   barrier  for
 * struct ::RFloat.  It has to be set  at the time ruby itself compiles.  Makes
 * no sense for 3rd parties.
 */
#ifndef RGENGC_WB_PROTECTED_FLOAT
# define RGENGC_WB_PROTECTED_FLOAT 1
#endif

/**
 * @private
 *
 * This  is   a  compile-time   flag  to   enable/disable  write   barrier  for
 * struct ::RComplex.   It has  to be  set at  the time  ruby itself  compiles.
 * Makes no sense for 3rd parties.
 */
#ifndef RGENGC_WB_PROTECTED_COMPLEX
# define RGENGC_WB_PROTECTED_COMPLEX 1
#endif

/**
 * @private
 *
 * This  is   a  compile-time   flag  to   enable/disable  write   barrier  for
 * struct ::RRational.  It  has to  be set  at the  time ruby  itself compiles.
 * Makes no sense for 3rd parties.
 */
#ifndef RGENGC_WB_PROTECTED_RATIONAL
# define RGENGC_WB_PROTECTED_RATIONAL 1
#endif

/**
 * @private
 *
 * This  is   a  compile-time   flag  to   enable/disable  write   barrier  for
 * struct ::RBignum.  It has to be set at the time ruby itself compiles.  Makes
 * no sense for 3rd parties.
 */
#ifndef RGENGC_WB_PROTECTED_BIGNUM
# define RGENGC_WB_PROTECTED_BIGNUM 1
#endif

/**
 * @private
 *
 * @deprecated  This macro once was a thing in the old days, but makes no sense
 *              any  longer today.   Exists  here  for backwards  compatibility
 *              only.  You can safely forget about it.
 *
 * @internal
 *
 * @shyouhei doesn't think anybody uses this right now.
 */
#ifndef RGENGC_WB_PROTECTED_NODE_CREF
# define RGENGC_WB_PROTECTED_NODE_CREF 1
#endif

/**
 * @defgroup rgengc Write barrier (WB) interfaces:
 *
 * @note The following  core interfaces can  be changed in the  future.  Please
 *       catch up if you want to insert WB into C-extensions correctly.
 *
 * @{
 */

/**
 * Declaration of a "back" pointer.  This  is a write barrier for new reference
 * from  "old"  generation  to  "young" generation.   It  writes  `young`  into
 * `*slot`, which is a pointer inside of `old`.
 *
 * @param[in]   old    An old object.
 * @param[in]   slot   A pointer inside of `old`.
 * @param[out]  young  A young object.
 */
#define RB_OBJ_WRITE(old, slot, young) \
    RBIMPL_CAST(rb_obj_write((VALUE)(old), (VALUE *)(slot), (VALUE)(young), __FILE__, __LINE__))

/**
 * Identical to #RB_OBJ_WRITE(), except it doesn't write any values, but only a
 * WB declaration.   `oldv` is  replaced value  with `b`  (not used  in current
 * Ruby).
 *
 * @param[in]   old    An old object.
 * @param[in]   oldv   An object previously stored inside of `old`.
 * @param[out]  young  A young object.
 */
#define RB_OBJ_WRITTEN(old, oldv, young) \
    RBIMPL_CAST(rb_obj_written((VALUE)(old), (VALUE)(oldv), (VALUE)(young), __FILE__, __LINE__))
/** @} */

#define OBJ_PROMOTED_RAW RB_OBJ_PROMOTED_RAW /**< @old{RB_OBJ_PROMOTED_RAW} */
#define OBJ_PROMOTED     RB_OBJ_PROMOTED     /**< @old{RB_OBJ_PROMOTED} */
#define OBJ_WB_UNPROTECT RB_OBJ_WB_UNPROTECT /**< @old{RB_OBJ_WB_UNPROTECT} */

/**
 * Asserts that the passed object is  not fenced by write barriers.  Objects of
 * such  property do  not contribute  to  generational GCs.   They are  scanned
 * always.
 *
 * @param[out]  x  An object that would not be protected by the barrier.
 */
#define RB_OBJ_WB_UNPROTECT(x) rb_obj_wb_unprotect(x, __FILE__, __LINE__)

/**
 * Identical  to #RB_OBJ_WB_UNPROTECT(),  except it  can also  assert that  the
 * given object is of given type.
 *
 * @param[in]   type  One of `ARRAY`, `STRING`, etc.
 * @param[out]  obj   An object of `type` that would not be protected.
 *
 * @internal
 *
 * @shyouhei doesn't understand why this has to be visible from extensions.
 */
#define RB_OBJ_WB_UNPROTECT_FOR(type, obj) \
    (RGENGC_WB_PROTECTED_##type ? OBJ_WB_UNPROTECT(obj) : obj)

/**
 * @private
 *
 * This is an implementation detail of rb_obj_wb_unprotect().  People don't use
 * it directly.
 */
#define RGENGC_LOGGING_WB_UNPROTECT rb_gc_unprotect_logging

/** @cond INTERNAL_MACRO */
#define RB_OBJ_PROMOTED_RAW RB_OBJ_PROMOTED_RAW
#define RB_OBJ_PROMOTED     RB_OBJ_PROMOTED
/** @endcond */

RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
 * This  is  the  implementation  of  #RB_OBJ_WRITE().   People  don't  use  it
 * directly.
 *
 * @param[in]   old    An object that points to `young`.
 * @param[out]  young  An object that is referenced from `old`.
 */
void rb_gc_writebarrier(VALUE old, VALUE young);

/**
 * This is the  implementation of #RB_OBJ_WB_UNPROTECT().  People  don't use it
 * directly.
 *
 * @param[out] obj  An object that does not participate in WB.
 */
void rb_gc_writebarrier_unprotect(VALUE obj);

#if USE_RGENGC_LOGGING_WB_UNPROTECT
/**
 * @private
 *
 * This  is  the   implementation  of  #RGENGC_LOGGING_WB_UNPROTECT().   People
 * don't use it directly.
 *
 * @param[in]  objptr    Don't  know why  this  is  a pointer  to  void but  in
 *                       reality this is  a pointer to an object  that is about
 *                       to be un-protected.
 * @param[in]  filename  Pass C's `__FILE__` here.
 * @param[in]  line      Pass C's `__LINE__` here.
 */
void rb_gc_unprotect_logging(void *objptr, const char *filename, int line);
#endif

RBIMPL_SYMBOL_EXPORT_END()

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
 * This  is the  implementation  of #RB_OBJ_PROMOTED().   People  don't use  it
 * directly.
 *
 * @param[in]  obj    An object to query.
 * @retval     true   The object is "promoted".
 * @retval     false  The object is young.  Have not experienced GC at all.
 */
static inline bool
RB_OBJ_PROMOTED_RAW(VALUE obj)
{
    RBIMPL_ASSERT_OR_ASSUME(RB_FL_ABLE(obj));
    return RB_FL_ANY_RAW(obj,  RUBY_FL_PROMOTED);
}

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Tests if the object is "promoted" -- that is, whether the object experienced
 * one or more GC marks.
 *
 * @param[in]  obj    An object to query.
 * @retval     true   The object is "promoted".
 * @retval     false  The object is young.  Have not experienced GC at all.
 * @note       Hello, is anyone actively calling this function?  @shyouhei have
 *             never seen  any actual usages  outside of the  GC implementation
 *             itself.
 */
static inline bool
RB_OBJ_PROMOTED(VALUE obj)
{
    if (! RB_FL_ABLE(obj)) {
        return false;
    }
    else {
        return RB_OBJ_PROMOTED_RAW(obj);
    }
}

/**
 * This is the  implementation of #RB_OBJ_WB_UNPROTECT().  People  don't use it
 * directly.
 *
 * @param[out]  x         An object that does not participate in WB.
 * @param[in]   filename  C's `__FILE__` of the caller function.
 * @param[in]   line      C's `__LINE__` of the caller function.
 * @return      x
 */
static inline VALUE
rb_obj_wb_unprotect(
    VALUE x,
    RBIMPL_ATTR_MAYBE_UNUSED()
    const char *filename,
    RBIMPL_ATTR_MAYBE_UNUSED()
    int line)
{
#if USE_RGENGC_LOGGING_WB_UNPROTECT
    RGENGC_LOGGING_WB_UNPROTECT(RBIMPL_CAST((void *)x), filename, line);
#endif
    rb_gc_writebarrier_unprotect(x);
    return x;
}

/**
 * @private
 *
 * This  is  the implementation  of  #RB_OBJ_WRITTEN().   People don't  use  it
 * directly.
 *
 * @param[in]   a         An old object.
 * @param[in]   oldv      An object previously stored inside of `old`.
 * @param[out]  b         A young object.
 * @param[in]   filename  C's `__FILE__` of the caller function.
 * @param[in]   line      C's `__LINE__` of the caller function.
 * @return      a
 */
static inline VALUE
rb_obj_written(
    VALUE a,
    RBIMPL_ATTR_MAYBE_UNUSED()
    VALUE oldv,
    VALUE b,
    RBIMPL_ATTR_MAYBE_UNUSED()
    const char *filename,
    RBIMPL_ATTR_MAYBE_UNUSED()
    int line)
{
#if USE_RGENGC_LOGGING_WB_UNPROTECT
    RGENGC_LOGGING_OBJ_WRITTEN(a, oldv, b, filename, line);
#endif

    if (!RB_SPECIAL_CONST_P(b)) {
        rb_gc_writebarrier(a, b);
    }

    return a;
}

/**
 * @private
 *
 * This  is  the  implementation  of  #RB_OBJ_WRITE().   People  don't  use  it
 * directly.
 *
 * @param[in]   a         An old object.
 * @param[in]   slot      A pointer inside of `old`.
 * @param[out]  b         A young object.
 * @param[in]   filename  C's `__FILE__` of the caller function.
 * @param[in]   line      C's `__LINE__` of the caller function.
 * @return      a
 */
static inline VALUE
rb_obj_write(
    VALUE a, VALUE *slot, VALUE b,
    RBIMPL_ATTR_MAYBE_UNUSED()
    const char *filename,
    RBIMPL_ATTR_MAYBE_UNUSED()
    int line)
{
#ifdef RGENGC_LOGGING_WRITE
    RGENGC_LOGGING_WRITE(a, slot, b, filename, line);
#endif

    *slot = b;

    rb_obj_written(a, RUBY_Qundef /* ignore `oldv' now */, b, filename, line);
    return a;
}

RBIMPL_ATTR_DEPRECATED(("Will be removed soon"))
static inline void rb_gc_force_recycle(VALUE obj){}

#endif /* RBIMPL_GC_H */
ruby/internal/abi.h000064400000003062151732674150010261 0ustar00#ifndef RUBY_ABI_H
#define RUBY_ABI_H

#ifdef RUBY_ABI_VERSION /* should match the definition in config.h */

/* This number represents Ruby's ABI version.
 *
 * In development Ruby, it should be bumped every time an ABI incompatible
 * change is introduced. This will force other developers to rebuild extension
 * gems.
 *
 * The following cases are considered as ABI incompatible changes:
 * - Changing any data structures.
 * - Changing macros or inline functions causing a change in behavior.
 * - Deprecating or removing function declarations.
 *
 * The following cases are NOT considered as ABI incompatible changes:
 * - Any changes that does not involve the header files in the `include`
 *   directory.
 * - Adding macros, inline functions, or function declarations.
 * - Backwards compatible refactors.
 * - Editing comments.
 *
 * In released versions of Ruby, this number is not defined since teeny
 * versions of Ruby should guarantee ABI compatibility.
 */
#define RUBY_ABI_VERSION 1

/* Windows does not support weak symbols so ruby_abi_version will not exist
 * in the shared library. */
#if defined(HAVE_FUNC_WEAK) && !defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
# define RUBY_DLN_CHECK_ABI
#endif
#endif  /* RUBY_ABI_VERSION */

#if defined(RUBY_DLN_CHECK_ABI) && !defined(RUBY_EXPORT)

# ifdef __cplusplus
extern "C" {
# endif

RUBY_FUNC_EXPORTED unsigned long long __attribute__((weak))
ruby_abi_version(void)
{
# ifdef RUBY_ABI_VERSION
    return RUBY_ABI_VERSION;
# else
    return 0;
# endif
}

# ifdef __cplusplus
}
# endif

#endif

#endif
ruby/internal/static_assert.h000064400000006327151732674150012405 0ustar00#ifndef RBIMPL_STATIC_ASSERT_H                       /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_STATIC_ASSERT_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_STATIC_ASSERT.
 */
#include <assert.h>
#include "ruby/internal/has/extension.h"
#include "ruby/internal/compiler_since.h"
#include "ruby/internal/attr/maybe_unused.h"

/** @cond INTERNAL_MACRO */
#if defined(__cplusplus) && defined(__cpp_static_assert)
# /* https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations */
# define RBIMPL_STATIC_ASSERT0 static_assert

#elif defined(__cplusplus) && RBIMPL_COMPILER_SINCE(MSVC, 16, 0, 0)
# define RBIMPL_STATIC_ASSERT0 static_assert

#elif defined(__INTEL_CXX11_MODE__)
# define RBIMPL_STATIC_ASSERT0 static_assert

#elif defined(__cplusplus) && __cplusplus >= 201103L
# define RBIMPL_STATIC_ASSERT0 static_assert

#elif defined(__cplusplus) && RBIMPL_HAS_EXTENSION(cxx_static_assert)
# define RBIMPL_STATIC_ASSERT0 __extension__ static_assert

#elif defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__
# define RBIMPL_STATIC_ASSERT0 __extension__ static_assert

#elif defined(__STDC_VERSION__) && RBIMPL_HAS_EXTENSION(c_static_assert)
# define RBIMPL_STATIC_ASSERT0 __extension__ _Static_assert

#elif defined(__STDC_VERSION__) && RBIMPL_COMPILER_SINCE(GCC, 4, 6, 0)
# define RBIMPL_STATIC_ASSERT0 __extension__ _Static_assert

#elif defined(static_assert)
# /* Take <assert.h> definition */
# define RBIMPL_STATIC_ASSERT0 static_assert
#endif
/** @endcond */

/**
 * @brief  Wraps (or simulates) `static_assert`
 * @param  name  Valid C/C++ identifier, describing the assertion.
 * @param  expr  Expression to assert.
 * @note   `name` shall not be a string literal.
 */
#if defined(__DOXYGEN__)
# define RBIMPL_STATIC_ASSERT static_assert

#elif defined(RBIMPL_STATIC_ASSERT0)
# define RBIMPL_STATIC_ASSERT(name, expr) \
    RBIMPL_STATIC_ASSERT0(expr, # name ": " # expr)

#else
# define RBIMPL_STATIC_ASSERT(name, expr) \
    RBIMPL_ATTR_MAYBE_UNUSED() typedef int static_assert_ ## name ## _check[1 - 2 * !(expr)]
#endif

#endif /* RBIMPL_STATIC_ASSERT_H */
ruby/internal/newobj.h000064400000014132151732674150011012 0ustar00#ifndef RBIMPL_NEWOBJ_H                              /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_NEWOBJ_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #NEWOBJ.
 */
#include "ruby/internal/attr/deprecated.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/core/rbasic.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/fl_type.h"
#include "ruby/internal/special_consts.h"
#include "ruby/internal/value.h"
#include "ruby/assert.h"

#define OBJSETUP   rb_obj_setup   /**< @old{rb_obj_setup} */
#define CLONESETUP rb_clone_setup /**< @old{rb_clone_setup} */
#define DUPSETUP   rb_dup_setup   /**< @old{rb_dup_setup} */

RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
 * Fills common fields in the object.
 *
 * @param[in,out]  obj    A Ruby object to be set up.
 * @param[in]      klass  `obj` will belong to this class.
 * @param[in]      type   One of ::ruby_value_type.
 * @return         The passed object.
 *
 * @internal
 *
 * Historically, authors of  Ruby has described the `type` argument  as "one of
 * ::ruby_value_type".   In   reality  it  accepts   either  ::ruby_value_type,
 * ::ruby_fl_type,   or   any   combinations   of  the   two.    For   instance
 * `RUBY_T_STRING | RUBY_FL_FREEZE` is a valid  value that this function takes,
 * and means this is a frozen string.
 *
 * 3rd  party extension  libraries rarely  need to  allocate Strings  this way.
 * They normally only concern ::RUBY_T_DATA.   This argument is mainly used for
 * specifying flags, @shyouhei suspects.
 */
VALUE rb_obj_setup(VALUE obj, VALUE klass, VALUE type);

/**
 * Queries  the  class  of  an  object.    This  is  not  always  identical  to
 * `RBASIC_CLASS(obj)`.   It   searches  for  the  nearest   ancestor  skipping
 * singleton classes or included modules.
 *
 * @param[in]  obj  Object in question.
 * @return     The object's class, in a normal sense.
 */
VALUE rb_obj_class(VALUE obj);

/**
 * Clones a singleton class.  An object  can have its own singleton class.  OK.
 * Then what  happens when a program  clones such object?  The  singleton class
 * that is  attached to  the source  object must also  be cloned.   Otherwise a
 * singleton object gets shared with two objects, which breaks "singleton"-ness
 * of such class.
 *
 * This  is basically  an  implementation detail  of rb_clone_setup().   People
 * need not be aware of this working behind-the-scene.
 *
 * @param[in]  obj  The object that has its own singleton class.
 * @return     Cloned singleton class.
 */
VALUE rb_singleton_class_clone(VALUE obj);

/**
 * Attaches a singleton class to its corresponding object.
 *
 * This  is basically  an  implementation detail  of rb_clone_setup().   People
 * need not be aware of this working behind-the-scene.
 *
 * @param[in]   klass  The singleton class.
 * @param[out]  obj    The object to attach a class.
 * @pre         The passed two objects must  agree with each other that `klass`
 *              becomes a singleton class of `obj`.
 * @post        `klass` becomes the singleton class of `obj`.
 */
void rb_singleton_class_attached(VALUE klass, VALUE obj);

/**
 * Copies the list of instance variables.  3rd parties need not know, but there
 * are several ways  to store an object's instance variables,  depending on its
 * internal structure.   This function  makes sense when  either of  the passed
 * objects are using so-called "generic"  backend storage.  This distinction is
 * purely an  implementation detail  of rb_clone_setup().   People need  not be
 * aware of this working behind-the-scenes.
 *
 * @param[out]  clone  The destination object.
 * @param[in]   obj    The source object.
 */
void rb_copy_generic_ivar(VALUE clone, VALUE obj);
RBIMPL_SYMBOL_EXPORT_END()

RBIMPL_ATTR_DEPRECATED(("This is no longer how Object#clone works."))
/**
 * @deprecated  Not sure exactly  when but at some time,  the implementation of
 *              `Object#clone`  stopped  using   this  function.   It  remained
 *              untouched for  a while, and  then @shyouhei realised  that they
 *              are no longer doing the  same thing.  It seems nobody seriously
 *              uses this function any longer.  Let's just abandon it.
 *
 * @param[out]  clone  The destination object.
 * @param[in]   obj    The source object.
 */
static inline void
rb_clone_setup(VALUE clone, VALUE obj)
{
    (void)clone;
    (void)obj;
    return;
}

RBIMPL_ATTR_DEPRECATED(("This is no longer how Object#dup works."))
/**
 * @deprecated  Not sure exactly  when but at some time,  the implementation of
 *              `Object#dup`   stopped  using   this  function.    It  remained
 *              untouched for  a while, and  then @shyouhei realised  that they
 *              are no longer  the same thing.  It seems  nobody seriously uses
 *              this function any longer.  Let's just abandon it.
 *
 * @param[out]  dup  The destination object.
 * @param[in]   obj  The source object.
 */
static inline void
rb_dup_setup(VALUE dup, VALUE obj)
{
    (void)dup;
    (void)obj;
    return;
}

#endif /* RBIMPL_NEWOBJ_H */
ruby/internal/compiler_is/sunpro.h000064400000005223151732674150013362 0ustar00#ifndef RBIMPL_COMPILER_IS_SUNPRO_H                  /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_COMPILER_IS_SUNPRO_H
/**
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines RBIMPL_COMPILER_IS_SunPro.
 */
#if ! (defined(__SUNPRO_C) || defined(__SUNPRO_CC))
# define RBIMPL_COMPILER_IS_SunPro 0

#elif defined(__SUNPRO_C) && __SUNPRO_C >= 0x5100
# define RBIMPL_COMPILER_IS_SunPro 1
# /* __SUNPRO_C = 0xXYYZ */
# define RBIMPL_COMPILER_VERSION_MAJOR  (__SUNPRO_C >> 12)
# define RBIMPL_COMPILER_VERSION_MINOR ((__SUNPRO_C >> 8 & 0xF) * 10 + (__SUNPRO_C >> 4 & 0xF))
# define RBIMPL_COMPILER_VERSION_PATCH  (__SUNPRO_C      & 0xF)

#elif defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5100
# define RBIMPL_COMPILER_IS_SunPro 1
# /* __SUNPRO_CC = 0xXYYZ */
# define RBIMPL_COMPILER_VERSION_MAJOR  (__SUNPRO_CC >> 12)
# define RBIMPL_COMPILER_VERSION_MINOR ((__SUNPRO_CC >> 8 & 0xF) * 10 + (__SUNPRO_CC >> 4 & 0xF))
# define RBIMPL_COMPILER_VERSION_PATCH  (__SUNPRO_CC      & 0xF)

#elif defined(__SUNPRO_C)
# define RBIMPL_COMPILER_IS_SunPro 1
# /* __SUNPRO_C = 0xXYZ */
# define RBIMPL_COMPILER_VERSION_MAJOR (__SUNPRO_C >> 8)
# define RBIMPL_COMPILER_VERSION_MINOR (__SUNPRO_C >> 4 & 0xF)
# define RBIMPL_COMPILER_VERSION_PATCH (__SUNPRO_C      & 0xF)

#else
# define RBIMPL_COMPILER_IS_SunPro 1
# /* __SUNPRO_CC = 0xXYZ */
# define RBIMPL_COMPILER_VERSION_MAJOR (__SUNPRO_CC >> 8)
# define RBIMPL_COMPILER_VERSION_MINOR (__SUNPRO_CC >> 4 & 0xF)
# define RBIMPL_COMPILER_VERSION_PATCH (__SUNPRO_CC      & 0xF)
#endif

#endif /* RBIMPL_COMPILER_IS_SUNPRO_H */
ruby/internal/compiler_is/clang.h000064400000003403151732674150013116 0ustar00#ifndef RBIMPL_COMPILER_IS_CLANG_H                   /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_COMPILER_IS_CLANG_H
/**
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines RBIMPL_COMPILER_IS_Clang.
 */
#include "ruby/internal/compiler_is/apple.h"

#if ! defined(__clang__)
# define RBIMPL_COMPILER_IS_Clang 0

#elif RBIMPL_COMPILER_IS(Apple)
# define RBIMPL_COMPILER_IS_Clang 0

#else
# define RBIMPL_COMPILER_IS_Clang 1
# define RBIMPL_COMPILER_VERSION_MAJOR __clang_major__
# define RBIMPL_COMPILER_VERSION_MINOR __clang_minor__
# define RBIMPL_COMPILER_VERSION_PATCH __clang_patchlevel__
#endif

#endif /* RBIMPL_COMPILER_IS_CLANG_H */
ruby/internal/compiler_is/apple.h000064400000003732151732674160013141 0ustar00#ifndef RBIMPL_COMPILER_IS_APPLE_H                   /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_COMPILER_IS_APPLE_H
/**
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines RBIMPL_COMPILER_IS_Apple.
 *
 * Apple  ships clang.   Problem is,  its  `__clang_major__` etc.  are not  the
 * upstream LLVM  version, but XCode's.  We  have to think Apple's  is distinct
 * from LLVM's,  when it comes  to compiler  detection business in  this header
 * file.
 */
#if ! defined(__clang__)
# define RBIMPL_COMPILER_IS_Apple 0

#elif ! defined(__apple_build_version__)
# define RBIMPL_COMPILER_IS_Apple 0

#else
# define RBIMPL_COMPILER_IS_Apple 1
# define RBIMPL_COMPILER_VERSION_MAJOR __clang_major__
# define RBIMPL_COMPILER_VERSION_MINOR __clang_minor__
# define RBIMPL_COMPILER_VERSION_PATCH __clang_patchlevel__
#endif

#endif /* RBIMPL_COMPILER_IS_APPLE_H */
ruby/internal/compiler_is/msvc.h000064400000004736151732674160013015 0ustar00#ifndef RBIMPL_COMPILER_IS_MSVC_H                    /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_COMPILER_IS_MSVC_H
/**
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines RBIMPL_COMPILER_IS_MSVC.
 */
#include "ruby/internal/compiler_is/clang.h"
#include "ruby/internal/compiler_is/intel.h"

#if ! defined(_MSC_VER)
# define RBIMPL_COMPILER_IS_MSVC 0

#elif RBIMPL_COMPILER_IS(Clang)
# define RBIMPL_COMPILER_IS_MSVC 0

#elif RBIMPL_COMPILER_IS(Intel)
# define RBIMPL_COMPILER_IS_MSVC 0

#elif _MSC_VER >= 1400
# define RBIMPL_COMPILER_IS_MSVC 1
# /* _MSC_FULL_VER = XXYYZZZZZ */
# define RBIMPL_COMPILER_VERSION_MAJOR (_MSC_FULL_VER / 10000000)
# define RBIMPL_COMPILER_VERSION_MINOR (_MSC_FULL_VER % 10000000 / 100000)
# define RBIMPL_COMPILER_VERSION_PATCH (_MSC_FULL_VER            % 100000)

#elif defined(_MSC_FULL_VER)
# define RBIMPL_COMPILER_IS_MSVC 1
# /* _MSC_FULL_VER = XXYYZZZZ */
# define RBIMPL_COMPILER_VERSION_MAJOR (_MSC_FULL_VER / 1000000)
# define RBIMPL_COMPILER_VERSION_MINOR (_MSC_FULL_VER % 1000000 / 10000)
# define RBIMPL_COMPILER_VERSION_PATCH (_MSC_FULL_VER           % 10000)

#else
# define RBIMPL_COMPILER_IS_MSVC 1
# /* _MSC_VER = XXYY */
# define RBIMPL_COMPILER_VERSION_MAJOR (_MSC_VER / 100)
# define RBIMPL_COMPILER_VERSION_MINOR (_MSC_VER % 100)
# define RBIMPL_COMPILER_VERSION_PATCH 0
#endif

#endif /* RBIMPL_COMPILER_IS_MSVC_H */
ruby/internal/compiler_is/gcc.h000064400000003715151732674160012575 0ustar00#ifndef RBIMPL_COMPILER_IS_GCC_H                     /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_COMPILER_IS_GCC_H
/**
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines RBIMPL_COMPILER_IS_GCC.
 */
#include "ruby/internal/compiler_is/apple.h"
#include "ruby/internal/compiler_is/clang.h"
#include "ruby/internal/compiler_is/intel.h"

#if ! defined(__GNUC__)
# define RBIMPL_COMPILER_IS_GCC 0

#elif RBIMPL_COMPILER_IS(Apple)
# define RBIMPL_COMPILER_IS_GCC 0

#elif RBIMPL_COMPILER_IS(Clang)
# define RBIMPL_COMPILER_IS_GCC 0

#elif RBIMPL_COMPILER_IS(Intel)
# define RBIMPL_COMPILER_IS_GCC 0

#else
# define RBIMPL_COMPILER_IS_GCC 1
# define RBIMPL_COMPILER_VERSION_MAJOR __GNUC__
# define RBIMPL_COMPILER_VERSION_MINOR __GNUC_MINOR__
# define RBIMPL_COMPILER_VERSION_PATCH __GNUC_PATCHLEVEL__
#endif

#endif /* RBIMPL_COMPILER_IS_GCC_H */
ruby/internal/compiler_is/intel.h000064400000004011151732674160013142 0ustar00#ifndef RBIMPL_COMPILER_IS_INTEL_H                   /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_COMPILER_IS_INTEL_H
/**
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines RBIMPL_COMPILER_IS_Intel.
 */
#if ! defined(__INTEL_COMPILER)
# define RBIMPL_COMPILER_IS_Intel 0

#elif ! defined(__INTEL_COMPILER_UPDATE)
# define RBIMPL_COMPILER_IS_Intel 1
# /* __INTEL_COMPILER = XXYZ */
# define RBIMPL_COMPILER_VERSION_MAJOR (__INTEL_COMPILER / 100)
# define RBIMPL_COMPILER_VERSION_MINOR (__INTEL_COMPILER % 100 / 10)
# define RBIMPL_COMPILER_VERSION_PATCH (__INTEL_COMPILER       % 10)

#else
# define RBIMPL_COMPILER_IS_Intel 1
# /* __INTEL_COMPILER = XXYZ */
# define RBIMPL_COMPILER_VERSION_MAJOR (__INTEL_COMPILER / 100)
# define RBIMPL_COMPILER_VERSION_MINOR (__INTEL_COMPILER % 100 / 10)
# define RBIMPL_COMPILER_VERSION_PATCH __INTEL_COMPILER_UPDATE
#endif

#endif /* RBIMPL_COMPILER_IS_INTEL_H */
ruby/internal/interpreter.h000064400000022711151732674160012074 0ustar00#ifndef RBIMPL_INTERPRETER_H                         /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERPRETER_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Interpreter embedding APIs.
 */
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/**
 * @defgroup embed CRuby Embedding APIs
 *
 * CRuby interpreter APIs. These are APIs to embed MRI interpreter into your
 * program.
 * These functions are not a part of Ruby extension library API.
 * Extension libraries of Ruby should not depend on these functions.
 *
 * @{
 */

/**
 * @defgroup ruby1 ruby(1) implementation
 *
 * A part of the implementation of ruby(1) command.
 * Other programs that embed Ruby interpreter do not always need to use these
 * functions.
 *
 * @{
 */

RBIMPL_ATTR_NONNULL(())
/**
 * Initializes the process for libruby.
 *
 * This function assumes this process is `ruby(1)` and it has just started.
 * Usually programs that embed CRuby interpreter may not call this function,
 * and may do their own initialization.
 *
 * @param[in]  argc  Pointer to process main's `argc`.
 * @param[in]  argv  Pointer to process main's `argv`.
 * @warning    `argc` and `argv` cannot be `NULL`.
 *
 * @internal
 *
 * AFAIK Ruby does write to argv, especially `argv[0][0]`, via setproctitle(3).
 * It is intentional that the argument is not const-qualified.
 */
void ruby_sysinit(int *argc, char ***argv);

/**
 * Calls ruby_setup() and check error.
 *
 * Prints errors and calls exit(3) if an error occurred.
 */
void ruby_init(void);

/**
 * Processes command line arguments and compiles the Ruby source to execute.
 *
 * This function does:
 *   - Processes the given command line flags and arguments for `ruby(1)`
 *   - Compiles the source code from the given argument, `-e` or `stdin`, and
 *   - Returns the compiled source as an opaque pointer to an internal data
 *     structure
 *
 * @param[in]  argc  Process main's `argc`.
 * @param[in]  argv  Process main's `argv`.
 * @return     An opaque pointer to the compiled source or an internal special
 *             value.  Pass it to ruby_executable_node() to detect which.
 * @see        ruby_executable_node
 */
void* ruby_options(int argc, char** argv);

/**
 * Checks the return value of ruby_options().
 *
 * ruby_options() sometimes returns a special value to indicate this process
 * should immediately exit. This function checks if the case. Also stores the
 * exit status that the caller have to pass to exit(3) into `*status`.
 *
 * @param[in]   n          A return value of ruby_options().
 * @param[out]  status     Pointer to the exit status of this process.
 * @retval      0          The given value is such a special value.
 * @retval      otherwise  The given opaque pointer is actually a compiled
 *                         source.
 */
int ruby_executable_node(void *n, int *status);

/**
 * Runs the given compiled source and exits this process.
 *
 * @param[in]  n             Opaque "node" pointer.
 * @retval     EXIT_SUCCESS  Successfully run the source.
 * @retval     EXIT_FAILURE  An error occurred.
 */
int ruby_run_node(void *n);

/* version.c */
/** Prints the version information of the CRuby interpreter to stdout. */
void ruby_show_version(void);

#ifndef ruby_show_copyright
/** Prints the copyright notice of the CRuby interpreter to stdout. */
void ruby_show_copyright(void);
#endif

/**
 * A convenience macro to call ruby_init_stack().
 * Must be placed just after variable declarations.
 */
#define RUBY_INIT_STACK \
    VALUE variable_in_this_stack_frame; \
    ruby_init_stack(&variable_in_this_stack_frame);
/** @} */

/**
 * Set stack bottom of Ruby implementation.
 *
 * You  must   call  this   function  before  any   heap  allocation   by  Ruby
 * implementation.  Or GC will break living objects.
 *
 * @param[in]  addr  A pointer somewhere on the stack, near its bottom.
 */
void ruby_init_stack(void *addr);

/**
 * Initializes the VM and builtin libraries.
 *
 * @retval  0          Initialization succeeded.
 * @retval  otherwise  An error occurred.
 *
 * @internal
 *
 * Though not  a part of our  public API, the return  value is in fact  an enum
 * ruby_tag_type.  You can  see the potential "otherwise" values  by looking at
 * vm_core.h.
 */
int ruby_setup(void);

/**
 * Destructs the VM.
 *
 * Runs the VM finalization processes as well as ruby_finalize(), and frees
 * resources used by the VM.
 *
 * @param[in]  ex  Default value to the return value.
 * @retval     EXIT_FAILURE  An error occurred.
 * @retval     ex            Successful cleanup.
 * @note       This function does not raise any exception.
 */
int ruby_cleanup(int ex);

/**
 * Runs the VM finalization processes.
 *
 * `END{}` and procs registered by `Kernel.#at_exit` are executed here. See the
 * Ruby language spec for more details.
 *
 * @note This function is allowed to raise an exception if an error occurred.
 */
void ruby_finalize(void);

RBIMPL_ATTR_NORETURN()
/** Calls ruby_cleanup() and exits the process. */
void ruby_stop(int);

/**
 * Checks for stack overflow.
 *
 * @retval  true   NG machine stack is about to overflow.
 * @retval  false  OK there still is a room in the stack.
 *
 * @internal
 *
 * Does anybody use it?  So far @shyouhei have never seen any actual use-case.
 */
int ruby_stack_check(void);

/**
 * Queries what Ruby thinks is the machine stack.  Ruby manages a region of
 * memory.  It calls that area the "machine stack".  By calling this function,
 * in spite of its name, you can obtain both one end of the stack and its
 * length at once.  Which means you can know the entire region.
 *
 * @param[out]  topnotch  On return the pointer points to the upmost address of
 *                        the macihne stack that Ruby knows.
 * @return      Length of the machine stack that Ruby knows.
 *
 * @internal
 *
 * Does anybody use it?  @shyouhei is quite skeptical if this is useful outside
 * of the VM.  Maybe it was a wrong idea to expose this API to 3rd parties.
 */
size_t ruby_stack_length(VALUE **topnotch);

/**
 * Identical to ruby_run_node(), except it returns an opaque execution status.
 * You can pass it to rb_cleanup().
 *
 * @param[in]  n          Opaque "node" pointer.
 * @retval     0          Successful end-of-execution.
 * @retval     otherwise  An error occurred.
 *
 * @internal
 *
 * Though not  a part of our  public API, the return  value is in fact  an enum
 * ruby_tag_type.  You can  see the potential "otherwise" values  by looking at
 * vm_core.h.
 */
int ruby_exec_node(void *n);

/**
 * Sets the current script name to this value.
 *
 * This is similar to `$0 = name` in Ruby level but also affects
 * `Method#location` and others.
 *
 * @param[in]  name  File name to set.
 */
void ruby_script(const char* name);

/**
 * Identical to ruby_script(), except it takes the name as a Ruby String
 * instance.
 *
 * @param[in]  name  File name to set.
 */
void ruby_set_script_name(VALUE name);

/** Defines built-in variables */
void ruby_prog_init(void);

/**
 * Sets argv that ruby understands.  Your program might have its own command
 * line parameters etc.  Handle them as you wish, and pass remaining parts of
 * argv here.
 *
 * @param[in]  argc  Number of elements of `argv`.
 * @param[in]  argv  Command line arguments.
 */
void ruby_set_argv(int argc, char **argv);

/**
 * Identical to ruby_options(), except it raises ruby-level exceptions on
 * failure.
 *
 * @param[in]  argc  Process main's `argc`.
 * @param[in]  argv  Process main's `argv`.
 * @return     An opaque "node" pointer.
 */
void *ruby_process_options(int argc, char **argv);

/**
 * Sets up `$LOAD_PATH`.
 *
 * @internal
 *
 * @shyouhei guesses this has to be called  at very later stage, at least after
 * the birth of object system.  But is not exactly sure when.
 */
void ruby_init_loadpath(void);

/**
 * Appends the given path to the end of the load path.
 *
 * @pre        ruby_init_loadpath() must be done beforehand.
 * @param[in]  path  The path you want to push to the load path.
 */
void ruby_incpush(const char *path);

/**
 * Clear signal handlers.
 *
 * Ruby installs its own signal handler (apart from those which user scripts
 * set).  This is to clear that.  Must be called when the ruby part terminates,
 * before switching to your program's own logic.
 */
void ruby_sig_finalize(void);

/** @} */

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERPRETER_H */
ruby/internal/encoding/ctype.h000064400000017527151732674160012454 0ustar00#ifndef RUBY_INTERNAL_ENCODING_CTYPE_H               /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_INTERNAL_ENCODING_CTYPE_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Routines to query chacater types.
 */

#include "ruby/onigmo.h"
#include "ruby/internal/attr/const.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/encoding/encoding.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/**
 * Queries if  the passed  pointer points  to a newline  character.  What  is a
 * newline and what is not depends on the passed encoding.
 *
 * @param[in]  p          Pointer to a possibly-middle of a character.
 * @param[in]  end        End of the string.
 * @param[in]  enc        Encoding.
 * @retval     false      It isn't.
 * @retval     true       It is.
 */
static inline bool
rb_enc_is_newline(const char *p,  const char *e, rb_encoding *enc)
{
    OnigUChar *up = RBIMPL_CAST((OnigUChar *)p);
    OnigUChar *ue = RBIMPL_CAST((OnigUChar *)e);

    return ONIGENC_IS_MBC_NEWLINE(enc, up, ue);
}

/**
 * Queries if the passed  code point is of passed character  type in the passed
 * encoding.  The "character type" here is a set of macros defined in onigmo.h,
 * like `ONIGENC_CTYPE_PUNCT`.
 *
 * @param[in]  c          An `OnigCodePoint` value.
 * @param[in]  t          An `OnigCtype` value.
 * @param[in]  enc        A `rb_encoding*` value.
 * @retval     true       `c` is of `t` in `enc`.
 * @retval     false      Otherwise.
 */
static inline bool
rb_enc_isctype(OnigCodePoint c, OnigCtype t, rb_encoding *enc)
{
    return ONIGENC_IS_CODE_CTYPE(enc, c, t);
}

/**
 * Identical to rb_isascii(), except it additionally takes an encoding.
 *
 * @param[in]  c          A code point.
 * @param[in]  enc        An encoding.
 * @retval     false      `c` is out of range of ASCII character set in `enc`.
 * @retval     true       Otherwise.
 *
 * @internal
 *
 * `enc` is  ignored.  This  is at least  an intentional  implementation detail
 * (not a bug).  But there could be rooms for future extensions.
 */
static inline bool
rb_enc_isascii(OnigCodePoint c, rb_encoding *enc)
{
    return ONIGENC_IS_CODE_ASCII(c);
}

/**
 * Identical to rb_isalpha(), except it additionally takes an encoding.
 *
 * @param[in]  c          A code point.
 * @param[in]  enc        An encoding.
 * @retval     true       `enc` classifies `c` as "ALPHA".
 * @retval     false      Otherwise.
 */
static inline bool
rb_enc_isalpha(OnigCodePoint c, rb_encoding *enc)
{
    return ONIGENC_IS_CODE_ALPHA(enc, c);
}

/**
 * Identical to rb_islower(), except it additionally takes an encoding.
 *
 * @param[in]  c          A code point.
 * @param[in]  enc        An encoding.
 * @retval     true       `enc` classifies `c` as "LOWER".
 * @retval     false      Otherwise.
 */
static inline bool
rb_enc_islower(OnigCodePoint c, rb_encoding *enc)
{
    return ONIGENC_IS_CODE_LOWER(enc, c);
}

/**
 * Identical to rb_isupper(), except it additionally takes an encoding.
 *
 * @param[in]  c          A code point.
 * @param[in]  enc        An encoding.
 * @retval     true       `enc` classifies `c` as "UPPER".
 * @retval     false      Otherwise.
 */
static inline bool
rb_enc_isupper(OnigCodePoint c, rb_encoding *enc)
{
    return ONIGENC_IS_CODE_UPPER(enc, c);
}

/**
 * Identical to rb_iscntrl(), except it additionally takes an encoding.
 *
 * @param[in]  c          A code point.
 * @param[in]  enc        An encoding.
 * @retval     true       `enc` classifies `c` as "CNTRL".
 * @retval     false      Otherwise.
 */
static inline bool
rb_enc_iscntrl(OnigCodePoint c, rb_encoding *enc)
{
    return ONIGENC_IS_CODE_CNTRL(enc, c);
}

/**
 * Identical to rb_ispunct(), except it additionally takes an encoding.
 *
 * @param[in]  c          A code point.
 * @param[in]  enc        An encoding.
 * @retval     true       `enc` classifies `c` as "PUNCT".
 * @retval     false      Otherwise.
 */
static inline bool
rb_enc_ispunct(OnigCodePoint c, rb_encoding *enc)
{
    return ONIGENC_IS_CODE_PUNCT(enc, c);
}

/**
 * Identical to rb_isalnum(), except it additionally takes an encoding.
 *
 * @param[in]  c          A code point.
 * @param[in]  enc        An encoding.
 * @retval     true       `enc` classifies `c` as "ANUM".
 * @retval     false      Otherwise.
 */
static inline bool
rb_enc_isalnum(OnigCodePoint c, rb_encoding *enc)
{
    return ONIGENC_IS_CODE_ALNUM(enc, c);
}

/**
 * Identical to rb_isprint(), except it additionally takes an encoding.
 *
 * @param[in]  c          A code point.
 * @param[in]  enc        An encoding.
 * @retval     true       `enc` classifies `c` as "PRINT".
 * @retval     false      Otherwise.
 */
static inline bool
rb_enc_isprint(OnigCodePoint c, rb_encoding *enc)
{
    return ONIGENC_IS_CODE_PRINT(enc, c);
}

/**
 * Identical to rb_isspace(), except it additionally takes an encoding.
 *
 * @param[in]  c          A code point.
 * @param[in]  enc        An encoding.
 * @retval     true       `enc` classifies `c` as "PRINT".
 * @retval     false      Otherwise.
 */
static inline bool
rb_enc_isspace(OnigCodePoint c, rb_encoding *enc)
{
    return ONIGENC_IS_CODE_SPACE(enc, c);
}

/**
 * Identical to rb_isdigit(), except it additionally takes an encoding.
 *
 * @param[in]  c          A code point.
 * @param[in]  enc        An encoding.
 * @retval     true       `enc` classifies `c` as "DIGIT".
 * @retval     false      Otherwise.
 */
static inline bool
rb_enc_isdigit(OnigCodePoint c, rb_encoding *enc)
{
    return ONIGENC_IS_CODE_DIGIT(enc, c);
}

RBIMPL_ATTR_CONST()
/**
 * Identical to rb_toupper(), except it additionally takes an encoding.
 *
 * @param[in]  c    A code point.
 * @param[in]  enc  An encoding.
 * @return     `c`'s (Ruby's definition of) upper case counterpart.
 *
 * @internal
 *
 * As `RBIMPL_ATTR_CONST` implies this function ignores `enc`.
 */
int rb_enc_toupper(int c, rb_encoding *enc);

RBIMPL_ATTR_CONST()
/**
 * Identical to rb_tolower(), except it additionally takes an encoding.
 *
 * @param[in]  c    A code point.
 * @param[in]  enc  An encoding.
 * @return     `c`'s (Ruby's definition of) lower case counterpart.
 *
 * @internal
 *
 * As `RBIMPL_ATTR_CONST` implies this function ignores `enc`.
 */
int rb_enc_tolower(int c, rb_encoding *enc);

RBIMPL_SYMBOL_EXPORT_END()

/** @cond INTERNAL_MACRO */
#define rb_enc_is_newline rb_enc_is_newline
#define rb_enc_isalnum    rb_enc_isalnum
#define rb_enc_isalpha    rb_enc_isalpha
#define rb_enc_isascii    rb_enc_isascii
#define rb_enc_isctype    rb_enc_isctype
#define rb_enc_isdigit    rb_enc_isdigit
#define rb_enc_islower    rb_enc_islower
#define rb_enc_isprint    rb_enc_isprint
#define rb_enc_iscntrl    rb_enc_iscntrl
#define rb_enc_ispunct    rb_enc_ispunct
#define rb_enc_isspace    rb_enc_isspace
#define rb_enc_isupper    rb_enc_isupper
/** @endcond */

#endif /* RUBY_INTERNAL_ENCODING_CTYPE_H */
ruby/internal/encoding/transcode.h000064400000062175151732674160013311 0ustar00#ifndef RUBY_INTERNAL_ENCODING_TRANSCODE_H           /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_INTERNAL_ENCODING_TRANSCODE_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      econv stuff
 */

#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/** return value of rb_econv_convert() */
typedef enum {

    /**
     * The conversion stopped when it found an invalid sequence.
     */
    econv_invalid_byte_sequence,

    /**
     * The conversion  stopped when  it found  a character  in the  input which
     * cannot be representable in the output.
     */
    econv_undefined_conversion,

    /**
     * The conversion stopped because there is no destination.
     */
    econv_destination_buffer_full,

    /**
     * The conversion stopped because there is no input.
     */
    econv_source_buffer_empty,

    /**
     * The conversion  stopped after  converting everything.  This  is arguably
     * the expected normal end of conversion.
     */
    econv_finished,

    /**
     * The  conversion stopped  after  writing something  to somewhere,  before
     * reading everything.
     */
    econv_after_output,

    /**
     * The conversion stopped in middle of reading a character, possibly due to
     * a partial read of a socket etc.
     */
    econv_incomplete_input
} rb_econv_result_t;

/** An opaque struct that represents a lowest level of encoding conversion. */
typedef struct rb_econv_t rb_econv_t;

/**
 * Converts the contents  of the passed string from its  encoding to the passed
 * one.
 *
 * @param[in]  str                           Target string.
 * @param[in]  to                            Destination encoding.
 * @param[in]  ecflags                       A        set        of        enum
 *                                           ::ruby_econv_flag_type.
 * @param[in]  ecopts                        A      keyword     hash,      like
 *                                           ::rb_io_t::rb_io_enc_t::ecopts.
 * @exception  rb_eArgError                  Not fully converted.
 * @exception  rb_eInvalidByteSequenceError  `str` is malformed.
 * @exception  rb_eUndefinedConversionError  `str`   has    a   character   not
 *                                           representable using `to`.
 * @exception  rb_eConversionNotFoundError   There is no  known conversion from
 *                                           `str`'s encoding to `to`.
 * @return     A string whose encoding is `to`, and whose contents is converted
 *             contents of `str`.
 * @note       Use rb_econv_prepare_options() to generate `ecopts`.
 */
VALUE rb_str_encode(VALUE str, VALUE to, int ecflags, VALUE ecopts);

/**
 * Queries if  there is  more than one  way to convert  between the  passed two
 * encodings.  Encoding  conversion are  has_and_belongs_to_many relationships.
 * There could be no direct conversion defined for the passed pair.  Ruby tries
 * to find  an indirect  way to  do so  then.  For  instance ISO-8859-1  has no
 * direct  conversion  to  ISO-2022-JP.   But  there  is  ISO-8859-1  to  UTF-8
 * conversion; then there is UTF-8 to  EUC-JP conversion; finally there also is
 * EUC-JP to ISO-2022-JP  conversion.  So in short ISO-8859-1  can be converted
 * to ISO-2022-JP using that path.   This function returns true.  Obviously not
 * everything that can be represented using UTF-8 can also be represented using
 * EUC-JP.  Conversions in practice can fail depending on the actual input, and
 * that renders exceptions in case of rb_str_encode().
 *
 * @param[in] from_encoding  One encoding.
 * @param[in] to_encoding    Another encoding.
 * @retval    0              No way to convert the two.
 * @retval    1              At least one way to convert the two.
 *
 * @internal
 *
 * Practically @shyouhei knows no way for  this function to return 0.  It seems
 * everything  can  eventually  be  converted  to/from  UTF-8,  which  connects
 * everything.
 */
int rb_econv_has_convpath_p(const char* from_encoding, const char* to_encoding);

/**
 * Identical  to  rb_econv_prepare_opts(),  except it  additionally  takes  the
 * initial  value of  flags.  The  extra bits  are bitwise-ORed  to the  return
 * value.
 *
 * @param[in]   opthash       Keyword arguments.
 * @param[out]  ecopts        Return buffer.
 * @param[in]   ecflags       Default set of enum ::ruby_econv_flag_type.
 * @exception   rb_eArgError  Unknown/Broken values passed.
 * @return      Calculated set of enum ::ruby_econv_flag_type.
 * @post        `ecopts`     holds    a     hash     object    suitable     for
 *              ::rb_io_t::rb_io_enc_t::ecopts.
 */
int rb_econv_prepare_options(VALUE opthash, VALUE *ecopts, int ecflags);

/**
 * Splits a  keyword arguments  hash (that  for instance  `String#encode` took)
 * into a  set of  enum ::ruby_econv_flag_type and  a hash  storing replacement
 * characters etc.
 *
 * @param[in]   opthash       Keyword arguments.
 * @param[out]  ecopts        Return buffer.
 * @exception   rb_eArgError  Unknown/Broken values passed.
 * @return      Calculated set of enum ::ruby_econv_flag_type.
 * @post        `ecopts`     holds    a     hash     object    suitable     for
 *              ::rb_io_t::rb_io_enc_t::ecopts.
 */
int rb_econv_prepare_opts(VALUE opthash, VALUE *ecopts);

/**
 * Creates a new instance of struct ::rb_econv_t.
 *
 * @param[in]  source_encoding       Name of an encoding.
 * @param[in]  destination_encoding  Name of another encoding.
 * @param[in]  ecflags               A set of enum ::ruby_econv_flag_type.
 * @exception  rb_eArgError          No such encoding.
 * @retval     NULL                  Failed to create a struct ::rb_econv_t.
 * @retval     otherwise             Allocated struct ::rb_econv_t.
 * @warning    Return value must be passed to rb_econv_close() exactly once.
 */
rb_econv_t *rb_econv_open(const char *source_encoding, const char *destination_encoding, int ecflags);

/**
 * Identical  to  rb_econv_open(),  except  it additionally  takes  a  hash  of
 * optional strings.
 *
 *
 * @param[in]  source_encoding       Name of an encoding.
 * @param[in]  destination_encoding  Name of another encoding.
 * @param[in]  ecflags               A set of enum ::ruby_econv_flag_type.
 * @param[in]  ecopts                Optional set of strings.
 * @exception  rb_eArgError          No such encoding.
 * @retval     NULL                  Failed to create a struct ::rb_econv_t.
 * @retval     otherwise             Allocated struct ::rb_econv_t.
 * @warning    Return value must be passed to rb_econv_close() exactly once.
 */
rb_econv_t *rb_econv_open_opts(const char *source_encoding, const char *destination_encoding, int ecflags, VALUE ecopts);

/**
 * Converts a string from an encoding to another.
 *
 * Possible  flags  are  either ::RUBY_ECONV_PARTIAL_INPUT  (means  the  source
 * buffer is a  part of much larger  one), ::RUBY_ECONV_AFTER_OUTPUT (instructs
 * the converter to stop after output before input), or both of them.
 *
 * @param[in,out]  ec                      Conversion specification/state etc.
 * @param[in]      source_buffer_ptr       Target string.
 * @param[in]      source_buffer_end       End of target string.
 * @param[out]     destination_buffer_ptr  Return buffer.
 * @param[out]     destination_buffer_end  End of return buffer.
 * @param[in]      flags                   Flags (see above).
 * @return         The status of the conversion.
 * @post           `destination_buffer_ptr` holds conversion results.
 */
rb_econv_result_t rb_econv_convert(rb_econv_t *ec,
    const unsigned char **source_buffer_ptr, const unsigned char *source_buffer_end,
    unsigned char **destination_buffer_ptr, unsigned char *destination_buffer_end,
    int flags);

/**
 * Destructs a converter.  Note that a converter  can have a buffer, and can be
 * non-empty.  Calling this would lose your data then.
 *
 * @param[out]  ec The converter to destroy.
 * @post        `ec` is no longer a valid pointer.
 */
void rb_econv_close(rb_econv_t *ec);

/**
 * Assigns  the replacement  string.  The  string passed  here would  appear in
 * converted string when it cannot  represent its source counterpart.  This can
 * happen for instance you convert an emoji to ISO-8859-1.
 *
 * @param[out]  ec       Target converter.
 * @param[in]   str      Replacement string.
 * @param[in]   len      Number of bytes of `str`.
 * @param[in]   encname  Name of encoding of `str`.
 * @retval      0        Success.
 * @retval      -1       Failure (ENOMEM etc.).
 * @post        `ec`'s replacement string is set to `str`.
 */
int rb_econv_set_replacement(rb_econv_t *ec, const unsigned char *str, size_t len, const char *encname);

/**
 * "Decorate"s  a  converter.   There  are  special  kind  of  converters  that
 * transforms the  contents, like  replacing CR  into CRLF.   You can  add such
 * decorators  to  a converter  using  this  API.   By  using this  function  a
 * decorator is prepended at the beginning of a conversion sequence: in case of
 * CRLF conversion, newlines are converted before encodings are converted.
 *
 * @param[out]  ec              Target converter to decorate.
 * @param[in]   decorator_name  Name of decorator to prepend.
 * @retval      0               Success.
 * @retval      -1              Failure (no such decorator etc.).
 * @post        Decorator works before encoding conversion happens.
 *
 * @internal
 *
 * What is the possible value of  the `decorator_name` is not public.  You have
 * to read through `transcode.c` carefully.
 */
int rb_econv_decorate_at_first(rb_econv_t *ec, const char *decorator_name);

/**
 * Identical to  rb_econv_decorate_at_first(), except  it adds to  the opposite
 * direction.  For  instance CRLF  conversion would  run _after_  encodings are
 * converted.
 *
 * @param[out]  ec              Target converter to decorate.
 * @param[in]   decorator_name  Name of decorator to prepend.
 * @retval      0               Success.
 * @retval      -1              Failure (no such decorator etc.).
 * @post        Decorator works after encoding conversion happens.
 */
int rb_econv_decorate_at_last(rb_econv_t *ec, const char *decorator_name);

/**
 * Creates  a  `rb_eConverterNotFoundError`  exception  object  (but  does  not
 * raise).
 *
 * @param[in]  senc     Name of source encoding.
 * @param[in]  denc     Name of destination encoding.
 * @param[in]  ecflags  A set of enum ::ruby_econv_flag_type.
 * @return     An instance of `rb_eConverterNotFoundError`.
 */
VALUE rb_econv_open_exc(const char *senc, const char *denc, int ecflags);

/**
 * Appends the passed string to the passed converter's output buffer.  This can
 * be  handy  when an  encoding  needs  bytes out  of  thin  air; for  instance
 * ISO-2022-JP  has  "shift   function"  which  does  not   correspond  to  any
 * characters.
 *
 * @param[out]  ec            Target converter.
 * @param[in]   str           String to insert.
 * @param[in]   len           Number of bytes of `str`.
 * @param[in]   str_encoding  Encoding of `str`.
 * @retval      0             Success.
 * @retval      -1            Failure (conversion error etc.).
 * @note        `str_encoding` can  be anything, and `str`  itself is converted
 *              when necessary.
 */
int rb_econv_insert_output(rb_econv_t *ec,
    const unsigned char *str, size_t len, const char *str_encoding);

/**
 * Queries  an encoding  name which  best suits  for rb_econv_insert_output()'s
 * last parameter.  Strings in this  encoding need no conversion when inserted;
 * can be both time/space efficient.
 *
 * @param[in]  ec  Target converter.
 * @return     Its encoding for insertion.
 */
const char *rb_econv_encoding_to_insert_output(rb_econv_t *ec);

/**
 * This is a rb_econv_make_exception() + rb_exc_raise() combo.
 *
 * @param[in]  ec                            (Possibly failed) conversion.
 * @exception  rb_eInvalidByteSequenceError  Invalid byte sequence.
 * @exception  rb_eUndefinedConversionError  Conversion undefined.
 * @note       This function can return when no error.
 */
void rb_econv_check_error(rb_econv_t *ec);

/**
 * This function makes sense right after rb_econv_convert() returns.  As listed
 * in ::rb_econv_result_t, rb_econv_convert() can bail out for various reasons.
 * This function checks the passed converter's internal state and convert it to
 * an appropriate exception object.
 *
 * @param[in]  ec         Target converter.
 * @retval     RUBY_Qnil  The converter has no error.
 * @retval     otherwise  Conversion error turned into an exception.
 */
VALUE rb_econv_make_exception(rb_econv_t *ec);

/**
 * Queries  if rb_econv_putback()  makes  sense, i.e.  there  are invalid  byte
 * sequences remain in the buffer.
 *
 * @param[in]  ec  Target converter.
 * @return     Number of bytes that can be pushed back.
 */
int rb_econv_putbackable(rb_econv_t *ec);

/**
 * Puts  back the  bytes.  In  case of  ::econv_invalid_byte_sequence, some  of
 * those  invalid  bytes are  discarded  and  the  others  are buffered  to  be
 * converted later.  The latter bytes can be put back using this API.
 *
 * @param[out]  ec  Target converter (invalid byte sequence).
 * @param[out]  p   Return buffer.
 * @param[in]   n   Max number of bytes to put back.
 * @post        At most `n` bytes of what was put back is written to `p`.
 */
void rb_econv_putback(rb_econv_t *ec, unsigned char *p, int n);

/**
 * Queries the passed encoding's corresponding ASCII compatible encoding.  "The
 * corresponding  ASCII  compatible  encoding"  in this  context  is  an  ASCII
 * compatible encoding which  can represent exactly the same  character sets as
 * the given  ASCII incompatible  encoding.  For instance  that of  UTF-16LE is
 * UTF-8.
 *
 * @param[in]  encname    Name of an ASCII incompatible encoding.
 * @retval     NULL       `encname` is already ASCII compatible.
 * @retval     otherwise  The corresponding ASCII compatible encoding.
 */
const char *rb_econv_asciicompat_encoding(const char *encname);

/**
 * Identical to  rb_econv_convert(), except it  takes Ruby's string  instead of
 * C's pointer.
 *
 * @param[in,out]  ec                            Target converter.
 * @param[in]      src                           Source string.
 * @param[in]      flags                         Flags (see rb_econv_convert).
 * @exception      rb_eArgError                  Converted string is too long.
 * @exception      rb_eInvalidByteSequenceError  Invalid byte sequence.
 * @exception      rb_eUndefinedConversionError  Conversion undefined.
 * @return         The conversion result.
 */
VALUE rb_econv_str_convert(rb_econv_t *ec, VALUE src, int flags);

/**
 * Identical to rb_econv_str_convert(),  except it converts only a  part of the
 * passed string.  Can be handy when  you for instance want to do line-buffered
 * conversion.
 *
 * @param[in,out]  ec                            Target converter.
 * @param[in]      src                           Source string.
 * @param[in]      byteoff                       Number of bytes to seek.
 * @param[in]      bytesize                      Number of bytes to read.
 * @param[in]      flags                         Flags (see rb_econv_convert).
 * @exception      rb_eArgError                  Converted string is too long.
 * @exception      rb_eInvalidByteSequenceError  Invalid byte sequence.
 * @exception      rb_eUndefinedConversionError  Conversion undefined.
 * @return         The conversion result.
 */
VALUE rb_econv_substr_convert(rb_econv_t *ec, VALUE src, long byteoff, long bytesize, int flags);

/**
 * Identical to rb_econv_str_convert(), except it appends the conversion result
 * to the additionally passed string instead  of creating a new string.  It can
 * also be seen as a routine  identical to rb_econv_append(), except it takes a
 * Ruby's string instead of C's pointer.
 *
 * @param[in,out]  ec                            Target converter.
 * @param[in]      src                           Source string.
 * @param[in]      dst                           Return buffer.
 * @param[in]      flags                         Flags (see rb_econv_convert).
 * @exception      rb_eArgError                  Converted string is too long.
 * @exception      rb_eInvalidByteSequenceError  Invalid byte sequence.
 * @exception      rb_eUndefinedConversionError  Conversion undefined.
 * @return         The conversion result.
 */
VALUE rb_econv_str_append(rb_econv_t *ec, VALUE src, VALUE dst, int flags);

/**
 * Identical to  rb_econv_str_append(), except  it appends only  a part  of the
 * passed string with  conversion.  It can also be seen  as a routine identical
 * to rb_econv_substr_convert(), except it appends the conversion result to the
 * additionally passed string instead of creating a new string.
 *
 * @param[in,out]  ec                            Target converter.
 * @param[in]      src                           Source string.
 * @param[in]      byteoff                       Number of bytes to seek.
 * @param[in]      bytesize                      Number of bytes to read.
 * @param[in]      dst                           Return buffer.
 * @param[in]      flags                         Flags (see rb_econv_convert).
 * @exception      rb_eArgError                  Converted string is too long.
 * @exception      rb_eInvalidByteSequenceError  Invalid byte sequence.
 * @exception      rb_eUndefinedConversionError  Conversion undefined.
 * @return         The conversion result.
 */
VALUE rb_econv_substr_append(rb_econv_t *ec, VALUE src, long byteoff, long bytesize, VALUE dst, int flags);

/**
 * Converts  the passed  C's pointer  according to  the passed  converter, then
 * append the conversion  result to the passed Ruby's string.   This way buffer
 * overflow is properly avoided to resize the destination properly.
 *
 * @param[in,out]  ec                            Target converter.
 * @param[in]      bytesrc                       Target string.
 * @param[in]      bytesize                      Number of bytes of `bytesrc`.
 * @param[in]      dst                           Return buffer.
 * @param[in]      flags                         Flags (see rb_econv_convert).
 * @exception      rb_eArgError                  Converted string is too long.
 * @exception      rb_eInvalidByteSequenceError  Invalid byte sequence.
 * @exception      rb_eUndefinedConversionError  Conversion undefined.
 * @return         The conversion result.
 */
VALUE rb_econv_append(rb_econv_t *ec, const char *bytesrc, long bytesize, VALUE dst, int flags);

/**
 * This badly named  function does not set the destination  encoding to binary,
 * but  instead just  nullifies newline  conversion decorators  if any.   Other
 * ordinal character conversions still  happen after this; something non-binary
 * would still be generated.
 *
 * @param[out]  ec  Target converter to modify.
 * @post        Any newline conversions, if any, would be killed.
 */
void rb_econv_binmode(rb_econv_t *ec);

/**
 * This enum is kind of omnibus.  Gathers various constants.
 */
enum ruby_econv_flag_type {

    /**
     * @name Flags for rb_econv_open()
     *
     * @{
     */

    /** Mask for error handling related bits. */
    RUBY_ECONV_ERROR_HANDLER_MASK               = 0x000000ff,

    /** Special handling of invalid sequences are there. */
    RUBY_ECONV_INVALID_MASK                     = 0x0000000f,

    /** Invalid sequences shall be replaced. */
    RUBY_ECONV_INVALID_REPLACE                  = 0x00000002,

    /** Special handling of undefined conversion are there. */
    RUBY_ECONV_UNDEF_MASK                       = 0x000000f0,

    /** Undefined characters shall be replaced. */
    RUBY_ECONV_UNDEF_REPLACE                    = 0x00000020,

    /** Undefined characters shall be escaped. */
    RUBY_ECONV_UNDEF_HEX_CHARREF                = 0x00000030,

    /** Decorators are there. */
    RUBY_ECONV_DECORATOR_MASK                   = 0x0001ff00,

    /** Newline converters are there. */
    RUBY_ECONV_NEWLINE_DECORATOR_MASK           = 0x00007f00,

    /** (Unclear; seems unused). */
    RUBY_ECONV_NEWLINE_DECORATOR_READ_MASK      = 0x00000f00,

    /** (Unclear; seems unused). */
    RUBY_ECONV_NEWLINE_DECORATOR_WRITE_MASK     = 0x00007000,

    /** Universal newline mode. */
    RUBY_ECONV_UNIVERSAL_NEWLINE_DECORATOR      = 0x00000100,

    /** CR to CRLF conversion shall happen. */
    RUBY_ECONV_CRLF_NEWLINE_DECORATOR           = 0x00001000,

    /** CRLF to CR conversion shall happen. */
    RUBY_ECONV_CR_NEWLINE_DECORATOR             = 0x00002000,

    /** CRLF to LF conversion shall happen. */
    RUBY_ECONV_LF_NEWLINE_DECORATOR             = 0x00004000,

    /** Texts shall be XML-escaped. */
    RUBY_ECONV_XML_TEXT_DECORATOR               = 0x00008000,

    /** Texts shall be AttrValue escaped */
    RUBY_ECONV_XML_ATTR_CONTENT_DECORATOR       = 0x00010000,

    /** (Unclear; seems unused). */
    RUBY_ECONV_STATEFUL_DECORATOR_MASK          = 0x00f00000,

    /** Texts shall be AttrValue escaped. */
    RUBY_ECONV_XML_ATTR_QUOTE_DECORATOR         = 0x00100000,

    /** Newline decorator's default. */
    RUBY_ECONV_DEFAULT_NEWLINE_DECORATOR        =
#if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
        RUBY_ECONV_CRLF_NEWLINE_DECORATOR,
#else
        0,
#endif

#define ECONV_ERROR_HANDLER_MASK                RUBY_ECONV_ERROR_HANDLER_MASK           /**< @old{RUBY_ECONV_ERROR_HANDLER_MASK} */
#define ECONV_INVALID_MASK                      RUBY_ECONV_INVALID_MASK                 /**< @old{RUBY_ECONV_INVALID_MASK} */
#define ECONV_INVALID_REPLACE                   RUBY_ECONV_INVALID_REPLACE              /**< @old{RUBY_ECONV_INVALID_REPLACE} */
#define ECONV_UNDEF_MASK                        RUBY_ECONV_UNDEF_MASK                   /**< @old{RUBY_ECONV_UNDEF_MASK} */
#define ECONV_UNDEF_REPLACE                     RUBY_ECONV_UNDEF_REPLACE                /**< @old{RUBY_ECONV_UNDEF_REPLACE} */
#define ECONV_UNDEF_HEX_CHARREF                 RUBY_ECONV_UNDEF_HEX_CHARREF            /**< @old{RUBY_ECONV_UNDEF_HEX_CHARREF} */
#define ECONV_DECORATOR_MASK                    RUBY_ECONV_DECORATOR_MASK               /**< @old{RUBY_ECONV_DECORATOR_MASK} */
#define ECONV_NEWLINE_DECORATOR_MASK            RUBY_ECONV_NEWLINE_DECORATOR_MASK       /**< @old{RUBY_ECONV_NEWLINE_DECORATOR_MASK} */
#define ECONV_NEWLINE_DECORATOR_READ_MASK       RUBY_ECONV_NEWLINE_DECORATOR_READ_MASK  /**< @old{RUBY_ECONV_NEWLINE_DECORATOR_READ_MASK} */
#define ECONV_NEWLINE_DECORATOR_WRITE_MASK      RUBY_ECONV_NEWLINE_DECORATOR_WRITE_MASK /**< @old{RUBY_ECONV_NEWLINE_DECORATOR_WRITE_MASK} */
#define ECONV_UNIVERSAL_NEWLINE_DECORATOR       RUBY_ECONV_UNIVERSAL_NEWLINE_DECORATOR  /**< @old{RUBY_ECONV_UNIVERSAL_NEWLINE_DECORATOR} */
#define ECONV_CRLF_NEWLINE_DECORATOR            RUBY_ECONV_CRLF_NEWLINE_DECORATOR       /**< @old{RUBY_ECONV_CRLF_NEWLINE_DECORATOR} */
#define ECONV_CR_NEWLINE_DECORATOR              RUBY_ECONV_CR_NEWLINE_DECORATOR         /**< @old{RUBY_ECONV_CR_NEWLINE_DECORATOR} */
#define ECONV_LF_NEWLINE_DECORATOR              RUBY_ECONV_LF_NEWLINE_DECORATOR         /**< @old{RUBY_ECONV_LF_NEWLINE_DECORATOR} */
#define ECONV_XML_TEXT_DECORATOR                RUBY_ECONV_XML_TEXT_DECORATOR           /**< @old{RUBY_ECONV_XML_TEXT_DECORATOR} */
#define ECONV_XML_ATTR_CONTENT_DECORATOR        RUBY_ECONV_XML_ATTR_CONTENT_DECORATOR   /**< @old{RUBY_ECONV_XML_ATTR_CONTENT_DECORATOR} */
#define ECONV_STATEFUL_DECORATOR_MASK           RUBY_ECONV_STATEFUL_DECORATOR_MASK      /**< @old{RUBY_ECONV_STATEFUL_DECORATOR_MASK} */
#define ECONV_XML_ATTR_QUOTE_DECORATOR          RUBY_ECONV_XML_ATTR_QUOTE_DECORATOR     /**< @old{RUBY_ECONV_XML_ATTR_QUOTE_DECORATOR} */
#define ECONV_DEFAULT_NEWLINE_DECORATOR         RUBY_ECONV_DEFAULT_NEWLINE_DECORATOR    /**< @old{RUBY_ECONV_DEFAULT_NEWLINE_DECORATOR} */
    /** @} */

    /**
     * @name Flags for rb_econv_convert()
     *
     * @{
     */

    /** Indicates the input is a part of much larger one. */
    RUBY_ECONV_PARTIAL_INPUT                    = 0x00020000,

    /** Instructs the converter to stop after output. */
    RUBY_ECONV_AFTER_OUTPUT                     = 0x00040000,
#define ECONV_PARTIAL_INPUT                     RUBY_ECONV_PARTIAL_INPUT /**< @old{RUBY_ECONV_PARTIAL_INPUT} */
#define ECONV_AFTER_OUTPUT                      RUBY_ECONV_AFTER_OUTPUT  /**< @old{RUBY_ECONV_AFTER_OUTPUT} */

    RUBY_ECONV_FLAGS_PLACEHOLDER /**< Placeholder (not used) */
};

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RUBY_INTERNAL_ENCODING_TRANSCODE_H */
ruby/internal/encoding/re.h000064400000004356151732674160011732 0ustar00#ifndef RUBY_INTERNAL_ENCODING_RE_H                  /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_INTERNAL_ENCODING_RE_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Routines to manipulate encodings of symbols.
 */

#include "ruby/internal/dllexport.h"
#include "ruby/internal/encoding/encoding.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/**
 * Identical to rb_reg_new(), except it additionally takes an encoding.
 *
 * @param[in]  ptr              A memory region of `len` bytes length.
 * @param[in]  len              Length of  `ptr`, in  bytes, not  including the
 *                              terminating NUL character.
 * @param[in]  enc              Encoding of `ptr`.
 * @param[in]  opts             Options e.g. ONIG_OPTION_MULTILINE.
 * @exception  rb_eRegexpError  Failed to compile `ptr`.
 * @return     An allocated  new instance  of ::rb_cRegexp, of  `enc` encoding,
 *             whose expression is compiled according to `ptr`.
 */
VALUE rb_enc_reg_new(const char *ptr, long len, rb_encoding *enc, int opts);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RUBY_INTERNAL_ENCODING_RE_H */
ruby/internal/encoding/coderange.h000064400000017616151732674160013256 0ustar00#ifndef RUBY_INTERNAL_ENCODING_CODERANGE_H           /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_INTERNAL_ENCODING_CODERANGE_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Routines for code ranges.
 */

#include "ruby/internal/attr/const.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/fl_type.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/** What rb_enc_str_coderange() returns. */
enum ruby_coderange_type {

    /** The object's coderange is unclear yet. */
    RUBY_ENC_CODERANGE_UNKNOWN  = 0,

    /** The object holds 0 to 127 inclusive and nothing else. */
    RUBY_ENC_CODERANGE_7BIT     = ((int)RUBY_FL_USER8),

    /** The object's encoding and contents are consistent each other */
    RUBY_ENC_CODERANGE_VALID    = ((int)RUBY_FL_USER9),

    /** The object holds invalid/malformed/broken character(s). */
    RUBY_ENC_CODERANGE_BROKEN   = ((int)(RUBY_FL_USER8|RUBY_FL_USER9)),

    /** Where the coderange resides. */
    RUBY_ENC_CODERANGE_MASK     = (RUBY_ENC_CODERANGE_7BIT|
                                   RUBY_ENC_CODERANGE_VALID|
                                   RUBY_ENC_CODERANGE_BROKEN)
};

RBIMPL_ATTR_CONST()
/**
 * @private
 *
 * This is an implementation detail of #RB_ENC_CODERANGE_CLEAN_P.  People don't
 * use it directly.
 *
 * @param[in]  cr  An enum ::ruby_coderange_type.
 * @retval     1   It is.
 * @retval     0   It isn't.
 */
static inline int
rb_enc_coderange_clean_p(int cr)
{
    return (cr ^ (cr >> 1)) & RUBY_ENC_CODERANGE_7BIT;
}

RBIMPL_ATTR_CONST()
/**
 * Queries if  a code range  is "clean".  "Clean" in  this context means  it is
 * known and valid.
 *
 * @param[in]  cr  An enum ::ruby_coderange_type.
 * @retval     1   It is.
 * @retval     0   It isn't.
 */
static inline bool
RB_ENC_CODERANGE_CLEAN_P(enum ruby_coderange_type cr)
{
    return rb_enc_coderange_clean_p(cr);
}

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
/**
 * Queries the  (inline) code range of  the passed object.  The  object must be
 * capable  of   having  inline   encoding.   Using   this  macro   needs  deep
 * understanding of bit level object binary layout.
 *
 * @param[in]  obj  Target object.
 * @return     An enum ::ruby_coderange_type.
 */
static inline enum ruby_coderange_type
RB_ENC_CODERANGE(VALUE obj)
{
    VALUE ret = RB_FL_TEST_RAW(obj, RUBY_ENC_CODERANGE_MASK);

    return RBIMPL_CAST((enum ruby_coderange_type)ret);
}

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
/**
 * Queries   the    (inline)   code   range    of   the   passed    object   is
 * ::RUBY_ENC_CODERANGE_7BIT.   The object  must  be capable  of having  inline
 * encoding.  Using  this macro  needs deep understanding  of bit  level object
 * binary layout.
 *
 * @param[in]  obj  Target object.
 * @retval     1    It is ascii only.
 * @retval     0    Otherwise (including cases when the range is not known).
 */
static inline bool
RB_ENC_CODERANGE_ASCIIONLY(VALUE obj)
{
    return RB_ENC_CODERANGE(obj) == RUBY_ENC_CODERANGE_7BIT;
}

/**
 * Destructively modifies the passed object so  that its (inline) code range is
 * the  passed one.   The object  must be  capable of  having inline  encoding.
 * Using this macro needs deep understanding of bit level object binary layout.
 *
 * @param[out]  obj  Target object.
 * @param[out]  cr   An enum ::ruby_coderange_type.
 * @post        `obj`'s code range is `cr`.
 */
static inline void
RB_ENC_CODERANGE_SET(VALUE obj, enum ruby_coderange_type cr)
{
    RB_FL_UNSET_RAW(obj, RUBY_ENC_CODERANGE_MASK);
    RB_FL_SET_RAW(obj, cr);
}

/**
 * Destructively clears  the passed object's  (inline) code range.   The object
 * must be  capable of  having inline  encoding.  Using  this macro  needs deep
 * understanding of bit level object binary layout.
 *
 * @param[out]  obj  Target object.
 * @post        `obj`'s code range is ::RUBY_ENC_CODERANGE_UNKNOWN.
 */
static inline void
RB_ENC_CODERANGE_CLEAR(VALUE obj)
{
    RB_FL_UNSET_RAW(obj, RUBY_ENC_CODERANGE_MASK);
}

RBIMPL_ATTR_CONST()
/* assumed ASCII compatibility */
/**
 * "Mix"  two code  ranges  into one.   This  is handy  for  instance when  you
 * concatenate two  strings into one.   Consider one of  then is valid  but the
 * other isn't.  The result must be  invalid.  This macro computes that kind of
 * mixture.
 *
 * @param[in]  a  An enum ::ruby_coderange_type.
 * @param[in]  b  Another enum ::ruby_coderange_type.
 * @return     The `a` "and" `b`.
 */
static inline enum ruby_coderange_type
RB_ENC_CODERANGE_AND(enum ruby_coderange_type a, enum ruby_coderange_type b)
{
    if (a == RUBY_ENC_CODERANGE_7BIT) {
        return b;
    }
    else if (a != RUBY_ENC_CODERANGE_VALID) {
        return RUBY_ENC_CODERANGE_UNKNOWN;
    }
    else if (b == RUBY_ENC_CODERANGE_7BIT) {
        return RUBY_ENC_CODERANGE_VALID;
    }
    else {
        return b;
    }
}

#define ENC_CODERANGE_MASK                        RUBY_ENC_CODERANGE_MASK                      /**< @old{RUBY_ENC_CODERANGE_MASK} */
#define ENC_CODERANGE_UNKNOWN                     RUBY_ENC_CODERANGE_UNKNOWN                   /**< @old{RUBY_ENC_CODERANGE_UNKNOWN} */
#define ENC_CODERANGE_7BIT                        RUBY_ENC_CODERANGE_7BIT                      /**< @old{RUBY_ENC_CODERANGE_7BIT} */
#define ENC_CODERANGE_VALID                       RUBY_ENC_CODERANGE_VALID                     /**< @old{RUBY_ENC_CODERANGE_VALID} */
#define ENC_CODERANGE_BROKEN                      RUBY_ENC_CODERANGE_BROKEN                    /**< @old{RUBY_ENC_CODERANGE_BROKEN} */
#define ENC_CODERANGE_CLEAN_P(cr)                 RB_ENC_CODERANGE_CLEAN_P(cr)                 /**< @old{RB_ENC_CODERANGE_CLEAN_P} */
#define ENC_CODERANGE(obj)                        RB_ENC_CODERANGE(obj)                        /**< @old{RB_ENC_CODERANGE} */
#define ENC_CODERANGE_ASCIIONLY(obj)              RB_ENC_CODERANGE_ASCIIONLY(obj)              /**< @old{RB_ENC_CODERANGE_ASCIIONLY} */
#define ENC_CODERANGE_SET(obj,cr)                 RB_ENC_CODERANGE_SET(obj,cr)                 /**< @old{RB_ENC_CODERANGE_SET} */
#define ENC_CODERANGE_CLEAR(obj)                  RB_ENC_CODERANGE_CLEAR(obj)                  /**< @old{RB_ENC_CODERANGE_CLEAR} */
#define ENC_CODERANGE_AND(a, b)                   RB_ENC_CODERANGE_AND(a, b)                   /**< @old{RB_ENC_CODERANGE_AND} */
#define ENCODING_CODERANGE_SET(obj, encindex, cr) RB_ENCODING_CODERANGE_SET(obj, encindex, cr) /**< @old{RB_ENCODING_CODERANGE_SET} */

/** @cond INTERNAL_MACRO */
#define RB_ENC_CODERANGE           RB_ENC_CODERANGE
#define RB_ENC_CODERANGE_AND       RB_ENC_CODERANGE_AND
#define RB_ENC_CODERANGE_ASCIIONLY RB_ENC_CODERANGE_ASCIIONLY
#define RB_ENC_CODERANGE_CLEAN_P   RB_ENC_CODERANGE_CLEAN_P
#define RB_ENC_CODERANGE_CLEAR     RB_ENC_CODERANGE_CLEAR
#define RB_ENC_CODERANGE_SET       RB_ENC_CODERANGE_SET
/** @endcond */

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RUBY_INTERNAL_ENCODING_CODERANGE_H */
ruby/internal/encoding/string.h000064400000036371151732674170012635 0ustar00#ifndef RUBY_INTERNAL_ENCODING_STRING_H              /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_INTERNAL_ENCODING_STRING_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Routines to manipulate encodings of strings.
 */

#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/internal/encoding/encoding.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/intern/string.h" /* rbimpl_strlen */

RBIMPL_SYMBOL_EXPORT_BEGIN()

/**
 * Identical to rb_str_new(), except it additionally takes an encoding.
 *
 * @param[in]  ptr             A memory region of `len` bytes length.
 * @param[in]  len             Length  of `ptr`,  in bytes,  not including  the
 *                             terminating NUL character.
 * @param[in]  enc             Encoding of `ptr`.
 * @exception  rb_eNoMemError  Failed to allocate `len+1` bytes.
 * @exception  rb_eArgError    `len` is negative.
 * @return     An instance  of ::rb_cString,  of `len`  bytes length,  of `enc`
 *             encoding, whose contents are verbatim copy of `ptr`.
 * @pre        At  least  `len` bytes  of  continuous  memory region  shall  be
 *             accessible via `ptr`.
 * @note       `enc` can be a  null pointer.  It can also be  seen as a routine
 *             identical to rb_usascii_str_new() then.
 */
VALUE rb_enc_str_new(const char *ptr, long len, rb_encoding *enc);

RBIMPL_ATTR_NONNULL((1))
/**
 * Identical to  rb_enc_str_new(), except  it assumes the  passed pointer  is a
 * pointer  to a  C string.  It can  also  be seen  as a  routine identical  to
 * rb_str_new_cstr(), except it additionally takes an encoding.
 *
 * @param[in]  ptr             A C string.
 * @param[in]  enc             Encoding of `ptr`.
 * @exception  rb_eNoMemError  Failed to allocate memory.
 * @return     An instance  of ::rb_cString, of `enc`  encoding, whose contents
 *             are verbatim copy of `ptr`.
 * @pre        `ptr` must not be a null pointer.
 * @pre        Because `ptr` is  a C string it  makes no sense for  `enc` to be
 *             something like UTF-32.
 * @note       `enc` can be a  null pointer.  It can also be  seen as a routine
 *             identical to rb_usascii_str_new_cstr() then.
 */
VALUE rb_enc_str_new_cstr(const char *ptr, rb_encoding *enc);

/**
 * Identical to rb_enc_str_new(),  except it takes a C string  literal.  It can
 * also  be seen  as  a  routine identical  to  rb_str_new_static(), except  it
 * additionally takes an encoding.
 *
 * @param[in]  ptr           A C string literal.
 * @param[in]  len           `strlen(ptr)`.
 * @param[in]  enc           Encoding of `ptr`.
 * @exception  rb_eArgError  `len` out of range of `size_t`.
 * @pre        `ptr` must be a C string constant.
 * @return     An instance  of ::rb_cString,  of `enc` encoding,  whose backend
 *             storage is the passed C string literal.
 * @warning    It is  a very  bad idea to  write to a  C string  literal (often
 *             immediate  SEGV shall  occur).  Consider  return values  of this
 *             function be read-only.
 * @note       `enc` can be a  null pointer.  It can also be  seen as a routine
 *             identical to rb_usascii_str_new_static() then.
 */
VALUE rb_enc_str_new_static(const char *ptr, long len, rb_encoding *enc);

/**
 * Identical to rb_enc_str_new(),  except it returns a "f"string.   It can also
 * be seen as a routine  identical to rb_interned_str(), except it additionally
 * takes an encoding.
 *
 * @param[in]  ptr           A memory region of `len` bytes length.
 * @param[in]  len           Length  of  `ptr`,  in bytes,  not  including  the
 *                           terminating NUL character.
 * @param[in]  enc           Encoding of `ptr`.
 * @exception  rb_eArgError  `len` is negative.
 * @return     A  found or  created instance  of ::rb_cString,  of `len`  bytes
 *             length, of `enc` encoding, whose  contents are identical to that
 *             of `ptr`.
 * @pre        At  least  `len` bytes  of  continuous  memory region  shall  be
 *             accessible via `ptr`.
 * @note       `enc` can be a null  pointer.
 */
VALUE rb_enc_interned_str(const char *ptr, long len, rb_encoding *enc);

RBIMPL_ATTR_NONNULL((1))
/**
 * Identical to rb_enc_str_new_cstr(),  except it returns a  "f"string.  It can
 * also be  seen as  a routine identical  to rb_interned_str_cstr(),  except it
 * additionally takes an encoding.
 *
 * @param[in]  ptr           A memory region of `len` bytes length.
 * @param[in]  enc           Encoding of `ptr`.
 * @return     A found  or created instance  of ::rb_cString of `enc` encoding,
 *             whose contents are identical to that of `ptr`.
 * @pre        At  least  `len` bytes  of  continuous  memory region  shall  be
 *             accessible via `ptr`.
 * @note       `enc` can be a null  pointer.
 */
VALUE rb_enc_interned_str_cstr(const char *ptr, rb_encoding *enc);

/**
 * Counts  the number  of characters  of the  passed string,  according to  the
 * passed encoding.   This has to be  complicated.  The passed string  could be
 * invalid and/or broken.   This routine would scan from the  beginning til the
 * end, byte by byte, to seek out character boundaries.  Could be super slow.
 *
 * @param[in]  head  Leftmost pointer to the string.
 * @param[in]  tail  Rightmost pointer to the string.
 * @param[in]  enc   Encoding of the string.
 * @return     Number of characters exist in  `head` .. `tail`.  The definition
 *             of "character" depends on the passed `enc`.
 */
long rb_enc_strlen(const char *head, const char *tail, rb_encoding *enc);

/**
 * Queries the n-th character.  Like  rb_enc_strlen() this function can be fast
 * or slow depending on the contents.   Don't expect characters to be uniformly
 * distributed across the entire string.
 *
 * @param[in]  head  Leftmost pointer to the string.
 * @param[in]  tail  Rightmost pointer to the string.
 * @param[in]  nth   Requested index of characters.
 * @param[in]  enc   Encoding of the string.
 * @return     Pointer  to  the first  byte  of  the  character that  is  `nth`
 *             character  ahead  of `head`,  or  `tail`  if  there is  no  such
 *             character (OOB  etc).  The definition of  "character" depends on
 *             the passed `enc`.
 */
char *rb_enc_nth(const char *head, const char *tail, long nth, rb_encoding *enc);

/**
 * Identical to rb_enc_get_index(), except the return type.
 *
 * @param[in]  obj            Object in question.
 * @exception  rb_eTypeError  `obj` is incapable of having an encoding.
 * @return     `obj`'s encoding.
 */
VALUE rb_obj_encoding(VALUE obj);

/**
 * Identical to rb_str_cat(), except it additionally takes an encoding.
 *
 * @param[out]  str                 Destination object.
 * @param[in]   ptr                 Contents to append.
 * @param[in]   len                 Length of `src`, in bytes.
 * @param[in]   enc                 Encoding of `ptr`.
 * @exception   rb_eArgError        `len` is negative.
 * @exception   rb_eEncCompatError  `enc` is not compatible with `str`.
 * @return      The passed `dst`.
 * @post        The  contents  of  `ptr`  is copied,  transcoded  into  `dst`'s
 *              encoding, then pasted into `dst`'s end.
 */
VALUE rb_enc_str_buf_cat(VALUE str, const char *ptr, long len, rb_encoding *enc);

/**
 * Encodes the passed code point into a series of bytes.
 *
 * @param[in]  code             Code point.
 * @param[in]  enc              Target encoding scheme.
 * @exception  rb_eRangeError  `enc` does not glean `code`.
 * @return     An  instance  of ::rb_cString,  of  `enc`  encoding, whose  sole
 *             contents is `code` represented in `enc`.
 * @note       No way to encode code points bigger than UINT_MAX.
 *
 * @internal
 *
 * In  other languages,  APIs like  this  one could  be seen  as the  primitive
 * routines where encodings' "encode" feature are implemented.  However in case
 * of  Ruby this  is not  the primitive  one.  We  directly manipulate  encoded
 * strings.  Encoding conversion routines  transcode an encoded string directly
 * to another one; not via a code point array.
 */
VALUE rb_enc_uint_chr(unsigned int code, rb_encoding *enc);

/**
 * Identical  to   rb_external_str_new(),  except  it  additionally   takes  an
 * encoding.  However the  whole point of rb_external_str_new() is  to encode a
 * string  into default  external encoding.   Being able  to specify  arbitrary
 * encoding just ruins the designed purpose the function meseems.
 *
 * @param[in]  ptr           A memory region of `len` bytes length.
 * @param[in]  len           Length  of  `ptr`,  in bytes,  not  including  the
 *                           terminating NUL character.
 * @param[in]  enc           Target encoding scheme.
 * @exception  rb_eArgError  `len` is negative.
 * @return     An instance  of ::rb_cString.  In case  encoding conversion from
 *             "default  internal" to  `enc` is  fully defined  over the  given
 *             contents, then the  return value is a string  of `enc` encoding,
 *             whose contents are the converted  ones.  Otherwise the string is
 *             a junk.
 * @warning    It doesn't raise on a conversion failure and silently ends up in
 *             a  corrupted  output.  You  can  know  the failure  by  querying
 *             `valid_encoding?` of the result object.
 *
 * @internal
 *
 * @shyouhei has  no idea why  this one does  not follow the  naming convention
 * that  others obey.   It  seems to  him  that this  should  have been  called
 * `rb_enc_external_str_new`.
 */
VALUE rb_external_str_new_with_enc(const char *ptr, long len, rb_encoding *enc);

/**
 * Identical to rb_str_export(), except it additionally takes an encoding.
 *
 * @param[in]  obj            Target object.
 * @param[in]  enc            Target encoding.
 * @exception  rb_eTypeError  No implicit conversion to String.
 * @return     Converted ruby string of `enc` encoding.
 */
VALUE rb_str_export_to_enc(VALUE obj, rb_encoding *enc);

/**
 * Encoding conversion main routine.
 *
 * @param[in]  str   String to convert.
 * @param[in]  from  Source encoding.
 * @param[in]  to    Destination encoding.
 * @return     A copy of `str`, with conversion from `from` to `to` applied.
 * @note       `from` can be a null pointer.  `str`'s encoding is taken then.
 * @note       `to` can be a null pointer.  No-op then.
 */
VALUE rb_str_conv_enc(VALUE str, rb_encoding *from, rb_encoding *to);

/**
 * Identical  to rb_str_conv_enc(),  except  it additionally  takes IO  encoder
 * options.  The extra arguments  can be constructed using io_extract_modeenc()
 * etc.
 *
 * @param[in]  str      String to convert.
 * @param[in]  from     Source encoding.
 * @param[in]  to       Destination encoding.
 * @param[in]  ecflags  A set of enum ::ruby_econv_flag_type.
 * @param[in]  ecopts   Optional hash.
 * @return     A copy of `str`, with conversion from `from` to `to` applied.
 * @note       `from` can be a null pointer.  `str`'s encoding is taken then.
 * @note       `to` can be a null pointer.  No-op then.
 * @note       `ecopts` can be  ::RUBY_Qnil, which is equivalent  to passing an
 *             empty hash.
 */
VALUE rb_str_conv_enc_opts(VALUE str, rb_encoding *from, rb_encoding *to, int ecflags, VALUE ecopts);

/**
 * Scans the passed string to collect  its code range.  Because a Ruby's string
 * is mutable, its contents  change from time to time; so  does its code range.
 * A  long-lived string  tends  to fall  back to  ::RUBY_ENC_CODERANGE_UNKNOWN.
 * This API scans it and re-assigns a fine-grained code range constant.
 *
 * @param[out]  str  A string.
 * @return      An enum ::ruby_coderange_type.
 */
int rb_enc_str_coderange(VALUE str);

/**
 * Scans the passed string until it finds something odd.  Returns the number of
 * bytes scanned.  As the name implies this is suitable for repeated call.  One
 * of its application is `IO#readlines`.   The method reads from its receiver's
 * read buffer, maybe more than once,  looking for newlines.  But "newline" can
 * be different among encodings.  This API is used to detect broken contents to
 * properly mark them as such.
 *
 * @param[in]   str  String to scan.
 * @param[in]   end  End of `str`.
 * @param[in]   enc  `str`'s encoding.
 * @param[out]  cr   Return buffer.
 * @return      Distance between `str` and first such byte where broken.
 * @post        `cr` has the code range type.
 */
long rb_str_coderange_scan_restartable(const char *str, const char *end, rb_encoding *enc, int *cr);

/**
 * Queries if  the passed string  is "ASCII only".  An  ASCII only string  is a
 * string  who doesn't  have any  non-ASCII  characters at  all.  This  doesn't
 * necessarily mean the string is in  ASCII encoding.  For instance a String of
 * CP932 encoding can quite much be ASCII only, depending on its contents.
 *
 * @param[in]  str  String in question.
 * @retval     1    It doesn't have non-ASCII characters.
 * @retval     0    It has characters that are out of ASCII.
 */
int rb_enc_str_asciionly_p(VALUE str);

RBIMPL_ATTR_NONNULL(())
/**
 * Looks for the passed string in the passed buffer.
 *
 * @param[in]  x          Query string.
 * @param[in]  m          Number of bytes of `x`.
 * @param[in]  y          Buffer that potentially includes `x`.
 * @param[in]  n          Number of bytes of `y`.
 * @param[in]  enc        Encoding of both `x` and `y`.
 * @retval     -1         Not found.
 * @retval     otherwise  Found index in `y`.
 * @note       This API can match at a non-character-boundary.
 */
long rb_memsearch(const void *x, long m, const void *y, long n, rb_encoding *enc);

/** @cond INTERNAL_MACRO */
RBIMPL_ATTR_NONNULL(())
static inline VALUE
rbimpl_enc_str_new_cstr(const char *str, rb_encoding *enc)
{
    long len = rbimpl_strlen(str);

    return rb_enc_str_new_static(str, len, enc);
}

#define rb_enc_str_new(str, len, enc)           \
    ((RBIMPL_CONSTANT_P(str) &&                 \
      RBIMPL_CONSTANT_P(len) ?                  \
      rb_enc_str_new_static:                    \
      rb_enc_str_new) ((str), (len), (enc)))

#define rb_enc_str_new_cstr(str, enc)           \
    ((RBIMPL_CONSTANT_P(str)  ?                 \
      rbimpl_enc_str_new_cstr :                 \
      rb_enc_str_new_cstr) ((str), (enc)))

/** @endcond */

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RUBY_INTERNAL_ENCODING_STRING_H */
ruby/internal/encoding/encoding.h000064400000107640151732674170013113 0ustar00#ifndef RUBY_INTERNAL_ENCODING_ENCODING_H            /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_INTERNAL_ENCODING_ENCODING_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines ::rb_encoding
 */

#include "ruby/oniguruma.h"
#include "ruby/internal/attr/const.h"
#include "ruby/internal/attr/deprecated.h"
#include "ruby/internal/attr/noalias.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/attr/returns_nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/encoding/coderange.h"
#include "ruby/internal/value.h"
#include "ruby/internal/core/rbasic.h"
#include "ruby/internal/fl_type.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/**
 * `Encoding` class.
 *
 * @ingroup object
 */
RUBY_EXTERN VALUE rb_cEncoding;

/**
 * @private
 *
 * Bit constants used when embedding encodings into ::RBasic::flags.  Extension
 * libraries must not bother such things.
 */
enum ruby_encoding_consts {

    /** Max possible number of embeddable encodings. */
    RUBY_ENCODING_INLINE_MAX = 127,

    /** Where inline encodings reside. */
    RUBY_ENCODING_SHIFT = (RUBY_FL_USHIFT+10),

    /** Bits we use to store inline encodings. */
    RUBY_ENCODING_MASK = (RUBY_ENCODING_INLINE_MAX<<RUBY_ENCODING_SHIFT
                          /* RUBY_FL_USER10..RUBY_FL_USER16 */),

    /** Max possible length of an encoding name. */
    RUBY_ENCODING_MAXNAMELEN = 42
};

#define ENCODING_INLINE_MAX RUBY_ENCODING_INLINE_MAX /**< @old{RUBY_ENCODING_INLINE_MAX} */
#define ENCODING_SHIFT RUBY_ENCODING_SHIFT           /**< @old{RUBY_ENCODING_SHIFT} */
#define ENCODING_MASK RUBY_ENCODING_MASK             /**< @old{RUBY_ENCODING_MASK} */

/**
 * Destructively assigns the passed encoding  to the passed object.  The object
 * must be  capable of  having inline  encoding.  Using  this macro  needs deep
 * understanding of bit level object binary layout.
 *
 * @param[out]  obj      Target object to modify.
 * @param[in]   ecindex  Encoding in encindex format.
 * @post        `obj`'s encoding is `encindex`.
 */
static inline void
RB_ENCODING_SET_INLINED(VALUE obj, int encindex)
{
    VALUE f = /* upcast */ RBIMPL_CAST((VALUE)encindex);

    f <<= RUBY_ENCODING_SHIFT;
    RB_FL_UNSET_RAW(obj, RUBY_ENCODING_MASK);
    RB_FL_SET_RAW(obj, f);
}

/**
 * Queries the  encoding of the  passed object.   The encoding must  be smaller
 * than ::RUBY_ENCODING_INLINE_MAX, which means you have some assumption on the
 * return value.  This means the API is for internal use only.
 *
 * @param[in]  obj  Target object.
 * @return     `obj`'s encoding index.
 */
static inline int
RB_ENCODING_GET_INLINED(VALUE obj)
{
    VALUE ret = RB_FL_TEST_RAW(obj, RUBY_ENCODING_MASK) >> RUBY_ENCODING_SHIFT;

    return RBIMPL_CAST((int)ret);
}

#define ENCODING_SET_INLINED(obj,i) RB_ENCODING_SET_INLINED(obj,i) /**< @old{RB_ENCODING_SET_INLINED} */
#define ENCODING_SET(obj,i) RB_ENCODING_SET(obj,i)                 /**< @old{RB_ENCODING_SET} */
#define ENCODING_GET_INLINED(obj) RB_ENCODING_GET_INLINED(obj)     /**< @old{RB_ENCODING_GET_INLINED} */
#define ENCODING_GET(obj) RB_ENCODING_GET(obj)                     /**< @old{RB_ENCODING_GET} */
#define ENCODING_IS_ASCII8BIT(obj) RB_ENCODING_IS_ASCII8BIT(obj)   /**< @old{RB_ENCODING_IS_ASCII8BIT} */
#define ENCODING_MAXNAMELEN RUBY_ENCODING_MAXNAMELEN               /**< @old{RUBY_ENCODING_MAXNAMELEN} */

/**
 * The  type  of encoding.   Our  design  here  is we  take  Oniguruma/Onigmo's
 * multilingualisation schema as our base data structure.
 */
typedef const OnigEncodingType rb_encoding;

RBIMPL_ATTR_NOALIAS()
/**
 * Converts  a character  option  to its  encoding.  It  only  supports a  very
 * limited set  of Japanese encodings due  to its Japanese origin.   Ruby still
 * has this in-core for backwards compatibility.  But new codes must not bother
 * such  concept like  one-character encoding  option.  Consider  deprecated in
 * practice.
 *
 * @param[in]   c       One of `['n', 'e', 's', 'u', 'i', 'x', 'm']`.
 * @param[out]  option  Return buffer.
 * @param[out]  kcode   Return buffer.
 * @retval      1       `c` understood properly.
 * @retval      0       `c` is not understood.
 * @post        `option` is a ::OnigOptionType.
 * @post        `kcode` is an enum `ruby_preserved_encindex`.
 *
 * @internal
 *
 * `kcode`  is opaque  because  `ruby_preserved_encindex` is  not visible  from
 * extension libraries.  But who cares?
 */
int rb_char_to_option_kcode(int c, int *option, int *kcode);

/**
 * Creates a new "dummy" encoding.  Roughly speaking, an encoding is dummy when
 * it is  stateful.  Notable  example of  dummy encoding  are those  defined in
 * ISO/IEC 2022
 *
 * @param[in]  name  Name of the creating encoding.
 * @exception  rb_eArgError  Duplicated or malformed `name`.
 * @return     New dummy encoding's index.
 * @post       Encoding  named `name`  is created,  whose index  is the  return
 *             value.
 */
int rb_define_dummy_encoding(const char *name);

RBIMPL_ATTR_PURE()
/**
 * Queries if the passed encoding is dummy.
 *
 * @param[in]  enc  Encoding in question.
 * @retval     1    It is.
 * @retval     0    It isn't.
 */
int rb_enc_dummy_p(rb_encoding *enc);

RBIMPL_ATTR_PURE()
/**
 * Queries the  index of  the encoding.   An encoding's  index is  a Ruby-local
 * concept.  It is a (sequential) number assigned to each encoding.
 *
 * @param[in]  enc  Encoding in question.
 * @return     Its index.
 * @note       You can pass  null pointers to this function.   It is equivalent
 *             to rb_usascii_encindex() then.
 */
int rb_enc_to_index(rb_encoding *enc);

/**
 * Queries the index of the encoding of the passed object, if any.
 *
 * @param[in]  obj        Object in question.
 * @retval     -1         `obj` is incapable of having an encoding.
 * @retval     otherwise  `obj`'s encoding's index.
 */
int rb_enc_get_index(VALUE obj);

/**
 * @alias{rb_enc_get_index}
 *
 * @internal
 *
 * Implementation wise this is not a verbatim alias of rb_enc_get_index().  But
 * the API is consistent.  Don't bother.
 */
static inline int
RB_ENCODING_GET(VALUE obj)
{
    int encindex = RB_ENCODING_GET_INLINED(obj);

    if (encindex == RUBY_ENCODING_INLINE_MAX) {
        return rb_enc_get_index(obj);
    }
    else {
        return encindex;
    }
}

/**
 * Destructively assigns an encoding (via its index) to an object.
 *
 * @param[out]  obj                Object in question.
 * @param[in]   encindex           An encoding index.
 * @exception   rb_eFrozenError    `obj` is frozen.
 * @exception   rb_eArgError       `obj` is incapable of having an encoding.
 * @exception   rb_eEncodingError  `encindex` is out of bounds.
 * @exception   rb_eLoadError      Failed to load the encoding.
 */
void rb_enc_set_index(VALUE obj, int encindex);

/** @alias{rb_enc_set_index} */
static inline void
RB_ENCODING_SET(VALUE obj, int encindex)
{
    rb_enc_set_index(obj, encindex);
}

/**
 * This is #RB_ENCODING_SET  + RB_ENC_CODERANGE_SET combo.  The  object must be
 * capable  of   having  inline   encoding.   Using   this  macro   needs  deep
 * understanding of bit level object binary layout.
 *
 * @param[out]  obj       Target object.
 * @param[in]   encindex  Encoding in encindex format.
 * @param[in]   cr        An enum ::ruby_coderange_type.
 * @post        `obj`'s encoding is `encindex`.
 * @post        `obj`'s code range is `cr`.
 */
static inline void
RB_ENCODING_CODERANGE_SET(VALUE obj, int encindex, enum ruby_coderange_type cr)
{
    RB_ENCODING_SET(obj, encindex);
    RB_ENC_CODERANGE_SET(obj, cr);
}

RBIMPL_ATTR_PURE()
/**
 * Queries if the passed object can have its encoding.
 *
 * @param[in]  obj  Object in question.
 * @retval     1    It can.
 * @retval     0    It cannot.
 */
int rb_enc_capable(VALUE obj);

/**
 * Queries the index of the encoding.
 *
 * @param[in]  name          Name of the encoding to find.
 * @exception  rb_eArgError  No such encoding named `name`.
 * @retval     -1            `name` exists, but unable to load.
 * @retval     otherwise     Index of encoding named `name`.
 */
int rb_enc_find_index(const char *name);

/**
 * Registers an  "alias" name.  In  the wild, an  encoding can be  called using
 * multiple names.  For instance an encoding  known as `"CP932"` is also called
 * `"SJIS"` on occasions.  This API registers such relationships.
 *
 * @param[in]  alias         New name.
 * @param[in]  orig          Old name.
 * @exception  rb_eArgError  `alias` is duplicated or malformed.
 * @retval     -1            Failed to load `orig`.
 * @retval     otherwise     The index of `orig` and `alias`.
 * @post       `alias` is  a synonym  of `orig`.  They  refer to  the identical
 *             encoding.
 */
int rb_enc_alias(const char *alias, const char *orig);

/**
 * Obtains   a  encoding   index  from   a   wider  range   of  objects   (than
 * rb_enc_find_index()).
 *
 * @param[in]  obj        An ::rb_cEncoding, or its name in ::rb_cString.
 * @retval     -1         `obj` is unexpected type/contents.
 * @retval     otherwise  Index corresponding to `obj`.
 */
int rb_to_encoding_index(VALUE obj);

/**
 * Identical to  rb_find_encoding(), except it  raises an exception  instead of
 * returning NULL.
 *
 * @param[in]  obj            An ::rb_cEncoding, or its name in ::rb_cString.
 * @exception  rb_eTypeError  `obj` is neither ::rb_cEncoding nor ::rb_cString.
 * @exception  rb_eArgError   `obj` is an unknown encoding name.
 * @return     Encoding of `obj`.
 */
rb_encoding *rb_to_encoding(VALUE obj);

/**
 * Identical to rb_to_encoding_index(), except the return type.
 *
 * @param[in]  obj            An ::rb_cEncoding, or its name in ::rb_cString.
 * @exception  rb_eTypeError  `obj` is neither ::rb_cEncoding nor ::rb_cString.
 * @retval     NULL           No such encoding.
 * @return     otherwise      Encoding of `obj`.
 */
rb_encoding *rb_find_encoding(VALUE obj);

/**
 * Identical to rb_enc_get_index(), except the return type.
 *
 * @param[in]  obj        Object in question.
 * @retval     NULL       Obj is incapable of having an encoding.
 * @retval     otherwise  `obj`'s encoding.
 */
rb_encoding *rb_enc_get(VALUE obj);

/**
 * Look for the "common" encoding between the two.  One character can or cannot
 * be expressed depending on an encoding.  This function finds the super-set of
 * encodings that  satisfy contents of  both arguments.  If that  is impossible
 * returns NULL.
 *
 * @param[in]  str1       An object.
 * @param[in]  str2       Another object.
 * @retval     NULL       No encoding can satisfy both at once.
 * @retval     otherwise  Common encoding between the two.
 * @note       Arguments can be non-string, e.g. Regexp.
 */
rb_encoding *rb_enc_compatible(VALUE str1, VALUE str2);

/**
 * Identical to rb_enc_compatible(),  except it raises an  exception instead of
 * returning NULL.
 *
 * @param[in]  str1                An object.
 * @param[in]  str2                Another object.
 * @exception  rb_eEncCompatError  No encoding can satisfy both.
 * @return     Common encoding between the two.
 * @note       Arguments can be non-string, e.g. Regexp.
 */
rb_encoding *rb_enc_check(VALUE str1,VALUE str2);

/**
 * Identical to rb_enc_set_index(), except it additionally does contents fix-up
 * depending on the passed object.  It  for instance changes the byte length of
 * terminating `U+0000` according to the passed encoding.
 *
 * @param[out]  obj                Object in question.
 * @param[in]   encindex           An encoding index.
 * @exception   rb_eFrozenError    `obj` is frozen.
 * @exception   rb_eArgError       `obj` is incapable of having an encoding.
 * @exception   rb_eEncodingError  `encindex` is out of bounds.
 * @exception   rb_eLoadError      Failed to load the encoding.
 * @return      The passed `obj`.
 * @post        `obj`'s contents might be fixed according to `encindex`.
 */
VALUE rb_enc_associate_index(VALUE obj, int encindex);

/**
 * Identical to  rb_enc_associate_index(), except  it takes an  encoding itself
 * instead of its index.
 *
 * @param[out]  obj                Object in question.
 * @param[in]   enc                An encoding.
 * @exception   rb_eFrozenError    `obj` is frozen.
 * @exception   rb_eArgError       `obj` is incapable of having an encoding.
 * @return      The passed `obj`.
 * @post        `obj`'s contents might be fixed according to `enc`.
 */
VALUE rb_enc_associate(VALUE obj, rb_encoding *enc);

/**
 * Destructively copies  the encoding of  the latter  object to that  of former
 * one.     It   can    also   be    seen   as    a   routine    identical   to
 * rb_enc_associate_index(), except it takes an object's encoding instead of an
 * encoding's index.
 *
 * @param[out]  dst                Object to modify.
 * @param[in]   src                Object to reference.
 * @exception   rb_eFrozenError    `dst` is frozen.
 * @exception   rb_eArgError       `dst` is incapable of having an encoding.
 * @exception   rb_eEncodingError  `src` is incapable of having an encoding.
 * @post        `dst`'s encoding is that of `src`'s.
 */
void rb_enc_copy(VALUE dst, VALUE src);


/**
 * Identical to rb_find_encoding(),  except it takes an  encoding index instead
 * of a Ruby object.
 *
 * @param[in]  idx        An encoding index.
 * @retval     NULL       No such encoding.
 * @retval     otherwise  An encoding whose index is `idx`.
 */
rb_encoding *rb_enc_from_index(int idx);

/**
 * Identical to  rb_find_encoding(), except  it takes a  C's string  instead of
 * Ruby's.
 *
 * @param[in]  name       Name of the encoding to query.
 * @retval     NULL       No such encoding.
 * @retval     otherwise  An encoding whose index is `idx`.
 */
rb_encoding *rb_enc_find(const char *name);

/**
 * Queries the (canonical) name of the passed encoding.
 *
 * @param[in]  enc  An encoding.
 * @return     Its name.
 */
static inline const char *
rb_enc_name(rb_encoding *enc)
{
    return enc->name;
}

/**
 * Queries  the minimum  number  of bytes  that the  passed  encoding needs  to
 * represent a character.  For ASCII and compatible encodings this is typically
 * 1.   There  are  however  encodings  whose   minimum  is  not  1;  they  are
 * historically called wide characters.
 *
 * @param[in]  enc  An encoding.
 * @return     Its least possible number of bytes except 0.
 */
static inline int
rb_enc_mbminlen(rb_encoding *enc)
{
    return enc->min_enc_len;
}

/**
 * Queries  the maximum  number  of bytes  that the  passed  encoding needs  to
 * represent a character.   Fixed-width encodings have the same  value for this
 * one  and  #rb_enc_mbminlen.   However there  are  variable-width  encodings.
 * UTF-8, for instance, takes from 1 up to 6 bytes.
 *
 * @param[in]  enc  An encoding.
 * @return     Its maximum possible number of bytes of a character.
 */
static inline int
rb_enc_mbmaxlen(rb_encoding *enc)
{
    return enc->max_enc_len;
}

/**
 * Queries the number of bytes of the character at the passed pointer.
 *
 * @param[in]  p    Pointer to a character's first byte.
 * @param[in]  e    End of the string that has `p`.
 * @param[in]  enc  Encoding of the string.
 * @return     If the character at `p` does  not end until `e`, number of bytes
 *             between `p`  and `e`.   Otherwise the number  of bytes  that the
 *             character at `p` is encoded.
 *
 * @internal
 *
 * Strictly speaking there  are chances when `p`  points to a middle  byte of a
 * wide character.   This function  returns "the  number of  bytes from  `p` to
 * nearest of either `e` or the next character boundary", if you go strict.
 */
int rb_enc_mbclen(const char *p, const char *e, rb_encoding *enc);

/**
 * Identical to rb_enc_mbclen() unless the character at `p` overruns `e`.  That
 * can happen  for instance when  you read from a  socket and its  partial read
 * cuts  a  wide  character  in-between.  In  those  situations  this  function
 * "estimates" theoretical length  of the character in  question.  Typically it
 * tends  to be  possible  to know  how  many bytes  a  character needs  before
 * actually reaching its  end; for instance UTF-8 encodes  a character's length
 * in the first byte of it.  This function returns that info.
 *
 * @note  This implies that the string is not broken.
 *
 * @param[in]  p    Pointer to the character's first byte.
 * @param[in]  e    End of the string that has `p`.
 * @param[in]  enc  Encoding of the string.
 * @return     Number of bytes of character at `p`, measured or estimated.
 */
int rb_enc_fast_mbclen(const char *p, const char *e, rb_encoding *enc);

/**
 * Queries the  number of bytes of  the character at the  passed pointer.  This
 * function returns 3 different types of information:
 *
 * ```CXX
 * auto n = rb_enc_precise_mbclen(p, q, r);
 *
 * if (ONIGENC_MBCLEN_CHARFOUND_P(n)) {
 *     // Character found.  Normal return.
 *     auto found_length = ONIGENC_MBCLEN_CHARFOUND_LEN(n);
 * }
 * else if (ONIGENC_MBCLEN_NEEDMORE_P(n)) {
 *     // Character overruns past `q`; needs more.
 *     auto requested_length = ONIGENC_MBCLEN_NEEDMORE_LEN(n);
 * }
 * else {
 *     // `p` is broken.
 *     assert(ONIGENC_MBCLEN_INVALID_P(n));
 * }
 * ```
 *
 * @param[in]  p    Pointer to the character's first byte.
 * @param[in]  e    End of the string that has `p`.
 * @param[in]  enc  Encoding of the string.
 * @return     Encoded read/needed number of bytes (see above).
 */
int rb_enc_precise_mbclen(const char *p, const char *e, rb_encoding *enc);

#define MBCLEN_CHARFOUND_P(ret)   ONIGENC_MBCLEN_CHARFOUND_P(ret)   /**< @old{ONIGENC_MBCLEN_CHARFOUND_P} */
#define MBCLEN_CHARFOUND_LEN(ret) ONIGENC_MBCLEN_CHARFOUND_LEN(ret) /**< @old{ONIGENC_MBCLEN_CHARFOUND_LEN} */
#define MBCLEN_INVALID_P(ret)     ONIGENC_MBCLEN_INVALID_P(ret)     /**< @old{ONIGENC_MBCLEN_INVALID_P} */
#define MBCLEN_NEEDMORE_P(ret)    ONIGENC_MBCLEN_NEEDMORE_P(ret)    /**< @old{ONIGENC_MBCLEN_NEEDMORE_P} */
#define MBCLEN_NEEDMORE_LEN(ret)  ONIGENC_MBCLEN_NEEDMORE_LEN(ret)  /**< @old{ONIGENC_MBCLEN_NEEDMORE_LEN} */

/**
 * Queries the code point of character  pointed by the passed pointer.  If that
 * code point is included in ASCII  that code point is returned.  Otherwise -1.
 * This can be different from just looking  at the first byte.  For instance it
 * reads 2 bytes in case of UTF-16BE.
 *
 * @param[in]  p          Pointer to the character's first byte.
 * @param[in]  e          End of the string that has `p`.
 * @param[in]  len        Return buffer.
 * @param[in]  enc        Encoding of the string.
 * @retval     -1         The character at `p` is not i ASCII.
 * @retval     otherwise  A code point of the character at `p`.
 * @post       `len` (if set) is the number of bytes of `p`.
 */
int rb_enc_ascget(const char *p, const char *e, int *len, rb_encoding *enc);

/**
 * Queries  the  code  point  of  character  pointed  by  the  passed  pointer.
 * Exceptions happen in case of broken input.
 *
 * @param[in]  p             Pointer to the character's first byte.
 * @param[in]  e             End of the string that has `p`.
 * @param[in]  len           Return buffer.
 * @param[in]  enc           Encoding of the string.
 * @exception  rb_eArgError  `p` is broken.
 * @return     Code point of the character pointed by `p`.
 * @post       `len` (if set) is the number of bytes of `p`.
 */
unsigned int rb_enc_codepoint_len(const char *p, const char *e, int *len, rb_encoding *enc);

/**
 * Queries  the  code  point  of  character  pointed  by  the  passed  pointer.
 * Exceptions happen in case of broken input.
 *
 * @deprecated  Use rb_enc_codepoint_len() instead.
 * @param[in]   p             Pointer to the character's first byte.
 * @param[in]   e             End of the string that has `p`.
 * @param[in]   enc           Encoding of the string.
 * @exception   rb_eArgError  `p` is broken.
 * @return      Code point of the character pointed by `p`.
 *
 * @internal
 *
 * @matz says in commit  91e5ba1cb865a2385d3e1cbfacd824496898e098 that the line
 * below  is a  "prototype for  obsolete function".   However even  today there
 * still are some use  cases of it throughout our repository.   It seems it has
 * its own niche.
 */
static inline unsigned int
rb_enc_codepoint(const char *p, const char *e, rb_encoding *enc)
{
    return rb_enc_codepoint_len(p, e, 0, enc);
    /*                               ^^^
     * This can be `NULL` in C, `nullptr` in C++, and `0` for both.
     * We choose the most portable one here.
     */
}


/**
 * Identical to rb_enc_codepoint(),  except it assumes the  passed character is
 * not broken.
 *
 * @param[in]   p    Pointer to the character's first byte.
 * @param[in]   e    End of the string that has `p`.
 * @param[in]   enc  Encoding of the string.
 * @return      Code point of the character pointed by `p`.
 */
static inline OnigCodePoint
rb_enc_mbc_to_codepoint(const char *p, const char *e, rb_encoding *enc)
{
    const OnigUChar *up = RBIMPL_CAST((const OnigUChar *)p);
    const OnigUChar *ue = RBIMPL_CAST((const OnigUChar *)e);

    return ONIGENC_MBC_TO_CODE(enc, up, ue);
}

/**
 * Queries the  number of bytes  requested to  represent the passed  code point
 * using the passed encoding.
 *
 * @param[in]  code          Code point in question.
 * @param[in]  enc           Encoding to convert the code into a byte sequence.
 * @exception  rb_eArgError  `enc` does not glean `code`.
 * @return     Number of bytes requested to represent `code` using `enc`.
 */
int rb_enc_codelen(int code, rb_encoding *enc);

/**
 * Identical to rb_enc_codelen(), except it returns 0 for invalid code points.
 *
 * @param[in]  c          Code point in question.
 * @param[in]  enc        Encoding to convert `c` into a byte sequence.
 * @retval     0          `c` is invalid.
 * @return     otherwise  Number of bytes needed for `enc` to encode `c`.
 */
static inline int
rb_enc_code_to_mbclen(int c, rb_encoding *enc)
{
    OnigCodePoint uc = RBIMPL_CAST((OnigCodePoint)c);

    return ONIGENC_CODE_TO_MBCLEN(enc, uc);
}

/**
 * Identical to rb_enc_uint_chr(),  except it writes back to  the passed buffer
 * instead of allocating one.
 *
 * @param[in]  c          Code point.
 * @param[out] buf        Return buffer.
 * @param[in]  enc        Target encoding scheme.
 * @retval     <= 0       `c` is invalid in `enc`.
 * @return     otherwise  Number of bytes written to `buf`.
 * @post       `c` is encoded according to `enc`, then written to `buf`.
 *
 * @internal
 *
 * The second argument  must be typed.  But its current  usages prevent us from
 * being any stricter than this. :FIXME:
 */
static inline int
rb_enc_mbcput(unsigned int c, void *buf, rb_encoding *enc)
{
    OnigCodePoint uc = RBIMPL_CAST((OnigCodePoint)c);
    OnigUChar *ubuf = RBIMPL_CAST((OnigUChar *)buf);

    return ONIGENC_CODE_TO_MBC(enc, uc, ubuf);
}

/**
 * Queries the previous (left) character.
 *
 * @param[in]  s          Start of the string.
 * @param[in]  p          Pointer to a character.
 * @param[in]  e          End of the string.
 * @param[in]  enc        Encoding.
 * @retval     NULL       No previous character.
 * @retval     otherwise  Pointer to the head of the previous character.
 */
static inline char *
rb_enc_prev_char(const char *s, const char *p, const char *e, rb_encoding *enc)
{
    const OnigUChar *us = RBIMPL_CAST((const OnigUChar *)s);
    const OnigUChar *up = RBIMPL_CAST((const OnigUChar *)p);
    const OnigUChar *ue = RBIMPL_CAST((const OnigUChar *)e);
    OnigUChar *ur = onigenc_get_prev_char_head(enc, us, up, ue);

    return RBIMPL_CAST((char *)ur);
}

/**
 * Queries the  left boundary of  a character.   This function takes  a pointer
 * that is not necessarily a head of a character, and searches for its head.
 *
 * @param[in]  s          Start of the string.
 * @param[in]  p          Pointer to a possibly-middle of a character.
 * @param[in]  e          End of the string.
 * @param[in]  enc        Encoding.
 * @return     Pointer to the head of the character that contains `p`.
 */
static inline char *
rb_enc_left_char_head(const char *s, const char *p, const char *e, rb_encoding *enc)
{
    const OnigUChar *us = RBIMPL_CAST((const OnigUChar *)s);
    const OnigUChar *up = RBIMPL_CAST((const OnigUChar *)p);
    const OnigUChar *ue = RBIMPL_CAST((const OnigUChar *)e);
    OnigUChar *ur = onigenc_get_left_adjust_char_head(enc, us, up, ue);

    return RBIMPL_CAST((char *)ur);
}

/**
 * Queries the  right boundary of a  character.  This function takes  a pointer
 * that is not necessarily a head of a character, and searches for its tail.
 *
 * @param[in]  s    Start of the string.
 * @param[in]  p    Pointer to a possibly-middle of a character.
 * @param[in]  e    End of the string.
 * @param[in]  enc  Encoding.
 * @return     Pointer to the end of the character that contains `p`.
 */
static inline char *
rb_enc_right_char_head(const char *s, const char *p, const char *e, rb_encoding *enc)
{
    const OnigUChar *us = RBIMPL_CAST((const OnigUChar *)s);
    const OnigUChar *up = RBIMPL_CAST((const OnigUChar *)p);
    const OnigUChar *ue = RBIMPL_CAST((const OnigUChar *)e);
    OnigUChar *ur = onigenc_get_right_adjust_char_head(enc, us, up, ue);

    return RBIMPL_CAST((char *)ur);
}

/**
 * Scans the string backwards for n characters.
 *
 * @param[in]  s          Start of the string.
 * @param[in]  p          Pointer to a character.
 * @param[in]  e          End of the string.
 * @param[in]  n          Steps.
 * @param[in]  enc        Encoding.
 * @retval     NULL       There are no `n` characters left.
 * @retval     otherwise  Pointer to `n` character before `p`.
 */
static inline char *
rb_enc_step_back(const char *s, const char *p, const char *e, int n, rb_encoding *enc)
{
    const OnigUChar *us = RBIMPL_CAST((const OnigUChar *)s);
    const OnigUChar *up = RBIMPL_CAST((const OnigUChar *)p);
    const OnigUChar *ue = RBIMPL_CAST((const OnigUChar *)e);
    const OnigUChar *ur = onigenc_step_back(enc, us, up, ue, n);

    return RBIMPL_CAST((char *)ur);
}

/**
 * @private
 *
 * This is an implementation detail  of rb_enc_asciicompat().  People don't use
 * it directly.  Just always use rb_enc_asciicompat().
 *
 * @param[in]  enc  Encoding in question.
 * @retval     1    It is ASCII compatible.
 * @retval     0    It isn't.
 */
static inline int
rb_enc_asciicompat_inline(rb_encoding *enc)
{
    return rb_enc_mbminlen(enc)==1 && !rb_enc_dummy_p(enc);
}

/**
 * Queries if  the passed encoding  is _in  some sense_ compatible  with ASCII.
 * The  concept  of  ASCII  compatibility   is  nuanced,  and  private  to  our
 * implementation.  For instance SJIS is  ASCII compatible to us, despite their
 * having different  characters at code  point `0x5C`.   This is based  on some
 * practical  consideration that  Japanese people  confuses SJIS  to be  "upper
 * compatible" with ASCII (which is in fact  a wrong idea, but we just don't go
 * strict here).  An example of  ASCII incompatible encoding is UTF-16.  UTF-16
 * shares code points  with ASCII, but employs a  completely different encoding
 * scheme.
 *
 * @param[in]  enc  Encoding in question.
 * @retval     0    It is incompatible.
 * @retval     1    It is compatible.
 */
static inline bool
rb_enc_asciicompat(rb_encoding *enc)
{
    if (rb_enc_mbminlen(enc) != 1) {
        return false;
    }
    else if (rb_enc_dummy_p(enc)) {
        return false;
    }
    else {
        return true;
    }
}

/**
 * Queries if the passed string is in an ASCII-compatible encoding.
 *
 * @param[in]  str  A Ruby's string to query.
 * @retval     0    `str` is not a String, or an ASCII-incompatible string.
 * @retval     1    Otherwise.
 */
static inline bool
rb_enc_str_asciicompat_p(VALUE str)
{
    rb_encoding *enc = rb_enc_get(str);

    return rb_enc_asciicompat(enc);
}

/**
 * Queries  the   Ruby-level  counterpart   instance  of   ::rb_cEncoding  that
 * corresponds to the passed encoding.
 *
 * @param[in]  enc  An encoding
 * @retval     RUBY_Qnil  `enc` is a null pointer.
 * @retval     otherwise  An instance of ::rb_cEncoding.
 */
VALUE rb_enc_from_encoding(rb_encoding *enc);

RBIMPL_ATTR_PURE()
/**
 * Queries if the passed encoding is either one of UTF-8/16/32.
 *
 * @note  It does not take UTF-7, which we actually support, into account.
 *
 * @param[in]  enc        Encoding in question.
 * @retval     0          It is not a Unicode variant.
 * @retval     otherwise  It is.
 *
 * @internal
 *
 * In   reality   it   returns   1/0,   but  the   value   is   abstracted   as
 * `ONIGENC_FLAG_UNICODE`.
 */
int rb_enc_unicode_p(rb_encoding *enc);

RBIMPL_ATTR_RETURNS_NONNULL()
/**
 * Queries the encoding that represents ASCII-8BIT a.k.a. binary.
 *
 * @return  The encoding that represents ASCII-8BIT.
 *
 * @internal
 *
 * This can not return NULL once the process properly boots up.
 */
rb_encoding *rb_ascii8bit_encoding(void);

RBIMPL_ATTR_RETURNS_NONNULL()
/**
 * Queries the encoding that represents UTF-8.
 *
 * @return  The encoding that represents UTF-8.
 *
 * @internal
 *
 * This can not return NULL once the process properly boots up.
 */
rb_encoding *rb_utf8_encoding(void);

RBIMPL_ATTR_RETURNS_NONNULL()
/**
 * Queries the encoding that represents US-ASCII.
 *
 * @return  The encoding that represents US-ASCII.
 *
 * @internal
 *
 * This can not return NULL once the process properly boots up.
 */
rb_encoding *rb_usascii_encoding(void);

/**
 * Queries the encoding that represents the current locale.
 *
 * @return  The encoding that represents the process' locale.
 *
 * @internal
 *
 * This  is dynamic.   If  you  change the  process'  locale  by e.g.   calling
 * `setlocale(3)`, that should also change the return value of this function.
 *
 * There is no official way for Ruby scripts to manipulate locales, though.
 */
rb_encoding *rb_locale_encoding(void);

/**
 * Queries the "filesystem"  encoding.  This is the encoding  that ruby expects
 * info from  the OS'  file system  are in.  This  affects for  instance return
 * value of rb_dir_getwd().  Most  notably on Windows it can be  an alias of OS
 * codepage.  Most  notably on Linux  users can  set this via  default external
 * encoding.
 *
 * @return  The "filesystem" encoding.
 */
rb_encoding *rb_filesystem_encoding(void);

/**
 * Queries  the "default  external" encoding.   This is  used to  interact with
 * outer-process things such as File.  Though not recommended, you can set this
 * using rb_enc_set_default_external().
 *
 * @return  The "default external"  encoding.
 */
rb_encoding *rb_default_external_encoding(void);

/**
 * Queries  the "default  internal" encoding.   This could  be a  null pointer.
 * Otherwise, outer-process info are  transcoded from default external encoding
 * to this one during reading from an IO.
 *
 * @return  The "default internal"  encoding (if any).
 */
rb_encoding *rb_default_internal_encoding(void);

#ifndef rb_ascii8bit_encindex
RBIMPL_ATTR_CONST()
/**
 * Identical to rb_ascii8bit_encoding(), except it returns the encoding's index
 * instead of the encoding itself.
 *
 * @return  The index of encoding of ASCII-8BIT.
 *
 * @internal
 *
 * This happens to be 0.
 */
int rb_ascii8bit_encindex(void);
#endif

/**
 * Queries if  the passed  object is  in ascii 8bit  (== binary)  encoding. The
 * object must  be capable of having  inline encoding.  Using this  macro needs
 * deep understanding of bit level object binary layout.
 *
 * @param[in]  obj  An object to check.
 * @retval     1    It is.
 * @retval     0    It isn't.
 */
static inline bool
RB_ENCODING_IS_ASCII8BIT(VALUE obj)
{
    return RB_ENCODING_GET_INLINED(obj) == rb_ascii8bit_encindex();
}

#ifndef rb_utf8_encindex
RBIMPL_ATTR_CONST()
/**
 * Identical  to rb_utf8_encoding(),  except  it returns  the encoding's  index
 * instead of the encoding itself.
 *
 * @return  The index of encoding of UTF-8.
 */
int rb_utf8_encindex(void);
#endif

#ifndef rb_usascii_encindex
RBIMPL_ATTR_CONST()
/**
 * Identical to  rb_usascii_encoding(), except it returns  the encoding's index
 * instead of the encoding itself.
 *
 * @return  The index of encoding of UTF-8.
 */
int rb_usascii_encindex(void);
#endif

/**
 * Identical to  rb_locale_encoding(), except  it returns the  encoding's index
 * instead of the encoding itself.
 *
 * @return  The index of the locale encoding.
 */
int rb_locale_encindex(void);

/**
 * Identical  to rb_filesystem_encoding(),  except  it  returns the  encoding's
 * index instead of the encoding itself.
 *
 * @return  The index of the filesystem encoding.
 */
int rb_filesystem_encindex(void);

/**
 * Identical   to  rb_default_external_encoding(),   except   it  returns   the
 * Ruby-level counterpart  instance of  ::rb_cEncoding that corresponds  to the
 * default external encoding.
 *
 * @return  An instance of ::rb_cEncoding of default external.
 */
VALUE rb_enc_default_external(void);

/**
 * Identical   to  rb_default_internal_encoding(),   except   it  returns   the
 * Ruby-level counterpart  instance of  ::rb_cEncoding that corresponds  to the
 * default internal encoding.
 *
 * @return  An instance of ::rb_cEncoding of default internal.
 */
VALUE rb_enc_default_internal(void);

/**
 * Destructively assigns the passed encoding  as the default external encoding.
 * You should not  use this API.  It has process-global  side effects.  Also it
 * doesn't change encodings of strings that have already been read.
 *
 * @param[in]  encoding      Ruby level encoding.
 * @exception  rb_eArgError  `encoding` is ::RUBY_Qnil.
 * @post       The default external encoding is `encoding`.
 */
void rb_enc_set_default_external(VALUE encoding);

/**
 * Destructively assigns the passed encoding  as the default internal encoding.
 * You should not  use this API.  It has process-global  side effects.  Also it
 * doesn't change encodings of strings that have already been read.
 *
 * @param[in]  encoding      Ruby level encoding.
 * @post       The default internal encoding is `encoding`.
 * @note       Unlike rb_enc_set_default_external() you can pass ::RUBY_Qnil.
 */
void rb_enc_set_default_internal(VALUE encoding);

/**
 * Returns  a   platform-depended  "charmap"  of  the   current  locale.   This
 * information  is  called   a  "Codeset  name"  in  IEEE   1003.1  section  13
 * (`<langinfo.h>`).  This is a very low-level  API.  The return value can have
 * no corresponding encoding when passed to rb_find_encoding().
 *
 * @param[in]  klass  Ignored for no reason (why...)
 * @return     The low-level locale charmap, in Ruby's String.
 */
VALUE rb_locale_charmap(VALUE klass);

RBIMPL_SYMBOL_EXPORT_END()

/** @cond INTERNAL_MACRO */
#define RB_ENCODING_GET          RB_ENCODING_GET
#define RB_ENCODING_GET_INLINED  RB_ENCODING_GET_INLINED
#define RB_ENCODING_IS_ASCII8BIT RB_ENCODING_IS_ASCII8BIT
#define RB_ENCODING_SET          RB_ENCODING_SET
#define RB_ENCODING_SET_INLINED  RB_ENCODING_SET_INLINED
#define rb_enc_asciicompat       rb_enc_asciicompat
#define rb_enc_code_to_mbclen    rb_enc_code_to_mbclen
#define rb_enc_codepoint         rb_enc_codepoint
#define rb_enc_left_char_head    rb_enc_left_char_head
#define rb_enc_mbc_to_codepoint  rb_enc_mbc_to_codepoint
#define rb_enc_mbcput            rb_enc_mbcput
#define rb_enc_mbmaxlen          rb_enc_mbmaxlen
#define rb_enc_mbminlen          rb_enc_mbminlen
#define rb_enc_name              rb_enc_name
#define rb_enc_prev_char         rb_enc_prev_char
#define rb_enc_right_char_head   rb_enc_right_char_head
#define rb_enc_step_back         rb_enc_step_back
#define rb_enc_str_asciicompat_p rb_enc_str_asciicompat_p
/** @endcond */

#endif /* RUBY_INTERNAL_ENCODING_ENCODING_H */
ruby/internal/encoding/symbol.h000064400000010650151732674170012624 0ustar00#ifndef RUBY_INTERNAL_ENCODING_SYMBOL_H              /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_INTERNAL_ENCODING_SYMBOL_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Routines to manipulate encodings of symbols.
 */

#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/encoding/encoding.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/**
 * Identical to rb_intern2(), except it additionally takes an encoding.
 *
 * @param[in]  name              The name of the id.
 * @param[in]  len               Length of `name`.
 * @param[in]  enc               `name`'s encoding.
 * @exception  rb_eRuntimeError  Too many symbols.
 * @return     A (possibly new) id whose value is the given name.
 * @note       These   days  Ruby   internally   has  two   kinds  of   symbols
 *             (static/dynamic).   Symbols created  using  this function  would
 *             become static ones;  i.e. would never be  garbage collected.  It
 *             is up  to you to avoid  memory leaks.  Think twice  before using
 *             it.
 */
ID rb_intern3(const char *name, long len, rb_encoding *enc);

RBIMPL_ATTR_NONNULL(())
/**
 * Identical to rb_symname_p(), except it additionally takes an encoding.
 *
 * @param[in]  str  A C string to check.
 * @param[in]  enc  `str`'s encoding.
 * @retval     1    It is a valid symbol name.
 * @retval     0    It is invalid as a symbol name.
 */
int rb_enc_symname_p(const char *str, rb_encoding *enc);

/**
 * Identical  to rb_enc_symname_p(),  except it  additionally takes  the passed
 * string's length.  This  is needed for strings containing NUL  bytes, like in
 * case of UTF-32.
 *
 * @param[in]  name  A C string to check.
 * @param[in]  len   Number of bytes of `str`.
 * @param[in]  enc   `str`'s encoding.
 * @retval     1     It is a valid symbol name.
 * @retval     0     It is invalid as a symbol name.
 */
int rb_enc_symname2_p(const char *name, long len, rb_encoding *enc);

/**
 * Identical to  rb_check_id(), except it  takes a  pointer to a  memory region
 * instead of Ruby's string.
 *
 * @param[in]  ptr                A pointer to a memory region.
 * @param[in]  len                Number of bytes of `ptr`.
 * @param[in]  enc                Encoding of `ptr`.
 * @exception  rb_eEncodingError  `ptr` contains non-ASCII according to `enc`.
 * @retval     0                  No such id ever existed in the history.
 * @retval     otherwise          The id that represents the given name.
 */
ID rb_check_id_cstr(const char *ptr, long len, rb_encoding *enc);

/**
 * Identical to rb_check_id_cstr(), except for the return type.  It can also be
 * seen as a routine identical to  rb_check_symbol(), except it takes a pointer
 * to a memory region instead of Ruby's string.
 *
 * @param[in]  ptr                A pointer to a memory region.
 * @param[in]  len                Number of bytes of `ptr`.
 * @param[in]  enc                Encoding of `ptr`.
 * @exception  rb_eEncodingError  `ptr` contains non-ASCII according to `enc`.
 * @retval     RUBY_Qnil          No such id ever existed in the history.
 * @retval     otherwise          The id that represents the given name.
 */
VALUE rb_check_symbol_cstr(const char *ptr, long len, rb_encoding *enc);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RUBY_INTERNAL_ENCODING_SYMBOL_H */
ruby/internal/encoding/pathname.h000064400000015420151732674170013114 0ustar00#ifndef RUBY_INTERNAL_ENCODING_PATHNAME_H            /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_INTERNAL_ENCODING_PATHNAME_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Routines to manipulate encodings of pathnames.
 */

#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/encoding/encoding.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()
RBIMPL_ATTR_NONNULL(())
/**
 * Returns a path component directly adjacent to the passed pointer.
 *
 * ```
 * "/multi/byte/encoded/pathname.txt"
 *         ^    ^                   ^
 *         |    |                   +--- end
 *         |    +--- @return
 *         +--- path
 * ```
 *
 * @param[in]  path  Where to start scanning.
 * @param[in]  end   End of the path string.
 * @param[in]  enc   Encoding of the string.
 * @return     A pointer  in the  passed string where  the next  path component
 *             resides, or `end` if there is no next path component.
 */
char *rb_enc_path_next(const char *path, const char *end, rb_encoding *enc);

RBIMPL_ATTR_NONNULL(())
/**
 * Seeks for non-prefix  part of a pathname.   This can be a no-op  when the OS
 * has no  such concept  like a  path prefix.   But there  are OSes  where path
 * prefixes do exist.
 *
 * ```
 * "C:\multi\byte\encoded\pathname.txt"
 *  ^ ^                               ^
 *  | |                               +--- end
 *  | +--- @return
 *  +--- path
 * ```
 *
 * @param[in]  path  Where to start scanning.
 * @param[in]  end   End of the path string.
 * @param[in]  enc   Encoding of the string.
 * @return     A pointer in the passed  string where non-prefix part starts, or
 *             `path` if the OS does not have path prefix.
 */
char *rb_enc_path_skip_prefix(const char *path, const char *end, rb_encoding *enc);

RBIMPL_ATTR_NONNULL(())
/**
 * Returns the last path component.
 *
 * ```
 * "/multi/byte/encoded/pathname.txt"
 *        ^             ^           ^
 *        |             |           +--- end
 *        |             +--- @return
 *        +--- path
 * ```
 *
 * @param[in]  path  Where to start scanning.
 * @param[in]  end   End of the path string.
 * @param[in]  enc   Encoding of the string.
 * @return     A pointer  in the  passed string where  the last  path component
 *             resides, or `end` if there is no more path component.
 */
char *rb_enc_path_last_separator(const char *path, const char *end, rb_encoding *enc);

RBIMPL_ATTR_NONNULL(())
/**
 * This just returns the passed end basically.  It makes difference in case the
 * passed string ends with tons of path separators like the following:
 *
 * ```
 * "/path/that/ends/with/lots/of/slashes//////////////"
 *  ^                                   ^             ^
 *  |                                   |             +--- end
 *  |                                   +--- @return
 *  +--- path
 * ```
 *
 * @param[in]  path  Where to start scanning.
 * @param[in]  end   End of the path string.
 * @param[in]  enc   Encoding of the string.
 * @return     A  pointer  in  the  passed   string  where  the  trailing  path
 *             separators  start,  or  `end`  if  there  is  no  trailing  path
 *             separators.
 *
 * @internal
 *
 * It  seems this  function  was  introduced to  mimic  what  POSIX says  about
 * `basename(3)`.
 */
char *rb_enc_path_end(const char *path, const char *end, rb_encoding *enc);

RBIMPL_ATTR_NONNULL((1, 4))
/**
 * Our own  encoding-aware version  of `basename(3)`.  Normally,  this function
 * returns the  last path  component of  the given name.   However in  case the
 * passed  name  ends  with a  path  separator,  it  returns  the name  of  the
 * directory, not  the last (empty)  component.  Also if  the passed name  is a
 * root directory, it  returns that root directory.  Note  however that Windows
 * filesystem have drive letters, which this function does not return.
 *
 * @param[in]      name     Target path.
 * @param[out]     baselen  Return buffer.
 * @param[in,out]  alllen   Number of bytes of `name`.
 * @param[enc]     enc      Encoding of `name`.
 * @return         The rightmost component of `name`.
 * @post           `baselen`, if passed,  is updated to be the  number of bytes
 *                 of the returned basename.
 * @post           `alllen`, if passed, is updated to be the number of bytes of
 *                 strings not considered as the basename.
 */
const char *ruby_enc_find_basename(const char *name, long *baselen, long *alllen, rb_encoding *enc);

RBIMPL_ATTR_NONNULL((1, 3))
/**
 * Our own  encoding-aware version of  `extname`.  This function  first applies
 * rb_enc_path_last_separator() to the passed name and only concerns its return
 * value (ignores  any parent directories).  This  function returns complicated
 * results:
 *
 * ```CXX
 * auto path = "...";
 * auto len = strlen(path);
 * auto ret = ruby_enc_find_extname(path, &len, rb_ascii8bit_encoding());
 *
 * switch(len) {
 * case 0:
 *     if (ret == 0) {
 *         // `path` is a file without extensions.
 *     }
 *     else {
 *         // `path` is a dotfile.
 *         // `ret` is the file's name.
 *     }
 *     break;
 *
 * case 1:
 *     // `path` _ends_ with a dot.
 *     // `ret` is that dot.
 *     break;
 *
 * default:
 *     // `path` has an extension.
 *     // `ret` is that extension.
 * }
 * ```
 *
 * @param[in]      name  Target path.
 * @param[in,out]  len   Number of bytes of `name`.
 * @param[in]      enc   Encoding of `name`.
 * @return         See above.
 * @post           `len`, if passed, is updated (see above).
 */
const char *ruby_enc_find_extname(const char *name, long *len, rb_encoding *enc);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RUBY_INTERNAL_ENCODING_PATHNAME_H */
ruby/internal/encoding/sprintf.h000064400000006600151732674170013004 0ustar00#ifndef RUBY_INTERNAL_ENCODING_SPRINTF_H             /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_INTERNAL_ENCODING_SPRINTF_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Routines to manipulate encodings of symbols.
 */
#include "ruby/internal/config.h"
#include <stdarg.h>
#include "ruby/internal/attr/format.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/encoding/encoding.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()
RBIMPL_ATTR_NONNULL((2))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 3)
/**
 * Identical to  rb_sprintf(), except it  additionally takes an  encoding.  The
 * passed encoding rules  both the incoming format specifier  and the resulting
 * string.
 *
 * @param[in]  enc  Encoding of `fmt`.
 * @param[in]  fmt  A `printf`-like format specifier.
 * @param[in]  ...  Variadic number of contents to format.
 * @return     A rendered new instance of ::rb_cString, of `enc` encoding.
 */
VALUE rb_enc_sprintf(rb_encoding *enc, const char *fmt, ...);

RBIMPL_ATTR_NONNULL((2))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 0)
/**
 * Identical  to  rb_enc_sprintf(), except  it  takes  a `va_list`  instead  of
 * variadic  arguments.   It  can  also  be seen  as  a  routine  identical  to
 * rb_vsprintf(), except it additionally takes an encoding.
 *
 * @param[in]  enc  Encoding of `fmt`.
 * @param[in]  fmt  A `printf`-like format specifier.
 * @param[in]  ap   Contents to format.
 * @return     A rendered new instance of ::rb_cString, of `enc` encoding.
 */
VALUE rb_enc_vsprintf(rb_encoding *enc, const char *fmt, va_list ap);

RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_NONNULL((3))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 3, 4)
/**
 * Identical to rb_raise(), except it additionally takes an encoding.
 *
 * @param[in]  enc  Encoding of the generating exception.
 * @param[in]  exc  A subclass of ::rb_eException.
 * @param[in]  fmt  Format specifier string compatible with rb_sprintf().
 * @param[in]  ...  Contents of the message.
 * @exception  exc  The specified exception.
 * @note       It never returns.
 */
void rb_enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RUBY_INTERNAL_ENCODING_SPRINTF_H */
ruby/internal/anyargs.h000064400000113734151732674170011204 0ustar00#ifndef RBIMPL_ANYARGS_H                             /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ANYARGS_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Function overloads to issue warnings around #ANYARGS.
 *
 * For instance ::rb_define_method  takes a pointer to  #ANYARGS -ed functions,
 * which in  fact varies 18  different prototypes.   We still need  to preserve
 * #ANYARGS for storages but why not check the consistencies if possible.  With
 * those complex macro overlays defined in  this header file, use of a function
 * pointer gets checked against the corresponding arity argument.
 *
 * ### Q&A ###
 *
 * - Q: Where did the magic number "18" came from in the description above?
 *
 * - A: Count the case branch of `vm_method.c:call_cfunc_invoker_func()`.  Note
 *      also that the 18  branches has lasted for at least  25 years.  See also
 *      commit 200e0ee2fd3c1c006c528874a88f684447215524.
 *
 * - Q: What is this `__weakref__` thing?
 *
 * - A: That is a kind of function overloading mechanism that GCC provides.  In
 *      this   case  for   instance  `rb_define_method_00`   is  an   alias  of
 *      ::rb_define_method, with a strong type.
 *
 * - Q: What is this `__transparent_union__` thing?
 *
 *   A: That  is  another  kind  of function  overloading  mechanism  that  GCC
 *      provides.   In this  case  the attributed  function  pointer is  either
 *      `VALUE(*)(int,VALUE*,VALUE)` or `VALUE(*)(int,const VALUE*,VALUE)`.
 *
 *      This is better than `void*` or #ANYARGS because we can reject all other
 *      possibilities than the two.
 *
 * - Q: What does this #rb_define_method macro mean?
 *
 * - A: It  selects  appropriate  alias  of  the  ::rb_define_method  function,
 *      depending on the last (arity) argument.
 *
 * - Q: Why the special case for ::rb_f_notimplement ?
 *
 * - A: Function   pointer  to   ::rb_f_notimplement   is   special  cased   in
 *      `vm_method.c:rb_add_method_cfunc()`.   That should  be  handled by  the
 *      `__builtin_choose_expr`   chain  inside   of  #rb_define_method   macro
 *      expansion.      In    order     to    do     so,    comparison     like
 *      `(func == rb_f_notimplement)`        is        inappropriate        for
 *      `__builtin_choose_expr`'s  expression  (which  must be  a  compile-time
 *      integer constant  but the address  of ::rb_f_notimplement is  not fixed
 *      until      the      linker).        Instead      we      are      using
 *      `__builtin_types_compatible_p`, and in doing  so we need to distinguish
 *      ::rb_f_notimplement from others, by type.
 */
#include "ruby/internal/attr/maybe_unused.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/weakref.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/config.h"
#include "ruby/internal/has/attribute.h"
#include "ruby/internal/intern/class.h"
#include "ruby/internal/intern/vm.h"
#include "ruby/internal/method.h"
#include "ruby/internal/value.h"
#include "ruby/backward/2/stdarg.h"

#if defined(__cplusplus)
# include "ruby/backward/cxxanyargs.hpp"

#elif defined(_WIN32) || defined(__CYGWIN__)
# /* Skip due to [Bug #16134] */
# define RBIMPL_CAST_FN_PTR 1

#elif ! RBIMPL_HAS_ATTRIBUTE(transparent_union)
# /* :TODO: improve here, please find a way to support. */
# define RBIMPL_CAST_FN_PTR 1

#elif ! defined(HAVE_VA_ARGS_MACRO)
# /* :TODO: improve here, please find a way to support. */
# define RBIMPL_CAST_FN_PTR 1

#else
# /** @cond INTERNAL_MACRO */
# if ! defined(HAVE_BUILTIN___BUILTIN_TYPES_COMPATIBLE_P)
#  define RBIMPL_CFUNC_IS_rb_f_notimplement(f) 0
# else
#  define RBIMPL_CFUNC_IS_rb_f_notimplement(f) \
    __builtin_types_compatible_p(             \
        __typeof__(f),                        \
        __typeof__(rb_f_notimplement))
# endif

# if ! defined(HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P)
#  define RBIMPL_ANYARGS_DISPATCH(expr, truthy, falsy) (falsy)
# else
#  define RBIMPL_ANYARGS_DISPATCH(expr, truthy, falsy) \
    __builtin_choose_expr(                            \
        __builtin_choose_expr(                        \
            __builtin_constant_p(expr),               \
            (expr), 0),                               \
        (truthy), (falsy))
# endif

# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_m2(n) RBIMPL_ANYARGS_DISPATCH((n) == -2, rb_define_singleton_method_m2, rb_define_singleton_method_m3)
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_m1(n) RBIMPL_ANYARGS_DISPATCH((n) == -1, rb_define_singleton_method_m1, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_m2(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_00(n) RBIMPL_ANYARGS_DISPATCH((n) ==  0, rb_define_singleton_method_00, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_m1(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_01(n) RBIMPL_ANYARGS_DISPATCH((n) ==  1, rb_define_singleton_method_01, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_00(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_02(n) RBIMPL_ANYARGS_DISPATCH((n) ==  2, rb_define_singleton_method_02, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_01(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_03(n) RBIMPL_ANYARGS_DISPATCH((n) ==  3, rb_define_singleton_method_03, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_02(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_04(n) RBIMPL_ANYARGS_DISPATCH((n) ==  4, rb_define_singleton_method_04, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_03(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_05(n) RBIMPL_ANYARGS_DISPATCH((n) ==  5, rb_define_singleton_method_05, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_04(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_06(n) RBIMPL_ANYARGS_DISPATCH((n) ==  6, rb_define_singleton_method_06, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_05(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_07(n) RBIMPL_ANYARGS_DISPATCH((n) ==  7, rb_define_singleton_method_07, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_06(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_08(n) RBIMPL_ANYARGS_DISPATCH((n) ==  8, rb_define_singleton_method_08, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_07(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_09(n) RBIMPL_ANYARGS_DISPATCH((n) ==  9, rb_define_singleton_method_09, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_08(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_10(n) RBIMPL_ANYARGS_DISPATCH((n) == 10, rb_define_singleton_method_10, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_09(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_11(n) RBIMPL_ANYARGS_DISPATCH((n) == 11, rb_define_singleton_method_11, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_10(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_12(n) RBIMPL_ANYARGS_DISPATCH((n) == 12, rb_define_singleton_method_12, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_11(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_13(n) RBIMPL_ANYARGS_DISPATCH((n) == 13, rb_define_singleton_method_13, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_12(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_14(n) RBIMPL_ANYARGS_DISPATCH((n) == 14, rb_define_singleton_method_14, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_13(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_15(n) RBIMPL_ANYARGS_DISPATCH((n) == 15, rb_define_singleton_method_15, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_14(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_m2(n) RBIMPL_ANYARGS_DISPATCH((n) == -2, rb_define_protected_method_m2, rb_define_protected_method_m3)
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_m1(n) RBIMPL_ANYARGS_DISPATCH((n) == -1, rb_define_protected_method_m1, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_m2(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_00(n) RBIMPL_ANYARGS_DISPATCH((n) ==  0, rb_define_protected_method_00, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_m1(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_01(n) RBIMPL_ANYARGS_DISPATCH((n) ==  1, rb_define_protected_method_01, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_00(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_02(n) RBIMPL_ANYARGS_DISPATCH((n) ==  2, rb_define_protected_method_02, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_01(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_03(n) RBIMPL_ANYARGS_DISPATCH((n) ==  3, rb_define_protected_method_03, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_02(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_04(n) RBIMPL_ANYARGS_DISPATCH((n) ==  4, rb_define_protected_method_04, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_03(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_05(n) RBIMPL_ANYARGS_DISPATCH((n) ==  5, rb_define_protected_method_05, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_04(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_06(n) RBIMPL_ANYARGS_DISPATCH((n) ==  6, rb_define_protected_method_06, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_05(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_07(n) RBIMPL_ANYARGS_DISPATCH((n) ==  7, rb_define_protected_method_07, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_06(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_08(n) RBIMPL_ANYARGS_DISPATCH((n) ==  8, rb_define_protected_method_08, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_07(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_09(n) RBIMPL_ANYARGS_DISPATCH((n) ==  9, rb_define_protected_method_09, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_08(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_10(n) RBIMPL_ANYARGS_DISPATCH((n) == 10, rb_define_protected_method_10, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_09(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_11(n) RBIMPL_ANYARGS_DISPATCH((n) == 11, rb_define_protected_method_11, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_10(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_12(n) RBIMPL_ANYARGS_DISPATCH((n) == 12, rb_define_protected_method_12, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_11(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_13(n) RBIMPL_ANYARGS_DISPATCH((n) == 13, rb_define_protected_method_13, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_12(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_14(n) RBIMPL_ANYARGS_DISPATCH((n) == 14, rb_define_protected_method_14, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_13(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_15(n) RBIMPL_ANYARGS_DISPATCH((n) == 15, rb_define_protected_method_15, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_14(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_m2(n)   RBIMPL_ANYARGS_DISPATCH((n) == -2, rb_define_private_method_m2,   rb_define_private_method_m3)
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_m1(n)   RBIMPL_ANYARGS_DISPATCH((n) == -1, rb_define_private_method_m1,   RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_m2(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_00(n)   RBIMPL_ANYARGS_DISPATCH((n) ==  0, rb_define_private_method_00,   RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_m1(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_01(n)   RBIMPL_ANYARGS_DISPATCH((n) ==  1, rb_define_private_method_01,   RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_00(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_02(n)   RBIMPL_ANYARGS_DISPATCH((n) ==  2, rb_define_private_method_02,   RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_01(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_03(n)   RBIMPL_ANYARGS_DISPATCH((n) ==  3, rb_define_private_method_03,   RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_02(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_04(n)   RBIMPL_ANYARGS_DISPATCH((n) ==  4, rb_define_private_method_04,   RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_03(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_05(n)   RBIMPL_ANYARGS_DISPATCH((n) ==  5, rb_define_private_method_05,   RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_04(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_06(n)   RBIMPL_ANYARGS_DISPATCH((n) ==  6, rb_define_private_method_06,   RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_05(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_07(n)   RBIMPL_ANYARGS_DISPATCH((n) ==  7, rb_define_private_method_07,   RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_06(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_08(n)   RBIMPL_ANYARGS_DISPATCH((n) ==  8, rb_define_private_method_08,   RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_07(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_09(n)   RBIMPL_ANYARGS_DISPATCH((n) ==  9, rb_define_private_method_09,   RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_08(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_10(n)   RBIMPL_ANYARGS_DISPATCH((n) == 10, rb_define_private_method_10,   RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_09(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_11(n)   RBIMPL_ANYARGS_DISPATCH((n) == 11, rb_define_private_method_11,   RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_10(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_12(n)   RBIMPL_ANYARGS_DISPATCH((n) == 12, rb_define_private_method_12,   RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_11(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_13(n)   RBIMPL_ANYARGS_DISPATCH((n) == 13, rb_define_private_method_13,   RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_12(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_14(n)   RBIMPL_ANYARGS_DISPATCH((n) == 14, rb_define_private_method_14,   RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_13(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_15(n)   RBIMPL_ANYARGS_DISPATCH((n) == 15, rb_define_private_method_15,   RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_14(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_m2(n)  RBIMPL_ANYARGS_DISPATCH((n) == -2, rb_define_module_function_m2,  rb_define_module_function_m3)
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_m1(n)  RBIMPL_ANYARGS_DISPATCH((n) == -1, rb_define_module_function_m1,  RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_m2(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_00(n)  RBIMPL_ANYARGS_DISPATCH((n) ==  0, rb_define_module_function_00,  RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_m1(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_01(n)  RBIMPL_ANYARGS_DISPATCH((n) ==  1, rb_define_module_function_01,  RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_00(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_02(n)  RBIMPL_ANYARGS_DISPATCH((n) ==  2, rb_define_module_function_02,  RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_01(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_03(n)  RBIMPL_ANYARGS_DISPATCH((n) ==  3, rb_define_module_function_03,  RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_02(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_04(n)  RBIMPL_ANYARGS_DISPATCH((n) ==  4, rb_define_module_function_04,  RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_03(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_05(n)  RBIMPL_ANYARGS_DISPATCH((n) ==  5, rb_define_module_function_05,  RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_04(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_06(n)  RBIMPL_ANYARGS_DISPATCH((n) ==  6, rb_define_module_function_06,  RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_05(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_07(n)  RBIMPL_ANYARGS_DISPATCH((n) ==  7, rb_define_module_function_07,  RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_06(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_08(n)  RBIMPL_ANYARGS_DISPATCH((n) ==  8, rb_define_module_function_08,  RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_07(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_09(n)  RBIMPL_ANYARGS_DISPATCH((n) ==  9, rb_define_module_function_09,  RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_08(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_10(n)  RBIMPL_ANYARGS_DISPATCH((n) == 10, rb_define_module_function_10,  RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_09(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_11(n)  RBIMPL_ANYARGS_DISPATCH((n) == 11, rb_define_module_function_11,  RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_10(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_12(n)  RBIMPL_ANYARGS_DISPATCH((n) == 12, rb_define_module_function_12,  RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_11(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_13(n)  RBIMPL_ANYARGS_DISPATCH((n) == 13, rb_define_module_function_13,  RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_12(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_14(n)  RBIMPL_ANYARGS_DISPATCH((n) == 14, rb_define_module_function_14,  RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_13(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_15(n)  RBIMPL_ANYARGS_DISPATCH((n) == 15, rb_define_module_function_15,  RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_14(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_m2(n)  RBIMPL_ANYARGS_DISPATCH((n) == -2, rb_define_global_function_m2,  rb_define_global_function_m3)
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_m1(n)  RBIMPL_ANYARGS_DISPATCH((n) == -1, rb_define_global_function_m1,  RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_m2(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_00(n)  RBIMPL_ANYARGS_DISPATCH((n) ==  0, rb_define_global_function_00,  RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_m1(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_01(n)  RBIMPL_ANYARGS_DISPATCH((n) ==  1, rb_define_global_function_01,  RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_00(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_02(n)  RBIMPL_ANYARGS_DISPATCH((n) ==  2, rb_define_global_function_02,  RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_01(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_03(n)  RBIMPL_ANYARGS_DISPATCH((n) ==  3, rb_define_global_function_03,  RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_02(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_04(n)  RBIMPL_ANYARGS_DISPATCH((n) ==  4, rb_define_global_function_04,  RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_03(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_05(n)  RBIMPL_ANYARGS_DISPATCH((n) ==  5, rb_define_global_function_05,  RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_04(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_06(n)  RBIMPL_ANYARGS_DISPATCH((n) ==  6, rb_define_global_function_06,  RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_05(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_07(n)  RBIMPL_ANYARGS_DISPATCH((n) ==  7, rb_define_global_function_07,  RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_06(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_08(n)  RBIMPL_ANYARGS_DISPATCH((n) ==  8, rb_define_global_function_08,  RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_07(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_09(n)  RBIMPL_ANYARGS_DISPATCH((n) ==  9, rb_define_global_function_09,  RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_08(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_10(n)  RBIMPL_ANYARGS_DISPATCH((n) == 10, rb_define_global_function_10,  RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_09(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_11(n)  RBIMPL_ANYARGS_DISPATCH((n) == 11, rb_define_global_function_11,  RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_10(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_12(n)  RBIMPL_ANYARGS_DISPATCH((n) == 12, rb_define_global_function_12,  RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_11(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_13(n)  RBIMPL_ANYARGS_DISPATCH((n) == 13, rb_define_global_function_13,  RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_12(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_14(n)  RBIMPL_ANYARGS_DISPATCH((n) == 14, rb_define_global_function_14,  RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_13(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_15(n)  RBIMPL_ANYARGS_DISPATCH((n) == 15, rb_define_global_function_15,  RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_14(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_m2(n)        RBIMPL_ANYARGS_DISPATCH((n) == -2, rb_define_method_id_m2,        rb_define_method_id_m3)
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_m1(n)        RBIMPL_ANYARGS_DISPATCH((n) == -1, rb_define_method_id_m1,        RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_m2(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_00(n)        RBIMPL_ANYARGS_DISPATCH((n) ==  0, rb_define_method_id_00,        RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_m1(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_01(n)        RBIMPL_ANYARGS_DISPATCH((n) ==  1, rb_define_method_id_01,        RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_00(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_02(n)        RBIMPL_ANYARGS_DISPATCH((n) ==  2, rb_define_method_id_02,        RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_01(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_03(n)        RBIMPL_ANYARGS_DISPATCH((n) ==  3, rb_define_method_id_03,        RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_02(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_04(n)        RBIMPL_ANYARGS_DISPATCH((n) ==  4, rb_define_method_id_04,        RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_03(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_05(n)        RBIMPL_ANYARGS_DISPATCH((n) ==  5, rb_define_method_id_05,        RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_04(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_06(n)        RBIMPL_ANYARGS_DISPATCH((n) ==  6, rb_define_method_id_06,        RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_05(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_07(n)        RBIMPL_ANYARGS_DISPATCH((n) ==  7, rb_define_method_id_07,        RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_06(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_08(n)        RBIMPL_ANYARGS_DISPATCH((n) ==  8, rb_define_method_id_08,        RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_07(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_09(n)        RBIMPL_ANYARGS_DISPATCH((n) ==  9, rb_define_method_id_09,        RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_08(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_10(n)        RBIMPL_ANYARGS_DISPATCH((n) == 10, rb_define_method_id_10,        RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_09(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_11(n)        RBIMPL_ANYARGS_DISPATCH((n) == 11, rb_define_method_id_11,        RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_10(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_12(n)        RBIMPL_ANYARGS_DISPATCH((n) == 12, rb_define_method_id_12,        RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_11(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_13(n)        RBIMPL_ANYARGS_DISPATCH((n) == 13, rb_define_method_id_13,        RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_12(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_14(n)        RBIMPL_ANYARGS_DISPATCH((n) == 14, rb_define_method_id_14,        RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_13(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_15(n)        RBIMPL_ANYARGS_DISPATCH((n) == 15, rb_define_method_id_15,        RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_14(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_m2(n)           RBIMPL_ANYARGS_DISPATCH((n) == -2, rb_define_method_m2,           rb_define_method_m3)
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_m1(n)           RBIMPL_ANYARGS_DISPATCH((n) == -1, rb_define_method_m1,           RBIMPL_ANYARGS_DISPATCH_rb_define_method_m2(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_00(n)           RBIMPL_ANYARGS_DISPATCH((n) ==  0, rb_define_method_00,           RBIMPL_ANYARGS_DISPATCH_rb_define_method_m1(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_01(n)           RBIMPL_ANYARGS_DISPATCH((n) ==  1, rb_define_method_01,           RBIMPL_ANYARGS_DISPATCH_rb_define_method_00(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_02(n)           RBIMPL_ANYARGS_DISPATCH((n) ==  2, rb_define_method_02,           RBIMPL_ANYARGS_DISPATCH_rb_define_method_01(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_03(n)           RBIMPL_ANYARGS_DISPATCH((n) ==  3, rb_define_method_03,           RBIMPL_ANYARGS_DISPATCH_rb_define_method_02(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_04(n)           RBIMPL_ANYARGS_DISPATCH((n) ==  4, rb_define_method_04,           RBIMPL_ANYARGS_DISPATCH_rb_define_method_03(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_05(n)           RBIMPL_ANYARGS_DISPATCH((n) ==  5, rb_define_method_05,           RBIMPL_ANYARGS_DISPATCH_rb_define_method_04(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_06(n)           RBIMPL_ANYARGS_DISPATCH((n) ==  6, rb_define_method_06,           RBIMPL_ANYARGS_DISPATCH_rb_define_method_05(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_07(n)           RBIMPL_ANYARGS_DISPATCH((n) ==  7, rb_define_method_07,           RBIMPL_ANYARGS_DISPATCH_rb_define_method_06(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_08(n)           RBIMPL_ANYARGS_DISPATCH((n) ==  8, rb_define_method_08,           RBIMPL_ANYARGS_DISPATCH_rb_define_method_07(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_09(n)           RBIMPL_ANYARGS_DISPATCH((n) ==  9, rb_define_method_09,           RBIMPL_ANYARGS_DISPATCH_rb_define_method_08(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_10(n)           RBIMPL_ANYARGS_DISPATCH((n) == 10, rb_define_method_10,           RBIMPL_ANYARGS_DISPATCH_rb_define_method_09(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_11(n)           RBIMPL_ANYARGS_DISPATCH((n) == 11, rb_define_method_11,           RBIMPL_ANYARGS_DISPATCH_rb_define_method_10(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_12(n)           RBIMPL_ANYARGS_DISPATCH((n) == 12, rb_define_method_12,           RBIMPL_ANYARGS_DISPATCH_rb_define_method_11(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_13(n)           RBIMPL_ANYARGS_DISPATCH((n) == 13, rb_define_method_13,           RBIMPL_ANYARGS_DISPATCH_rb_define_method_12(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_14(n)           RBIMPL_ANYARGS_DISPATCH((n) == 14, rb_define_method_14,           RBIMPL_ANYARGS_DISPATCH_rb_define_method_13(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_15(n)           RBIMPL_ANYARGS_DISPATCH((n) == 15, rb_define_method_15,           RBIMPL_ANYARGS_DISPATCH_rb_define_method_14(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method(n, f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_singleton_method_notimpl, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_15(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method(n, f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_protected_method_notimpl, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_15(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method(n, f)   RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_private_method_notimpl,   RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_15(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function(n, f)  RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_module_function_notimpl,  RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_15(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function(n, f)  RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_global_function_notimpl,  RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_15(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id(n, f)        RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_method_id_notimpl,        RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_15(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method(n, f)           RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_method_notimpl,           RBIMPL_ANYARGS_DISPATCH_rb_define_method_15(n))
# define RBIMPL_ANYARGS_ATTRSET(sym) RBIMPL_ATTR_MAYBE_UNUSED() RBIMPL_ATTR_NONNULL(()) RBIMPL_ATTR_WEAKREF(sym)
# define RBIMPL_ANYARGS_DECL(sym, ...) \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _notimpl(__VA_ARGS__, VALUE(*)(int, const VALUE *, VALUE, VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _m3(__VA_ARGS__, VALUE(*)(ANYARGS), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _m2(__VA_ARGS__, VALUE(*)(VALUE, VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _m1(__VA_ARGS__, VALUE(*)(int, union { VALUE *x; const VALUE *y; } __attribute__((__transparent_union__)), VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _00(__VA_ARGS__, VALUE(*)(VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _01(__VA_ARGS__, VALUE(*)(VALUE, VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _02(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _03(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _04(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _05(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _06(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _07(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _08(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _09(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _10(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _11(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _12(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _13(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _14(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _15(__VA_ARGS__, VALUE(*)(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE), int);
RBIMPL_ANYARGS_DECL(rb_define_singleton_method, VALUE, const char *)
RBIMPL_ANYARGS_DECL(rb_define_protected_method, VALUE, const char *)
RBIMPL_ANYARGS_DECL(rb_define_private_method, VALUE, const char *)
RBIMPL_ANYARGS_DECL(rb_define_module_function, VALUE, const char *)
RBIMPL_ANYARGS_DECL(rb_define_global_function, const char *)
RBIMPL_ANYARGS_DECL(rb_define_method_id, VALUE, ID)
RBIMPL_ANYARGS_DECL(rb_define_method, VALUE, const char *)
/** @endcond */

/**
 * @brief  Defines klass\#mid.
 * @see    ::rb_define_method
 * @param  klass  Where the method lives.
 * @param  mid    Name of the defining method.
 * @param  func   Implementation of klass\#mid.
 * @param  arity  Arity of klass\#mid.
 */
#define rb_define_method(klass, mid, func, arity)           RBIMPL_ANYARGS_DISPATCH_rb_define_method((arity), (func))((klass), (mid), (func), (arity))

/**
 * @brief  Defines klass\#mid.
 * @see    ::rb_define_method_id
 * @param  klass  Where the method lives.
 * @param  mid    Name of the defining method.
 * @param  func   Implementation of klass\#mid.
 * @param  arity  Arity of klass\#mid.
 */
#define rb_define_method_id(klass, mid, func, arity)        RBIMPL_ANYARGS_DISPATCH_rb_define_method_id((arity), (func))((klass), (mid), (func), (arity))

/**
 * @brief  Defines obj.mid.
 * @see    ::rb_define_singleton_method
 * @param  obj    Where the method lives.
 * @param  mid    Name of the defining method.
 * @param  func   Implementation of obj.mid.
 * @param  arity  Arity of obj.mid.
 */
#define rb_define_singleton_method(obj, mid, func, arity)   RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method((arity), (func))((obj), (mid), (func), (arity))

/**
 * @brief  Defines klass\#mid and make it protected.
 * @see    ::rb_define_protected_method
 * @param  klass  Where the method lives.
 * @param  mid    Name of the defining method.
 * @param  func   Implementation of klass\#mid.
 * @param  arity  Arity of klass\#mid.
 */
#define rb_define_protected_method(klass, mid, func, arity) RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method((arity), (func))((klass), (mid), (func), (arity))

/**
 * @brief  Defines klass\#mid and make it private.
 * @see    ::rb_define_private_method
 * @param  klass  Where the method lives.
 * @param  mid    Name of the defining method.
 * @param  func   Implementation of klass\#mid.
 * @param  arity  Arity of klass\#mid.
 */
#define rb_define_private_method(klass, mid, func, arity)   RBIMPL_ANYARGS_DISPATCH_rb_define_private_method((arity), (func))((klass), (mid), (func), (arity))

/**
 * @brief  Defines mod\#mid and make it a module function.
 * @see    ::rb_define_module_function
 * @param  mod    Where the method lives.
 * @param  mid    Name of the defining method.
 * @param  func   Implementation of mod\#mid.
 * @param  arity  Arity of mod\#mid.
 */
#define rb_define_module_function(mod, mid, func, arity)    RBIMPL_ANYARGS_DISPATCH_rb_define_module_function((arity), (func))((mod), (mid), (func), (arity))

/**
 * @brief  Defines ::rb_mKerbel \#mid.
 * @see    ::rb_define_global_function
 * @param  mid    Name of the defining method.
 * @param  func   Implementation of ::rb_mKernel \#mid.
 * @param  arity  Arity of ::rb_mKernel \#mid.
 */
#define rb_define_global_function(mid, func, arity)         RBIMPL_ANYARGS_DISPATCH_rb_define_global_function((arity), (func))((mid), (func), (arity))

#endif /* __cplusplus */

#if defined(RBIMPL_CAST_FN_PTR) && !defined(__cplusplus)
/* In C23, K&R style prototypes are gone and so `void foo(ANYARGS)` became
 * equivalent to `void foo(void)` unlike in earlier versions. This is a problem
 * for rb_define_* functions since that makes all valid functions one can pass
 * trip -Wincompatible-pointer-types, which we treat as errors. This is mostly
 * not a problem for the __builtin_choose_expr path, but outside of that we
 * need to add a cast for compatibility.
 */
#define rb_define_method(klass, mid, func, arity)           rb_define_method((klass), (mid), (VALUE (*)(ANYARGS))(func), (arity))
#define rb_define_method_id(klass, mid, func, arity)        rb_define_method_id((klass), (mid), (VALUE (*)(ANYARGS))(func), (arity))
#define rb_define_singleton_method(obj, mid, func, arity)   rb_define_singleton_method((obj), (mid), (VALUE (*)(ANYARGS))(func), (arity))
#define rb_define_protected_method(klass, mid, func, arity) rb_define_protected_method((klass), (mid), (VALUE (*)(ANYARGS))(func), (arity))
#define rb_define_private_method(klass, mid, func, arity)   rb_define_private_method((klass), (mid), (VALUE (*)(ANYARGS))(func), (arity))
#define rb_define_module_function(mod, mid, func, arity)    rb_define_module_function((mod), (mid), (VALUE (*)(ANYARGS))(func), (arity))
#define rb_define_global_function(mid, func, arity)         rb_define_global_function((mid), (VALUE (*)(ANYARGS))(func), (arity))

#undef RBIMPL_CAST_FN_PTR
#endif /* defined(RBIMPL_CAST_FN_PTR) && !defined(__cplusplus) */

/**
 * This  macro is  to properly  cast  a function  parameter of  *_define_method
 * family.  It  has been  around since  1.x era so  you can  maximise backwards
 * compatibility by using it.
 *
 * ```CXX
 * rb_define_method(klass, "method", RUBY_METHOD_FUNC(func), arity);
 * ```
 *
 * @param  func  A pointer to a function that implements a method.
 */
#if ! defined(RUBY_DEVEL)
# define RUBY_METHOD_FUNC(func) RBIMPL_CAST((VALUE (*)(ANYARGS))(func))

#elif ! RUBY_DEVEL
# define RUBY_METHOD_FUNC(func) RBIMPL_CAST((VALUE (*)(ANYARGS))(func))

#elif ! defined(rb_define_method)
# define RUBY_METHOD_FUNC(func) RBIMPL_CAST((VALUE (*)(ANYARGS))(func))

#else
# define RUBY_METHOD_FUNC(func) (func)

#endif

#endif /* RBIMPL_ANYARGS_H */
ruby/internal/error.h000064400000051661151732674170010671 0ustar00#ifndef RBIMPL_ERROR_H                               /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ERROR_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Declares ::rb_raise().
 */
#include "ruby/internal/attr/cold.h"
#include "ruby/internal/attr/format.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"

/**
 * @defgroup exception Exception handlings
 * @{
 */

/**
 * Warning  categories.  A  warning issued  using this  API can  be selectively
 * requested   /   suppressed   by   the  end-users.   For   instance   passing
 * `-W:no-deprecated`  to the  ruby process  would suppress  those warnings  in
 * deprecated category.
 *
 * @warning    There is no way to declare a new category (for now).
 */
typedef enum {
    /** Category unspecified. */
    RB_WARN_CATEGORY_NONE,

    /** Warning is for deprecated features. */
    RB_WARN_CATEGORY_DEPRECATED,

    /** Warning is for experimental features. */
    RB_WARN_CATEGORY_EXPERIMENTAL,

    /** Warning is for performance issues (not enabled by -w). */
    RB_WARN_CATEGORY_PERFORMANCE,

    /** Warning is for checking unused block strictly */
    RB_WARN_CATEGORY_STRICT_UNUSED_BLOCK,

    RB_WARN_CATEGORY_DEFAULT_BITS = (
        (1U << RB_WARN_CATEGORY_DEPRECATED) |
        (1U << RB_WARN_CATEGORY_EXPERIMENTAL) |
        0),

    RB_WARN_CATEGORY_ALL_BITS = (
        (1U << RB_WARN_CATEGORY_DEPRECATED) |
        (1U << RB_WARN_CATEGORY_EXPERIMENTAL) |
        (1U << RB_WARN_CATEGORY_PERFORMANCE) |
        (1U << RB_WARN_CATEGORY_STRICT_UNUSED_BLOCK) |
        0)
} rb_warning_category_t;

/** for rb_readwrite_sys_fail first argument */
enum rb_io_wait_readwrite {RB_IO_WAIT_READABLE, RB_IO_WAIT_WRITABLE};
/** @cond INTERNAL_MACRO */
#define RB_IO_WAIT_READABLE RB_IO_WAIT_READABLE
#define RB_IO_WAIT_WRITABLE RB_IO_WAIT_WRITABLE
/** @endcond */

RBIMPL_SYMBOL_EXPORT_BEGIN()

/**
 * This is the same as `$!` in Ruby.
 *
 * @retval   RUBY_Qnil  Not handling exceptions at the moment.
 * @retval   otherwise  The current exception in the current thread.
 * @ingroup  exception
 */
VALUE rb_errinfo(void);

/**
 * Sets the current exception (`$!`) to the given value.
 *
 * @param[in]  err            An instance of ::rb_eException, or ::RUBY_Qnil.
 * @exception  rb_eTypeError  What  is given  was  neither ::rb_eException  nor
 *                            ::RUBY_Qnil.
 * @note       Use  rb_raise()  instead to  raise  `err`.   This function  just
 *             assigns the given object to the global variable.
 * @ingroup    exception
 */
void rb_set_errinfo(VALUE err);

RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_NONNULL((2))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 3)
/**
 * Exception  entry point.   By calling  this  function the  execution of  your
 * program gets interrupted to "raise" an  exception up to the callee entities.
 * Programs could "rescue" that exception, or could "ensure" some part of them.
 * If nobody cares  about such things, the raised exception  reaches at the top
 * of execution.  This yields abnormal end of the process.
 *
 * @param[in]  exc  A subclass of ::rb_eException.
 * @param[in]  fmt  Format specifier string compatible with rb_sprintf().
 * @exception  exc  The specified exception.
 * @note       It never returns.
 */
void rb_raise(VALUE exc, const char *fmt, ...);

RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_NONNULL((1))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 1, 2)
/**
 * Raises the unsung "fatal" exception.  This is considered severe.  Nobody can
 * rescue  the  exception.  Once  raised,  process  termination is  inevitable.
 * However ensure clauses still run, so that resources are properly cleaned up.
 *
 * @param[in]  fmt        Format specifier string compatible with rb_sprintf().
 * @exception  rb_eFatal  An exception that you cannot rescue.
 * @note       It never returns.
 */
void rb_fatal(const char *fmt, ...);

RBIMPL_ATTR_COLD()
RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_NONNULL((1))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 1, 2)
/**
 * Interpreter  panic  switch.   Immediate   process  termination  without  any
 * synchronisations shall  occur.  LOTS of  internal states, stack  traces, and
 * even  machine registers  are displayed  if possible  for debugging  purposes
 * then.
 *
 * @warning    Do not use this API.
 * @warning    You are not expected to use this API.
 * @warning    Why not just fix your code instead of calling this API?
 * @warning    It was a  bad idea to expose this API  to extension libraries at
 *             the first  place.  We just  cannot delete  it at this  point for
 *             backwards  compatibility.    That  doesn't  mean   everyone  are
 *             welcomed to call this function at will.
 * @param[in]  fmt  Format specifier string compatible with rb_sprintf().
 * @note       It never returns.
 */
void rb_bug(const char *fmt, ...);

RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_NONNULL(())
/**
 * This is  a wrapper  of rb_bug()  which automatically  constructs appropriate
 * message from the passed errno.
 *
 * @param[in]  msg  Additional message to display.
 * @exception  err  C level errno.
 * @note       It never returns.
 */
void rb_bug_errno(const char *msg, int err);

RBIMPL_ATTR_NORETURN()
/**
 * Converts a C errno into a Ruby exception, then raises it.  For instance:
 *
 * ```CXX
 * static VALUE
 * foo(VALUE argv)
 * {
 *    const auto cmd = StringValueCStr(argv);
 *    const auto waitr = system(cmd);
 *    if (waitr == -1) {
 *        rb_sys_fail("system(3posix)"); // <-------------- this
 *    }
 *    else {
 *        return INT2FIX(fd);
 *    }
 * }
 * ```
 *
 * @param[in]  msg                  Additional message to raise.
 * @exception  rb_eSystemCallError  An exception representing errno.
 * @note       It never returns.
 */
void rb_sys_fail(const char *msg);

RBIMPL_ATTR_NORETURN()
/**
 * Identical to  rb_sys_fail(), except  it takes the  message in  Ruby's String
 * instead of C's.
 *
 * @param[in]  msg                  Additional message to raise.
 * @exception  rb_eSystemCallError  An exception representing errno.
 * @note       It never returns.
 */
void rb_sys_fail_str(VALUE msg);

RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_NONNULL((2))
/**
 * Identical to rb_sys_fail(), except it  takes additional module to extend the
 * exception object before raising.
 *
 * @param[in]  mod                  A ::rb_cModule instance.
 * @param[in]  msg                  Additional message to raise.
 * @exception  rb_eSystemCallError  An exception representing errno.
 * @note       It never returns.
 *
 * @internal
 *
 * Does anybody use it?
 */
void rb_mod_sys_fail(VALUE mod, const char *msg);

RBIMPL_ATTR_NORETURN()
/**
 * Identical to rb_mod_sys_fail(), except it takes the message in Ruby's String
 * instead of C's.
 *
 * @param[in]  mod                  A ::rb_cModule instance.
 * @param[in]  msg                  Additional message to raise.
 * @exception  rb_eSystemCallError  An exception representing errno.
 * @note       It never returns.
 */
void rb_mod_sys_fail_str(VALUE mod, VALUE msg);

RBIMPL_ATTR_NORETURN()
/**
 * Raises appropriate exception using the parameters.
 *
 * In Ruby level there are  rb_eEAGAINWaitReadable etc.  This function maps the
 * given parameter to an appropriate exception class, then raises it.
 *
 * @param[in]  waiting  Reason for the IO to wait.
 * @param[in]  msg      Additional message to raise.
 * @exception  rb_eEAGAINWaitWritable
 * @exception  rb_eEWOULDBLOCKWaitWritable
 * @exception  rb_eEINPROGRESSWaitWritable
 * @exception  rb_eEAGAINWaitReadable
 * @exception  rb_eEWOULDBLOCKWaitReadable
 * @exception  rb_eEINPROGRESSWaitReadable
 * @exception  rb_eSystemCallError
 * @note       It never returns.
 */
void rb_readwrite_sys_fail(enum rb_io_wait_readwrite waiting, const char *msg);

RBIMPL_ATTR_NORETURN()
/**
 * Breaks from a block.  Because you are  using a CAPI this is not as intuitive
 * as  it  sounds.   In order  for  this  function  to  properly work,  make  a
 * ::rb_block_call_func_t  function that  calls  it internally,  and pass  that
 * function to rb_block_call().
 *
 * @exception  rb_eLocalJumpError  Called from outside of a block.
 * @note       It never returns.
 */
void rb_iter_break(void);

RBIMPL_ATTR_NORETURN()
/**
 * Identical to  rb_iter_break(), except it  additionally takes the  "value" of
 * this breakage.  It  will be the evaluation result of  the iterator.  This is
 * kind  of  complicated; you  cannot  see  this as  a  "return  from a  block"
 * behaviour.  Take a look at this example:
 *
 * ```ruby
 * def foo(q)
 *   puts(w = yield(q))
 *   puts(e = yield(w))
 *   puts(r = yield(e))
 *   puts(t = yield(r))
 *   puts(y = yield(t))
 *   return "howdy!"
 * end
 *
 * x = foo(0) {|i|
 *   if i > 2
 *     break "hello!"
 *   else
 *     next i + 1
 *   end
 * }
 *
 * puts x
 * ```
 *
 * This script outputs 1, 2, 3, and hello.  Note that the value passed to break
 * becomes the  return value of  foo method, not the  value of yield.   This is
 * confusing, but  can be  handy on occasions  e.g.  when you  want to  bring a
 * local variable out of a block.
 *
 * @param[in]  val                 The value of the iterator.
 * @exception  rb_eLocalJumpError  Called from outside of a block.
 * @note       It never returns.
 */
void rb_iter_break_value(VALUE val);

RBIMPL_ATTR_NORETURN()
/**
 * Terminates the current execution context.  This  API is the entry point of a
 * "well-mannered"  termination  sequence.   When   called  from  an  extension
 * library, it  raises ::rb_eSystemExit exception.  Programs  could rescue that
 * exception.  Can cancel process exit then.  Otherwise, that exception results
 * in a process termination with the status passed to this function.
 *
 * @param[in]  status          Exit status, see also exit(3).
 * @exception  rb_eSystemExit  Exception representing the exit status.
 * @note       It never returns.
 *
 * @internal
 *
 * "When called from  an extension library"?  You might wonder.   In fact there
 * are chances for this function to be  called from outside of it, for instance
 * when dlopen(3)  failed.  In  case it  is not possible  for this  function to
 * raise an exception,  it does not (silently enters to  process cleanup).  But
 * that  is a  kind of  implementation detail  which extension  library authors
 * should not bother.
 */
void rb_exit(int status);

RBIMPL_ATTR_NORETURN()
/**
 * @exception  rb_eNotImpError
 * @note       It never returns.
 */
void rb_notimplement(void);

/**
 * Creates an exception object that represents the given C errno.
 *
 * @param[in]  err                  C level errno.
 * @param[in]  msg                  Additional message.
 * @retval     rb_eSystemCallError  An exception for the errno.
 */
VALUE rb_syserr_new(int err, const char * msg);

/**
 * Identical to rb_syserr_new(),  except it takes the message  in Ruby's String
 * instead of C's.
 *
 * @param[in]  n                    C level errno.
 * @param[in]  arg                  Additional message.
 * @retval     rb_eSystemCallError  An exception for the errno.
 */
VALUE rb_syserr_new_str(int n, VALUE arg);

RBIMPL_ATTR_NORETURN()
/**
 * Raises appropriate exception that represents a C errno.
 *
 * @param[in]  err                  C level errno.
 * @param[in]  msg                  Additional message to raise.
 * @exception  rb_eSystemCallError  An exception representing `err`.
 * @note       It never returns.
 */
void rb_syserr_fail(int err, const char *msg);

RBIMPL_ATTR_NORETURN()
/**
 * Identical to rb_syserr_fail(), except it  takes the message in Ruby's String
 * instead of C's.
 *
 * @param[in]  err                  C level errno.
 * @param[in]  msg                  Additional message to raise.
 * @exception  rb_eSystemCallError  An exception representing `err`.
 * @note       It never returns.
 */
void rb_syserr_fail_str(int err, VALUE msg);

RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_NONNULL(())
/**
 * Identical  to rb_mod_sys_fail(),  except  it  does not  depend  on C  global
 * variable errno.  Pass it explicitly.
 *
 * @param[in]  mod                  A ::rb_cModule instance.
 * @param[in]  err                  C level errno.
 * @param[in]  msg                  Additional message to raise.
 * @exception  rb_eSystemCallError  An exception representing `err`.
 * @note       It never returns.
 */
void rb_mod_syserr_fail(VALUE mod, int err, const char *msg);

RBIMPL_ATTR_NORETURN()
/**
 * Identical to  rb_mod_syserr_fail(), except  it takes  the message  in Ruby's
 * String instead of C's.
 *
 * @param[in]  mod                  A ::rb_cModule instance.
 * @param[in]  err                  C level errno.
 * @param[in]  msg                  Additional message to raise.
 * @exception  rb_eSystemCallError  An exception representing `err`.
 * @note       It never returns.
 */
void rb_mod_syserr_fail_str(VALUE mod, int err, VALUE msg);

RBIMPL_ATTR_NORETURN()
/**
 * Identical to rb_readwrite_sys_fail(), except it  does not depend on C global
 * variable errno.  Pass it explicitly.
 *
 * @param[in]  waiting  Reason for the IO to wait.
 * @param[in]  err      C level errno.
 * @param[in]  msg      Additional message to raise.
 * @exception  rb_eEAGAINWaitWritable
 * @exception  rb_eEWOULDBLOCKWaitWritable
 * @exception  rb_eEINPROGRESSWaitWritable
 * @exception  rb_eEAGAINWaitReadable
 * @exception  rb_eEWOULDBLOCKWaitReadable
 * @exception  rb_eEINPROGRESSWaitReadable
 * @exception  rb_eSystemCallError
 * @note       It never returns.
 */
void rb_readwrite_syserr_fail(enum rb_io_wait_readwrite waiting, int err, const char *msg);

RBIMPL_ATTR_COLD()
RBIMPL_ATTR_NORETURN()
/**
 * Fails with the given object's type incompatibility to the type.
 *
 * It  seems this  function is  visible from  extension libraries  only because
 * RTYPEDDATA_TYPE() uses  it on RUBY_DEBUG.   So you can basically  ignore it;
 * use some other fine-grained method instead.
 *
 * @param[in]  self           The object in question.
 * @param[in]  t              Expected type of the object.
 * @exception  rb_eTypeError  `self` not in type `t`.
 * @note       It never returns.
 * @note       The second  argument must  have been an  enum ::ruby_value_type,
 *             but for  historical reasons it  remains to  be an int  (in other
 *             words we see no benefits fixing this bug).
 */
void rb_unexpected_type(VALUE self, int t);

/**
 * @private
 *
 * This  is an  implementation detail  of #ruby_verbose.   Please don't  use it
 * directly.
 *
 * @retval  Qnil       Interpreter is quiet.
 * @retval  Qfalse     Interpreter is kind of chatty.
 * @retval  otherwise  Interpreter is very verbose.
 */
VALUE *rb_ruby_verbose_ptr(void);

/**
 * @private
 *
 * This  is an  implementation  detail  of #ruby_debug.   Please  don't use  it
 * directly.
 *
 * @retval  Qnil       Interpreter not in debug mode.
 * @retval  Qfalse     Interpreter not in debug mode.
 * @retval  otherwise  Interpreter is in debug mode.
 */
VALUE *rb_ruby_debug_ptr(void);

/**
 * This variable  controls whether the  interpreter is in debug  mode.  Setting
 * this  to  some truthy  value  is  equivalent to  passing  `-W`  flag to  the
 * interpreter.  Setting this  to ::Qfalse is equivalent to  passing `-W1` flag
 * to the interpreter.   Setting this to ::Qnil is equivalent  to passing `-W0`
 * flag to the interpreter.
 *
 * @retval  Qnil       Interpreter is quiet.
 * @retval  Qfalse     Interpreter is kind of chatty.
 * @retval  otherwise  Interpreter is very verbose.
 */
#define ruby_verbose (*rb_ruby_verbose_ptr())

/**
 * This variable  controls whether the  interpreter is in debug  mode.  Setting
 * this  to  some truthy  value  is  equivalent to  passing  `-d`  flag to  the
 * interpreter.
 *
 * @retval  Qnil       Interpreter not in debug mode.
 * @retval  Qfalse     Interpreter not in debug mode.
 * @retval  otherwise  Interpreter is in debug mode.
 */
#define ruby_debug   (*rb_ruby_debug_ptr())

/* reports if $VERBOSE is true */
RBIMPL_ATTR_NONNULL((1))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 1, 2)
/**
 * Issues a warning.
 *
 * In  ruby, warnings  these  days  are tightly  coupled  with the  rb_mWarning
 * constant and its `warn` singleton method.   This CAPI is just a thin wrapper
 * of it;  everything passed  are formatted like  what rb_sprintf()  does, then
 * passed  through   to  the  method.    Programs  can  have  their   own  `def
 * Warning.warn` at will  to do whatever they want, from  ignoring the warnings
 * at all to sinking them to some  BigQuery data set via a Fluentd cluster.  By
 * default,  the method  just emits  its passed  contents to  ::rb_stderr using
 * rb_io_write().
 *
 * @note       This function is affected by the value of $VERBOSE, it does
 *             nothing unless $VERBOSE is true.
 * @param[in]  fmt  Format specifier string compatible with rb_sprintf().
 *
 * @internal
 *
 * Above description is in fact inaccurate.  This API interfaces with Ractors.
 */
void rb_warning(const char *fmt, ...);

RBIMPL_ATTR_NONNULL((2))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 3)
/**
 * Identical to rb_warning(), except it takes additional "category" parameter.
 *
 * @param[in]  cat  Name of a known category.
 * @param[in]  fmt  Format specifier string compatible with rb_sprintf().
 */
void rb_category_warning(rb_warning_category_t cat, const char *fmt, ...);

RBIMPL_ATTR_NONNULL((1, 3))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 3, 4)
/**
 * Issues a compile-time warning  that happens at `__file__:__line__`.  Purpose
 * of this function being exposed to CAPI is unclear.
 *
 * @note       This function is affected by the value of $VERBOSE.
 * @param[in]  file  The path corresponding to Ruby level `__FILE__`.
 * @param[in]  line  The number corresponding to Ruby level `__LINE__`.
 * @param[in]  fmt   Format specifier string compatible with rb_sprintf().
 */
void rb_compile_warning(const char *file, int line, const char *fmt, ...);

RBIMPL_ATTR_NONNULL((1))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 1, 2)
/**
 * Identical to rb_sys_fail(), except it does  not raise an exception to render
 * a warning instead.
 *
 * @note       This function is affected by the value of $VERBOSE.
 * @param[in]  fmt  Format specifier string compatible with rb_sprintf().
 */
void rb_sys_warning(const char *fmt, ...);

/* reports if $VERBOSE is not nil (so if it is true or false) */
RBIMPL_ATTR_COLD()
RBIMPL_ATTR_NONNULL((1))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 1, 2)
/**
 * Identical to rb_warning(), except it reports unless $VERBOSE is nil.
 *
 * @note       This function is affected by the value of $VERBOSE, it does
 *             nothing if $VERBOSE is nil.
 * @param[in]  fmt  Format specifier string compatible with rb_sprintf().
 */
void rb_warn(const char *fmt, ...);

RBIMPL_ATTR_COLD()
RBIMPL_ATTR_NONNULL((2))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 3)
/**
 * Identical to rb_category_warning(), except it reports unless $VERBOSE is nil.
 *
 * @param[in]  cat  Category e.g. deprecated.
 * @param[in]  fmt  Format specifier string compatible with rb_sprintf().
 */
void rb_category_warn(rb_warning_category_t cat, const char *fmt, ...);

RBIMPL_ATTR_NONNULL((1, 3))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 3, 4)
/**
 * Identical to rb_compile_warning(), except  it reports unless $VERBOSE is nil.
 *
 * @param[in]  file  The path corresponding to Ruby level `__FILE__`.
 * @param[in]  line  The number corresponding to Ruby level `__LINE__`.
 * @param[in]  fmt   Format specifier string compatible with rb_sprintf().
 */
void rb_compile_warn(const char *file, int line, const char *fmt, ...);

RBIMPL_ATTR_NONNULL((2, 4))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 4, 5)
/**
 * Identical to  rb_compile_warn(), except  it also accepts category.
 *
 * @param[in]  cat   Category e.g. deprecated.
 * @param[in]  file  The path corresponding to Ruby level `__FILE__`.
 * @param[in]  line  The number corresponding to Ruby level `__LINE__`.
 * @param[in]  fmt   Format specifier string compatible with rb_sprintf().
 */
void rb_category_compile_warn(rb_warning_category_t cat, const char *file, int line, const char *fmt, ...);

/** @} */

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_ERROR_H */
ruby/internal/config.h000064400000011431151732674170010774 0ustar00#ifndef RBIMPL_CONFIG_H                              /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_CONFIG_H
/**
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Thin wrapper to ruby/config.h
 */
#include "ruby/config.h"

#ifdef RUBY_EXTCONF_H
# include RUBY_EXTCONF_H
#endif

#include "ruby/internal/compiler_since.h"

#undef  HAVE_PROTOTYPES
#define HAVE_PROTOTYPES 1

#undef  HAVE_STDARG_PROTOTYPES
#define HAVE_STDARG_PROTOTYPES 1

#undef  TOKEN_PASTE
#define TOKEN_PASTE(x,y) x##y

#if defined(__cplusplus)
#/* __builtin_choose_expr and __builtin_types_compatible aren't available
# * on C++.  See https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html */
# undef HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P
# undef HAVE_BUILTIN___BUILTIN_TYPES_COMPATIBLE_P

/* HAVE_VA_ARGS_MACRO is for C.  C++ situations might be different. */
# undef HAVE_VA_ARGS_MACRO
# if __cplusplus >= 201103L
#  define HAVE_VA_ARGS_MACRO
# elif defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__
#  define HAVE_VA_ARGS_MACRO
# elif defined(__INTEL_CXX11_MODE__)
#  define HAVE_VA_ARGS_MACRO
# elif RBIMPL_COMPILER_SINCE(MSVC, 16, 0, 0)
#  define HAVE_VA_ARGS_MACRO
# else
#  /* NG, not known. */
# endif
#endif

#if RBIMPL_COMPILER_BEFORE(GCC, 4, 9, 0)
# /* See https://bugs.ruby-lang.org/issues/14221 */
# undef HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P
#endif

#if RBIMPL_COMPILER_BEFORE(GCC, 5, 0, 0)
# /* GCC 4.9.2 reportedly has this feature  and is broken.  The function is not
#  * officially documented below.  Seems we should not use it.
#  * https://gcc.gnu.org/onlinedocs/gcc-4.9.4/gcc/Other-Builtins.html */
# undef HAVE_BUILTIN___BUILTIN_ALLOCA_WITH_ALIGN
#endif

#if defined(__SUNPRO_CC)
# /* Oracle  Developer Studio  12.5: GCC compatibility guide  says it  supports
#  * statement expressions.   But to our  knowledge they support  the extension
#  * only for C and not for C++.  Prove  me wrong.  Am happy to support them if
#  * there is a way. */
# undef HAVE_STMT_AND_DECL_IN_EXPR
#endif

#ifndef STRINGIZE0
# define STRINGIZE(expr) STRINGIZE0(expr)
# define STRINGIZE0(expr) #expr
#endif

#ifdef AC_APPLE_UNIVERSAL_BUILD
# undef WORDS_BIGENDIAN
# ifdef __BIG_ENDIAN__
#  define WORDS_BIGENDIAN
# endif
#endif

#ifndef DLEXT_MAXLEN
# define DLEXT_MAXLEN 4
#endif

#ifndef RUBY_PLATFORM
# define RUBY_PLATFORM "unknown-unknown"
#endif

#ifdef UNALIGNED_WORD_ACCESS
# /* Take that. */
#elif defined(__i386)
# define UNALIGNED_WORD_ACCESS 1
#elif defined(__i386__)
# define UNALIGNED_WORD_ACCESS 1
#elif defined(_M_IX86)
# define UNALIGNED_WORD_ACCESS 1
#elif defined(__x86_64)
# define UNALIGNED_WORD_ACCESS 1
#elif defined(__x86_64__)
# define UNALIGNED_WORD_ACCESS 1
#elif defined(_M_AMD64)
# define UNALIGNED_WORD_ACCESS 1
#elif defined(__powerpc64__)
# define UNALIGNED_WORD_ACCESS 1
#elif defined(__POWERPC__) // __POWERPC__ is defined for ppc and ppc64 on Darwin
# define UNALIGNED_WORD_ACCESS 1
#elif defined(__aarch64__)
# define UNALIGNED_WORD_ACCESS 1
#elif defined(__mc68020__)
# define UNALIGNED_WORD_ACCESS 1
#else
# define UNALIGNED_WORD_ACCESS 0
#endif

/* Detection of __VA_OPT__ */
#if ! defined(HAVE_VA_ARGS_MACRO)
# undef HAVE___VA_OPT__

#elif defined(__cplusplus)
# if __cplusplus > 201703L
#  define HAVE___VA_OPT__
# else
#  undef HAVE___VA_OPT__
# endif
#else
# /* Idea taken from: https://stackoverflow.com/a/48045656 */
# define RBIMPL_TEST3(q, w, e, ...) e
# define RBIMPL_TEST2(...)          RBIMPL_TEST3(__VA_OPT__(,),1,0,0)
# define RBIMPL_TEST1()             RBIMPL_TEST2("ruby")
# if RBIMPL_TEST1()
#  define HAVE___VA_OPT__
# else
#  undef HAVE___VA_OPT__
# endif
# undef RBIMPL_TEST1
# undef RBIMPL_TEST2
# undef RBIMPL_TEST3
#endif /* HAVE_VA_ARGS_MACRO */

#endif /* RBIMPL_CONFIG_H */
ruby/internal/stdalign.h000064400000011125151732674170011334 0ustar00#ifndef RBIMPL_STDALIGN_H                            /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_STDALIGN_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_ALIGNAS / #RBIMPL_ALIGNOF
 */
#include "ruby/internal/config.h"

#ifdef STDC_HEADERS
# include <stddef.h>
#endif

#include "ruby/internal/compiler_is.h"
#include "ruby/internal/has/attribute.h"
#include "ruby/internal/has/declspec_attribute.h"
#include "ruby/internal/has/feature.h"

/**
 * Wraps (or simulates) `alignas`. This is C++11's `alignas` and is _different_
 * from C11 `_Alignas`.  For instance,
 *
 * ```CXX
 * typedef struct alignas(128) foo { int foo } foo;
 * ```
 *
 * is a valid C++ while
 *
 * ```C
 * typedef struct _Alignas(128) foo { int foo } foo;
 * ```
 *
 * is an invalid C because:
 *
 * - You cannot `struct _Alignas`.
 * - A `typedef` cannot have alignments.
 */
#if defined(__cplusplus) && RBIMPL_HAS_FEATURE(cxx_alignas)
# define RBIMPL_ALIGNAS alignas

#elif defined(__cplusplus) && (__cplusplus >= 201103L)
# define RBIMPL_ALIGNAS alignas

#elif defined(__INTEL_CXX11_MODE__)
# define RBIMPL_ALIGNAS alignas

#elif defined(__GXX_EXPERIMENTAL_CXX0X__)
# define RBIMPL_ALIGNAS alignas

#elif RBIMPL_HAS_DECLSPEC_ATTRIBUTE(align)
# define RBIMPL_ALIGNAS(_) __declspec(align(_))

#elif RBIMPL_HAS_ATTRIBUTE(aligned)
# define RBIMPL_ALIGNAS(_) __attribute__((__aligned__(_)))

#else
# define RBIMPL_ALIGNAS(_) /* void */
#endif

/**
 * Wraps (or simulates) `alignof`.
 *
 * We want C11's `_Alignof`.  However in spite of its clear language, compilers
 * (including GCC  and clang) tend to  have buggy implementations.  We  have to
 * avoid such things to resort to our own version.
 *
 * @see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52023
 * @see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560
 * @see https://bugs.llvm.org/show_bug.cgi?id=26547
 */
#if defined(__DOXYGEN__)
# define RBIMPL_ALIGNOF alignof
#elif defined(__cplusplus)
# /* C++11 `alignof()` can be buggy. */
# /* see: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69560 */
# /* But don't worry, we can use templates. */
# define RBIMPL_ALIGNOF(T) (static_cast<size_t>(ruby::rbimpl_alignof<T>::value))

namespace ruby {
template<typename T>
struct rbimpl_alignof {
    typedef struct {
        char _;
        T t;
    } type;

    enum {
        value = offsetof(type, t)
    };
};
}

#elif RBIMPL_COMPILER_IS(MSVC)
# /* Windows have no alignment glitch.*/
# define RBIMPL_ALIGNOF __alignof

#elif defined(HAVE__ALIGNOF)
# /* Autoconf detected availability of a sane `_Alignof()`. */
# define RBIMPL_ALIGNOF(T) RB_GNUC_EXTENSION(_Alignof(T))

#else
# /* :BEWARE:  This is  the last  resort.   If your  compiler somehow  supports
#  * querying the alignment of a type,  you definitely should use that instead.
#  * There are 2 known pitfalls for this fallback implementation:
#  *
#  * First, it is either an undefined  behaviour (C) or an explicit error (C++)
#  * to define a  struct inside of `offsetof`.  C compilers  tend to accept such
#  * things, but AFAIK C++ has no room to allow.
#  *
#  * Second, there exist T  such that `struct { char _; T t;  }` is invalid.  A
#  * known example is  when T is a  struct with a flexible  array member.  Such
#  * struct cannot be enclosed into another one.
#  */
# /* see: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2083.htm */
# /* see: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm */
# define RBIMPL_ALIGNOF(T) offsetof(struct { char _; T t; }, t)

#endif

#endif /* RBIMPL_STDALIGN_H */
ruby/internal/xmalloc.h000064400000034267151732674200011174 0ustar00#ifndef RBIMPL_XMALLOC_H                             /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_XMALLOC_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Declares ::ruby_xmalloc().
 */
#include "ruby/internal/config.h"

#ifdef STDC_HEADERS
# include <stddef.h>
#endif

#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif

#include "ruby/internal/attr/alloc_size.h"
#include "ruby/internal/attr/nodiscard.h"
#include "ruby/internal/attr/noexcept.h"
#include "ruby/internal/attr/restrict.h"
#include "ruby/internal/attr/returns_nonnull.h"
#include "ruby/internal/dllexport.h"

/**
 * @private
 * @warning  Do not touch this macro.
 * @warning  It is an implementation detail.
 * @warning  It was a failure at the first place to let you know about it.
 * @warning  The  value of  this  macro  must match  for  ruby  itself and  all
 *           extension  libraries, otherwise  serious  memory corruption  shall
 *           occur.
 */
#ifndef USE_GC_MALLOC_OBJ_INFO_DETAILS
# define USE_GC_MALLOC_OBJ_INFO_DETAILS 0
#endif

#define xmalloc   ruby_xmalloc   /**< @old{ruby_xmalloc} */
#define xmalloc2  ruby_xmalloc2  /**< @old{ruby_xmalloc2} */
#define xcalloc   ruby_xcalloc   /**< @old{ruby_xcalloc} */
#define xrealloc  ruby_xrealloc  /**< @old{ruby_xrealloc} */
#define xrealloc2 ruby_xrealloc2 /**< @old{ruby_xrealloc2} */
#define xfree     ruby_xfree     /**< @old{ruby_xfree} */

RBIMPL_SYMBOL_EXPORT_BEGIN()

RBIMPL_ATTR_NODISCARD()
RBIMPL_ATTR_RESTRICT()
RBIMPL_ATTR_RETURNS_NONNULL()
RBIMPL_ATTR_ALLOC_SIZE((1))
/**
 * Allocates a  storage instance.  It is  largely the same as  system malloc(),
 * except:
 *
 *   - It raises Ruby exceptions instead of returning NULL, and
 *   - In case of `ENOMEM` it tries to GC to make some room.
 *
 * @param[in]  size            Requested amount of memory.
 * @exception  rb_eNoMemError  No space left for `size` bytes allocation.
 * @return     A valid pointer  to an allocated storage instance;  which has at
 *             least `size` bytes width, with appropriate alignment detected by
 *             the underlying malloc() routine.
 * @note       It doesn't return NULL.
 * @note       Unlike some malloc() implementations, it allocates something and
 *             returns a meaningful value even when `size` is equal to zero.
 * @warning    The return  value shall  be invalidated  exactly once  by either
 *             ruby_xfree(),  ruby_xrealloc(), or  ruby_xrealloc2().   It is  a
 *             failure to pass it to system free(), because the system and Ruby
 *             might or might not share the same malloc() implementation.
 */
void *ruby_xmalloc(size_t size)
RBIMPL_ATTR_NOEXCEPT(malloc(size))
;

RBIMPL_ATTR_NODISCARD()
RBIMPL_ATTR_RESTRICT()
RBIMPL_ATTR_RETURNS_NONNULL()
RBIMPL_ATTR_ALLOC_SIZE((1,2))
/**
 * Identical to ruby_xmalloc(), except it allocates `nelems` * `elemsiz` bytes.
 * This is needed  because the multiplication could integer  overflow.  On such
 * situations  Ruby does  not try  to  allocate at  all but  raises Ruby  level
 * exceptions  instead.  If  there  is  no integer  overflow  the behaviour  is
 * exactly the same as `ruby_xmalloc(nelems*elemsiz)`.
 *
 * @param[in]  nelems          Number of elements.
 * @param[in]  elemsiz         Size of an element.
 * @exception  rb_eNoMemError  No space left for allocation.
 * @exception  rb_eArgError    `nelems` * `elemsiz` would overflow.
 * @return     A valid pointer  to an allocated storage instance;  which has at
 *             least  `nelems`  *  `elemsiz`   bytes  width,  with  appropriate
 *             alignment detected by the underlying malloc() routine.
 * @note       It doesn't return NULL.
 * @note       Unlike some malloc() implementations, it allocates something and
 *             returns a  meaningful value even  when `nelems` or  `elemsiz` or
 *             both are zero.
 * @warning    The return  value shall  be invalidated  exactly once  by either
 *             ruby_xfree(),  ruby_xrealloc(), or  ruby_xrealloc2().   It is  a
 *             failure to pass it to system free(), because the system and Ruby
 *             might or might not share the same malloc() implementation.
 */
void *ruby_xmalloc2(size_t nelems, size_t elemsiz)
RBIMPL_ATTR_NOEXCEPT(malloc(nelems * elemsiz))
;

RBIMPL_ATTR_NODISCARD()
RBIMPL_ATTR_RESTRICT()
RBIMPL_ATTR_RETURNS_NONNULL()
RBIMPL_ATTR_ALLOC_SIZE((1,2))
/**
 * Identical  to  ruby_xmalloc2(),  except  it returns  a  zero-filled  storage
 * instance.  It  can also be  seen as  a routine identical  to ruby_xmalloc(),
 * except it calls calloc() instead of malloc().
 *
 * @param[in]  nelems          Number of elements.
 * @param[in]  elemsiz         Size of an element.
 * @exception  rb_eNoMemError  No space left for allocation.
 * @exception  rb_eArgError    `nelems` * `elemsiz` would overflow.
 * @return     A valid pointer  to an allocated storage instance;  which has at
 *             least  `nelems`  *  `elemsiz`   bytes  width,  with  appropriate
 *             alignment detected by the underlying calloc() routine.
 * @post       The returned storage instance is filled with zeros.
 * @note       It doesn't return NULL.
 * @note       Unlike some calloc() implementations, it allocates something and
 *             returns a  meaningful value even  when `nelems` or  `elemsiz` or
 *             both are zero.
 * @warning    The return  value shall  be invalidated  exactly once  by either
 *             ruby_xfree(),  ruby_xrealloc(), or  ruby_xrealloc2().   It is  a
 *             failure to pass it to system free(), because the system and Ruby
 *             might or might not share the same malloc() implementation.
 */
void *ruby_xcalloc(size_t nelems, size_t elemsiz)
RBIMPL_ATTR_NOEXCEPT(calloc(nelems, elemsiz))
;

RBIMPL_ATTR_NODISCARD()
RBIMPL_ATTR_RETURNS_NONNULL()
RBIMPL_ATTR_ALLOC_SIZE((2))
/**
 * Resize the storage instance.
 *
 * @param[in]  ptr             A valid  pointer to a storage  instance that was
 *                             previously returned from either:
 *                               - ruby_xmalloc(),
 *                               - ruby_xmalloc2(),
 *                               - ruby_xcalloc(),
 *                               - ruby_xrealloc(), or
 *                               - ruby_xrealloc2().
 * @param[in]  newsiz          Requested new amount of memory.
 * @exception  rb_eNoMemError  No space left for `newsiz` bytes allocation.
 * @return     A  valid  pointer  to   a  (possibly  newly  allocated)  storage
 *             instance;  which  has  at   least  `newsiz`  bytes  width,  with
 *             appropriate  alignment  detected  by  the  underlying  realloc()
 *             routine.
 * @pre        The passed pointer must point  to a valid live storage instance.
 *             It is a failure to pass an already freed pointer.
 * @post       In  case the  function  returns the  passed  pointer as-is,  the
 *             storage  instance that  the  pointer holds  is  either grown  or
 *             shrunken  to have  at least  `newsiz` bytes.  Otherwise a  valid
 *             pointer to a  newly allocated storage instance  is returned.  In
 *             this  case  `ptr`  is  invalidated   as  if  it  was  passed  to
 *             ruby_xfree().
 * @note       It doesn't return NULL.
 * @warning    Unlike some realloc() implementations,  passing zero to `newsiz`
 *             is not the  same as calling ruby_xfree(),  because this function
 *             never returns NULL.  Something meaningful still returns then.
 * @warning    It is  a failure not to  check the return value.   Do not assume
 *             anything on  it.  It could  be either identical to,  or distinct
 *             form the passed argument.
 * @warning    Do not  assume anything  on the alignment  of the  return value.
 *             There is  no guarantee  that it  inherits the  passed argument's
 *             one.
 * @warning    The return  value shall  be invalidated  exactly once  by either
 *             ruby_xfree(),  ruby_xrealloc(), or  ruby_xrealloc2().   It is  a
 *             failure to pass it to system free(), because the system and Ruby
 *             might or might not share the same malloc() implementation.
 */
void *ruby_xrealloc(void *ptr, size_t newsiz)
RBIMPL_ATTR_NOEXCEPT(realloc(ptr, newsiz))
;

RBIMPL_ATTR_NODISCARD()
RBIMPL_ATTR_RETURNS_NONNULL()
RBIMPL_ATTR_ALLOC_SIZE((2,3))
/**
 * Identical to ruby_xrealloc(),  except it resizes the  given storage instance
 * to `newelems` *  `newsiz` bytes.  This is needed  because the multiplication
 * could integer overflow.   On such situations Ruby does not  try to touch the
 * contents  of  argument pointer  at  all  but  raises Ruby  level  exceptions
 * instead.  If there is no integer  overflow the behaviour is exactly the same
 * as `ruby_xrealloc(ptr,nelems*elemsiz)`.
 *
 * This  is   roughly  the  same   as  reallocarray()  function   that  OpenBSD
 * etc. provides, but also interacts with our GC.
 *
 * @param[in]  ptr             A valid  pointer to a storage  instance that was
 *                             previously returned from either:
 *                               - ruby_xmalloc(),
 *                               - ruby_xmalloc2(),
 *                               - ruby_xcalloc(),
 *                               - ruby_xrealloc(), or
 *                               - ruby_xrealloc2().
 * @param[in]  newelems        Requested new number of elements.
 * @param[in]  newsiz          Requested new size of each element.
 * @exception  rb_eNoMemError  No space left for  allocation.
 * @exception  rb_eArgError    `newelems` * `newsiz` would overflow.
 * @return     A  valid  pointer  to   a  (possibly  newly  allocated)  storage
 *             instance; which has at least  `newelems` * `newsiz` bytes width,
 *             with appropriate alignment detected  by the underlying realloc()
 *             routine.
 * @pre        The passed pointer must point  to a valid live storage instance.
 *             It is a failure to pass an already freed pointer.
 * @post       In  case the  function  returns the  passed  pointer as-is,  the
 *             storage  instance that  the  pointer holds  is  either grown  or
 *             shrunken  to   have  at  least  `newelems`   *  `newsiz`  bytes.
 *             Otherwise a valid pointer to  a newly allocated storage instance
 *             is returned.   In this case  `ptr` is  invalidated as if  it was
 *             passed to ruby_xfree().
 * @note       It doesn't return NULL.
 * @warning    Unlike some  realloc() implementations,  passing zero  to either
 *             `newelems`   or  `elemsiz`   are   not  the   same  as   calling
 *             ruby_xfree(),   because  this   function  never   returns  NULL.
 *             Something meaningful still returns then.
 * @warning    It is  a failure not to  check the return value.   Do not assume
 *             anything on  it.  It could  be either identical to,  or distinct
 *             form the passed argument.
 * @warning    Do not  assume anything  on the alignment  of the  return value.
 *             There is  no guarantee  that it  inherits the  passed argument's
 *             one.
 * @warning    The return  value shall  be invalidated  exactly once  by either
 *             ruby_xfree(),  ruby_xrealloc(), or  ruby_xrealloc2().   It is  a
 *             failure to pass it to system free(), because the system and Ruby
 *             might or might not share the same malloc() implementation.
 */
void *ruby_xrealloc2(void *ptr, size_t newelems, size_t newsiz)
RBIMPL_ATTR_NOEXCEPT(realloc(ptr, newelems * newsiz))
;

/**
 * Deallocates a storage instance.
 *
 * @param[out]  ptr  Either
 *                     - NULL, or
 *                     - a valid pointer previously returned from one of:
 *                       - ruby_xmalloc(),
 *                       - ruby_xmalloc2(),
 *                       - ruby_xcalloc(),
 *                       - ruby_xrealloc(), or
 *                       - ruby_xrealloc2().
 * @pre         The passed pointer must point to a valid live storage instance.
 *              It is a failure to pass an already freed pointer.
 * @post        The  storage  instance  pointed  by  the  passed  pointer  gets
 *              invalidated; it is no longer addressable.
 * @warning     Every single storage instance  that was previously allocated by
 *              either    ruby_xmalloc(),   ruby_xmalloc2(),    ruby_xcalloc(),
 *              ruby_xrealloc(),  or  ruby_xrealloc2()   shall  be  invalidated
 *              exactly once by  either passing it to  ruby_xfree(), or passing
 *              it to  either ruby_xrealloc(), ruby_xrealloc2() then  check the
 *              return value for invalidation.
 * @warning     Do not pass anything other  than pointers described above.  For
 *              instance pointers returned from malloc() or mmap() shall not be
 *              passed  to   this  function,  because  the   underlying  memory
 *              management mechanism could differ.
 * @warning     Do  not pass  any invalid  pointers  to this  function e.g.  by
 *              calling it twice with a same argument.
 */
void ruby_xfree(void *ptr)
RBIMPL_ATTR_NOEXCEPT(free(ptr))
;

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_XMALLOC_H */
ruby/internal/arithmetic.h000064400000004105151732674200011652 0ustar00#ifndef RBIMPL_ARITHMETIC_H                          /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ARITHMETIC_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Conversion  between  C's arithmetic  types  and  Ruby's  numeric
 *             types.
 */
#include "ruby/internal/arithmetic/char.h"
#include "ruby/internal/arithmetic/double.h"
#include "ruby/internal/arithmetic/fixnum.h"
#include "ruby/internal/arithmetic/gid_t.h"
#include "ruby/internal/arithmetic/int.h"
#include "ruby/internal/arithmetic/intptr_t.h"
#include "ruby/internal/arithmetic/long.h"
#include "ruby/internal/arithmetic/long_long.h"
#include "ruby/internal/arithmetic/mode_t.h"
#include "ruby/internal/arithmetic/off_t.h"
#include "ruby/internal/arithmetic/pid_t.h"
#include "ruby/internal/arithmetic/short.h"
#include "ruby/internal/arithmetic/size_t.h"
#include "ruby/internal/arithmetic/st_data_t.h"
#include "ruby/internal/arithmetic/uid_t.h"
#endif /* RBIMPL_ARITHMETIC_H */
ruby/internal/core/rmatch.h000064400000012502151732674200011727 0ustar00#ifndef RBIMPL_RMATCH_H                              /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_RMATCH_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines struct ::RMatch.
 */
#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/core/rbasic.h"
#include "ruby/internal/value.h"
#include "ruby/internal/value_type.h"
#include "ruby/assert.h"

/**
 * Convenient casting macro.
 *
 * @param   obj  An object, which is in fact an ::RMatch.
 * @return  The passed object casted to ::RMatch.
 */
#define RMATCH(obj) RBIMPL_CAST((struct RMatch *)(obj))
/** @cond INTERNAL_MACRO */
#define RMATCH_REGS RMATCH_REGS
/** @endcond */

struct re_patter_buffer; /* a.k.a. OnigRegexType, defined in onigmo.h */
struct re_registers;     /* Also in onigmo.h */

/**
 * @old{re_pattern_buffer}
 *
 * @internal
 *
 * @shyouhei wonders: is anyone actively using this typedef ...?
 */
typedef struct re_pattern_buffer Regexp;

/**
 * Represents the  region of a  capture group.   This is basically  for caching
 * purpose.  re_registers have similar concepts  (`beg` and `end`) but they are
 * in `ptrdiff_t*`.  In order for  us to implement `MatchData#offset` that info
 * has to  be converted to  offset integers.  This is  the struct to  hold such
 * things.
 *
 * @internal
 *
 * But why on earth it has to be visible from extension libraries?
 */
struct rmatch_offset {
    long beg; /**< Beginning of a group. */
    long end; /**< End of a group. */
};

/** Represents a match. */
struct rb_matchext_struct {
    /**
     * "Registers"  of a  match.   This  is a  quasi-opaque  struct that  holds
     * execution result of a match.  Roughly resembles `&~`.
     */
    struct re_registers regs;

    /** Capture group offsets, in C array. */
    struct rmatch_offset *char_offset;

    /** Number of ::rmatch_offset that ::rmatch::char_offset holds. */
    int char_offset_num_allocated;
};

typedef struct rb_matchext_struct rb_matchext_t;

/**
 * Regular expression  execution context.  When a  regular expression "matches"
 * to a string, it generates capture  groups etc.  This struct holds that info.
 * Visible from Ruby as an instance of `MatchData`.
 *
 * @note  There is  no way  for extension libraries  to manually  generate this
 *        struct except by actually exercising the match operation of a regular
 *        expression.
 */
struct RMatch {

    /** Basic part, including flags and class. */
    struct RBasic basic;

    /**
     * The target string that the match was made against.
     */
    VALUE str;

    /**
     * The expression of this match.
     */
    VALUE regexp;  /* RRegexp */
};

#define RMATCH_EXT(m) ((rb_matchext_t *)((char *)(m) + sizeof(struct RMatch)))

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Queries the raw ::re_registers.
 *
 * @param[in]  match  A match object
 * @pre        `match` must be of ::RMatch.
 * @return     Its execution result.
 * @note       Good.  So you  are aware of the fact that  it could return NULL.
 *             Yes.  It  actually does.  This  is a really bizarre  thing.  The
 *             situation  is about  `String#gsub`  and its  family.  They  take
 *             strings as  arguments, like `"foo".sub("bar", "baz")`.   On such
 *             situations,  in  order  to optimise  memory  allocations,  these
 *             methods do  not involve regular  expressions at all.   They just
 *             sequentially scan  the receiver.  Okay.  The  story begins here.
 *             Even when  they do  not kick  our regexp  engine, there  must be
 *             backref objects e.g. `$&`.  But how?  You know what?  Ruby fakes
 *             them.  It  allocates an empty  ::RMatch and behaves as  if there
 *             were  execution   contexts.   In  reality  there   weren't.   No
 *             ::re_registers are  allocated then.   There is  no way  for this
 *             function but  to return NULL  for those fake ::RMatch.   This is
 *             the reason for the nullability of this function.
 */
static inline struct re_registers *
RMATCH_REGS(VALUE match)
{
    RBIMPL_ASSERT_TYPE(match, RUBY_T_MATCH);
    return &RMATCH_EXT(match)->regs;
}

#endif /* RBIMPL_RMATCH_H */
ruby/internal/core/rstring.h000064400000037127151732674200012153 0ustar00#ifndef RBIMPL_RSTRING_H                             /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_RSTRING_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines struct ::RString.
 */
#include "ruby/internal/config.h"
#include "ruby/internal/arithmetic/long.h"
#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/core/rbasic.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/fl_type.h"
#include "ruby/internal/value_type.h"
#include "ruby/internal/warning_push.h"
#include "ruby/assert.h"

/**
 * Convenient casting macro.
 *
 * @param   obj  An object, which is in fact an ::RString.
 * @return  The passed object casted to ::RString.
 */
#define RSTRING(obj)            RBIMPL_CAST((struct RString *)(obj))

/** @cond INTERNAL_MACRO */
#define RSTRING_NOEMBED         RSTRING_NOEMBED
#define RSTRING_FSTR            RSTRING_FSTR
#define RSTRING_LEN       RSTRING_LEN
#define RSTRING_LENINT    RSTRING_LENINT
#define RSTRING_PTR       RSTRING_PTR
#define RSTRING_END       RSTRING_END
/** @endcond */

/**
 * @name Conversion of Ruby strings into C's
 *
 * @{
 */

/**
 * Ensures that the parameter object is a  String.  This is done by calling its
 * `to_str` method.
 *
 * @param[in,out]  v              Arbitrary Ruby object.
 * @exception      rb_eTypeError  No implicit conversion defined.
 * @post           `v` is a String.
 */
#define StringValue(v)     rb_string_value(&(v))

/**
 * Identical to #StringValue, except it returns a `char*`.
 *
 * @param[in,out]  v              Arbitrary Ruby object.
 * @exception      rb_eTypeError  No implicit conversion defined.
 * @return         Converted Ruby string's backend C string.
 * @post           `v` is a String.
 */
#define StringValuePtr(v)  rb_string_value_ptr(&(v))

/**
 * Identical to #StringValuePtr, except it additionally checks for the contents
 * for viability  as a C  string.  Ruby can accept  wider range of  contents as
 * strings, compared to C.  This function is to check that.
 *
 * @param[in,out]  v              Arbitrary Ruby object.
 * @exception      rb_eTypeError  No implicit conversion defined.
 * @exception      rb_eArgError   String is not C-compatible.
 * @return         Converted Ruby string's backend C string.
 * @post           `v` is a String.
 */
#define StringValueCStr(v) rb_string_value_cstr(&(v))

/**
 * @private
 *
 * @deprecated  This macro once was a thing in the old days, but makes no sense
 *              any  longer today.   Exists  here  for backwards  compatibility
 *              only.  You can safely forget about it.
 */
#define SafeStringValue(v) StringValue(v)

/**
 * Identical  to #StringValue,  except  it additionally  converts the  string's
 * encoding to default external encoding.  Ruby has a concept called encodings.
 * A string can have different  encoding than the environment expects.  Someone
 * has to make  sure its contents be converted to  something suitable.  This is
 * that routine.  Call it when necessary.
 *
 * @param[in,out]  v              Arbitrary Ruby object.
 * @exception      rb_eTypeError  No implicit conversion defined.
 * @return         Converted Ruby string's backend C string.
 * @post           `v` is a String.
 *
 * @internal
 *
 * Not   sure  but   it  seems   this  macro   does  not   raise  on   encoding
 * incompatibilities?  Doesn't sound right to @shyouhei.
 */
#define ExportStringValue(v) do { \
    StringValue(v);               \
    (v) = rb_str_export(v);       \
} while (0)

/** @} */

/**
 * @private
 *
 * Bits that you can set to ::RBasic::flags.
 *
 * @warning  These enums are not the only bits we use for strings.
 *
 * @internal
 *
 * Actually all bits  through FL_USER1 to FL_USER19 are used  for strings.  Why
 * only this  tiny part of  them are made public  here?  @shyouhei can  find no
 * reason.
 */
enum ruby_rstring_flags {

    /**
     * This flag has  something to do with memory footprint.   If the string is
     * short enough, ruby tries to be  creative to abuse padding bits of struct
     * ::RString for  storing contents.  If this  flag is set that  string does
     * _not_  do that,  to resort  to  good old  fashioned external  allocation
     * strategy instead.
     *
     * @warning  This  bit has  to be  considered read-only.   Setting/clearing
     *           this  bit without  corresponding fix  up must  cause immediate
     *           SEGV.    Also,  internal   structures  of   a  string   change
     *           dynamically  and  transparently  throughout of  its  lifetime.
     *           Don't assume it being persistent.
     *
     * @internal
     *
     * 3rd parties must  not be aware that  there even is more than  one way to
     * store a string.  Might better be hidden.
     */
    RSTRING_NOEMBED         = RUBY_FL_USER1,

    /* Actually,  string  encodings are  also  encoded  into the  flags,  using
     * remaining bits.*/

    /**
     * This  flag has  something  to do  with infamous  "f"string.   What is  a
     * fstring?  Well  it is a  special subkind  of strings that  is immutable,
     * deduped globally, and managed  by our GC.  It is much  like a Symbol (in
     * fact Symbols are  dynamic these days and are  backended using fstrings).
     * This concept  has been  silently introduced  at some  point in  2.x era.
     * Since  then it  gained  wider  acceptance in  the  core.  But  extension
     * libraries could not know that until very recently.  Strings of this flag
     * live in  a special Limbo deep  inside of the interpreter.   Never try to
     * manipulate it by hand.
     *
     * @internal
     *
     * Fstrings  are not  the only  variant  strings that  we implement  today.
     * Other things are behind-the-scene.  This is the only one that is visible
     * from extension  library.  There  is no  clear reason why  it has  to be.
     * Given there are more "polite" ways to create fstrings, it seems this bit
     * need not be exposed to extension libraries.  Might better be hidden.
     */
    RSTRING_FSTR            = RUBY_FL_USER17
};

/**
 * Ruby's String.  A string in ruby conceptually has these information:
 *
 * - Encoding of the string.
 * - Length of the string.
 * - Contents of the string.
 *
 * It is worth  noting that a string  is _not_ an array of  characters in ruby.
 * It has never been.   In 1.x a string was an array of  integers.  Since 2.x a
 * string is no longer an array of anything.  A string is a string -- just like
 * a Time is not an integer.
 */
struct RString {

    /** Basic part, including flags and class. */
    struct RBasic basic;

    /**
     * Length of the string, not including terminating NUL character.
     *
     * @note  This is in bytes.
     */
    long len;

    /** String's specific fields. */
    union {

        /**
         * Strings  that use  separated  memory region  for  contents use  this
         * pattern.
         */
        struct {
            /**
             * Pointer to  the contents of  the string.   In the old  days each
             * string had  dedicated memory  regions.  That  is no  longer true
             * today,  but there  still are  strings of  such properties.  This
             * field could be used to point such things.
             */
            char *ptr;

            /** Auxiliary info. */
            union {

                /**
                 * Capacity of `*ptr`.  A continuous  memory region of at least
                 * `capa` bytes  is expected to  exist at `*ptr`.  This  can be
                 * bigger than `len`.
                 */
                long capa;

                /**
                 * Parent  of the  string.   Nowadays strings  can share  their
                 * contents each other, constructing  gigantic nest of objects.
                 * This situation is called "shared",  and this is the field to
                 * control such properties.
                 */
                VALUE shared;
            } aux;
        } heap;

        /** Embedded contents. */
        struct {
            /* This is a length 1 array because:
             *   1. GCC has a bug that does not optimize C flexible array members
             *      (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102452)
             *   2. Zero length arrays are not supported by all compilers
             */
            char ary[1];
        } embed;
    } as;
};

RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
 * Identical to rb_check_string_type(), except it  raises exceptions in case of
 * conversion failures.
 *
 * @param[in]  obj            Target object.
 * @exception  rb_eTypeError  No implicit conversion to String.
 * @return     Return value of `obj.to_str`.
 * @see        rb_io_get_io
 * @see        rb_ary_to_ary
 */
VALUE rb_str_to_str(VALUE obj);

/**
 * Identical to  rb_str_to_str(), except it  fills the passed pointer  with the
 * converted object.
 *
 * @param[in,out]  ptr            Pointer to a variable of target object.
 * @exception      rb_eTypeError  No implicit conversion to String.
 * @return         Return value of `obj.to_str`.
 * @post           `*ptr` is the return value.
 */
VALUE rb_string_value(volatile VALUE *ptr);

/**
 * Identical  to  rb_str_to_str(), except  it  returns  the converted  string's
 * backend memory region.
 *
 * @param[in,out]  ptr            Pointer to a variable of target object.
 * @exception      rb_eTypeError  No implicit conversion to String.
 * @post           `*ptr` is the return value of `obj.to_str`.
 * @return         Pointer to the contents of the return value.
 */
char *rb_string_value_ptr(volatile VALUE *ptr);

/**
 * Identical to  rb_string_value_ptr(), except  it additionally checks  for the
 * contents  for viability  as a  C  string.  Ruby  can accept  wider range  of
 * contents as strings, compared to C.  This function is to check that.
 *
 * @param[in,out]  ptr            Pointer to a variable of target object.
 * @exception      rb_eTypeError  No implicit conversion to String.
 * @exception      rb_eArgError   String is not C-compatible.
 * @post           `*ptr` is the return value of `obj.to_str`.
 * @return         Pointer to the contents of the return value.
 */
char *rb_string_value_cstr(volatile VALUE *ptr);

/**
 * Identical  to rb_str_to_str(),  except it  additionally converts  the string
 * into default  external encoding.   Ruby has a  concept called  encodings.  A
 * string can  have different encoding  than the environment  expects.  Someone
 * has to make  sure its contents be converted to  something suitable.  This is
 * that routine.  Call it when necessary.
 *
 * @param[in]  obj            Target object.
 * @exception  rb_eTypeError  No implicit conversion to String.
 * @return     Converted ruby string of default external encoding.
 */
VALUE rb_str_export(VALUE obj);

/**
 * Identical to  rb_str_export(), except it  converts into the  locale encoding
 * instead.
 *
 * @param[in]  obj            Target object.
 * @exception  rb_eTypeError  No implicit conversion to String.
 * @return     Converted ruby string of locale encoding.
 */
VALUE rb_str_export_locale(VALUE obj);

RBIMPL_ATTR_ERROR(("rb_check_safe_str() and Check_SafeStr() are obsolete; use StringValue() instead"))
/**
 * @private
 *
 * @deprecated  This function  once was a thing  in the old days,  but makes no
 *              sense   any   longer   today.   Exists   here   for   backwards
 *              compatibility only.  You can safely forget about it.
 */
void rb_check_safe_str(VALUE);

/**
 * @private
 *
 * @deprecated  This macro once was a thing in the old days, but makes no sense
 *              any  longer today.   Exists  here  for backwards  compatibility
 *              only.  You can safely forget about it.
 */
#define Check_SafeStr(v) rb_check_safe_str(RBIMPL_CAST((VALUE)(v)))

/**
 * @private
 *
 * Prints diagnostic message to stderr when RSTRING_PTR or RSTRING_END
 * is NULL.
 *
 * @param[in]  func           The function name where encountered NULL pointer.
 */
void rb_debug_rstring_null_ptr(const char *func);
RBIMPL_SYMBOL_EXPORT_END()

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Queries the length of the string.
 *
 * @param[in]  str  String in question.
 * @return     Its length, in bytes.
 * @pre        `str` must be an instance of ::RString.
 */
static inline long
RSTRING_LEN(VALUE str)
{
    return RSTRING(str)->len;
}

RBIMPL_ATTR_ARTIFICIAL()
/**
 * Queries the contents pointer of the string.
 *
 * @param[in]  str  String in question.
 * @return     Pointer to its contents.
 * @pre        `str` must be an instance of ::RString.
 */
static inline char *
RSTRING_PTR(VALUE str)
{
    char *ptr = RB_FL_TEST_RAW(str, RSTRING_NOEMBED) ?
        RSTRING(str)->as.heap.ptr :
        RSTRING(str)->as.embed.ary;

    if (RUBY_DEBUG && RB_UNLIKELY(! ptr)) {
        /* :BEWARE: @shyouhei thinks  that currently, there are  rooms for this
         * function to return  NULL.  Better check here for maximum safety.
         *
         * Also,  this is  not rb_warn()  because RSTRING_PTR()  can be  called
         * during GC (see  what obj_info() does).  rb_warn()  needs to allocate
         * Ruby objects.  That is not possible at this moment. */
        rb_debug_rstring_null_ptr("RSTRING_PTR");
    }

    return ptr;
}

RBIMPL_ATTR_ARTIFICIAL()
/**
 * Queries the end of the contents pointer of the string.
 *
 * @param[in]  str  String in question.
 * @return     Pointer to its end of contents.
 * @pre        `str` must be an instance of ::RString.
 */
static inline char *
RSTRING_END(VALUE str)
{
    char *ptr = RB_FL_TEST_RAW(str, RSTRING_NOEMBED) ?
        RSTRING(str)->as.heap.ptr :
        RSTRING(str)->as.embed.ary;
    long len = RSTRING_LEN(str);

    if (RUBY_DEBUG && RB_UNLIKELY(!ptr)) {
        /* Ditto. */
        rb_debug_rstring_null_ptr("RSTRING_END");
    }

    return &ptr[len];
}

RBIMPL_ATTR_ARTIFICIAL()
/**
 * Identical to RSTRING_LEN(), except it differs for the return type.
 *
 * @param[in]  str             String in question.
 * @exception  rb_eRangeError  Too long.
 * @return     Its length, in bytes.
 * @pre        `str` must be an instance of ::RString.
 *
 * @internal
 *
 * This API seems redundant but has actual usages.
 */
static inline int
RSTRING_LENINT(VALUE str)
{
    return rb_long2int(RSTRING_LEN(str));
}

/**
 * Convenient macro to obtain the contents and length at once.
 *
 * @param  str     String in question.
 * @param  ptrvar  Variable where its contents is stored.
 * @param  lenvar  Variable where its length is stored.
 */
# define RSTRING_GETMEM(str, ptrvar, lenvar) \
    ((ptrvar) = RSTRING_PTR(str),           \
     (lenvar) = RSTRING_LEN(str))
#endif /* RBIMPL_RSTRING_H */
ruby/internal/core/rregexp.h000064400000013002151732674200012121 0ustar00#ifndef RBIMPL_RREGEXP_H                             /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_RREGEXP_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines struct ::RRegexp.
 */
#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/core/rbasic.h"
#include "ruby/internal/core/rstring.h"
#include "ruby/internal/value.h"
#include "ruby/internal/value_type.h"

/**
 * Convenient casting macro.
 *
 * @param   obj  An object, which is in fact an ::RRegexp.
 * @return  The passed object casted to ::RRegexp.
 */
#define RREGEXP(obj)     RBIMPL_CAST((struct RRegexp *)(obj))

/**
 * Convenient accessor macro.
 *
 * @param   obj  An object, which is in fact an ::RRegexp.
 * @return  The passed object's pattern buffer.
 */
#define RREGEXP_PTR(obj) (RREGEXP(obj)->ptr)
/** @cond INTERNAL_MACRO */
#define RREGEXP_SRC      RREGEXP_SRC
#define RREGEXP_SRC_PTR  RREGEXP_SRC_PTR
#define RREGEXP_SRC_LEN  RREGEXP_SRC_LEN
#define RREGEXP_SRC_END  RREGEXP_SRC_END
/** @endcond */

struct re_patter_buffer;  /* a.k.a. OnigRegexType, defined in onigmo.h */

/**
 * Ruby's regular expression.   A regexp is compiled into  its own intermediate
 * representation.  This  one holds that  info.  Regexp "match"  operation then
 * executes that IR.
 */
struct RRegexp {

    /** Basic part, including flags and class. */
    struct RBasic basic;

    /**
     * The pattern buffer.   This is a quasi-opaque struct  that holds compiled
     * intermediate representation of the regular expression.
     *
     * @note  Compilation of a regexp could be delayed until actual match.
     */
    struct re_pattern_buffer *ptr;

    /** Source code of this expression. */
    const VALUE src;

    /**
     * Reference count.  A  regexp match can take extraordinarily  long time to
     * run.  Ruby's  regular expression is  heavily extended and not  a regular
     * language any  longer; runs in NP-time  in practice.  Now, Ruby  also has
     * threads and GVL.  In order to prevent long GVL lockup, our regexp engine
     * can release it on occasions.  This means that multiple threads can touch
     * a regular expressions at once.  That  itself is okay.  But their cleanup
     * phase shall wait for all  the concurrent runs, to prevent use-after-free
     * situation.  This field is used to  count such threads that are executing
     * this particular pattern buffer.
     *
     * @warning  Of course, touching this field from extension libraries causes
     *           catastrophic effects.  Just leave it.
     */
    unsigned long usecnt;
};

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Convenient getter function.
 *
 * @param[in]  rexp  The regular expression in question.
 * @return     The source code of the regular expression.
 * @pre        `rexp` must be of ::RRegexp.
 */
static inline VALUE
RREGEXP_SRC(VALUE rexp)
{
    RBIMPL_ASSERT_TYPE(rexp, RUBY_T_REGEXP);
    VALUE ret = RREGEXP(rexp)->src;
    RBIMPL_ASSERT_TYPE(ret, RUBY_T_STRING);
    return ret;
}

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Convenient getter function.
 *
 * @param[in]  rexp  The regular expression in question.
 * @return     The source code of the regular expression, in C's string.
 * @pre        `rexp` must be of ::RRegexp.
 *
 * @internal
 *
 * It seems nobody uses this function in the wild.  Subject to hide?
 */
static inline char *
RREGEXP_SRC_PTR(VALUE rexp)
{
    return RSTRING_PTR(RREGEXP_SRC(rexp));
}

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Convenient getter function.
 *
 * @param[in]  rexp  The regular expression in question.
 * @return     The length of the source code of the regular expression.
 * @pre        `rexp` must be of ::RRegexp.
 *
 * @internal
 *
 * It seems nobody uses this function in the wild.  Subject to hide?
 */
static inline long
RREGEXP_SRC_LEN(VALUE rexp)
{
    return RSTRING_LEN(RREGEXP_SRC(rexp));
}

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Convenient getter function.
 *
 * @param[in]  rexp  The regular expression in question.
 * @return     The end of the source code of the regular expression.
 * @pre        `rexp` must be of ::RRegexp.
 *
 * @internal
 *
 * It seems nobody uses this function in the wild.  Subject to hide?
 */
static inline char *
RREGEXP_SRC_END(VALUE rexp)
{
    return RSTRING_END(RREGEXP_SRC(rexp));
}

#endif /* RBIMPL_RREGEXP_H */
ruby/internal/core/rbasic.h000064400000012533151732674200011720 0ustar00#ifndef RBIMPL_RBASIC_H                              /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_RBASIC_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines struct ::RBasic.
 */
#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/attr/constexpr.h"
#include "ruby/internal/attr/forceinline.h"
#include "ruby/internal/attr/noalias.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/special_consts.h"
#include "ruby/internal/value.h"
#include "ruby/assert.h"

/**
 * Convenient casting macro.
 *
 * @param   obj  Arbitrary Ruby object.
 * @return  The passed object casted to ::RBasic.
 */
#define RBASIC(obj)                 RBIMPL_CAST((struct RBasic *)(obj))
/** @cond INTERNAL_MACRO */
#define RBASIC_CLASS                RBASIC_CLASS
#define RBIMPL_RVALUE_EMBED_LEN_MAX 3
#define RVALUE_EMBED_LEN_MAX        RVALUE_EMBED_LEN_MAX
#define RBIMPL_EMBED_LEN_MAX_OF(T) \
    RBIMPL_CAST((int)(sizeof(VALUE[RBIMPL_RVALUE_EMBED_LEN_MAX]) / (sizeof(T))))
/** @endcond */

/**
 * This is an enum because GDB wants it (rather than a macro).  People need not
 * bother.
 */
enum ruby_rvalue_flags {
    /** Max possible number of objects that can be embedded. */
    RVALUE_EMBED_LEN_MAX = RBIMPL_RVALUE_EMBED_LEN_MAX
};

/**
 * Ruby object's base components. All Ruby objects have them in common.
 */
struct
RUBY_ALIGNAS(SIZEOF_VALUE)
RBasic {

    /**
     * Per-object flags.   Each Ruby object  has its own  characteristics apart
     * from its class.  For instance, whether an object is frozen or not is not
     * controlled by its class.  This is where such properties are stored.
     *
     * @see enum ::ruby_fl_type
     *
     * @note  This is ::VALUE rather than  an enum for alignment purposes.  Back
     *        in the 1990s there were no such thing like `_Alignas` in C.
     */
    VALUE flags;

    /**
     * Class of an object.  Every object has its class.  Also, everything is an
     * object  in Ruby.   This means  classes are  also objects.   Classes have
     * their own classes,  classes  of classes have their classes too,  and  it
     * recursively continues forever.
     *
     * Also note the `const` qualifier.  In Ruby, an object cannot "change" its
     * class.
     */
    const VALUE klass;

#ifdef __cplusplus
  public:
    RBIMPL_ATTR_CONSTEXPR(CXX11)
    RBIMPL_ATTR_ARTIFICIAL()
    RBIMPL_ATTR_FORCEINLINE()
    RBIMPL_ATTR_NOALIAS()
    /**
     * We need to define this explicit constructor because the field `klass` is
     * const-qualified above,  which effectively  defines the  implicit default
     * constructor as "deleted"  (as of C++11) --  No way but to  define one by
     * ourselves.
     */
    RBasic() :
        flags(RBIMPL_VALUE_NULL),
        klass(RBIMPL_VALUE_NULL)
    {
    }
# define RBASIC_INIT RBasic()
#else
# define RBASIC_INIT {RBIMPL_VALUE_NULL}
#endif
};

RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
 * Make the object invisible from Ruby code.
 *
 * It is  useful to let  Ruby's GC manage your  internal data structure  -- The
 * object keeps being managed by GC, but `ObjectSpace.each_object` never yields
 * the object.
 *
 * Note that the object also lose a way to call a method on it.
 *
 * @param[out]  obj  A Ruby object.
 * @return      The passed object.
 * @post        The object is destructively modified to be invisible.
 * @see         rb_obj_reveal
 */
VALUE rb_obj_hide(VALUE obj);

/**
 * Make a hidden object visible again.
 *
 * It is  the caller's  responsibility to  pass the  right `klass`  which `obj`
 * originally used to belong to.
 *
 * @param[out]  obj    A Ruby object.
 * @param[in]   klass  Class of `obj`.
 * @return      Passed `obj`.
 * @pre         `obj` was previously hidden.
 * @post        `obj`'s class is `klass`.
 * @see         rb_obj_hide
 */
VALUE rb_obj_reveal(VALUE obj, VALUE klass); /* do not use this API to change klass information */
RBIMPL_SYMBOL_EXPORT_END()

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Queries the class of an object.
 *
 * @param[in]  obj  An object.
 * @return     Its class.
 */
static inline VALUE
RBASIC_CLASS(VALUE obj)
{
    RBIMPL_ASSERT_OR_ASSUME(! RB_SPECIAL_CONST_P(obj));
    return RBASIC(obj)->klass;
}

#endif /* RBIMPL_RBASIC_H */
ruby/internal/core/rstruct.h000064400000010153151732674200012157 0ustar00#ifndef RBIMPL_RSTRUCT_H                             /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_RSTRUCT_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Routines to manipulate struct RStruct.
 * @note       The struct RStruct itself is opaque.
 */
#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/internal/value_type.h"
#include "ruby/internal/arithmetic/long.h"
#include "ruby/internal/arithmetic/int.h"
#if !defined RUBY_EXPORT && !defined RUBY_NO_OLD_COMPATIBILITY
# include "ruby/backward.h"
#endif

/**
 * @private
 *
 * @deprecated  This macro once was a thing in the old days, but makes no sense
 *              any  longer today.   Exists  here  for backwards  compatibility
 *              only.  You can safely forget about it.
 *
 * @internal
 *
 * Declaration of rb_struct_ptr() is at include/ruby/backward.h.
 */
#define RSTRUCT_PTR(st) rb_struct_ptr(st)
/** @cond INTERNAL_MACRO */
#define RSTRUCT_LEN RSTRUCT_LEN
#define RSTRUCT_SET RSTRUCT_SET
#define RSTRUCT_GET RSTRUCT_GET
/** @endcond */

RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
 * Returns the number of struct members.
 *
 * @param[in]  st  An instance of RStruct.
 * @return     The number of members of `st`.
 * @pre        `st` must be of ::RUBY_T_STRUCT.
 */
VALUE rb_struct_size(VALUE st);

/**
 * Resembles `Struct#[]`.
 *
 * @param[in]  st              An instance of RStruct.
 * @param[in]  k               Index a.k.a. key of the struct.
 * @exception  rb_eTypeError   `k` is neither Numeric, Symbol, nor String.
 * @exception  rb_eIndexError  Numerical index out of range.
 * @exception  rb_eNameError   No such key.
 * @return     The member stored at `k` in `st`.
 * @pre        `st` must be of ::RUBY_T_STRUCT.
 */
VALUE rb_struct_aref(VALUE st, VALUE k);

/**
 * Resembles `Struct#[]=`.
 *
 * @param[out]  st              An instance of RStruct.
 * @param[in]   k               Index a.k.a. key of the struct.
 * @param[in]   v               Value to store.
 * @exception  rb_eTypeError    `k` is neither Numeric, Symbol, nor String.
 * @exception  rb_eIndexError   Numerical index out of range.
 * @exception  rb_eNameError    No such key.
 * @return     Passed `v`.
 * @pre        `st` must be of ::RUBY_T_STRUCT.
 * @post       `v` is stored at `k` in `st`.
 */
VALUE rb_struct_aset(VALUE st, VALUE k, VALUE v);
RBIMPL_SYMBOL_EXPORT_END()

RBIMPL_ATTR_ARTIFICIAL()
/** @copydoc rb_struct_size()  */
static inline long
RSTRUCT_LEN(VALUE st)
{
    RBIMPL_ASSERT_TYPE(st, RUBY_T_STRUCT);

    return RB_NUM2LONG(rb_struct_size(st));
}

RBIMPL_ATTR_ARTIFICIAL()
/** @copydoc rb_struct_aset()  */
static inline VALUE
RSTRUCT_SET(VALUE st, int k, VALUE v)
{
    RBIMPL_ASSERT_TYPE(st, RUBY_T_STRUCT);

    return rb_struct_aset(st, INT2NUM(k), (v));
}

RBIMPL_ATTR_ARTIFICIAL()
/** @copydoc rb_struct_aref()  */
static inline VALUE
RSTRUCT_GET(VALUE st, int k)
{
    RBIMPL_ASSERT_TYPE(st, RUBY_T_STRUCT);

    return rb_struct_aref(st, INT2NUM(k));
}

#endif /* RBIMPL_RSTRUCT_H */
ruby/internal/core/rhash.h000064400000010670151732674210011563 0ustar00#ifndef RBIMPL_RHASH_H                               /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_RHASH_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Routines to manipulate struct RHash.
 * @note       The struct RHash itself is opaque.
 */
#include "ruby/internal/config.h"

#ifdef STDC_HEADERS
# include <stddef.h>
#endif

#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#if !defined RUBY_EXPORT && !defined RUBY_NO_OLD_COMPATIBILITY
# include "ruby/backward.h"
#endif

/**
 * Retrieves the internal table.
 *
 * @param[in]  h  An instance of RHash.
 * @pre        `h` must be of ::RUBY_T_HASH.
 * @return     A struct st_table which has the contents of this hash.
 * @note       Nowadays as Ruby  evolved over ages, RHash  has multiple backend
 *             storage  engines.   `h`'s backend  is  not  guaranteed to  be  a
 *             st_table.  This function creates one when necessary.
 */
#define RHASH_TBL(h)                rb_hash_tbl(h, __FILE__, __LINE__)

/**
 * @private
 *
 * @deprecated  This macro once was a thing in the old days, but makes no sense
 *              any  longer today.   Exists  here  for backwards  compatibility
 *              only.  You can safely forget about it.
 *
 * @internal
 *
 * Declaration of rb_hash_ifnone() is at include/ruby/backward.h.
 */
#define RHASH_IFNONE(h)             rb_hash_ifnone(h)

/**
 * Queries the size of  the hash.  Size here means the number  of keys that the
 * hash stores.
 *
 * @param[in]  h  An instance of RHash.
 * @pre        `h` must be of ::RUBY_T_HASH.
 * @return     The size of the hash.
 */
#define RHASH_SIZE(h)               rb_hash_size_num(h)

/**
 * Checks if the hash is empty.
 *
 * @param[in]  h      An instance of RHash.
 * @pre        `h` must be of ::RUBY_T_HASH.
 * @retval     true   It is.
 * @retval     false  It isn't.
 */
#define RHASH_EMPTY_P(h)            (RHASH_SIZE(h) == 0)

/**
 * Destructively updates the default value of the hash.
 *
 * @param[out]  h       An instance of RHash.
 * @param[in]   ifnone  Arbitrary default value.
 * @pre        `h` must be of ::RUBY_T_HASH.
 *
 * @internal
 *
 * But why you can set this, given rb_hash_ifnone() doesn't exist?
 */
#define RHASH_SET_IFNONE(h, ifnone) rb_hash_set_ifnone((VALUE)h, ifnone)

struct st_table;  /* in ruby/st.h */

RBIMPL_SYMBOL_EXPORT_BEGIN()

/**
 * This is  the implementation detail  of #RHASH_SIZE.  People don't  call this
 * directly.
 *
 * @param[in]  hash  An instance of RHash.
 * @pre        `hash` must be of ::RUBY_T_HASH.
 * @return     The size of the hash.
 */
size_t rb_hash_size_num(VALUE hash);

/**
 * This is  the implementation  detail of #RHASH_TBL.   People don't  call this
 * directly.
 *
 * @param[in]  hash  An instance of RHash.
 * @param[in]  file  The `__FILE__`.
 * @param[in]  line  The `__LINE__`.
 * @pre        `hash` must be of ::RUBY_T_HASH.
 * @return     Table that has the contents of the hash.
 */
struct st_table *rb_hash_tbl(VALUE hash, const char *file, int line);

/**
 * This is the  implementation detail of #RHASH_SET_IFNONE.   People don't call
 * this directly.
 *
 * @param[out]  hash    An instance of RHash.
 * @param[in]   ifnone  Arbitrary default value.
 * @pre        `hash` must be of ::RUBY_T_HASH.
 */
VALUE rb_hash_set_ifnone(VALUE hash, VALUE ifnone);
RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_RHASH_H */
ruby/internal/core/rarray.h000064400000032344151732674210011760 0ustar00#ifndef RBIMPL_RARRAY_H                              /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_RARRAY_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines struct ::RArray.
 */
#include "ruby/internal/arithmetic/long.h"
#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/attr/constexpr.h"
#include "ruby/internal/attr/maybe_unused.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/core/rbasic.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/fl_type.h"
#include "ruby/internal/gc.h"
#include "ruby/internal/stdbool.h"
#include "ruby/internal/value.h"
#include "ruby/internal/value_type.h"
#include "ruby/assert.h"

/**
 * Convenient casting macro.
 *
 * @param   obj  An object, which is in fact an ::RArray.
 * @return  The passed object casted to ::RArray.
 */
#define RARRAY(obj)            RBIMPL_CAST((struct RArray *)(obj))
/** @cond INTERNAL_MACRO */
#define RARRAY_EMBED_FLAG      RARRAY_EMBED_FLAG
#define RARRAY_EMBED_LEN_MASK  RARRAY_EMBED_LEN_MASK
#define RARRAY_EMBED_LEN_MAX   RARRAY_EMBED_LEN_MAX
#define RARRAY_EMBED_LEN_SHIFT RARRAY_EMBED_LEN_SHIFT
/** @endcond */
#define RARRAY_LEN                 rb_array_len                 /**< @alias{rb_array_len} */
#define RARRAY_CONST_PTR           rb_array_const_ptr           /**< @alias{rb_array_const_ptr} */

/** @cond INTERNAL_MACRO */
#if defined(__fcc__) || defined(__fcc_version) || \
    defined(__FCC__) || defined(__FCC_VERSION)
/* workaround for old version of Fujitsu C Compiler (fcc) */
# define FIX_CONST_VALUE_PTR(x) ((const VALUE *)(x))
#else
# define FIX_CONST_VALUE_PTR(x) (x)
#endif

#define RARRAY_EMBED_LEN   RARRAY_EMBED_LEN
#define RARRAY_LENINT      RARRAY_LENINT
#define RARRAY_ASET        RARRAY_ASET
#define RARRAY_PTR         RARRAY_PTR
/** @endcond */

/**
 * @private
 *
 * Bits that you can set to ::RBasic::flags.
 *
 * @warning  These enums are not the only bits we use for arrays.
 *
 * @internal
 *
 * Unlike  strings, flag  usages for  arrays  are scattered  across the  entire
 * source codes.  @shyouhei doesn't know the complete list.  But what is listed
 * here is at least incomplete.
 */
enum ruby_rarray_flags {
    /* RUBY_FL_USER0 is for ELTS_SHARED */

    /**
     * This flag  has something to do  with memory footprint.  If  the array is
     * "small"  enough, ruby  tries to  be creative  to abuse  padding bits  of
     * struct  ::RArray  for storing  its  contents.   This flag  denotes  that
     * situation.
     *
     * @warning  This  bit has  to be  considered read-only.   Setting/clearing
     *           this  bit without  corresponding fix  up must  cause immediate
     *           SEGV.    Also,  internal   structures  of   an  array   change
     *           dynamically  and  transparently  throughout of  its  lifetime.
     *           Don't assume it being persistent.
     *
     * @internal
     *
     * 3rd parties must  not be aware that  there even is more than  one way to
     * store array elements.  It was a bad idea to expose this to them.
     */
    RARRAY_EMBED_FLAG      = RUBY_FL_USER1,

    /**
     * When an array employs embedded strategy (see ::RARRAY_EMBED_FLAG), these
     * bits  are used  to store  the number  of elements  actually filled  into
     * ::RArray::ary.
     *
     * @internal
     *
     * 3rd parties must  not be aware that  there even is more than  one way to
     * store array elements.  It was a bad idea to expose this to them.
     */
    RARRAY_EMBED_LEN_MASK  = RUBY_FL_USER9 | RUBY_FL_USER8 | RUBY_FL_USER7 | RUBY_FL_USER6 |
                                 RUBY_FL_USER5 | RUBY_FL_USER4 | RUBY_FL_USER3
};

/**
 * This is an enum because GDB wants it (rather than a macro).  People need not
 * bother.
 */
enum ruby_rarray_consts {
    /** Where ::RARRAY_EMBED_LEN_MASK resides. */
    RARRAY_EMBED_LEN_SHIFT = RUBY_FL_USHIFT + 3
};

/** Ruby's array. */
struct RArray {

    /** Basic part, including flags and class. */
    struct RBasic basic;

    /** Array's specific fields. */
    union {

        /**
         * Arrays  that  use separated  memory  region  for elements  use  this
         * pattern.
         */
        struct {

            /** Number of elements of the array. */
            long len;

            /** Auxiliary info. */
            union {

                /**
                 * Capacity of `*ptr`.  A continuous  memory region of at least
                 * `capa` elements is expected to exist at `*ptr`.  This can be
                 * bigger than `len`.
                 */
                long capa;

                /**
                 * Parent  of  the  array.   Nowadays arrays  can  share  their
                 * backend  memory regions  each  other, constructing  gigantic
                 * nest  of objects.   This situation  is called  "shared", and
                 * this is the field to control such properties.
                 */
#if defined(__clang__)      /* <- clang++ is sane */ || \
    !defined(__cplusplus)   /* <- C99 is sane */     || \
    (__cplusplus > 199711L) /* <- C++11 is sane */
                const
#endif
                VALUE shared_root;
            } aux;

            /**
             * Pointer to the C array that holds the elements of the array.  In
             * the old days  each array had dedicated memory  regions.  That is
             * no  longer  true today,  but  there  still  are arrays  of  such
             * properties.  This field could be used to point such things.
             */
            const VALUE *ptr;
        } heap;

        /**
         * Embedded elements.  When an array is short enough, it uses this area
         * to store its elements.  In this  case the length is encoded into the
         * flags.
         */
        /* This is a length 1 array because:
         *   1. GCC has a bug that does not optimize C flexible array members
         *      (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102452)
         *   2. Zero length arrays are not supported by all compilers
         */
        const VALUE ary[1];
    } as;
};

RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
 * @private
 *
 * Declares  a  section of  code  where  raw pointers  are  used.   This is  an
 * implementation detail of #RARRAY_PTR_USE.  People don't use it directly.
 *
 * @param[in]  ary  An object of ::RArray.
 * @return     `ary`'s backend C array.
 */
VALUE *rb_ary_ptr_use_start(VALUE ary);

/**
 * @private
 *
 * Declares an  end of  a section  formerly started  by rb_ary_ptr_use_start().
 * This is  an implementation detail  of #RARRAY_PTR_USE.  People don't  use it
 * directly.
 *
 * @param[in]  a  An object of ::RArray.
 */
void rb_ary_ptr_use_end(VALUE a);

RBIMPL_SYMBOL_EXPORT_END()

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Queries the length of the array.
 *
 * @param[in]  ary  Array in question.
 * @return     Its number of elements.
 * @pre        `ary`  must  be  an  instance  of ::RArray,  and  must  has  its
 *             ::RARRAY_EMBED_FLAG flag set.
 *
 * @internal
 *
 * This was a macro  before.  It was inevitable to be  public, since macros are
 * global constructs.   But should it be  forever?  Now that it  is a function,
 * @shyouhei thinks  it could  just be  eliminated, hidden  into implementation
 * details.
 */
static inline long
RARRAY_EMBED_LEN(VALUE ary)
{
    RBIMPL_ASSERT_TYPE(ary, RUBY_T_ARRAY);
    RBIMPL_ASSERT_OR_ASSUME(RB_FL_ANY_RAW(ary, RARRAY_EMBED_FLAG));

    VALUE f = RBASIC(ary)->flags;
    f &= RARRAY_EMBED_LEN_MASK;
    f >>= RARRAY_EMBED_LEN_SHIFT;
    return RBIMPL_CAST((long)f);
}

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
/**
 * Queries the length of the array.
 *
 * @param[in]  a  Array in question.
 * @return     Its number of elements.
 * @pre        `a` must be an instance of ::RArray.
 */
static inline long
rb_array_len(VALUE a)
{
    RBIMPL_ASSERT_TYPE(a, RUBY_T_ARRAY);

    if (RB_FL_ANY_RAW(a, RARRAY_EMBED_FLAG)) {
        return RARRAY_EMBED_LEN(a);
    }
    else {
        return RARRAY(a)->as.heap.len;
    }
}

RBIMPL_ATTR_ARTIFICIAL()
/**
 * Identical to rb_array_len(), except it differs for the return type.
 *
 * @param[in]  ary             Array in question.
 * @exception  rb_eRangeError  Too long.
 * @return     Its number of elements.
 * @pre        `ary` must be an instance of ::RArray.
 *
 * @internal
 *
 * This API seems redundant but has actual usages.
 */
static inline int
RARRAY_LENINT(VALUE ary)
{
    return rb_long2int(RARRAY_LEN(ary));
}

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
/**
 * @private
 *
 * This is  an implementation  detail of  RARRAY_PTR().  People  do not  use it
 * directly.
 *
 * @param[in]  a  An object of ::RArray.
 * @return     Its backend storage.
 */
static inline const VALUE *
rb_array_const_ptr(VALUE a)
{
    RBIMPL_ASSERT_TYPE(a, RUBY_T_ARRAY);

    if (RB_FL_ANY_RAW(a, RARRAY_EMBED_FLAG)) {
        return FIX_CONST_VALUE_PTR(RARRAY(a)->as.ary);
    }
    else {
        return FIX_CONST_VALUE_PTR(RARRAY(a)->as.heap.ptr);
    }
}

/**
 * @private
 *
 * This is an  implementation detail of #RARRAY_PTR_USE.  People do  not use it
 * directly.
 */
#define RBIMPL_RARRAY_STMT(ary, var, expr) do {        \
    RBIMPL_ASSERT_TYPE((ary), RUBY_T_ARRAY);                 \
    const VALUE rbimpl_ary = (ary);                          \
    VALUE *var = rb_ary_ptr_use_start(rbimpl_ary); \
    expr;                                                   \
    rb_ary_ptr_use_end(rbimpl_ary);                \
} while (0)

/**
 * Declares a section of code where raw pointers are used.  In case you need to
 * touch the raw C array instead of  polite CAPIs, then that operation shall be
 * wrapped using this macro.
 *
 * ```CXX
 * const auto ary = rb_eval_string("[...]");
 * const auto len = RARRAY_LENINT(ary);
 * const auto symwrite = rb_intern("write");
 *
 * RARRAY_PTR_USE(ary, ptr, {
 *     rb_funcallv(rb_stdout, symwrite, len, ptr);
 * });
 * ```
 *
 * @param  ary       An object of ::RArray.
 * @param  ptr_name  A variable name which points the C array in `expr`.
 * @param  expr      The expression that touches `ptr_name`.
 *
 * @internal
 *
 * For  historical reasons  use  of  this macro  is  not  enforced.  There  are
 * extension libraries in the wild which call RARRAY_PTR() without it.  We want
 * them use it...  Maybe some transition path can be implemented later.
 */
#define RARRAY_PTR_USE(ary, ptr_name, expr)     \
    RBIMPL_RARRAY_STMT(ary, ptr_name, expr)

/**
 * Wild  use of  a  C  pointer.  This  function  accesses  the backend  storage
 * directly.   This is  slower  than  #RARRAY_PTR_USE.  It  exercises
 * extra manoeuvres  to protect our generational  GC.  Use of this  function is
 * considered archaic.  Use a modern way instead.
 *
 * @param[in]  ary  An object of ::RArray.
 * @return     The backend C array.
 *
 * @internal
 *
 * That said...  there are  extension libraries  in the wild  who uses  it.  We
 * cannot but continue supporting.
 */
static inline VALUE *
RARRAY_PTR(VALUE ary)
{
    RBIMPL_ASSERT_TYPE(ary, RUBY_T_ARRAY);

    VALUE tmp = RB_OBJ_WB_UNPROTECT_FOR(ARRAY, ary);
    return RBIMPL_CAST((VALUE *)RARRAY_CONST_PTR(tmp));
}

/**
 * Assigns an object in an array.
 *
 * @param[out]  ary  Destination array object.
 * @param[in]   i    Index of `ary`.
 * @param[in]   v    Arbitrary ruby object.
 * @pre         `ary` must be an instance of ::RArray.
 * @pre         `ary`'s length must be longer than or equal to `i`.
 * @pre         `i` must be greater than or equal to zero.
 * @post        `ary`'s `i`th element is set to `v`.
 */
static inline void
RARRAY_ASET(VALUE ary, long i, VALUE v)
{
    RARRAY_PTR_USE(ary, ptr,
        RB_OBJ_WRITE(ary, &ptr[i], v));
}

/**
 * @deprecated
 *
 * :FIXME: we want to convert RARRAY_AREF into an inline function (to add rooms
 * for more sanity checks).  However there were situations where the address of
 * this macro is taken i.e. &RARRAY_AREF(...).  They cannot be possible if this
 * is not a  macro.  Such usages are abuse, and  we eliminated them internally.
 * However we are afraid  of similar things to remain in  the wild.  This macro
 * remains as  it is due to  that.  If we could  warn such usages we  can set a
 * transition path, but currently no way is found to do so.
 */
#define RARRAY_AREF(a, i) RARRAY_CONST_PTR(a)[i]

#endif /* RBIMPL_RARRAY_H */
ruby/internal/core/rfile.h000064400000004126151732674210011556 0ustar00#ifndef RBIMPL_RFILE_H                               /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_RFILE_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines struct ::RFile.
 */
#include "ruby/internal/core/rbasic.h"
#include "ruby/internal/cast.h"

/* rb_io_t is in ruby/io.h.  The header file has historically not been included
 * into ruby/ruby.h.  We follow that tradition. */
struct rb_io;

/**
 * Ruby's File  and IO.  Ruby's  IO are not  just file descriptors.   They have
 * buffers.   They also  have  encodings.  Various  information are  controlled
 * using this struct.
 */
struct RFile {

    /** Basic part, including flags and class. */
    struct RBasic basic;

    /** IO's specific fields. */
    struct rb_io *fptr;
};

/**
 * Convenient casting macro.
 *
 * @param   obj  An object, which is in fact an ::RFile.
 * @return  The passed object casted to ::RFile.
 */
#define RFILE(obj) RBIMPL_CAST((struct RFile *)(obj))
#endif /* RBIMPL_RFILE_H */
ruby/internal/core/rtypeddata.h000064400000055451151732674210012625 0ustar00#ifndef RBIMPL_RTYPEDDATA_H                          /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_RTYPEDDATA_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines struct ::RTypedData.
 */
#include "ruby/internal/config.h"

#ifdef STDC_HEADERS
# include <stddef.h>
#endif

#include "ruby/internal/assume.h"
#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/attr/flag_enum.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/core/rbasic.h"
#include "ruby/internal/core/rdata.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/error.h"
#include "ruby/internal/fl_type.h"
#include "ruby/internal/stdbool.h"
#include "ruby/internal/value_type.h"

/**
 * @private
 *
 * @deprecated  This macro once was a thing in the old days, but makes no sense
 *              any  longer today.   Exists  here  for backwards  compatibility
 *              only.  You can safely forget about it.
 */
#define HAVE_TYPE_RB_DATA_TYPE_T     1

/**
 * @private
 *
 * @deprecated  This macro once was a thing in the old days, but makes no sense
 *              any  longer today.   Exists  here  for backwards  compatibility
 *              only.  You can safely forget about it.
 */
#define HAVE_RB_DATA_TYPE_T_FUNCTION 1

/**
 * @private
 *
 * @deprecated  This macro once was a thing in the old days, but makes no sense
 *              any  longer today.   Exists  here  for backwards  compatibility
 *              only.  You can safely forget about it.
 */
#define HAVE_RB_DATA_TYPE_T_PARENT   1

/**
 * This is a  value you can set to  ::rb_data_type_struct::dfree.  Setting this
 * means the data was allocated using ::ruby_xmalloc() (or variants), and shall
 * be freed using ::ruby_xfree().
 *
 * @warning  Do not  use this  if you  want to use  system malloc,  because the
 *           system  and  Ruby  might  or  might  not  share  the  same  malloc
 *           implementation.
 */
#define RUBY_TYPED_DEFAULT_FREE      RUBY_DEFAULT_FREE

/**
 * This is a  value you can set to  ::rb_data_type_struct::dfree.  Setting this
 * means the data  is managed by someone else, like,  statically allocated.  Of
 * course you are on your own then.
 */
#define RUBY_TYPED_NEVER_FREE        RUBY_NEVER_FREE

/**
 * Convenient casting macro.
 *
 * @param   obj  An object, which is in fact an ::RTypedData.
 * @return  The passed object casted to ::RTypedData.
 */
#define RTYPEDDATA(obj)              RBIMPL_CAST((struct RTypedData *)(obj))

/**
 * Convenient getter macro.
 *
 * @param   v  An object, which is in fact an ::RTypedData.
 * @return  The passed object's ::RTypedData::data field.
 */
#define RTYPEDDATA_DATA(v)           (RTYPEDDATA(v)->data)

/** @old{rb_check_typeddata} */
#define Check_TypedStruct(v, t)      \
    rb_check_typeddata(RBIMPL_CAST((VALUE)(v)), (t))

/** @cond INTERNAL_MACRO */
#define RTYPEDDATA_P                 RTYPEDDATA_P
#define RTYPEDDATA_TYPE              RTYPEDDATA_TYPE
#define RUBY_TYPED_FREE_IMMEDIATELY  RUBY_TYPED_FREE_IMMEDIATELY
#define RUBY_TYPED_FROZEN_SHAREABLE  RUBY_TYPED_FROZEN_SHAREABLE
#define RUBY_TYPED_WB_PROTECTED      RUBY_TYPED_WB_PROTECTED
#define RUBY_TYPED_PROMOTED1         RUBY_TYPED_PROMOTED1
/** @endcond */

#define TYPED_DATA_EMBEDDED 2

/**
 * @private
 *
 * Bits for rb_data_type_struct::flags.
 */
enum
RBIMPL_ATTR_FLAG_ENUM()
rbimpl_typeddata_flags {
    /**
     * This flag has something to do  with Ruby's global interpreter lock.  For
     * maximum  safety, Ruby  locks  the  entire VM  during  GC.  However  your
     * callback functions  could unintentionally  unlock it, for  instance when
     * they try to flush an IO  buffer.  Such operations are dangerous (threads
     * then  run alongside  of GC).   By  default, to  prevent those  scenario,
     * callbacks are deferred until the GC engine is 100% sure threads can run.
     * This flag skips  that; structs with it are deallocated  during the sweep
     * phase.
     *
     * Using this  flag needs deep understanding  of both GC and  threads.  You
     * would better leave it unspecified.
     */
    RUBY_TYPED_FREE_IMMEDIATELY = 1,

    RUBY_TYPED_EMBEDDABLE = 2,

    /**
     * This flag has something to do with Ractor.  Multiple Ractors run without
     * protecting each  other.  Sharing  an object  among Ractors  is basically
     * dangerous,  disabled by  default.   This  flag is  used  to bypass  that
     * restriction.  but  setting it is not  enough.  In addition to  do so, an
     * object    also    has    to    be   frozen,    and    be    passed    to
     * rb_ractor_make_shareable() before being  actually shareable.  Of course,
     * you have to manually prevent race conditions then.
     *
     * Using this  flag needs deep understanding  of multithreaded programming.
     * You would better leave it unspecified.
     */
    RUBY_TYPED_FROZEN_SHAREABLE = RUBY_FL_SHAREABLE,

    /**
     * This flag  has something to do  with our garbage collector.   These days
     * ruby  objects are  "generational".  There  are those  who are  young and
     * those who are old.  Young objects are prone to die; monitored relatively
     * extensively by  the garbage  collector.  OTOH old  objects tend  to live
     * longer.  They  are relatively rarely considered.   This basically works.
     * But there is one  tweak that has to be exercised.   When an elder object
     * has reference(s)  to younger  one(s), that  referenced objects  must not
     * die.  In order  to detect additions of such  references, old generations
     * are  protected by  write  barriers.   It is  a  very  difficult hack  to
     * appropriately  insert  write  barriers everywhere.   This  mechanism  is
     * disabled by default for 3rd party  extensions (they never get aged).  By
     * specifying this  flag you  can enable the  generational feature  to your
     * data structure.  Of  course, you have to manually  insert write barriers
     * then.
     *
     * Using this  flag needs deep understanding  of GC internals, often at the
     * level of source code.  You would better leave it unspecified.
     */
    RUBY_TYPED_WB_PROTECTED     = RUBY_FL_WB_PROTECTED, /* THIS FLAG DEPENDS ON Ruby version */

    /**
     * This flag no longer in use
     */
    RUBY_TYPED_UNUSED           = RUBY_FL_UNUSED6,

    /**
     * This flag determines whether marking and compaction should be carried out
     * using the dmark/dcompact callback functions or whether we should mark
     * declaratively using a list of references defined inside the data struct we're wrapping
     */
    RUBY_TYPED_DECL_MARKING     = RUBY_FL_USER2
};

/**
 * This  is the  struct that  holds necessary  info for  a struct.   It roughly
 * resembles a Ruby level class;  multiple objects can share a ::rb_data_type_t
 * instance.
 */
typedef struct rb_data_type_struct rb_data_type_t;

/** @copydoc rb_data_type_t */
struct rb_data_type_struct {

    /**
     * Name of  structs of this  kind.  This  is used for  diagnostic purposes.
     * This has  to be unique  in the  process, but doesn't  has to be  a valid
     * C/Ruby identifier.
     */
    const char *wrap_struct_name;

    /** Function pointers.  Resembles C++ `vtbl`.*/
    struct {

        /**
         * This function  is called when  the object is experiencing  GC marks.
         * If it  contains references to other  Ruby objects, you need  to mark
         * them also.  Otherwise GC will smash your data.
         *
         * @see      rb_gc_mark()
         * @warning  This  is called  during GC  runs.  Object  allocations are
         *           impossible at that moment (that is why GC runs).
         */
        RUBY_DATA_FUNC dmark;

        /**
         * This function is called when the object is no longer used.  You need
         * to do whatever necessary to avoid memory leaks.
         *
         * @warning  This  is called  during GC  runs.  Object  allocations are
         *           impossible at that moment (that is why GC runs).
         */
        RUBY_DATA_FUNC dfree;

        /**
         * This function is to query the size of the underlying memory regions.
         *
         * @internal
         *
         * This  function  has  only  one   usage,  which  is  form  inside  of
         * `ext/objspace`.
         */
        size_t (*dsize)(const void *);

        /**
         * This  function  is  called  when  the  object  is  relocated.   Like
         * ::rb_data_type_struct::dmark, you need to  update references to Ruby
         * objects inside of your structs.
         *
         * @see      rb_gc_location()
         * @warning  This  is called  during GC  runs.  Object  allocations are
         *           impossible at that moment (that is why GC runs).
         */
        RUBY_DATA_FUNC dcompact;

        /**
         * This field  is reserved for future  extension.  For now, it  must be
         * filled with zeros.
         */
        void *reserved[1]; /* For future extension.
                              This array *must* be filled with ZERO. */
    } function;

    /**
     * Parent  of  this  class.   Sometimes  C  structs  have  inheritance-like
     * relationships.  An example is `struct sockaddr`  and its family.  If you
     * design such things,  make ::rb_data_type_t for each of  them and connect
     * using this field.   Ruby can then transparently cast your  data back and
     * forth when you call #TypedData_Get_Struct().
     *
     * ```CXX
     * struct parent { };
     * static inline const rb_data_type_t parent_type = {
     *     .wrap_struct_name = "parent",
     * };
     *
     * struct child: public parent { };
     * static inline const rb_data_type_t child_type = {
     *     .wrap_struct_name = "child",
     *     .parent = &parent_type,
     * };
     *
     * // This function can take both parent_class and child_class.
     * static inline struct parent *
     * get_parent(VALUE v)
     * {
     *     struct parent *p;
     *     TypedData_Get_Struct(v, parent_type, struct parent, p);
     *     return p;
     * }
     * ```
     */
    const rb_data_type_t *parent;

    /**
     * Type-specific static data.   This area can be used for  any purpose by a
     * programmer who define the type.  Ruby does not manage this at all.
     */
    void *data;        /* This area can be used for any purpose
                          by a programmer who define the type. */

    /**
     * Type-specific behavioural  characteristics.  This is a  bitfield.  It is
     * an EXTREMELY  WISE IDEA to  leave this field  blank.  It is  designed so
     * that setting  zero is the safest  thing to do.   If you risk to  set any
     * bits on, you have to know exactly what you are doing.
     *
     * @internal
     *
     * Why it has to be a ::VALUE?  @shyouhei doesn't understand the design.
     */
    VALUE flags;       /* RUBY_FL_WB_PROTECTED */
};

/**
 * "Typed" user data.   By using this, extension libraries can  wrap a C struct
 * to make it visible from Ruby.  For  instance if you have a `struct timeval`,
 * and you want users to use it,
 *
 * ```CXX
 * static inline const rb_data_type_t timeval_type = {
 *     // Note that unspecified fields are 0-filled by default.
 *     .wrap_struct_name = "timeval",
 *     .function = {
 *         .dmark = nullptr,                 // no need to mark
 *         .dfree = RUBY_TYPED_DEFAULT_FREE, // use ruby_xfree()
 *         .dsize = [](auto) {
 *             return sizeof(struct timeval);
 *         },
 *     },
 * };
 *
 * extern "C" void
 * Init_timeval(void)
 * {
 *     auto klass = rb_define_class("YourName", rb_cObject);
 *
 *     rb_define_alloc_func(klass, [](auto klass) {
 *         struct timeval *t;
 *         auto ret = TypedData_Make_Struct(
 *            klass, struct timeval, &timeval_type, t);
 *
 *         if (auto i = gettimeofday(t, nullptr); i == -1) {
 *             rb_sys_fail("gettimeofday(3)");
 *         }
 *         else {
 *             return ret;
 *         }
 *     });
 * }
 * ```
 */
struct RTypedData {

    /** The part that all ruby objects have in common. */
    struct RBasic basic;

    /**
     * This field  stores various  information about how  Ruby should  handle a
     * data.   This roughly  resembles a  Ruby level  class (apart  from method
     * definition etc.)
     */
    const rb_data_type_t *const type;

    /**
     * This has to be always 1.
     *
     * @internal
     */
    const VALUE typed_flag;

    /** Pointer to the actual C level struct that you want to wrap. */
    void *data;
};

RBIMPL_SYMBOL_EXPORT_BEGIN()
RBIMPL_ATTR_NONNULL((3))
/**
 * This is the primitive way to wrap an existing C struct into ::RTypedData.
 *
 * @param[in]  klass          Ruby level class of the returning object.
 * @param[in]  datap          Pointer to the target C struct.
 * @param[in]  type           The characteristics of the passed data.
 * @exception  rb_eTypeError  `klass` is not a class.
 * @exception  rb_eNoMemError  Out of memory.
 * @return     An allocated object that wraps `datap`.
 */
VALUE rb_data_typed_object_wrap(VALUE klass, void *datap, const rb_data_type_t *type);

/**
 * Identical  to rb_data_typed_object_wrap(),  except it  allocates a  new data
 * region internally instead of taking an existing one.  The allocation is done
 * using ruby_calloc().  Hence it makes  no sense for `type->function.dfree` to
 * be anything other than ::RUBY_TYPED_DEFAULT_FREE.
 *
 * @param[in]  klass          Ruby level class of the returning object.
 * @param[in]  size           Requested size of memory to allocate.
 * @param[in]  type           The characteristics of the passed data.
 * @exception  rb_eTypeError  `klass` is not a class.
 * @exception  rb_eNoMemError  Out of memory.
 * @return     An allocated object that wraps a new `size` byte region.
 */
VALUE rb_data_typed_object_zalloc(VALUE klass, size_t size, const rb_data_type_t *type);

/**
 * Checks for the domestic relationship between the two.
 *
 * @param[in]  child   A data type supposed to be a child of `parent`.
 * @param[in]  parent  A data type supposed to be a parent of `child`.
 * @retval     true    `child` is a descendent of `parent`.
 * @retval     false   Otherwise.
 *
 * @internal
 *
 * You can path NULL to both arguments, don't know what that means though.
 */
int rb_typeddata_inherited_p(const rb_data_type_t *child, const rb_data_type_t *parent);

/**
 * Checks if the given object is of given kind.
 *
 * @param[in]  obj        An instance of ::RTypedData.
 * @param[in]  data_type  Expected data type of `obj`.
 * @retval     true       `obj` is of `data_type`.
 * @retval     false      Otherwise.
 */
int rb_typeddata_is_kind_of(VALUE obj, const rb_data_type_t *data_type);

/**
 * Identical to rb_typeddata_is_kind_of(), except  it raises exceptions instead
 * of returning false.
 *
 * @param[in]  obj            An instance of ::RTypedData.
 * @param[in]  data_type      Expected data type of `obj`.
 * @exception  rb_eTypeError  obj is not of `data_type`.
 * @return     Unwrapped C struct that `obj` holds.
 * @post       Upon successful return `obj`'s type is guaranteed `data_type`.
 */
void *rb_check_typeddata(VALUE obj, const rb_data_type_t *data_type);
RBIMPL_SYMBOL_EXPORT_END()

/**
 * Converts sval, a pointer to your struct, into a Ruby object.
 *
 * @param      klass          A ruby level class.
 * @param      data_type      The type of `sval`.
 * @param      sval           A pointer to your struct.
 * @exception  rb_eTypeError  `klass` is not a class.
 * @exception  rb_eNoMemError  Out of memory.
 * @return     A created Ruby object.
 */
#define TypedData_Wrap_Struct(klass,data_type,sval)\
  rb_data_typed_object_wrap((klass),(sval),(data_type))

/**
 * @private
 *
 * This is  an implementation  detail of #TypedData_Make_Struct.   People don't
 * use it directly.
 *
 * @param  result     Variable name of created Ruby object.
 * @param  klass      Ruby level class of the object.
 * @param  type       Type name of the C struct.
 * @param  size       Size of the C struct.
 * @param  data_type  The data type describing `type`.
 * @param  sval       Variable name of created C struct.
 */
#define TypedData_Make_Struct0(result, klass, type, size, data_type, sval) \
    VALUE result = rb_data_typed_object_zalloc(klass, size, data_type);    \
    (sval) = (type *)RTYPEDDATA_GET_DATA(result); \
    RBIMPL_CAST(/*suppress unused variable warnings*/(void)(sval))

/**
 * Identical to #TypedData_Wrap_Struct,  except it allocates a  new data region
 * internally instead of taking an existing  one.  The allocation is done using
 * ruby_calloc().  Hence  it makes no sense  for `data_type->function.dfree` to
 * be anything other than ::RUBY_TYPED_DEFAULT_FREE.
 *
 * @param      klass          Ruby level class of the object.
 * @param      type           Type name of the C struct.
 * @param      data_type      The data type describing `type`.
 * @param      sval           Variable name of created C struct.
 * @exception  rb_eTypeError  `klass` is not a class.
 * @exception  rb_eNoMemError  Out of memory.
 * @return     A created Ruby object.
 */
#ifdef HAVE_STMT_AND_DECL_IN_EXPR
#define TypedData_Make_Struct(klass, type, data_type, sval) \
    RB_GNUC_EXTENSION({         \
        TypedData_Make_Struct0( \
            data_struct_obj,    \
            klass,              \
            type,               \
            sizeof(type),       \
            data_type,          \
            sval);              \
        data_struct_obj;        \
    })
#else
#define TypedData_Make_Struct(klass, type, data_type, sval) \
    rb_data_typed_object_make(        \
        (klass),                      \
        (data_type),                  \
        RBIMPL_CAST((void **)&(sval)), \
        sizeof(type))
#endif

/**
 * Obtains a C struct from inside of a wrapper Ruby object.
 *
 * @param      obj            An instance of ::RTypedData.
 * @param      type           Type name of the C struct.
 * @param      data_type      The data type describing `type`.
 * @param      sval           Variable name of obtained C struct.
 * @exception  rb_eTypeError  `obj` is not a kind of `data_type`.
 * @return     Unwrapped C struct that `obj` holds.
 */
#define TypedData_Get_Struct(obj,type,data_type,sval) \
    ((sval) = RBIMPL_CAST((type *)rb_check_typeddata((obj), (data_type))))

static inline bool
RTYPEDDATA_EMBEDDED_P(VALUE obj)
{
#if RUBY_DEBUG
    if (RB_UNLIKELY(!RB_TYPE_P(obj, RUBY_T_DATA))) {
        Check_Type(obj, RUBY_T_DATA);
        RBIMPL_UNREACHABLE_RETURN(false);
    }
#endif

    return RTYPEDDATA(obj)->typed_flag & TYPED_DATA_EMBEDDED;
}

static inline void *
RTYPEDDATA_GET_DATA(VALUE obj)
{
#if RUBY_DEBUG
    if (RB_UNLIKELY(!RB_TYPE_P(obj, RUBY_T_DATA))) {
        Check_Type(obj, RUBY_T_DATA);
        RBIMPL_UNREACHABLE_RETURN(false);
    }
#endif

    /* We reuse the data pointer in embedded TypedData. We can't use offsetof
     * since RTypedData a non-POD type in C++. */
    const size_t embedded_typed_data_size = sizeof(struct RTypedData) - sizeof(void *);

    return RTYPEDDATA_EMBEDDED_P(obj) ? (char *)obj + embedded_typed_data_size : RTYPEDDATA(obj)->data;
}

RBIMPL_ATTR_PURE()
RBIMPL_ATTR_ARTIFICIAL()
/**
 * @private
 *
 * This  is an  implementation detail  of  Check_Type().  People  don't use  it
 * directly.
 *
 * @param[in]  obj    Object in question
 * @retval     true   `obj` is an instance of ::RTypedData.
 * @retval     false  `obj` is an instance of ::RData.
 * @pre        `obj` must be a Ruby object of ::RUBY_T_DATA.
 */
static inline bool
rbimpl_rtypeddata_p(VALUE obj)
{
    VALUE typed_flag = RTYPEDDATA(obj)->typed_flag;
    return typed_flag != 0 && typed_flag <= 3;
}

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Checks whether the passed object is ::RTypedData or ::RData.
 *
 * @param[in]  obj    Object in question
 * @retval     true   `obj` is an instance of ::RTypedData.
 * @retval     false  `obj` is an instance of ::RData.
 * @pre        `obj` must be a Ruby object of ::RUBY_T_DATA.
 */
static inline bool
RTYPEDDATA_P(VALUE obj)
{
#if RUBY_DEBUG
    if (RB_UNLIKELY(! RB_TYPE_P(obj, RUBY_T_DATA))) {
        Check_Type(obj, RUBY_T_DATA);
        RBIMPL_UNREACHABLE_RETURN(false);
    }
#endif

    return rbimpl_rtypeddata_p(obj);
}

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/* :TODO: can this function be __attribute__((returns_nonnull)) or not? */
/**
 * Queries for the type of given object.
 *
 * @param[in]  obj    Object in question
 * @return     Data type struct that corresponds to `obj`.
 * @pre        `obj` must be an instance of ::RTypedData.
 */
static inline const struct rb_data_type_struct *
RTYPEDDATA_TYPE(VALUE obj)
{
#if RUBY_DEBUG
    if (RB_UNLIKELY(! RTYPEDDATA_P(obj))) {
        rb_unexpected_type(obj, RUBY_T_DATA);
        RBIMPL_UNREACHABLE_RETURN(NULL);
    }
#endif

    return RTYPEDDATA(obj)->type;
}

/**
 * While  we don't  stop  you from  using  this  function, it  seems  to be  an
 * implementation  detail of  #TypedData_Make_Struct, which  is preferred  over
 * this one.
 *
 * @param[in]  klass      Ruby level class of the returning object.
 * @param[in]  type       The data type
 * @param[out] datap      Return pointer.
 * @param[in]  size       Size of the C struct.
 * @exception  rb_eTypeError  `klass` is not a class.
 * @exception  rb_eNoMemError  Out of memory.
 * @return     A created Ruby object.
 * @post       `*datap` points to the C struct wrapped by the returned object.
 */
static inline VALUE
rb_data_typed_object_make(VALUE klass, const rb_data_type_t *type, void **datap, size_t size)
{
    TypedData_Make_Struct0(result, klass, void, size, type, *datap);
    return result;
}

RBIMPL_ATTR_DEPRECATED(("by: rb_data_typed_object_wrap"))
/** @deprecated  This function was renamed to rb_data_typed_object_wrap(). */
static inline VALUE
rb_data_typed_object_alloc(VALUE klass, void *datap, const rb_data_type_t *type)
{
    return rb_data_typed_object_wrap(klass, datap, type);
}

#endif /* RBIMPL_RTYPEDDATA_H */
ruby/internal/core/rbignum.h000064400000005605151732674210012123 0ustar00#ifndef RBIMPL_RBIGNUM_H                             /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_RBIGNUM_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Routines to manipulate struct RBignum.
 * @note       The struct RBignum itself is opaque.
 */
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/internal/value_type.h"
#include "ruby/internal/stdbool.h"

#define RBIGNUM_SIGN rb_big_sign /**< @alias{rb_big_sign} */

/** @cond INTERNAL_MACRO */
#define RBIGNUM_POSITIVE_P RBIGNUM_POSITIVE_P
#define RBIGNUM_NEGATIVE_P RBIGNUM_NEGATIVE_P
/** @endcond */

RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
 * The "sign" of a bignum.
 *
 * @param[in]  num  An object of RBignum.
 * @retval     1    It is greater than or equal to zero.
 * @retval     0    It is less than zero.
 *
 * @internal
 *
 * Implementation wise, unlike fixnums (which  are 2's complement), bignums are
 * signed  magnitude  system.   Theoretically  it could  be  possible  to  have
 * negative zero  instances.  But  in reality  there is no  way to  create such
 * thing.  Nobody ever needed that kind of insanity.
 */
int rb_big_sign(VALUE num);
RBIMPL_SYMBOL_EXPORT_END()

/**
 * Checks if the bignum is positive.
 * @param[in]  b      An object of RBignum.
 * @retval     false  `b` is less than zero.
 * @retval     true   Otherwise.
 */
static inline bool
RBIGNUM_POSITIVE_P(VALUE b)
{
    RBIMPL_ASSERT_TYPE(b, RUBY_T_BIGNUM);
    return RBIGNUM_SIGN(b);
}

/**
 * Checks if the bignum is negative.
 * @param[in]  b      An object of RBignum.
 * @retval     true   `b` is less than zero.
 * @retval     false  Otherwise.
 */
static inline bool
RBIGNUM_NEGATIVE_P(VALUE b)
{
    RBIMPL_ASSERT_TYPE(b, RUBY_T_BIGNUM);
    return ! RBIGNUM_POSITIVE_P(b);
}

#endif /* RBIMPL_RBIGNUM_H */
ruby/internal/core/robject.h000064400000012044151732674210012103 0ustar00#ifndef RBIMPL_ROBJECT_H                             /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ROBJECT_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines struct ::RObject.
 */
#include "ruby/internal/config.h"

#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif

#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/attr/deprecated.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/fl_type.h"
#include "ruby/internal/value.h"
#include "ruby/internal/value_type.h"

/**
 * Convenient casting macro.
 *
 * @param   obj  An object, which is in fact an ::RObject.
 * @return  The passed object casted to ::RObject.
 */
#define ROBJECT(obj)          RBIMPL_CAST((struct RObject *)(obj))
/** @cond INTERNAL_MACRO */
#define ROBJECT_EMBED_LEN_MAX ROBJECT_EMBED_LEN_MAX
#define ROBJECT_EMBED         ROBJECT_EMBED
#define ROBJECT_IV_CAPACITY   ROBJECT_IV_CAPACITY
#define ROBJECT_IVPTR         ROBJECT_IVPTR
/** @endcond */

/**
 * @private
 *
 * Bits that you can set to ::RBasic::flags.
 */
enum ruby_robject_flags {
    /**
     * This flag has  something to do with memory footprint.   If the object is
     * "small"  enough, ruby  tries to  be creative  to abuse  padding bits  of
     * struct ::RObject for storing instance variables.  This flag denotes that
     * situation.
     *
     * @warning  This  bit has  to be  considered read-only.   Setting/clearing
     *           this  bit without  corresponding fix  up must  cause immediate
     *           SEGV.   Also,   internal  structures   of  an   object  change
     *           dynamically  and  transparently  throughout of  its  lifetime.
     *           Don't assume it being persistent.
     *
     * @internal
     *
     * 3rd parties must  not be aware that  there even is more than  one way to
     * store instance variables.  Might better be hidden.
     */
    ROBJECT_EMBED = RUBY_FL_USER1
};

struct st_table;

/**
 * Ruby's ordinal objects.  Unless otherwise  special cased, all predefined and
 * user-defined classes share this struct to hold their instances.
 */
struct RObject {

    /** Basic part, including flags and class. */
    struct RBasic basic;

    /** Object's specific fields. */
    union {

        /**
         * Object that use  separated memory region for  instance variables use
         * this pattern.
         */
        struct {
            /** Pointer to a C array that holds instance variables. */
            VALUE *ivptr;

            /**
             * This  is a  table that  holds  instance variable  name to  index
             * mapping.  Used when accessing instance variables using names.
             *
             * @internal
             *
             * This is a shortcut for `RCLASS_IV_INDEX_TBL(rb_obj_class(obj))`.
             */
            struct rb_id_table *iv_index_tbl;
        } heap;

        /* Embedded instance variables. When an object is small enough, it
         * uses this area to store the instance variables.
         *
         * This is a length 1 array because:
         *   1. GCC has a bug that does not optimize C flexible array members
         *      (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102452)
         *   2. Zero length arrays are not supported by all compilers
         */
        VALUE ary[1];
    } as;
};

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Queries the instance variables.
 *
 * @param[in]  obj  Object in question.
 * @return     Its instance variables, in C array.
 * @pre        `obj` must be an instance of ::RObject.
 *
 * @internal
 *
 * @shyouhei finds no reason for this to be visible from extension libraries.
 */
static inline VALUE *
ROBJECT_IVPTR(VALUE obj)
{
    RBIMPL_ASSERT_TYPE(obj, RUBY_T_OBJECT);

    struct RObject *const ptr = ROBJECT(obj);

    if (RB_FL_ANY_RAW(obj, ROBJECT_EMBED)) {
        return ptr->as.ary;
    }
    else {
        return ptr->as.heap.ivptr;
    }
}

#endif /* RBIMPL_ROBJECT_H */
ruby/internal/core/rclass.h000064400000006716151732674210011753 0ustar00#ifndef RBIMPL_RCLASS_H                              /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_RCLASS_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Routines to manipulate struct RClass.
 * @note       The struct RClass itself is opaque.
 */
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/internal/cast.h"

/** @cond INTERNAL_MACRO */
#define RMODULE_IS_REFINEMENT            RMODULE_IS_REFINEMENT
/** @endcond */

/**
 * Convenient casting macro.
 *
 * @param   obj  An object, which is in fact an RClass.
 * @return  The passed object casted to RClass.
 */
#define RCLASS(obj)  RBIMPL_CAST((struct RClass *)(obj))

/** @alias{RCLASS} */
#define RMODULE      RCLASS

/** @alias{rb_class_get_superclass} */
#define RCLASS_SUPER rb_class_get_superclass

/**
 * @private
 *
 * Bits that you can set to ::RBasic::flags.
 *
 * @internal
 *
 * Why is it here, given RClass itself is not?
 */
enum ruby_rmodule_flags {
    /**
     * This flag has something to do  with refinements.  A module created using
     * rb_mod_refine()  has this  flag set.   This  is the  bit which  controls
     * difference between normal inclusion versus refinements.
     */
    RMODULE_IS_REFINEMENT            = RUBY_FL_USER3
};

struct RClass; /* Opaque, declared here for RCLASS() macro. */

RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
 * Returns the superclass of a class.
 * @param[in]  klass        An object of RClass.
 * @retval     RUBY_Qfalse  `klass` has no super class.
 * @retval     otherwise    Raw superclass of `klass`
 * @see        rb_class_superclass
 *
 * ### Q&A ###
 *
 * - Q: How can a class have no super class?
 *
 * - A: `klass` could be a module.  Or it could be ::rb_cBasicObject.
 *
 * - Q: What do you mean by "raw" superclass?
 *
 * - A: This  is a  really good  question.  The  answer is  that this  function
 *      returns something  different from what  you would normally  expect.  On
 *      occasions  ruby  inserts  hidden  classes   in  a  hierarchy  of  class
 *      inheritance behind-the-scene.   Such classes are called  "iclass"es and
 *      distinguished  using  ::RUBY_T_ICLASS  in  C  level.   They  are  truly
 *      transparent from Ruby  level but can be accessed from  C, by using this
 *      API.
 */
VALUE rb_class_get_superclass(VALUE klass);
RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_RCLASS_H */
ruby/internal/core/rdata.h000064400000032536151732674210011556 0ustar00#ifndef RBIMPL_RDATA_H                               /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_RDATA_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines struct ::RData.
 */
#include "ruby/internal/config.h"

#ifdef STDC_HEADERS
# include <stddef.h>
#endif

#include "ruby/internal/attr/deprecated.h"
#include "ruby/internal/attr/warning.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/core/rbasic.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/fl_type.h"
#include "ruby/internal/value.h"
#include "ruby/internal/value_type.h"
#include "ruby/defines.h"

/** @cond INTERNAL_MACRO */
#ifndef RUBY_UNTYPED_DATA_WARNING
#define RUBY_UNTYPED_DATA_WARNING 1
#endif

#define RBIMPL_DATA_FUNC(f) RBIMPL_CAST((void (*)(void *))(f))
#define RBIMPL_ATTRSET_UNTYPED_DATA_FUNC() \
    RBIMPL_ATTR_WARNING(("untyped Data is unsafe; use TypedData instead")) \
    RBIMPL_ATTR_DEPRECATED(("by TypedData"))

#define RBIMPL_MACRO_SELECT(x, y) x ## y
#define RUBY_MACRO_SELECT(x, y)   RBIMPL_MACRO_SELECT(x, y)
/** @endcond */

/**
 * Convenient casting macro.
 *
 * @param   obj  An object, which is in fact an ::RData.
 * @return  The passed object casted to ::RData.
 */
#define RDATA(obj)                RBIMPL_CAST((struct RData *)(obj))

/**
 * Convenient getter macro.
 *
 * @param   obj  An object, which is in fact an ::RData.
 * @return  The passed object's ::RData::data field.
 */
#define DATA_PTR(obj)             RDATA(obj)->data

/**
 * This is a value you can set  to ::RData::dfree.  Setting this means the data
 * was allocated using ::ruby_xmalloc() (or variants), and shall be freed using
 * ::ruby_xfree().
 *
 * @warning  Do not  use this  if you  want to use  system malloc,  because the
 *           system  and  Ruby  might  or  might  not  share  the  same  malloc
 *           implementation.
 */
#define RUBY_DEFAULT_FREE         RBIMPL_DATA_FUNC(-1)

/**
 * This is a value you can set  to ::RData::dfree.  Setting this means the data
 * is managed by  someone else, like, statically allocated.  Of  course you are
 * on your own then.
 */
#define RUBY_NEVER_FREE           RBIMPL_DATA_FUNC(0)

/**
 * @private
 *
 * @deprecated  This macro once was a thing in the old days, but makes no sense
 *              any  longer today.   Exists  here  for backwards  compatibility
 *              only.  You can safely forget about it.
 */
#define RUBY_UNTYPED_DATA_FUNC(f) f RBIMPL_ATTRSET_UNTYPED_DATA_FUNC()

/*
#define RUBY_DATA_FUNC(func) ((void (*)(void*))(func))
*/

/**
 * This is  the type of callbacks  registered to ::RData.  The  argument is the
 * `data` field.
 */
typedef void (*RUBY_DATA_FUNC)(void*);

/**
 * @deprecated
 *
 * Old  "untyped"  user  data.   It  has  roughly  the  same  usage  as  struct
 * ::RTypedData, but lacked several features such as support for compaction GC.
 * Use of this struct is not recommended  any longer.  If it is dead necessary,
 * please inform the core devs about your usage.
 *
 * @internal
 *
 * @shyouhei tried to add RBIMPL_ATTR_DEPRECATED for this type but that yielded
 * too many warnings  in the core.  Maybe  we want to retry  later...  Just add
 * deprecated document for now.
 */
struct RData {

    /** Basic part, including flags and class. */
    struct RBasic basic;

    /**
     * This function is called when the object is experiencing GC marks.  If it
     * contains references to  other Ruby objects, you need to  mark them also.
     * Otherwise GC will smash your data.
     *
     * @see      rb_gc_mark()
     * @warning  This  is  called  during  GC  runs.   Object  allocations  are
     *           impossible at that moment (that is why GC runs).
     */
    RUBY_DATA_FUNC dmark;

    /**
     * This function is called when the object  is no longer used.  You need to
     * do whatever necessary to avoid memory leaks.
     *
     * @warning  This  is  called  during  GC  runs.   Object  allocations  are
     *           impossible at that moment (that is why GC runs).
     */
    RUBY_DATA_FUNC dfree;

    /** Pointer to the actual C level struct that you want to wrap. */
    void *data;
};

RBIMPL_SYMBOL_EXPORT_BEGIN()

/**
 * This is the primitive way to wrap an existing C struct into ::RData.
 *
 * @param[in]  klass          Ruby level class of the returning object.
 * @param[in]  datap          Pointer to the target C struct.
 * @param[in]  dmark          Mark function.
 * @param[in]  dfree          Free function.
 * @exception  rb_eTypeError  `klass` is not a class.
 * @exception  rb_eNoMemError  Out of memory.
 * @return     An allocated object that wraps `datap`.
 */
VALUE rb_data_object_wrap(VALUE klass, void *datap, RUBY_DATA_FUNC dmark, RUBY_DATA_FUNC dfree);

/**
 * Identical to  rb_data_object_wrap(), except it  allocates a new  data region
 * internally instead of taking an existing  one.  The allocation is done using
 * ruby_calloc().   Hence  it  makes  no  sense to  pass  anything  other  than
 * ::RUBY_DEFAULT_FREE to the last argument.
 *
 * @param[in]  klass          Ruby level class of the returning object.
 * @param[in]  size           Requested size of memory to allocate.
 * @param[in]  dmark          Mark function.
 * @param[in]  dfree          Free function.
 * @exception  rb_eTypeError  `klass` is not a class.
 * @exception  rb_eNoMemError  Out of memory.
 * @return     An allocated object that wraps a new `size` byte region.
 */
VALUE rb_data_object_zalloc(VALUE klass, size_t size, RUBY_DATA_FUNC dmark, RUBY_DATA_FUNC dfree);

/**
 * @private
 * Documented in include/ruby/internal/globals.h
 */
RUBY_EXTERN VALUE rb_cObject;
RBIMPL_SYMBOL_EXPORT_END()

/**
 * Converts sval, a pointer to your struct, into a Ruby object.
 *
 * @param      klass          A ruby level class.
 * @param      mark           Mark function.
 * @param      free           Free function.
 * @param      sval           A pointer to your struct.
 * @exception  rb_eTypeError  `klass` is not a class.
 * @exception  rb_eNoMemError  Out of memory.
 * @return     A created Ruby object.
 */
#define Data_Wrap_Struct(klass, mark, free, sval) \
    rb_data_object_wrap(                          \
        (klass),                                  \
        (sval),                                   \
        RBIMPL_DATA_FUNC(mark),                    \
        RBIMPL_DATA_FUNC(free))

/**
 * @private
 *
 * This is an implementation detail  of #Data_Make_Struct.  People don't use it
 * directly.
 *
 * @param  result     Variable name of created Ruby object.
 * @param  klass      Ruby level class of the object.
 * @param  type       Type name of the C struct.
 * @param  size       Size of the C struct.
 * @param  mark       Mark function.
 * @param  free       Free function.
 * @param  sval       Variable name of created C struct.
 */
#define Data_Make_Struct0(result, klass, type, size, mark, free, sval)  \
    VALUE result = rb_data_object_zalloc(          \
        (klass),                                   \
        (size),                                    \
        RBIMPL_DATA_FUNC(mark),                     \
        RBIMPL_DATA_FUNC(free));                    \
    (sval) = RBIMPL_CAST((type *)DATA_PTR(result)); \
    RBIMPL_CAST(/*suppress unused variable warnings*/(void)(sval))

/**
 * Identical  to  #Data_Wrap_Struct, except  it  allocates  a new  data  region
 * internally instead of taking an existing  one.  The allocation is done using
 * ruby_calloc().   Hence  it  makes  no  sense to  pass  anything  other  than
 * ::RUBY_DEFAULT_FREE to the `free` argument.
 *
 * @param      klass          Ruby level class of the returning object.
 * @param      type           Type name of the C struct.
 * @param      mark           Mark function.
 * @param      free           Free function.
 * @param      sval           Variable name of created C struct.
 * @exception  rb_eTypeError  `klass` is not a class.
 * @exception  rb_eNoMemError  Out of memory.
 * @return     A created Ruby object.
 */
#ifdef HAVE_STMT_AND_DECL_IN_EXPR
#define Data_Make_Struct(klass, type, mark, free, sval) \
    RB_GNUC_EXTENSION({      \
        Data_Make_Struct0(   \
            data_struct_obj, \
            klass,           \
            type,            \
            sizeof(type),    \
            mark,            \
            free,            \
            sval);           \
        data_struct_obj;     \
    })
#else
#define Data_Make_Struct(klass, type, mark, free, sval) \
    rb_data_object_make(              \
        (klass),                      \
        RBIMPL_DATA_FUNC(mark),        \
        RBIMPL_DATA_FUNC(free),        \
        RBIMPL_CAST((void **)&(sval)), \
        sizeof(type))
#endif

/**
 * Obtains a C struct from inside of a wrapper Ruby object.
 *
 * @param      obj            An instance of ::RData.
 * @param      type           Type name of the C struct.
 * @param      sval           Variable name of obtained C struct.
 * @return     Unwrapped C struct that `obj` holds.
 */
#define Data_Get_Struct(obj, type, sval) \
    ((sval) = RBIMPL_CAST((type*)rb_data_object_get(obj)))

RBIMPL_ATTRSET_UNTYPED_DATA_FUNC()
/**
 * @private
 *
 * This is an implementation detail of rb_data_object_wrap().  People don't use
 * it directly.
 *
 * @param[in]  klass          Ruby level class of the returning object.
 * @param[in]  ptr            Pointer to the target C struct.
 * @param[in]  mark           Mark function.
 * @param[in]  free           Free function.
 * @exception  rb_eTypeError  `klass` is not a class.
 * @exception  rb_eNoMemError  Out of memory.
 * @return     An allocated object that wraps `datap`.
 */
static inline VALUE
rb_data_object_wrap_warning(VALUE klass, void *ptr, RUBY_DATA_FUNC mark, RUBY_DATA_FUNC free)
{
    return rb_data_object_wrap(klass, ptr, mark, free);
}

/**
 * @private
 *
 * This is an  implementation detail of #Data_Get_Struct.  People  don't use it
 * directly.
 *
 * @param[in]  obj  An instance of ::RData.
 * @return     Unwrapped C struct that `obj` holds.
 */
static inline void *
rb_data_object_get(VALUE obj)
{
    Check_Type(obj, RUBY_T_DATA);
    return DATA_PTR(obj);
}

RBIMPL_ATTRSET_UNTYPED_DATA_FUNC()
/**
 * @private
 *
 * This is an  implementation detail of #Data_Get_Struct.  People  don't use it
 * directly.
 *
 * @param[in]  obj  An instance of ::RData.
 * @return     Unwrapped C struct that `obj` holds.
 */
static inline void *
rb_data_object_get_warning(VALUE obj)
{
    return rb_data_object_get(obj);
}

/**
 * This is an implementation detail  of #Data_Make_Struct.  People don't use it
 * directly.
 *
 * @param[in]  klass           Ruby level class of the returning object.
 * @param[in]  mark_func       Mark function.
 * @param[in]  free_func       Free function.
 * @param[in]  datap           Variable of created C struct.
 * @param[in]  size            Requested size of allocation.
 * @exception  rb_eTypeError  `klass` is not a class.
 * @exception  rb_eNoMemError  Out of memory.
 * @return     A created Ruby object.
 * @post       `*datap` holds the created C struct.
 */
static inline VALUE
rb_data_object_make(VALUE klass, RUBY_DATA_FUNC mark_func, RUBY_DATA_FUNC free_func, void **datap, size_t size)
{
    Data_Make_Struct0(result, klass, void, size, mark_func, free_func, *datap);
    return result;
}

RBIMPL_ATTR_DEPRECATED(("by: rb_data_object_wrap"))
/** @deprecated  This function was renamed to rb_data_object_wrap(). */
static inline VALUE
rb_data_object_alloc(VALUE klass, void *data, RUBY_DATA_FUNC dmark, RUBY_DATA_FUNC dfree)
{
    return rb_data_object_wrap(klass, data, dmark, dfree);
}

/** @cond INTERNAL_MACRO */
#define rb_data_object_wrap_0 rb_data_object_wrap
#define rb_data_object_wrap_1 rb_data_object_wrap_warning
#define rb_data_object_wrap_2 rb_data_object_wrap_ /* Used here vvvv */
#define rb_data_object_wrap   RUBY_MACRO_SELECT(rb_data_object_wrap_2, RUBY_UNTYPED_DATA_WARNING)
#define rb_data_object_get_0  rb_data_object_get
#define rb_data_object_get_1  rb_data_object_get_warning
#define rb_data_object_get_2  rb_data_object_get_ /* Used here vvvv */
#define rb_data_object_get    RUBY_MACRO_SELECT(rb_data_object_get_2, RUBY_UNTYPED_DATA_WARNING)
#define rb_data_object_make_0 rb_data_object_make
#define rb_data_object_make_1 rb_data_object_make_warning
#define rb_data_object_make_2 rb_data_object_make_ /* Used here vvvv */
#define rb_data_object_make   RUBY_MACRO_SELECT(rb_data_object_make_2, RUBY_UNTYPED_DATA_WARNING)
/** @endcond */
#endif /* RBIMPL_RDATA_H */
ruby/internal/eval.h000064400000044315151732674210010460 0ustar00#ifndef RBIMPL_EVAL_H                                /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_EVAL_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Declares ::rb_eval_string().
 */
#include "ruby/internal/dllexport.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

RBIMPL_ATTR_NONNULL(())
/**
 * Evaluates the given string.
 *
 * In case  it is called  from within a  C-backended method, the  evaluation is
 * done under  the current binding.  However  there can be no  method.  On such
 * situation this  function evaluates  in an  isolated binding,  like `require`
 * runs in a separate one.
 *
 * `__FILE__`  will  be  `"(eval)"`,  and  `__LINE__`  starts  from  1  in  the
 * evaluation.
 *
 * @param[in]  str            Ruby code to evaluate.
 * @exception  rb_eException  Raises an exception on error.
 * @return     The evaluated result.
 *
 * @internal
 *
 * @shyouhei's old tale about the birth and growth of this function:
 *
 * At  the beginning,  there  was no  rb_eval_string().   @shyouhei heard  that
 * @shugo, author of  Apache httpd's mod_ruby module, requested  @matz for this
 * API.  He wanted a way so that mod_ruby can evaluate ruby scripts one by one,
 * separately, in each different contexts.  So  this function was made.  It was
 * designed to be a global interpreter entry point like ruby_run_node().
 *
 * The  way it  is implemented  however  allows extension  libraries (not  just
 * programs like  Apache httpd) to call  this function.  Because its  name says
 * nothing  about the  initial design,  people  started to  think of  it as  an
 * orthodox  way  to  call  ruby  level  `eval`  method  from  their  extension
 * libraries.  Even our `extension.rdoc` has had a description of this function
 * basically according to this understanding.
 *
 * The old  (mod_ruby like) usage still  works.  But over time,  usages of this
 * function from extension libraries got  popular, while mod_ruby faded out; is
 * no  longer maintained  now.  Devs  decided to  actively support  both.  This
 * function  now auto-detects  how  it is  called, and  switches  how it  works
 * depending on it.
 *
 * @see https://bugs.ruby-lang.org/issues/18780
 */
VALUE rb_eval_string(const char *str);

RBIMPL_ATTR_NONNULL((1))
/**
 * Identical to  rb_eval_string(), except  it avoids potential  global escapes.
 * Such global escapes include exceptions, `throw`, `break`, for example.
 *
 * It first evaluates the given string  as rb_eval_string() does.  If no global
 * escape occurred during the evaluation, it returns the result and `*state` is
 * zero.   Otherwise, it  returns some  undefined  value and  sets `*state`  to
 * nonzero.  If state is `NULL`, it is not set in both cases.
 *
 * @param[in]   str    Ruby code to evaluate.
 * @param[out]  state  State of execution.
 * @return      The  evaluated  result  if  succeeded, an  undefined  value  if
 *              otherwise.
 * @post        `*state` is set to zero if succeeded.  Nonzero otherwise.
 * @warning     You have to clear the error info with `rb_set_errinfo(Qnil)` if
 *              you decide to ignore the caught exception.
 * @see         rb_eval_string
 * @see         rb_protect
 *
 * @internal
 *
 * The "undefined value"  described above is in fact ::RUBY_Qnil  for now.  But
 * @shyouhei doesn't think that we would never change that.
 *
 * Though   not  a   part  of   our  public   API,  `state`   is  in   fact  an
 * enum ruby_tag_type.  You can  see the potential "nonzero"  values by looking
 * at vm_core.h.
 */
VALUE rb_eval_string_protect(const char *str, int *state);

RBIMPL_ATTR_NONNULL((1))
/**
 * Identical to rb_eval_string_protect(), except  it evaluates the given string
 * under  a module  binding in  an isolated  binding.  This  is the  same as  a
 * binding for loaded libraries on `rb_load(something, true)`.
 *
 * @param[in]   str    Ruby code to evaluate.
 * @param[out]  state  State of execution.
 * @return      The  evaluated  result  if  succeeded, an  undefined  value  if
 *              otherwise.
 * @post        `*state` is set to zero if succeeded.  Nonzero otherwise.
 * @warning     You have to clear the error info with `rb_set_errinfo(Qnil)` if
 *              you decide to ignore the caught exception.
 * @see         rb_eval_string
 */
VALUE rb_eval_string_wrap(const char *str, int *state);

/**
 * Calls a method.  Can call both public and private methods.
 *
 * @param[in,out]  recv               Receiver of the method.
 * @param[in]      mid                Name of the method to call.
 * @param[in]      n                  Number of arguments that follow.
 * @param[in]      ...                Arbitrary number of method arguments.
 * @exception      rb_eNoMethodError  No such method.
 * @exception      rb_eException      Any exceptions happen inside.
 * @return         What the method evaluates to.
 */
VALUE rb_funcall(VALUE recv, ID mid, int n, ...);

/**
 * Identical  to rb_funcall(),  except it  takes the  method arguments  as a  C
 * array.
 *
 * @param[in,out]  recv               Receiver of the method.
 * @param[in]      mid                Name of the method to call.
 * @param[in]      argc               Number of arguments.
 * @param[in]      argv               Arbitrary number of method arguments.
 * @exception      rb_eNoMethodError  No such method.
 * @exception      rb_eException      Any exceptions happen inside.
 * @return         What the method evaluates to.
 */
VALUE rb_funcallv(VALUE recv, ID mid, int argc, const VALUE *argv);

/**
 * Identical to  rb_funcallv(), except you can  specify how to handle  the last
 * element of the given array.
 *
 * @param[in,out]  recv               Receiver of the method.
 * @param[in]      mid                Name of the method to call.
 * @param[in]      argc               Number of arguments.
 * @param[in]      argv               Arbitrary number of method arguments.
 * @param[in]      kw_splat           Handling of keyword parameters:
 *   - RB_NO_KEYWORDS           `argv`'s last is not a keyword argument.
 *   - RB_PASS_KEYWORDS         `argv`'s last is a keyword argument.
 *   - RB_PASS_CALLED_KEYWORDS  it depends if there is a passed block.
 * @exception      rb_eNoMethodError  No such method.
 * @exception      rb_eException      Any exceptions happen inside.
 * @return         What the method evaluates to.
 */
VALUE rb_funcallv_kw(VALUE recv, ID mid, int argc, const VALUE *argv, int kw_splat);

/**
 * Identical  to  rb_funcallv(),  except  it only  takes  public  methods  into
 * account.  This is roughly Ruby's `Object#public_send`.
 *
 * @param[in,out]  recv               Receiver of the method.
 * @param[in]      mid                Name of the method to call.
 * @param[in]      argc               Number of arguments.
 * @param[in]      argv               Arbitrary number of method arguments.
 * @exception      rb_eNoMethodError  No such method.
 * @exception      rb_eNoMethodError  The method is private or protected.
 * @exception      rb_eException      Any exceptions happen inside.
 * @return         What the method evaluates to.
 */
VALUE rb_funcallv_public(VALUE recv, ID mid, int argc, const VALUE *argv);

/**
 * Identical to rb_funcallv_public(), except you  can specify how to handle the
 * last element of the given array.  It can also be seen as a routine identical
 * to rb_funcallv_kw(), except it only takes public methods into account.
 *
 * @param[in,out]  recv               Receiver of the method.
 * @param[in]      mid                Name of the method to call.
 * @param[in]      argc               Number of arguments.
 * @param[in]      argv               Arbitrary number of method arguments.
 * @param[in]      kw_splat           Handling of keyword parameters:
 *   - RB_NO_KEYWORDS           `argv`'s last is not a keyword argument.
 *   - RB_PASS_KEYWORDS         `argv`'s last is a keyword argument.
 *   - RB_PASS_CALLED_KEYWORDS  it depends if there is a passed block.
 * @exception      rb_eNoMethodError  No such method.
 * @exception      rb_eNoMethodError  The method is private or protected.
 * @exception      rb_eException      Any exceptions happen inside.
 * @return         What the method evaluates to.
 */
VALUE rb_funcallv_public_kw(VALUE recv, ID mid, int argc, const VALUE *argv, int kw_splat);

/**
 * @deprecated   This  is an  old  name of  rb_funcallv().   Provided here  for
 *               backwards compatibility  to 2.x programs (introduced  in 2.1).
 *               It is not a good name.  Please don't use it any longer.
 */
#define rb_funcall2 rb_funcallv

/**
 * @deprecated   This is  an old  name of rb_funcallv_public().   Provided here
 *               for  backwards compatibility  to 2.x  programs (introduced  in
 *               2.1).  It is not a good name.  Please don't use it any longer.
 */
#define rb_funcall3 rb_funcallv_public

/**
 * Identical to rb_funcallv_public(), except you can pass the passed block.
 *
 * Sometimes you want  to "pass" a block parameter form  one method to another.
 * Suppose you have this Ruby method `foo`:
 *
 * ```ruby
 * def foo(x, y, &z)
 *   x.open(y, &z)
 * end
 * ```
 *
 * And    suppose   you    want    to   translate    this    into   C.     Then
 * rb_funcall_passing_block() function is usable in this situation.
 *
 * ```CXX
 * VALUE
 * foo_translated_into_C(VALUE self, VALUE x, VALUE y)
 * {
 *     const auto open = rb_intern("open");
 *
 *     return rb_funcall_passing_block(x, open, 1, &y);
 * }
 * ```
 *
 * @see            rb_yield_block
 * @param[in,out]  recv               Receiver of the method.
 * @param[in]      mid                Name of the method to call.
 * @param[in]      argc               Number of arguments.
 * @param[in]      argv               Arbitrary number of method arguments.
 * @exception      rb_eNoMethodError  No such method.
 * @exception      rb_eNoMethodError  The method is private or protected.
 * @exception      rb_eException      Any exceptions happen inside.
 * @return         What the method evaluates to.
 */
VALUE rb_funcall_passing_block(VALUE recv, ID mid, int argc, const VALUE *argv);

/**
 * Identical  to rb_funcallv_passing_block(),  except  you can  specify how  to
 * handle  the last  element of  the given  array.  It  can also  be seen  as a
 * routine identical to rb_funcallv_public_kw(), except you can pass the passed
 * block.
 *
 * @param[in,out]  recv               Receiver of the method.
 * @param[in]      mid                Name of the method to call.
 * @param[in]      argc               Number of arguments.
 * @param[in]      argv               Arbitrary number of method arguments.
 * @param[in]      kw_splat           Handling of keyword parameters:
 *   - RB_NO_KEYWORDS           `argv`'s last is not a keyword argument.
 *   - RB_PASS_KEYWORDS         `argv`'s last is a keyword argument.
 *   - RB_PASS_CALLED_KEYWORDS  it depends if there is a passed block.
 * @exception      rb_eNoMethodError  No such method.
 * @exception      rb_eNoMethodError  The method is private or protected.
 * @exception      rb_eException      Any exceptions happen inside.
 * @return         What the method evaluates to.
 */
VALUE rb_funcall_passing_block_kw(VALUE recv, ID mid, int argc, const VALUE *argv, int kw_splat);

/**
 * Identical to  rb_funcallv_public(), except  you can pass  a block.   A block
 * here  basically is  an  instance of  ::rb_cProc.  If  you  want to  exercise
 * `to_proc` conversion, do so before passing it here.  However nil and symbols
 * are special-case allowed.
 *
 * @param[in,out]  recv               Receiver of the method.
 * @param[in]      mid                Name of the method to call.
 * @param[in]      argc               Number of arguments.
 * @param[in]      argv               Arbitrary number of method arguments.
 * @param[in]      procval            An instance of Proc, Symbol, or NilClass.
 * @exception      rb_eNoMethodError  No such method.
 * @exception      rb_eNoMethodError  The method is private or protected.
 * @exception      rb_eException      Any exceptions happen inside.
 * @return         What the method evaluates to.
 *
 * @internal
 *
 * Implementation-wise, `procval`  is in  fact a  "block handler"  object.  You
 * could also pass an IFUNC (block_handler_ifunc) here to say precise.  --- But
 * AFAIK there is no  3rd party way to even know that  there are objects called
 * IFUNC behind-the-scene.
 */
VALUE rb_funcall_with_block(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE procval);

/**
 * Identical to rb_funcallv_with_block(), except you  can specify how to handle
 * the last  element of  the given  array.  It can  also be  seen as  a routine
 * identical to rb_funcallv_public_kw(), except you can pass a block.
 *
 * @param[in,out]  recv               Receiver of the method.
 * @param[in]      mid                Name of the method to call.
 * @param[in]      argc               Number of arguments.
 * @param[in]      argv               Arbitrary number of method arguments.
 * @param[in]      procval            An instance of Proc, Symbol, or NilClass.
 * @param[in]      kw_splat           Handling of keyword parameters:
 *   - RB_NO_KEYWORDS           `argv`'s last is not a keyword argument.
 *   - RB_PASS_KEYWORDS         `argv`'s last is a keyword argument.
 *   - RB_PASS_CALLED_KEYWORDS  it depends if there is a passed block.
 * @exception      rb_eNoMethodError  No such method.
 * @exception      rb_eNoMethodError  The method is private or protected.
 * @exception      rb_eException      Any exceptions happen inside.
 * @return         What the method evaluates to.
 */
VALUE rb_funcall_with_block_kw(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE procval, int kw_splat);

/**
 * This resembles ruby's `super`.
 *
 * @param[in]  argc               Number of arguments.
 * @param[in]  argv               Arbitrary number of method arguments.
 * @exception  rb_eNoMethodError  No super method are there.
 * @exception  rb_eException      Any exceptions happen inside.
 * @return     What the super method evaluates to.
 */
VALUE rb_call_super(int argc, const VALUE *argv);

/**
 * Identical to rb_call_super(), except you can  specify how to handle the last
 * element of the given array.
 *
 * @param[in]  argc               Number of arguments.
 * @param[in]  argv               Arbitrary number of method arguments.
 * @param[in]  kw_splat           Handling of keyword parameters:
 *   - RB_NO_KEYWORDS           `argv`'s last is not a keyword argument.
 *   - RB_PASS_KEYWORDS         `argv`'s last is a keyword argument.
 *   - RB_PASS_CALLED_KEYWORDS  it depends if there is a passed block.
 * @exception  rb_eNoMethodError  No super method are there.
 * @exception  rb_eException      Any exceptions happen inside.
 * @return     What the super method evaluates to.
 */
VALUE rb_call_super_kw(int argc, const VALUE *argv, int kw_splat);

/**
 * This resembles ruby's `self`.
 *
 * @exception  rb_eRuntimeError  Called from outside of method context.
 * @return     Current receiver.
 */
VALUE rb_current_receiver(void);

RBIMPL_ATTR_NONNULL((2))
/**
 * Keyword argument deconstructor.
 *
 * Retrieves argument values bound to  keywords, which directed by `table` into
 * `values`,  deleting retrieved  entries  from `keyword_hash`  along the  way.
 * First  `required` number  of  IDs  referred by  `table`  are mandatory,  and
 * succeeding `optional`  (`-optional-1` if  `optional` is negative)  number of
 * IDs are  optional.  If a mandatory  key is not contained  in `keyword_hash`,
 * raises ::rb_eArgError.  If an optional key is not present in `keyword_hash`,
 * the  corresponding  element  in  `values`   is  set  to  ::RUBY_Qundef.   If
 * `optional` is negative, rest of `keyword_hash` are ignored, otherwise raises
 * ::rb_eArgError.
 *
 * @warning     Handling keyword arguments in the  C API is less efficient than
 *              handling them  in Ruby.  Consider  using a Ruby  wrapper method
 *              around a non-keyword C function.
 * @see         https://bugs.ruby-lang.org/issues/11339
 * @param[out]  keyword_hash  Target hash to deconstruct.
 * @param[in]   table         List of keywords that you are interested in.
 * @param[in]   required      Number of mandatory keywords.
 * @param[in]   optional      Number of optional keywords (can be negative).
 * @param[out]  values        Buffer to be filled.
 * @exception   rb_eArgError  Absence of a mandatory keyword.
 * @exception   rb_eArgError  Found an unknown keyword.
 * @return      Number of found values that are stored into `values`.
 */
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values);

RBIMPL_ATTR_NONNULL(())
/**
 * Splits a hash into two.
 *
 * Takes  a hash  of various  keys, and  split it  into symbol-keyed  parts and
 * others.   Symbol-keyed part  becomes  the return  value.   What remains  are
 * returned as a new hash object stored at the argument pointer.
 *
 * @param[in,out]  orighash  Pointer to a target hash to split.
 * @return         An extracted keyword hash.
 * @post           Upon  successful return  `orighash` points  to another  hash
 *                 object, whose contents are the remainder of the operation.
 * @note           The argument hash object is not modified.
 */
VALUE rb_extract_keywords(VALUE *orighash);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_EVAL_H */
ruby/internal/dllexport.h000064400000006056151732674210011546 0ustar00#ifndef RBIMPL_DLLEXPORT_H                           /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_DLLEXPORT_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Tweaking visibility of C variables/functions.
 */
#include "ruby/internal/config.h"
#include "ruby/internal/compiler_is.h"

/**
 * Declaration of externally visible global variables.  Here "externally" means
 * they should  be visible  from extension  libraries.  Depending  on operating
 * systems (dynamic linkers,  to be precise), global variables inside  of a DLL
 * may  or may  not be  visible  form outside  of  that DLL  by default.   This
 * declaration manually tweaks  that default and ensures  the declared variable
 * be truly globally visible.
 *
 * ```CXX
 * extern VALUE foo;      // hidden on some OS
 * RUBY_EXTERN VALUE foo; // ensure visible
 * ```
 */
#undef RUBY_EXTERN
#if defined(RUBY_EXPORT)
# define RUBY_EXTERN extern
#elif defined(_WIN32)
# define RUBY_EXTERN extern __declspec(dllimport)
#else
# define RUBY_EXTERN extern
#endif

#ifndef RUBY_SYMBOL_EXPORT_BEGIN
# define RUBY_SYMBOL_EXPORT_BEGIN /* begin */
#endif

#ifndef RUBY_SYMBOL_EXPORT_END
# define RUBY_SYMBOL_EXPORT_END   /* end */
#endif

#ifndef RUBY_FUNC_EXPORTED
# define RUBY_FUNC_EXPORTED /* void */
#endif

/** @endcond */

/** Shortcut macro equivalent to `RUBY_SYMBOL_EXPORT_BEGIN extern "C" {`.
 * \@shyouhei finds it handy. */
#if defined(__DOXYGEN__)
# define RBIMPL_SYMBOL_EXPORT_BEGIN() /* void */
#elif defined(__cplusplus)
# define RBIMPL_SYMBOL_EXPORT_BEGIN() RUBY_SYMBOL_EXPORT_BEGIN extern "C" {
#else
# define RBIMPL_SYMBOL_EXPORT_BEGIN() RUBY_SYMBOL_EXPORT_BEGIN
#endif

/** Counterpart of #RBIMPL_SYMBOL_EXPORT_BEGIN */
#if defined(__DOXYGEN__)
# define RBIMPL_SYMBOL_EXPORT_END() /* void */
#elif defined(__cplusplus)
# define RBIMPL_SYMBOL_EXPORT_END() } RUBY_SYMBOL_EXPORT_END
#else
# define RBIMPL_SYMBOL_EXPORT_END()   RUBY_SYMBOL_EXPORT_END
#endif
#endif /* RBIMPL_DLLEXPORT_H */
ruby/internal/attr/packed_struct.h000064400000004107151732674210013331 0ustar00#ifndef RBIMPL_ATTR_PACKED_STRUCT_H                 /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_PACKED_STRUCT_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_ATTR_PACKED_STRUCT_BEGIN,
 *             #RBIMPL_ATTR_PACKED_STRUCT_END,
 *             #RBIMPL_ATTR_PACKED_STRUCT_UNALIGNED_BEGIN, and
 *             #RBIMPL_ATTR_PACKED_STRUCT_UNALIGNED_END.
 */
#include "ruby/internal/config.h"

#ifndef RBIMPL_ATTR_PACKED_STRUCT_BEGIN
# define RBIMPL_ATTR_PACKED_STRUCT_BEGIN() /* void */
#endif
#ifndef RBIMPL_ATTR_PACKED_STRUCT_END
# define RBIMPL_ATTR_PACKED_STRUCT_END() /* void */
#endif

#if UNALIGNED_WORD_ACCESS
# define RBIMPL_ATTR_PACKED_STRUCT_UNALIGNED_BEGIN() RBIMPL_ATTR_PACKED_STRUCT_BEGIN()
# define RBIMPL_ATTR_PACKED_STRUCT_UNALIGNED_END() RBIMPL_ATTR_PACKED_STRUCT_END()
#else
# define RBIMPL_ATTR_PACKED_STRUCT_UNALIGNED_BEGIN() /* void */
# define RBIMPL_ATTR_PACKED_STRUCT_UNALIGNED_END() /* void */
#endif

#endif
ruby/internal/attr/forceinline.h000064400000003752151732674210013000 0ustar00#ifndef RBIMPL_ATTR_FORCEINLINE_H                    /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_FORCEINLINE_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_ATTR_FORCEINLINE.
 */
#include "ruby/internal/compiler_since.h"
#include "ruby/internal/has/attribute.h"

/**
 * Wraps (or  simulates) `__forceinline`.  MSVC complains  on declarations like
 * `static inline __forceinline void foo()`.   It  seems  MSVC's  `inline`  and
 * `__forceinline` are mutually exclusive.  We have to mimic that behaviour for
 * non-MSVC compilers.
 */
#if RBIMPL_COMPILER_SINCE(MSVC, 12, 0, 0)
# define RBIMPL_ATTR_FORCEINLINE() __forceinline
#elif RBIMPL_HAS_ATTRIBUTE(always_inline)
# define RBIMPL_ATTR_FORCEINLINE() __attribute__((__always_inline__)) inline
#else
# define RBIMPL_ATTR_FORCEINLINE() inline
#endif

#endif /* RBIMPL_ATTR_FORCEINLINE_H */
ruby/internal/attr/alloc_size.h000064400000003220151732674210012615 0ustar00#ifndef RBIMPL_ATTR_ALLOC_SIZE_H                     /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_ALLOC_SIZE_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_ATTR_ALLOC_SIZE.
 */
#include "ruby/internal/has/attribute.h"

/** Wraps (or simulates) `__attribute__((alloc_size))` */
#if RBIMPL_HAS_ATTRIBUTE(alloc_size)
# define RBIMPL_ATTR_ALLOC_SIZE(tuple) __attribute__((__alloc_size__ tuple))
#else
# define RBIMPL_ATTR_ALLOC_SIZE(tuple) /* void */
#endif

#endif /* RBIMPL_ATTR_ALLOC_SIZE_H */
ruby/internal/attr/format.h000064400000003405151732674210011766 0ustar00#ifndef RBIMPL_ATTR_FORMAT_H                         /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_FORMAT_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_ATTR_FORMAT.
 */
#include "ruby/internal/has/attribute.h"

/** Wraps (or simulates) `__attribute__((format))` */
#if RBIMPL_HAS_ATTRIBUTE(format)
# define RBIMPL_ATTR_FORMAT(x, y, z) __attribute__((__format__(x, y, z)))
#else
# define RBIMPL_ATTR_FORMAT(x, y, z) /* void */
#endif

#if defined(__MINGW_PRINTF_FORMAT)
# define RBIMPL_PRINTF_FORMAT __MINGW_PRINTF_FORMAT
#else
# define RBIMPL_PRINTF_FORMAT __printf__
#endif

#endif /* RBIMPL_ATTR_FORMAT_H */
ruby/internal/attr/diagnose_if.h000064400000003723151732674210012750 0ustar00#ifndef RBIMPL_ATTR_DIAGNOSE_IF_H                    /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_DIAGNOSE_IF_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_ATTR_DIAGNOSE_IF.
 */
#include "ruby/internal/has/attribute.h"
#include "ruby/internal/warning_push.h"

/** Wraps (or simulates) `__attribute__((diagnose_if))` */
#if RBIMPL_COMPILER_BEFORE(Clang, 5, 0, 0)
# /* https://bugs.llvm.org/show_bug.cgi?id=34319 */
# define RBIMPL_ATTR_DIAGNOSE_IF(_, __, ___) /* void */

#elif RBIMPL_HAS_ATTRIBUTE(diagnose_if)
# define RBIMPL_ATTR_DIAGNOSE_IF(_, __, ___) \
    RBIMPL_WARNING_PUSH() \
    RBIMPL_WARNING_IGNORED(-Wgcc-compat) \
    __attribute__((__diagnose_if__(_, __, ___))) \
    RBIMPL_WARNING_POP()

#else
# define RBIMPL_ATTR_DIAGNOSE_IF(_, __, ___) /* void */
#endif

#endif /* RBIMPL_ATTR_DIAGNOSE_IF_H */
ruby/internal/attr/deprecated.h000064400000006474151732674210012607 0ustar00#ifndef RBIMPL_ATTR_DEPRECATED_H                     /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_DEPRECATED_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_ATTR_DEPRECATED.
 */
#include "ruby/internal/compiler_since.h"
#include "ruby/internal/has/attribute.h"
#include "ruby/internal/has/c_attribute.h"
#include "ruby/internal/has/cpp_attribute.h"
#include "ruby/internal/has/declspec_attribute.h"
#include "ruby/internal/has/extension.h"

/** Wraps (or simulates) `[[deprecated]]` */
#if defined(__COVERITY__)
/* Coverity Scan emulates gcc but seems not to support this attribute correctly */
# define RBIMPL_ATTR_DEPRECATED(msg)

#elif RBIMPL_HAS_EXTENSION(attribute_deprecated_with_message)
# define RBIMPL_ATTR_DEPRECATED(msg) __attribute__((__deprecated__ msg))

#elif defined(__cplusplus) && RBIMPL_COMPILER_SINCE(GCC, 10, 1, 0) && RBIMPL_COMPILER_BEFORE(GCC, 10, 3, 0)
# /* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95302 */
# define RBIMPL_ATTR_DEPRECATED(msg) /* disable until they fix this bug */

#elif RBIMPL_COMPILER_SINCE(GCC, 4, 5, 0)
# define RBIMPL_ATTR_DEPRECATED(msg) __attribute__((__deprecated__ msg))

#elif RBIMPL_COMPILER_SINCE(Intel, 13, 0, 0)
# define RBIMPL_ATTR_DEPRECATED(msg) __attribute__((__deprecated__ msg))

#elif RBIMPL_HAS_ATTRIBUTE(deprecated) /* but not with message. */
# define RBIMPL_ATTR_DEPRECATED(msg) __attribute__((__deprecated__))

#elif RBIMPL_COMPILER_SINCE(MSVC, 14, 0, 0)
# define RBIMPL_ATTR_DEPRECATED(msg) __declspec(deprecated msg)

#elif RBIMPL_HAS_DECLSPEC_ATTRIBUTE(deprecated)
# define RBIMPL_ATTR_DEPRECATED(msg) __declspec(deprecated)

#elif RBIMPL_HAS_CPP_ATTRIBUTE(deprecated)
# define RBIMPL_ATTR_DEPRECATED(msg) [[deprecated msg]]

#elif RBIMPL_HAS_C_ATTRIBUTE(deprecated)
# define RBIMPL_ATTR_DEPRECATED(msg) [[deprecated msg]]

#else
# define RBIMPL_ATTR_DEPRECATED(msg) /* void */
#endif

/** This is when a function is used internally (for backwards compatibility
 * etc.), but extension libraries must consider it deprecated. */
#if defined(RUBY_EXPORT)
# define RBIMPL_ATTR_DEPRECATED_EXT(msg) /* void */
#else
# define RBIMPL_ATTR_DEPRECATED_EXT(msg) RBIMPL_ATTR_DEPRECATED(msg)
#endif

#endif /* RBIMPL_ATTR_DEPRECATED_H */
ruby/internal/attr/weakref.h000064400000003165151732674210012125 0ustar00#ifndef RBIMPL_ATTR_WEAKREF_H                        /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_WEAKREF_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_ATTR_WEAKREF.
 */
#include "ruby/internal/has/attribute.h"

/** Wraps (or simulates) `__attribute__((weakref))` */
#if RBIMPL_HAS_ATTRIBUTE(weakref)
# define RBIMPL_ATTR_WEAKREF(sym) __attribute__((__weakref__(# sym)))
#else
# define RBIMPL_ATTR_WEAKREF(sym) /* void */
#endif

#endif /* RBIMPL_ATTR_WEAKREF_H */
ruby/internal/attr/constexpr.h000064400000006700151732674210012524 0ustar00#ifndef RBIMPL_ATTR_CONSTEXPR_H                      /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_CONSTEXPR_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      #RBIMPL_ATTR_CONSTEXPR.
 */
#include "ruby/internal/has/feature.h"
#include "ruby/internal/compiler_is.h"

/** @cond INTERNAL_MACRO */
#if ! defined(__cplusplus)
# /* Makes no sense. */
# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX11 0
# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX14 0

#elif defined(__cpp_constexpr)
# /* https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations */
# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX11 (__cpp_constexpr >= 200704L)
# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX14 (__cpp_constexpr >= 201304L)

#elif RBIMPL_COMPILER_SINCE(MSVC, 19, 0, 0)
# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX11 RBIMPL_COMPILER_SINCE(MSVC, 19, 00, 00)
# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX14 RBIMPL_COMPILER_SINCE(MSVC, 19, 11, 00)

#elif RBIMPL_COMPILER_SINCE(SunPro, 5, 13, 0)
# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX11 (__cplusplus >= 201103L)
# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX14 (__cplusplus >= 201402L)

#elif RBIMPL_COMPILER_SINCE(GCC, 4, 9, 0)
# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX11 (__cplusplus >= 201103L)
# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX14 (__cplusplus >= 201402L)

#elif RBIMPL_HAS_FEATURE(cxx_relaxed_constexpr)
# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX11 1
# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX14 1

#elif RBIMPL_HAS_FEATURE(cxx_constexpr)
# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX11 1
# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX14 0

#else
# /* :FIXME: icpc must have constexpr but don't know how to detect. */
# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX11 0
# define RBIMPL_HAS_ATTR_CONSTEXPR_CXX14 0
#endif
/** @endcond */

/** Wraps (or simulates) C++11 `constexpr`.  */
#if RBIMPL_HAS_ATTR_CONSTEXPR_CXX14
# define RBIMPL_ATTR_CONSTEXPR(_) constexpr

#elif RBIMPL_HAS_ATTR_CONSTEXPR_CXX11
# define RBIMPL_ATTR_CONSTEXPR(_) RBIMPL_ATTR_CONSTEXPR_ ## _
# define RBIMPL_ATTR_CONSTEXPR_CXX11 constexpr
# define RBIMPL_ATTR_CONSTEXPR_CXX14 /* void */

#else
# define RBIMPL_ATTR_CONSTEXPR(_) /* void */
#endif

/** Enables #RBIMPL_ATTR_CONSTEXPR if and only if. ! #RUBY_DEBUG. */
#if !RUBY_DEBUG
# define RBIMPL_ATTR_CONSTEXPR_UNLESS_DEBUG(_) RBIMPL_ATTR_CONSTEXPR(_)
#else
# define RBIMPL_ATTR_CONSTEXPR_UNLESS_DEBUG(_) /* void */
#endif

#endif /* RBIMPL_ATTR_CONSTEXPR_H */
ruby/internal/attr/warning.h000064400000003162151732674210012143 0ustar00#ifndef RBIMPL_ATTR_WARNING_H                        /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_WARNING_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_ATTR_WARNING.
 */
#include "ruby/internal/has/attribute.h"

/** Wraps (or simulates) `__attribute__((warning))` */
#if RBIMPL_HAS_ATTRIBUTE(warning)
# define RBIMPL_ATTR_WARNING(msg) __attribute__((__warning__ msg))
#else
# define RBIMPL_ATTR_WARNING(msg) /* void */
#endif

#endif /* RBIMPL_ATTR_WARNING_H */
ruby/internal/attr/nonnull.h000064400000003336151732674210012166 0ustar00#ifndef RBIMPL_ATTR_NONNULL_H                        /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_NONNULL_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_ATTR_NONNULL.
 */
#include "ruby/internal/has/attribute.h"

/** Wraps (or simulates) `__attribute__((nonnull))` */
#if RBIMPL_HAS_ATTRIBUTE(nonnull)
# define RBIMPL_ATTR_NONNULL(list) __attribute__((__nonnull__ list))
# define RBIMPL_NONNULL_ARG(arg) RBIMPL_ASSERT_NOTHING
#else
# define RBIMPL_ATTR_NONNULL(list) /* void */
# define RBIMPL_NONNULL_ARG(arg) RUBY_ASSERT(arg)
#endif

#endif /* RBIMPL_ATTR_NONNULL_H */
ruby/internal/attr/enum_extensibility.h000064400000003275151732674210014423 0ustar00#ifndef RBIMPL_ATTR_ENUM_EXTENSIBILITY_H             /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_ENUM_EXTENSIBILITY_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      #RBIMPL_ATTR_ENUM_EXTENSIBILITY.
 */
#include "ruby/internal/has/attribute.h"

/** Wraps (or simulates) `__attribute__((enum_extensibility))` */
#if RBIMPL_HAS_ATTRIBUTE(enum_extensibility)
# define RBIMPL_ATTR_ENUM_EXTENSIBILITY(_) __attribute__((__enum_extensibility__(_)))
#else
# define RBIMPL_ATTR_ENUM_EXTENSIBILITY(_) /* void */
#endif

#endif /* RBIMPL_ATTR_ENUM_EXTENSIBILITY_H */
ruby/internal/attr/noalias.h000064400000006734151732674210012134 0ustar00#ifndef RBIMPL_ATTR_NOALIAS_H                        /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_NOALIAS_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_ATTR_NOALIAS.
 *
 * ### Q&A ###
 *
 * - Q: There  are  seemingly   similar  attributes  named  #RBIMPL_ATTR_CONST,
 *      #RBIMPL_ATTR_PURE, and #RBIMPL_ATTR_NOALIAS.  What are the difference?
 *
 * - A: Allowed operations are different.
 *
 *     - #RBIMPL_ATTR_CONST ... Functions attributed by this are not allowed to
 *       read/write  _any_ pointers  at all  (there are  exceptional situations
 *       when  reading a  pointer is  possible but  forget that;  they are  too
 *       exceptional  to be  useful).  Just  remember that  everything pointer-
 *       related are NG.
 *
 *     - #RBIMPL_ATTR_PURE  ...   Functions attributed  by  this  can read  any
 *       nonvolatile pointers, but  no writes are allowed at  all.  The ability
 *       to read _any_ nonvolatile pointers  makes it possible to mark ::VALUE-
 *       taking functions as being pure, as long as they are read-only.
 *
 *     - #RBIMPL_ATTR_NOALIAS  ...  Can  both   read/write,  but  only  through
 *       pointers  passed to  the function  as parameters.   This is  a typical
 *       situation when you create a  C++ non-static member function which only
 *       concerns `this`.  No  global variables are allowed  to read/write.  So
 *       this is not a super-set of being pure.  If you want to read something,
 *       that has to  be passed to the function as  a pointer.  ::VALUE -taking
 *       functions thus cannot be attributed as such.
 */
#include "ruby/internal/compiler_since.h"
#include "ruby/internal/has/declspec_attribute.h"

/** Wraps (or simulates) `__declspec((noalias))` */
#if RBIMPL_COMPILER_BEFORE(Clang, 12, 0, 0)
# /*
#  * `::llvm::Attribute::ArgMemOnly`  was buggy  before.  Maybe  because nobody
#  * actually seriously used it.  It seems they somehow mitigated the situation
#  * in  LLVM  12.  Still  not  found  the  exact  changeset which  fiexed  the
#  * attribute, though.
#  *
#  * :FIXME: others (armclang, xlclang, ...) can also be affected?
#  */
# define RBIMPL_ATTR_NOALIAS() /* void */
#elif RBIMPL_HAS_DECLSPEC_ATTRIBUTE(noalias)
# define RBIMPL_ATTR_NOALIAS() __declspec(noalias)
#else
# define RBIMPL_ATTR_NOALIAS() /* void */
#endif

#endif /* RBIMPL_ATTR_NOALIAS_H */
ruby/internal/attr/nonstring.h000064400000003705151732674210012522 0ustar00#ifndef RBIMPL_ATTR_NONSTRING_H                        /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_NONSTRING_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_ATTR_NONSTRING.
 */
#include "ruby/internal/has/attribute.h"

/** Wraps (or simulates) `__attribute__((nonstring))` */
#if RBIMPL_HAS_ATTRIBUTE(nonstring)
# define RBIMPL_ATTR_NONSTRING() __attribute__((nonstring))
# if RBIMPL_COMPILER_SINCE(GCC, 15, 0, 0)
#   define RBIMPL_ATTR_NONSTRING_ARRAY() RBIMPL_ATTR_NONSTRING()
# elif RBIMPL_COMPILER_SINCE(Clang, 21, 0, 0)
#   define RBIMPL_ATTR_NONSTRING_ARRAY() RBIMPL_ATTR_NONSTRING()
# else
#   define RBIMPL_ATTR_NONSTRING_ARRAY() /* void */
# endif
#else
# define RBIMPL_ATTR_NONSTRING() /* void */
# define RBIMPL_ATTR_NONSTRING_ARRAY() /* void */
#endif

#endif /* RBIMPL_ATTR_NONSTRING_H */
ruby/internal/attr/error.h000064400000003142151732674210011625 0ustar00#ifndef RBIMPL_ATTR_ERROR_H                          /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_ERROR_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_ATTR_ERROR.
 */
#include "ruby/internal/has/attribute.h"

/** Wraps (or simulates) `__attribute__((error))` */
#if RBIMPL_HAS_ATTRIBUTE(error)
# define RBIMPL_ATTR_ERROR(msg) __attribute__((__error__ msg))
#else
# define RBIMPL_ATTR_ERROR(msg) /* void */
#endif

#endif /* RBIMPL_ATTR_ERROR_H */
ruby/internal/attr/cold.h000064400000003504151732674210011417 0ustar00#ifndef RBIMPL_ATTR_COLD_H                           /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_COLD_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_ATTR_COLD.
 */
#include "ruby/internal/compiler_is.h"
#include "ruby/internal/has/attribute.h"

/** Wraps (or simulates) `__attribute__((cold))` */
#if RBIMPL_COMPILER_IS(SunPro)
# /* Recent SunPro has __has_attribute, and is broken. */
# /* It reports it has attribute cold, reality isn't (warnings issued). */
# define RBIMPL_ATTR_COLD() /* void */
#elif RBIMPL_HAS_ATTRIBUTE(cold)
# define RBIMPL_ATTR_COLD() __attribute__((__cold__))
#else
# define RBIMPL_ATTR_COLD() /* void */
#endif

#endif /* RBIMPL_ATTR_COLD_H */
ruby/internal/attr/pure.h000064400000003721151732674210011452 0ustar00#ifndef RBIMPL_ATTR_PURE_H                           /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_PURE_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_ATTR_PURE.
 */
#include "ruby/internal/compiler_since.h"
#include "ruby/internal/has/attribute.h"
#include "ruby/assert.h"

/** Wraps (or simulates) `__attribute__((pure))` */
#if RBIMPL_HAS_ATTRIBUTE(pure)
# define RBIMPL_ATTR_PURE() __attribute__((__pure__))
#elif RBIMPL_COMPILER_SINCE(SunPro, 5, 10, 0)
# define RBIMPL_ATTR_PURE() _Pragma("does_not_write_global_data")
#else
# define RBIMPL_ATTR_PURE() /* void */
#endif

/** Enables #RBIMPL_ATTR_PURE if and only if. ! #RUBY_DEBUG. */
#if !RUBY_DEBUG
# define RBIMPL_ATTR_PURE_UNLESS_DEBUG() RBIMPL_ATTR_PURE()
#else
# define RBIMPL_ATTR_PURE_UNLESS_DEBUG() /* void */
#endif

#endif /* RBIMPL_ATTR_PURE_H */
ruby/internal/attr/noexcept.h000064400000010256151732674220012326 0ustar00#ifndef RBIMPL_ATTR_NOEXCEPT_H                       /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_NOEXCEPT_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_ATTR_NOEXCEPT.
 *
 * This isn't actually an attribute in C++ but who cares...
 *
 * Mainly due  to aesthetic reasons,  this one is  rarely used in  the project.
 * But can  be handy on  occasions, especially when a  function's noexcept-ness
 * depends on its calling functions.
 *
 * ### Q&A ###
 *
 * - Q: Can a function that raises Ruby exceptions be attributed `noexcept`?
 *
 * - A: Yes.   `noexcept` is  about  C++ exceptions,  not  Ruby's.  They  don't
 *      interface each other.  You can  safely attribute a function that raises
 *      Ruby exceptions as `noexcept`.
 *
 * - Q: How, then, can I assert that  a function I wrote doesn't raise any Ruby
 *      exceptions?
 *
 * - A: `__attribute__((__leaf__))` is for that purpose.  A function attributed
 *      as leaf can still throw C++  exceptions, but not Ruby's.  Note however,
 *      that it's extremely difficult -- if  not impossible -- to assert that a
 *      function  doesn't  raise any  Ruby  exceptions  at  all.  Use  of  that
 *      attribute is not  recommended; mere mortals can't properly  use that by
 *      hand.
 *
 * - Q: Does it make sense to attribute an inline function `noexcept`?
 *
 * - A: I thought so before.  But no, I don't think they are useful any longer.
 *
 *     - When an  inline function attributed `noexcept`  actually doesn't throw
 *       any  exceptions at  all:  these days  I don't  see  any difference  in
 *       generated assembly  by adding/removing this attribute.   C++ compilers
 *       get smarter and  smarter.  Today they can infer if  it actually throws
 *       or not without any annotations by humans (correct me if I'm wrong).
 *
 *     - When an inline function attributed `noexcept` actually _does_ throw an
 *       exception:  they  have to  call  `std::terminate`  then (C++  standard
 *       mandates  so).  This  means exception  handling routines  are actually
 *       enforced, not  omitted.  This doesn't impact  runtime performance (The
 *       Itanium C++ ABI has zero-cost  exception handling), but does impact on
 *       generated binary size.  This is bad.
 */
#include "ruby/internal/compiler_since.h"
#include "ruby/internal/has/feature.h"

/** Wraps (or simulates) C++11 `noexcept` */
#if ! defined(__cplusplus)
# /* Doesn't make sense. */
# define RBIMPL_ATTR_NOEXCEPT(_) /* void */

#elif RBIMPL_HAS_FEATURE(cxx_noexcept)
# define RBIMPL_ATTR_NOEXCEPT(_) noexcept(noexcept(_))

#elif defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__
# define RBIMPL_ATTR_NOEXCEPT(_) noexcept(noexcept(_))

#elif defined(__INTEL_CXX11_MODE__)
# define RBIMPL_ATTR_NOEXCEPT(_) noexcept(noexcept(_))

#elif RBIMPL_COMPILER_SINCE(MSVC, 19, 0, 0)
# define RBIMPL_ATTR_NOEXCEPT(_) noexcept(noexcept(_))

#elif __cplusplus >= 201103L
# define RBIMPL_ATTR_NOEXCEPT(_) noexcept(noexcept(_))

#else
# define RBIMPL_ATTR_NOEXCEPT(_) /* void */
#endif

#endif /* RBIMPL_ATTR_NOEXCEPT_H */
ruby/internal/attr/nodiscard.h000064400000004252151732674220012446 0ustar00#ifndef RBIMPL_ATTR_NODISCARD_H                      /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_NODISCARD_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_ATTR_NODISCARD.
 */
#include "ruby/internal/has/attribute.h"
#include "ruby/internal/has/c_attribute.h"
#include "ruby/internal/has/cpp_attribute.h"

/**
 * Wraps  (or simulates)  `[[nodiscard]]`.  In  C++  (at least  since C++20)  a
 * nodiscard attribute can  have a message why the result shall not be ignored.
 * However GCC attribute and SAL annotation cannot take them.
 */
#if RBIMPL_HAS_CPP_ATTRIBUTE(nodiscard)
# define RBIMPL_ATTR_NODISCARD() [[nodiscard]]
#elif RBIMPL_HAS_C_ATTRIBUTE(nodiscard)
# define RBIMPL_ATTR_NODISCARD() [[nodiscard]]
#elif RBIMPL_HAS_ATTRIBUTE(warn_unused_result)
# define RBIMPL_ATTR_NODISCARD() __attribute__((__warn_unused_result__))
#elif defined(_Check_return_)
# /* Take SAL definition. */
# define RBIMPL_ATTR_NODISCARD() _Check_return_
#else
# define RBIMPL_ATTR_NODISCARD() /* void */
#endif

#endif /* RBIMPL_ATTR_NODISCARD_H */
ruby/internal/attr/const.h000064400000004237151732674220011631 0ustar00#ifndef RBIMPL_ATTR_CONST_H                          /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_CONST_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_ATTR_CONST.
 */
#include "ruby/internal/compiler_since.h"
#include "ruby/internal/has/attribute.h"
#include "ruby/internal/has/declspec_attribute.h"

/** Wraps (or simulates) `__attribute__((const))` */
#if RBIMPL_HAS_ATTRIBUTE(const)
# define RBIMPL_ATTR_CONST() __attribute__((__const__))
#elif RBIMPL_HAS_DECLSPEC_ATTRIBUTE(noalias)
# /* If a function can be a const, that is also a noalias. */
# define RBIMPL_ATTR_CONST() __declspec(noalias)
#elif RBIMPL_COMPILER_SINCE(SunPro, 5, 10, 0)
# define RBIMPL_ATTR_CONST() _Pragma("no_side_effect")
#else
# define RBIMPL_ATTR_CONST() /* void */
#endif

/** Enables #RBIMPL_ATTR_CONST if and only if. ! #RUBY_DEBUG. */
#if !defined(RUBY_DEBUG) || !RUBY_DEBUG
# define RBIMPL_ATTR_CONST_UNLESS_DEBUG() RBIMPL_ATTR_CONST()
#else
# define RBIMPL_ATTR_CONST_UNLESS_DEBUG() /* void */
#endif

#endif /* RBIMPL_ATTR_CONST_H */
ruby/internal/attr/flag_enum.h000064400000003303151732674220012431 0ustar00#ifndef RBIMPL_ATTR_FLAG_ENUM_H                      /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_FLAG_ENUM_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_ATTR_FLAG_ENUM.
 * @see        https://clang.llvm.org/docs/AttributeReference.html#flag_enum
 */
#include "ruby/internal/has/attribute.h"

/** Wraps (or simulates) `__attribute__((flag_enum)` */
#if RBIMPL_HAS_ATTRIBUTE(flag_enum)
# define RBIMPL_ATTR_FLAG_ENUM() __attribute__((__flag_enum__))
#else
# define RBIMPL_ATTR_FLAG_ENUM() /* void */
#endif

#endif /* RBIMPLATTR_FLAG_ENUM_H */
ruby/internal/attr/artificial.h000064400000004635151732674220012614 0ustar00#ifndef RBIMPL_ATTR_ARTIFICIAL_H                     /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_ARTIFICIAL_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_ATTR_ARTIFICIAL.
 *
 * ### Q&A ###
 *
 * - Q: What is this attribute?  I don't get what GCC manual is talking about.
 *
 * - A: In  short  it  is  an  attribute to  manipulate  GDB  backtraces.   The
 *      attribute    makes    the   best    sense    when    it   comes    with
 *      __attribute__((always_inline)).   When a  function annotated  with this
 *      attribute gets inlined, and when you  somehow look at a backtrace which
 *      includes such  inlined call site,  then the backtrace shows  the caller
 *      and  not the  callee.  This  is handy  for instance  when an  identical
 *      function is inlined  more than once in a single  big function.  On such
 *      case it gets  vital to know where the inlining  happened in the callee.
 *      See also https://stackoverflow.com/a/21936099
 */
#include "ruby/internal/has/attribute.h"

/** Wraps (or simulates) `__attribute__((artificial))` */
#if RBIMPL_HAS_ATTRIBUTE(artificial)
# define RBIMPL_ATTR_ARTIFICIAL() __attribute__((__artificial__))
#else
# define RBIMPL_ATTR_ARTIFICIAL() /* void */
#endif

#endif /* RBIMPL_ATTR_ARTIFICIAL_H */
ruby/internal/attr/maybe_unused.h000064400000003621151732674220013157 0ustar00#ifndef RBIMPL_ATTR_MAYBE_UNUSED_H                   /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_MAYBE_UNUSED_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_ATTR_MAYBE_UNUSED.
 */
#include "ruby/internal/has/attribute.h"
#include "ruby/internal/has/c_attribute.h"
#include "ruby/internal/has/cpp_attribute.h"

/** Wraps  (or simulates)  `[[maybe_unused]]` */
#if RBIMPL_HAS_CPP_ATTRIBUTE(maybe_unused)
# define RBIMPL_ATTR_MAYBE_UNUSED() [[maybe_unused]]
#elif RBIMPL_HAS_C_ATTRIBUTE(maybe_unused)
# define RBIMPL_ATTR_MAYBE_UNUSED() [[maybe_unused]]
#elif RBIMPL_HAS_ATTRIBUTE(unused)
# define RBIMPL_ATTR_MAYBE_UNUSED() __attribute__((__unused__))
#else
# define RBIMPL_ATTR_MAYBE_UNUSED() /* void */
#endif

#endif /* RBIMPL_ATTR_MAYBE_UNUSED */
ruby/internal/attr/noreturn.h000064400000004131151732674220012350 0ustar00#ifndef RBIMPL_ATTR_NORETURN_H                       /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_NORETURN_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_ATTR_NORETURN.
 */
#include "ruby/internal/has/attribute.h"
#include "ruby/internal/has/cpp_attribute.h"
#include "ruby/internal/has/declspec_attribute.h"

/** Wraps (or simulates) `[[noreturn]]` */
#if RBIMPL_HAS_DECLSPEC_ATTRIBUTE(noreturn)
# define RBIMPL_ATTR_NORETURN() __declspec(noreturn)

#elif RBIMPL_HAS_ATTRIBUTE(noreturn)
# define RBIMPL_ATTR_NORETURN() __attribute__((__noreturn__))

#elif RBIMPL_HAS_CPP_ATTRIBUTE(noreturn)
# define RBIMPL_ATTR_NORETURN() [[noreturn]]

#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112)
# define RBIMPL_ATTR_NORETURN() _Noreturn

#elif defined(_Noreturn)
# /* glibc <sys/cdefs.h> has this macro. */
# define RBIMPL_ATTR_NORETURN() _Noreturn

#else
# define RBIMPL_ATTR_NORETURN() /* void */
#endif

#endif /* RBIMPL_ATTR_NORETURN_H */
ruby/internal/attr/returns_nonnull.h000064400000003431151732674220013745 0ustar00#ifndef RBIMPL_ATTR_RETURNS_NONNULL_H                /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_RETURNS_NONNULL_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_ATTR_RETURNS_NONNULL.
 */
#include "ruby/internal/has/attribute.h"

/** Wraps (or simulates) `__attribute__((returns_nonnull))` */
#if defined(_Ret_nonnull_)
# /* Take SAL definition. */
# define RBIMPL_ATTR_RETURNS_NONNULL() _Ret_nonnull_

#elif RBIMPL_HAS_ATTRIBUTE(returns_nonnull)
# define RBIMPL_ATTR_RETURNS_NONNULL() __attribute__((__returns_nonnull__))

#else
# define RBIMPL_ATTR_RETURNS_NONNULL() /* void */
#endif

#endif /* RBIMPL_ATTR_RETURNS_NONNULL_H */
ruby/internal/attr/noinline.h000064400000003400151732674220012305 0ustar00#ifndef RBIMPL_ATTR_NOINLINE_H                       /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_NOINLINE_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_ATTR_NOINLINE.
 */
#include "ruby/internal/has/attribute.h"
#include "ruby/internal/has/declspec_attribute.h"

/** Wraps (or simulates) `__declspec(noinline)` */
#if RBIMPL_HAS_DECLSPEC_ATTRIBUTE(noinline)
# define RBIMPL_ATTR_NOINLINE() __declspec(noinline)
#elif RBIMPL_HAS_ATTRIBUTE(noinline)
# define RBIMPL_ATTR_NOINLINE() __attribute__((__noinline__))
#else
# define RBIMPL_ATTR_NOINLINE() /* void */
#endif

#endif /* RBIMPL_ATTR_NOINLINE_H */
ruby/internal/attr/restrict.h000064400000004114151732674220012334 0ustar00#ifndef RBIMPL_ATTR_RESTRICT_H                       /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ATTR_RESTRICT_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_ATTR_RESTRICT.
 */
#include "ruby/internal/compiler_since.h"
#include "ruby/internal/has/attribute.h"

/* :FIXME:  config.h  includes conflicting  `#define  restrict`.   MSVC can  be
 * detected  using `RBIMPL_COMPILER_SINCE()`,  but  Clang &  family cannot  use
 * `__has_declspec_attribute()` which involves macro substitution. */

/** Wraps (or simulates) `__declspec(restrict)` */
#if RBIMPL_COMPILER_SINCE(MSVC, 14, 0, 0)
# define RBIMPL_ATTR_RESTRICT() __declspec(re ## strict)

#elif RBIMPL_HAS_ATTRIBUTE(malloc)
# define RBIMPL_ATTR_RESTRICT() __attribute__((__malloc__))

#elif RBIMPL_COMPILER_SINCE(SunPro, 5, 10, 0)
# define RBIMPL_ATTR_RESTRICT() _Pragma("returns_new_memory")

#else
# define RBIMPL_ATTR_RESTRICT() /* void */
#endif

#endif /* RBIMPL_ATTR_RESTRICT_H */
ruby/internal/dosish.h000064400000006250151732674220011017 0ustar00#ifndef RBIMPL_DOSISH_H                              /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_DOSISH_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Support for so-called dosish systems.
 */
#ifdef __CYGWIN__
#undef _WIN32
#endif

#if defined(_WIN32)
/*
  DOSISH mean MS-Windows style filesystem.
  But you should use more precise macros like DOSISH_DRIVE_LETTER, PATH_SEP,
  ENV_IGNORECASE or CASEFOLD_FILESYSTEM.
 */
#define DOSISH 1
# define DOSISH_DRIVE_LETTER
#endif

#ifdef _WIN32
#include "ruby/win32.h"
#endif

/** The delimiter of `PATH` environment variable. */
#if defined(DOSISH)
#define PATH_SEP ";"
#else
#define PATH_SEP ":"
#endif

/** Identical to #PATH_SEP, except it is of type `char`. */
#define PATH_SEP_CHAR PATH_SEP[0]

/**
 * @private
 *
 * @deprecated  This macro once was a thing in the old days, but makes no sense
 *              any  longer today.   Exists  here  for backwards  compatibility
 *              only.  You can safely forget about it.
 *
 * @internal
 *
 * For  historical interests:  there was  an operating  system called  Human68k
 * which used an environment variable called `"path"` for this purpose.
 */
#define PATH_ENV "PATH"

#if defined(DOSISH)
#define ENV_IGNORECASE
#endif

/**
 * Stone age  assumption was that  an operating  system supports only  one file
 * system at a  moment.  This macro was  to detect if such (one  and only) file
 * system  has case  sensitivity.   This  assumption is  largely  not true  any
 * longer; most operating systems can mount  many kinds of file systems side by
 * side.  Also there are file systems that  do or do not ignore cases depending
 * on configuration (e.g.  EXT4's `casefold` feature).
 *
 * This  macro is  still  used  internally (for  instance  Ruby level  constant
 * `File::FNM_SYSCASE` depends on it), but it is basically a wrong idea for you
 * to use it today.  Please just find another way.
 */
#ifndef CASEFOLD_FILESYSTEM
# if defined DOSISH
#   define CASEFOLD_FILESYSTEM 1
# else
#   define CASEFOLD_FILESYSTEM 0
# endif
#endif

#endif /* RBIMPL_DOSISH_H */
ruby/internal/arithmetic/uid_t.h000064400000003536151732674220012767 0ustar00#ifndef RBIMPL_ARITHMETIC_UID_T_H                    /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ARITHMETIC_UID_T_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Arithmetic conversion between C's `uid_t` and Ruby's.
 */
#include "ruby/internal/config.h"
#include "ruby/internal/arithmetic/long.h"

/** Converts a C's `uid_t` into an instance of ::rb_cInteger. */
#ifndef UIDT2NUM
# define UIDT2NUM RB_LONG2NUM
#endif

/** Converts an instance of ::rb_cNumeric into C's `uid_t`. */
#ifndef NUM2UIDT
# define NUM2UIDT RB_NUM2LONG
#endif

/** A rb_sprintf() format prefix to be used for a `uid_t` parameter. */
#ifndef PRI_UIDT_PREFIX
# define PRI_UIDT_PREFIX PRI_LONG_PREFIX
#endif

#endif /* RBIMPL_ARITHMETIC_UID_T_H */
ruby/internal/arithmetic/off_t.h000064400000004704151732674220012756 0ustar00#ifndef RBIMPL_ARITHMETIC_OFF_T_H                    /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ARITHMETIC_OFF_T_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Arithmetic conversion between C's `off_t` and Ruby's.
 */
#include "ruby/internal/config.h"
#include "ruby/internal/arithmetic/int.h"
#include "ruby/internal/arithmetic/long.h"
#include "ruby/internal/arithmetic/long_long.h"
#include "ruby/backward/2/long_long.h"

/** Converts a C's `off_t` into an instance of ::rb_cInteger. */
#ifdef OFFT2NUM
# /* take that. */
#elif SIZEOF_OFF_T == SIZEOF_LONG_LONG
# define OFFT2NUM RB_LL2NUM
#elif SIZEOF_OFF_T == SIZEOF_LONG
# define OFFT2NUM RB_LONG2NUM
#else
# define OFFT2NUM RB_INT2NUM
#endif

/** Converts an instance of ::rb_cNumeric into C's `off_t`. */
#ifdef NUM2OFFT
# /* take that. */
#elif SIZEOF_OFF_T == SIZEOF_LONG_LONG
# define NUM2OFFT RB_NUM2LL
#elif SIZEOF_OFF_T == SIZEOF_LONG
# define NUM2OFFT RB_NUM2LONG
#else
# define NUM2OFFT RB_NUM2INT
#endif

/** A rb_sprintf() format prefix to be used for an `off_t` parameter. */
#ifdef PRI_OFFT_PREFIX
# /* take that. */
#elif SIZEOF_OFF_T == SIZEOF_LONG_LONG
# define PRI_OFFT_PREFIX PRI_LL_PREFIX
#elif SIZEOF_OFF_T == SIZEOF_LONG
# define PRI_OFFT_PREFIX PRI_LONG_PREFIX
#else
# define PRI_OFFT_PREFIX PRI_INT_PREFIX
#endif

#endif /* RBIMPL_ARITHMETIC_OFF_T_H */
ruby/internal/arithmetic/st_data_t.h000064400000005741151732674220013625 0ustar00#ifndef RBIMPL_ARITHMERIC_ST_DATA_T_H                /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ARITHMERIC_ST_DATA_T_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Arithmetic conversion between C's `st_data_t` and Ruby's.
 */
#include "ruby/internal/arithmetic/fixnum.h"
#include "ruby/internal/arithmetic/long.h"
#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/attr/const.h"
#include "ruby/internal/attr/constexpr.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/value.h"
#include "ruby/assert.h"
#include "ruby/st.h"

#define ST2FIX    RB_ST2FIX     /**< @old{RB_ST2FIX} */
/** @cond INTERNAL_MACRO */
#define RB_ST2FIX RB_ST2FIX
/** @endcond */

RBIMPL_ATTR_CONST_UNLESS_DEBUG()
RBIMPL_ATTR_CONSTEXPR_UNLESS_DEBUG(CXX14)
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Converts a C's `st_data_t` into an instance of ::rb_cInteger.
 *
 * @param[in]  i  The data in question.
 * @return     A converted result
 * @warning    THIS CONVERSION LOSES DATA!  Be warned.
 * @see        https://bugs.ruby-lang.org/issues/13877
 * @see        https://bugs.ruby-lang.org/issues/14218
 *
 * @internal
 *
 * This  is   needed  because  of   hash  functions.   Hash   functions  return
 * `st_data_t`,  which could  theoretically  be bigger  than Fixnums.   However
 * allocating Bignums for them every time  we calculate hash values is just too
 * heavy.  To avoid  penalty we need to  ignore some upper bit(s)  and stick to
 * Fixnums.  This function is used for that purpose.
 */
static inline VALUE
RB_ST2FIX(st_data_t i)
{
    SIGNED_VALUE x = RBIMPL_CAST((SIGNED_VALUE)i);

    if (x >= 0) {
        x &= RUBY_FIXNUM_MAX;
    }
    else {
        x |= RUBY_FIXNUM_MIN;
    }

    RBIMPL_ASSERT_OR_ASSUME(RB_FIXABLE(x));
    unsigned long y = RBIMPL_CAST((unsigned long)x);
    return RB_LONG2FIX(RBIMPL_CAST((long)y));
}

#endif /* RBIMPL_ARITHMETIC_ST_DATA_T_H */
ruby/internal/arithmetic/fixnum.h000064400000005573151732674220013174 0ustar00#ifndef RBIMPL_ARITHMETIC_FIXNUM_H                   /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ARITHMETIC_FIXNUM_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Handling of integers formerly known as Fixnums.
 */
#include "ruby/backward/2/limits.h"

#define FIXABLE    RB_FIXABLE      /**< @old{RB_FIXABLE} */
#define FIXNUM_MAX RUBY_FIXNUM_MAX /**< @old{RUBY_FIXNUM_MAX} */
#define FIXNUM_MIN RUBY_FIXNUM_MIN /**< @old{RUBY_FIXNUM_MIN} */
#define NEGFIXABLE RB_NEGFIXABLE   /**< @old{RB_NEGFIXABLE} */
#define POSFIXABLE RB_POSFIXABLE   /**< @old{RB_POSFIXABLE} */

/**
 * Checks if the passed value is in  range of fixnum, assuming it is a positive
 * number.  Can sometimes be useful for C's unsigned integer types.
 *
 * @internal
 *
 * FIXABLE can be applied to anything, from double to intmax_t.  The problem is
 * double.   On a  64bit system  RUBY_FIXNUM_MAX is  4,611,686,018,427,387,903,
 * which is not representable by a double.  The nearest value that a double can
 * represent  is   4,611,686,018,427,387,904,  which   is  not   fixable.   The
 * seemingly-strange "< FIXNUM_MAX + 1" expression below is due to this.
 */
#define RB_POSFIXABLE(_) ((_) <  RUBY_FIXNUM_MAX + 1)

/**
 * Checks if the passed value is in  range of fixnum, assuming it is a negative
 * number.  This is an implementation of #RB_FIXABLE.  Rarely used stand alone.
 */
#define RB_NEGFIXABLE(_) ((_) >= RUBY_FIXNUM_MIN)

/** Checks if the passed value is in  range of fixnum */
#define RB_FIXABLE(_)    (RB_POSFIXABLE(_) && RB_NEGFIXABLE(_))

/** Maximum possible value that a fixnum can represent. */
#define RUBY_FIXNUM_MAX  (LONG_MAX / 2)

/** Minimum possible value that a fixnum can represent. */
#define RUBY_FIXNUM_MIN  (LONG_MIN / 2)

#endif /* RBIMPL_ARITHMETIC_FIXNUM_H */
ruby/internal/arithmetic/size_t.h000064400000005524151732674220013157 0ustar00#ifndef RBIMPL_ARITHMETIC_SIZE_T_H                   /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ARITHMETIC_SIZE_T_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Arithmetic conversion between C's `size_t` and Ruby's.
 */
#include "ruby/internal/config.h"
#include "ruby/internal/arithmetic/int.h"
#include "ruby/internal/arithmetic/long.h"
#include "ruby/internal/arithmetic/long_long.h"
#include "ruby/backward/2/long_long.h"

#if defined(__DOXYGEN__)
# /** Converts a C's `size_t` into an instance of ::rb_cInteger. */
# define RB_SIZE2NUM RB_ULONG2NUM
# /** Converts a C's `ssize_t` into an instance of ::rb_cInteger. */
# define RB_SSIZE2NUM RB_LONG2NUM
#elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG
# define RB_SIZE2NUM RB_ULL2NUM
# define RB_SSIZE2NUM RB_LL2NUM
#elif SIZEOF_SIZE_T == SIZEOF_LONG
# define RB_SIZE2NUM RB_ULONG2NUM
# define RB_SSIZE2NUM RB_LONG2NUM
#else
# define RB_SIZE2NUM RB_UINT2NUM
# define RB_SSIZE2NUM RB_INT2NUM
#endif

#if defined(__DOXYGEN__)
# /** Converts an instance of ::rb_cInteger into C's `size_t`. */
# define RB_NUM2SIZE RB_NUM2ULONG
# /** Converts an instance of ::rb_cInteger into C's `ssize_t`. */
# define RB_NUM2SSIZE RB_NUM2LONG
#elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG
# define RB_NUM2SIZE RB_NUM2ULL
# define RB_NUM2SSIZE RB_NUM2LL
#elif SIZEOF_SIZE_T == SIZEOF_LONG
# define RB_NUM2SIZE RB_NUM2ULONG
# define RB_NUM2SSIZE RB_NUM2LONG
#else
# define RB_NUM2SIZE RB_NUM2UINT
# define RB_NUM2SSIZE RB_NUM2INT
#endif

#define NUM2SIZET RB_NUM2SIZE   /**< @old{RB_NUM2SIZE} */
#define SIZET2NUM RB_SIZE2NUM   /**< @old{RB_SIZE2NUM} */
#define NUM2SSIZET RB_NUM2SSIZE /**< @old{RB_NUM2SSIZE} */
#define SSIZET2NUM RB_SSIZE2NUM /**< @old{RB_SSIZE2NUM} */

#endif /* RBIMPL_ARITHMETIC_SIZE_T_H */
ruby/internal/arithmetic/gid_t.h000064400000003536151732674220012751 0ustar00#ifndef RBIMPL_ARITHMETIC_GID_T_H                    /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ARITHMETIC_GID_T_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Arithmetic conversion between C's `gid_t` and Ruby's.
 */
#include "ruby/internal/config.h"
#include "ruby/internal/arithmetic/long.h"

/** Converts a C's `gid_t` into an instance of ::rb_cInteger. */
#ifndef GIDT2NUM
# define GIDT2NUM RB_LONG2NUM
#endif

/** Converts an instance of ::rb_cNumeric into C's `gid_t`. */
#ifndef NUM2GIDT
# define NUM2GIDT RB_NUM2LONG
#endif

/** A rb_sprintf() format prefix to be used for a `gid_t` parameter. */
#ifndef PRI_GIDT_PREFIX
# define PRI_GIDT_PREFIX PRI_LONG_PREFIX
#endif

#endif /* RBIMPL_ARITHMETIC_GID_T_H */
ruby/internal/arithmetic/double.h000064400000005366151732674220013140 0ustar00#ifndef RBIMPL_ARITHMETIC_DOUBLE_H                   /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ARITHMETIC_DOUBLE_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Arithmetic conversion between C's `double` and Ruby's.
 */
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"

#define NUM2DBL      rb_num2dbl       /**< @old{rb_num2dbl} */
#define RFLOAT_VALUE rb_float_value   /**< @old{rb_float_value} */
#define DBL2NUM      rb_float_new     /**< @old{rb_float_new} */

RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
 * Converts an instance of ::rb_cNumeric into C's `double`.
 *
 * @param[in]  num             Something numeric.
 * @exception  rb_eTypeError   `num` is not a numeric.
 * @return     The passed value converted into C's `double`.
 */
double rb_num2dbl(VALUE num);

RBIMPL_ATTR_PURE()
/**
 * Extracts its double value from an instance of ::rb_cFloat.
 *
 * @param[in]  num  An instance of ::rb_cFloat.
 * @pre        Must not pass anything other than a Fixnum.
 * @return     The passed value converted into C's `double`.
 */
double rb_float_value(VALUE num);

/**
 * Converts a C's `double` into an instance of ::rb_cFloat.
 *
 * @param[in]  d  Arbitrary `double` value.
 * @return     An instance of ::rb_cFloat.
 */
VALUE rb_float_new(double d);

/**
 * Identical to rb_float_new(), except it does not generate Flonums.
 *
 * @param[in]  d  Arbitrary `double` value.
 * @return     An instance of ::rb_cFloat.
 *
 * @internal
 *
 * @shyouhei has no idea why it is here.
 */
VALUE rb_float_new_in_heap(double d);
RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_ARITHMETIC_DOUBLE_H */
ruby/internal/arithmetic/short.h000064400000010523151732674220013014 0ustar00#ifndef RBIMPL_ARITHMETIC_SHORT_H                    /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ARITHMETIC_SHORT_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Arithmetic conversion between C's `short` and Ruby's.
 *
 * Shyouhei  wonders:  why  there  is   no  SHORT2NUM,  given  there  are  both
 * #USHORT2NUM and #CHR2FIX?
 */
#include "ruby/internal/value.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/special_consts.h"

#define RB_NUM2SHORT  rb_num2short_inline /**< @alias{rb_num2short_inline} */
#define RB_NUM2USHORT rb_num2ushort       /**< @alias{rb_num2ushort} */
#define NUM2SHORT     RB_NUM2SHORT        /**< @old{RB_NUM2SHORT} */
#define NUM2USHORT    RB_NUM2USHORT       /**< @old{RB_NUM2USHORT} */
#define USHORT2NUM    RB_INT2FIX          /**< @old{RB_INT2FIX} */
#define RB_FIX2SHORT  rb_fix2short        /**< @alias{rb_fix2ushort} */
#define FIX2SHORT     RB_FIX2SHORT        /**< @old{RB_FIX2SHORT} */

RBIMPL_SYMBOL_EXPORT_BEGIN()

/**
 * Converts an instance of ::rb_cNumeric into C's `short`.
 *
 * @param[in]  num             Something numeric.
 * @exception  rb_eTypeError   `num` is not a numeric.
 * @exception  rb_eRangeError  `num` is out of range of `short`.
 * @return     The passed value converted into C's `short`.
 */
short rb_num2short(VALUE num);

/**
 * Converts an instance of ::rb_cNumeric into C's `unsigned short`.
 *
 * @param[in]  num             Something numeric.
 * @exception  rb_eTypeError   `num` is not a numeric.
 * @exception  rb_eRangeError  `num` is out of range of `unsigned short`.
 * @return     The passed value converted into C's `unsigned short`.
 */
unsigned short rb_num2ushort(VALUE num);

/**
 * Identical to rb_num2short().
 *
 * @param[in]  num             Something numeric.
 * @exception  rb_eTypeError   `num` is not a numeric.
 * @exception  rb_eRangeError  `num` is out of range of `short`.
 * @return     The passed value converted into C's `short`.
 *
 * @internal
 *
 * This function seems to be a complete  waste of disk space.  @shyouhei has no
 * idea why this is a different thing from rb_num2short().
 */
short rb_fix2short(VALUE num);

/**
 * Identical to rb_num2ushort().
 *
 * @param[in]  num             Something numeric.
 * @exception  rb_eTypeError   `num` is not a numeric.
 * @exception  rb_eRangeError  `num` is out of range of `unsigned short`.
 * @return     The passed value converted into C's `unsigned short`.
 *
 * @internal
 *
 * This function seems to be a complete  waste of disk space.  @shyouhei has no
 * idea why this is a different thing from rb_num2ushort().
 */
unsigned short rb_fix2ushort(VALUE num);
RBIMPL_SYMBOL_EXPORT_END()

/**
 * Identical to rb_num2short().
 *
 * @param[in]  x               Something numeric.
 * @exception  rb_eTypeError   `x` is not a numeric.
 * @exception  rb_eRangeError  `x` is out of range of `short`.
 * @return     The passed value converted into C's `short`.
 *
 * @internal
 *
 * This function seems to  be a complete waste of time.   @shyouhei has no idea
 * why this is a different thing from rb_num2short().
 */
static inline short
rb_num2short_inline(VALUE x)
{
    if (RB_FIXNUM_P(x))
        return rb_fix2short(x);
    else
        return rb_num2short(x);
}

#endif /* RBIMPL_ARITHMETIC_SHORT_H */
ruby/internal/arithmetic/long_long.h000064400000011524151732674220013635 0ustar00#ifndef RBIMPL_ARITHMETIC_LONG_LONG_H                /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ARITHMETIC_LONG_LONG_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Arithmetic conversion between C's `long long` and Ruby's.
 */
#include "ruby/internal/value.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/special_consts.h"
#include "ruby/backward/2/long_long.h"

#define RB_LL2NUM  rb_ll2num_inline   /**< @alias{rb_ll2num_inline} */
#define RB_ULL2NUM rb_ull2num_inline  /**< @alias{rb_ull2num_inline} */
#define LL2NUM     RB_LL2NUM          /**< @old{RB_LL2NUM} */
#define ULL2NUM    RB_ULL2NUM         /**< @old{RB_ULL2NUM} */
#define RB_NUM2LL  rb_num2ll_inline   /**< @alias{rb_num2ll_inline} */
#define RB_NUM2ULL rb_num2ull_inline  /**< @alias{rb_num2ull_inline} */
#define NUM2LL     RB_NUM2LL          /**< @old{RB_NUM2LL} */
#define NUM2ULL    RB_NUM2ULL         /**< @old{RB_NUM2ULL} */

RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
 * Converts a C's `long long` into an instance of ::rb_cInteger.
 *
 * @param[in]  num  Arbitrary `long long` value.
 * @return     An instance of ::rb_cInteger.
 */
VALUE rb_ll2inum(LONG_LONG num);

/**
 * Converts a C's `unsigned long long` into an instance of ::rb_cInteger.
 *
 * @param[in]  num  Arbitrary `unsigned long long` value.
 * @return     An instance of ::rb_cInteger.
 */
VALUE rb_ull2inum(unsigned LONG_LONG num);

/**
 * Converts an instance of ::rb_cNumeric into C's `long long`.
 *
 * @param[in]  num             Something numeric.
 * @exception  rb_eTypeError   `num` is not a numeric.
 * @exception  rb_eRangeError  `num` is out of range of `long long`.
 * @return     The passed value converted into C's `long long`.
 */
LONG_LONG rb_num2ll(VALUE num);

/**
 * Converts an instance of ::rb_cNumeric into C's `unsigned long long`.
 *
 * @param[in]  num             Something numeric.
 * @exception  rb_eTypeError   `num` is not a numeric.
 * @exception  rb_eRangeError  `num` is out of range of `unsigned long long`.
 * @return     The passed value converted into C's `unsigned long long`.
 */
unsigned LONG_LONG rb_num2ull(VALUE num);
RBIMPL_SYMBOL_EXPORT_END()

/**
 * Converts a C's `long long` into an instance of ::rb_cInteger.
 *
 * @param[in]  n  Arbitrary `long long` value.
 * @return     An instance of ::rb_cInteger
 */
static inline VALUE
rb_ll2num_inline(LONG_LONG n)
{
    if (FIXABLE(n)) return LONG2FIX((long)n);
    return rb_ll2inum(n);
}

/**
 * Converts a C's `unsigned long long` into an instance of ::rb_cInteger.
 *
 * @param[in]  n  Arbitrary `unsigned long long` value.
 * @return     An instance of ::rb_cInteger
 */
static inline VALUE
rb_ull2num_inline(unsigned LONG_LONG n)
{
    if (POSFIXABLE(n)) return LONG2FIX((long)n);
    return rb_ull2inum(n);
}

/**
 * Converts an instance of ::rb_cNumeric into C's `long long`.
 *
 * @param[in]  x               Something numeric.
 * @exception  rb_eTypeError   `x` is not a numeric.
 * @exception  rb_eRangeError  `x` is out of range of `long long`.
 * @return     The passed value converted into C's `long long`.
 */
static inline LONG_LONG
rb_num2ll_inline(VALUE x)
{
    if (RB_FIXNUM_P(x))
        return RB_FIX2LONG(x);
    else
        return rb_num2ll(x);
}

/**
 * Converts an instance of ::rb_cNumeric into C's `unsigned long long`.
 *
 * @param[in]  x               Something numeric.
 * @exception  rb_eTypeError   `x` is not a numeric.
 * @exception  rb_eRangeError  `x` is out of range of `unsigned long long`.
 * @return     The passed value converted into C's `unsigned long long`.
 */
static inline unsigned LONG_LONG
rb_num2ull_inline(VALUE x)
{
    if (RB_FIXNUM_P(x))
        return RBIMPL_CAST((unsigned LONG_LONG)RB_FIX2LONG(x));
    else
        return rb_num2ull(x);
}

#endif /* RBIMPL_ARITHMETIC_LONG_LONG_H */
ruby/internal/arithmetic/intptr_t.h000064400000005421151732674220013521 0ustar00#ifndef RBIMPL_ARITHMETIC_INTPTR_T_H                 /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ARITHMETIC_INTPTR_T_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Arithmetic conversion between C's `intptr_t` and Ruby's.
 */
#include "ruby/internal/config.h"

#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif

#include "ruby/internal/value.h"
#include "ruby/internal/dllexport.h"

#define rb_int_new  rb_int2inum  /**< @alias{rb_int2inum} */
#define rb_uint_new rb_uint2inum /**< @alias{rb_uint2inum} */

RBIMPL_SYMBOL_EXPORT_BEGIN()

/**
 * Converts a C's `intptr_t` into an instance of ::rb_cInteger.
 *
 * @param[in]  i  Arbitrary `intptr_t` value.
 * @return     An instance of ::rb_cInteger.
 * @note       This function always allocates Bignums, even if the given number
 *             is small enough to fit into a Fixnum.
 */
VALUE rb_int2big(intptr_t i);

/**
 * Converts a C's `intptr_t` into an instance of ::rb_cInteger.
 *
 * @param[in]  i  Arbitrary `intptr_t` value.
 * @return     An instance of ::rb_cInteger.
 */
VALUE rb_int2inum(intptr_t i);

/**
 * Converts a C's `intptr_t` into an instance of ::rb_cInteger.
 *
 * @param[in]  i  Arbitrary `intptr_t` value.
 * @return     An instance of ::rb_cInteger.
 * @note       This function always allocates Bignums, even if the given number
 *             is small enough to fit into a Fixnum.
 */
VALUE rb_uint2big(uintptr_t i);

/**
 * Converts a C's `uintptr_t` into an instance of ::rb_cInteger.
 *
 * @param[in]  i  Arbitrary `uintptr_t` value.
 * @return     An instance of ::rb_cInteger.
 */
VALUE rb_uint2inum(uintptr_t i);
RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_ARITHMETIC_INTPTR_T_H */
ruby/internal/arithmetic/int.h000064400000020105151732674220012444 0ustar00#ifndef RBIMPL_ARITHMETIC_INT_H                      /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ARITHMETIC_INT_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Arithmetic conversion between C's `int` and Ruby's.
 */
#include "ruby/internal/config.h"
#include "ruby/internal/arithmetic/fixnum.h"
#include "ruby/internal/arithmetic/intptr_t.h"
#include "ruby/internal/arithmetic/long.h"
#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/attr/const.h"
#include "ruby/internal/attr/constexpr.h"
#include "ruby/internal/compiler_is.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/special_consts.h"
#include "ruby/internal/value.h"
#include "ruby/internal/warning_push.h"
#include "ruby/assert.h"

#define RB_INT2NUM  rb_int2num_inline  /**< @alias{rb_int2num_inline} */
#define RB_NUM2INT  rb_num2int_inline  /**< @alias{rb_num2int_inline} */
#define RB_UINT2NUM rb_uint2num_inline /**< @alias{rb_uint2num_inline} */

#define FIX2INT    RB_FIX2INT          /**< @old{RB_FIX2INT} */
#define FIX2UINT   RB_FIX2UINT         /**< @old{RB_FIX2UINT} */
#define INT2NUM    RB_INT2NUM          /**< @old{RB_INT2NUM} */
#define NUM2INT    RB_NUM2INT          /**< @old{RB_NUM2INT} */
#define NUM2UINT   RB_NUM2UINT         /**< @old{RB_NUM2UINT} */
#define UINT2NUM   RB_UINT2NUM         /**< @old{RB_UINT2NUM} */

/** @cond INTERNAL_MACRO */
#define RB_FIX2INT  RB_FIX2INT
#define RB_NUM2UINT RB_NUM2UINT
#define RB_FIX2UINT RB_FIX2UINT
/** @endcond */

RBIMPL_SYMBOL_EXPORT_BEGIN()

/**
 * Converts an instance of ::rb_cNumeric into C's `long`.
 *
 * @param[in]  num             Something numeric.
 * @exception  rb_eTypeError   `num` is not a numeric.
 * @exception  rb_eRangeError  `num` is out of range of `int`.
 * @return     The passed value converted into C's `long`.
 *
 * @internal
 *
 * Yes, the  API is  really strange.   It returns `long`,  but raises  when the
 * value is out of `int`.  This seems to  be due to the fact that Matz favoured
 * K&R before, and his machine at that moment was an ILP32 architecture.
 */
long rb_num2int(VALUE num);

/**
 * Identical to rb_num2int().
 *
 * @param[in]  num             Something numeric.
 * @exception  rb_eTypeError   `num` is not a numeric.
 * @exception  rb_eRangeError  `num` is out of range of `int`.
 * @return     The passed value converted into C's `long`.
 *
 * @internal
 *
 * This function seems to be a complete  waste of disk space.  @shyouhei has no
 * idea why this is a different thing from rb_num2short().
 */
long rb_fix2int(VALUE num);

/**
 * Converts an instance of ::rb_cNumeric into C's `unsigned long`.
 *
 * @param[in]  num             Something numeric.
 * @exception  rb_eTypeError   `num` is not a numeric.
 * @exception  rb_eRangeError  `num` is out of range of `unsigned int`.
 * @return     The passed value converted into C's `unsigned long`.
 *
 * @internal
 *
 * Yes, the API is really strange.  It returns `unsigned long`, but raises when
 * the value is out  of `unsigned int`.  This seems to be due  to the fact that
 * Matz  favoured K&R  before, and  his  machine at  that moment  was an  ILP32
 * architecture.
 */
unsigned long rb_num2uint(VALUE num);

/**
 * Identical to rb_num2uint().
 *
 * @param[in]  num             Something numeric.
 * @exception  rb_eTypeError   `num` is not a numeric.
 * @exception  rb_eRangeError  `num` is out of range of `unsigned int`.
 * @return     The passed value converted into C's `unsigned long`.
 *
 * @internal
 *
 * This function seems to be a complete  waste of disk space.  @shyouhei has no
 * idea why this is a different thing from rb_num2short().
 */
unsigned long rb_fix2uint(VALUE num);
RBIMPL_SYMBOL_EXPORT_END()

RBIMPL_ATTR_ARTIFICIAL()
/**
 * Converts a Fixnum into C's `int`.
 *
 * @param[in]  x  Some Fixnum.
 * @pre        Must not pass anything other than a Fixnum.
 * @return     The passed value converted into C's `int`.
 */
static inline int
RB_FIX2INT(VALUE x)
{
    /* "FIX2INT raises a  TypeError if passed nil", says rubyspec.  Not sure if
     * that is a desired behaviour but just preserve backwards compatilibily.
     */
#if 0
    RBIMPL_ASSERT_OR_ASSUME(RB_FIXNUM_P(x));
#endif
    long ret;

    if /* constexpr */ (sizeof(int) < sizeof(long)) {
        ret = rb_fix2int(x);
    }
    else {
        ret = RB_FIX2LONG(x);
    }

    return RBIMPL_CAST((int)ret);
}

/**
 * Converts an instance of ::rb_cNumeric into C's `int`.
 *
 * @param[in]  x               Something numeric.
 * @exception  rb_eTypeError   `x` is not a numeric.
 * @exception  rb_eRangeError  `x` is out of range of `int`.
 * @return     The passed value converted into C's `int`.
 */
static inline int
rb_num2int_inline(VALUE x)
{
    long ret;

    if /* constexpr */ (sizeof(int) == sizeof(long)) {
        ret = RB_NUM2LONG(x);
    }
    else if (RB_FIXNUM_P(x)) {
        ret = rb_fix2int(x);
    }
    else {
        ret = rb_num2int(x);
    }

    return RBIMPL_CAST((int)ret);
}

/**
 * Converts an instance of ::rb_cNumeric into C's `unsigned int`.
 *
 * @param[in]  x               Something numeric.
 * @exception  rb_eTypeError   `x` is not a numeric.
 * @exception  rb_eRangeError  `x` is out of range of `unsigned int`.
 * @return     The passed value converted into C's `unsigned int`.
 */
RBIMPL_ATTR_ARTIFICIAL()
static inline unsigned int
RB_NUM2UINT(VALUE x)
{
    unsigned long ret;

    if /* constexpr */ (sizeof(int) < sizeof(long)) {
        ret = rb_num2uint(x);
    }
    else {
        ret = RB_NUM2ULONG(x);
    }

    return RBIMPL_CAST((unsigned int)ret);
}

RBIMPL_ATTR_ARTIFICIAL()
/**
 * Converts a Fixnum into C's `int`.
 *
 * @param[in]  x  Some Fixnum.
 * @pre        Must not pass anything other than a Fixnum.
 * @return     The passed value converted into C's `int`.
 */
static inline unsigned int
RB_FIX2UINT(VALUE x)
{
#if 0 /* Ditto for RB_FIX2INT. */
    RBIMPL_ASSERT_OR_ASSUME(RB_FIXNUM_P(x));
#endif
    unsigned long ret;

    if /* constexpr */ (sizeof(int) < sizeof(long)) {
        ret = rb_fix2uint(x);
    }
    else {
        ret = RB_FIX2ULONG(x);
    }

    return RBIMPL_CAST((unsigned int)ret);
}

RBIMPL_WARNING_PUSH()
#if RBIMPL_COMPILER_IS(GCC)
RBIMPL_WARNING_IGNORED(-Wtype-limits) /* We can ignore them here. */
#elif RBIMPL_HAS_WARNING("-Wtautological-constant-out-of-range-compare")
RBIMPL_WARNING_IGNORED(-Wtautological-constant-out-of-range-compare)
#endif

/**
 * Converts a C's `int` into an instance of ::rb_cInteger.
 *
 * @param[in]  v  Arbitrary `int` value.
 * @return     An instance of ::rb_cInteger.
 */
static inline VALUE
rb_int2num_inline(int v)
{
    if (RB_FIXABLE(v))
        return RB_INT2FIX(v);
    else
        return rb_int2big(v);
}

/**
 * Converts a C's `unsigned int` into an instance of ::rb_cInteger.
 *
 * @param[in]  v  Arbitrary `unsigned int` value.
 * @return     An instance of ::rb_cInteger.
 */
static inline VALUE
rb_uint2num_inline(unsigned int v)
{
    if (RB_POSFIXABLE(v))
        return RB_LONG2FIX(RBIMPL_CAST((long)v));
    else
        return rb_uint2big(v);
}

RBIMPL_WARNING_POP()

#endif /* RBIMPL_ARITHMETIC_INT_H */
ruby/internal/arithmetic/mode_t.h000064400000003546151732674220013133 0ustar00#ifndef RBIMPL_ARITHMETIC_MODE_T_H                   /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ARITHMETIC_MODE_T_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Arithmetic conversion between C's `mode_t` and Ruby's.
 */
#include "ruby/internal/config.h"
#include "ruby/internal/arithmetic/int.h"

/** Converts a C's `mode_t` into an instance of ::rb_cInteger. */
#ifndef NUM2MODET
# define NUM2MODET RB_NUM2INT
#endif

/** Converts an instance of ::rb_cNumeric into C's `mode_t`. */
#ifndef MODET2NUM
# define MODET2NUM RB_INT2NUM
#endif

/** A rb_sprintf() format prefix to be used for a `mode_t` parameter. */
#ifndef PRI_MODET_PREFIX
# define PRI_MODET_PREFIX PRI_INT_PREFIX
#endif

#endif /* RBIMPL_ARITHMETIC_MODE_T_H */
ruby/internal/arithmetic/pid_t.h000064400000003536151732674220012762 0ustar00#ifndef RBIMPL_ARITHMETIC_PID_T_H                    /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ARITHMETIC_PID_T_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Arithmetic conversion between C's `pid_t` and Ruby's.
 */
#include "ruby/internal/config.h"
#include "ruby/internal/arithmetic/long.h"

/** Converts a C's `pid_t` into an instance of ::rb_cInteger. */
#ifndef PIDT2NUM
# define PIDT2NUM RB_LONG2NUM
#endif

/** Converts an instance of ::rb_cNumeric into C's `pid_t`. */
#ifndef NUM2PIDT
# define NUM2PIDT RB_NUM2LONG
#endif

/** A rb_sprintf() format prefix to be used for a `pid_t` parameter. */
#ifndef PRI_PIDT_PREFIX
# define PRI_PIDT_PREFIX PRI_LONG_PREFIX
#endif

#endif /* RBIMPL_ARITHMETIC_PID_T_H */
ruby/internal/arithmetic/long.h000064400000026545151732674220012627 0ustar00#ifndef RBIMPL_ARITHMETIC_LONG_H                     /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ARITHMETIC_LONG_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Arithmetic conversion between C's `long` and Ruby's.
 *
 * ### Q&A ###
 *
 * - Q: Why are INT2FIX etc. here, not in `int.h`?
 *
 * - A: Because they  are in fact  handling `long`.   It seems someone  did not
 *      understand the difference of `int`  and `long` when they designed those
 *      macros.
 */
#include "ruby/internal/config.h"
#include "ruby/internal/arithmetic/fixnum.h"   /* FIXABLE */
#include "ruby/internal/arithmetic/intptr_t.h" /* rb_int2big etc.*/
#include "ruby/internal/assume.h"
#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/attr/cold.h"
#include "ruby/internal/attr/const.h"
#include "ruby/internal/attr/constexpr.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/special_consts.h"      /* FIXNUM_FLAG */
#include "ruby/internal/value.h"
#include "ruby/assert.h"

#define FIX2LONG     RB_FIX2LONG          /**< @old{RB_FIX2LONG} */
#define FIX2ULONG    RB_FIX2ULONG         /**< @old{RB_FIX2ULONG} */
#define INT2FIX      RB_INT2FIX           /**< @old{RB_INT2FIX} */
#define LONG2FIX     RB_INT2FIX           /**< @old{RB_INT2FIX} */
#define LONG2NUM     RB_LONG2NUM          /**< @old{RB_LONG2NUM} */
#define NUM2LONG     RB_NUM2LONG          /**< @old{RB_NUM2LONG} */
#define NUM2ULONG    RB_NUM2ULONG         /**< @old{RB_NUM2ULONG} */
#define RB_FIX2LONG  rb_fix2long          /**< @alias{rb_fix2long} */
#define RB_FIX2ULONG rb_fix2ulong         /**< @alias{rb_fix2ulong} */
#define RB_LONG2FIX  RB_INT2FIX           /**< @alias{RB_INT2FIX} */
#define RB_LONG2NUM  rb_long2num_inline   /**< @alias{rb_long2num_inline} */
#define RB_NUM2LONG  rb_num2long_inline   /**< @alias{rb_num2long_inline} */
#define RB_NUM2ULONG rb_num2ulong_inline  /**< @alias{rb_num2ulong_inline} */
#define RB_ULONG2NUM rb_ulong2num_inline  /**< @alias{rb_ulong2num_inline} */
#define ULONG2NUM    RB_ULONG2NUM         /**< @old{RB_ULONG2NUM} */
#define rb_fix_new   RB_INT2FIX           /**< @alias{RB_INT2FIX} */
#define rb_long2int  rb_long2int_inline   /**< @alias{rb_long2int_inline} */

/** @cond INTERNAL_MACRO */
#define RB_INT2FIX RB_INT2FIX
/** @endcond */

RBIMPL_SYMBOL_EXPORT_BEGIN()

RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_COLD()
/**
 * This is an utility function to raise an ::rb_eRangeError.
 *
 * @param[in]  num             A signed value about to overflow.
 * @exception  rb_eRangeError  `num` is out of range of `int`.
 */
void rb_out_of_int(SIGNED_VALUE num);

/**
 * Converts an instance of ::rb_cNumeric into C's `long`.
 *
 * @param[in]  num             Something numeric.
 * @exception  rb_eTypeError   `num` is not a numeric.
 * @exception  rb_eRangeError  `num` is out of range of `long`.
 * @return     The passed value converted into C's `long`.
 */
long rb_num2long(VALUE num);

/**
 * Converts an instance of ::rb_cNumeric into C's `unsigned long`.
 *
 * @param[in]  num             Something numeric.
 * @exception  rb_eTypeError   `num` is not a numeric.
 * @exception  rb_eRangeError  `num` is out of range of `unsigned long`.
 * @return     The passed value converted into C's `unsigned long`.
 */
unsigned long rb_num2ulong(VALUE num);
RBIMPL_SYMBOL_EXPORT_END()

RBIMPL_ATTR_CONST_UNLESS_DEBUG()
RBIMPL_ATTR_CONSTEXPR_UNLESS_DEBUG(CXX14)
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Converts a C's `long` into an instance of ::rb_cInteger.
 *
 * @param[in]  i  Arbitrary `long` value.
 * @return     An instance of ::rb_cInteger.
 */
static inline VALUE
RB_INT2FIX(long i)
{
    RBIMPL_ASSERT_OR_ASSUME(RB_FIXABLE(i));

    /* :NOTE: VALUE can be wider than long.  As j being unsigned, 2j+1 is fully
     * defined. Also it can be compiled into a single LEA instruction. */
    const unsigned long j = RBIMPL_CAST((unsigned long)i);
    const unsigned long k = (j << 1) + RUBY_FIXNUM_FLAG;
    const long          l = RBIMPL_CAST((long)k);
    const SIGNED_VALUE  m = l; /* Sign extend */
    const VALUE         n = RBIMPL_CAST((VALUE)m);

    RBIMPL_ASSERT_OR_ASSUME(RB_FIXNUM_P(n));
    return n;
}

/**
 * Checks if `int` can hold the given integer.
 *
 * @param[in]  n               Arbitrary `long` value.
 * @exception  rb_eRangeError  `n` is out of range of `int`.
 * @return     Identical value of type `int`
 */
static inline int
rb_long2int_inline(long n)
{
    int i = RBIMPL_CAST((int)n);

    if /* constexpr */ (sizeof(long) <= sizeof(int)) {
        RBIMPL_ASSUME(i == n);
    }

    if (i != n)
        rb_out_of_int(n);

    return i;
}

RBIMPL_ATTR_CONST_UNLESS_DEBUG()
RBIMPL_ATTR_CONSTEXPR_UNLESS_DEBUG(CXX14)
/**
 * @private
 *
 * This  is an  implementation detail  of rb_fix2long().   People don't  use it
 * directly.
 *
 * @param[in]  x  A Fixnum.
 * @return     Identical value of type `long`
 * @pre        Must not pass anything other than a Fixnum.
 */
static inline long
rbimpl_fix2long_by_idiv(VALUE x)
{
    RBIMPL_ASSERT_OR_ASSUME(RB_FIXNUM_P(x));

    /* :NOTE: VALUE  can be wider  than long.  (x-1)/2 never  overflows because
     * RB_FIXNUM_P(x)  holds.   Also it  has  no  portability issue  like  y>>1
     * below. */
    const SIGNED_VALUE y = RBIMPL_CAST((SIGNED_VALUE)(x - RUBY_FIXNUM_FLAG));
    const SIGNED_VALUE z = y / 2;
    const long         w = RBIMPL_CAST((long)z);

    RBIMPL_ASSERT_OR_ASSUME(RB_FIXABLE(w));
    return w;
}

RBIMPL_ATTR_CONST_UNLESS_DEBUG()
RBIMPL_ATTR_CONSTEXPR_UNLESS_DEBUG(CXX14)
/**
 * @private
 *
 * This  is an  implementation detail  of rb_fix2long().   People don't  use it
 * directly.
 *
 * @param[in]  x  A Fixnum.
 * @return     Identical value of type `long`
 * @pre        Must not pass anything other than a Fixnum.
 */
static inline long
rbimpl_fix2long_by_shift(VALUE x)
{
    RBIMPL_ASSERT_OR_ASSUME(RB_FIXNUM_P(x));

    /* :NOTE: VALUE can be wider than long.  If right shift is arithmetic, this
     * is noticeably faster than above. */
    const SIGNED_VALUE y = RBIMPL_CAST((SIGNED_VALUE)x);
    const SIGNED_VALUE z = y >> 1;
    const long         w = RBIMPL_CAST((long)z);

    RBIMPL_ASSERT_OR_ASSUME(RB_FIXABLE(w));
    return w;
}

RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
/**
 * @private
 *
 * This  is an  implementation detail  of rb_fix2long().   People don't  use it
 * directly.
 *
 * @retval  true   This C compiler's right shift operator is arithmetic.
 * @retval  false  This C compiler's right shift operator is logical.
 */
static inline bool
rbimpl_right_shift_is_arithmetic_p(void)
{
    return (-1 >> 1) == -1;
}

RBIMPL_ATTR_CONST_UNLESS_DEBUG()
RBIMPL_ATTR_CONSTEXPR_UNLESS_DEBUG(CXX14)
/**
 * Converts a Fixnum into C's `long`.
 *
 * @param[in]  x  Some Fixnum.
 * @pre        Must not pass anything other than a Fixnum.
 * @return     The passed value converted into C's `long`.
 */
static inline long
rb_fix2long(VALUE x)
{
    if /* constexpr */ (rbimpl_right_shift_is_arithmetic_p()) {
        return rbimpl_fix2long_by_shift(x);
    }
    else {
        return rbimpl_fix2long_by_idiv(x);
    }
}

RBIMPL_ATTR_CONST_UNLESS_DEBUG()
RBIMPL_ATTR_CONSTEXPR_UNLESS_DEBUG(CXX14)
/**
 * Converts a Fixnum into C's `unsigned long`.
 *
 * @param[in]  x  Some Fixnum.
 * @pre        Must not pass anything other than a Fixnum.
 * @return     The passed value converted into C's `unsigned long`.
 * @note       Negative fixnums will be converted into large unsigned longs.
 */
static inline unsigned long
rb_fix2ulong(VALUE x)
{
    RBIMPL_ASSERT_OR_ASSUME(RB_FIXNUM_P(x));
    return RBIMPL_CAST((unsigned long)rb_fix2long(x));
}

/**
 * Converts an instance of ::rb_cNumeric into C's `long`.
 *
 * @param[in]  x               Something numeric.
 * @exception  rb_eTypeError   `x` is not a numeric.
 * @exception  rb_eRangeError  `x` is out of range of `long`.
 * @return     The passed value converted into C's `long`.
 */
static inline long
rb_num2long_inline(VALUE x)
{
    if (RB_FIXNUM_P(x))
        return RB_FIX2LONG(x);
    else
        return rb_num2long(x);
}

/**
 * Converts an instance of ::rb_cNumeric into C's `unsigned long`.
 *
 * @param[in]  x               Something numeric.
 * @exception  rb_eTypeError   `x` is not a numeric.
 * @exception  rb_eRangeError  `x` is out of range of `unsigned long`.
 * @return     The passed value converted into C's `unsigned long`.
 *
 * @internal
 *
 * This  (negative fixnum  would become  a large  unsigned long  while negative
 * bignum  is an  exception)  has been  THE behaviour  of  NUM2ULONG since  the
 * beginning.  It is strange, but we can  no longer change how it works at this
 * moment.  We have to get by with it.
 *
 * @see https://bugs.ruby-lang.org/issues/9089
 */
static inline unsigned long
rb_num2ulong_inline(VALUE x)
{
    if (RB_FIXNUM_P(x))
        return RB_FIX2ULONG(x);
    else
        return rb_num2ulong(x);
}

/**
 * Converts a C's `long` into an instance of ::rb_cInteger.
 *
 * @param[in]  v  Arbitrary `long` value.
 * @return     An instance of ::rb_cInteger.
 */
static inline VALUE
rb_long2num_inline(long v)
{
    if (RB_FIXABLE(v))
        return RB_LONG2FIX(v);
    else
        return rb_int2big(v);
}

/**
 * Converts a C's `unsigned long` into an instance of ::rb_cInteger.
 *
 * @param[in]  v  Arbitrary `unsigned long` value.
 * @return     An instance of ::rb_cInteger.
 */
static inline VALUE
rb_ulong2num_inline(unsigned long v)
{
    if (RB_POSFIXABLE(v))
        return RB_LONG2FIX(RBIMPL_CAST((long)v));
    else
        return rb_uint2big(v);
}

/**
 * @cond INTERNAL_MACRO
 *
 * Following overload is necessary because sometimes  INT2FIX is used as a enum
 * value (e.g. `enum {  FOO = INT2FIX(0) };`).  THIS IS NG  in theory because a
 * VALUE does not fit into an enum (which must be a signed int).  But we cannot
 * break existing codes.
 */
#if RBIMPL_HAS_ATTR_CONSTEXPR_CXX14
# /* C++ can write constexpr as enum values. */

#elif ! defined(HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P)
# undef INT2FIX
# define INT2FIX(i) (RBIMPL_CAST((VALUE)(i)) << 1 | RUBY_FIXNUM_FLAG)

#else
# undef INT2FIX
# define INT2FIX(i)                                     \
    __builtin_choose_expr(                              \
        __builtin_constant_p(i),                        \
        RBIMPL_CAST((VALUE)(i)) << 1 | RUBY_FIXNUM_FLAG, \
        RB_INT2FIX(i))
#endif
/** @endcond */

#endif /* RBIMPL_ARITHMETIC_LONG_H */
ruby/internal/arithmetic/char.h000064400000006453151732674220012601 0ustar00#ifndef RBIMPL_ARITHMETIC_CHAR_H                     /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ARITHMETIC_CHAR_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Arithmetic conversion between C's `char` and Ruby's.
 */
#include "ruby/internal/arithmetic/int.h"  /* NUM2INT is here, but */
#include "ruby/internal/arithmetic/long.h" /* INT2FIX is here.*/
#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/attr/const.h"
#include "ruby/internal/attr/constexpr.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/core/rstring.h"
#include "ruby/internal/value_type.h"

#define RB_NUM2CHR rb_num2char_inline /**< @alias{rb_num2char_inline} */
#define NUM2CHR    RB_NUM2CHR         /**< @old{RB_NUM2CHR} */
#define CHR2FIX    RB_CHR2FIX         /**< @old{RB_CHR2FIX} */

/** @cond INTERNAL_MACRO */
#define RB_CHR2FIX RB_CHR2FIX
/** @endcond */

RBIMPL_ATTR_CONST_UNLESS_DEBUG()
RBIMPL_ATTR_CONSTEXPR_UNLESS_DEBUG(CXX14)
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Converts a C's `unsigned char` into an instance of ::rb_cInteger.
 *
 * @param[in]  c  Arbitrary `unsigned char` value.
 * @return     An instance of ::rb_cInteger.
 *
 * @internal
 *
 * Nobody explicitly states this but in  Ruby, a char means an unsigned integer
 * value of  range 0..255.   This is  a general principle.   AFAIK there  is no
 * single line of code where char is signed.
 */
static inline VALUE
RB_CHR2FIX(unsigned char c)
{
    return RB_INT2FIX(c);
}

/**
 * Converts an instance of ::rb_cNumeric into  C's `char`.  At the same time it
 * accepts a String of more than one character, and returns its first byte.  In
 * the  early days  there  was a  Ruby level  "character"  literal `?c`,  which
 * roughly worked this way.
 *
 * @param[in]  x               Either a string or a numeric.
 * @exception  rb_eTypeError   `x` is not a numeric.
 * @exception  rb_eRangeError  `x` is out of range of `unsigned int`.
 * @return     The passed value converted into C's `char`.
 */
static inline char
rb_num2char_inline(VALUE x)
{
    if (RB_TYPE_P(x, RUBY_T_STRING) && (RSTRING_LEN(x)>=1))
        return RSTRING_PTR(x)[0];
    else
        return RBIMPL_CAST((char)RB_NUM2INT(x));
}

#endif /* RBIMPL_ARITHMETIC_CHAR_H */
ruby/internal/globals.h000064400000023430151732674220011150 0ustar00#ifndef RBIMPL_GLOBALS_H                             /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_GLOBALS_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Ruby-level global variables / constants, visible from C.
 */
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/fl_type.h"
#include "ruby/internal/special_consts.h"
#include "ruby/internal/value.h"
#include "ruby/internal/value_type.h"

/**
 * @defgroup object Core objects and their operations
 *
 * @internal
 *
 * There are several  questionable constants listed in this  header file.  They
 * are intentionally left untouched for purely academic backwards compatibility
 * concerns.  But for instance do any one of 3rd party extension libraries even
 * need to know that there is NameError::Message?
 *
 * @endinternal
 *
 * @{
 */

RBIMPL_SYMBOL_EXPORT_BEGIN()

/**
 * @private
 *
 * @deprecated  This macro once was a thing in the old days, but makes no sense
 *              any  longer today.   Exists  here  for backwards  compatibility
 *              only.  You can safely forget about it.
 */
#define RUBY_INTEGER_UNIFICATION 1

RUBY_EXTERN VALUE rb_mKernel;                 /**< `Kernel` module. */
RUBY_EXTERN VALUE rb_mComparable;             /**< `Comparable` module. */
RUBY_EXTERN VALUE rb_mEnumerable;             /**< `Enumerable` module. */
RUBY_EXTERN VALUE rb_mErrno;                  /**< `Errno` module. */
RUBY_EXTERN VALUE rb_mFileTest;               /**< `FileTest` module. */
RUBY_EXTERN VALUE rb_mGC;                     /**< `GC` module. */
RUBY_EXTERN VALUE rb_mMath;                   /**< `Math` module. */
RUBY_EXTERN VALUE rb_mProcess;                /**< `Process` module. */
RUBY_EXTERN VALUE rb_mWaitReadable;           /**< `IO::WaitReadable` module. */
RUBY_EXTERN VALUE rb_mWaitWritable;           /**< `IO::WaitReadable` module. */

RUBY_EXTERN VALUE rb_cBasicObject;            /**< `BasicObject` class. */
RUBY_EXTERN VALUE rb_cObject;                 /**< `Object` class. */
RUBY_EXTERN VALUE rb_cArray;                  /**< `Array` class. */
RUBY_EXTERN VALUE rb_cBinding;                /**< `Binding` class. */
RUBY_EXTERN VALUE rb_cClass;                  /**< `Class` class. */
RUBY_EXTERN VALUE rb_cDir;                    /**< `Dir` class. */
RUBY_EXTERN VALUE rb_cEncoding;               /**< `Encoding` class. */
RUBY_EXTERN VALUE rb_cEnumerator;             /**< `Enumerator` class. */
RUBY_EXTERN VALUE rb_cFalseClass;             /**< `FalseClass` class. */
RUBY_EXTERN VALUE rb_cFile;                   /**< `File` class. */
RUBY_EXTERN VALUE rb_cComplex;                /**< `Complex` class. */
RUBY_EXTERN VALUE rb_cFloat;                  /**< `Float` class. */
RUBY_EXTERN VALUE rb_cHash;                   /**< `Hash` class. */
RUBY_EXTERN VALUE rb_cIO;                     /**< `IO` class. */
RUBY_EXTERN VALUE rb_cInteger;                /**< `Module` class. */
RUBY_EXTERN VALUE rb_cMatch;                  /**< `MatchData` class. */
RUBY_EXTERN VALUE rb_cMethod;                 /**< `Method` class. */
RUBY_EXTERN VALUE rb_cModule;                 /**< `Module` class. */
RUBY_EXTERN VALUE rb_cRefinement;             /**< `Refinement` class. */
RUBY_EXTERN VALUE rb_cNameErrorMesg;          /**< `NameError::Message` class. */
RUBY_EXTERN VALUE rb_cNilClass;               /**< `NilClass` class. */
RUBY_EXTERN VALUE rb_cNumeric;                /**< `Numeric` class. */
RUBY_EXTERN VALUE rb_cProc;                   /**< `Proc` class. */
RUBY_EXTERN VALUE rb_cRandom;                 /**< `Random` class. */
RUBY_EXTERN VALUE rb_cRange;                  /**< `Range` class. */
RUBY_EXTERN VALUE rb_cRational;               /**< `Rational` class. */
RUBY_EXTERN VALUE rb_cRegexp;                 /**< `Regexp` class. */
RUBY_EXTERN VALUE rb_cStat;                   /**< `File::Stat` class. */
RUBY_EXTERN VALUE rb_cString;                 /**< `String` class. */
RUBY_EXTERN VALUE rb_cStruct;                 /**< `Struct` class. */
RUBY_EXTERN VALUE rb_cSymbol;                 /**< `Symbol` class. */
RUBY_EXTERN VALUE rb_cThread;                 /**< `Thread` class. */
RUBY_EXTERN VALUE rb_cTime;                   /**< `Time` class. */
RUBY_EXTERN VALUE rb_cTrueClass;              /**< `TrueClass` class. */
RUBY_EXTERN VALUE rb_cUnboundMethod;          /**< `UnboundMethod` class. */

/**
 * @}
 * @addtogroup exception
 * @{
 */

RUBY_EXTERN VALUE rb_eException;                 /**< Mother of all exceptions. */
RUBY_EXTERN VALUE rb_eStandardError;             /**< `StandardError` exception. */
RUBY_EXTERN VALUE rb_eSystemExit;                /**< `SystemExit` exception. */
RUBY_EXTERN VALUE rb_eInterrupt;                 /**< `Interrupt` exception. */
RUBY_EXTERN VALUE rb_eSignal;                    /**< `SignalException` exception. */
RUBY_EXTERN VALUE rb_eFatal;                     /**< `fatal` exception. */
RUBY_EXTERN VALUE rb_eArgError;                  /**< `ArgumentError` exception. */
RUBY_EXTERN VALUE rb_eEOFError;                  /**< `EOFError` exception. */
RUBY_EXTERN VALUE rb_eIndexError;                /**< `IndexError` exception. */
RUBY_EXTERN VALUE rb_eStopIteration;             /**< `StopIteration` exception. */
RUBY_EXTERN VALUE rb_eKeyError;                  /**< `KeyError` exception. */
RUBY_EXTERN VALUE rb_eRangeError;                /**< `RangeError` exception. */
RUBY_EXTERN VALUE rb_eIOError;                   /**< `IOError` exception. */
RUBY_EXTERN VALUE rb_eRuntimeError;              /**< `RuntimeError` exception. */
RUBY_EXTERN VALUE rb_eFrozenError;               /**< `FrozenError` exception. */
RUBY_EXTERN VALUE rb_eSecurityError;             /**< `SecurityError` exception. */
RUBY_EXTERN VALUE rb_eSystemCallError;           /**< `SystemCallError` exception. */
RUBY_EXTERN VALUE rb_eThreadError;               /**< `ThreadError` exception. */
RUBY_EXTERN VALUE rb_eTypeError;                 /**< `TypeError` exception. */
RUBY_EXTERN VALUE rb_eZeroDivError;              /**< `ZeroDivisionError` exception. */
RUBY_EXTERN VALUE rb_eNotImpError;               /**< `NotImplementedError` exception. */
RUBY_EXTERN VALUE rb_eNoMemError;                /**< `NoMemoryError` exception. */
RUBY_EXTERN VALUE rb_eNoMethodError;             /**< `NoMethodError` exception. */
RUBY_EXTERN VALUE rb_eFloatDomainError;          /**< `FloatDomainError` exception. */
RUBY_EXTERN VALUE rb_eLocalJumpError;            /**< `LocalJumpError` exception. */
RUBY_EXTERN VALUE rb_eSysStackError;             /**< `SystemStackError` exception. */
RUBY_EXTERN VALUE rb_eRegexpError;               /**< `RegexpError` exception. */
RUBY_EXTERN VALUE rb_eEncodingError;             /**< `EncodingError` exception. */
RUBY_EXTERN VALUE rb_eEncCompatError;            /**< `Encoding::CompatibilityError` exception. */
RUBY_EXTERN VALUE rb_eNoMatchingPatternError;    /**< `NoMatchingPatternError` exception. */
RUBY_EXTERN VALUE rb_eNoMatchingPatternKeyError; /**< `NoMatchingPatternKeyError` exception. */

RUBY_EXTERN VALUE rb_eScriptError;               /**< `ScriptError` exception. */
RUBY_EXTERN VALUE rb_eNameError;                 /**< `NameError` exception. */
RUBY_EXTERN VALUE rb_eSyntaxError;               /**< `SyntaxError` exception. */
RUBY_EXTERN VALUE rb_eLoadError;                 /**< `LoadError` exception. */

RUBY_EXTERN VALUE rb_eMathDomainError;           /**< `Math::DomainError` exception. */

/**
 * @}
 * @addtogroup object
 * @{
 */

RUBY_EXTERN VALUE rb_stdin;                      /**< `STDIN` constant. */
RUBY_EXTERN VALUE rb_stdout;                     /**< `STDOUT` constant. */
RUBY_EXTERN VALUE rb_stderr;                     /**< `STDERR` constant. */

RBIMPL_ATTR_PURE()
/**
 * Object  to class  mapping  function.   Every object  have  its class.   This
 * function obtains that.
 *
 * @param[in]  obj  Target object to query.
 * @return     The class of the given object.
 *
 * @internal
 *
 * This  function is  a super-duper  hot  path.  Optimised  targeting modern  C
 * compilers and x86_64 architecture.
 */
static inline VALUE
rb_class_of(VALUE obj)
{
    if (! RB_SPECIAL_CONST_P(obj)) {
        return RBASIC_CLASS(obj);
    }
    else if (obj == RUBY_Qfalse) {
        return rb_cFalseClass;
    }
    else if (obj == RUBY_Qnil) {
        return rb_cNilClass;
    }
    else if (obj == RUBY_Qtrue) {
        return rb_cTrueClass;
    }
    else if (RB_FIXNUM_P(obj)) {
        return rb_cInteger;
    }
    else if (RB_STATIC_SYM_P(obj)) {
        return rb_cSymbol;
    }
    else if (RB_FLONUM_P(obj)) {
        return rb_cFloat;
    }

#if !RUBY_DEBUG
    RBIMPL_UNREACHABLE_RETURN(Qfalse);
#else
    RUBY_ASSERT_FAIL("unexpected type");
#endif
}

#define CLASS_OF rb_class_of /**< @old{rb_class_of} */

RBIMPL_SYMBOL_EXPORT_END()

/** @} */

#endif /* RBIMPL_GLOBALS_H */
ruby/internal/assume.h000064400000006255151732674220011030 0ustar00#ifndef RBIMPL_ASSUME_H                              /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ASSUME_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_ASSUME / #RBIMPL_UNREACHABLE.
 *
 * These macros must be defined at once because:
 *
 * - #RBIMPL_ASSUME could fallback to #RBIMPL_UNREACHABLE.
 * - #RBIMPL_UNREACHABLE could fallback to #RBIMPL_ASSUME.
 */
#include "ruby/internal/config.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/compiler_since.h"
#include "ruby/internal/has/builtin.h"
#include "ruby/internal/warning_push.h"

/** @cond INTERNAL_MACRO */
#if defined(HAVE___ASSUME)
# define RBIMPL_HAVE___ASSUME
#endif
/** @endcond */

/** Wraps (or simulates) `__builtin_unreachable`. */
#if RBIMPL_HAS_BUILTIN(__builtin_unreachable)
# define RBIMPL_UNREACHABLE_RETURN(_) __builtin_unreachable()

#elif defined(RBIMPL_HAVE___ASSUME)
# define RBIMPL_UNREACHABLE_RETURN(_) return (__assume(0), (_))

#else
# define RBIMPL_UNREACHABLE_RETURN(_) return (_)
#endif

/** Wraps (or simulates) `__builtin_unreachable`. */
#if RBIMPL_HAS_BUILTIN(__builtin_unreachable)
# define RBIMPL_UNREACHABLE __builtin_unreachable

#elif defined(RBIMPL_HAVE___ASSUME)
# define RBIMPL_UNREACHABLE() __assume(0)
#endif

/** Wraps (or simulates) `__assume`. */
#if RBIMPL_COMPILER_SINCE(Intel, 13, 0, 0)
# /* icc warnings are false positives.  Ignore them. */
# /* "warning #2261: __assume expression with side effects discarded" */
# define RBIMPL_ASSUME(expr)     \
    RBIMPL_WARNING_PUSH()        \
    RBIMPL_WARNING_IGNORED(2261) \
    __assume(expr)              \
    RBIMPL_WARNING_POP()

#elif defined(RBIMPL_HAVE___ASSUME)
# define RBIMPL_ASSUME __assume

#elif RBIMPL_HAS_BUILTIN(__builtin_assume)
# define RBIMPL_ASSUME __builtin_assume

#elif ! defined(RBIMPL_UNREACHABLE)
# define RBIMPL_ASSUME(_) RBIMPL_CAST((void)(_))

#else
# define RBIMPL_ASSUME(_) \
    (RB_LIKELY(!!(_)) ? RBIMPL_CAST((void)0) : RBIMPL_UNREACHABLE())
#endif

#if ! defined(RBIMPL_UNREACHABLE)
# define RBIMPL_UNREACHABLE() RBIMPL_ASSUME(0)
#endif

#endif /* RBIMPL_ASSUME_H */
ruby/internal/special_consts.h000064400000027717151732674220012552 0ustar00#ifndef RBIMPL_SPECIAL_CONSTS_H                      /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_SPECIAL_CONSTS_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines enum ::ruby_special_consts.
 * @see        Sasada,  K.,  "A  Lightweight Representation  of  Floating-Point
 *             Numbers  on  Ruby Interpreter",  in  proceedings  of 10th  JSSST
 *             SIGPPL  Workshop   on  Programming  and   Programming  Languages
 *             (PPL2008), pp. 9-16, 2008.
 */
#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/attr/const.h"
#include "ruby/internal/attr/constexpr.h"
#include "ruby/internal/attr/enum_extensibility.h"
#include "ruby/internal/stdbool.h"
#include "ruby/internal/value.h"

/**
 * @private
 * @warning  Do not touch this macro.
 * @warning  It is an implementation detail.
 * @warning  The  value of  this  macro  must match  for  ruby  itself and  all
 *           extension  libraries, otherwise  serious  memory corruption  shall
 *           occur.
 */
#if defined(USE_FLONUM)
# /* Take that. */
#elif SIZEOF_VALUE >= SIZEOF_DOUBLE
# define USE_FLONUM 1
#else
# define USE_FLONUM 0
#endif

/** This is an old name of #RB_TEST.  Not sure which name is preferred. */
#define RTEST           RB_TEST

#define FIXNUM_P        RB_FIXNUM_P            /**< @old{RB_FIXNUM_P} */
#define IMMEDIATE_P     RB_IMMEDIATE_P         /**< @old{RB_IMMEDIATE_P} */
#define NIL_P           RB_NIL_P               /**< @old{RB_NIL_P} */
#define SPECIAL_CONST_P RB_SPECIAL_CONST_P     /**< @old{RB_SPECIAL_CONST_P} */
#define STATIC_SYM_P    RB_STATIC_SYM_P        /**< @old{RB_STATIC_SYM_P} */

#define Qfalse          RUBY_Qfalse            /**< @old{RUBY_Qfalse} */
#define Qnil            RUBY_Qnil              /**< @old{RUBY_Qnil} */
#define Qtrue           RUBY_Qtrue             /**< @old{RUBY_Qtrue} */
#define Qundef          RUBY_Qundef            /**< @old{RUBY_Qundef} */

#define FIXNUM_FLAG        RUBY_FIXNUM_FLAG    /**< @old{RUBY_FIXNUM_FLAG} */
#define FLONUM_FLAG        RUBY_FLONUM_FLAG    /**< @old{RUBY_FLONUM_FLAG} */
#define FLONUM_MASK        RUBY_FLONUM_MASK    /**< @old{RUBY_FLONUM_MASK} */
#define FLONUM_P           RB_FLONUM_P         /**< @old{RB_FLONUM_P} */
#define IMMEDIATE_MASK     RUBY_IMMEDIATE_MASK /**< @old{RUBY_IMMEDIATE_MASK} */
#define SYMBOL_FLAG        RUBY_SYMBOL_FLAG    /**< @old{RUBY_SYMBOL_FLAG} */

/** @cond INTERNAL_MACRO */
#define RB_FIXNUM_P        RB_FIXNUM_P
#define RB_FLONUM_P        RB_FLONUM_P
#define RB_IMMEDIATE_P     RB_IMMEDIATE_P
#define RB_NIL_P           RB_NIL_P
#define RB_SPECIAL_CONST_P RB_SPECIAL_CONST_P
#define RB_STATIC_SYM_P    RB_STATIC_SYM_P
#define RB_TEST            RB_TEST
#define RB_UNDEF_P         RB_UNDEF_P
#define RB_NIL_OR_UNDEF_P  RB_NIL_OR_UNDEF_P
/** @endcond */

/** special constants - i.e. non-zero and non-fixnum constants */
enum
RBIMPL_ATTR_ENUM_EXTENSIBILITY(closed)
ruby_special_consts {
#if defined(__DOXYGEN__)
    RUBY_Qfalse,                /**< @see ::rb_cFalseClass */
    RUBY_Qtrue,                 /**< @see ::rb_cTrueClass */
    RUBY_Qnil,                  /**< @see ::rb_cNilClass */
    RUBY_Qundef,                /**< Represents so-called undef. */
    RUBY_IMMEDIATE_MASK,        /**< Bit mask detecting special consts. */
    RUBY_FIXNUM_FLAG,           /**< Flag to denote a fixnum. */
    RUBY_FLONUM_MASK,           /**< Bit mask detecting a flonum. */
    RUBY_FLONUM_FLAG,           /**< Flag to denote a flonum. */
    RUBY_SYMBOL_FLAG,           /**< Flag to denote a static symbol. */
#elif USE_FLONUM
    RUBY_Qfalse         = 0x00, /* ...0000 0000 */
    RUBY_Qnil           = 0x04, /* ...0000 0100 */
    RUBY_Qtrue          = 0x14, /* ...0001 0100 */
    RUBY_Qundef         = 0x24, /* ...0010 0100 */
    RUBY_IMMEDIATE_MASK = 0x07, /* ...0000 0111 */
    RUBY_FIXNUM_FLAG    = 0x01, /* ...xxxx xxx1 */
    RUBY_FLONUM_MASK    = 0x03, /* ...0000 0011 */
    RUBY_FLONUM_FLAG    = 0x02, /* ...xxxx xx10 */
    RUBY_SYMBOL_FLAG    = 0x0c, /* ...xxxx 1100 */
#else
    RUBY_Qfalse         = 0x00, /* ...0000 0000 */
    RUBY_Qnil           = 0x02, /* ...0000 0010 */
    RUBY_Qtrue          = 0x06, /* ...0000 0110 */
    RUBY_Qundef         = 0x0a, /* ...0000 1010 */
    RUBY_IMMEDIATE_MASK = 0x03, /* ...0000 0011 */
    RUBY_FIXNUM_FLAG    = 0x01, /* ...xxxx xxx1 */
    RUBY_FLONUM_MASK    = 0x00, /* any values ANDed with FLONUM_MASK cannot be FLONUM_FLAG */
    RUBY_FLONUM_FLAG    = 0x02, /* ...0000 0010 */
    RUBY_SYMBOL_FLAG    = 0x0e, /* ...xxxx 1110 */
#endif

    RUBY_SPECIAL_SHIFT  = 8 /**< Least significant 8 bits are reserved. */
};

RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Emulates Ruby's "if" statement.
 *
 * @param[in]  obj    An arbitrary ruby object.
 * @retval     false  `obj` is either ::RUBY_Qfalse or ::RUBY_Qnil.
 * @retval     true   Anything else.
 *
 * @internal
 *
 * It HAS to be `__attribute__((const))` in  order for clang to properly deduce
 * `__builtin_assume()`.
 */
static inline bool
RB_TEST(VALUE obj)
{
    /*
     * if USE_FLONUM
     *  Qfalse:  ....0000 0000
     *  Qnil:    ....0000 0100
     * ~Qnil:    ....1111 1011
     *  v        ....xxxx xxxx
     * ----------------------------
     *  RTEST(v) ....xxxx x0xx
     *
     * if ! USE_FLONUM
     *  Qfalse:  ....0000 0000
     *  Qnil:    ....0000 0010
     * ~Qnil:    ....1111 1101
     *  v        ....xxxx xxxx
     * ----------------------------
     *  RTEST(v) ....xxxx xx0x
     *
     *  RTEST(v) can be 0 if and only if (v == Qfalse || v == Qnil).
     */
    return obj & RBIMPL_CAST((VALUE)~RUBY_Qnil);
}

RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Checks if the given object is nil.
 *
 * @param[in]  obj    An arbitrary ruby object.
 * @retval     true   `obj` is ::RUBY_Qnil.
 * @retval     false  Anything else.
 */
static inline bool
RB_NIL_P(VALUE obj)
{
    return obj == RUBY_Qnil;
}

RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Checks if the given object is undef.
 *
 * @param[in]  obj    An arbitrary ruby object.
 * @retval     true   `obj` is ::RUBY_Qundef.
 * @retval     false  Anything else.
 */
static inline bool
RB_UNDEF_P(VALUE obj)
{
    return obj == RUBY_Qundef;
}

RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX14)
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Checks if the given object is nil or undef.  Can be used to see if
 * a keyword argument is not given or given `nil`.
 *
 * @param[in]  obj    An arbitrary ruby object.
 * @retval     true   `obj` is ::RUBY_Qnil or ::RUBY_Qundef.
 * @retval     false  Anything else.
 */
static inline bool
RB_NIL_OR_UNDEF_P(VALUE obj)
{
    /*
     * if USE_FLONUM
     *  Qundef:       ....0010 0100
     *  Qnil:         ....0000 0100
     *  mask:         ....1101 1111
     *  common_bits:  ....0000 0100
     * ---------------------------------
     *  Qnil & mask   ....0000 0100
     *  Qundef & mask ....0000 0100
     *
     * if ! USE_FLONUM
     *  Qundef:       ....0000 1010
     *  Qnil:         ....0000 0010
     *  mask:         ....1111 0111
     *  common_bits:  ....0000 0010
     * ----------------------------
     *  Qnil & mask   ....0000 0010
     *  Qundef & mask ....0000 0010
     *
     *  NIL_OR_UNDEF_P(v) can be true only when v is Qundef or Qnil.
     */
    const VALUE mask = RBIMPL_CAST((VALUE)~(RUBY_Qundef ^ RUBY_Qnil));
    const VALUE common_bits = RUBY_Qundef & RUBY_Qnil;
    return (obj & mask) == common_bits;
}

RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Checks if the given object is a so-called Fixnum.
 *
 * @param[in]  obj    An arbitrary ruby object.
 * @retval     true   `obj` is a Fixnum.
 * @retval     false  Anything else.
 * @note       Fixnum was  a thing  in the  20th century, but  it is  rather an
 *             implementation detail today.
 */
static inline bool
RB_FIXNUM_P(VALUE obj)
{
    return obj & RUBY_FIXNUM_FLAG;
}

RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX14)
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Checks if the given object is a static symbol.
 *
 * @param[in]  obj    An arbitrary ruby object.
 * @retval     true   `obj` is a static symbol
 * @retval     false  Anything else.
 * @see        RB_DYNAMIC_SYM_P()
 * @see        RB_SYMBOL_P()
 * @note       These days  there are static  and dynamic symbols, just  like we
 *             once had Fixnum/Bignum back in the old days.
 */
static inline bool
RB_STATIC_SYM_P(VALUE obj)
{
    RBIMPL_ATTR_CONSTEXPR(CXX14)
    const VALUE mask = ~(RBIMPL_VALUE_FULL << RUBY_SPECIAL_SHIFT);
    return (obj & mask) == RUBY_SYMBOL_FLAG;
}

RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Checks if the given object is a so-called Flonum.
 *
 * @param[in]  obj    An arbitrary ruby object.
 * @retval     true   `obj` is a Flonum.
 * @retval     false  Anything else.
 * @see        RB_FLOAT_TYPE_P()
 * @note       These days there are Flonums and non-Flonum floats, just like we
 *             once had Fixnum/Bignum back in the old days.
 */
static inline bool
RB_FLONUM_P(VALUE obj)
{
#if USE_FLONUM
    return (obj & RUBY_FLONUM_MASK) == RUBY_FLONUM_FLAG;
#else
    return false;
#endif
}

RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Checks if  the given  object is  an immediate  i.e. an  object which  has no
 * corresponding storage inside of the object space.
 *
 * @param[in]  obj    An arbitrary ruby object.
 * @retval     true   `obj` is a Flonum.
 * @retval     false  Anything else.
 * @see        RB_FLOAT_TYPE_P()
 * @note       The concept of "immediate" is purely C specific.
 */
static inline bool
RB_IMMEDIATE_P(VALUE obj)
{
    return obj & RUBY_IMMEDIATE_MASK;
}

RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Checks if the given object is of enum ::ruby_special_consts.
 *
 * @param[in]  obj    An arbitrary ruby object.
 * @retval     true   `obj` is a special constant.
 * @retval     false  Anything else.
 */
static inline bool
RB_SPECIAL_CONST_P(VALUE obj)
{
    return (obj == RUBY_Qfalse) || RB_IMMEDIATE_P(obj);
}

RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
/**
 * Identical to RB_SPECIAL_CONST_P, except it returns a ::VALUE.
 *
 * @param[in]  obj          An arbitrary ruby object.
 * @retval     RUBY_Qtrue   `obj` is a special constant.
 * @retval     RUBY_Qfalse  Anything else.
 *
 * @internal
 *
 * This  function is  to mimic  old  rb_special_const_p macro  but have  anyone
 * actually used its return value?  Wasn't it just something no one needed?
 */
static inline VALUE
rb_special_const_p(VALUE obj)
{
    return (unsigned int)RB_SPECIAL_CONST_P(obj) * RUBY_Qtrue;
}

/**
 * @cond INTERNAL_MACRO
 * See [ruby-dev:27513] for the following macros.
 */
#define RUBY_Qfalse RBIMPL_CAST((VALUE)RUBY_Qfalse)
#define RUBY_Qtrue  RBIMPL_CAST((VALUE)RUBY_Qtrue)
#define RUBY_Qnil   RBIMPL_CAST((VALUE)RUBY_Qnil)
#define RUBY_Qundef RBIMPL_CAST((VALUE)RUBY_Qundef)
/** @endcond */

#endif /* RBIMPL_SPECIAL_CONSTS_H */
ruby/internal/glob.h000064400000011756151732674220010460 0ustar00#ifndef RBIMPL_GLOB_H                                /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_GLOB_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Declares ::rb_glob().
 */
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/**
 * Type of a glob callback function.  Called every time glob scans a path.
 *
 * @param[in]  path       The path in question.
 * @param[in]  arg        The argument passed to rb_glob().
 * @param[in]  enc        Encoding of the path.
 * @retval     -1         Not enough memory to do the operation.
 * @retval     0          Operation successful.
 * @retval     otherwise  Opaque exception state.
 * @note       You can use rb_protect() to generate the return value.
 *
 * @internal
 *
 * This  is a  wrong design.   Type of  `enc` should  have been  `rb_encoding*`
 * instead of just `void*`.  But we cannot change the API any longer.
 *
 * Though not a part of our public API, the "opaque exception state" is in fact
 * an  enum ruby_tag_type.   You can  see the  potential "otherwise"  values by
 * looking at vm_core.h.
 */
typedef int ruby_glob_func(const char *path, VALUE arg, void *enc);

RBIMPL_ATTR_NONNULL(())
/**
 * The "glob"  operator.  Expands  the given pattern  against the  actual local
 * filesystem,  then  iterates  over  the expanded  filenames  by  calling  the
 * callback function.
 *
 * @param[in]  pattern        A glob pattern.
 * @param[in]  func           Identical to ruby_glob_func,  except it can raise
 *                            exceptions instead of returning opaque state.
 * @param[in]  arg            Extra argument passed to func.
 * @exception  rb_eException  Can propagate what `func` raises.
 * @note       The  language  accepted   as  the  pattern  is   not  a  regular
 *             expression.  It resembles shell's glob.
 */
void rb_glob(const char *pattern, void (*func)(const char *path, VALUE arg, void *enc), VALUE arg);

RBIMPL_ATTR_NONNULL(())
/**
 * Identical to rb_glob(), except it returns opaque exception states instead of
 * raising exceptions.
 *
 * @param[in]  pattern  A glob pattern.
 * @param[in]  flags    No, you are not allowed to use this.  Just pass 0.
 * @param[in]  func     A callback function.
 * @param[in]  arg      Extra argument passed to func.
 * @return     Return value of `func`.
 *
 * @internal
 *
 * This function is  completely broken by design...  Not only  is there no sane
 * way to pass flags, but there also is no sane way to know what a return value
 * is meant to be.
 *
 * Though not a part of our public API, and @shyouhei thinks it's a failure not
 * to be  a public  API, the  flags can  be `FNM_EXTGLOB`,  `FNM_DOTMATCH` etc.
 * Look at dir.c for the list.
 *
 * Though  not a  part  of our  public  API, the  return value  is  in fact  an
 * enum ruby_tag_type.   You  can  see  the  potential  values  by  looking  at
 * vm_core.h.
 */
int ruby_glob(const char *pattern, int flags, ruby_glob_func *func, VALUE arg);

RBIMPL_ATTR_NONNULL(())
/**
 * Identical to  ruby_glob(), @shyouhei  currently suspects.   Historically you
 * had to  call this function  instead of  ruby_glob() if the  pattern included
 * "{x,y,...}" syntax.  However since commit 0f63d961169989a7f6dcf7c0487fe29da,
 * ruby_glob() also  supports that syntax.   It seems  as of writing  these two
 * functions  provide   basically  the   same  functionality  in   a  different
 * implementation.  Is this analysis right?  Correct me! :FIXME:
 *
 * @param[in]  pattern  A glob pattern.
 * @param[in]  flags    No, you are not allowed to use this.  Just pass 0.
 * @param[in]  func     A callback function.
 * @param[in]  arg      Extra argument passed to func.
 * @return     Return value of `func`.
 */
int ruby_brace_glob(const char *pattern, int flags, ruby_glob_func *func, VALUE arg);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_GLOB_H */
ruby/internal/stdckdint.h000064400000005265151732674220011522 0ustar00#ifndef RBIMPL_STDCKDINT_H                           /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_STDCKDINT_H
/**
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      C23 shim for <stdckdint.h>
 */
#include "ruby/internal/config.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/has/builtin.h"
#include "ruby/internal/stdbool.h"

#ifdef __has_include
# if __has_include(<stdckdint.h>)
#  /* Conforming C23 situation; e.g. recent clang */
#  define RBIMPL_HAVE_STDCKDINT_H
# endif
#endif

#ifdef HAVE_STDCKDINT_H
# /* Some OSes (most notably FreeBSD) have this file. */
# define RBIMPL_HAVE_STDCKDINT_H
#endif

#ifdef __cplusplus
# /* It seems OS/Compiler provided stdckdint.h tend not support C++ yet.
#  * Situations could improve someday but in a meantime let us work around.
#  */
# undef RBIMPL_HAVE_STDCKDINT_H
#endif

#ifdef RBIMPL_HAVE_STDCKDINT_H
# /* Take that. */
# include <stdckdint.h>

#elif RBIMPL_HAS_BUILTIN(__builtin_add_overflow)
# define ckd_add(x, y, z) RBIMPL_CAST((bool)__builtin_add_overflow((y), (z), (x)))
# define ckd_sub(x, y, z) RBIMPL_CAST((bool)__builtin_sub_overflow((y), (z), (x)))
# define ckd_mul(x, y, z) RBIMPL_CAST((bool)__builtin_mul_overflow((y), (z), (x)))
# define __STDC_VERSION_STDCKDINT_H__ 202311L

#/* elif defined(__cplusplus) */
#/* :TODO: if we assume C++11 we can use `<type_traits>` to implement them. */

#else
# /* intentionally leave them undefined */
# /* to make `#ifdef ckd_add` etc. work as intended. */
# undef ckd_add
# undef ckd_sub
# undef ckd_mul
# undef __STDC_VERSION_STDCKDINT_H__
#endif

#endif /* RBIMPL_STDCKDINT_H */
ruby/internal/variable.h000064400000027473151732674220011325 0ustar00#ifndef RBIMPL_VARIABLE_H                            /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_VARIABLE_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Declares rb_define_variable().
 */
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/noreturn.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/**
 * Type that represents a global variable getter function.
 *
 * @param[in]      id    The variable name.
 * @param[in,out]  data  Where the value is stored.
 * @return         The value that shall be visible from Ruby.
 */
typedef VALUE rb_gvar_getter_t(ID id, VALUE *data);

/**
 * Type that represents a global variable setter function.
 *
 * @param[in]      val   The value to set.
 * @param[in]      id    The variable name.
 * @param[in,out]  data  Where the value is to be stored.
 */
typedef void  rb_gvar_setter_t(VALUE val, ID id, VALUE *data);

/**
 * Type that represents a global variable marker function.
 *
 * @param[in]  var  Where the value is to be stored.
 */
typedef void  rb_gvar_marker_t(VALUE *var);

/**
 * @deprecated
 *
 * This function has no actual usage (than in ruby itself).  Please ignore.  It
 * was a bad idea to expose this function  to 3rd parties, but we can no longer
 * delete it.
 */
rb_gvar_getter_t rb_gvar_undef_getter;

/**
 * @deprecated
 *
 * This function has no actual usage (than in ruby itself).  Please ignore.  It
 * was a bad idea to expose this function  to 3rd parties, but we can no longer
 * delete it.
 */
rb_gvar_setter_t rb_gvar_undef_setter;

/**
 * @deprecated
 *
 * This function has no actual usage (than in ruby itself).  Please ignore.  It
 * was a bad idea to expose this function  to 3rd parties, but we can no longer
 * delete it.
 */
rb_gvar_marker_t rb_gvar_undef_marker;

/**
 * This is the getter function that  backs global variables defined from a ruby
 * script.  Extension  libraries can use this  if its global variable  needs no
 * custom logic.
 */
rb_gvar_getter_t rb_gvar_val_getter;

/**
 * This is the setter function that  backs global variables defined from a ruby
 * script.  Extension  libraries can use this  if its global variable  needs no
 * custom logic.
 */
rb_gvar_setter_t rb_gvar_val_setter;

/**
 * This is the setter function that  backs global variables defined from a ruby
 * script.  Extension  libraries can use this  if its global variable  needs no
 * custom logic.
 */
rb_gvar_marker_t rb_gvar_val_marker;

/**
 * @deprecated
 *
 * This function has no actual usage (than in ruby itself).  Please ignore.  It
 * was a bad idea to expose this function  to 3rd parties, but we can no longer
 * delete it.
 */
rb_gvar_getter_t rb_gvar_var_getter;

/**
 * @deprecated
 *
 * This function has no actual usage (than in ruby itself).  Please ignore.  It
 * was a bad idea to expose this function  to 3rd parties, but we can no longer
 * delete it.
 */
rb_gvar_setter_t rb_gvar_var_setter;

/**
 * @deprecated
 *
 * This function has no actual usage (than in ruby itself).  Please ignore.  It
 * was a bad idea to expose this function  to 3rd parties, but we can no longer
 * delete it.
 */
rb_gvar_marker_t rb_gvar_var_marker;

RBIMPL_ATTR_NORETURN()
/**
 * This function just raises ::rb_eNameError.   Handy when you want to prohibit
 * a global variable from being squashed by someone.
 */
rb_gvar_setter_t rb_gvar_readonly_setter;

RBIMPL_ATTR_NONNULL(())
/**
 * "Shares" a global variable between Ruby and C.  Normally a Ruby-level global
 * variable  is stored  somewhere deep  inside of  the interpreter's  execution
 * context, but this way you can explicitly specify its storage.
 *
 * ```CXX
 * static VALUE foo;
 *
 * extern "C" void
 * init_Foo(void)
 * {
 *     foo = rb_eval_string("...");
 *     rb_define_variable("$foo", &foo);
 * }
 * ```
 *
 * In the above  example a Ruby global  variable named `$foo` is stored  in a C
 * global variable named `foo`.
 *
 * @param[in]  name  Variable (Ruby side).
 * @param[in]  var   Variable (C side).
 * @post       Ruby level  global variable named  `name` is defined  if absent,
 *             and its storage is set to `var`.
 */
void rb_define_variable(const char *name, VALUE *var);

RBIMPL_ATTR_NONNULL((1))
/**
 * Defines a global variable that  is purely function-backended.  By using this
 * API a programmer can define a  global variable that dynamically changes from
 * time to time.
 *
 * @param[in]  name   Variable name, in C's string.
 * @param[in]  getter A getter function.
 * @param[in]  setter A setter function.
 * @post       Ruby level global variable named `name` is defined if absent.
 *
 * @internal
 *
 * @shyouhei doesn't know if this is an  Easter egg or an official feature, but
 * you can pass  0 to the third argument (setter).   That effectively nullifies
 * any efforts to write to the defining global variable.
 */
void rb_define_virtual_variable(const char *name, rb_gvar_getter_t *getter, rb_gvar_setter_t *setter);

RBIMPL_ATTR_NONNULL((1))
/**
 * Identical to  rb_define_virtual_variable(), but can also  specify a storage.
 * A programmer can use the storage for e.g.  memoisation, storing intermediate
 * computation result, etc.
 *
 * Also you can pass 0 to this function, unlike other variants:
 *
 *   - When getter is 0 ::rb_gvar_var_getter is used instead.
 *   - When setter is 0 ::rb_gvar_var_setter is used instead.
 *   - When data is 0, you must  specify a non-zero setter function.  Otherwise
 *     ::rb_gvar_var_setter tries to write to `*NULL`, and just causes SEGV.
 *
 * @param[in]  name   Variable name, in C's string.
 * @param[in]  var    Variable storage.
 * @param[in]  getter A getter function.
 * @param[in]  setter A setter function.
 * @post       Ruby level global variable named `name` is defined if absent.
 */
void rb_define_hooked_variable(const char *name, VALUE *var, rb_gvar_getter_t *getter, rb_gvar_setter_t *setter);

RBIMPL_ATTR_NONNULL(())
/**
 * Identical to rb_define_variable(), except it does not allow Ruby programs to
 * assign values  to such  global variable.   C codes can  still set  values at
 * will.   This  could be  handy  for  you  when implementing  an  `errno`-like
 * experience, where  a method updates a  read-only global variable as  a side-
 * effect.
 *
 * @param[in]  name  Variable (Ruby side).
 * @param[in]  var   Variable (C side).
 * @post       Ruby level  global variable named  `name` is defined  if absent,
 *             and its storage is set to `var`.
 */
void rb_define_readonly_variable(const char *name, const VALUE *var);

RBIMPL_ATTR_NONNULL(())
/**
 * Defines a Ruby level constant under a namespace.
 *
 * @param[out]  klass            Namespace for the constant to reside.
 * @param[in]   name             Name of the constant.
 * @param[in]   val              Value of the constant.
 * @exception   rb_eTypeError    `klass` is not a kind of ::rb_cModule.
 * @exception   rb_eFrozenError  `klass` is frozen.
 * @post        Ruby level constant `klass::name` is defined to be `val`.
 * @note        This API  does not stop  you from  defining a constant  that is
 *              unable  to   reach  from   ruby  (like  for   instance  passing
 *              non-capital letter to `name`).
 * @note        This API  does not  stop you from  overwriting a  constant that
 *              already exist.
 *
 * @internal
 *
 * Above description is in fact inaccurate.  This API interfaces with Ractors.
 */
void rb_define_const(VALUE klass, const char *name, VALUE val);

RBIMPL_ATTR_NONNULL(())
/**
 * Identical  to  rb_define_const(),  except   it  defines  that  of  "global",
 * i.e. toplevel constant.
 *
 * @param[in]   name             Name of the constant.
 * @param[in]   val              Value of the constant.
 * @exception   rb_eFrozenError  ::rb_cObject is frozen.
 * @post        Ruby level constant \::name is defined to be `val`.
 * @note        This API  does not stop  you from  defining a constant  that is
 *              unable  to   reach  from   ruby  (like  for   instance  passing
 *              non-capital letter to `name`).
 * @note        This API  does not  stop you from  overwriting a  constant that
 *              already exist.
 */
void rb_define_global_const(const char *name, VALUE val);

RBIMPL_ATTR_NONNULL(())
/**
 * Asserts  that the  given  constant  is deprecated.   Attempt  to refer  such
 * constant will produce a warning.
 *
 * @param[in]  mod              Namespace of the target constant.
 * @param[in]  name             Name of the constant.
 * @exception  rb_eNameError    No such constant.
 * @exception  rb_eFrozenError  `mod` is frozen.
 * @post       `name` under `mod` is deprecated.
 */
void rb_deprecate_constant(VALUE mod, const char *name);

RBIMPL_ATTR_NONNULL(())
/**
 * Assigns to a global variable.
 *
 * @param[in]  name  Target global variable.
 * @param[in]  val   Value to assign.
 * @return     Passed value.
 * @post       Ruby level  global variable named  `name` is defined  if absent,
 *             whose value is set to `val`.
 *
 * @internal
 *
 * Above  description  is  in  fact   inaccurate.   This  API  interfaces  with
 * `set_trace_func`.
 */
VALUE rb_gv_set(const char *name, VALUE val);

RBIMPL_ATTR_NONNULL(())
/**
 * Obtains a global variable.
 *
 * @param[in]  name       Global variable to query.
 * @retval     RUBY_Qnil  The global variable does not exist.
 * @retval     otherwise  The value assigned to the global variable.
 *
 * @internal
 *
 * Unlike rb_gv_set(), there is no way to trace this function.
 */
VALUE rb_gv_get(const char *name);

RBIMPL_ATTR_NONNULL(())
/**
 * Obtains an instance variable.
 *
 * @param[in]  obj                Target object.
 * @param[in]  name               Target instance variable to query.
 * @exception  rb_eEncodingError  `name` is corrupt (contains Hanzi etc.).
 * @retval     RUBY_nil           No such instance variable.
 * @retval     otherwise          The value assigned to the instance variable.
 */
VALUE rb_iv_get(VALUE obj, const char *name);

RBIMPL_ATTR_NONNULL(())
/**
 * Assigns to an instance variable.
 *
 * @param[out]  obj                Target object.
 * @param[in]   name               Target instance variable.
 * @param[in]   val                Value to assign.
 * @exception   rb_eFrozenError    Can't modify `obj`.
 * @exception   rb_eArgError       `obj` has too many instance variables.
 * @return      Passed value.
 * @post        An  instance variable  named  `name` is  defined  if absent  on
 *              `obj`, whose value is set to `val`.
 *
 * @internal
 *
 * This function does not stop you form creating an ASCII-incompatible instance
 * variable, but there is no way to get one because rb_iv_get raises exceptions
 * for such things.  This design seems broken...  But no idea why.
 */
VALUE rb_iv_set(VALUE obj, const char *name, VALUE val);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_VARIABLE_H */
ruby/internal/intern/cont.h000064400000026665151732674230012005 0ustar00#ifndef  RBIMPL_INTERN_CONT_H                        /*-*-C++-*-vi:se ft=cpp:*/
#define  RBIMPL_INTERN_CONT_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Public APIs related to rb_cFiber.
 */
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/internal/iterator.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/* cont.c */

/**
 * Creates a Fiber instance from a C-backended block.
 *
 * @param[in]  func          A function, to become the fiber's body.
 * @param[in]  callback_obj  Passed as-is to `func`.
 * @return     An allocated  new instance  of rb_cFiber, which  is ready  to be
 *             "resume"d.
 */
VALUE rb_fiber_new(rb_block_call_func_t func, VALUE callback_obj);

/**
 * Creates a Fiber instance from a C-backended block with the specified
 * storage.
 *
 * If the given storage is Qundef or Qtrue, this function is equivalent to
 * rb_fiber_new() which inherits storage from the current fiber.
 *
 * Specifying Qtrue is experimental and may be changed in the future.
 *
 * If the given storage is Qnil, this function will lazy initialize the
 * internal storage which starts of empty (without any inheritance).
 *
 * Otherwise, the given storage is used as the internal storage.
 *
 * @param[in]  func          A function, to become the fiber's body.
 * @param[in]  callback_obj  Passed as-is to `func`.
 * @param[in]  storage       The way to set up the storage for the fiber.
 * @return     An allocated  new instance  of rb_cFiber, which  is ready  to be
 *             "resume"d.
 */
VALUE rb_fiber_new_storage(rb_block_call_func_t func, VALUE callback_obj, VALUE storage);

/**
 * Queries  the fiber  which  is  calling this  function.   Any ruby  execution
 * context has its fiber, either explicitly or implicitly.
 *
 * @return  The current fiber.
 */
VALUE rb_fiber_current(void);

/**
 * Queries the  liveness of the  passed fiber.   "Alive" in this  context means
 * that  the fiber  can  still be  resumed.   Once  it reaches  is  its end  of
 * execution, this function returns ::RUBY_Qfalse.
 *
 * @param[in]  fiber        A target fiber.
 * @retval     RUBY_Qtrue   It is.
 * @retval     RUBY_Qfalse  It isn't.
 */
VALUE rb_fiber_alive_p(VALUE fiber);

/**
 * Queries if an object is a fiber.
 *
 * @param[in]  obj          Arbitrary ruby object.
 * @retval     RUBY_Qtrue   It is.
 * @retval     RUBY_Qfalse  It isn't.
 */
VALUE rb_obj_is_fiber(VALUE obj);

/**
 * Resumes the  execution of the passed  fiber, either from the  point at which
 * the last  rb_fiber_yield() was  called if  any, or at  the beginning  of the
 * fiber body if it is the first call to this function.
 *
 * Other arguments are passed into the fiber's body, either as return values of
 * rb_fiber_yield() in case it switches to  there, or as the block parameter of
 * the fiber body if it switches to the beginning of the fiber.
 *
 * The return  value of this  function is either  the value passed  to previous
 * rb_fiber_yield() call, or  the ultimate evaluated value of  the entire fiber
 * body if the execution reaches the end of it.
 *
 * When an exception happens inside of a fiber it propagates to this function.
 *
 * ```ruby
 * f = Fiber.new do |i|
 *   puts "<x> =>> #{i}"
 *   puts "<y> <-- #{i + 1}"
 *   j = Fiber.yield(i + 1)
 *   puts "<z> =>> #{j}"
 *   puts "<w> <-- #{j + 1}"
 *   next j + 1
 * end
 *
 * puts "[a] <-- 1"
 * p = f.resume(1)
 * puts "[b] =>> #{p}"
 * puts "[c] <-- #{p + 1}"
 * q = f.resume(p + 1)
 * puts "[d] =>> #{q}"
 * ```
 *
 * Above program executes in `[a] <x> <y> [b] [c] <z> <w> [d]`.
 *
 * @param[out]  fiber          The fiber to resume.
 * @param[in]   argc            Number of objects of `argv`.
 * @param[in]   argv            Passed (somehow) to `fiber`.
 * @exception   rb_eFiberError  `fib` is terminated etc.
 * @exception   rb_eException   Any exceptions happen in `fiber`.
 * @return      (See above)
 * @note        This function _does_ return.
 *
 * @internal
 *
 * @shyouhei  expected  this function  to  raise  ::rb_eFrozenError for  frozen
 * fibers but it doesn't in practice.  Intentional or ...?
 */
VALUE rb_fiber_resume(VALUE fiber, int argc, const VALUE *argv);

/**
 * Identical to  rb_fiber_resume(), except  you can specify  how to  handle the
 * last element of the given array.
 *
 * @param[out]  fiber           The fiber to resume.
 * @param[in]   argc            Number of objects of `argv`.
 * @param[in]   argv            Passed (somehow) to `fiber`.
 * @param[in]   kw_splat        Handling of keyword parameters:
 *   - RB_NO_KEYWORDS           `argv`'s last is not a keyword argument.
 *   - RB_PASS_KEYWORDS         `argv`'s last is a keyword argument.
 *   - RB_PASS_CALLED_KEYWORDS  it depends if there is a passed block.
 * @exception   rb_eFiberError  `fiber` is terminated etc.
 * @exception   rb_eException   Any exceptions happen in `fiber`.
 * @return      Either what was yielded or the last value of the fiber body.
 */
VALUE rb_fiber_resume_kw(VALUE fiber, int argc, const VALUE *argv, int kw_splat);

/**
 * Yields the  control back to the  point where the current  fiber was resumed.
 * The passed  objects would  be the return  value of  rb_fiber_resume().  This
 * fiber then suspends its execution until next time it is resumed.
 *
 * This function can  also raise arbitrary exceptions injected  from outside of
 * the fiber using rb_fiber_raise().
 *
 * ```ruby
 * exc = Class.new Exception
 *
 * f = Fiber.new do
 *   Fiber.yield
 * rescue exc => e
 *   puts e.message
 * end
 *
 * f.resume
 * f.raise exc, "Hi!"
 * ```
 *
 * @param[in]  argc           Number of objects of `argv`.
 * @param[in]  argv           Passed to rb_fiber_resume().
 * @exception  rb_eException  (See above)
 * @return     (See rb_fiber_resume() for details)
 */
VALUE rb_fiber_yield(int argc, const VALUE *argv);

/**
 * Identical to rb_fiber_yield(), except you can specify how to handle the last
 * element of the given array.
 *
 * @param[in]  argc            Number of objects of `argv`.
 * @param[in]  argv            Passed to rb_fiber_resume().
 * @param[in]  kw_splat        Handling of keyword parameters:
 *   - RB_NO_KEYWORDS           `argv`'s last is not a keyword argument.
 *   - RB_PASS_KEYWORDS         `argv`'s last is a keyword argument.
 *   - RB_PASS_CALLED_KEYWORDS  it depends if there is a passed block.
 * @exception  rb_eException   What was raised using `Fiber#raise`.
 * @return     (See rb_fiber_resume() for details)
 */
VALUE rb_fiber_yield_kw(int argc, const VALUE *argv, int kw_splat);

/**
 * Transfers control to  another fiber, resuming it from where  it last stopped
 * or starting  it if  it was not  resumed before.  The  calling fiber  will be
 * suspended much like in a call to rb_fiber_yield().
 *
 * The fiber  which receives  the transfer  call treats it  much like  a resume
 * call.  Arguments passed to transfer are treated like those passed to resume.
 *
 * The two style of control passing to and from fiber (one is rb_fiber_resume()
 * and  rb_fiber_yield(), another  is  rb_fiber_transfer() to  and from  fiber)
 * can't be freely mixed.
 *
 *   - If the  Fiber's lifecycle had  started with  transfer, it will  never be
 *     able to  yield or be  resumed control  passing, only finish  or transfer
 *     back.   (It  still can  resume  other  fibers  that  are allowed  to  be
 *     resumed.)
 *
 *   - If  the Fiber's  lifecycle  had started  with resume,  it  can yield  or
 *     transfer to  another Fiber, but  can receive  control back only  the way
 *     compatible with  the way it  was given away:  if it had  transferred, it
 *     only can  be transferred  back, and if  it had yielded,  it only  can be
 *     resumed back.  After that, it again can transfer or yield.
 *
 * If those rules are broken, rb_eFiberError is raised.
 *
 * For an  individual Fiber design,  yield/resume is  easier to use  (the Fiber
 * just gives away control,  it doesn't need to think about  who the control is
 * given to),  while transfer is more  flexible for complex cases,  allowing to
 * build arbitrary graphs of Fibers dependent on each other.
 *
 * @param[out]  fiber           Explicit control destination.
 * @param[in]   argc            Number of objects of `argv`.
 * @param[in]   argv            Passed to rb_fiber_resume().
 * @exception   rb_eFiberError  (See above)
 * @exception   rb_eException   What was raised using `Fiber#raise`.
 * @return      (See rb_fiber_resume() for details)
 */
VALUE rb_fiber_transfer(VALUE fiber, int argc, const VALUE *argv);

/**
 * Identical to rb_fiber_transfer(),  except you can specify how  to handle the
 * last element of the given array.
 *
 * @param[out]  fiber           Explicit control destination.
 * @param[in]   argc            Number of objects of `argv`.
 * @param[in]   argv            Passed to rb_fiber_resume().
 * @param[in]   kw_splat        Handling of keyword parameters:
 *   - RB_NO_KEYWORDS           `argv`'s last is not a keyword argument.
 *   - RB_PASS_KEYWORDS         `argv`'s last is a keyword argument.
 *   - RB_PASS_CALLED_KEYWORDS  it depends if there is a passed block.
 * @exception   rb_eFiberError  (See above)
 * @exception   rb_eException   What was raised using `Fiber#raise`.
 * @return      (See rb_fiber_resume() for details)
 */
VALUE rb_fiber_transfer_kw(VALUE fiber, int argc, const VALUE *argv, int kw_splat);

/**
 * Identical to rb_fiber_resume()  but instead of resuming  normal execution of
 * the passed fiber, it  raises the given exception in it.   From inside of the
 * fiber this would be seen as if rb_fiber_yield() raised.
 *
 * This function  does return in case  the passed fiber gracefully  handled the
 * passed exception.  But  if it does not, the raised  exception propagates out
 * of the passed fiber; this function then does not return.
 *
 * Parameters are passed to rb_make_exception()  to create an exception object.
 * See its document for what are allowed here.
 *
 * It is  a failure to  call this function against  a fiber which  is resuming,
 * have never run yet, or has already finished running.
 *
 * @param[out]  fiber           Where exception is raised.
 * @param[in]   argc            Passed as-is to rb_make_exception().
 * @param[in]   argv            Passed as-is to rb_make_exception().
 * @exception   rb_eFiberError  `fiber` is terminated etc.
 * @return      (See rb_fiber_resume() for details)
 */
VALUE rb_fiber_raise(VALUE fiber, int argc, const VALUE *argv);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERN_CONT_H */
ruby/internal/intern/compar.h000064400000005015151732674230012305 0ustar00#ifndef  RBIMPL_INTERN_COMPAR_H                      /*-*-C++-*-vi:se ft=cpp:*/
#define  RBIMPL_INTERN_COMPAR_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Public APIs related to ::rb_mComparable.
 */
#include "ruby/internal/attr/cold.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/* bignum.c */

/**
 * Canonicalises the passed `val`, which is the return value of `a <=> b`, into
 * C's `{-1, 0, 1}`.  This can be  handy when you implement a callback function
 * to pass to `qsort(3)` etc.
 *
 * @param[in]  val           Return value of a space ship operator.
 * @param[in]  a             Comparison LHS.
 * @param[in]  b             Comparison RHS.
 * @exception  rb_eArgError  `a` and `b` are not comparable each other.
 * @retval     -1            `val` is less than zero.
 * @retval     0             `val` is equal to zero.
 * @retval     1             `val` is greater than zero.
 */
int rb_cmpint(VALUE val, VALUE a, VALUE b);

/* compar.c */

RBIMPL_ATTR_COLD()
RBIMPL_ATTR_NORETURN()
/**
 * Raises "comparison failed" error.
 *
 * @param[in]  a             Comparison LHS.
 * @param[in]  b             Comparison RHS.
 * @exception  rb_eArgError  `a` and `b` are not comparable each other.
 */
void rb_cmperr(VALUE a, VALUE b);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERN_COMPAR_H */
ruby/internal/intern/io.h000064400000064420151732674230011440 0ustar00#ifndef RBIMPL_INTERN_IO_H                           /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_IO_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Public APIs related to ::rb_cIO.
 */
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/* io.c */

/**
 * @private
 *
 * @deprecated  This macro once was a thing in the old days, but makes no sense
 *              any  longer today.   Exists  here  for backwards  compatibility
 *              only.  You can safely forget about it.
 */
#define rb_defout rb_stdout

/* string.c */ /* ...why? moved in commit de7161526014b781468cea5d84411e23be */

/**
 * The field  separator character for  inputs, or  the `$;`.  This  affects how
 * `String#split` works.   You can set this  via the `-F` command  line option.
 * You can  also assign arbitrary  ruby objects programmatically, but  it makes
 * best sense for you to assign a regular expression here.
 *
 * @internal
 *
 * Tidbit: "fs" comes from AWK's `FS` variable.
 */
RUBY_EXTERN VALUE rb_fs;

/* io.c */ /* ...why? given rb_fs is in string.c? */

/**
 * The field  separator character for outputs,  or the `$,`.  This  affects how
 * `Array#join` works.
 *
 * @deprecated Assigning  anything other than  ::RUBY_Qnil to this  variable is
 *             deprecated.
 */
RUBY_EXTERN VALUE rb_output_fs;

/**
 * The record  separator character for inputs,  or the `$/`.  This  affects how
 * `IO#gets` works.  You can set this via the `-0` command line option.
 *
 * @deprecated Assigning  anything other than  ::RUBY_Qnil to this  variable is
 *             deprecated.
 *
 * @internal
 *
 * Tidbit: "rs" comes from AWK's `RS` variable.
 */
RUBY_EXTERN VALUE rb_rs;

/**
 * This is the default  value of ::rb_rs, i.e. `"\n"`.  It  seems it has always
 * been just a newline string since the beginning.  Not sure why C codes has to
 * use this, given there is no way for ruby programs to interface.
 *
 * Also it has not been deprecated for unknown reasons.
 */
RUBY_EXTERN VALUE rb_default_rs;

/**
 * The record separator  character for outputs, or the `$\`.   This affects how
 * `IO#print` works.
 *
 * @deprecated Assigning  anything other than  ::RUBY_Qnil to this  variable is
 *             deprecated.
 */
RUBY_EXTERN VALUE rb_output_rs;

/**
 * Writes the given string to the given IO.
 *
 * @param[out]  io                   An IO, opened for writing.
 * @param[in]   str                  A String-like object to write to `io`.
 * @exception   rb_eIOError          `io` isn't opened for writing.
 * @exception   rb_eFrozenError      `io` is frozen.
 * @exception   rb_eTypeError        No conversion from `str` to String.
 * @exception   rb_eSystemCallError  `write(2)` failed for some reason.
 * @return      The number of bytes written to the `io`.
 * @post        `str` (up to the length of return value) is written to `io`.
 * @note        This function blocks.
 * @note        Partial write is a thing.  It must be at least questionable not
 *              to check the return value.
 *
 * @internal
 *
 * Above description is  in fact inaccurate.  This function  can take arbitrary
 * objects, and  calls their  `write` method.   What is  written above  in fact
 * describes how `IO#write` works.  You can  pass StringIO etc. here, and would
 * work completely differently.
 */
VALUE rb_io_write(VALUE io, VALUE str);

/**
 * Reads a "line" from  the given IO.  A line here means  a chunk of characters
 * which is terminated by either `"\n"` or an EOF.
 *
 * @param[in,out]  io               An IO, opened for reading.
 * @exception      rb_eIOError      `io` isn't opened for reading.
 * @exception      rb_eFrozenError  `io` is frozen.
 * @retval         RUBY_Qnil        `io` is at EOF.
 * @retval         otherwise        An instance of ::rb_cString.
 * @post           `io` is read.
 * @note           Unlike `IO#gets` it doesn't set `$_`.
 * @note           Unlike `IO#gets` it doesn't consider `$/`.
 */
VALUE rb_io_gets(VALUE io);

/**
 * Reads a byte from the given IO.
 *
 * @note           In Ruby a "byte" always means  an 8 bit integer ranging from
 *                 0 to 255 inclusive.
 * @param[in,out]  io               An IO, opened for reading.
 * @exception      rb_eIOError      `io` is not opened for reading.
 * @exception      rb_eFrozenError  `io` is frozen.
 * @retval         RUBY_Qnil        `io` is at EOF.
 * @retval         otherwise        An instance of ::rb_cInteger.
 * @post           `io` is read.
 *
 * @internal
 *
 * Of course  there was a  function called  `rb_io_getc()`.  It was  removed in
 * commit a25fbe3b3e531bbe479f344af24eaf9d2eeae6ea.
 */
VALUE rb_io_getbyte(VALUE io);

/**
 * "Unget"s a  string.  This function  pushes back  the passed string  onto the
 * passed IO,  such that  a subsequent  buffered read will  return it.   If the
 * passed content  is in  fact an  integer, a single  character string  of that
 * codepoint of the encoding of the IO will be pushed back instead.
 *
 * It  might be  counter-intuitive but  this  function can  push back  multiple
 * characters at  once.  Also this function  can be called multiple  times on a
 * same IO.   Also a  "character" can be  wider than a  byte, depending  on the
 * encoding of the IO.
 *
 * @param[out]  io               An IO, opened for reading.
 * @param[in]   c                Either a String, or an Integer.
 * @exception   rb_eIOError      `io` is not opened for reading.
 * @exception   rb_eFrozenError  `io` is frozen.
 * @exception   rb_eTypeError    No conversion from `c` to ::rb_cString.
 * @return      Always returns ::RUBY_Qnil.
 *
 * @internal
 *
 * Why there is ungetc, given there is no getc?
 */
VALUE rb_io_ungetc(VALUE io, VALUE c);

/**
 * Identical  to rb_io_ungetc(),  except it  doesn't take  the encoding  of the
 * passed IO into account.  When an integer is passed, it just casts that value
 * to C's `unsigned char`, and pushes that back.
 *
 * @param[out]  io               An IO, opened for reading.
 * @param[in]   b                Either a String, or an Integer.
 * @exception   rb_eIOError      `io` is not opened for reading.
 * @exception   rb_eFrozenError  `io` is frozen.
 * @exception   rb_eTypeError    No conversion from `b` to ::rb_cString.
 * @return      Always returns ::RUBY_Qnil.
 */
VALUE rb_io_ungetbyte(VALUE io, VALUE b);

/**
 * Closes the IO.   Any buffered contents are flushed to  the operating system.
 * Any future operations against the IO would raise ::rb_eIOError.  In case the
 * io was created using `IO.popen`, it also sets the `$?`.
 *
 * @param[out]  io  Target IO to close.
 * @return      Always returns ::RUBY_Qnil.
 * @post        `$?` is set in case IO is a pipe.
 * @post        No operations are possible against `io` any further.
 * @note        This can block to flush the contents.
 * @note        This  can  wake other  threads  up,  especially those  who  are
 *              `select()`-ing the passed IO.
 * @note        Multiple invocations  of this function  over the same  IO again
 *              and again is not an error, since Ruby 2.3.
 *
 * @internal
 *
 * You can close a frozen IO... Is this intentional?
 */
VALUE rb_io_close(VALUE io);

/**
 * Flushes any buffered  data within the passed IO to  the underlying operating
 * system.
 *
 * @param[out]  io                   Target IO to flush.
 * @exception   rb_eIOError          `io` is closed.
 * @exception   rb_eFrozenError      `io` is frozen.
 * @exception   rb_eSystemCallError  `write(2)` failed for some reason.
 * @return      The passed `io`.
 * @post        `io`'s buffers are empty.
 * @note        This operation also discards the read buffer.  Should basically
 *              be harmless, but in an esoteric situation like when user pushed
 *              something  different from  what was  read using  `ungetc`, this
 *              operation in fact changes the behaviour of the `io`.
 * @note        Buffering is  difficult.  This operation flushes  the data from
 *              our userspace to  the kernel, but that doesn't  always mean you
 *              can expect them stored persistently onto your hard drive.
 */
VALUE rb_io_flush(VALUE io);

/**
 * Queries if the passed IO is at the end of file.  "The end of file" here mans
 * that there are  no more data to  read.  This function blocks  until the read
 * buffer is filled in, and if that operation reached the end of file, it still
 * returns  ::RUBY_Qfalse (because  there are  data  yet in  that buffer).   It
 * returns ::RUBY_Qtrue once after the buffer is cleared.
 *
 * @param[in,out]  io              Target io to query.
 * @exception      rb_eIOError     `io` is not opened for reading.
 * @exception      rb_eFrozenError  `io` is frozen.
 * @retval         RUBY_Qfalse     There are things yet to be read.
 * @retval         RUBY_Qtrue      "The end of file" situation.
 */
VALUE rb_io_eof(VALUE io);

/**
 * Sets the binmode.  This operation  nullifies the effect of textmode (newline
 * conversion from  `"\r\n"` to `"\n"`  or vice  versa).  Note that  it doesn't
 * stop character encodings conversions.  For instance an IO created using:
 *
 * ```ruby
 * File.open(
 *   "/dev/urandom",
 *   textmode: true,
 *   external_encoding: Encoding::GB18030,
 *   internal_encoding: Encoding::Windows_31J)
 * ```
 *
 * has both  newline and character  conversions.  If you  pass such IO  to this
 * function, only  the `textmode:true` part  is cancelled.  Texts  read through
 * the IO would still  be encoded in Windows-31J; texts written  to the IO will
 * be encoded in GB18030.
 *
 * @param[out]  io               Target IO to modify.
 * @exception   rb_eFrozenError  `io` is frozen.
 * @return      The passed `io`.
 * @post        `io` is in binmode.
 * @note        There is no equivalent operation in Ruby.  You can do this only
 *              in C.
 */
VALUE rb_io_binmode(VALUE io);

/**
 * Forces no conversions be applied  to the passed IO.  Unlike rb_io_binmode(),
 * this cancels any  newline conversions as well as  encoding conversions.  Any
 * texts read/written through the IO will be the verbatim binary contents.
 *
 * @param[out]  io               Target IO to modify.
 * @exception   rb_eFrozenError  `io` is frozen.
 * @return      The passed `io`.
 * @post        `io` is in binmode.  Both external/internal encoding are set to
 *              rb_ascii8bit_encoding().
 * @note        This is the implementation of `IO#binmode`.
 */
VALUE rb_io_ascii8bit_binmode(VALUE io);

/**
 * Identical to rb_io_write(), except it always returns the passed IO.
 *
 * @param[out]  io                   An IO, opened for writing.
 * @param[in]   str                  A String-like object to write to `io`.
 * @exception   rb_eIOError          `io` isn't opened for writing.
 * @exception   rb_eFrozenError      `io` is frozen.
 * @exception   rb_eTypeError        No conversion from `str` to String.
 * @exception   rb_eSystemCallError  `write(2)` failed.
 * @return      The passed `io`.
 * @post        `str` is written to `io`.
 * @note        This function blocks.
 *
 * @internal
 *
 * As rb_io_write(), above description is a fake.
 */
VALUE rb_io_addstr(VALUE io, VALUE str);

/**
 * This is a rb_f_sprintf() + rb_io_write() combo.
 *
 * @param[in]   argc                 Number of objects of `argv`.
 * @param[in]   argv                 A format string followed by its arguments.
 * @param[out]  io                   An IO, opened for writing.
 * @exception   rb_eIOError          `io` isn't opened for writing.
 * @exception   rb_eFrozenError      `io` is frozen.
 * @exception   rb_eTypeError        No conversion from `str` to String.
 * @exception   rb_eSystemCallError  `write(2)` failed.
 * @return      Always returns ::RUBY_Qnil.
 * @post        `argv` is formatted, then written to `io`.
 * @note        This function blocks.
 *
 * @internal
 *
 * As rb_io_write(), above descriptions include fakes.
 */
VALUE rb_io_printf(int argc, const VALUE *argv, VALUE io);

/**
 * Iterates  over the  passed array  to apply  rb_io_write() individually.   If
 * there  is  `$,`,  this  function  inserts  the  string  in  middle  of  each
 * iterations.  If there is `$\`, this  function appends the string at the end.
 * If the array is empty, this function outputs `$_`.
 *
 * @param[in]   argc                 Number of objects of `argv`.
 * @param[in]   argv                 An array of strings to display.
 * @param[out]  io                   An IO, opened for writing.
 * @exception   rb_eIOError          `io` isn't opened for writing.
 * @exception   rb_eFrozenError      `io` is frozen.
 * @exception   rb_eTypeError        No conversion from `str` to String.
 * @exception   rb_eSystemCallError  `write(2)` failed.
 * @return      Always returns ::RUBY_Qnil.
 * @post        `argv` is written to `io`.
 * @note        This function blocks.
 * @note        This function calls rb_io_write() multiple times.  Which means,
 *              it is not  an atomic operation.  Outputs  from multiple threads
 *              can interleave.
 *
 * @internal
 *
 * As rb_io_write(), above descriptions include fakes.
 */
VALUE rb_io_print(int argc, const VALUE *argv, VALUE io);

/**
 * Iterates over the passed array  to apply rb_io_write() individually.  Unlike
 * rb_io_print(), this  function prints  a newline per  each element.   It also
 * flattens   the   passed   array   (OTOH  rb_io_print()   just   resorts   to
 * rb_ary_to_s()).
 *
 * @param[in]   argc                 Number of objects of `argv`.
 * @param[in]   argv                 An array of strings to display.
 * @param[out]  io                   An IO, opened for writing.
 * @exception   rb_eIOError          `io` isn't opened for writing.
 * @exception   rb_eFrozenError      `io` is frozen.
 * @exception   rb_eTypeError        No conversion from `str` to String.
 * @exception   rb_eSystemCallError  `write(2)` failed.
 * @return      Always returns ::RUBY_Qnil.
 * @post        `argv` is written to `io`.
 * @note        This function blocks.
 * @note        This function calls rb_io_write() multiple times.  Which means,
 *              it is not  an atomic operation.  Outputs  from multiple threads
 *              can interleave.
 *
 * @internal
 *
 * As rb_io_write(), above descriptions include fakes.
 */
VALUE rb_io_puts(int argc, const VALUE *argv, VALUE io);

/**
 * Creates  an IO  instance  whose backend  is the  given  file descriptor.   C
 * extension libraries sometimes have file descriptors created elsewhere (maybe
 * deep inside  of another shared  library), which  they want ruby  programs to
 * handle.  This function is handy for such situations.
 *
 * @param[in]  fd     Target file descriptor.
 * @param[in]  flags  Flags, e.g. `O_CREAT|O_EXCL`
 * @param[in]  path   The path of the file that backs `fd`, for diagnostics.
 * @return     An allocated instance of ::rb_cIO with the autoclose flag set.
 * @note       Leave `path` NULL if you don't know.
 */
VALUE rb_io_fdopen(int fd, int flags, const char *path);

RBIMPL_ATTR_NONNULL(())
/**
 * Opens a file located at the given path.
 *
 * `fmode` is a C string that represents the open mode.  It can be one of:
 *
 *   - `r` (means `O_RDONLY`),
 *   - `w` (means `O_WRONLY | O_TRUNC | O_CREAT`),
 *   - `a` (means `O_WRONLY | O_APPEND | O_CREAT`),
 *
 *  Followed by zero or more combinations of:
 *
 *   - `b` (means `_O_BINARY`),
 *   - `t` (means `_O_TEXT`),
 *   - `+` (means `O_RDWR`),
 *   - `x` (means `O_TRUNC`), or
 *   - `:[BOM|]enc[:enc]` (see below).
 *
 * This  last  one   specifies  external  (and  internal   if  any)  encodings,
 * respectively.  If  optional `BOM|` is  specified and the  specified external
 * encoding is capable of expressing  BOMs, opening file's contents' byte order
 * is auto-detected using the mechanism.
 *
 * So for instance, fmode of `"rt|BOM:utf-16le:utf-8"` specifies that...
 *
 *   - the physical representation of the contents of the file is in UTF-16;
 *   - honours its BOM but assumes little endian if absent;
 *   - opens the file for reading;
 *   - what is read is converted into UTF-8;
 *   - with newlines cannibalised to `\n`.
 *
 * @param[in]  fname                Path to open.
 * @param[in]  fmode                Mode specifier much like `fopen(3)`.
 * @exception  rb_eArgError         `fmode` contradicted (e.g. `"bt"`).
 * @exception  rb_eSystemCallError  `open(2)` failed for some reason.
 * @return     An instance of ::rb_cIO.
 */
VALUE rb_file_open(const char *fname, const char *fmode);

RBIMPL_ATTR_NONNULL(())
/**
 * Identical to rb_file_open(), except it takes the pathname as a Ruby's string
 * instead of C's.  In case the passed  Ruby object is a non-String it tries to
 * call `#to_path`.
 *
 * @param[in]  fname                Path to open.
 * @param[in]  fmode                Mode specifier much like `fopen(3)`.
 * @exception  rb_eTypeError        `fname` is not a String.
 * @exception  rb_eEncCompatError   `fname` is not ASCII-compatible.
 * @exception  rb_eArgError         `fmode` contradicted (e.g. `"bt"`).
 * @exception  rb_eSystemCallError  `open(2)` failed for some reason.
 * @return     An instance of ::rb_cIO.
 */
VALUE rb_file_open_str(VALUE fname, const char *fmode);

/**
 * Much like rb_io_gets(), but it reads  from the mysterious ARGF object.  ARGF
 * in this context can  be seen as a virtual IO  which concatenates contents of
 * the files passed to the process via the  ARGV, or just STDIN if there are no
 * such files.
 *
 * Unlike rb_io_gets() this function sets `$_`.
 *
 * @exception      rb_eFrozenError  ARGF resorts to STDIN but it is frozen.
 * @retval         RUBY_Qnil        ARGF is at EOF.
 * @retval         otherwise        An instance of ::rb_cString.
 * @post           ARGF is read.
 * @post           `$_` is set.
 *
 * @internal
 *
 * In reality, this function can call `ARGF.gets`.  Its redefinition can affect
 * the behaviour.
 *
 * Also, you can tamper ARGV on-the-fly in middle of ARGF usages:
 *
 * ```
 * gets                        # Reads the first file.
 * ARGV << '/proc/self/limits' # Adds a file.
 * gets                        # Can read from /proc/self/limits.
 * ```
 */
VALUE rb_gets(void);

RBIMPL_ATTR_NONNULL(())
/**
 * Writes the given error message to  somewhere applicable.  On Windows it goes
 * to the console.  On POSIX environments it goes to the standard error.
 *
 * @warning  IT IS  A BAD  IDEA to  use this function  form your  C extensions.
 *           It  is often  annoying when  GUI applications  write to  consoles;
 *           users  don't want  to look  at  there.  Programmers  also want  to
 *           control  the cause  of the  message  itself, like  by rescuing  an
 *           exception.  Just let ruby handle errors.  That must be better than
 *           going your own way.
 *
 * @param[in]  str  Error message to display.
 * @post       `str` is written to somewhere.
 *
 * @internal
 *
 * AFAIK this function  is listed here without marked  deprecated because there
 * are usages of this function in the wild.
 */
void rb_write_error(const char *str);

/**
 * Identical to  rb_write_error(), except  it additionally takes  the message's
 * length.  Necessary when you want to handle wide characters.
 *
 * @param[in]  str  Error message to display.
 * @param[in]  len  Length of `str`, in bytes.
 * @post       `str` is written to somewhere.
 */
void rb_write_error2(const char *str, long len);

/**
 * Closes everything.  In case of  POSIX environments, a child process inherits
 * its parent's opened  file descriptors.  Which is nowadays  considered as one
 * of the UNIX mistakes.  This function closes such inherited file descriptors.
 * When your C  extension needs to have  a child process, don't  forget to call
 * this from your child process right before exec.
 *
 * @param[in]  lowfd        Lower bound of FDs (you want STDIN to remain, no?).
 * @param[in]  maxhint      Hint of max FDs.
 * @param[in]  noclose_fds  A hash, whose keys are an allowlist.
 *
 * @internal
 *
 * As of writing, in  spite of the name, this function  does not actually close
 * anything.  It just  sets `FD_CLOEXEC` for everything and  let `execve(2)` to
 * atomically close them at once.  This is  because as far as we know there are
 * no such platform that has `fork(2)` but lacks `FD_CLOEXEC`.
 *
 * Because this function is expected to run  on a forked process it is entirely
 * async-signal-safe.
 */
void rb_close_before_exec(int lowfd, int maxhint, VALUE noclose_fds);

RBIMPL_ATTR_NONNULL(())
/**
 * This is an rb_cloexec_pipe() + rb_update_max_fd() combo.
 *
 * @param[out]  pipes  Return buffer.  Must at least hold 2 elements.
 * @retval      0      Successful creation of a pipe.
 * @retval      -1     Failure in underlying system call(s).
 * @post        `pipes` is filled with file descriptors.
 * @post        `errno` is set on failure.
 */
int rb_pipe(int *pipes);

/**
 * Queries if the  given FD is reserved or not.   Occasionally Ruby interpreter
 * opens files  for its own  purposes.  Use  this function to  prevent touching
 * such behind-the-scene descriptors.
 *
 * @param[in]  fd  Target file descriptor.
 * @retval     1   `fd` is reserved.
 * @retval     0   Otherwise.
 */
int rb_reserved_fd_p(int fd);

/** @alias{rb_reserved_fd_p} */
#define RB_RESERVED_FD_P(fd) rb_reserved_fd_p(fd)

/**
 * Opens a file  that closes on exec.   In case of POSIX  environments, a child
 * process inherits  its parent's opened  file descriptors.  Which  is nowadays
 * considered  as  one of  the  UNIX  mistakes.   This  function opens  a  file
 * descriptor  as  `open(2)` does,  but  additionally  instructs the  operating
 * system that we don't want it be seen from child processes.
 *
 * @param[in]  pathname   File path to open.
 * @param[in]  flags      Open mode, as in `open(2)`.
 * @param[in]  mode       File mode, in case of `O_CREAT`.
 * @retval     -1         `open(2)` failed for some reason.
 * @retval     otherwise  An allocated new file descriptor.
 * @note       This function does not raise.
 *
 * @internal
 *
 * Whether this function can take NULL or not depends on the underlying open(2)
 * system call implementation but @shyouhei doesn't think it's worth trying.
 */
int rb_cloexec_open(const char *pathname, int flags, mode_t mode);

/**
 * Identical to rb_cloexec_fcntl_dupfd(), except it implies minfd is 3.
 *
 * @param[in]  oldfd     File descriptor to duplicate.
 * @retval     -1        `dup2(2)` failed for some reason.
 * @retval     otherwise  An allocated new file descriptor.
 * @note       This function does not raise.
 */
int rb_cloexec_dup(int oldfd);

/**
 * Identical to rb_cloexec_dup(),  except you can specify  the destination file
 * descriptor.   If  the  destination  is  already  squatted  by  another  file
 * descriptor that gets silently closed without  any warnings.  (This is a spec
 * requested by POSIX.)
 *
 * @param[in]  oldfd  File descriptor to duplicate.
 * @param[in]  newfd  Return value destination.
 * @retval     -1     `dup2(2)` failed for some reason.
 * @retval     newfd  An allocated new file descriptor.
 * @post       Whatever sat at `newfd` gets closed with no notifications.
 * @post       In case return value is -1 `newfd` is untouched.
 * @note       This function does not raise.
 */
int rb_cloexec_dup2(int oldfd, int newfd);

RBIMPL_ATTR_NONNULL(())
/**
 * Opens a pipe with  closing on exec.  In case of  POSIX environments, a child
 * process inherits  its parent's opened  file descriptors.  Which  is nowadays
 * considered  as one  of the  UNIX mistakes.   This function  opens a  pipe as
 * `pipe(2)`  does, but  additionally instructs  the operating  system that  we
 * don't want the duplicated FDs be seen from child processes.
 *
 * @param[out]  fildes  Return buffer.  Must at least hold 2 elements.
 * @retval      0       Successful creation of a pipe.
 * @retval      -1      Failure in underlying system call(s).
 * @post        `pipes` is filled with file descriptors.
 * @post        `errno` is set on failure.
 */
int rb_cloexec_pipe(int fildes[2]);

/**
 * Duplicates  a file  descriptor  with  closing on  exec.   In  case of  POSIX
 * environments, a child process inherits its parent's opened file descriptors.
 * Which is  nowadays considered as  one of  the UNIX mistakes.   This function
 * duplicates a  file descriptor as  `dup(2)` does, but  additionally instructs
 * the operating system that we don't want the duplicated FD be seen from child
 * processes.
 *
 * @param[in]  fd         File descriptor to duplicate.
 * @param[in]  minfd      Minimum allowed FD to return.
 * @retval     -1         `dup(2)` failed for some reason.
 * @retval     otherwise  An allocated new file descriptor.
 * @note       This function does not raise.
 *
 * `minfd` is handy  when for instance STDERR  is closed but you  don't want to
 * use fd 2.
 */
int rb_cloexec_fcntl_dupfd(int fd, int minfd);

/**
 * Informs the interpreter that the passed fd can be the max.  This information
 * is used from rb_close_before_exec().
 *
 * @param[in]  fd  An open FD, which can be large.
 */
void rb_update_max_fd(int fd);

/**
 * Sets or clears  the close-on-exec flag of the passed  file descriptor to the
 * desired state.  STDIN,  STDOUT, STDERR are the  exceptional file descriptors
 * that shall  remain open.  All  others are  to be closed  on exec.  When  a C
 * extension  library  opens  a  file  descriptor  using  anything  other  than
 * rb_cloexec_open() etc., that file descriptor shall experience this function.
 *
 * @param[in]  fd  An open file descriptor.
 */
void rb_fd_fix_cloexec(int fd);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERN_IO_H */
ruby/internal/intern/complex.h000064400000020326151732674230012475 0ustar00#ifndef RBIMPL_INTERN_COMPLEX_H                      /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_COMPLEX_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Public APIs related to ::rb_cComplex.
 */
#include "ruby/internal/attr/deprecated.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/internal/arithmetic/long.h" /* INT2FIX is here. */

RBIMPL_SYMBOL_EXPORT_BEGIN()

/* complex.c */

/**
 * Identical  to rb_complex_new(),  except it  assumes both  arguments are  not
 * instances of ::rb_cComplex.  It is thus dangerous for extension libraries.
 *
 * @param[in]  real  Real part, in any numeric except Complex.
 * @param[in]  imag  Imaginary part, in any numeric except Complex.
 * @return     An instance of ::rb_cComplex whose value is `real + (imag)i`.
 */
VALUE rb_complex_raw(VALUE real, VALUE imag);

/**
 * Shorthand of  `x+0i`.  It  practically converts  `x` into  a Complex  of the
 * identical value.
 *
 * @param[in]  x  Any numeric except Complex.
 * @return     An instance of ::rb_cComplex, whose value is `x + 0i`.
 */
#define rb_complex_raw1(x) rb_complex_raw((x), INT2FIX(0))

/** @alias{rb_complex_raw} */
#define rb_complex_raw2(x,y) rb_complex_raw((x), (y))

/**
 * Constructs a Complex, by first multiplying the imaginary part with `1i` then
 * adds it  to the real part.   This definition doesn't need  both arguments be
 * real numbers.  It  can happily combine two instances  of ::rb_cComplex (with
 * rotating the latter one).
 *
 * @param[in]  real  An instance of ::rb_cNumeric.
 * @param[in]  imag  Another instance of ::rb_cNumeric.
 * @return     An instance of ::rb_cComplex whose value is `imag * 1i + real`.
 */
VALUE rb_complex_new(VALUE real, VALUE imag);

/**
 * Shorthand of  `x+0i`.  It  practically converts  `x` into  a Complex  of the
 * identical value.
 *
 * @param[in]  x  Any numeric value.
 * @return     An instance of ::rb_cComplex, whose value is `x + 0i`.
 */
#define rb_complex_new1(x) rb_complex_new((x), INT2FIX(0))

/** @alias{rb_complex_new} */
#define rb_complex_new2(x,y) rb_complex_new((x), (y))

/**
 * Constructs a  Complex using polar representations.   Unlike rb_complex_new()
 * it makes no sense to pass non-real instances to this function.
 *
 * @param[in]  abs  Magnitude, in any numeric except Complex.
 * @param[in]  arg  Angle, in radians, in any numeric except Complex.
 * @return     An  instance  of ::rb_cComplex  which  denotes  the given  polar
 *             coordinates.
 */
VALUE rb_complex_new_polar(VALUE abs, VALUE arg);

RBIMPL_ATTR_DEPRECATED(("by: rb_complex_new_polar"))
/** @old{rb_complex_new_polar} */
VALUE rb_complex_polar(VALUE abs, VALUE arg);

RBIMPL_ATTR_PURE()
/**
 * Queries the real part of the passed Complex.
 *
 * @param[in]  z  An instance of ::rb_cComplex.
 * @return     Its real part, which is an instance of ::rb_cNumeric.
 */
VALUE rb_complex_real(VALUE z);

RBIMPL_ATTR_PURE()
/**
 * Queries the imaginary part of the passed Complex.
 *
 * @param[in]  z  An instance of ::rb_cComplex.
 * @return     Its imaginary part, which is an instance of ::rb_cNumeric.
 */
VALUE rb_complex_imag(VALUE z);

/**
 * Performs addition of the passed two objects.
 *
 * @param[in]  x  An instance of ::rb_cComplex.
 * @param[in]  y  Arbitrary ruby object.
 * @return     What `x + y` evaluates to.
 * @see        rb_num_coerce_bin()
 */
VALUE rb_complex_plus(VALUE x, VALUE y);

/**
 * Performs subtraction of the passed two objects.
 *
 * @param[in]  x  An instance of ::rb_cComplex.
 * @param[in]  y  Arbitrary ruby object.
 * @return     What `x - y` evaluates to.
 * @see        rb_num_coerce_bin()
 */
VALUE rb_complex_minus(VALUE x, VALUE y);

/**
 * Performs multiplication of the passed two objects.
 *
 * @param[in]  x  An instance of ::rb_cComplex.
 * @param[in]  y  Arbitrary ruby object.
 * @return     What `x * y` evaluates to.
 * @see        rb_num_coerce_bin()
 */
VALUE rb_complex_mul(VALUE x, VALUE y);

/**
 * Performs division of the passed two objects.
 *
 * @param[in]  x  An instance of ::rb_cComplex.
 * @param[in]  y  Arbitrary ruby object.
 * @return     What `x / y` evaluates to.
 * @see        rb_num_coerce_bin()
 */
VALUE rb_complex_div(VALUE x, VALUE y);

/**
 * Performs negation of the passed object.
 *
 * @param[in]  z  An instance of ::rb_cComplex.
 * @return     What `-z` evaluates to.
 */
VALUE rb_complex_uminus(VALUE z);

/**
 * Performs complex conjugation of the passed object.
 *
 * @param[in]  z  An instance of ::rb_cComplex.
 * @return     Its complex conjugate, in ::rb_cComplex.
 */
VALUE rb_complex_conjugate(VALUE z);

/**
 * Queries the absolute (or the magnitude) of the passed object.
 *
 * @param[in]  z  An instance of ::rb_cComplex.
 * @return     Its magnitude, in ::rb_cFloat.
 */
VALUE rb_complex_abs(VALUE z);

/**
 * Queries the argument (or the angle) of the passed object.
 *
 * @param[in]  z  An instance of ::rb_cComplex.
 * @return     Its magnitude, in ::rb_cFloat.
 */
VALUE rb_complex_arg(VALUE z);

/**
 * Performs exponentiation of the passed two objects.
 *
 * @param[in]  base  An instance of ::rb_cComplex.
 * @param[in]  exp   Arbitrary ruby object.
 * @return     What `base ** exp` evaluates to.
 * @see        rb_num_coerce_bin()
 */
VALUE rb_complex_pow(VALUE base, VALUE exp);

/**
 * Identical to rb_complex_new(),  except it takes the arguments  as C's double
 * instead of Ruby's object.
 *
 * @param[in]  real  Real part.
 * @param[in]  imag  Imaginary part.
 * @return     An instance of ::rb_cComplex whose value is `real + (imag)i`.
 */
VALUE rb_dbl_complex_new(double real, double imag);

/** @alias{rb_complex_plus} */
#define rb_complex_add rb_complex_plus

/** @alias{rb_complex_minus} */
#define rb_complex_sub rb_complex_minus

/** @alias{rb_complex_uminus} */
#define rb_complex_nagate rb_complex_uminus

/**
 * Converts various values into a Complex.  This function accepts:
 *
 * - Instances of ::rb_cComplex (taken as-is),
 * - Instances of ::rb_cNumeric (adds `0i`),
 * - Instances of ::rb_cString  (parses),
 * - Other objects that respond to `#to_c`.
 *
 * It (possibly recursively) applies `#to_c`  until both sides become a Complex
 * value, then computes `imag * 1i + real`.
 *
 * As a  special case, passing ::RUBY_Qundef  to `imag` is the  same as passing
 * `RB_INT2NUM(0)`.
 *
 * @param[in]  real           Real part (see above).
 * @param[in]  imag           Imaginary part (see above).
 * @exception  rb_eTypeError  Passed something not described above.
 * @return     An instance of ::rb_cComplex whose value is `1i * imag + real`.
 *
 * @internal
 *
 * This was the implementation of `Kernel#Complex` before, but they diverged.
 */
VALUE rb_Complex(VALUE real, VALUE imag);

/**
 * Shorthand of  `x+0i`.  It  practically converts  `x` into  a Complex  of the
 * identical value.
 *
 * @param[in]  x  ::rb_cNumeric,  ::rb_cString, or  something that  responds to
 *                `#to_c`.
 * @return     An instance of ::rb_cComplex, whose value is `x + 0i`.
 */
#define rb_Complex1(x) rb_Complex((x), INT2FIX(0))

/** @alias{rb_Complex} */
#define rb_Complex2(x,y) rb_Complex((x), (y))

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERN_COMPLEX_H */
ruby/internal/intern/process.h000064400000026461151732674230012512 0ustar00#ifndef RBIMPL_INTERN_PROCESS_H                      /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_PROCESS_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Public APIs related to ::rb_mProcess.
 */
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/config.h"      /* rb_pid_t is defined here. */
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/* process.c */

/**
 * Wait for the specified process to terminate, reap it, and return its status.
 *
 * @param[in] pid The process ID to wait for.
 * @param[in] flags The flags to pass to waitpid(2).
 * @return VALUE An instance of Process::Status.
 */
VALUE rb_process_status_wait(rb_pid_t pid, int flags);

/**
 * Sets the "last status", or the `$?`.
 *
 * @param[in]  status  The termination status, as defined in `waitpid(3posix)`.
 * @param[in]  pid     The last child of the current process.
 * @post       `$?` is updated.
 */
void rb_last_status_set(int status, rb_pid_t pid);

/**
 * Queries the "last status", or the `$?`.
 *
 * @retval  RUBY_Qnil  The current thread has no dead children.
 * @retval  otherwise  An instance of Process::Status  describing the status of
 *                     the child that was most recently `wait`-ed.
 */
VALUE rb_last_status_get(void);

RBIMPL_ATTR_NONNULL(())
/**
 * Executes a shell command.
 *
 * @warning    THIS FUNCTION RETURNS on error!
 * @param[in]  cmd  Passed to the shell.
 * @retval     -1   Something prevented the command execution.
 * @post       Upon successful execution this function doesn't return.
 * @post       In case it returns the `errno` is set properly.
 */
int rb_proc_exec(const char *cmd);

RBIMPL_ATTR_NORETURN()
/**
 * Replaces the current process by running the given external command.  This is
 * the implementation of `Kernel#exec`.
 *
 * @param[in]  argc                 Number of objects in `argv`.
 * @param[in]  argv                 Command and its options to execute.
 * @exception  rb_eTypeError        Invalid options e.g. non-String argv.
 * @exception  rb_eArgError         Invalid options e.g. redirection cycle.
 * @exception  rb_eNotImpError      Not implemented e.g. no `setuid(2)`.
 * @exception  rb_eRuntimeError     `Process::UID.switch` in operation.
 * @exception  rb_eSystemCallError  `execve(2)` failed.
 * @warning    This function doesn't return.
 * @warning    On failure it raises.  On success the process is replaced.
 *
 * @internal
 *
 * @shyouhei have to say that the  rdoc for `Kernel#exec` is fairly incomplete.
 * AFAIK this function ultimately takes the following signature:
 *
 * ```rbs
 * type boolx  = bool | nil                # !=  `boolish`
 *
 * type rlim_t = Integer                   # rlim_cur
 *             | [ Integer, Integer ]      # rlim_cur, rlim_max
 *
 * type uid_t  = String                    # e.g. "root"
 *             | Integer                   # e.g. 0
 *
 * type gid_t  = String                    # e.g. "wheel"
 *             | Integer                   # e.g. 0
 *
 * type fmode  = String                    # e.g. "rb"
 *             | Integer                   # e.g. O_RDONLY | O_BINARY
 *
 * type mode_t = Integer                   # e.g. 0644
 *
 * type pgrp   = true                      # Creates a dedicated pgroup
 *             | 0                         # ditto
 *             | nil                       # Uses the current one
 *             | Integer                   # Uses this specific pgroup
 *
 * type fd     = :in                       # STDIN
 *             | :out                      # STDOUT
 *             | :err                      # STDERR
 *             | IO                        # This specific IO
 *             | Integer                   # A file descriptor of this #
 *
 * type src    = fd | [ fd ]
 * type dst    = :close                    # Intuitive
 *             | fd                        # Intuitive
 *             | String                    # Open a file at this path
 *             | [ String ]                # ... using O_RDONLY
 *             | [ String, fmode ]         # ... using this mode
 *             | [ String, fmode, mode_t ] # ... with a permission
 *             | [ :child, fd ]            # fd of child side
 *
 * type redir  = Hash[ src, dst ]
 *
 * # ----
 *
 * # Key-value pair of environment variables
 * type envp  = Hash[ String, String ]
 *
 * # Actual name (and the name passed to the subprocess if any)
 * type arg0  = String | [ String, String ]
 *
 * # Arbitrary string parameters
 * type argv  = String
 *
 * # Exec options:
 * type argh  = redir | {
 *   chdir:             String, # Working directory
 *   close_others:      boolx,  # O_CLOEXEC like behaviour
 *   gid:               gid_t,  # setegid(2)
 *   pgrooup:           pgrp,   # setpgrp(2)
 *   rlimit_as:         rlim_t, # setrlimit(2)
 *   rlimit_core:       rlim_t, # ditto
 *   rlimit_cpu:        rlim_t, # ditto
 *   rlimit_data:       rlim_t, # ditto
 *   rlimit_fsize:      rlim_t, # ditto
 *   rlimit_memlock:    rlim_t, # ditto
 *   rlimit_msgqueue:   rlim_t, # ditto
 *   rlimit_nice:       rlim_t, # ditto
 *   rlimit_nofile:     rlim_t, # ditto
 *   rlimit_nproc:      rlim_t, # ditto
 *   rlimit_rss:        rlim_t, # ditto
 *   rlimit_rtprio:     rlim_t, # ditto
 *   rlimit_rttime:     rlim_t, # ditto
 *   rlimit_sbsize:     rlim_t, # ditto
 *   rlimit_sigpending: rlim_t, # ditto
 *   rlimit_stack:      rlim_t, # ditto
 *   uid:               uid_t,  # seteuid(2)
 *   umask:             mode_t, # umask(2)
 *   unsetenv_others:   boolx   # Unset everything except the passed envp
 * }
 *
 * # ====
 *
 * class Kernel
 *   def self?.exec
 *     : (          arg0 cmd, *argv args           ) -> void
 *     | (          arg0 cmd, *argv args, argh opts) -> void
 *     | (envp env, arg0 cmd, *argv args           ) -> void
 *     | (envp env, arg0 cmd, *argv args, argh opts) -> void
 * end
 * ```
 */
VALUE rb_f_exec(int argc, const VALUE *argv);

/**
 * Waits for a process, with releasing GVL.
 *
 * @param[in]   pid        Process ID.
 * @param[out]  status     The wait status is filled back.
 * @param[in]   flags      Wait options.
 * @retval      -1         System call failed, errno set.
 * @retval      0          WNOHANG but no waitable children.
 * @retval      otherwise  A process ID that was `wait()`-ed.
 * @post        Upon successful return `status` is updated to have the process'
 *              status.
 * @note        `status` can be NULL.
 * @note        The arguments are passed  through to underlying system call(s).
 *              Can have special meanings.  For instance passing `(rb_pid_t)-1`
 *              to   `pid`   means   it   waits  for   any   processes,   under
 *              POSIX-compliant situations.
 */
rb_pid_t rb_waitpid(rb_pid_t pid, int *status, int flags);

/**
 * This is  a shorthand of  rb_waitpid without status  and flags.  It  has been
 * like this  since the very beginning.   The initial revision already  did the
 * same thing.  Not sure why, then, it has been named `syswait`.  AFAIK this is
 * different from how `wait(3posix)` works.
 *
 * @param[in]  pid  Passed to rb_waitpid().
 */
void rb_syswait(rb_pid_t pid);

/**
 * Identical  to rb_f_exec(),  except  it  spawns a  child  process instead  of
 * replacing the current one.
 *
 * @param[in]  argc              Number of objects in `argv`.
 * @param[in]  argv              Command and its options to execute.
 * @exception  rb_eTypeError     Invalid options e.g. non-String argv.
 * @exception  rb_eArgError      Invalid options e.g. redirection cycle.
 * @exception  rb_eNotImpError   Not implemented e.g. no `setuid(2)`.
 * @exception  rb_eRuntimeError  `Process::UID.switch` in operation.
 * @retval     -1                Child process died for some reason.
 * @retval     otherwise         The ID of the born child.
 *
 * @internal
 *
 * This  is _really_  identical  to rb_f_exec()  until  ultimately calling  the
 * system  call.    Almost  everything   are  shared   among  these   two  (and
 * rb_f_system()).
 */
rb_pid_t rb_spawn(int argc, const VALUE *argv);

/**
 * Identical  to rb_spawn(),  except  you can  additionally  know the  detailed
 * situation in case of abnormal parturitions.
 *
 * @param[in]   argc              Number of objects in `argv`.
 * @param[in]   argv              Command and its options to execute.
 * @param[out]  errbuf            Error description write-back buffer.
 * @param[in]   buflen            Number of bytes of `errbuf`, including NUL.
 * @exception   rb_eTypeError     Invalid options e.g. non-String argv.
 * @exception   rb_eArgError      Invalid options e.g. redirection cycle.
 * @exception   rb_eNotImpError   Not implemented e.g. no `setuid(2)`.
 * @exception   rb_eRuntimeError  `Process::UID.switch` in operation.
 * @retval      -1                Child process died for some reason.
 * @retval      otherwise         The ID of the born child.
 * @post        In case  of `-1`, at most  `buflen` bytes of the  reason why is
 *              written back to `errbuf`.
 */
rb_pid_t rb_spawn_err(int argc, const VALUE *argv, char *errbuf, size_t buflen);

/**
 * Gathers info about resources consumed by the current process.
 *
 * @param[in]  _  Not used.  Pass anything.
 * @return     An instance of `Process::Tms`.
 *
 * @internal
 *
 * This function  might or might  not exist depending on  `./configure` result.
 * It must be a portability hell.  Better not use.
 */
VALUE rb_proc_times(VALUE _);

/**
 * "Detaches"  a subprocess.   In POSIX  systems every  child processes  that a
 * process creates must be `wait(2)`-ed.  A child process that died yet has not
 * been  waited so  far  is called  a  "zombie", which  more  or less  consumes
 * resources.   This function  automates reclamation  of such  processes.  Once
 * after this function successfully returns  you can basically forget about the
 * child process.
 *
 * @param[in]  pid  Process to wait.
 * @return     An instance of ::rb_cThread which is `waitpid(2)`-ing `pid`.
 * @post       You can just forget about the return value.  GC reclaims it.
 * @post       You  can  know the  exit  status  by  querying `#value`  of  the
 *             return value (which is a blocking operation).
 */
VALUE rb_detach_process(rb_pid_t pid);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERN_PROCESS_H */
ruby/internal/intern/dir.h000064400000003626151732674230011610 0ustar00#ifndef RBIMPL_INTERN_DIR_H                          /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_DIR_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Public APIs related to ::rb_cDir.
 */
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/* dir.c */

/**
 * Queries the path of the current working directory of the current process.
 *
 * @return  An instance of ::rb_cString that holds the working directory.
 * @note    The returned string  is in "filesystem" encoding.   Most notably on
 *          Linux this is an alias  of default external encoding.  Most notably
 *          on Windows it can be an alias of OS codepage.
 */
VALUE rb_dir_getwd(void);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERN_DIR_H */
ruby/internal/intern/thread.h000064400000044034151732674230012277 0ustar00#ifndef RBIMPL_INTERN_THREAD_H                       /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_THREAD_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Public APIs related to ::rb_cThread.
 */
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/config.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

struct timeval;

/* thread.c */

/**
 * Tries to switch  to another thread.  This function blocks  until the current
 * thread re-acquires the GVL.
 *
 * @exception  rb_eInterrupt  Operation interrupted.
 */
void rb_thread_schedule(void);

/**
 * Blocks the  current thread until  the given file  descriptor is ready  to be
 * read.
 *
 * @param[in]  fd                    A file descriptor.
 * @exception  rb_eIOError           Closed stream.
 * @exception  rb_eSystemCallError   Situations like EBADF.
 */
int rb_thread_wait_fd(int fd);

/**
 * Identical to rb_thread_wait_fd(), except it  blocks the current thread until
 * the given file descriptor is ready to be written.
 *
 * @param[in]  fd                    A file descriptor.
 * @exception  rb_eIOError           Closed stream.
 * @exception  rb_eSystemCallError   Situations like EBADF.
 */
int rb_thread_fd_writable(int fd);

/**
 * Notifies a closing of a file  descriptor to other threads.  Multiple threads
 * can wait for the given file descriptor  at once.  If such file descriptor is
 * closed, threads need to start propagating their exceptions.  This is the API
 * to kick that process.
 *
 * @param[in]  fd  A file descriptor.
 * @note       This function blocks  until all the threads waiting  for such fd
 *             have woken up.
 */
void rb_thread_fd_close(int fd);

/**
 * Checks if  the thread this  function is running is  the only thread  that is
 * currently alive.
 *
 * @retval  1  Yes it is.
 * @retval  0  No it isn't.
 *
 * @internal
 *
 * Above description is in fact inaccurate.  There are Ractors these days.
 */
int rb_thread_alone(void);

/**
 * Blocks for the given period of time.
 *
 * @warning    This function can be interrupted by signals.
 * @param[in]  sec            Duration in seconds.
 * @exception  rb_eInterrupt  Interrupted.
 */
void rb_thread_sleep(int sec);

/**
 * Blocks indefinitely.
 *
 * @exception  rb_eInterrupt  Interrupted.
 */
void rb_thread_sleep_forever(void);

/**
 * Identical  to  rb_thread_sleep_forever(),  except the  thread  calling  this
 * function is considered "dead" when our deadlock checker is triggered.
 *
 * @exception  rb_eInterrupt  Interrupted.
 */
void rb_thread_sleep_deadly(void);

/**
 * Stops the current thread.  This is not the end of the thread's lifecycle.  A
 * stopped thread can later be woken up.
 *
 * @exception  rb_eThreadError  Stopping this thread would deadlock.
 * @retval     ::RUBY_Qnil      Always.
 *
 * @internal
 *
 * The return value makes no sense at all.
 */
VALUE rb_thread_stop(void);

/**
 * Marks a given thread as eligible for scheduling.
 *
 * @note  It may still remain blocked on I/O.
 * @note  This does not invoke the scheduler itself.
 *
 * @param[out]  thread           Thread in question to wake up.
 * @exception   rb_eThreadError  Stop flogging a dead horse.
 * @return      The passed thread.
 * @post        The passed thread is made runnable.
 */
VALUE rb_thread_wakeup(VALUE thread);

/**
 * Identical  to rb_thread_wakeup(),  except  it doesn't  raise  on an  already
 * killed thread.
 *
 * @param[out]  thread     A thread to wake up.
 * @retval      RUBY_Qnil  `thread` is already killed.
 * @retval      otherwise  `thread` is alive.
 * @post        The passed thread is made runnable, unless killed.
 */
VALUE rb_thread_wakeup_alive(VALUE thread);

/**
 * This is a rb_thread_wakeup() + rb_thread_schedule() combo.
 *
 * @note        There is no  guarantee that this function yields  to the passed
 *              thread.  It may still remain blocked on I/O.
 * @param[out]  thread           Thread in question to wake up.
 * @exception   rb_eThreadError  Stop flogging a dead horse.
 * @return      The passed thread.
 */
VALUE rb_thread_run(VALUE thread);

/**
 * Terminates the given thread.  Unlike a stopped thread, a killed thread could
 * never be revived.   This function does return, when passed  e.g.  an already
 * killed thread.   But if  the passed  thread is  the only  one, or  a special
 * thread called "main", then it also terminates the entire process.
 *
 * @param[out]  thread          The thread to terminate.
 * @exception   rb_eFatal       The passed thread is the running thread.
 * @exception   rb_eSystemExit  The passed thread is the last thread.
 * @return      The passed thread.
 * @post        Either the passed thread, or the process entirely, is killed.
 *
 * @internal
 *
 * It seems killing the main thread also kills the entire process even if there
 * are multiple running ractors.  No idea why.
 */
VALUE rb_thread_kill(VALUE thread);

RBIMPL_ATTR_NONNULL((1))
/**
 * Creates a Ruby thread that is backended by a C function.
 *
 * @param[in]      f                    The function to run on a thread.
 * @param[in,out]  g                    Passed through to `f`.
 * @exception      rb_eThreadError      Could not create a ruby thread.
 * @exception      rb_eSystemCallError  Situations like `EPERM`.
 * @return         Allocated instance of ::rb_cThread.
 * @note           This doesn't wait for anything.
 */
VALUE rb_thread_create(VALUE (*f)(void *g), void *g);

/**
 * Identical to rb_thread_sleep(), except it takes struct `timeval` instead.
 *
 * @warning    This function can be interrupted by signals.
 * @param[in]  time           Duration.
 * @exception  rb_eInterrupt  Interrupted.
 */
void rb_thread_wait_for(struct timeval time);

/**
 * Obtains the "current" thread.
 *
 * @return  The current thread  of the current ractor of  the current execution
 *          context.
 * @pre     This function must be called from a thread controlled by ruby.
 */
VALUE rb_thread_current(void);

/**
 * Obtains the "main" thread.  There are threads called main.  Historically the
 * (only) main thread was the one which  runs when the process boots.  Now that
 * we have Ractor, there are more than one main threads.
 *
 * @return  The  main thread  of the  current ractor  of the  current execution
 *          context.
 * @pre     This function must be called from a thread controlled by ruby.
 */
VALUE rb_thread_main(void);

/**
 * This  badly named  function reads  from a  Fiber local  storage.  When  this
 * function was  born there  was no  such thing  like a  Fiber.  The  world was
 * innocent.  But now...  This is a Fiber local storage.  Sorry.
 *
 * @param[in]  thread     Thread that the target Fiber is running.
 * @param[in]  key        The name of the Fiber local storage to read.
 * @retval     RUBY_Qnil  No such storage.
 * @retval     otherwise  The value stored at `key`.
 * @note       There in fact are "true"  thread local storage, but Ruby doesn't
 *             provide any interface of them to you, C programmers.
 */
VALUE rb_thread_local_aref(VALUE thread, ID key);

/**
 * This  badly named  function  writes to  a Fiber  local  storage.  When  this
 * function was  born there  was no  such thing  like a  Fiber.  The  world was
 * innocent.  But now...  This is a Fiber local storage.  Sorry.
 *
 * @param[in]  thread           Thread that the target Fiber is running.
 * @param[in]  key              The name of the Fiber local storage to write.
 * @param[in]  val              The new value of the storage.
 * @exception  rb_eFrozenError  `thread` is frozen.
 * @return     The passed `val` as-is.
 * @post       Fiber local storage `key` has value of `val`.
 * @note       There in fact are "true"  thread local storage, but Ruby doesn't
 *             provide any interface of them to you, C programmers.
 */
VALUE rb_thread_local_aset(VALUE thread, ID key, VALUE val);

/**
 * A `pthread_atfork(3posix)`-like  API.  Ruby  expects its child  processes to
 * call this function at the very beginning of their processes.  If you plan to
 * fork a process don't forget to call it.
 */
void rb_thread_atfork(void);

/**
 * :FIXME: situation  of this function  is unclear.   It seems nobody  uses it.
 * Maybe a good idea to KonMari.
 */
void rb_thread_atfork_before_exec(void);

/**
 * "Recursion" API entry  point.  This basically calls the  given function with
 * the given arguments, but additionally with  recursion flag.  The flag is set
 * to 1  if the  execution have  already experienced  the passed  `g` parameter
 * before.
 *
 * @param[in]      f  The function that possibly recurs.
 * @param[in,out]  g  Passed as-is to `f`.
 * @param[in,out]  h  Passed as-is to `f`.
 * @return         The return value of f.
 */
VALUE rb_exec_recursive(VALUE (*f)(VALUE g, VALUE h, int r), VALUE g, VALUE h);

/**
 * Identical to rb_exec_recursive(), except it  checks for the recursion on the
 * ordered pair of `{ g, p }` instead of just `g`.
 *
 * @param[in]      f  The function that possibly recurs.
 * @param[in,out]  g  Passed as-is to `f`.
 * @param[in]      p  Paired object for recursion detection.
 * @param[in,out]  h  Passed as-is to `f`.
 */
VALUE rb_exec_recursive_paired(VALUE (*f)(VALUE g, VALUE h, int r), VALUE g, VALUE p, VALUE h);

/**
 * Identical  to  rb_exec_recursive(),  except   it  calls  `f`  for  outermost
 * recursion only.  Inner recursions yield calls to rb_throw_obj().
 *
 * @param[in]      f  The function that possibly recurs.
 * @param[in,out]  g  Passed as-is to `f`.
 * @param[in,out]  h  Passed as-is to `f`.
 * @return         The return value of f.
 *
 * @internal
 *
 * It seems  nobody uses the "it  calls rb_throw_obj()" part of  this function.
 * @shyouhei doesn't understand the needs.
 */
VALUE rb_exec_recursive_outer(VALUE (*f)(VALUE g, VALUE h, int r), VALUE g, VALUE h);

/**
 * Identical to  rb_exec_recursive_outer(), except it checks  for the recursion
 * on the ordered pair of `{ g, p }`  instead of just `g`.  It can also be seen
 * as a  routine identical to  rb_exec_recursive_paired(), except it  calls `f`
 * for   outermost   recursion  only.    Inner   recursions   yield  calls   to
 * rb_throw_obj().
 *
 * @param[in]      f  The function that possibly recurs.
 * @param[in,out]  g  Passed as-is to `f`.
 * @param[in]      p  Paired object for recursion detection.
 * @param[in,out]  h  Passed as-is to `f`.
 *
 * @internal
 *
 * It seems  nobody uses the "it  calls rb_throw_obj()" part of  this function.
 * @shyouhei doesn't understand the needs.
 */
VALUE rb_exec_recursive_paired_outer(VALUE (*f)(VALUE g, VALUE h, int r), VALUE g, VALUE p, VALUE h);

/**
 * This is  the type of UBFs.   An UBF is  a function that unblocks  a blocking
 * region.  For instance when a thread is blocking due to `pselect(3posix)`, it
 * is highly expected that `pthread_kill(3posix)` can interrupt the system call
 * and  the  thread  could  revive.   Or  when a  thread  is  blocking  due  to
 * `waitpid(3posix)`, it  is highly  expected that  killing the  waited process
 * should suffice.  An UBF is a function that does such things.  Designing your
 * own UBF  needs deep understanding  of why  your blocking region  blocks, how
 * threads work in ruby, and a matter of luck.  It often is the case you simply
 * cannot cancel something that had already begun.
 *
 * @see rb_thread_call_without_gvl()
 */
typedef void rb_unblock_function_t(void *);

/**
 * @private
 *
 * This is an implementation detail.  Must be a mistake to be here.
 *
 * @internal
 *
 * Why is  this function type different  from what rb_thread_call_without_gvl()
 * takes?
 */
typedef VALUE rb_blocking_function_t(void *);

/**
 * Checks for  interrupts.  In ruby,  signals are  masked by default.   You can
 * call this function at  will to check if there are  pending signals.  In case
 * there are, they would be handled in this function.
 *
 * If your  extension library has a  function that takes a  long time, consider
 * calling it periodically.
 *
 * @note  It might switch to another thread.
 */
void rb_thread_check_ints(void);

/**
 * Checks if the  thread's execution was recently interrupted.   If called from
 * that thread, this function can be used to detect spurious wake-ups.
 *
 * @param[in]  thval      Thread in question.
 * @retval     0          The thread was not interrupted.
 * @retval     otherwise  The thread was interrupted recently.
 *
 * @internal
 *
 * Above description is not a lie.  But  actually the return value is an opaque
 * trap vector.  If you know which bit means which, you can know what happened.
 */
int rb_thread_interrupted(VALUE thval);

/**
 * A special  UBF for blocking IO  operations.  You need deep  understanding of
 * what this  actually do before using.   Basically you should not  use it from
 * extension libraries.  It is too easy to mess up.
 */
#define RUBY_UBF_IO RBIMPL_CAST((rb_unblock_function_t *)-1)

/**
 * A special UBF for blocking  process operations.  You need deep understanding
 * of what this actually do before using.  Basically you should not use it from
 * extension libraries.  It is too easy to mess up.
 */
#define RUBY_UBF_PROCESS RBIMPL_CAST((rb_unblock_function_t *)-1)

/* thread_sync.c */

/**
 * Creates a mutex.
 *
 * @return An allocated instance of rb_cMutex.
 */
VALUE rb_mutex_new(void);

/**
 * Queries if there are any threads that holds the lock.
 *
 * @param[in]  mutex  The mutex in question.
 * @retval     RUBY_Qtrue  The mutex is locked by someone.
 * @retval     RUBY_Qfalse The mutex is not locked by anyone.
 */
VALUE rb_mutex_locked_p(VALUE mutex);

/**
 * Attempts to lock the mutex, without  waiting for other threads to unlock it.
 * Failure in locking the mutex can be detected by the return value.
 *
 * @param[out]  mutex        The mutex to lock.
 * @retval      RUBY_Qtrue   Successfully locked by the current thread.
 * @retval      RUBY_Qfalse  Otherwise.
 * @note        This  function also  returns  ::RUBY_Qfalse when  the mutex  is
 *              already owned by the calling thread itself.
 */
VALUE rb_mutex_trylock(VALUE mutex);

/**
 * Attempts to lock the mutex.  It waits until the mutex gets available.
 *
 * @param[out]  mutex            The mutex to lock.
 * @exception   rb_eThreadError  Recursive deadlock situation.
 * @return      The passed mutex.
 * @post        The mutex is owned by the current thread.
 */
VALUE rb_mutex_lock(VALUE mutex);

/**
 * Releases the mutex.
 *
 * @param[out]  mutex            The mutex to unlock.
 * @exception   rb_eThreadError  The mutex is not owned by the current thread.
 * @return      The passed mutex.
 * @post        Upon successful return  the passed mutex is no  longer owned by
 *              the current thread.
 */
VALUE rb_mutex_unlock(VALUE mutex);

/**
 * Releases  the lock  held in  the mutex  and waits  for the  period of  time;
 * reacquires the lock on wakeup.
 *
 * @pre         The lock has to be owned by the current thread beforehand.
 * @param[out]  self             The target mutex.
 * @param[in]   timeout          Duration, in seconds, in ::rb_cNumeric.
 * @exception   rb_eArgError     `timeout` is negative.
 * @exception   rb_eRangeError   `timeout` is out of range of `time_t`.
 * @exception   rb_eThreadError  The mutex is not owned by the current thread.
 * @return      Number of seconds it actually slept.
 * @warning     It is a  failure not to check the return  value.  This function
 *              can return spuriously for various reasons.  Maybe other threads
 *              can  rb_thread_wakeup().   Maybe  an  end user  can  press  the
 *              Control and C  key from the interactive console.   On the other
 *              hand it  can also  take longer than  the specified.   The mutex
 *              could be locked by someone else.  It waits then.
 * @post        Upon successful return the passed mutex is owned by the current
 *              thread.
 *
 * @internal
 *
 * This  function is  called from  `ConditionVariable#wait`.   So it  is not  a
 * deprecated feature.   However @shyouhei  have never  seen any  similar mutex
 * primitive available in any other languages than Ruby.
 *
 * EDIT: In 2021,  @shyouhei asked @ko1 in person about  this API.  He answered
 * that it is his invention.  The  motivation behind its design is to eliminate
 * needs of condition variables as  primitives.  Unlike other languages, Ruby's
 * `ConditionVariable` class was written in pure-Ruby initially.  We don't have
 * to implement  machine-native condition  variables in  assembly each  time we
 * port Ruby to a new architecture.  This function made it possible.  "I felt I
 * was a genius when this idea came to me", said @ko1.
 *
 * `rb_cConditionVariable` is now written in C for speed, though.
 */
VALUE rb_mutex_sleep(VALUE self, VALUE timeout);

/**
 * Obtains the  lock, runs the passed  function, and releases the  lock when it
 * completes.
 *
 * @param[out]     mutex  The mutex to lock.
 * @param[in]      func   What to do during the mutex is locked.
 * @param[in,out]  arg    Passed as-is to `func`.
 */
VALUE rb_mutex_synchronize(VALUE mutex, VALUE (*func)(VALUE arg), VALUE arg);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERN_THREAD_H */
ruby/internal/intern/enumerator.h000064400000030206151732674230013205 0ustar00#ifndef RBIMPL_INTERN_ENUMERATOR_H                   /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_ENUMERATOR_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Public APIs related to ::rb_cEnumerator.
 */
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/intern/eval.h" /* rb_frame_this_func */
#include "ruby/internal/iterator.h"    /* rb_block_given_p */
#include "ruby/internal/symbol.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/**
 * This is the type of functions that rb_enumeratorize_with_size() expects.  In
 * theory an enumerator can have indefinite number of elements, but in practice
 * it often is  the case we can  compute the size of  an enumerator beforehand.
 * If your enumerator has such property, supply a function that calculates such
 * values.
 *
 * @param[in]  recv  The original receiver of the enumerator.
 * @param[in]  argv  Arguments passed to `Object#enum_for` etc.
 * @param[in]  eobj  The enumerator object.
 * @return     The size of `eobj`, in ::rb_cNumeric, or ::RUBY_Qnil if the size
 *             is not known until we actually iterate.
 */
typedef VALUE rb_enumerator_size_func(VALUE recv, VALUE argv, VALUE eobj);

/**
 * Decomposed   `Enumerator::ArithmeicSequence`.   This   is   a  subclass   of
 * ::rb_cEnumerator,  which  represents  a  sequence  of  numbers  with  common
 * difference.  Internal  data structure of the  class is opaque to  users, but
 * you can obtain a decomposed one using rb_arithmetic_sequence_extract().
 */
typedef struct {
    VALUE begin;          /**< "Left" or "lowest" endpoint of the sequence. */
    VALUE end;            /**< "Right" or "highest" endpoint of the sequence.*/
    VALUE step;           /**< Step between a sequence. */
    int exclude_end;      /**< Whether the endpoint is open or closed.  */
} rb_arithmetic_sequence_components_t;

/* enumerator.c */

/**
 * Constructs an enumerator.  This roughly resembles `Object#enum_for`.
 *
 * @param[in]  recv           A receiver of `meth`.
 * @param[in]  meth           Method ID in a symbol object.
 * @param[in]  argc           Number of objects of `argv`.
 * @param[in]  argv           Arguments passed to `meth`.
 * @exception  rb_eTypeError  `meth` is not an instance of ::rb_cSymbol.
 * @return     A  new   instance  of  ::rb_cEnumerator  which,   when  yielded,
 *             enumerates by calling `meth` on `recv` with `argv`.
 */
VALUE rb_enumeratorize(VALUE recv, VALUE meth, int argc, const VALUE *argv);

/**
 * Identical  to rb_enumeratorize(),  except you  can additionally  specify the
 * size function of return value.
 *
 * @param[in]  recv           A receiver of `meth`.
 * @param[in]  meth           Method ID in a symbol object.
 * @param[in]  argc           Number of objects of `argv`.
 * @param[in]  argv           Arguments passed to `meth`.
 * @param[in]  func           Size calculator.
 * @exception  rb_eTypeError  `meth` is not an instance of ::rb_cSymbol.
 * @return     A  new   instance  of  ::rb_cEnumerator  which,   when  yielded,
 *             enumerates by calling `meth` on `recv` with `argv`.
 * @note       `func` can be zero, which means the size is unknown.
 */
VALUE rb_enumeratorize_with_size(VALUE recv, VALUE meth, int argc, const VALUE *argv, rb_enumerator_size_func *func);

/**
 * Identical  to rb_enumeratorize_with_func(),  except you  can specify  how to
 * handle the last element of the given array.
 *
 * @param[in]  recv             A receiver of `meth`.
 * @param[in]  meth             Method ID in a symbol object.
 * @param[in]  argc             Number of objects of `argv`.
 * @param[in]  argv             Arguments passed to `meth`.
 * @param[in]  func             Size calculator.
 * @param[in]  kw_splat         Handling of keyword parameters:
 *   - RB_NO_KEYWORDS           `argv`'s last is not a keyword argument.
 *   - RB_PASS_KEYWORDS         `argv`'s last is a keyword argument.
 *   - RB_PASS_CALLED_KEYWORDS  it depends if there is a passed block.
 * @exception  rb_eTypeError    `meth` is not an instance of ::rb_cSymbol.
 * @return     A  new   instance  of  ::rb_cEnumerator  which,   when  yielded,
 *             enumerates by calling `meth` on `recv` with `argv`.
 * @note       `func` can be zero, which means the size is unknown.
 */
VALUE rb_enumeratorize_with_size_kw(VALUE recv, VALUE meth, int argc, const VALUE *argv, rb_enumerator_size_func *func, int kw_splat);

RBIMPL_ATTR_NONNULL(())
/**
 * Extracts components of the passed arithmetic  sequence.  This can be seen as
 * an extended version of rb_range_values().
 *
 * @param[in]   as   Target instance of `Enumerator::ArithmericSequence`.
 * @param[out]  buf  Decomposed results buffer.
 * @return      0    `as` is not `Enumerator::ArithmericSequence`.
 * @return      1    Success.
 * @post        `buf` is filled.
 */
int rb_arithmetic_sequence_extract(VALUE as, rb_arithmetic_sequence_components_t *buf);

RBIMPL_ATTR_NONNULL(())
/**
 * Identical   to  rb_range_beg_len(),   except   it  takes   an  instance   of
 * `Enumerator::ArithmericSequence`.
 *
 * @param[in]   as              An `Enumerator::ArithmericSequence` instance.
 * @param[out]  begp            Return value buffer.
 * @param[out]  lenp            Return value buffer.
 * @param[out]  stepp           Return value buffer.
 * @param[in]   len             Updated length.
 * @param[in]   err             In case `len` is out of range...
 *                                - `0`: returns ::RUBY_Qnil.
 *                                - `1`: raises  ::rb_eRangeError.
 *                                - `2`: `beg` and `len` expanded accordingly.
 * @exception   rb_eRangeError  `as` cannot fit into `long`.
 * @retval      RUBY_Qfalse     `as` is not `Enumerator::ArithmericSequence`.
 * @retval      RUBY_Qnil       `len` is out of `as` but `err` is zero.
 * @retval      RUBY_Qtrue      Otherwise.
 * @post        `beg` is the (possibly updated) left endpoint.
 * @post        `len` is the (possibly updated) length of the range.
 *
 * @internal
 *
 * Currently no 3rd party applications of this function is found.  But that can
 * be because this function is relatively new.
 */
VALUE rb_arithmetic_sequence_beg_len_step(VALUE as, long *begp, long *lenp, long *stepp, long len, int err);

RBIMPL_SYMBOL_EXPORT_END()

/** @cond INTERNAL_MACRO */
#ifndef RUBY_EXPORT
# define rb_enumeratorize_with_size(obj, id, argc, argv, size_fn) \
    rb_enumeratorize_with_size(obj, id, argc, argv, (rb_enumerator_size_func *)(size_fn))
# define rb_enumeratorize_with_size_kw(obj, id, argc, argv, size_fn, kw_splat) \
    rb_enumeratorize_with_size_kw(obj, id, argc, argv, (rb_enumerator_size_func *)(size_fn), kw_splat)
#endif
/** @endcond */

/**
 * This is  an implementation detail of  #RETURN_SIZED_ENUMERATOR().  You could
 * use it directly, but can hardly be handy.
 *
 * @param[in]  obj      A receiver.
 * @param[in]  argc     Number of objects of `argv`.
 * @param[in]  argv     Arguments passed to the current method.
 * @param[in]  size_fn  Size calculator.
 * @return     A  new   instance  of  ::rb_cEnumerator  which,   when  yielded,
 *             enumerates by calling the current method on `recv` with `argv`.
 */
#define SIZED_ENUMERATOR(obj, argc, argv, size_fn)                  \
    rb_enumeratorize_with_size((obj), ID2SYM(rb_frame_this_func()), \
                               (argc), (argv), (size_fn))

/**
 * This  is an  implementation  detail  of #RETURN_SIZED_ENUMERATOR_KW().   You
 * could use it directly, but can hardly be handy.
 *
 * @param[in]  obj              A receiver.
 * @param[in]  argc             Number of objects of `argv`.
 * @param[in]  argv             Arguments passed to the current method.
 * @param[in]  size_fn          Size calculator.
 * @param[in]  kw_splat         Handling of keyword parameters:
 *   - RB_NO_KEYWORDS           `argv`'s last is not a keyword argument.
 *   - RB_PASS_KEYWORDS         `argv`'s last is a keyword argument.
 *   - RB_PASS_CALLED_KEYWORDS  it depends if there is a passed block.
 * @return     A  new   instance  of  ::rb_cEnumerator  which,   when  yielded,
 *             enumerates by calling the current method on `recv` with `argv`.
 */
#define SIZED_ENUMERATOR_KW(obj, argc, argv, size_fn, kw_splat)        \
    rb_enumeratorize_with_size_kw((obj), ID2SYM(rb_frame_this_func()), \
                                  (argc), (argv), (size_fn), (kw_splat))

/**
 * This roughly resembles `return enum_for(__callee__) unless block_given?`.
 *
 * @param[in]  obj      A receiver.
 * @param[in]  argc     Number of objects of `argv`.
 * @param[in]  argv     Arguments passed to the current method.
 * @param[in]  size_fn  Size calculator.
 * @note       This macro may return inside.
 */
#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn) do {          \
        if (!rb_block_given_p())                                        \
            return SIZED_ENUMERATOR(obj, argc, argv, size_fn);          \
    } while (0)


/**
 * Identical  to  #RETURN_SIZED_ENUMERATOR(), except  you  can  specify how  to
 * handle the last element of the given array.
 *
 * @param[in]  obj              A receiver.
 * @param[in]  argc             Number of objects of `argv`.
 * @param[in]  argv             Arguments passed to the current method.
 * @param[in]  size_fn          Size calculator.
 * @param[in]  kw_splat         Handling of keyword parameters:
 *   - RB_NO_KEYWORDS           `argv`'s last is not a keyword argument.
 *   - RB_PASS_KEYWORDS         `argv`'s last is a keyword argument.
 *   - RB_PASS_CALLED_KEYWORDS  it depends if there is a passed block.
 * @note       This macro may return inside.
 */
#define RETURN_SIZED_ENUMERATOR_KW(obj, argc, argv, size_fn, kw_splat) do { \
        if (!rb_block_given_p())                                            \
            return SIZED_ENUMERATOR_KW(obj, argc, argv, size_fn, kw_splat);              \
    } while (0)

/**
 * Identical to #RETURN_SIZED_ENUMERATOR(), except its size is unknown.
 *
 * @param[in]  obj   A receiver.
 * @param[in]  argc  Number of objects of `argv`.
 * @param[in]  argv  Arguments passed to the current method.
 * @note       This macro may return inside.
 */
#define RETURN_ENUMERATOR(obj, argc, argv) \
    RETURN_SIZED_ENUMERATOR(obj, argc, argv, 0)

/**
 * Identical to #RETURN_SIZED_ENUMERATOR_KW(), except  its size is unknown.  It
 * can also be seen as a  routine identical to #RETURN_ENUMERATOR(), except you
 * can specify how to handle the last element of the given array.
 *
 * @param[in]  obj              A receiver.
 * @param[in]  argc             Number of objects of `argv`.
 * @param[in]  argv             Arguments passed to the current method.
 * @param[in]  kw_splat         Handling of keyword parameters:
 *   - RB_NO_KEYWORDS           `argv`'s last is not a keyword argument.
 *   - RB_PASS_KEYWORDS         `argv`'s last is a keyword argument.
 *   - RB_PASS_CALLED_KEYWORDS  it depends if there is a passed block.
 * @note       This macro may return inside.
 */
#define RETURN_ENUMERATOR_KW(obj, argc, argv, kw_splat) \
    RETURN_SIZED_ENUMERATOR_KW(obj, argc, argv, 0, kw_splat)

#endif /* RBIMPL_INTERN_ENUMERATOR_H */
ruby/internal/intern/array.h000064400000062551151732674230012152 0ustar00#ifndef RBIMPL_INTERN_ARRAY_H                        /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_ARRAY_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Public APIs related to ::rb_cArray.
 */
#include "ruby/internal/attr/noalias.h"
#include "ruby/internal/attr/noexcept.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/* array.c */

RBIMPL_ATTR_NONNULL(())
RBIMPL_ATTR_NOALIAS()
/**
 * Fills the memory region with a series of ::RUBY_Qnil.
 *
 * @param[out]  buf  Buffer to squash.
 * @param[in]   len  Number of objects of `buf`.
 * @post        `buf` is filled with ::RUBY_Qnil.
 */
void rb_mem_clear(VALUE *buf, long len)
    RBIMPL_ATTR_NOEXCEPT(true)
    ;

/**
 * Identical  to  rb_ary_new_from_values(),  except   it  expects  exactly  two
 * parameters.
 *
 * @param[in]  car  Arbitrary ruby object.
 * @param[in]  cdr  Arbitrary ruby object.
 * @return     An  allocated new  array, of  length 2,  whose contents  are the
 *             passed objects.
 */
VALUE rb_assoc_new(VALUE car, VALUE cdr);

/**
 * Try  converting an  object to  its array  representation using  its `to_ary`
 * method, if any.  If there is no such thing, returns ::RUBY_Qnil.
 *
 * @param[in]  obj            Arbitrary ruby object to convert.
 * @exception  rb_eTypeError  `obj.to_ary` returned something non-Array.
 * @retval     RUBY_Qnil      No conversion from `obj` to array defined.
 * @retval     otherwise      Converted array representation of `obj`.
 * @see        rb_io_check_io
 * @see        rb_check_string_type
 * @see        rb_check_hash_type
 */
VALUE rb_check_array_type(VALUE obj);

/**
 * Allocates a new, empty array.
 *
 * @return  An allocated new array, whose length is 0.
 */
VALUE rb_ary_new(void);

/**
 * Identical to rb_ary_new(),  except it additionally specifies  how many rooms
 * of  objects it  should allocate.   This way  you can  create an  array whose
 * capacity is  bigger than the  length of  it.  If you  can say that  an array
 * grows to a  specific amount, this could be effective  than resizing an array
 * over and over again and again.
 *
 * @param[in]  capa  Designed capacity of the generating array.
 * @return     An empty array, whose capacity is `capa`.
 */
VALUE rb_ary_new_capa(long capa);

/**
 * Constructs an array from the passed objects.
 *
 * @param[in]  n    Number of passed objects.
 * @param[in]  ...  Arbitrary ruby objects, filled into the returning array.
 * @return     An array of size `n`, whose contents are the passed objects.
 */
VALUE rb_ary_new_from_args(long n, ...);

/**
 * Identical to rb_ary_new_from_args(), except how objects are passed.
 *
 * @param[in]  n     Number of objects of `elts`.
 * @param[in]  elts  Arbitrary ruby objects, filled into the returning array.
 * @return     An array of size `n`, whose contents are the passed objects.
 */
VALUE rb_ary_new_from_values(long n, const VALUE *elts);

/**
 * Allocates a hidden (no class) empty array.
 *
 * @param[in]  capa  Designed capacity of the array.
 * @return     A hidden, empty array.
 * @see        rb_obj_hide()
 */
VALUE rb_ary_hidden_new(long capa);
#define rb_ary_tmp_new rb_ary_hidden_new

/**
 * Destroys the given array for no reason.
 *
 * @warning  DO NOT USE IT.
 * @warning  Leave this task to our GC.
 * @warning  It was a wrong indea at the first place to let you know about it.
 *
 * @param[out]  ary  The array to be executed.
 * @post        The given array no longer exists.
 * @note        Maybe `Array#clear` could be what you want.
 *
 * @internal
 *
 * Should have moved this to `internal/array.h`.
 */
void rb_ary_free(VALUE ary);

/**
 * Declares that the array is about to  be modified.  This for instance let the
 * array have a dedicated backend storage.
 *
 * @param[out]  ary               Array about to be modified.
 * @exception   rb_eFrozenError   `ary` is frozen.
 * @post        Upon  successful return  the  passed array  is  eligible to  be
 *              modified.
 */
void rb_ary_modify(VALUE ary);

/**
 * Freeze an array, preventing further modifications. The underlying  buffer may
 * be shrunk before freezing to conserve memory.
 *
 * @param[out]  obj  Object assumed to be an array to freeze.
 * @see         RB_OBJ_FREEZE()
 */
VALUE rb_ary_freeze(VALUE obj);

RBIMPL_ATTR_PURE()
/**
 * Queries if the passed two arrays share the same backend storage.  A use-case
 * for  knowing  such  property is  to  take  a  snapshot  of an  array  (using
 * e.g. rb_ary_replace()), then  check later if that snapshot  still shares the
 * storage with  the original.  Taking  a snapshot is ultra-cheap.   If nothing
 * happens the impact shall be minimal.   But if someone modifies the original,
 * that entity shall pay the cost  of copy-on-write.  You can detect that using
 * this API.
 *
 * @param[in]  lhs          Comparison LHS.
 * @param[in]  rhs          Comparison RHS.
 * @retval     RUBY_Qtrue   They share the same backend storage.
 * @retval     RUBY_Qfalse  They are distinct.
 * @pre        Both arguments must be of ::RUBY_T_ARRAY.
 */
VALUE rb_ary_shared_with_p(VALUE lhs, VALUE rhs);

/**
 * Queries element(s) of  an array.  This is  complicated!  Refer `Array#slice`
 * document for the complete description of how it behaves.
 *
 * @param[in]  argc            Number of objects of `argv`.
 * @param[in]  argv            Up to 2 objects.
 * @param[in]  ary             Target array.
 * @exception  rb_eTypeError   `argv` (or its part) includes non-Integer.
 * @exception  rb_eRangeError  rb_cArithSeq is passed, and is OOB.
 * @return     An  element  (if  requested),  or   an  array  of  elements  (if
 *             requested), or ::RUBY_Qnil (if index OOB).
 *
 * @internal
 *
 * ```rbs
 * # "int" is ::Integer or `#to_int`, defined in builtin.rbs
 *
 * class ::Array[unchecked out T]
 *   def slice
 *     : (int i)                 -> T?
 *     | (int beg, int len)      -> ::Array[T]?
 *     | (Range[int] r)          -> ::Array[T]?
 *     | (ArithmeticSequence as) -> ::Array[T]? # This also raises RangeError.
 * end
 * ```
 */
VALUE rb_ary_aref(int argc, const VALUE *argv, VALUE ary);

/**
 * Obtains a part of the passed array.
 *
 * @param[in]  ary        Target array.
 * @param[in]  beg        Subpart index.
 * @param[in]  len        Requested length of returning array.
 * @retval     RUBY_Qnil  Requested range out of bounds of `ary`.
 * @retval     otherwise  An  allocated new  array whose  contents are  `ary`'s
 *                        `beg` to `len`.
 * @note       Return  array  can  be  shorter than  `len`  when  for  instance
 *             `[0, 1, 2, 3]`'s 4th to 1,000,000,000th is requested.
 */
VALUE rb_ary_subseq(VALUE ary, long beg, long len);

/**
 * Destructively stores  the passed value  to the passed array's  passed index.
 * It also resizes  the array's backend storage so that  the requested index is
 * not out of bounds.
 *
 * @param[out]  ary              Target array to modify.
 * @param[in]   key              Where to store `val`.
 * @param[in]   val              What to store at `key`.
 * @exception   rb_eFrozenError  `ary` is frozen.
 * @exception   rb_eIndexError   `key` is negative.
 * @post        `ary`'s `key`th position is occupied with `val`.
 * @post        Depending on `key` and previous  length of `ary` this operation
 *              can  also create  a series  of "hole"  positions inside  of the
 *              backend storage.  They are filled with ::RUBY_Qnil.
 */
void rb_ary_store(VALUE ary, long key, VALUE val);

/**
 * Duplicates an array.
 *
 * @param[in]  ary  Target to duplicate.
 * @return     An allocated new array whose contents are identical to `ary`.
 *
 * @internal
 *
 * Not sure why this has to be something different from `ary_make_shared_copy`,
 * which seems much efficient.
 */
VALUE rb_ary_dup(VALUE ary);

/**
 * I guess there  is no use case  of this function in  extension libraries, but
 * this is a routine identical to rb_ary_dup().  This makes the most sense when
 * the passed array is formerly hidden by rb_obj_hide().
 *
 * @param[in]  ary  An array, possibly hidden.
 * @return     A duplicated new instance of ::rb_cArray.
 */
VALUE rb_ary_resurrect(VALUE ary);

/**
 * Force converts an object to an  array.  It first tries its `#to_ary` method.
 * Takes the result  if any.  Otherwise creates  an array of size  1 whose sole
 * element is the passed object.
 *
 * @param[in]  obj  Arbitrary ruby object.
 * @return     An array representation of `obj`.
 * @note       Unlike    rb_str_to_str()     which    is    a     variant    of
 *             rb_check_string_type(),  rb_ary_to_ary()  is  not a  variant  of
 *             rb_check_array_type().
 */
VALUE rb_ary_to_ary(VALUE obj);

/**
 * Converts an array into a  human-readable string.  Historically its behaviour
 * changed over time.   Currently it is identical to  calling `inspect` method.
 * This behaviour is from that of python (!!) circa 2006.
 *
 * @param[in]  ary  Array to inspect.
 * @return     Recursively inspected representation of `ary`.
 * @see        `[ruby-dev:29520]`
 */
VALUE rb_ary_to_s(VALUE ary);

/**
 * Destructively appends multiple elements at the end of the array.
 *
 * @param[out]  ary              Where to push `train`.
 * @param[in]   train            Arbitrary ruby objects to push to `ary`.
 * @param[in]   len              Number of objects of `train`.
 * @exception   rb_eIndexError   `len` too large.
 * @exception   rb_eFrozenError  `ary` is frozen.
 * @return      The passed `ary`.
 * @post        `ary` has contents from `train` appended at its end.
 */
VALUE rb_ary_cat(VALUE ary, const VALUE *train, long len);

/**
 * Special case of rb_ary_cat() that it adds only one element.
 *
 * @param[out]  ary              Where to push `elem`.
 * @param[in]   elem             Arbitrary ruby object to push.
 * @exception   rb_eFrozenError  `ary` is frozen.
 * @return      The passed `ary`.
 * @post        `ary` has `elem` appended at its end.
 */
VALUE rb_ary_push(VALUE ary, VALUE elem);

/**
 * Destructively  deletes an  element  from the  end of  the  passed array  and
 * returns what was deleted.
 *
 * @param[out]  ary              Target array to modify.
 * @exception   rb_eFrozenError  `ary` is frozen.
 * @return      What  was at  the  end of  `ary`, or  ::RUBY_Qnil  if there  is
 *              nothing to remove.
 * @post        `ary`'s last element, if any, is removed.
 * @note        There is no  way to distinguish whether `ary`  was an 1-element
 *              array whose content was ::RUBY_Qnil, or was empty.
 */
VALUE rb_ary_pop(VALUE ary);

/**
 * Destructively deletes an element from the  beginning of the passed array and
 * returns what  was deleted.  It  can also be seen  as a routine  identical to
 * rb_ary_pop(), except which side of the array to scrub.
 *
 * @param[out]  ary              Target array to modify.
 * @exception   rb_eFrozenError  `ary` is frozen.
 * @return      What was at the beginning of  `ary`, or ::RUBY_Qnil if there is
 *              nothing to remove.
 * @post        `ary`'s first element, if any, is removed.  As the name implies
 *              everything else  remaining in `ary` gets  moved towards `ary`'s
 *              beginning.
 * @note        There is no  way to distinguish whether `ary`  was an 1-element
 *              array whose content was ::RUBY_Qnil, or was empty.
 */
VALUE rb_ary_shift(VALUE ary);

/**
 * Destructively prepends the passed item at the beginning of the passed array.
 * It can  also be seen as  a routine identical to  rb_ary_push(), except which
 * side of the array to modify.
 *
 * @param[out]  ary              Target array to modify.
 * @param[in]   elem             Arbitrary ruby object to unshift.
 * @exception   rb_eFrozenError  `ary` is frozen.
 * @return      The passed `ary`.
 * @post        `ary` has `elem` prepended at this beginning.
 */
VALUE rb_ary_unshift(VALUE ary, VALUE elem);

RBIMPL_ATTR_PURE()
/**
 * Queries an  element of an array.   When passed offset is  negative it counts
 * backwards.
 *
 * @param[in]  ary  An array to look into.
 * @param[in]  off  Offset (can be negative).
 * @return     ::RUBY_Qnil when  `off` is  out of  bounds of  `ary`.  Otherwise
 *             what is stored at `off`-th position of `ary`.
 * @note       `ary`'s `off`-th element can happen to be ::RUBY_Qnil.
 */
VALUE rb_ary_entry(VALUE ary, long off);

/**
 * Iteratively yields each element of the passed array to the implicitly passed
 * block if any.  In case there is  no block given, an enumerator that does the
 * thing is generated instead.
 *
 * @param[in]  ary  Array to iterate over.
 * @retval     ary  Passed block was evaluated.
 * @retval     otherwise  An instance of ::rb_cEnumerator for `Array#each`.
 */
VALUE rb_ary_each(VALUE ary);

/**
 * Recursively  stringises the  elements  of the  passed  array, flattens  that
 * result, then joins the sequence using the passed separator.
 *
 * @param[in]  ary                 Target array to convert.
 * @param[in]  sep                 Separator.  Either a  string, or ::RUBY_Qnil
 *                                 if you want no separator.
 * @exception  rb_eArgError        Infinite recursion in `ary`.
 * @exception  rb_eTypeError      `sep` is not a string.
 * @exception  rb_eEncCompatError  Strings do not agree with their encodings.
 * @return     An  instance  of   ::rb_cString  which  concatenates  stringised
 *             contents of `ary`, using `sep` as separator.
 */
VALUE rb_ary_join(VALUE ary, VALUE sep);

/**
 * _Destructively_ reverses the passed array in-place.
 *
 * @warning     This is `Array#reverse!`, not `Array#reverse`.
 * @param[out]  ary              Target array to modify.
 * @exception   rb_eFrozenError  `ary` is frozen.
 * @return      Passed `ary`.
 * @post        `ary` is reversed.
 */
VALUE rb_ary_reverse(VALUE ary);

/**
 * _Destructively_ rotates the  passed array in-place to towards  its end.  The
 * amount can be negative.  Would rotate to the opposite direction then.
 *
 * @warning     This is `Array#rotate!`, not `Array#rotate`.
 * @param[out]  ary              Target array to modify.
 * @param[in]   rot              Amount of rotation.
 * @exception   rb_eFrozenError  `ary` is frozen.
 * @retval      RUBY_Qnil        Not rotated.
 * @retval      ary              Rotated.
 * @post        `ary` is rotated.
 */
VALUE rb_ary_rotate(VALUE ary, long rot);

/**
 * Creates a copy  of the passed array, whose elements  are sorted according to
 * their `<=>` result.
 *
 * @param[in]  ary               Array to sort.
 * @exception  rb_eArgError      Comparison not defined among elements.
 * @exception  rb_eRuntimeError  Infinite recursion in `<=>`.
 * @return     A copy of `ary`, sorted.
 * @note       As of writing  this function uses `qsort`  as backend algorithm,
 *             which means the result is unstable (in terms of sort stability).
 */
VALUE rb_ary_sort(VALUE ary);

/**
 * Destructively sorts the  passed array in-place, according  to each elements'
 * `<=>` result.
 *
 * @param[in]  ary               Target array to modify.
 * @exception  rb_eArgError      Comparison not defined among elements.
 * @exception  rb_eRuntimeError  Infinite recursion in `<=>`.
 * @return     Passed `ary`.
 * @post       `ary` is sorted.
 * @note       As of writing  this function uses `qsort`  as backend algorithm,
 *             which means the result is unstable (in terms of sort stability).
 */
VALUE rb_ary_sort_bang(VALUE ary);

/**
 * Destructively removes elements from the passed array, so that there would be
 * no elements  inside that satisfy  `==` relationship with the  passed object.
 * Returns the last deleted  element if any.  But in case  there was nothing to
 * delete it gets complicated.  It checks  for the implicitly passed block.  If
 * there is  a block  the return value  would be what  the block  evaluates to.
 * Otherwise it resorts to ::RUBY_Qnil.
 *
 * @param[out]  ary              Target array to modify.
 * @param[in]   elem             Template object to match against each element.
 * @exception   rb_eFrozenError  `ary` is frozen.
 * @return      What  was  deleted,   or  what  was  the   block  returned,  or
 *              ::RUBY_Qnil (see above).
 * @post        All elements that have `==` relationship with `elem` are purged
 *              from `ary`.  Elements shift their  positions so that `ary` gets
 *              compact.
 *
 * @internal
 *
 * Internally there also is `rb_ary_delete_same`, which compares by identity.
 */
VALUE rb_ary_delete(VALUE ary, VALUE elem);

/**
 * Destructively removes an element which resides  at the specific index of the
 * passed array.  Unlike  rb_ary_stre() the index can be  negative, which means
 * the index counts backwards from the array's tail.
 *
 * @param[out]  ary  Target array to modify.
 * @param[in]   pos  Position (can be negative).
 * @exception   rb_eFrozenError `ary` is frozen.
 * @return      What was deleted, or ::RUBY_Qnil in case of OOB.
 * @post        `ary`'s `pos`-th element is deleted if any.
 * @note        There is no  way to distinguish whether `pos` is  out of bound,
 *              or `pos` did exist but stored ::RUBY_Qnil as an ordinal value.
 */
VALUE rb_ary_delete_at(VALUE ary, long pos);

/**
 * Destructively removes everything form an array.
 *
 * @param[out]  ary              Target array to modify.
 * @exception   rb_eFrozenError  `ary` is frozen.
 * @return      The passed `ary`.
 * @post        `ary` is an empty array.
 */
VALUE rb_ary_clear(VALUE ary);

/**
 * Creates a new array, concatenating the former to the latter.
 *
 * @param[in]  lhs             Source array #1.
 * @param[in]  rhs             Source array #2.
 * @exception  rb_eIndexError  Result array too big.
 * @return     A new array containing `rhs` concatenated to `lhs`.
 * @note       This  operation  doesn't commute.   Don't  get  confused by  the
 *             "plus"  terminology.   For  historical reasons  there  are  some
 *             noncommutative `+`s in Ruby.  This is one of such things.  There
 *             has been a long discussion around `+`s in programming languages.
 *
 * @internal
 *
 * rb_ary_concat() is not  a destructive version of  rb_ary_plus().  They raise
 * different exceptions.  Don't know why though.
 */
VALUE rb_ary_plus(VALUE lhs, VALUE rhs);

/**
 * Destructively appends the contents of latter into the end of former.
 *
 * @param[out]  lhs              Destination array.
 * @param[in]   rhs              Source array.
 * @exception   rb_eFrozenError  `lhs` is frozen.
 * @exception   rb_eIndexError   Result array too big.
 * @exception   rb_eTypeError    `rhs` doesn't respond to `#to_ary`.
 * @return      The passed `lhs`.
 * @post        `lhs` has contents of `rhs` appended to its end.
 */
VALUE rb_ary_concat(VALUE lhs, VALUE rhs);

/**
 * Looks up the passed key, assuming the  passed array is an alist.  An "alist"
 * here  is a  list of  "association"s,  much like  that of  Emacs.  Emacs  has
 * `assoc` function that behaves exactly the same as this one.
 *
 * ```ruby
 * # This is an example of aliist.
 * auto_mode_alist = [
 *   [ /\.[ch]\z/, :"c-mode" ],
 *   [ /\.[ch]pp\z/, :"c++-mode" ],
 *   [ /\.awk\z/, :"awk-mode" ],
 *   [ /\.cs\z/, :"csharp-mode" ],
 *   [ /\.go\z/, :"go-mode" ],
 *   [ /\.java\z/, :"java-mode" ],
 *   [ /\.pas\z/, :"pascal-mode" ],
 *   [ /\.rs\z/, :"rust-mode" ],
 *   [ /\.txt\z/, :"text-mode" ],
 * ]
 * ```
 *
 * This function scans the passed array looking for an element, which itself is
 * an array,  whose first  element is the  passed key.  If  no such  element is
 * found, returns ::RUBY_Qnil.
 *
 * Although this  function expects the passed  array be an array  of arrays, it
 * can happily accept non-array elements; it just ignores such things.
 *
 * @param[in]  alist      An array of arrays.
 * @param[in]  key        Needle.
 * @retval     RUBY_Qnil  Nothing was found.
 * @retval     otherwise  An element in `alist` whose  first element is in `==`
 *                        relationship with `key`.
 */
VALUE rb_ary_assoc(VALUE alist, VALUE key);

/**
 * Identical  to rb_ary_assoc(),  except it  scans  the passed  array from  the
 * opposite direction.
 *
 * @param[in]  alist      An array of arrays.
 * @param[in]  key        Needle.
 * @retval     RUBY_Qnil  Nothing was found.
 * @retval     otherwise  An element in `alist` whose  first element is in `==`
 *                        relationship with `key`.
 */
VALUE rb_ary_rassoc(VALUE alist, VALUE key);

/**
 * Queries if the passed array has the passed entry.
 *
 * @param[in]  ary          Target array to scan.
 * @param[in]  elem         Target array to find.
 * @retval     RUBY_Qfalse  No element  in `ary`  is in `==`  relationship with
 *                          `elem`.
 * @retval     RUBY_Qtrue   There is at least one  element in `ary` which is in
 *                          `==` relationship with `elem`.
 *
 * @internal
 *
 * This is  the only function  in the  entire C API  that is named  using third
 * person singular  form of  a verb  (except #ISASCII etc.,  which are  not our
 * naming).  The counterpart Ruby API of this function is `Array#include?`.
 */
VALUE rb_ary_includes(VALUE ary, VALUE elem);

/**
 * Recursively compares each elements of the two arrays one-by-one using `<=>`.
 *
 * @param[in]  lhs        Comparison LHS.
 * @param[in]  rhs        Comparison RHS.
 * @retval     RUBY_Qnil  `lhs` and `rhs` are not comparable.
 * @retval     -1         `lhs` is less than `rhs`.
 * @retval      0         They are equal.
 * @retval      1         `rhs` is less then `lhs`.
 */
VALUE rb_ary_cmp(VALUE lhs, VALUE rhs);

/**
 * Replaces the contents of the former object with the contents of the latter.
 *
 * @param[out]  copy               Destination object.
 * @param[in]   orig               Source object.
 * @exception   rb_eTypeError     `orig` has no implicit conversion to Array.
 * @exception   rb_eFrozenError   `copy` is frozen.
 * @return      The passed `copy`.
 * @post        `copy`'s  former  components are  abandoned.   It  now has  the
 *              identical length and contents to `orig`.
 */
VALUE rb_ary_replace(VALUE copy, VALUE orig);

/**
 * This _was_  a generalisation  of `Array#values_at`,  `Struct#values_at`, and
 * `MatchData#values_at`.  It begun its life  as a refactoring effort.  However
 * as Ruby  evolves over  time, as  of writing  none of  aforementioned methods
 * share their implementations at all.   This function is not deprecated; still
 * works as it has been.  But it is now kind of like a rudimentum.
 *
 * This  function  takes an  object,  which  is a  receiver,  and  a series  of
 * "indices",  which are  either integers,  or ranges  of integers.   Calls the
 * passed callback  for each of those  indices, along with the  receiver.  This
 * callback is  expected to do something  like rb_ary_aref(), rb_struct_aref(),
 * etc.   In  case of  a  range  index  rb_range_beg_len() expands  the  range.
 * Finally  return values  of  the  callback are  gathered  as  an array,  then
 * returned.
 *
 * @param[in]  obj   Arbitrary ruby object.
 * @param[in]  olen  "Length" of `obj`.
 * @param[in]  argc  Number of objects of `argv`.
 * @param[in]  argv  List of "indices", described above.
 * @param[in]  func  Callback function.
 * @return     A new instance of ::rb_cArray gathering `func`outputs.
 *
 * @internal
 *
 * `Array#values_at` no  longer uses this  function.  There is no  reason apart
 * from historical ones to list this function here.
 */
VALUE rb_get_values_at(VALUE obj, long olen, int argc, const VALUE *argv, VALUE (*func)(VALUE obj, long oidx));

/**
 * Expands or shrinks the passed array to the passed length.
 *
 * @param[out]  ary              An array to modify.
 * @param[in]   len              Desired length of `ary`.
 * @exception   rb_eFrozenError  `ary`  is frozen.
 * @exception   rb_eIndexError   `len` too long.
 * @return      The passed `ary`.
 * @post        `ary`'s length is `len`.
 * @post        Depending on `len` and previous  length of `ary` this operation
 *              can  also create  a series  of "hole"  positions inside  of the
 *              backend storage.  They are filled with ::RUBY_Qnil.
 *
 * @internal
 *
 * `len` is signed.  Intentional or...?
 */
VALUE rb_ary_resize(VALUE ary, long len);

#define rb_ary_new2 rb_ary_new_capa         /**< @old{rb_ary_new_capa} */
#define rb_ary_new3 rb_ary_new_from_args    /**< @old{rb_ary_new_from_args} */
#define rb_ary_new4 rb_ary_new_from_values  /**< @old{rb_ary_new_from_values} */

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERN_ARRAY_H */
ruby/internal/intern/bignum.h000064400000074054151732674230012316 0ustar00#ifndef RBIMPL_INTERN_BIGNUM_H                       /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_BIGNUM_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Public APIs related to so-called rb_cBignum.
 */
#include "ruby/internal/config.h"

#ifdef STDC_HEADERS
# include <stddef.h>
#endif

#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/backward/2/long_long.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/* bignum.c */

/**
 * Allocates a bignum object.
 *
 * @param[in]  len   Length of the bignum's backend storage, in words.
 * @param[in]  sign  Sign of the bignum.
 * @return     An allocated new bignum instance.
 * @note       This only allocates an object, doesn't fill its value in.
 *
 * @internal
 *
 * @shyouhei  finds it  hard to  use from  extension libraries.   `len` is  per
 * `BDIGIT` but its definition is hidden.
 */
VALUE rb_big_new(size_t len, int sign);

/**
 * Queries if  the passed bignum  instance is a  "bigzero".  What is a bigzero?
 * Well, bignums  are for very big  integers, but can also  represent tiny ones
 * like -1,  0, 1.   Bigzero are  instances of bignums  whose values  are zero.
 * Knowing if a bignum is bigzero can  be handy on occasions, like for instance
 * detecting division by zero situation.
 *
 * @param[in]  x  A bignum.
 * @retval     1  It is a bigzero.
 * @retval     0  Otherwise.
 */
int rb_bigzero_p(VALUE x);

/**
 * Duplicates the given bignum.
 *
 * @param[in]  num  A bignum.
 * @return     An allocated bignum, who is equivalent to `num`.
 */
VALUE rb_big_clone(VALUE num);

/**
 * Destructively modify the passed bignum into 2's complement representation.
 *
 * @note  By default bignums are in signed magnitude system.
 *
 * @param[out]  num  A bignum to modify.
 */
void rb_big_2comp(VALUE num);

/**
 * Normalises the passed bignum.  It for  instance returns a fixnum of the same
 * value if fixnum can represent that number.
 *
 * @param[out]  x  Target bignum (can be destructively modified).
 * @return      An integer of the identical value (can be `x` itself).
 */
VALUE rb_big_norm(VALUE x);

/**
 * Destructively resizes the backend storage of the passed bignum.
 *
 * @param[out]  big  A bignum.
 * @param[in]   len  New length of `big`'s backend, in words.
 */
void rb_big_resize(VALUE big, size_t len);

RBIMPL_ATTR_NONNULL(())
/**
 * Parses C's string to convert into a Ruby's integer.  It understands prefixes
 * (e.g. `0x`) and underscores.
 *
 * @param[in]  str           Stringised representation of the return value.
 * @param[in]  base          Base of conversion.   Must be `-36..36` inclusive,
 *                           except `1`.  `2..36` means  the conversion is done
 *                           according to it,  with unmatched prefix understood
 *                           as  a part  of  the result.   `-36..-2` means  the
 *                           conversion  honours prefix  when  present, or  use
 *                           `-base` when  absent. `0` is equivalent  to `-10`.
 *                           `-1` mandates a prefix. `1` is an error.
 * @param[in]  badcheck      Whether  to raise  ::rb_eArgError on  failure.  If
 *                           `0`  is  passed  here  this  function  can  return
 *                           `INT2FIX(0)` for parse errors.
 * @exception  rb_eArgError  Failed to parse (and `badcheck` is truthy).
 * @return     An instance of ::rb_cInteger,  which is a numeric interpretation
 *             of what is written in `str`.
 *
 * @internal
 *
 * Not sure if it intentionally accepts `base  == -1` or is just buggy.  Nobody
 * practically uses negative bases these days.
 */
VALUE rb_cstr_to_inum(const char *str, int base, int badcheck);

/**
 * Identical to rb_cstr2inum(), except it takes Ruby's strings instead of C's.
 *
 * @param[in]  str                 Stringised  representation   of  the  return
 *                                 value.
 * @param[in]  base                Base  of  conversion.    Must  be  `-36..36`
 *                                 inclusive,  except `1`.   `2..36` means  the
 *                                 conversion  is done  according  to it,  with
 *                                 unmatched prefix understood as a part of the
 *                                 result.   `-36..-2`   means  the  conversion
 *                                 honours prefix when  present, or use `-base`
 *                                 when  absent. `0`  is  equivalent to  `-10`.
 *                                 `-1` mandates a prefix. `1` is an error.
 * @param[in]  badcheck            Whether to raise  ::rb_eArgError on failure.
 *                                 If  `0` is  passed  here  this function  can
 *                                 return `INT2FIX(0)` for parse errors.
 * @exception  rb_eArgError        Failed to parse (and `badcheck` is truthy).
 * @exception  rb_eTypeError       `str` is not a string.
 * @exception  rb_eEncCompatError  `str` is not ASCII compatible.
 * @return     An instance of ::rb_cInteger,  which is a numeric interpretation
 *             of what is written in `str`.
 */
VALUE rb_str_to_inum(VALUE str, int base, int badcheck);

RBIMPL_ATTR_NONNULL(())
/**
 * Identical to rb_cstr_to_inum(), except the second argument controls the base
 * and badcheck at  once.  It basically doesn't raise for  parse errors, unless
 * the base is zero.
 *
 * This is an older API.  New codes might prefer rb_cstr_to_inum().
 *
 * @param[in]  str           Stringised representation of the return value.
 * @param[in]  base          Base of conversion.   Must be `-36..36` inclusive,
 *                           except `1`.  `2..36` means  the conversion is done
 *                           according to it,  with unmatched prefix understood
 *                           as  a part  of  the result.   `-36..-2` means  the
 *                           conversion  honours prefix  when  present, or  use
 *                           `-base` when  absent. `0` is equivalent  to `-10`.
 *                           `-1` mandates a prefix. `1` is an error.
 * @exception  rb_eArgError  Failed to parse (and `base` is zero).
 * @return     An instance of ::rb_cInteger,  which is a numeric interpretation
 *             of what is written in `str`.
 */
VALUE rb_cstr2inum(const char *str, int base);

/**
 * Identical to rb_str_to_inum(), except the  second argument controls the base
 * and  badcheck at  once.  It  can  also be  seen  as a  routine identical  to
 * rb_cstr2inum(), except it takes Ruby's strings instead of C's.
 *
 * This is an older API.  New codes might prefer rb_cstr_to_inum().
 *
 * @param[in]  str                 Stringised  representation   of  the  return
 *                                 value.
 * @param[in]  base                Base  of  conversion.    Must  be  `-36..36`
 *                                 inclusive,  except `1`.   `2..36` means  the
 *                                 conversion  is done  according  to it,  with
 *                                 unmatched prefix understood as a part of the
 *                                 result.   `-36..-2`   means  the  conversion
 *                                 honours prefix when  present, or use `-base`
 *                                 when  absent. `0`  is  equivalent to  `-10`.
 *                                 `-1` mandates a prefix. `1` is an error.
 * @exception  rb_eArgError        Failed to parse (and `base` is zero).
 * @exception  rb_eTypeError       `str` is not a string.
 * @exception  rb_eEncCompatError  `str` is not ASCII compatible.
 * @return     An instance of ::rb_cInteger,  which is a numeric interpretation
 *             of what is written in `str`.
 */
VALUE rb_str2inum(VALUE str, int base);

/**
 * Generates a place-value representation of the passed integer.
 *
 * @param[in]  x               An integer to stringify.
 * @param[in]  base            `2` to `36` inclusive for each radix.
 * @exception  rb_eArgError    `base` is out of range.
 * @exception  rb_eRangeError  `x` is too big, cannot represent in string.
 * @return     An instance of ::rb_cString which represents `x`.
 */
VALUE rb_big2str(VALUE x, int base);

/**
 * Converts a bignum into C's `long`.
 *
 * @param[in]  x               A bignum.
 * @exception  rb_eRangeError  `x` is out of range of `long`.
 * @return     The passed value converted into C's `long`.
 */
long rb_big2long(VALUE x);

/** @alias{rb_big2long} */
#define rb_big2int(x) rb_big2long(x)

/**
 * Converts a bignum into C's `unsigned long`.
 *
 * @param[in]  x               A bignum.
 * @exception  rb_eRangeError  `x` is out of range of `unsigned long`.
 * @return     The passed value converted into C's `unsigned long`.
 *
 * @internal
 *
 * This function  can generate  a very  large positive  integer for  a negative
 * input.   For instance  applying  Ruby's  -4,611,686,018,427,387,905 to  this
 * function yields C's  13,835,058,055,282,163,711 on my machine.   This is how
 * it has been.  Cannot change any longer.
 */
unsigned long rb_big2ulong(VALUE x);

/** @alias{rb_big2long} */
#define rb_big2uint(x) rb_big2ulong(x)

#if HAVE_LONG_LONG
/**
 * Converts a bignum into C's `long long`.
 *
 * @param[in]  x               A bignum.
 * @exception  rb_eRangeError  `x` is out of range of `long long`.
 * @return     The passed value converted into C's `long long`.
 */
LONG_LONG rb_big2ll(VALUE);

/**
 * Converts a bignum into C's `unsigned long long`.
 *
 * @param[in]  x               A bignum.
 * @exception  rb_eRangeError  `x` is out of range of `unsigned long long`.
 * @return     The passed value converted into C's `unsigned long long`.
 *
 * @internal
 *
 * This function  can generate  a very  large positive  integer for  a negative
 * input.   For instance  applying  Ruby's  -4,611,686,018,427,387,905 to  this
 * function yields C's  13,835,058,055,282,163,711 on my machine.   This is how
 * it has been.  Cannot change any longer.
 */
unsigned LONG_LONG rb_big2ull(VALUE);

#endif  /* HAVE_LONG_LONG */

RBIMPL_ATTR_NONNULL(())
/**
 * Converts a bignum into a series of its parts.
 *
 * @param[in]   val            An integer.
 * @param[out]  buf            Return buffer.
 * @param[in]   num_longs      Number of words of `buf`.
 * @exception   rb_eTypeError  `val` doesn't respond to `#to_int`.
 * @post        `buf` is filled with  `val`'s 2's complement representation, in
 *              the host CPU's  native byte order, from  least significant word
 *              towards the most significant one, for `num_longs` words.
 * @note        The "pack" terminology comes from `Array#pack`.
 */
void rb_big_pack(VALUE val, unsigned long *buf, long num_longs);

RBIMPL_ATTR_NONNULL(())
/**
 * Constructs a (possibly very big) bignum from a series of integers.  `buf[0]`
 * would be the return value's least significant word; `buf[num_longs-1]` would
 * be that of most significant.
 *
 * @param[in]  buf           A series of integers.
 * @param[in]  num_longs     Number of words of `buf`.
 * @exception  rb_eArgError  Result would be too big.
 * @return     An instance  of ::rb_cInteger which  is an "unpack"-ed  value of
 *             the parameters.
 * @note       The "unpack" terminology comes from `String#pack`.
 */
VALUE rb_big_unpack(unsigned long *buf, long num_longs);

/* pack.c */

RBIMPL_ATTR_NONNULL(())
/**
 * Encodes a Unicode codepoint into its UTF-8 representation.
 *
 * @param[out]  buf             Return buffer, must at least be 6 bytes width.
 * @param[in]   uv              An Unicode codepoint.
 * @exception   rb_eRangeError  `uv` is out of Unicode.
 * @return      Number of bytes written to `buf`
 * @post        `buf` holds a UTF-8 representation of `uv`.
 */
int rb_uv_to_utf8(char buf[6], unsigned long uv);

/* bignum.c */

/**
 * Converts a C's `double` into a bignum.
 *
 * @param[in]  d                     A value to convert.
 * @exception  rb_eFloatDomainError  `d` is Inf/NaN.
 * @return     An instance of ::rb_cInteger whose value is approximately `d`.
 *
 * @internal
 *
 * @shyouhei is not sure if the result  is guaranteed to be the nearest integer
 * of `d`.
 */
VALUE rb_dbl2big(double d);

/**
 * Converts a bignum into C's `double`.
 *
 * @param[in]  x  A bignum.
 * @return     The passed value converted into C's `double`.
 *
 * @internal
 *
 * @shyouhei is not sure if the result  is guaranteed to be `x`'s nearest value
 * that a `double` can represent.
 */
double rb_big2dbl(VALUE x);

/**
 * Compares the passed two bignums.
 *
 * @param[in]  lhs  Comparison LHS.
 * @param[in]  rhs  Comparison RHS.
 * @retval     -1   `rhs` is bigger than `lhs`.
 * @retval     0    They are identical.
 * @retval     1    `lhs` is bigger than `rhs`.
 * @see        rb_num_coerce_cmp()
 */
VALUE rb_big_cmp(VALUE lhs, VALUE rhs);

/**
 * Equality, in terms of `==`.  This checks if the _value_ is the same, not the
 * identity.  For instance `1 == 1.0` must hold.
 *
 * @param[in]  lhs          Comparison LHS.
 * @param[in]  rhs          Comparison RHS.
 * @retval     RUBY_Qtrue   They are the same.
 * @retval     RUBY_Qfalse  They are different.
 */
VALUE rb_big_eq(VALUE lhs, VALUE rhs);

/**
 * Equality,  in terms  of  `eql?`.   Unlike rb_big_eq()  it  does not  convert
 * ::rb_cFloat etc.   This function  returns ::RUBY_Qtrue if  and only  if both
 * parameters are bignums, which represent the identical numerical value.
 *
 * @param[in]  lhs          Comparison LHS.
 * @param[in]  rhs          Comparison RHS.
 * @retval     RUBY_Qtrue   They are identical.
 * @retval     RUBY_Qfalse  They are distinct.
 */
VALUE rb_big_eql(VALUE lhs, VALUE rhs);

/**
 * Performs addition of the passed two objects.
 *
 * @param[in]  x  A bignum.
 * @param[in]  y  Arbitrary ruby object.
 * @return     What `x + y` evaluates to.
 * @see        rb_num_coerce_bin()
 */
VALUE rb_big_plus(VALUE x, VALUE y);

/**
 * Performs subtraction of the passed two objects.
 *
 * @param[in]  x  A bignum.
 * @param[in]  y  Arbitrary ruby object.
 * @return     What `x - y` evaluates to.
 * @see        rb_num_coerce_bin()
 */
VALUE rb_big_minus(VALUE x, VALUE y);

/**
 * Performs multiplication of the passed two objects.
 *
 * @param[in]  x  A bignum.
 * @param[in]  y  Arbitrary ruby object.
 * @return     What `x * y` evaluates to.
 * @see        rb_num_coerce_bin()
 */
VALUE rb_big_mul(VALUE x, VALUE y);

/**
 * Performs division of the passed two objects.
 *
 * @param[in]  x  A bignum.
 * @param[in]  y  Arbitrary ruby object.
 * @return     What `x / y` evaluates to.
 * @see        rb_num_coerce_bin()
 */
VALUE rb_big_div(VALUE x, VALUE y);

/**
 * Performs "integer division".  This is different from rb_big_div().
 *
 * @param[in]  x  A bignum.
 * @param[in]  y  Arbitrary ruby object.
 * @return     What `x.div y` evaluates to.
 * @see        rb_num_coerce_bin()
 */
VALUE rb_big_idiv(VALUE x, VALUE y);

/**
 * Performs modulo of the passed two objects.
 *
 * @param[in]  x  A bignum.
 * @param[in]  y  Arbitrary ruby object.
 * @return     What `x % y` evaluates to.
 * @see        rb_num_coerce_bin()
 *
 * @internal
 *
 * There also is `rb_big_remainder()` internally,  which is different from this
 * one.
 */
VALUE rb_big_modulo(VALUE x, VALUE y);

/**
 * Performs "divmod" operation.   The operation in bignum's context  is that it
 * calculates rb_big_idiv() and rb_big_modulo() at once.
 *
 * @param[in]  x  A bignum.
 * @param[in]  y  Arbitrary ruby object.
 * @return     What `x.divmod y` evaluates to.
 * @see        rb_num_coerce_bin()
 */
VALUE rb_big_divmod(VALUE x, VALUE y);

/**
 * Raises `x` to the powerof `y`.
 *
 * @param[in]  x  A bignum.
 * @param[in]  y  Arbitrary ruby object.
 * @return     What `x ** y` evaluates to.
 * @see        rb_num_coerce_bin()
 * @note       This can return  an instance of ::rb_cFloat, even  when both `x`
 *             and `y` are bignums.  Or an instance of ::rb_cRational, when for
 *             instance `y` is negative.
 */
VALUE rb_big_pow(VALUE x, VALUE y);

/**
 * Performs bitwise and of the passed two objects.
 *
 * @param[in]  x  A bignum.
 * @param[in]  y  Arbitrary ruby object.
 * @return     What `x & y` evaluates to.
 * @see        rb_num_coerce_bit()
 */
VALUE rb_big_and(VALUE x, VALUE y);

/**
 * Performs bitwise or of the passed two objects.
 *
 * @param[in]  x  A bignum.
 * @param[in]  y  Arbitrary ruby object.
 * @return     What `x | y` evaluates to.
 * @see        rb_num_coerce_bit()
 */
VALUE rb_big_or(VALUE x, VALUE y);

/**
 * Performs exclusive or of the passed two objects.
 *
 * @param[in]  x  A bignum.
 * @param[in]  y  Arbitrary ruby object.
 * @return     What `x ^ y` evaluates to.
 * @see        rb_num_coerce_bit()
 */
VALUE rb_big_xor(VALUE x, VALUE y);

/**
 * Performs shift left.
 *
 * @param[in]  x              A bignum.
 * @param[in]  y              Shift amount.
 * @exception  rb_eTypeError  `y` is not an integer.
 * @exception  rb_eArgError   `y` is too big.
 * @return     `x` shifted left to `y` bits.
 * @note       `y` can be negative.  Shifts right then.
 */
VALUE rb_big_lshift(VALUE x, VALUE y);

/**
 * Performs shift right.
 *
 * @param[in]  x              A bignum.
 * @param[in]  y              Shift amount.
 * @exception  rb_eTypeError  `y` is not an integer.
 * @return     `x` shifted right to `y` bits.
 * @note       This is arithmetic.  Because bignums  are not bitfields there is
 *             no shift right logical operator.
 */
VALUE rb_big_rshift(VALUE x, VALUE y);

/**
 * @name Flags for rb_integer_pack()/rb_integer_unpack()
 * @{
 */

/** Stores/interprets the most significant word as the first word. */
#define INTEGER_PACK_MSWORD_FIRST       0x01

/** Stores/interprets the least significant word as the first word. */
#define INTEGER_PACK_LSWORD_FIRST       0x02

/**
 * Stores/interprets the most  significant byte in a word as  the first byte in
 * the word.
 */
#define INTEGER_PACK_MSBYTE_FIRST       0x10

/**
 * Stores/interprets the least significant byte in  a word as the first byte in
 * the word.
 */
#define INTEGER_PACK_LSBYTE_FIRST       0x20

/**
 * Means   either  #INTEGER_PACK_MSBYTE_FIRST   or  #INTEGER_PACK_LSBYTE_FIRST,
 * depending on the host processor's endian.
 */
#define INTEGER_PACK_NATIVE_BYTE_ORDER  0x40

/** Uses 2's complement representation. */
#define INTEGER_PACK_2COMP              0x80

/** Uses "generic" implementation (handy on test). */
#define INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION     0x400

/**
 * Always generates  a bignum object even  if the integer can  be representable
 * using fixnum scheme (unpack only)
 */
#define INTEGER_PACK_FORCE_BIGNUM       0x100

/**
 * Interprets the  input as  a signed  negative number  (unpack only).   If not
 * specified returns a positive number.
 */
#define INTEGER_PACK_NEGATIVE           0x200

/** Little endian combination. */
#define INTEGER_PACK_LITTLE_ENDIAN \
    (INTEGER_PACK_LSWORD_FIRST | \
     INTEGER_PACK_LSBYTE_FIRST)

/** Big endian combination */
#define INTEGER_PACK_BIG_ENDIAN \
    (INTEGER_PACK_MSWORD_FIRST | \
     INTEGER_PACK_MSBYTE_FIRST)

/** @} */

RBIMPL_ATTR_NONNULL(())
/**
 * Exports an integer into a buffer.   This function fills the buffer specified
 * by `words`  and `numwords` as `val`  in the format specified  by `wordsize`,
 * `nails` and `flags`.
 *
 * @param[in]   val            Integer   or  integer-like   object  which   has
 *                             `#to_int` method.
 * @param[out]  words          Return buffer.
 * @param[in]   numwords       Number of words of `words`.
 * @param[in]   wordsize       Number of bytes per word.
 * @param[in]   nails          Number  of   padding  bits  in  a   word.   Most
 *                             significant nails  bits of each word  are filled
 *                             by zero.
 * @param[in]   flags          Bitwise  or  of   constants  whose  name  starts
 *                             "INTEGER_PACK_".
 * @exception   rb_eTypeError  `val` doesn't respond to `#to_int`.
 *
 * Possible flags are:
 *
 *   - #INTEGER_PACK_MSWORD_FIRST:
 *       Stores the most significant word as the first word.
 *
 *   - #INTEGER_PACK_LSWORD_FIRST:
 *       Stores the least significant word as the first word.
 *
 *   - #INTEGER_PACK_MSBYTE_FIRST:
 *       Stores the most  significant byte in a  word as the first  byte in the
 *       word.
 *
 *   - #INTEGER_PACK_LSBYTE_FIRST:
 *       Stores the least significant  byte in a word as the  first byte in the
 *       word.
 *
 *   - #INTEGER_PACK_NATIVE_BYTE_ORDER:
 *       Either   #INTEGER_PACK_MSBYTE_FIRST    or   #INTEGER_PACK_LSBYTE_FIRST
 *       corresponding to the host's endian.
 *
 *   - #INTEGER_PACK_2COMP:
 *       Uses 2's complement representation.
 *
 *   - #INTEGER_PACK_LITTLE_ENDIAN: Shorthand of
 *       `INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_LSBYTE_FIRST`.
 *
 *   - #INTEGER_PACK_BIG_ENDIAN: Shorthand of
 *       `INTEGER_PACK_MSWORD_FIRST|INTEGER_PACK_MSBYTE_FIRST`.
 *
 *   - #INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION:
 *       Uses generic implementation (for test and debug).
 *
 * This  function  fills  the  buffer  specified  by  `words`  as  `val`'s  2's
 * complement representation  if #INTEGER_PACK_2COMP  is specified  in `flags`.
 * Otherwise it fills `words` as `abs(val)`  and signedness is returned via the
 * return value.
 *
 * @return  The  signedness and  overflow  condition.   The overflow  condition
 *          depends on #INTEGER_PACK_2COMP.
 *
 * When #INTEGER_PACK_2COMP is not specified:
 *
 *   - `-2` :
 *       Negative overflow.  `val <= -2**(numwords*(wordsize*CHAR_BIT-nails))`
 *
 *   - `-1` :
 *       Negative without overflow.
 *       `-2**(numwords*(wordsize*CHAR_BIT-nails)) < val < 0`
 *
 *   - `0` : zero.  `val == 0`
 *
 *   - `1` :
 *       Positive without overflow.
 *       `0 < val < 2**(numwords*(wordsize*CHAR_BIT-nails))`
 *
 *   - `2` :
 *       Positive overflow.  `2**(numwords*(wordsize*CHAR_BIT-nails)) <= val`
 *
 * When #INTEGER_PACK_2COMP is specified:
 *
 *   - `-2` :
 *       Negative overflow.  `val < -2**(numwords*(wordsize*CHAR_BIT-nails))`
 *
 *   - `-1` :
 *       Negative without overflow.
 *       `-2**(numwords*(wordsize*CHAR_BIT-nails)) <= val < 0`
 *
 *   - `0` : zero.  `val == 0`
 *
 *   - `1` :
 *       Positive without overflow.
 *       `0 < val < 2**(numwords*(wordsize*CHAR_BIT-nails))`
 *
 *   - `2` :
 *       Positive overflow.  `2**(numwords*(wordsize*CHAR_BIT-nails)) <= val`
 *
 * The value,  `-2**(numwords*(wordsize*CHAR_BIT-nails))`, is  representable in
 * 2's complement representation  but not representable in  absolute value.  So
 * `-1`  is returned  for the  value  if #INTEGER_PACK_2COMP  is specified  but
 * returns `-2` if #INTEGER_PACK_2COMP is not specified.
 *
 * The least significant words are filled in the buffer when overflow occur.
 */
int rb_integer_pack(VALUE val, void *words, size_t numwords, size_t wordsize, size_t nails, int flags);

RBIMPL_ATTR_NONNULL(())
/**
 * Import an integer from a buffer.
 *
 * @param[in]  words         Buffer to import.
 * @param[in]  numwords      Number of words of `words`.
 * @param[in]  wordsize      Number of bytes per word.
 * @param[in]  nails         Number   of  padding   bits  in   a  word.    Most
 *                           significant nails bits of each word are ignored.
 * @param[in]  flags         Bitwise   or  of   constants  whose   name  starts
 *                           "INTEGER_PACK_".
 * @exception  rb_eArgError  `numwords * wordsize` too big.
 *
 * Possible flags are:
 *
 *   - #INTEGER_PACK_MSWORD_FIRST:
 *       Interpret the first word as the most significant word.
 *
 *   - #INTEGER_PACK_LSWORD_FIRST:
 *       Interpret the first word as the least significant word.
 *
 *   - #INTEGER_PACK_MSBYTE_FIRST:
 *       Interpret the first byte in a word as the most significant byte in the
 *       word.
 *
 *   - #INTEGER_PACK_LSBYTE_FIRST:
 *       Interpret the  first byte in a  word as the least  significant byte in
 *       the word.
 *
 *   - #INTEGER_PACK_NATIVE_BYTE_ORDER:
 *       Either   #INTEGER_PACK_MSBYTE_FIRST    or   #INTEGER_PACK_LSBYTE_FIRST
 *       corresponding to the host's endian.
 *
 *   - #INTEGER_PACK_2COMP:
 *       Uses 2's complement representation.
 *
 *   - #INTEGER_PACK_LITTLE_ENDIAN: Shorthand of
 *       `INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_LSBYTE_FIRST`
 *
 *   - #INTEGER_PACK_BIG_ENDIAN: Shorthand of
 *       `INTEGER_PACK_MSWORD_FIRST|INTEGER_PACK_MSBYTE_FIRST`
 *
 *   - #INTEGER_PACK_FORCE_BIGNUM:
 *       Returns a bignum even if its value is representable as a fixnum.
 *
 *   - #INTEGER_PACK_NEGATIVE:
 *       Returns a  non-positive value.  (Returns a  non-negative value  if not
 *       specified.)
 *
 *   - #INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION:
 *       Uses generic implementation (for test and debug).
 *
 * @return  An  instance  of  ::rb_cInteger  whose  value  is  the  interpreted
 *          `words`.    The   range   of    the   result   value   depends   on
 *          #INTEGER_PACK_2COMP and #INTEGER_PACK_NEGATIVE.
 *
 * When #INTEGER_PACK_2COMP is not set:
 *
 *   - `0 <= val < 2**(numwords*(wordsize*CHAR_BIT-nails))` if
 *     `!INTEGER_PACK_NEGATIVE`
 *
 *   - `-2**(numwords*(wordsize*CHAR_BIT-nails)) < val <= 0` if
 *     `INTEGER_PACK_NEGATIVE`
 *
 * When #INTEGER_PACK_2COMP is set:
 *
 *   - `-2**(numwords*(wordsize*CHAR_BIT-nails)-1)` `<= val <=`
 *     `2**(numwords*(wordsize*CHAR_BIT-nails)-1)-1` if
 *     `!INTEGER_PACK_NEGATIVE`
 *
 *   - `-2**(numwords*(wordsize*CHAR_BIT-nails)) <= val <= -1` if
 *     `INTEGER_PACK_NEGATIVE`
 *
 * Passing  #INTEGER_PACK_2COMP   without  #INTEGER_PACK_NEGATIVE   means  sign
 * extension.  #INTEGER_PACK_2COMP  with #INTEGER_PACK_NEGATIVE  means assuming
 * the higher bits are `1`.
 *
 * Note   that  this   function  returns   0  when   `numwords`  is   zero  and
 * #INTEGER_PACK_2COMP is set but #INTEGER_PACK_NEGATIVE is not set.
 */
VALUE rb_integer_unpack(const void *words, size_t numwords, size_t wordsize, size_t nails, int flags);

/**
 * Calculates the number of bytes needed to represent the absolute value of the
 * passed integer.
 *
 * @param[in]   val            Integer   or  integer-like   object  which   has
 *                             `#to_int` method.
 * @param[out]  nlz_bits_ret   Number  of   leading  zero  bits  in   the  most
 *                             significant byte is returned if not `NULL`.
 * @exception   rb_eTypeError  `val` doesn't respond to `#to_int`.
 * @return      `((val_numbits * CHAR_BIT + CHAR_BIT - 1) / CHAR_BIT)`,   where
 *              val_numbits is the number of bits of `abs(val)`.
 * @post        If `nlz_bits_ret` is not `NULL`,
 *              `(return_value * CHAR_BIT - val_numbits)`    is    stored    in
 *              `*nlz_bits_ret`.  In this case,
 *              `0 <= *nlz_bits_ret < CHAR_BIT`.
 *
 * This function should not overflow.
 */
size_t rb_absint_size(VALUE val, int *nlz_bits_ret);

/**
 * Calculates the  number of words needed  represent the absolute value  of the
 * passed  integer.  Unlike  rb_absint_size() this  function can  overflow.  It
 * returns `(size_t)-1` then.
 *
 * @param[in]   val            Integer   or  integer-like   object  which   has
 *                             `#to_int` method.
 * @param[in]   word_numbits   Number of bits per word.
 * @param[out]  nlz_bits_ret   Number  of   leading  zero  bits  in   the  most
 *                             significant word is returned if not `NULL`.
 * @exception   rb_eTypeError  `val` doesn't respond to `#to_int`.
 * @retval      (size_t)-1     Overflowed.
 * @retval      otherwise
 *              `((val_numbits * CHAR_BIT + word_numbits - 1) / word_numbits)`,
 *              where val_numbits is the number of bits of `abs(val)`.
 * @post        If  `nlz_bits_ret` is  not  `NULL` and  there  is no  overflow,
 *              `(return_value * word_numbits - val_numbits)`   is  stored   in
 *              `*nlz_bits_ret`.  In this case,
 *              `0 <= *nlz_bits_ret < word_numbits.`
 *
 */
size_t rb_absint_numwords(VALUE val, size_t word_numbits, size_t *nlz_bits_ret);

/**
 * Tests `abs(val)` consists only of a bit or not.
 *
 * @param[in]   val            Integer   or  integer-like   object  which   has
 *                             `#to_int` method.
 * @exception   rb_eTypeError  `val` doesn't respond to `#to_int`.
 * @retval      1              `abs(val) == 1 << n` for some `n >= 0`.
 * @retval      0              Otherwise.
 *
 * rb_absint_singlebit_p() can  be used to  determine required buffer  size for
 * rb_integer_pack() used with #INTEGER_PACK_2COMP (two's complement).
 *
 * Following example  calculates number  of bits required  to represent  val in
 * two's complement number, without sign bit.
 *
 * ```CXX
 *   size_t size;
 *   int neg = FIXNUM_P(val) ? FIX2LONG(val) < 0 : BIGNUM_NEGATIVE_P(val);
 *   size = rb_absint_numwords(val, 1, NULL)
 *   if (size == (size_t)-1) ...overflow...
 *   if (neg && rb_absint_singlebit_p(val))
 *     size--;
 * ```
 *
 * Following example  calculates number of  bytes required to represent  val in
 * two's complement number, with sign bit.
 *
 * ```CXX
 *   size_t size;
 *   int neg = FIXNUM_P(val) ? FIX2LONG(val) < 0 : BIGNUM_NEGATIVE_P(val);
 *   int nlz_bits;
 *   size = rb_absint_size(val, &nlz_bits);
 *   if (nlz_bits == 0 && !(neg && rb_absint_singlebit_p(val)))
 *     size++;
 * ```
 */
int rb_absint_singlebit_p(VALUE val);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERN_BIGNUM_H */
ruby/internal/intern/re.h000064400000021030151732674230011425 0ustar00#ifndef RBIMPL_INTERN_RE_H                           /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_RE_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Public APIs related to ::rb_cRegexp.
 */
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/* re.c */

/**
 * @deprecated  This macro once was a thing in the old days, but makes no sense
 *              any  longer today.   Exists  here  for backwards  compatibility
 *              only.  You can safely forget about it.
 *
 * @internal
 *
 * This was a  function that switched between memcmp  and rb_memcicmp depending
 * on then-called `ruby_ignorecase`, or the `$=` global variable.  That feature
 * was abandoned in sometime around version 1.9.0.
 */
#define rb_memcmp memcmp

/**
 * Identical to  st_locale_insensitive_strcasecmp(), except  it is  timing safe
 * and returns something different.
 *
 * @param[in]  s1  Comparison LHS.
 * @param[in]  s2  Comparison RHS.
 * @param[in]  n   Comparison shall stop after first `n` bytes are scanned.
 * @retval     <0  `s1` is "less" than `s2`.
 * @retval      0  Both sides converted into lowercase would be identical.
 * @retval     >0  `s1` is "greater" than `s2`.
 * @note       The "case" here means that of the POSIX Locale.
 *
 * @internal
 *
 * Can accept NULLs as long as n is also 0, and returns 0.
 */
int rb_memcicmp(const void *s1,const void *s2, long n);

/**
 * Asserts  that  the given  MatchData  is  "occupied".  MatchData  shares  its
 * backend storages  with its  Regexp object.   But programs  can destructively
 * tamper its  contents.  Calling this  function beforehand shall  prevent such
 * modifications to spill over into other objects.
 *
 * @param[out]  md  Target instance of ::rb_cMatch.
 * @post        The object is "busy".
 *
 * @internal
 *
 * There is rb_match_unbusy internally, but extension libraries are left unable
 * to do so.
 */
void rb_match_busy(VALUE md);

/**
 * Identical to rb_reg_nth_match(), except it just returns Boolean.  This could
 * skip allocating a  returning string, resulting in  reduced memory footprints
 * if applicable.
 *
 * @param[in]  n              Match index.
 * @param[in]  md             An instance of ::rb_cMatch.
 * @exception  rb_eTypeError  `md` is not initialised.
 * @retval     RUBY_Qnil      There is no `n`-th capture.
 * @retval     RUBY_Qfalse    There is a `n`-th capture and is empty.
 * @retval     RUBY_Qtrue     There is a `n`-th capture that has something.
 *
 */
VALUE rb_reg_nth_defined(int n, VALUE md);

/**
 * Queries the nth captured substring.
 *
 * @param[in]  n              Match index.
 * @param[in]  md             An instance of ::rb_cMatch.
 * @exception  rb_eTypeError  `md` is not initialised.
 * @retval     RUBY_Qnil      There is no `n`-th capture.
 * @retval     otherwise      An allocated instance of  ::rb_cString containing
 *                            the contents captured.
 */
VALUE rb_reg_nth_match(int n, VALUE md);

/**
 * Queries the index of the given named capture.  Captures could be named.  But
 * that doesn't mean named ones are  not indexed.  A regular expression can mix
 * named  and non-named  captures, and  they  are all  indexed.  This  function
 * converts from a name to its index.
 *
 * @param[in]  match           An instance of ::rb_cMatch.
 * @param[in]  backref         Capture name, in String, Symbol, or Numeric.
 * @exception  rb_eIndexError  No such named capture.
 * @return     The index of the given name.
 */
int rb_reg_backref_number(VALUE match, VALUE backref);

/**
 * This just returns the argument, stringified.  What a poor name.
 *
 * @param[in]  md  An instance of ::rb_cMatch.
 * @return     Its 0th capture (i.e. entire matched string).
 */
VALUE rb_reg_last_match(VALUE md);

/**
 * The portion of the original string before the given match.
 *
 * @param[in]  md  An instance of ::rb_cMatch.
 * @return     Its "prematch".  This is perl's ``$```.
 */
VALUE rb_reg_match_pre(VALUE md);

/**
 * The portion of the original string after the given match.
 *
 * @param[in]  md  An instance of ::rb_cMatch.
 * @return     Its "postmatch".  This is perl's `$'`.
 */
VALUE rb_reg_match_post(VALUE md);

/**
 * The portion of the original string that captured at the very last.
 *
 * @param[in]  md  An instance of ::rb_cMatch.
 * @return     Its "lastmatch".  This is perl's `$+`.
 */
VALUE rb_reg_match_last(VALUE md);

/**
 * @private
 *
 * @deprecated  This macro once was a thing in the old days, but makes no sense
 *              any  longer today.   Exists  here  for backwards  compatibility
 *              only.  You can safely forget about it.
 */
#define HAVE_RB_REG_NEW_STR 1

/**
 * Identical to rb_reg_new(),  except it takes the expression  in Ruby's string
 * instead of C's.
 *
 * @param[in]  src              Source code in String.
 * @param[in]  opts             Options e.g. ONIG_OPTION_MULTILINE.
 * @exception  rb_eRegexpError  `src` and `opts` do not interface.
 * @return     Allocated new instance of ::rb_cRegexp.
 */
VALUE rb_reg_new_str(VALUE src, int opts);

RBIMPL_ATTR_NONNULL(())
/**
 * Creates a new Regular expression.
 *
 * @param[in]  src              Source code.
 * @param[in]  len              `strlen(src)`.
 * @param[in]  opts             Options e.g. ONIG_OPTION_MULTILINE.
 * @return     Allocated new instance of ::rb_cRegexp.
 */
VALUE rb_reg_new(const char *src, long len, int opts);

/**
 * Allocates an instance of ::rb_cRegexp.
 *
 * @private
 *
 * Nobody  should  call  this  function.   Regular  expressions  that  are  not
 * initialised must not exist in the wild.
 */
VALUE rb_reg_alloc(void);

/**
 * Initialises an instance of ::rb_cRegexp.
 *
 * @private
 *
 * This just raises  for ordinal regexp objects.  Extension  libraries must not
 * use.
 */
VALUE rb_reg_init_str(VALUE re, VALUE s, int options);

/**
 * This is the match operator.
 *
 * @param[in]  re               An instance of ::rb_cRegexp.
 * @param[in]  str              An instance of ::rb_cString.
 * @exception  rb_eTypeError    `str` is not a string.
 * @exception  rb_eRegexpError  Error inside of Onigmo (unlikely).
 * @retval     RUBY_Qnil        Match failed.
 * @retval     otherwise        Matched  position  (character index  inside  of
 *                              `str`).
 * @post       `Regexp.last_match` is updated.
 * @post       `$&`, `$~`, etc., are updated.
 * @note       If you  do this in  ruby, named  captures are assigned  to local
 *             variable of the local scope.  But that doesn't happen here.  The
 *             assignment is done by the interpreter.
 */
VALUE rb_reg_match(VALUE re, VALUE str);

/**
 * Identical  to rb_reg_match(),  except it  matches against  rb_lastline_get()
 * (or, the `$_`).
 *
 * @param[in]  re               An instance of ::rb_cRegexp.
 * @exception  rb_eRegexpError  Error inside of Onigmo (unlikely).
 * @retval     RUBY_Qnil        Match failed or `$_` is absent.
 * @retval     otherwise        Matched  position  (character index  inside  of
 *                              `$_`).
 * @post       `Regexp.last_match` is updated.
 * @post       `$&`, `$~`, etc., are updated.
 */
VALUE rb_reg_match2(VALUE re);

/**
 * Queries the options of the passed regular expression.
 *
 * @param[in]  re  An instance of ::rb_cRegexp.
 * @return     Its options.
 * @note       Possible return values are defined in Onigmo.h.
 */
int rb_reg_options(VALUE re);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERN_RE_H */
ruby/internal/intern/numeric.h000064400000016770151732674230012500 0ustar00#ifndef RBIMPL_INTERN_NUMERIC_H                      /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_NUMERIC_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Public APIs related to ::rb_cNumeric.
 */
#include "ruby/internal/attr/cold.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"

/**
 * @private
 *
 * @deprecated  This macro once was a thing in the old days, but makes no sense
 *              any  longer today.   Exists  here  for backwards  compatibility
 *              only.  You can safely forget about it.
 */
#define RB_NUM_COERCE_FUNCS_NEED_OPID 1

RBIMPL_SYMBOL_EXPORT_BEGIN()

/* numeric.c */

RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_COLD()
/**
 * Just always raises an exception.
 *
 * @exception  rb_eZeroDivError  Division by zero error.
 */
void rb_num_zerodiv(void);

/**
 * @name Coercion operators.
 *
 * What  is a  coercion?   Well Ruby  is  basically  an OOPL  but  it also  has
 * arithmetic operators.   They are  implemented in  OO manners.   For instance
 * `a+b` is  a binary operation  `+`, whose receiver  is `a`, and  whose (sole)
 * argument is `b`.
 *
 * The problem is, you  often want `a+b == b+a` to hold.  That  is easy if both
 * `a` and `b` belongs to the same class...  Ensuring  `1 + 2 == 2 + 1` is kind
 * of intuitive.  But  if you want `1.0 +  2 == 2 + 1.0`,  things start getting
 * complicated.  `1.0+2` is `Float#+`, while  `2+1.0` is `Integer#+`.  In order
 * to achieve the equality Float's and  Integer's methods must agree with their
 * behaviours.
 *
 * Now.  Floats  versus Integers situation  is still controllable  because they
 * are both  built-in.  But in  Ruby you can  define your own  numeric classes.
 * BigDecimal, which is a rubygems  gem distributed along with the interpreter,
 * is one  of such  examples.  Rational  was another  such example  before.  In
 * short you cannot create list of all possible combination of the classes that
 * could  be  the  operand  of  `+`  operator.  Then  how  do  we  achieve  the
 * commutativity?
 *
 * Here  comes  the concept  of  coercion.   If  a  definition of  an  operator
 * encounters an object  which is unknown to the author,  just assumes that the
 * unknown object  knows how  to handle  the situation.   So for  instance when
 * `1+x` has unknown `x`, it lets the `x` handle this.
 *
 * ```ruby
 * class Foo
 *   def +(x)
 *     if we_know_what_is_x? then
 *       ... # handle here
 *     else
 *       y, z = x.coerce self
 *       return y + z
 *     end
 *   end
 * end
 * ```
 *
 * The `x.coerce` method returns a  2-element array which are "casted" versions
 * of `x` and `self`.
 *
 * @{
 */

/**
 * Coerced binary operation.  This function first coerces the two objects, then
 * applies the operation.
 *
 * @param[in]  lhs            LHS operand.
 * @param[in]  rhs            RHS operand.
 * @param[in]  op             Operator method name.
 * @exception  rb_eTypeError  Coercion failed for some reason.
 * @return     `lhs op rhs`, in a coerced way.
 */
VALUE rb_num_coerce_bin(VALUE lhs, VALUE rhs, ID op);

/**
 * Identical to  rb_num_coerce_bin(), except for return  values.  This function
 * best suits for comparison operators e.g. `<=>`.
 *
 * @param[in]  lhs        LHS operand.
 * @param[in]  rhs        RHS operand.
 * @param[in]  op         Operator method name.
 * @retval     RUBY_Qnil  Coercion failed for some reason.
 * @retval     otherwise  `lhs op rhs`, in a coerced way.
 */
VALUE rb_num_coerce_cmp(VALUE lhs, VALUE rhs, ID op);

/**
 * Identical to  rb_num_coerce_cmp(), except for return  values.  This function
 * best suits for relationship operators e.g. `<=`.
 *
 * @param[in]  lhs           LHS operand.
 * @param[in]  rhs           RHS operand.
 * @param[in]  op            Operator method name.
 * @exception  rb_eArgError  Coercion failed for some reason.
 * @return     `lhs op rhs`, in a coerced way.
 */
VALUE rb_num_coerce_relop(VALUE lhs, VALUE rhs, ID op);

/**
 * This one  is optimised for bitwise  operations, but the API  is identical to
 * rb_num_coerce_bin().
 *
 * @param[in]  lhs           LHS operand.
 * @param[in]  rhs           RHS operand.
 * @param[in]  op            Operator method name.
 * @exception  rb_eArgError  Coercion failed for some reason.
 * @return     `lhs op rhs`, in a coerced way.
 */
VALUE rb_num_coerce_bit(VALUE lhs, VALUE rhs, ID op);

/** @} */

/**
 * Converts  a  numeric  value  into  a  Fixnum.   This  is  not  a  preserving
 * conversion; for instance 1.5 would be converted into 1.
 *
 * @param[in]  val             A numeric object.
 * @exception  rb_eTypeError   No conversion from `val` to Integer.
 * @exception  rb_eRangeError  `val` out of range.
 * @return     A fixnum converted from `val`.
 *
 * @internal
 *
 * This seems used from nowhere?
 */
VALUE rb_num2fix(VALUE val);

/**
 * Generates  a place-value  representation  of the  given  Fixnum, with  given
 * radix.
 *
 * @param[in]  val           A fixnum to stringify.
 * @param[in]  base          `2` to `36` inclusive for each radix.
 * @exception  rb_eArgError  `base` is out of range.
 * @return     An instance of ::rb_cString representing `val`.
 * @pre        `val` must be a Fixnum (no checks performed).
 */
VALUE rb_fix2str(VALUE val, int base);

RBIMPL_ATTR_CONST()
/**
 * Compares two `double`s.  Handy when implementing a spaceship operator.
 *
 * @param[in]  lhs             A value.
 * @param[in]  rhs             Another value.
 * @retval     RB_INT2FIX(-1)  `lhs` is "bigger than" `rhs`.
 * @retval     RB_INT2FIX(1)   `rhs` is "bigger than" `lhs`.
 * @retval     RB_INT2FIX(0)   They are equal.
 * @retval     RUBY_Qnil       Not comparable, e.g. NaN.
 */
VALUE rb_dbl_cmp(double lhs, double rhs);

/**
 * Raises the passed `x` to the power of `y`.
 *
 * @note       The return value can be really big.
 * @note       Also the  return value  can be  really small, in  case `x`  is a
 *             negative number.
 * @param[in]  x          A number.
 * @param[in]  y          Another number.
 * @retval     Inf        Cannot express the result.
 * @retval     1          Either `y` is 0 or `x` is 1.
 * @retval     otherwise  An instance of ::rb_cInteger whose value is `x ** y`.
 *
 * @internal
 *
 * This function  returns Infinity  when `y` is  big enough not  to fit  into a
 * Fixnum.  Warning is issued then.
 */
RUBY_EXTERN VALUE rb_int_positive_pow(long x, unsigned long y);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERN_NUMERIC_H */
ruby/internal/intern/file.h000064400000022576151732674230011756 0ustar00#ifndef RBIMPL_INTERN_FILE_H                         /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_FILE_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Public APIs related to ::rb_cFile.
 */
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/* file.c */

RBIMPL_ATTR_NONNULL(())
/**
 * Identical to rb_file_expand_path(), except how arguments are passed.
 *
 * @param[in]  argc                Number of objects of `argv`.
 * @param[in]  argv                Filename, and base directory, in that order.
 * @exception  rb_eArgError        Wrong `argc`.
 * @exception  rb_eTypeError       Non-string passed.
 * @exception  rb_eEncCompatError  No conversion from arguments to a path.
 * @return     Expanded path.
 *
 * @internal
 *
 * It seems nobody actually uses this function right now.  Maybe delete it?
 */
VALUE rb_file_s_expand_path(int argc, const VALUE *argv);

/**
 * Identical  to rb_file_absolute_path(),  except  it additionally  understands
 * `~`.  If a given pathname starts  with `~someone/`, that part expands to the
 * user's home directory (or that of current process' owner's in case of `~/`).
 *
 * @param[in]  fname               Relative file name.
 * @param[in]  dname               Lookup  base  directory  name,  or  in  case
 *                                 ::RUBY_Qnil is  passed the  process' current
 *                                 working directory is assumed.
 * @exception  rb_eArgError        Home directory is not absolute.
 * @exception  rb_eTypeError       Non-string passed.
 * @exception  rb_eEncCompatError  No conversion from arguments to a path.
 * @return     Expanded path.
 */
VALUE rb_file_expand_path(VALUE fname, VALUE dname);

RBIMPL_ATTR_NONNULL(())
/**
 * Identical to rb_file_absolute_path(), except how arguments are passed.
 *
 * @param[in]  argc                Number of objects of `argv`.
 * @param[in]  argv                Filename, and base directory, in that order.
 * @exception  rb_eArgError        Wrong `argc`.
 * @exception  rb_eTypeError       Non-string passed.
 * @exception  rb_eEncCompatError  No conversion from arguments to a path.
 * @return     Expanded path.
 *
 * @internal
 *
 * It seems nobody actually uses this function right now.  Maybe delete it?
 */
VALUE rb_file_s_absolute_path(int argc, const VALUE *argv);

/**
 * Maps a  relative path  to its absolute  representation.  Relative  paths are
 * referenced  from the  passed directory  name, or  from the  process' current
 * working directory in case ::RUBY_Qnil is passed.
 *
 * @param[in]  fname               Relative file name.
 * @param[in]  dname               Lookup  base  directory  name,  or  in  case
 *                                 ::RUBY_Qnil is  passed the  process' current
 *                                 working directory is assumed.
 * @exception  rb_eArgError        Strings contain NUL bytes.
 * @exception  rb_eTypeError       Non-string passed.
 * @exception  rb_eEncCompatError  No conversion from arguments to a path.
 * @return     Expanded path.
 */
VALUE rb_file_absolute_path(VALUE fname, VALUE dname);

/**
 * Strips a file path's last component  (and trailing separators if any).  This
 * function is relatively  simple on POSIX environments; just  splits the input
 * with  `/`, strips  the  last one,  if something  remains  joins them  again,
 * otherwise the return value is `"."`.   However when it comes to Windows this
 * function is  quite very  much complicated.   We have to  take UNC  etc. into
 * account.  So for instance `"C:foo"`'s dirname is `"C:."`.
 *
 * @param[in]  fname               File name to strip.
 * @exception  rb_eTypeError       `fname` is not a String.
 * @exception  rb_eArgError        `fname` contains NUL bytes.
 * @exception  rb_eEncCompatError  `fname`'s encoding is not path-compat.
 * @return     A dirname of `fname`.
 * @note       This is a "pure" operation;  it computes the return value solely
 *             from the passed object and never does any file IO.
 */
VALUE rb_file_dirname(VALUE fname);

RBIMPL_ATTR_NONNULL(())
/**
 * Resolves a  feature's path.  This  function takes for instance  `"json"` and
 * `[".so", ".rb"]`,  and iterates  over the  `$LOAD_PATH` to  see if  there is
 * either `json.so` or `json.rb` in the directory.
 *
 * This is not what everything `require`  does, but at least `require` is built
 * on top of it.
 *
 * @param[in,out]  feature             File to search, and return buffer.
 * @param[in]      exts                List of file extensions.
 * @exception      rb_eTypeError       `feature` is not a String.
 * @exception      rb_eArgError        `feature` contains NUL bytes.
 * @exception      rb_eEncCompatError  `feature`'s encoding is not path-compat.
 * @retval         0                   Not found
 * @retval         otherwise           Found index in `ext`, plus one.
 * @post           `*feature` is a resolved path.
 */
int rb_find_file_ext(VALUE *feature, const char *const *exts);

/**
 * Identical  to rb_find_file_ext(),  except it  takes  a feature  name and  is
 * extension  at once,  e.g. `"json.rb"`.   This  difference is  much like  how
 * `require` and `load` are different.
 *
 * @param[in]  path                A path relative to `$LOAD_PATH`.
 * @exception  rb_eTypeError       `path` is not a String.
 * @exception  rb_eArgError        `path` contains NUL bytes.
 * @exception  rb_eEncCompatError  `path`'s encoding is not path-compat.
 * @return     Expanded path.
 */
VALUE rb_find_file(VALUE path);

/**
 * Queries  if  the  given path  is  either  a  directory,  or a  symlink  that
 * (potentially recursively) points to such thing.
 *
 * @param[in]  _                   Ignored (why...?)
 * @param[in]  path                String,  or IO.   In  case of  IO it  issues
 *                                 `fstat(2)` instead of `stat(2)`.
 * @exception  rb_eFrozenError     `path` is a frozen IO (why...?)
 * @exception  rb_eTypeError       `path` is neither String nor IO.
 * @exception  rb_eArgError        `path` contains NUL bytes.
 * @exception  rb_eEncCompatError  `path`'s encoding is not path-compat.
 * @retval     RUBY_Qtrue          `path` is a directory.
 * @retval     RUBY_Qfalse         Otherwise.
 */
VALUE rb_file_directory_p(VALUE _, VALUE path);

/**
 * Converts a  string into an  "OS Path" encoding,  if any.  In  most operating
 * systems there are  no such things like per-OS default  encoding of filename.
 * For them this  function is no-op.  However most notably  on MacOS, pathnames
 * are UTF-8 encoded.  It converts the given string into such encoding.
 *
 * @param[in]  path                An instance of ::rb_cString.
 * @exception  rb_eEncCompatError  `path`'s encoding is not path-compat.
 * @return     `path`'s contents converted to the OS' path encoding.
 */
VALUE rb_str_encode_ospath(VALUE path);

RBIMPL_ATTR_NONNULL(())
RBIMPL_ATTR_PURE()
/**
 * Queries if the given path is an  absolute path.  On POSIX environments it is
 * as easy  as `path[0]  == '/'`.   However on Windows,  drive letters  and UNC
 * paths are also taken into account.
 *
 * @param[in]  path  A possibly relative path string.
 * @retval     1     `path` is absolute.
 * @retval     0     `path` is relative.
 */
int rb_is_absolute_path(const char *path);

/**
 * Queries  the file  size  of the  given file.   Because  this function  calls
 * `fstat(2)`  internally, it  is  a failure  to  pass a  closed  file to  this
 * function.
 *
 * This function flushes the passed file's buffer if any.  Can take time.
 *
 * @param[in]   file                 A file object.
 * @exception   rb_eFrozenError      `file` is frozen.
 * @exception   rb_eIOError          `file` is closed.
 * @exception   rb_eSystemCallError  Permission denied etc.
 * @exception   rb_eNoMethodError    The given non-file object doesn't respond
 *                                   to `#size`.
 * @return      The size of the passed file.
 * @note        Passing a non-regular file such as a UNIX domain socket to this
 *              function  is   not  a  failure.    But  the  return   value  is
 *              unpredictable.  POSIX's `<sys/stat.h>` states  that "the use of
 *              this field is unspecified" then.
 */
rb_off_t rb_file_size(VALUE file);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERN_FILE_H */
ruby/internal/intern/parse.h000064400000014266151732674240012147 0ustar00#ifndef RBIMPL_INTERN_PARSE_H                        /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_PARSE_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Public APIs related to ::rb_cSymbol.
 */
#include "ruby/internal/attr/const.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/* symbol.c */

/**
 * Calculates an ID of attribute writer.   For instance it returns `:foo=` when
 * passed `:foo`.
 *
 * @param[in]  id             An id.
 * @exception  rb_eNameError  `id` is not for attributes (e.g. operator).
 * @return     Calculated name of attribute writer.
 */
ID rb_id_attrset(ID id);

RBIMPL_ATTR_CONST()
/**
 * Classifies the given ID, then sees if it is a constant.  In case an ID is in
 * Unicode (likely), its  "constant"-ness is determined if  its first character
 * is  either upper  case or  title case.   Otherwise it  is detected  if case-
 * folding the first character changes its case or not.
 *
 * @param[in]  id  An id to classify.
 * @retval     1   It is a constant.
 * @retval     0   It isn't.
 */
int rb_is_const_id(ID id);

RBIMPL_ATTR_CONST()
/**
 * Classifies the  given ID, then  sees if it is  a global variable.   A global
 * variable must start with `$`.
 *
 * @param[in]  id  An id to classify.
 * @retval     1   It is a global variable.
 * @retval     0   It isn't.
 */
int rb_is_global_id(ID id);

RBIMPL_ATTR_CONST()
/**
 * Classifies  the given  ID, then  sees  if it  is an  instance variable.   An
 * instance variable must start with `@`, but not `@@`.
 *
 * @param[in]  id  An id to classify.
 * @retval     1   It is an instance variable.
 * @retval     0   It isn't.
 */
int rb_is_instance_id(ID id);

RBIMPL_ATTR_CONST()
/**
 * Classifies  the given  ID,  then sees  if  it is  an  attribute writer.   An
 * attribute writer is otherwise a local variable, except it ends with `=`.
 *
 * @param[in]  id  An id to classify.
 * @retval     1   It is an attribute writer.
 * @retval     0   It isn't.
 */
int rb_is_attrset_id(ID id);

RBIMPL_ATTR_CONST()
/**
 * Classifies the  given ID,  then sees  if it  is a  class variable.   A class
 * variable is must start with `@@`.
 *
 * @param[in]  id  An id to classify.
 * @retval     1   It is a class variable.
 * @retval     0   It isn't.
 */
int rb_is_class_id(ID id);

RBIMPL_ATTR_CONST()
/**
 * Classifies the  given ID,  then sees  if it  is a  local variable.   A local
 * variable starts  with a lowercase  character, followed by  some alphanumeric
 * characters or `_`, then ends with anything other than `!`, `?`, or `=`.
 *
 * @param[in]  id  An id to classify.
 * @retval     1   It is a local variable.
 * @retval     0   It isn't.
 */
int rb_is_local_id(ID id);

RBIMPL_ATTR_CONST()
/**
 * Classifies the  given ID,  then sees  if it  is a  junk ID.   An ID  with no
 * special syntactic structure is considered  junk.  This category includes for
 * instance punctuation.
 *
 * @param[in]  id  An id to classify.
 * @retval     1   It is a junk.
 * @retval     0   It isn't.
 */
int rb_is_junk_id(ID);

RBIMPL_ATTR_NONNULL(())
/**
 * Sees if  the passed C string  constructs a valid syntactic  symbol.  Invalid
 * ones for instance includes whitespaces.
 *
 * @param[in]  str  A C string to check.
 * @retval     1    It is a valid symbol name.
 * @retval     0    It is invalid as a symbol name.
 */
int rb_symname_p(const char *str);

/* vm.c */

/**
 * Queries the last match, or `Regexp.last_match`, or the `$~`.  You don't have
 * to use it, because in reality you can get `$~` using rb_gv_get() as usual.
 *
 * @retval  RUBY_Qnil  The method has not ran a regular expression.
 * @retval  otherwise  An instance of ::rb_cMatch.
 */
VALUE rb_backref_get(void);

/**
 * Updates `$~`.  You don't have to use it, because in reality you can set `$~`
 * using rb_gv_set() as usual.
 *
 * @param[in]  md  Arbitrary Ruby object.
 * @post       The passed object is assigned to `$~`.
 *
 * @internal
 *
 * Yes, this  function bypasses  the Check_Type()  that would  normally prevent
 * evil souls from assigning  evil objects to `$~`.  Use of  this function is a
 * really bad smell.
 */
void rb_backref_set(VALUE md);

/**
 * Queries the last  line, or the `$_`.   You don't have to use  it, because in
 * reality you can get `$_` using rb_gv_get() as usual.
 *
 * @retval  RUBY_Qnil  There has never been a "line" yet.
 * @retval  otherwise  The last set `$_` value.
 */
VALUE rb_lastline_get(void);

/**
 * Updates `$_`.  You don't have to use it, because in reality you can set `$_`
 * using rb_gv_set() as usual.
 *
 * @param[in]  str  Arbitrary Ruby object.
 * @post       The passed object is assigned to `$_`.
 *
 * @internal
 *
 * Unlike `$~`, you can assign non-strings to `$_`, even from ruby scripts.
 */
void rb_lastline_set(VALUE str);

/* symbol.c */

/**
 * Collects every single bits of symbols  that have ever interned in the entire
 * history of the current process.
 *
 * @return  An array that contains all symbols that have ever existed.
 */
VALUE rb_sym_all_symbols(void);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERN_PARSE_H */
ruby/internal/intern/marshal.h000064400000012712151732674240012456 0ustar00#ifndef RBIMPL_INTERN_MARSHAL_H                      /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_MARSHAL_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Public APIs related to rb_mMarshal.
 */
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/* marshal.c */

/**
 * Serialises the  given object and  all its  referring objects, to  write them
 * down to the passed port.
 *
 * @param[in]   obj               Target object to dump.
 * @param[out]  port              IO-like destination buffer.
 * @exception   rb_eTypeError     `obj` cannot be dumped for some reason.
 * @exception   rb_eRuntimeError  `obj` was tampered during dumping.
 * @exception   rb_eArgError      Traversal too deep.
 * @return      The passed `port` as-is.
 * @post        Serialised representation of `obj` is written to `port`.
 * @note        `port` is basically an IO but StringIO is also possible.
 */
VALUE rb_marshal_dump(VALUE obj, VALUE port);

/**
 * Deserialises  a  previous output  of  rb_marshal_dump()  into a  network  of
 * objects.
 *
 * @param[in,out]  port           Either IO or String.
 * @exception      rb_eTypeError  `port` is in unexpected type.
 * @exception      rb_eArgError   Contents of `port` is broken.
 * @return         Object(s) rebuilt using the info from `port`.
 *
 * SECURITY  CONSIDERATIONS
 * ========================
 *
 * @warning        By  design,  rb_marshal_load()  can deserialise  almost  any
 *                 class loaded into the Ruby  process.  In many cases this can
 *                 lead to remote code execution  if the Marshal data is loaded
 *                 from an untrusted source.
 * @warning        As a result, rb_marshal_load() is  not suitable as a general
 *                 purpose serialisation format and  you should never unmarshal
 *                 user supplied input or other untrusted data.
 * @warning        If  you need  to  deserialise untrusted  data,  use JSON  or
 *                 another  serialisation  format that  is  only  able to  load
 *                 simple, 'primitive' types such  as String, Array, Hash, etc.
 *                 Never  allow  user  input  to  specify  arbitrary  types  to
 *                 deserialise into.
 */
VALUE rb_marshal_load(VALUE port);

/**
 * Marshal  format compatibility  layer.  Over  time, classes  evolve, so  that
 * their internal data structure change  drastically.  For instance an instance
 * of ::rb_cRange  was made  of ::RUBY_T_OBJECT  in 1.x.,  but in  3.x it  is a
 * ::RUBY_T_STRUCT now.  In  order to keep binary compatibility,  we "fake" the
 * marshalled representation to stick to old  types.  This is the API to enable
 * that manoeuvre.  Here is how:
 *
 * First, because  you are going to  keep backwards compatibility, you  need to
 * retain the old implementation of your  class.  Rename it, and keep the class
 * somewhere  (for  instance  rb_register_global_address() could  help).   Next
 * create your new class.  Do whatever you want.
 *
 * Then, this is the key point.  Create two new "bridge" functions that convert
 * the structs back and forth:
 *
 *   - the  "dumper" function  that takes  an instance  of the  new class,  and
 *     returns   an  instance   of  the   old   one.   This   is  called   from
 *     rb_marshal_dump(), to keep it possible for old programs to read your new
 *     data.
 *
 *   - the "loader" function that takes two  arguments, new one and old one, in
 *     that  order.  rb_marshal_load()  calls  this function  when  it finds  a
 *     representation of  the retained old class.   The old one passed  to this
 *     function   is   the   reconstructed   instance   of   the   old   class.
 *     Reverse-engineer  that to  modify the  new  one, to  have the  identical
 *     contents.
 *
 * Finally, connect all of them using this function.
 *
 * @param[in]  newclass       The class that needs conversion.
 * @param[in]  oldclass       Old implementation of `newclass`.
 * @param[in]  dumper         Function that converts `newclass` to `oldclass`.
 * @param[in]  loader         Function that converts `oldclass` to `newclass`.
 * @exception  rb_eTypeError  `newclass` has no allocator.
 */
void rb_marshal_define_compat(VALUE newclass, VALUE oldclass, VALUE (*dumper)(VALUE), VALUE (*loader)(VALUE, VALUE));

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERN_MARSHAL_H */
ruby/internal/intern/enum.h000064400000005513151732674240011774 0ustar00#ifndef RBIMPL_INTERN_ENUM_H                         /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_ENUM_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Public APIs related to ::rb_mEnumerable.
 */
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/* enum.c */

/**
 * Basically identical to rb_ary_new_form_values(), except it returns something
 * different when `argc` < 2.
 *
 * @param[in]  argc       Number of objects of `argv`.
 * @param[in]  argv       Arbitrary objects.
 * @retval     RUBY_Qnil  `argc` is zero.
 * @retval     argv[0]    `argc` is one.
 * @retval     otherwise  Otherwise.
 *
 * @internal
 *
 * What  is this  business?   Well,  this function  is  about `yield`'s  taking
 * multiple values.  Consider following user-defined class:
 *
 * ```ruby
 * class Foo
 *   include Enumerable
 *
 *   def each
 *     yield :q, :w, :e, :r
 *   end
 * end
 *
 * Foo.new.each_with_object([]) do |i, j|
 *   j << i                      # ^^^ <- What to expect for `i`?
 * end
 * ```
 *
 * Here, `Foo#each_with_object` is in fact `Enumerable#each_with_object`, which
 * doesn't know what would be yielded.  Yet, it has to take a block of arity 2.
 * This function  is used here, to  "pack" arbitrary number of  yielded objects
 * into one.
 *
 * If people want to implement their own `Enumerable#each_with_object` this API
 * can be handy.  Though @shyouhei suspects it is relatively rare for 3rd party
 * extension libraries  to have  such things.  Also  `Enumerable#each_entry` is
 * basically this function exposed as a Ruby method.
 */
VALUE rb_enum_values_pack(int argc, const VALUE *argv);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERN_ENUM_H */
ruby/internal/intern/error.h000064400000023451151732674240012162 0ustar00#ifndef RBIMPL_INTERN_ERROR_H                        /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_ERROR_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Public APIs related to ::rb_eException.
 */
#include "ruby/internal/attr/format.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/internal/fl_type.h"
#include "ruby/backward/2/assume.h"

/**
 * This macro is used in conjunction  with rb_check_arity().  If you pass it to
 * the function's last  (max) argument, that means the function  does not check
 * upper limit.
 */
#define UNLIMITED_ARGUMENTS     (-1)

#define rb_exc_new2             rb_exc_new_cstr  /**< @old{rb_exc_new_cstr} */
#define rb_exc_new3             rb_exc_new_str  /**< @old{rb_exc_new_str} */

/** @cond INTERNAL_MACRO */
#define rb_check_arity          rb_check_arity
/** @endcond */

RBIMPL_SYMBOL_EXPORT_BEGIN()

/* error.c */

/**
 * Creates an instance of the passed exception class.
 *
 * @param[in]  etype           A subclass of ::rb_eException.
 * @param[in]  ptr             Buffer contains error message.
 * @param[in]  len             Length  of `ptr`,  in bytes,  not including  the
 *                             terminating NUL character.
 * @exception  rb_eTypeError  `etype` is not a class.
 * @exception  rb_eArgError   `len` is negative.
 * @return     An instance of `etype`.
 * @pre        At  least  `len` bytes  of  continuous  memory region  shall  be
 *             accessible via `ptr`.
 *
 * @internal
 *
 * This function works for non-exception classes  as well, as long as they take
 * one string argument.
 */
VALUE rb_exc_new(VALUE etype, const char *ptr, long len);

RBIMPL_ATTR_NONNULL(())
/**
 * Identical to rb_exc_new(), except it assumes the passed pointer is a pointer
 * to a C string.
 *
 * @param[in]  etype           A subclass of ::rb_eException.
 * @param[in]  str             A C string (becomes an error message).
 * @exception  rb_eTypeError  `etype` is not a class.
 * @return     An instance of `etype`.
 */
VALUE rb_exc_new_cstr(VALUE etype, const char *str);

/**
 * Identical to rb_exc_new_cstr(),  except it takes a Ruby's  string instead of
 * C's.
 *
 * @param[in]  etype           A subclass of ::rb_eException.
 * @param[in]  str             An instance of ::rb_cString.
 * @exception  rb_eTypeError  `etype` is not a class.
 * @return     An instance of `etype`.
 */
VALUE rb_exc_new_str(VALUE etype, VALUE str);

RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_NONNULL((1))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 1, 2)
/**
 * Raises an instance of ::rb_eLoadError.
 *
 * @param[in]  fmt  Format specifier string compatible with rb_sprintf().
 * @exception  rb_eLoadError  Always raises this.
 * @note       It never returns.
 *
 * @internal
 *
 * Who needs this?  Except ruby itself?
 */
void rb_loaderror(const char *fmt, ...);

RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_NONNULL((2))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 3)
/**
 * Identical  to rb_loaderror(),  except it  additionally takes  which file  is
 * unable to  load.  The path can  be obtained later using  `LoadError#path` of
 * the raising exception.
 *
 * @param[in]  path  What failed.
 * @param[in]  fmt   Format specifier string compatible with rb_sprintf().
 * @exception  rb_eLoadError  Always raises this.
 * @note       It never returns.
 */
void rb_loaderror_with_path(VALUE path, const char *fmt, ...);

RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_NONNULL((2))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 3)
/**
 * Raises an instance of ::rb_eNameError.  The name can be obtained later using
 * `NameError#name` of the raising exception.
 *
 * @param[in]  name  What failed.
 * @param[in]  fmt   Format specifier string compatible with rb_sprintf().
 * @exception  rb_eNameError  Always raises this.
 * @note       It never returns.
 */
void rb_name_error(ID name, const char *fmt, ...);

RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_NONNULL((2))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 3)
/**
 * Identical to rb_name_error(), except it takes a ::VALUE instead of ::ID.
 *
 * @param[in]  name  What failed.
 * @param[in]  fmt   Format specifier string compatible with rb_sprintf().
 * @exception  rb_eNameError  Always raises this.
 * @note       It never returns.
 */
void rb_name_error_str(VALUE name, const char *fmt, ...);

RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_NONNULL((2))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 3)
/**
 * Raises an instance  of ::rb_eFrozenError.  The object can  be obtained later
 * using `FrozenError#receiver` of the raising exception.
 *
 * @param[in]  recv  What is frozen.
 * @param[in]  fmt   Format specifier string compatible with rb_sprintf().
 * @exception  rb_eFrozenError  Always raises this.
 * @note       It never returns.
 *
 * @internal
 *
 * Note however,  that it  is often  not possible to  inspect a  frozen object,
 * because the inspection itself could be forbidden by the frozen-ness.
 */
void rb_frozen_error_raise(VALUE recv, const char *fmt, ...);

RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_NONNULL(())
/**
 * Honestly  I  don't  understand  the  name, but  it  raises  an  instance  of
 * ::rb_eArgError.
 *
 * @param[in]  str           A message.
 * @param[in]  type          Another message.
 * @exception  rb_eArgError  Always raises this.
 * @note       It never returns.
 */
void rb_invalid_str(const char *str, const char *type);

RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_NONNULL(())
/**
 * Identical  to rb_frozen_error_raise(),  except its  raising exception  has a
 * message like "can't modify frozen /what/".
 *
 * @param[in]  what             What was frozen.
 * @exception  rb_eFrozenError  Always raises this.
 * @note       It never returns.
 */
void rb_error_frozen(const char *what);

RBIMPL_ATTR_NORETURN()
/**
 * Identical  to  rb_error_frozen(),  except  it takes  arbitrary  Ruby  object
 * instead of C's string.
 *
 * @param[in]  what             What was frozen.
 * @exception  rb_eFrozenError  Always raises this.
 * @note       It never returns.
 */
void rb_error_frozen_object(VALUE what);

/**
 * Queries  if the  passed  object is  frozen.
 *
 * @param[in]  obj  Target object to test frozen-ness.
 * @exception  rb_eFrozenError  It is frozen.
 * @post       Upon successful return it is guaranteed _not_ frozen.
 */
void rb_check_frozen(VALUE obj);

/**
 * Ensures that the passed object  can be `initialize_copy` relationship.  When
 * you implement your own one you would better call this at the right beginning
 * of your implementation.
 *
 * @param[in]  obj              Destination object.
 * @param[in]  orig             Source object.
 * @exception  rb_eFrozenError  `obj` is frozen.
 * @post       Upon successful return obj is guaranteed safe to copy orig.
 */
void rb_check_copyable(VALUE obj, VALUE orig);

RBIMPL_ATTR_NORETURN()
/**
 * @private
 *
 * This  is an  implementation detail  of  rb_scan_args().  You  don't have  to
 * bother.
 *
 * @pre        `argc` is out of range of `min`..`max`, both inclusive.
 * @param[in]  argc          Arbitrary integer.
 * @param[in]  min           Minimum allowed `argc`.
 * @param[in]  max           Maximum allowed `argc`.
 * @exception  rb_eArgError  Always.
 */
void rb_error_arity(int argc, int min, int max);

void rb_str_modify(VALUE str);

RBIMPL_SYMBOL_EXPORT_END()

/**
 * @deprecated
 *
 * Does anyone use this?  Remain not deleted for compatibility.
 */
#define rb_check_frozen_internal rb_check_frozen

/** @alias{rb_check_frozen} */
static inline void
rb_check_frozen_inline(VALUE obj)
{
    if (RB_UNLIKELY(RB_OBJ_FROZEN(obj))) {
        rb_error_frozen_object(obj);
    }

    /* ref: internal CHILLED_STRING_P()
       This is an implementation detail subject to change. */
    if (RB_UNLIKELY(RB_TYPE_P(obj, T_STRING) && FL_TEST_RAW(obj, RUBY_FL_USER2 | RUBY_FL_USER3))) { // STR_CHILLED
        rb_str_modify(obj);
    }
}

/* rb_check_frozen() is available as a symbol, but have
 * the inline version take priority for native consumers. */
#define rb_check_frozen rb_check_frozen_inline

/**
 * Ensures that the  passed integer is in  the passed range.  When  you can use
 * rb_scan_args() that is preferred over this one (powerful, descriptive).  But
 * it can have its own application area.
 *
 * @param[in]  argc          Arbitrary integer.
 * @param[in]  min           Minimum allowed `argv`.
 * @param[in]  max           Maximum allowed `argv`, or `UNLIMITED_ARGUMENTS`.
 * @exception  rb_eArgError  `argc` out of range.
 * @return     The passed `argc`.
 * @post       Upon successful return `argc` is  in range of `min`..`max`, both
 *             inclusive.
 */
static inline int
rb_check_arity(int argc, int min, int max)
{
    if ((argc < min) || (max != UNLIMITED_ARGUMENTS && argc > max))
        rb_error_arity(argc, min, max);
    return argc;
}

#endif /* RBIMPL_INTERN_ERROR_H */
ruby/internal/intern/vm.h000064400000040645151732674240011457 0ustar00#ifndef RBIMPL_INTERN_VM_H                           /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_VM_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Public APIs related to rb_cRubyVM.
 */
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/* vm.c */

/**
 * Resembles `__LINE__`.
 *
 * @retval  0          Current execution context not in a ruby method.
 * @retval  otherwise  The current  line number  of the  current thread  of the
 *                     current ractor of the current execution context.
 */
int rb_sourceline(void);

/**
 * Resembles `__FILE__`.
 *
 * @retval  0          Current execution context not in a ruby method.
 * @retval  otherwise  The current  source path  of the  current thread  of the
 *                     current ractor of the current execution context.
 * @note    This may or may not be an absolute path.
 */
const char *rb_sourcefile(void);

/**
 * Resembles `__method__`.
 *
 * @param[out]  idp     Return buffer for method id.
 * @param[out]  klassp  Return buffer for class.
 * @retval      0       Current execution context not in a method.
 * @retval      1       Successful return.
 * @post        Upon successful return `*idp` and `*klassp` are updated to have
 *              the current method name and its defined class respectively.
 * @note        Both parameters can be `NULL`.
 */
int rb_frame_method_id_and_class(ID *idp, VALUE *klassp);

/* vm_eval.c */

/**
 * Identical  to  rb_funcallv(), except  it  returns  ::RUBY_Qundef instead  of
 * raising ::rb_eNoMethodError.
 *
 * @param[in,out]  recv         Receiver of the method.
 * @param[in]      mid          Name of the method to call.
 * @param[in]      argc         Number of arguments.
 * @param[in]      argv         Arbitrary number of method arguments.
 * @retval         RUBY_Qundef  `recv` doesn't respond to `mid`.
 * @retval         otherwise    What the method evaluates to.
 */
VALUE rb_check_funcall(VALUE recv, ID mid, int argc, const VALUE *argv);

/**
 * Identical to  rb_check_funcall(), except you  can specify how to  handle the
 * last element of the given array.  It can also be seen as a routine identical
 * to  rb_funcallv_kw(), except  it  returns ::RUBY_Qundef  instead of  raising
 * ::rb_eNoMethodError.
 *
 * @param[in,out]  recv         Receiver of the method.
 * @param[in]      mid          Name of the method to call.
 * @param[in]      argc         Number of arguments.
 * @param[in]      argv         Arbitrary number of method arguments.
 * @param[in]      kw_splat     Handling of keyword parameters:
 *   - RB_NO_KEYWORDS           `argv`'s last is not a keyword argument.
 *   - RB_PASS_KEYWORDS         `argv`'s last is a keyword argument.
 *   - RB_PASS_CALLED_KEYWORDS  it depends if there is a passed block.
 * @retval         RUBY_Qundef  `recv` doesn't respond to `mid`.
 * @retval         otherwise    What the method evaluates to.
 */
VALUE rb_check_funcall_kw(VALUE recv, ID mid, int argc, const VALUE *argv, int kw_splat);

/**
 * This API  is practically a  variant of rb_proc_call_kw()  now.  Historically
 * when there  still was a  concept called `$SAFE`, this  was an API  for that.
 * But we  no longer have  that.  This function  basically ended its  role.  It
 * just remains here because of no harm.
 *
 * @param[in]  cmd       A string, or something callable.
 * @param[in]  arg       Argument passed to the call.
 * @param[in]  kw_splat  Handling of keyword parameters:
 *   - RB_NO_KEYWORDS           `arg`'s last is not a keyword argument.
 *   - RB_PASS_KEYWORDS         `arg`'s last is a keyword argument.
 *   - RB_PASS_CALLED_KEYWORDS  it depends if there is a passed block.
 * @return     What the command evaluates to.
 */
VALUE rb_eval_cmd_kw(VALUE cmd, VALUE arg, int kw_splat);

/**
 * Identical to rb_funcallv(), except it takes Ruby's array instead of C's.
 * @param[in,out]  recv               Receiver of the method.
 * @param[in]      mid                Name of the method to call.
 * @param[in]      args               An instance of ::RArray.
 * @exception      rb_eNoMethodError  No such method.
 * @exception      rb_eException      Any exceptions happen inside.
 * @return         What the method evaluates to.
 * @pre            `args` must  be an ::RArray.  Call  `to_ary` beforehand when
 *                 necessary.
 */
VALUE rb_apply(VALUE recv, ID mid, VALUE args);

/**
 * Evaluates a string  containing Ruby source code, or the  given block, within
 * the  context of  the receiver.  In order  to set  the context,  the variable
 * `self` is set to `recv` while the  code is executing, giving the code access
 * to `recv`'s instance variables and private methods.
 *
 * When given a block, `recv` is also passed in as the block's only argument.
 *
 * When  given a  string, the  optional second  and third  parameters supply  a
 * filename and starting  line number that are used  when reporting compilation
 * errors.
 *
 * @param[in]  argc  Number of objects in `argv`
 * @param[in]  argv  C array of 0 up to 3 elements.
 * @param[in]  recv  The object in question.
 * @return     What was evaluated.
 */
VALUE rb_obj_instance_eval(int argc, const VALUE *argv, VALUE recv);

/**
 * Executes the  given block within the  context of the receiver.   In order to
 * set the  context, the  variable `self` is  set to `recv`  while the  code is
 * executing, giving the code access to `recv`'s instance variables.  Arguments
 * are passed as block parameters.
 *
 * @param[in]  argc  Number of objects in `argv`
 * @param[in]  argv  Arbitrary parameters to be passed to the block.
 * @param[in]  recv  The object in question.
 * @return     What was evaluated.
 * @note       Don't  confuse   this  with  rb_obj_instance_eval().    The  key
 *             difference is whether  you can pass arbitrary  parameters to the
 *             block, like this:
 *
 * ```ruby
 * class Foo
 *   def initialize
 *     @foo = 5
 *   end
 * end
 * Foo.new.instance_exec(7) {|i| @foo + i } # => 12
 * ```
 */
VALUE rb_obj_instance_exec(int argc, const VALUE *argv, VALUE recv);

/**
 * Identical to rb_obj_instance_eval(), except  it evaluates within the context
 * of module.
 *
 * @param[in]  argc  Number of objects in `argv`
 * @param[in]  argv  C array of 0 up to 3 elements.
 * @param[in]  mod   The module in question.
 * @pre        `mod` must be a Module.
 * @return     What was evaluated.
 */
VALUE rb_mod_module_eval(int argc, const VALUE *argv, VALUE mod);

/**
 * Identical to rb_obj_instance_exec(), except  it evaluates within the context
 * of module.
 *
 * @param[in]  argc  Number of objects in `argv`
 * @param[in]  argv  Arbitrary parameters to be passed to the block.
 * @param[in]  mod   The module in question.
 * @pre        `mod` must be a Module.
 * @return     What was evaluated.
 */
VALUE rb_mod_module_exec(int argc, const VALUE *argv, VALUE mod);

/* vm_method.c */

/**
 * @private
 *
 * @deprecated  This macro once was a thing in the old days, but makes no sense
 *              any  longer today.   Exists  here  for backwards  compatibility
 *              only.  You can safely forget about it.
 */
#define HAVE_RB_DEFINE_ALLOC_FUNC 1

/**
 * This is  the type of  functions that ruby calls  when trying to  allocate an
 * object.  It is  sometimes necessary to allocate extra memory  regions for an
 * object.  When you define a class that uses ::RTypedData, it is typically the
 * case.  On  such situations  define a function  of this type  and pass  it to
 * rb_define_alloc_func().
 *
 * @param[in]  klass  The class that this function is registered.
 * @return     A newly allocated instance of `klass`.
 */
typedef VALUE (*rb_alloc_func_t)(VALUE klass);

/**
 * Sets the allocator function of a class.
 *
 * @param[out]  klass  The class to modify.
 * @param[in]   func   An allocator function for the class.
 * @pre         `klass` must be an instance of Class.
 */
void rb_define_alloc_func(VALUE klass, rb_alloc_func_t func);

/**
 * Deletes the  allocator function of  a class.   It is sometimes  desirable to
 * restrict creation  of an instance of  a class.  For example  it rarely makes
 * sense for  a DB adaptor class  to allow programmers creating  DB row objects
 * without querying  the DB  itself.  You  can kill  sporadic creation  of such
 * objects then,  by nullifying  the allocator function  using this  API.
 *
 * @param[out]  klass  The class to modify.
 * @pre         `klass` must be an instance of Class.
 */
void rb_undef_alloc_func(VALUE klass);

/**
 * Queries the allocator function of a class.
 *
 * @param[in]  klass      The class in question.
 * @pre        `klass` must be an instance of Class.
 * @retval     0          No allocator function is registered.
 * @retval     otherwise  The allocator function.
 *
 * @internal
 *
 * Who cares?  @shyouhei finds no practical usage of the return value.  Maybe we
 * need KonMari.
 */
rb_alloc_func_t rb_get_alloc_func(VALUE klass);

/**
 * Clears the inline constant caches associated with a particular ID. Extension
 * libraries should not bother with such things. Just forget about this API (or
 * even, the presence of constant caches).
 */
void rb_clear_constant_cache_for_id(ID id);

/**
 * Resembles `alias`.
 *
 * @param[out]  klass            Where to define an alias.
 * @param[in]   dst              New name.
 * @param[in]   src              Existing name.
 * @exception   rb_eTypeError    `klass` is not a class.
 * @exception   rb_eFrozenError  `klass` is frozen.
 * @exception   rb_eNameError    No such method named `src`.
 * @post        `klass` has a method named `dst`, which is the identical to its
 *              method named `src`.
 */
void rb_alias(VALUE klass, ID dst, ID src);

/**
 * This function resembles now-deprecated `Module#attr`.
 *
 * @param[out]  klass              Where to define an attribute.
 * @param[in]   name               Name of an instance variable.
 * @param[in]   need_reader        Whether attr_reader is needed.
 * @param[in]   need_writer        Whether attr_writer is needed.
 * @param[in]   honour_visibility  Whether to use the current visibility.
 * @exception   rb_eTypeError      `klass` is not a class.
 * @exception   rb_eFrozenError    `klass` is frozen.
 * @post        If `need_reader` is set `klass` has a method named `name`.
 * @post        If `need_writer` is set `klass` has a method named `name=`.
 *
 * @internal
 *
 * The three `int` arguments should have been bool, but there was no such thing
 * like a bool when K&R was used in this project.
 */
void rb_attr(VALUE klass, ID name, int need_reader, int need_writer, int honour_visibility);

RBIMPL_ATTR_NONNULL(())
/**
 * Removes a  method.  Don't confuse  this to rb_undef_method(),  which doesn't
 * remove a method.  This one resembles `Module#remove_method`.
 *
 * @param[out]  klass            The class to remove a method.
 * @param[in]   name             Name of a method to be removed.
 * @exception   rb_eTypeError    `klass` is a non-module.
 * @exception   rb_eFrozenError  `klass` is frozen.
 * @exception   rb_eNameError    No such method.
 * @see         rb_undef_method
 */
void rb_remove_method(VALUE klass, const char *name);

/**
 * Identical to rb_remove_method(), except it accepts the method name as ::ID.
 *
 * @param[out]  klass            The class to remove a method.
 * @param[in]   mid              Name of a method to be removed.
 * @exception   rb_eTypeError    `klass` is a non-module.
 * @exception   rb_eFrozenError  `klass` is frozen.
 * @exception   rb_eNameError    No such method.
 * @see         rb_undef
 */
void rb_remove_method_id(VALUE klass, ID mid);

/**
 * Queries if the  klass has this method.   This function has only  one line of
 * document in the implementation that states "// deprecated".  Don't know what
 * that means though.
 *
 * @param[in]  klass  The class in question.
 * @param[in]  id     The method name to query.
 * @param[in]  ex     Undocumented magic value.
 * @retval     false  Method not found.
 * @retval     true   There is a method.
 * @pre        `klass` must be a module.
 *
 * @internal
 *
 * @shyouhei has no  motivation to describe what should be  passed to `ex`.  It
 * seems this function should just be trashed.
 */
int rb_method_boundp(VALUE klass, ID id, int ex);

/**
 * Well...  Let us hesitate from describing what a "basic definition" is.  This
 * nuanced concept  should have been  kept private.  Just please.   Don't touch
 * it.  This function is a badly distributed random number generator.  Right?
 *
 * @param[in]  klass  The class in question.
 * @param[in]  mid    The method name in question.
 * @retval     1      It is.
 * @retval     0      It isn't.
 */
int rb_method_basic_definition_p(VALUE klass, ID mid);

/**
 * Identical to  rb_respond_to(), except  it additionally takes  the visibility
 * parameter.   This   does  not   make  difference   unless  the   object  has
 * `respond_to?` undefined,  but has `respond_to_missing?` defined.   That case
 * the passed argument becomes the second argument of `respond_to_missing?`.
 *
 * @param[in]  obj        The object in question.
 * @param[in]  mid        The method name in question.
 * @param[in]  private_p  This    is   the    second   argument    of   `obj`'s
 *                        `respond_to_missing?`.
 * @retval     1          Yes it does.
 * @retval     0          No it doesn't.
 */
int rb_obj_respond_to(VALUE obj, ID mid, int private_p);

/**
 * Queries if  the object responds  to the  method.  This involves  calling the
 * object's `respond_to?` method.
 *
 * @param[in]  obj        The object in question.
 * @param[in]  mid        The method name in question.
 * @retval     1          Yes it does.
 * @retval     0          No it doesn't.
 */
int rb_respond_to(VALUE obj, ID mid);

RBIMPL_ATTR_NORETURN()
/**
 * Raises  ::rb_eNotImpError.   This  function  is   used  as  an  argument  to
 * rb_define_method() etc.
 *
 * ```CXX
 * rb_define_method(rb_cFoo, "foo", rb_f_notimplement, -1);
 * ```
 *
 * @param     argc             Unused parameter.
 * @param     argv             Unused parameter.
 * @param     obj              Unused parameter.
 * @param     marker           Unused parameter.
 * @exception rb_eNotImpError  Always.
 * @return    Never returns.
 *
 * @internal
 *
 * See also the Q&A section of include/ruby/internal/anyargs.h.
 */
VALUE rb_f_notimplement(int argc, const VALUE *argv, VALUE obj, VALUE marker);
#if !defined(RUBY_EXPORT) && defined(_WIN32)
RUBY_EXTERN VALUE (*const rb_f_notimplement_)(int, const VALUE *, VALUE, VALUE marker);
#define rb_f_notimplement (*rb_f_notimplement_)
#endif

/* vm_backtrace.c */

/**
 * Prints the backtrace  out to the standard error.  This  just confuses people
 * for no reason.  Evil souls must only use it.
 *
 * @internal
 *
 * Actually it is very useful when called from an interactive GDB session.
 */
void rb_backtrace(void);

/**
 * Creates the good old fashioned array-of-strings style backtrace info.
 *
 * @return  An   array  which   contains   strings,  which   are  the   textual
 *          representations of the backtrace locations of the current thread of
 *          the current ractor of the current execution context.
 * @note    Ruby      scripts      can      access      more      sophisticated
 *          `Thread::Backtrace::Location`.  But it seems there  is no way for C
 *          extensions to use that API.
 */
VALUE rb_make_backtrace(void);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERN_VM_H */
ruby/internal/intern/rational.h000064400000014533151732674240012643 0ustar00#ifndef RBIMPL_INTERN_RATIONAL_H                     /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_RATIONAL_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Public APIs related to ::rb_cRational.
 */
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/internal/arithmetic/long.h" /* INT2FIX is here. */

RBIMPL_SYMBOL_EXPORT_BEGIN()

/* rational.c */

/**
 * Identical to rb_rational_new(), except it skips argument validations.  It is
 * thus  dangerous  for extension  libraries.   For  instance `1/0r`  could  be
 * constructed using this.
 *
 * @param[in]  num            Numerator, an instance of ::rb_cInteger.
 * @param[in]  den            Denominator, an instance of ::rb_cInteger.
 * @exception  rb_eTypeError  Either argument is not an Integer.
 * @return     An instance of ::rb_cRational whose value is `(num/den)r`.
 */
VALUE rb_rational_raw(VALUE num, VALUE den);

/**
 * Shorthand  of  `(x/1)r`.  As  `x`  is  already  an Integer,  it  practically
 * converts it into a Rational of the identical value.
 *
 * @param[in]  x  An instance of ::rb_cInteger.
 * @return     An instance of ::rb_cRational, whose value is `(x/1)r`.
 */
#define rb_rational_raw1(x) rb_rational_raw((x), INT2FIX(1))

/** @alias{rb_rational_raw} */
#define rb_rational_raw2(x,y) rb_rational_raw((x), (y))

/**
 * Constructs a Rational,  with reduction.  This returns  for instance `(2/3)r`
 * for `rb_rational_new(INT2NUM(-384), INT2NUM(-576))`.
 *
 * @param[in]  num               Numerator, an instance of ::rb_cInteger.
 * @param[in]  den               Denominator, an instance of ::rb_cInteger.
 * @exception  rb_eZeroDivError  `den` is zero.
 * @return     An instance of ::rb_cRational whose value is `(num/den)r`.
 */
VALUE rb_rational_new(VALUE num, VALUE den);

/**
 * Shorthand  of  `(x/1)r`.  As  `x`  is  already  an Integer,  it  practically
 * converts it into a Rational of the identical value.
 *
 * @param[in]  x  An instance of ::rb_cInteger.
 * @return     An instance of ::rb_cRational, whose value is `(x/1)r`.
 */
#define rb_rational_new1(x) rb_rational_new((x), INT2FIX(1))

/** @alias{rb_rational_new} */
#define rb_rational_new2(x,y) rb_rational_new((x), (y))

/**
 * Converts various values into a Rational.  This function accepts:
 *
 * - Instances of ::rb_cInteger (taken as-is),
 * - Instances of ::rb_cRational (taken as-is),
 * - Instances of ::rb_cFloat (applies `#to_r`),
 * - Instances of ::rb_cComplex (applies `#to_r`),
 * - Instances of ::rb_cString (applies `#to_r`),
 * - Other objects that respond to `#to_r`.
 *
 * It (possibly  recursively) applies  `#to_r` until  both sides  become either
 * Integer or Rational, then divides them.
 *
 * As a  special case, passing  ::RUBY_Qundef to `den`  is the same  as passing
 * `RB_INT2NUM(1)`.
 *
 * @param[in]  num                   Numerator (see above).
 * @param[in]  den                   Denominator (see above).
 * @exception  rb_eTypeError         Passed something not described above.
 * @exception  rb_eFloatDomainError  `#to_r` produced Nan/Inf.
 * @exception  rb_eZeroDivError      `#to_r` produced zero for `den`.
 * @return     An instance of ::rb_cRational whose value is `(num/den)r`.
 *
 * @internal
 *
 * This was the implementation of `Kernel#Rational` before, but they diverged.
 */
VALUE rb_Rational(VALUE num, VALUE den);

/**
 * Shorthand of  `(x/1)r`.  It practically converts  it into a Rational  of the
 * identical value.
 *
 * @param[in]  x  ::rb_cInteger, ::rb_cRational, or  something that responds to
 *                `#to_r`.
 * @return     An instance of ::rb_cRational, whose value is `(x/1)r`.
 */
#define rb_Rational1(x) rb_Rational((x), INT2FIX(1))

/** @alias{rb_Rational} */
#define rb_Rational2(x,y) rb_Rational((x), (y))

RBIMPL_ATTR_PURE()
/**
 * Queries the numerator of the passed Rational.
 *
 * @param[in]  rat  An instance of ::rb_cRational.
 * @return     Its numerator part, which is an instance of ::rb_cInteger.
 */
VALUE rb_rational_num(VALUE rat);

RBIMPL_ATTR_PURE()
/**
 * Queries the denominator of the passed Rational.
 *
 * @param[in]  rat  An instance of ::rb_cRational.
 * @return     Its  denominator part,  which  is an  instance of  ::rb_cInteger
 *             greater than or equal to one..
 */
VALUE rb_rational_den(VALUE rat);

/**
 * Simplified  approximation of  a float.   It returns  a rational  `rat` which
 * satisfies:
 *
 * ```
 * flt - |prec| <= rat <= flt + |prec|
 * ```
 *
 * ```ruby
 * 3.141592.rationalize(0.001) # => (201/64)r
 * 3.141592.rationalize(0.01)' # => (22/7)r
 * 3.141592.rationalize(0.1)'  # => (16/5)r
 * 3.141592.rationalize(1)'    # => (3/1)r
 * ```
 *
 * @param[in]  flt   An instance of ::rb_cFloat to rationalise.
 * @param[in]  prec  Another ::rb_cFloat, which is the "precision".
 * @return     Approximation of `flt`, in ::rb_cRational.
 */
VALUE rb_flt_rationalize_with_prec(VALUE flt, VALUE prec);

/**
 * Identical   to   rb_flt_rationalize_with_prec(),  except   it   auto-detects
 * appropriate precision depending on the passed value.
 *
 * @param[in]  flt   An instance of ::rb_cFloat to rationalise.
 * @return     Approximation of `flt`, in ::rb_cRational.
 */
VALUE rb_flt_rationalize(VALUE flt);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERN_RATIONAL_H */
ruby/internal/intern/hash.h000064400000027170151732674240011756 0ustar00#ifndef RBIMPL_INTERN_HASH_H                         /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_HASH_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Public APIs related to ::rb_cHash.
 */
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/st.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/* hash.c */

RBIMPL_ATTR_NONNULL(())
/**
 * Identical to rb_st_foreach(), except it  raises exceptions when the callback
 * function tampers the table during iterating over it.
 *
 * @param[in]  st                Table to iterate over.
 * @param[in]  func              Callback function to apply.
 * @param[in]  arg               Passed as-is to `func`.
 * @exception  rb_eRuntimeError  `st` was tampered during iterating.
 *
 * @internal
 *
 * This is declared here because exceptions are Ruby level concept.
 *
 * This is in fact a very thin wrapper of rb_st_foreach_check().
 */
void rb_st_foreach_safe(struct st_table *st, st_foreach_callback_func *func, st_data_t arg);

/** @alias{rb_st_foreach_safe} */
#define st_foreach_safe rb_st_foreach_safe

/**
 * Try  converting an  object to  its hash  representation using  its `to_hash`
 * method, if any.  If there is no such thing, returns ::RUBY_Qnil.
 *
 * @param[in]  obj            Arbitrary ruby object to convert.
 * @exception  rb_eTypeError  `obj.to_hash` returned something non-Hash.
 * @retval     RUBY_Qnil      No conversion from `obj` to hash defined.
 * @retval     otherwise      Converted hash representation of `obj`.
 * @see        rb_io_check_io
 * @see        rb_check_array_type
 * @see        rb_check_string_type
 *
 * @internal
 *
 * There   is  no   rb_hash_to_hash()   that   analogous  to   rb_str_to_str().
 * Intentional or ...?
 */
VALUE rb_check_hash_type(VALUE obj);

RBIMPL_ATTR_NONNULL(())
/**
 * Iterates   over  a   hash.   This   basically   does  the   same  thing   as
 * rb_st_foreach().  But because the passed hash is a Ruby object, its keys and
 * values are both Ruby objects.
 *
 * @param[in]  hash              An instance of ::rb_cHash to iterate over.
 * @param[in]  func              Callback function to yield.
 * @param[in]  arg               Passed as-is to `func`.
 * @exception  rb_eRuntimeError  `hash` was tampered during iterating.
 */
void rb_hash_foreach(VALUE hash, int (*func)(VALUE key, VALUE val, VALUE arg), VALUE arg);

/**
 * Calculates a message  authentication code of the passed  object.  The return
 * value is  a very small  integer used as  an index of a  key of a  table.  In
 * order  to calculate  the value  this function  calls `#hash`  method of  the
 * passed  object.  Ruby  provides you  a default  implementation.  But  if you
 * implement  your class  in C,  that  default implementation  cannot know  the
 * underlying data structure.  You must implement your own `#hash` method then,
 * which  must return  an integer  of  uniform distribution  in a  sufficiently
 * instant manner.
 *
 * @param[in]  obj            Arbitrary Ruby object.
 * @exception  rb_eTypeError  `obj.hash` returned something non-Integer.
 * @return     A small integer.
 * @note       `#hash` can return very big integers, but they get truncated.
 */
VALUE rb_hash(VALUE obj);

/**
 * Creates a new, empty hash object.
 *
 * @return  An allocated new instance of ::rb_cHash.
 */
VALUE rb_hash_new(void);

/**
 * Identical to rb_hash_new(), except it additionally specifies how many keys
 * it is expected to contain. This way you can create a hash that is large enough
 * for your need. For large hashes it means it won't need to be reallocated and
 * rehashed as much, improving performance.
 *
 * @param[in]  capa  Designed capacity of the hash.
 * @return     An empty Hash, whose capacity is `capa`.
 */
VALUE rb_hash_new_capa(long capa);

/**
 * Duplicates a hash.
 *
 * @param[in]  hash  An instance of ::rb_cHash.
 * @return     An  allocated new  instance  of ::rb_cHash,  whose contents  are
 *             a verbatim copy of from `hash`.
 */
VALUE rb_hash_dup(VALUE hash);

/** @alias{rb_obj_freeze} */
VALUE rb_hash_freeze(VALUE obj);

/**
 * Queries the given key  in the given hash table.  If there is  the key in the
 * hash, returns the  value associated with the key.  Otherwise  it returns the
 * "default" value (defined per hash table).
 *
 * @param[in]  hash  Hash table to look into.
 * @param[in]  key   Hash key to look for.
 * @return     Either the value associated with the  key, or the default one if
 *             absent.
 */
VALUE rb_hash_aref(VALUE hash, VALUE key);

/**
 * Identical  to  rb_hash_aref(),  except  it always  returns  ::RUBY_Qnil  for
 * misshits.
 *
 * @param[in]  hash  Hash table to look into.
 * @param[in]  key   Hash key to look for.
 * @return     Either  the value  associated with  the key,  or ::RUBY_Qnil  if
 *             absent.
 * @note       A hash can  store ::RUBY_Qnil as an ordinary  value.  You cannot
 *             distinguish whether the  key is missing, or  just its associated
 *             value happens to be ::RUBY_Qnil, as far as you use this API.
 */
VALUE rb_hash_lookup(VALUE hash, VALUE key);

/**
 * Identical  to rb_hash_lookup(),  except you  can specify  what to  return on
 * misshits.  This is much like 2-arguments version of `Hash#fetch`.
 *
 * ```CXX
 * VALUE hash;
 * VALUE key;
 * VALUE tmp = rb_obj_alloc(rb_cObject);
 * VALUE val = rb_hash_lookup2(hash, key, tmp);
 * if (val == tmp) {
 *     printf("misshit");
 * }
 * else {
 *     printf("hit");
 * }
 * ```
 *
 * @param[in]  hash       Hash table to look into.
 * @param[in]  key        Hash key to look for.
 * @param[in]  def        Default value.
 * @retval     def        `hash` does not have `key`.
 * @retval     otherwise  The value associated with `key`.
 */
VALUE rb_hash_lookup2(VALUE hash, VALUE key, VALUE def);

/**
 * Identical  to rb_hash_lookup(),  except  it yields  the (implicitly)  passed
 * block instead of returning ::RUBY_Qnil.
 *
 * @param[in]  hash          Hash table to look into.
 * @param[in]  key           Hash key to look for.
 * @exception  rb_eKeyError  No block given.
 * @return     Either  the value  associated with  the key,  or what  the block
 *             evaluates to if absent.
 */
VALUE rb_hash_fetch(VALUE hash, VALUE key);

/**
 * Inserts or replaces ("upsert"s) the objects into the given hash table.  This
 * basically associates the  given value with the given key.   On duplicate key
 * this function updates its associated value with the given one.  Otherwise it
 * inserts the association at the end of the table.
 *
 * @param[out]  hash             Target hash table to modify.
 * @param[in]   key              Arbitrary Ruby object.
 * @param[in]   val              A value to be associated with `key`.
 * @exception   rb_eFrozenError  `hash` is frozen.
 * @return      The passed `val`
 * @post        `val` is associated with `key` in `hash`.
 */
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val);

/**
 * Swipes everything out of the passed hash table.
 *
 * @param[out]  hash             Target to clear.
 * @exception   rb_eFrozenError  `hash`is frozen.
 * @return      The passed `hash`
 * @post        `hash` has no contents.
 */
VALUE rb_hash_clear(VALUE hash);

/**
 * Deletes each entry for which the block  returns a truthy value.  If there is
 * no block given, it returns an enumerator that does the thing.
 *
 * @param[out]  hash             Target hash to modify.
 * @exception   rb_eFrozenError  `hash` is frozen.
 * @retval      hash             The hash is modified.
 * @retval      otherwise        An instance of ::rb_cEnumerator that does it.
 */
VALUE rb_hash_delete_if(VALUE hash);

/**
 * Deletes the passed key from the passed hash table, if any.
 *
 * @param[out]  hash       Target hash to modify.
 * @param[in]   key        Key to delete.
 * @retval      RUBY_Qnil  `hash` has no such key as `key`.
 * @retval      otherwise  What was associated with `key`.
 * @post        `hash` has no such key as `key`.
 */
VALUE rb_hash_delete(VALUE hash, VALUE key);

/**
 * Inserts  a list  of  key-value pairs  into  a  hash table  at  once.  It  is
 * semantically  identical to  repeatedly  calling rb_hash_aset(),  but can  be
 * faster than that.
 *
 * @param[in]   argc  Length of `argv`, must be even.
 * @param[in]   argv  A list of key, value, key, value, ...
 * @param[out]  hash  Target hash table to modify.
 * @post        `hash` has contents from `argv`.
 * @note        `argv` is allowed to be NULL as long as `argc` is zero.
 *
 * @internal
 *
 * What happens for  duplicated keys?  Well it silently discards  older ones to
 * accept the newest (rightmost) one.  This behaviour also mimics repeated call
 * of rb_hash_aset().
 */
void rb_hash_bulk_insert(long argc, const VALUE *argv, VALUE hash);

/**
 * Type of callback functions to pass to rb_hash_update_by().
 *
 * @param[in]  newkey  A key of the table.
 * @param[in]  oldkey  Value associated with `key` in hash1.
 * @param[in]  value   Value associated with `key` in hash2.
 * @return     Either one of the passed values to take.
 */
typedef VALUE rb_hash_update_func(VALUE newkey, VALUE oldkey, VALUE value);

/**
 * Destructively merges two hash tables into one.  It resolves key conflicts by
 * calling the passed function and take its return value.
 *
 * @param[out]  hash1             Target hash to be modified.
 * @param[in]   hash2             A hash to merge into `hash1`.
 * @param[in]   func              Conflict reconciler.
 * @exception   rb_eFrozenError   `hash1` is frozen.
 * @exception   rb_eRuntimeError  `hash2` is updated instead.
 * @return      The passed `hash1`.
 * @post        Contents of `hash2` is merged into `hash1`.
 * @note        You can  pass zero to  `func`.  This means values  from `hash2`
 *              are always taken.
 */
VALUE rb_hash_update_by(VALUE hash1, VALUE hash2, rb_hash_update_func *func);

/* file.c */

/**
 * This function is mysterious.  What it does is not immediately obvious.  Also
 * what it does seems platform dependent.
 *
 * @param[in]  path       A local path.
 * @retval     0          The "check" succeeded.
 * @retval     otherwise  The "check" failed.
 */
int rb_path_check(const char *path);

/* hash.c */

/**
 * Destructively removes every environment variables of the running process.
 *
 * @return  The `ENV` object.
 * @post    The process has no environment variables.
 */
VALUE rb_env_clear(void);

/**
 * Identical to  #RHASH_SIZE(), except  it returns the  size in  Ruby's integer
 * instead of C's.
 *
 * @param[in]  hash  A hash object.
 * @return     The size of the hash.
 */
VALUE rb_hash_size(VALUE hash);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERN_HASH_H */
ruby/internal/intern/object.h000064400000046122151732674250012300 0ustar00#ifndef RBIMPL_INTERN_OBJECT_H                       /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_OBJECT_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Public APIs related to ::rb_cObject.
 */
#include "ruby/internal/attr/const.h"
#include "ruby/internal/attr/deprecated.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/**
 * This macro is (used but) mysterious.  Why on earth do we need this?
 *
 * - `obj != orig` check is done anyways inside of rb_obj_init_copy().
 * - rb_obj_init_copy() returns something.  No need are there to add `, 1`.
 */
#define RB_OBJ_INIT_COPY(obj, orig) \
    ((obj) != (orig) && (rb_obj_init_copy((obj), (orig)), 1))
/** @old{RB_OBJ_INIT_COPY} */
#define OBJ_INIT_COPY(obj, orig) RB_OBJ_INIT_COPY(obj, orig)

/* object.c */

/**
 * Identical to  rb_class_new_instance(), except it passes  the passed keywords
 * if any to the `#initialize` method.
 *
 * @param[in]  argc           Number of objects of `argv`.
 * @param[in]  argv           Arbitrary number of method arguments.
 * @param[in]  klass          An instance of ::rb_cClass.
 * @exception  rb_eTypeError  `klass`'s allocator is undefined.
 * @exception  rb_eException  Any exceptions can happen inside.
 * @return     An allocated new instance of `klass`.
 * @note       This is _the_ implementation of `Object.new`.
 */
VALUE rb_class_new_instance_pass_kw(int argc, const VALUE *argv, VALUE klass);

/**
 * Allocates, then initialises an instance of  the given class.  It first calls
 * the passed  class' allocator to  obtain an uninitialised object,  then calls
 * its initialiser with the remaining arguments.
 *
 * @param[in]  argc           Number of objects of `argv`.
 * @param[in]  argv           Arguments passed to `#initialize`.
 * @param[in]  klass          An instance of ::rb_cClass.
 * @exception  rb_eTypeError  `klass`'s allocator is undefined.
 * @exception  rb_eException  Any exceptions can happen inside.
 * @return     An allocated new instance of `klass`.
 */
VALUE rb_class_new_instance(int argc, const VALUE *argv, VALUE klass);

/**
 * Identical to rb_class_new_instance(),  except you can specify  how to handle
 * the last element of the given array.
 *
 * @param[in]  argc             Number of objects of `argv`.
 * @param[in]  argv             Arbitrary number of method arguments.
 * @param[in]  klass            An instance of ::rb_cClass.
 * @param[in]  kw_splat         Handling of keyword parameters:
 *   - RB_NO_KEYWORDS           `argv`'s last is not a keyword argument.
 *   - RB_PASS_KEYWORDS         `argv`'s last is a keyword argument.
 *   - RB_PASS_CALLED_KEYWORDS  it depends if there is a passed block.
 * @exception  rb_eTypeError    `klass`'s allocator is undefined.
 * @exception  rb_eException    Any exceptions can happen inside.
 * @return     An allocated new instance of `klass`.
 */
VALUE rb_class_new_instance_kw(int argc, const VALUE *argv, VALUE klass, int kw_splat);

/**
 * Checks for equality of the passed objects, in terms of `Object#eql?`.
 *
 * @param[in]  lhs          Comparison left hand side.
 * @param[in]  rhs          Comparison right hand side.
 * @retval     non-zero     They are equal.
 * @retval     0            Otherwise.
 * @note       This  function  actually  calls `lhs.eql?(rhs)`  so  you  cannot
 *             implement your class' `#eql?` method using it.
 */
int rb_eql(VALUE lhs, VALUE rhs);

/**
 * Generates a textual representation of the given object.
 *
 * @param[in]  obj  Arbitrary ruby object.
 * @return     An instance of ::rb_cString that represents `obj`.
 * @note       This is  the default  implementation of `Object#to_s`  that each
 *             subclasses want to override.
 */
VALUE rb_any_to_s(VALUE obj);

/**
 * Generates a human-readable textual representation of the given object.  This
 * is  largely similar  to Ruby  level `Object#inspect`  but not  the same;  it
 * additionally escapes the inspection result  so that the string be compatible
 * with that of default internal (or default external, if absent).
 *
 * @param[in]  obj  Arbitrary ruby object.
 * @return     An instance of ::rb_cString that represents `obj`.
 */
VALUE rb_inspect(VALUE obj);

/**
 * Queries if the given object is a direct instance of the given class.
 *
 * @param[in]  obj            Arbitrary ruby object.
 * @param[in]  klass          An instance of ::rb_cModule.
 * @exception  rb_eTypeError  `klass` is neither module nor class.
 * @retval     RUBY_Qtrue     `obj` is an instance of `klass`.
 * @retval     RUBY_Qfalse    Otherwise.
 */
VALUE rb_obj_is_instance_of(VALUE obj, VALUE klass);

/**
 * Queries if the given object is  an instance (of possibly descendants) of the
 * given class.
 *
 * @param[in]  obj            Arbitrary ruby object.
 * @param[in]  klass          An instance of ::rb_cModule.
 * @exception  rb_eTypeError  `klass` is neither module nor class.
 * @retval     RUBY_Qtrue     `obj` is a `klass`.
 * @retval     RUBY_Qfalse    Otherwise.
 */
VALUE rb_obj_is_kind_of(VALUE obj, VALUE klass);

/**
 * Allocates an instance of the given class.
 *
 * @param[in]  klass          A class to instantiate.
 * @exception  rb_eTypeError  `klass` is not a class.
 * @return     An allocated, not yet initialised instance of `klass`.
 * @note       It calls  the allocator defined by  rb_define_alloc_func().  You
 *             cannot  use   this  function   to  define  an   allocator.   Use
 *             TypedData_Make_Struct or others, instead.
 * @note       Usually  prefer  rb_class_new_instance() to  rb_obj_alloc()  and
 *             rb_obj_call_init().
 * @see        rb_class_new_instance()
 * @see        rb_obj_call_init()
 * @see        rb_define_alloc_func()
 * @see        #TypedData_Make_Struct
 */
VALUE rb_obj_alloc(VALUE klass);

/**
 * Produces a shallow copy of the given object.  Its list of instance variables
 * are copied, but  not the objects they reference.  It  also copies the frozen
 * value state.
 *
 * @param[in]  obj            Arbitrary ruby object.
 * @exception  rb_eException  `#initialize_copy` can raise anything.
 * @return     A "clone" of `obj`.
 *
 * @internal
 *
 * Unlike ruby-level `Object#clone`, there is no way to control the frozen-ness
 * of the return value.
 */
VALUE rb_obj_clone(VALUE obj);

/**
 * Duplicates  the  given   object.   This  does  almost  the   same  thing  as
 * rb_obj_clone() do.  However  it does not copy the singleton  class (if any).
 * It also doesn't copy frozen-ness.
 *
 * @param[in]  obj            Arbitrary ruby object.
 * @exception  rb_eException  `#initialize_copy` can raise anything.
 * @return     A shallow copy of `obj`.
 */
VALUE rb_obj_dup(VALUE obj);

/**
 * Default   implementation   of  `#initialize_copy`,   `#initialize_dup`   and
 * `#initialize_clone`.  It  does almost  nothing.  Just raises  exceptions for
 * checks.
 *
 * @param[in]  dst              The destination object.
 * @param[in]  src              The source object.
 * @exception  rb_eFrozenError  `dst` is frozen.
 * @exception  rb_eTypeError    `dst` and `src` have different classes.
 * @return     Always returns `dst`.
 */
VALUE rb_obj_init_copy(VALUE src, VALUE dst);

/**
 * Just  calls  rb_obj_freeze_inline() inside.   Does  this  make any  sens  to
 * extension libraries?
 *
 * @param[out]  obj  Object to freeze.
 * @return      Verbatim `obj`.
 */
VALUE rb_obj_freeze(VALUE obj);

RBIMPL_ATTR_PURE()
/**
 * Just calls  RB_OBJ_FROZEN() inside.   Does this make  any sens  to extension
 * libraries?
 *
 * @param[in]  obj          Object in question.
 * @retval     RUBY_Qtrue   Yes it is.
 * @retval     RUBY_Qfalse  No it isn't.
 */
VALUE rb_obj_frozen_p(VALUE obj);

/* gc.c */

/**
 * Finds or  creates an integer  primary key of the  given object.  In  the old
 * days  this  function  was  a  purely  arithmetic  operation  that  maps  the
 * underlying memory  address where the  object resides into a  Ruby's integer.
 * Some time around  2.x this changed.  It no longer  relates its return values
 * to C level pointers.  This function  assigns some random number to the given
 * object  if absent.   The  same number  will be  returned  on all  subsequent
 * requests.  No two active objects share a number.
 *
 * @param[in]  obj  Arbitrary ruby object.
 * @return     An instance of ::rb_cInteger which is an "identifier" of `obj`.
 *
 * @internal
 *
 * The "some  random number" is  in fact a  monotonic-increasing process-global
 * unique integer, much like an  `INTEGER AUTO_INCREMENT PRIMARY KEY` column in
 * a MySQL table.
 */
VALUE rb_obj_id(VALUE obj);

RBIMPL_ATTR_CONST()
/**
 * Identical to rb_obj_id(), except it hesitates from allocating a new instance
 * of ::rb_cInteger.  rb_obj_id() could allocate ::RUBY_T_BIGNUM objects.  That
 * allocation  might  perhaps  impact  negatively.  On  such  situations,  this
 * function  instead returns  one-shot temporary  small integers  that need  no
 * allocations at all.  The values are  guaranteed unique at the moment, but no
 * future promise  is made; could  be reused.  Use of  this API should  be very
 * instant.  It is a failure to store the returned integer to somewhere else.
 *
 * In short it is difficult to use.
 *
 * @param[in]  obj  Arbitrary ruby object.
 * @return     An instance of ::rb_cInteger unique at the moment.
 *
 * @internal
 *
 * This is roughly the old behaviour of rb_obj_id().
 */
VALUE rb_memory_id(VALUE obj);

/* object.c */

RBIMPL_ATTR_PURE()
/**
 * Finds a "real" class.  As the name  implies there are class objects that are
 * surreal.   This function  takes a  class, traverses  its ancestry  tree, and
 * returns  its nearest  ancestor which  is neither  a module  nor a  singleton
 * class.
 *
 * @param[in]  klass        An instance of ::rb_cClass.
 * @retval     RUBY_Qfalse  No real class in `klass`' ancestry tree.
 * @retval     klass        `klass` itself is a real class.
 * @retval     otherwise    Nearest ancestor of `klass` who is real.
 */
VALUE rb_class_real(VALUE klass);

RBIMPL_ATTR_PURE()
/**
 * Determines if the given two modules are relatives.
 *
 * @param[in]  scion          Possible subclass.
 * @param[in]  ascendant      Possible superclass.
 * @exception  rb_eTypeError  `ascendant` is not a module.
 * @retval     RUBY_Qtrue     `scion` inherits, or is equal to `ascendant`.
 * @retval     RUBY_Qfalse    `ascendant` inherits `scion`.
 * @retval     RUBY_Qnil      They are not relatives.
 */
VALUE rb_class_inherited_p(VALUE scion, VALUE ascendant);

RBIMPL_ATTR_PURE()
/**
 * Queries the parent of the given class.
 *
 * @param[in]  klass          A child class.
 * @exception  rb_eTypeError  `klass` is a `Class.allocate`.
 * @retval     RUBY_Qfalse    `klass` has no superclass.
 * @retval     otherwise      `klass`' superclass.
 *
 * @internal
 *
 * Is there any class except ::rb_cBasicObject, that has no superclass?
 */
VALUE rb_class_superclass(VALUE klass);

RBIMPL_ATTR_NONNULL(())
/**
 * Converts an object into another type.  Calls the specified conversion method
 * if necessary.
 *
 * @param[in]  val            An object to convert.
 * @param[in]  type           A value of enum ::ruby_value_type.
 * @param[in]  name           Name to display on error (e.g. "Array").
 * @param[in]  mid            Conversion method (e.g. "to_ary").
 * @exception  rb_eTypeError  Failed to convert.
 * @return     An object of the specified type.
 */
VALUE rb_convert_type(VALUE val, int type, const char *name, const char *mid);

RBIMPL_ATTR_NONNULL(())
/**
 * Identical  to rb_convert_type(),  except it  returns ::RUBY_Qnil  instead of
 * raising  exceptions,  in  case  of  conversion  failure.   It  still  raises
 * exceptions  for various  reasons,  like when  the  conversion method  itself
 * raises, though.
 *
 * @param[in]  val            An object to convert.
 * @param[in]  type           A value of enum ::ruby_value_type.
 * @param[in]  name           Name to display on error (e.g. "Array").
 * @param[in]  mid            Conversion method (e.g. "to_ary").
 * @exception  rb_eTypeError  The `mid` does not generate `type`.
 * @retval     RUBY_Qnil      No conversion defined.
 * @retval     otherwise      An object of the specified type.
 */
VALUE rb_check_convert_type(VALUE val, int type, const char *name, const char *mid);

RBIMPL_ATTR_NONNULL(())
/**
 * Identical to rb_check_convert_type(), except the  return value type is fixed
 * to ::rb_cInteger.
 *
 * @param[in]  val            An object to convert.
 * @param[in]  mid            Conversion method (e.g. "to_ary").
 * @exception  rb_eTypeError  The `mid` does not generate an integer.
 * @retval     RUBY_Qnil      No conversion defined.
 * @retval     otherwise      An instance of ::rb_cInteger.
 */
VALUE rb_check_to_integer(VALUE val, const char *mid);

/**
 * This is complicated.
 *
 *   - When  the passed  object is  already  an instance  of ::rb_cFloat,  just
 *     returns it as-is.
 *
 *   - When  the passed  object is  something  numeric, the  function tries  to
 *     convert it using `#to_f` method.
 *
 *       - If that conversion fails (this happens for instance when the numeric
 *         is a complex) it returns ::RUBY_Qnil.
 *
 *       - Otherwise returns the conversion result.
 *
 *   - Otherwise it also returns ::RUBY_Qnil.
 *
 * @param[in]  val        An object to convert.
 * @retval     RUBY_Qnil  Conversion from `val` to float is undefined.
 * @retval     otherwise  Converted result.
 */
VALUE rb_check_to_float(VALUE val);

/**
 * Identical  to rb_check_to_int(),  except  it raises  in  case of  conversion
 * mismatch.
 *
 * @param[in]  val            An object to convert.
 * @exception  rb_eTypeError  `#to_int` does not generate an integer.
 * @return     An instance of ::rb_cInteger.
 */
VALUE rb_to_int(VALUE val);

/**
 * Identical to rb_check_to_integer(), except it uses `#to_int` for conversion.
 *
 * @param[in]  val            An object to convert.
 * @exception  rb_eTypeError  `#to_int` does not return an integer.
 * @retval     RUBY_Qnil      No conversion defined.
 * @retval     otherwise      An instance of ::rb_cInteger.
 */
VALUE rb_check_to_int(VALUE val);

/**
 * This  is the  logic behind  `Kernel#Integer`.  Numeric  types are  converted
 * directly,  with  floating  point   numbers  being  truncated.   Strings  are
 * interpreted  strictly; only  leading/trailing whitespaces,  plus/minus sign,
 * radix  indicators  such  as  `0x`,  digits,  and  underscores  are  allowed.
 * Anything else are converted by first trying `#to_int`, then `#to_i`.
 *
 * This is slightly stricter than `String#to_i`.
 *
 * @param[in]  val            An object to convert.
 * @exception  rb_eArgError   Malformed `val` passed.
 * @exception  rb_eTypeError  No conversion defined.
 * @return     An instance of ::rb_cInteger.
 */
VALUE rb_Integer(VALUE val);

/**
 * Identical to rb_check_to_float(), except it raises on error.
 *
 * @param[in]  val            An object to convert.
 * @exception  rb_eTypeError  No conversion defined.
 * @return     An instance of ::rb_cFloat.
 */
VALUE rb_to_float(VALUE val);

/**
 * This  is  the logic  behind  `Kernel#Float`.   Numeric types  are  converted
 * directly  to the  nearest value  that a  Float can  represent.  Strings  are
 * interpreted strictly;  only leading/trailing whitespaces are  allowed except
 * what `strtod` understands.  Anything else are converted using `#to_f`.
 *
 * This is slightly stricter than `String#to_f`.
 *
 * @param[in]  val            An object to convert.
 * @exception  rb_eArgError   Malformed `val` passed.
 * @exception  rb_eTypeError  No conversion defined.
 * @return     An instance of ::rb_cFloat.
 */
VALUE rb_Float(VALUE val);

/**
 * This is the logic behind  `Kernel#String`.  Arguments are converted by first
 * trying `#to_str`, then `#to_s`.
 *
 * @param[in]  val            An object to convert.
 * @exception  rb_eTypeError  No conversion defined.
 * @return     An instance of ::rb_cString.
 */
VALUE rb_String(VALUE val);

/**
 * This is the  logic behind `Kernel#Array`.  Arguments are  converted by first
 * trying `#to_ary`,  then `#to_a`,  and if  both failed,  returns an  array of
 * length 1 that contains the passed argument as the sole contents.
 *
 * @param[in]  val  An object to convert.
 * @return     An instance of ::rb_cArray.
 */
VALUE rb_Array(VALUE val);

/**
 * This is  the logic behind  `Kernel#Hash`.  Arguments are converted  by first
 * trying `#to_hash`.  if it failed, and  the argument is either ::RUBY_Qnil or
 * an empty array, returns an empty hash.  Otherwise an exception is raised.
 *
 * @param[in]  val            An object to convert.
 * @exception  rb_eTypeError  No conversion defined.
 * @return     An instance of ::rb_cHash.
 */
VALUE rb_Hash(VALUE val);

RBIMPL_ATTR_NONNULL(())
/**
 * Converts a textual representation of a  real number into a numeric, which is
 * the nearest value that the return type  can represent, of the value that the
 * argument represents.  This is in fact  a 2-in-1 function whose behaviour can
 * be controlled using  the second (mode) argument.  If the  mode is zero, this
 * function is in "historical"  mode which only understands "floating-constant"
 * defined at ISO/IEC 9899:1990 section 6.1.3.1.  If the mode is nonzero, it is
 * in  "extended"  mode,  which  also  accepts  "hexadecimal-floating-constant"
 * defined at ISO/IEC 9899:2018 section 6.4.4.2.
 *
 * @param[in]  str           A textual representation of a real number.
 * @param[in]  mode          Conversion mode, as described above.
 * @exception  rb_eArgError  Malformed `str` passed.
 * @see        https://bugs.ruby-lang.org/issues/2969
 * @note       Null pointers are allowed, and it returns 0.0 then.
 */
double rb_cstr_to_dbl(const char *str, int mode);

/**
 * Identical to rb_cstr_to_dbl(), except it  accepts a Ruby's string instead of
 * C's.
 *
 * @param[in]  str           A textual representation of a real number.
 * @param[in]  mode          Conversion mode, as described in rb_cstr_to_dbl().
 * @exception  rb_eArgError  Malformed `str` passed.
 * @see        https://bugs.ruby-lang.org/issues/2969
 */
double rb_str_to_dbl(VALUE str, int mode);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERN_OBJECT_H */
ruby/internal/intern/eval.h000064400000020770151732674250011762 0ustar00#ifndef  RBIMPL_INTERN_EVAL_H                        /*-*-C++-*-vi:se ft=cpp:*/
#define  RBIMPL_INTERN_EVAL_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Pre-1.9 era evaluator APIs (now considered miscellaneous).
 */
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/* eval.c */
RBIMPL_ATTR_NORETURN()
/**
 * Identical to rb_raise(), except it  raises the passed exception instance as-
 * is instead of creating new one.
 *
 * @param[in]  exc            An instance of a subclass of ::rb_eException.
 * @exception  exc            What is passed.
 * @exception  rb_eTypeError  `exc` is not an exception.
 * @note       It never returns.
 *
 * @internal
 *
 * Wellll  actually, it  can  take more  than what  is  described above.   This
 * function tries  to call `exception`  method of  the passed object.   If that
 * function returns an exception object that is used instead.
 */
void rb_exc_raise(VALUE exc);

RBIMPL_ATTR_NORETURN()
/**
 * Identical to rb_fatal(), except it  raises the passed exception instance as-
 * is instead of creating new one.
 *
 * @param[in]  exc  An instance of a subclass of ::rb_eException.
 * @exception  exc  What is passed.
 * @note       It never returns.
 *
 * @internal
 *
 * You know  what...?  Using this API  you can make arbitrary  exceptions, like
 * `RuntimeError`, that doesn't  interface with `rescue` clause.   This is very
 * confusing.
 */
void rb_exc_fatal(VALUE exc);

/* process.c */

RBIMPL_ATTR_NORETURN()
/**
 * Identical to rb_exit(), except how arguments are passed.
 *
 * @param[in]  argc            Number of objects of `argv`.
 * @param[in]  argv            Contains at most one of the following:
 *                               - ::RUBY_Qtrue - means `EXIT_SUCCESS`.
 *                               - ::RUBY_Qfalse - means `EXIT_FAILURE`.
 *                               - Numerical value - takes that value.
 * @exception  rb_eArgError    Wrong `argc`.
 * @exception  rb_eSystemExit  Exception representing the exit status.
 * @note       It never returns.
 */
VALUE rb_f_exit(int argc, const VALUE *argv);

RBIMPL_ATTR_NORETURN()
/**
 * This is  similar to rb_f_exit().   In fact  on some situation  it internally
 * calls rb_exit().  But can be very esoteric on occasions.
 *
 * It takes up to one argument.  If  an argument is passed, it tries to display
 * that.   Otherwise if  there is  `$!`, displays  that exception  instead.  It
 * finally raise ::rb_eSystemExit in both cases.
 *
 * @param[in]  argc            Number of objects of `argv`.
 * @param[in]  argv            Contains at most one string-ish object.
 * @exception  rb_eArgError    Wrong `argc`.
 * @exception  rb_eTypeError   No conversion from `argv[0]` to String.
 * @exception  rb_eSystemExit  Exception representing `EXIT_FAILURE`.
 * @note       It never returns.
 */
VALUE rb_f_abort(int argc, const VALUE *argv);

/* eval.c*/

RBIMPL_ATTR_NORETURN()
/**
 * Raises an instance of ::rb_eInterrupt.
 *
 * @exception  rb_eInterrupt  Always raises this exception.
 * @note       It never returns.
 */
void rb_interrupt(void);

/**
 * Queries the  name of the  Ruby level method  that is calling  this function.
 * The "name" in this context is the one assigned to the function for the first
 * time (note that methods can have multiple names via aliases).
 *
 * @retval  0          There is no method (e.g. toplevel context).
 * @retval  otherwise  The name of the current method.
 */
ID rb_frame_this_func(void);

RBIMPL_ATTR_NORETURN()
/**
 * This function  is to re-throw  global escapes.  Such global  escapes include
 * exceptions, `throw`, `break`, for example.
 *
 * It makes  sense only  when used  in conjunction  with "protect"  series APIs
 * e.g.  rb_protect(),  rb_load_protect(), rb_eval_string_protect(),  etc.   In
 * case  these functions  experience  global escapes,  they  fill their  opaque
 * `state` return  buffer.  You  can ignore  such escapes.   But if  you decide
 * otherwise, you have to somehow escape globally again.  This function is used
 * for that purpose.
 *
 * @param[in]  state  Opaque state of execution.
 * @note       It never returns.
 *
 * @internal
 *
 * Though  not  a  part  of  our  public  API,  `state`  is  in  fact  an  enum
 * ruby_tag_type.  You can see the potential values by looking at vm_core.h.
 */
void rb_jump_tag(int state);

/**
 * Calls `initialize`  method of the  passed object with the  passed arguments.
 * It also forwards the implicitly passed block to the method.
 *
 * @param[in]  obj            Receiver object.
 * @param[in]  argc           Number of objects of `argv`.
 * @param[in]  argv           Passed as-is to `obj.initialize`.
 * @exception  rb_eException  Any exceptions happen inside.
 */
void rb_obj_call_init(VALUE obj, int argc, const VALUE *argv);

/**
 * Identical to  rb_obj_call_init(), except you  can specify how to  handle the
 * last element of the given array.
 *
 * @param[in]  obj                Receiver object.
 * @param[in]  argc               Number of objects of `argv`.
 * @param[in]  argv               Passed as-is to `obj.initialize`.
 * @param[in]  kw_splat           Handling of keyword parameters:
 *   - RB_NO_KEYWORDS             `argv`'s last is not a keyword argument.
 *   - RB_PASS_KEYWORDS           `argv`'s last is a keyword argument.
 *   - RB_PASS_CALLED_KEYWORDS    it depends if there is a passed block.
 * @exception  rb_eNoMethodError  No such method.
 * @exception  rb_eException      Any exceptions happen inside.
 */
void rb_obj_call_init_kw(VALUE, int, const VALUE*, int);

/**
 * Identical to rb_frame_this_func(), except it  returns the named used to call
 * the method.
 *
 * @retval  0          There is no method (e.g. toplevel context).
 * @retval  otherwise  The name of the current method.
 */
ID rb_frame_callee(void);

/**
 * Constructs  an exception  object from  the list  of arguments,  in a  manner
 * similar to Ruby's `raise`.  This function can take:
 *
 *   - No arguments  at all,  i.e. `argc  == 0`.   This is  not a  failure.  It
 *     returns ::RUBY_Qnil then.
 *
 *   - An  object, which  is  an instance  of ::rb_cString.   In  this case  an
 *     instance of  ::rb_eRuntimeError whose  message is  the passed  string is
 *     created then returned.
 *
 *   - An  object, which  responds to  `exception` method,  and optionally  its
 *     argument,  and  optionally  its  backtrace.  For  example  instances  of
 *     subclasses of ::rb_eException  have this method.  What  is returned from
 *     the method is returned.
 *
 * @param[in]  argc           Number of objects of `argv`.
 * @param[in]  argv           0 up to 3 objects.
 * @exception  rb_eArgError   Wrong `argc`.
 * @exception  rb_eTypeError  `argv[0].exception` returned non-exception.
 * @return     An instance of a subclass of ::rb_eException.
 *
 * @internal
 *
 * Historically  this was  _the_  way  `raise` converted  its  arguments to  an
 * exception.  However they diverged.
 */
VALUE rb_make_exception(int argc, const VALUE *argv);

/* eval_jump.c */

/**
 * Registers a function  that shall run on process  exit.  Registered functions
 * run in  reverse-chronological order,  mixed with  syntactic `END`  block and
 * `Kernel#at_exit`.
 *
 * @param[in]  func  Function to run at process exit.
 * @param[in]  arg   Passed as-is to `func`.
 */
void rb_set_end_proc(void (*func)(VALUE arg), VALUE arg);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERN_EVAL_H */
ruby/internal/intern/select/largesize.h000064400000015750151732674250014301 0ustar00#ifndef RBIMPL_INTERN_SELECT_LARGESIZE_H             /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_SELECT_LARGESIZE_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Public APIs to provide ::rb_fd_select().
 *
 * Several Unix  platforms support file  descriptors bigger than  FD_SETSIZE in
 * `select(2)` system call.
 *
 * - Linux 2.2.12 (?)
 *
 * - NetBSD 1.2 (src/sys/kern/sys_generic.c:1.25)
 *   `select(2)` documents how to allocate fd_set dynamically.
 *   http://netbsd.gw.com/cgi-bin/man-cgi?select++NetBSD-4.0
 *
 * - FreeBSD 2.2 (src/sys/kern/sys_generic.c:1.19)
 *
 * - OpenBSD 2.0 (src/sys/kern/sys_generic.c:1.4)
 *   `select(2)` documents how to allocate fd_set dynamically.
 *   http://www.openbsd.org/cgi-bin/man.cgi?query=select&manpath=OpenBSD+4.4
 *
 * - Solaris 8 has `select_large_fdset`
 *
 * - Mac OS X 10.7 (Lion)
 *   `select(2)` returns `EINVAL`  if `nfds` is greater  than `FD_SET_SIZE` and
 *   `_DARWIN_UNLIMITED_SELECT` (or `_DARWIN_C_SOURCE`) isn't defined.
 *   http://developer.apple.com/library/mac/#releasenotes/Darwin/SymbolVariantsRelNotes/_index.html
 *
 * When `fd_set` is not  big enough to hold big file  descriptors, it should be
 * allocated dynamically.   Note that  this assumes  `fd_set` is  structured as
 * bitmap.
 *
 * `rb_fd_init` allocates the memory.
 * `rb_fd_term` frees the memory.
 * `rb_fd_set` may re-allocate bitmap.
 *
 * So `rb_fd_set` doesn't reject file descriptors bigger than `FD_SETSIZE`.
 */
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/dllexport.h"

/**@cond INTERNAL_MACRO */
#define rb_fd_ptr rb_fd_ptr
#define rb_fd_max rb_fd_max
/** @endcond */

struct timeval;

/**
 * The data  structure which wraps the  fd_set bitmap used by  select(2).  This
 * allows Ruby to use FD sets  larger than that allowed by historic limitations
 * on modern platforms.
 */
typedef struct {
    int maxfd;                  /**< Maximum allowed number of FDs. */
    fd_set *fdset;              /**< File descriptors buffer */
} rb_fdset_t;

RBIMPL_SYMBOL_EXPORT_BEGIN()
RBIMPL_ATTR_NONNULL(())
/**
 * (Re-)initialises a  fdset.  One must  be initialised before  other `rb_fd_*`
 * operations.  Analogous to calling `malloc(3)` to allocate an `fd_set`.
 *
 * @param[out]  f  An fdset to squash.
 * @post        `f` holds no file descriptors.
 */
void rb_fd_init(rb_fdset_t *f);

RBIMPL_ATTR_NONNULL(())
/**
 * Destroys the ::rb_fdset_t,  releasing any memory and resources  it used.  It
 * must be  reinitialised using rb_fd_init()  before future use.   Analogous to
 * calling `free(3)` to release memory for an `fd_set`.
 *
 * @param[out]  f  An fdset to squash.
 * @post        `f` holds no file descriptors.
 */
void rb_fd_term(rb_fdset_t *f);

RBIMPL_ATTR_NONNULL(())
/**
 * Wipes out the current set of FDs.
 *
 * @param[out]  f  The fdset to clear.
 * @post        `f` has no FDs.
 */
void rb_fd_zero(rb_fdset_t *f);

RBIMPL_ATTR_NONNULL(())
/**
 * Sets an fd to a fdset.
 *
 * @param[in]   fd  A file descriptor.
 * @param[out]  f   Target fdset.
 * @post        `f` holds `fd`.
 */
void rb_fd_set(int fd, rb_fdset_t *f);

RBIMPL_ATTR_NONNULL(())
/**
 * Releases a specific FD from the given fdset.
 *
 * @param[in]   fd  Target FD.
 * @param[out]  f   The fdset that holds `fd`.
 * @post        `f` doesn't hold n.
 */
void rb_fd_clr(int fd, rb_fdset_t *f);

RBIMPL_ATTR_NONNULL(())
RBIMPL_ATTR_PURE()
/**
 * Queries if the given FD is in the given set.
 *
 * @param[in]  fd  Target FD.
 * @param[in]  f   The fdset to scan.
 * @retval     1   Yes there is.
 * @retval     0   No there isn't.
 * @see        http://www.freebsd.org/cgi/query-pr.cgi?pr=91421
 */
int rb_fd_isset(int fd, const rb_fdset_t *f);

/**
 * Destructively overwrites an fdset with another.
 *
 * @param[out]  dst   Target fdset.
 * @param[in]   src   Source fdset.
 * @param[in]   max   Maximum number of file descriptors to copy.
 * @post        `dst` is a copy of `src`.
 */
void rb_fd_copy(rb_fdset_t *dst, const fd_set *src, int max);

/**
 * Identical  to  rb_fd_copy(),  except  it copies  unlimited  number  of  file
 * descriptors.
 *
 * @param[out]  dst   Target fdset.
 * @param[in]   src   Source fdset.
 * @post        `dst` is a copy of `src`.
 */
void rb_fd_dup(rb_fdset_t *dst, const rb_fdset_t *src);

/**
 * Waits for multiple file descriptors at once.
 *
 * @param[in]      nfds       Max FD in everything passed, plus one.
 * @param[in,out]  rfds       Set of FDs to wait for reads.
 * @param[in,out]  wfds       Set of FDs to wait for writes.
 * @param[in,out]  efds       Set of FDs to wait for OOBs.
 * @param[in,out]  timeout    Max blocking duration.
 * @retval         -1         Failed, errno set.
 * @retval          0         Timeout exceeded.
 * @retval         otherwise  Total number of file descriptors returned.
 * @post           `rfds` contains readable FDs.
 * @post           `wfds` contains writable FDs.
 * @post           `efds` contains exceptional FDs.
 * @post           `timeout` is the time left.
 * @note           All pointers are allowed to be null pointers.
 */
int rb_fd_select(int nfds, rb_fdset_t *rfds, rb_fdset_t *wfds, rb_fdset_t *efds, struct timeval *timeout);
RBIMPL_SYMBOL_EXPORT_END()

RBIMPL_ATTR_NONNULL(())
RBIMPL_ATTR_PURE()
/**
 * Raw pointer to `fd_set`.
 *
 * @param[in]  f         Target fdset.
 * @retval     NULL      `f` is already terminated by rb_fd_term().
 * @retval     otherwise  Underlying fd_set.
 *
 * @internal
 *
 * Extension library  must not touch  raw pointers.  It was  a bad idea  to let
 * them use it.
 */
static inline fd_set *
rb_fd_ptr(const rb_fdset_t *f)
{
    return f->fdset;
}

RBIMPL_ATTR_NONNULL(())
RBIMPL_ATTR_PURE()
/**
 * It seems this function has no use.  Maybe just remove?
 *
 * @param[in]  f  A set.
 * @return     Number of file descriptors stored.
 */
static inline int
rb_fd_max(const rb_fdset_t *f)
{
    return f->maxfd;
}

#endif /* RBIMPL_INTERN_SELECT_LARGESIZE_H */
ruby/internal/intern/select/posix.h000064400000010335151732674250013450 0ustar00#ifndef RBIMPL_INTERN_SELECT_POSIX_H                 /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_SELECT_POSIX_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Public APIs to provide ::rb_fd_select().
 */
#include "ruby/internal/config.h"

#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>        /* for select(2) (modern POSIX) */
#endif

#ifdef HAVE_UNISTD_H
# include <unistd.h>            /* for select(2) (archaic UNIX) */
#endif

#include "ruby/internal/attr/const.h"
#include "ruby/internal/attr/noalias.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/pure.h"

/**
 * The data structure which wraps the  fd_set bitmap used by `select(2)`.  This
 * allows Ruby to use FD sets larger than what has been historically allowed on
 * modern platforms.
 *
 * @internal
 *
 * ... but because  this header file is  included only when the  system is with
 * that "historic restrictions", this is nothing more than an alias of fd_set.
 */
typedef fd_set rb_fdset_t;

/** Clears the given ::rb_fdset_t. */
#define rb_fd_zero   FD_ZERO

/** Sets the given fd to the ::rb_fdset_t. */
#define rb_fd_set    FD_SET

/** Unsets the given fd from the ::rb_fdset_t. */
#define rb_fd_clr    FD_CLR

/** Queries if the given fd is in the ::rb_fdset_t. */
#define rb_fd_isset  FD_ISSET

/** Initialises the :given :rb_fdset_t. */
#define rb_fd_init   FD_ZERO

/** Waits for multiple file descriptors at once. */
#define rb_fd_select select

/**@cond INTERNAL_MACRO */
#define rb_fd_copy  rb_fd_copy
#define rb_fd_dup   rb_fd_dup
#define rb_fd_ptr   rb_fd_ptr
#define rb_fd_max   rb_fd_max
/** @endcond */

RBIMPL_ATTR_NONNULL(())
RBIMPL_ATTR_NOALIAS()
/**
 * Destructively overwrites an fdset with another.
 *
 * @param[out]  dst   Target fdset.
 * @param[in]   src   Source fdset.
 * @param[in]   n     Unused parameter.
 * @post        `dst` is a copy of `src`.
 */
static inline void
rb_fd_copy(rb_fdset_t *dst, const fd_set *src, int n)
{
    *dst = *src;
}

RBIMPL_ATTR_NONNULL(())
RBIMPL_ATTR_NOALIAS()
/**
 * Destructively overwrites an fdset with another.
 *
 * @param[out]  dst   Target fdset.
 * @param[in]   src   Source fdset.
 * @post        `dst` is a copy of `src`.
 */
static inline void
rb_fd_dup(rb_fdset_t *dst, const fd_set *src)
{
    *dst = *src;
}

RBIMPL_ATTR_PURE()
/* :TODO: can this function be __attribute__((returns_nonnull)) or not? */
/**
 * Raw pointer to `fd_set`.
 *
 * @param[in]  f  Target fdset.
 * @return     Underlying fd_set.
 *
 * @internal
 *
 * Extension library  must not touch  raw pointers.  It was  a bad idea  to let
 * them use it.
 */
static inline fd_set *
rb_fd_ptr(rb_fdset_t *f)
{
    return f;
}

RBIMPL_ATTR_CONST()
/**
 * It seems this function has no use.  Maybe just remove?
 *
 * @param[in]  f  A set.
 * @return     Number of file descriptors stored.
 */
static inline int
rb_fd_max(const rb_fdset_t *f)
{
    return FD_SETSIZE;
}

/** @cond INTERNAL_MACRO */
/* :FIXME: What are these?  They don't exist for sibling implementations. */
#define rb_fd_init_copy(d, s) (*(d) = *(s))
#define rb_fd_term(f)   ((void)(f))
/** @endcond */

#endif /* RBIMPL_INTERN_SELECT_POSIX_H */
ruby/internal/intern/string.h000064400000206621151732674250012342 0ustar00#ifndef RBIMPL_INTERN_STRING_H                       /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_STRING_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Public APIs related to ::rb_cString.
 */
#include "ruby/internal/config.h"

#ifdef STDC_HEADERS
# include <stddef.h>
#endif

#ifdef HAVE_STRING_H
# include <string.h>
#endif

#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif

#include "ruby/internal/attr/deprecated.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/constant_p.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/internal/variable.h" /* rb_gvar_setter_t */
#include "ruby/st.h"         /* st_index_t */

RBIMPL_SYMBOL_EXPORT_BEGIN()

/* string.c */

/**
 * Allocates an instance of ::rb_cString.
 *
 * @param[in]  ptr             A memory region of `len` bytes length.
 * @param[in]  len             Length  of `ptr`,  in bytes,  not including  the
 *                             terminating NUL character.
 * @exception  rb_eNoMemError  Failed to allocate `len+1` bytes.
 * @exception  rb_eArgError    `len` is negative.
 * @return     An  instance   of  ::rb_cString,  of  `len`   bytes  length,  of
 *             "binary" encoding, whose contents are verbatim copy of `ptr`.
 * @pre        At  least  `len` bytes  of  continuous  memory region  shall  be
 *             accessible via `ptr`.
 */
VALUE rb_str_new(const char *ptr, long len);

/**
 * Identical to rb_str_new(), except it assumes the passed pointer is a pointer
 * to a C string.
 *
 * @param[in]  ptr             A C string.
 * @exception  rb_eNoMemError  Failed to allocate memory.
 * @exception  rb_eArgError    `ptr` is a null pointer.
 * @return     An  instance  of  ::rb_cString,   of  "binary"  encoding,  whose
 *             contents are verbatim copy of `ptr`.
 * @pre        `ptr` must not be a null pointer.
 */
VALUE rb_str_new_cstr(const char *ptr);

/**
 * Identical to rb_str_new_cstr(),  except it takes a Ruby's  string instead of
 * C's.  Implementation wise it creates a string that shares the backend memory
 * region with the receiver.   So the name.  But there is  no way for extension
 * libraries to know if a string is of such variant.
 *
 * @param[in]  str  An object of ::RString.
 * @return     An  allocated   instance  of  ::rb_cString,  which   shares  the
 *             encoding, length, and contents with the passed string.
 * @pre        `str` must not be any arbitrary object except ::RString.
 * @note       Use #StringValue to enforce the precondition.
 */
VALUE rb_str_new_shared(VALUE str);

/**
 * Creates  a frozen  copy of  the string,  if necessary.   This function  does
 * nothing when the passed string is already frozen.  Otherwise, it allocates a
 * copy of it, which is frozen.  The passed string is untouched either ways.
 *
 * @param[in]  str  An object of ::RString.
 * @return     Something frozen.
 * @pre        `str` must not be any arbitrary object except ::RString.
 * @note       Use #StringValue to enforce the precondition.
 */
VALUE rb_str_new_frozen(VALUE str);

/**
 * Identical  to rb_str_new(),  except it  takes  the class  of the  allocating
 * object.
 *
 * @param[in]  obj             A string-ish object.
 * @param[in]  ptr             A memory region of `len` bytes length.
 * @param[in]  len             Length  of `ptr`,  in bytes,  not including  the
 *                             terminating NUL character.
 * @exception  rb_eNoMemError  Failed to allocate `len+1` bytes.
 * @exception  rb_eArgError    `len` is negative.
 * @return     An instance  of the class  of `obj`,  of `len` bytes  length, of
 *             "binary" encoding, whose contents are verbatim copy of `ptr`.
 * @pre        At  least  `len` bytes  of  continuous  memory region  shall  be
 *             accessible via `ptr`.
 *
 * @internal
 *
 * Why it doesn't take an instance of ::rb_cClass?
 */
VALUE rb_str_new_with_class(VALUE obj, const char *ptr, long len);

/**
 * Identical  to  rb_str_new(),  except  it  generates  a  string  of  "default
 * external" encoding.
 *
 * @param[in]  ptr             A memory region of `len` bytes length.
 * @param[in]  len             Length  of `ptr`,  in bytes,  not including  the
 *                             terminating NUL character.
 * @exception  rb_eNoMemError  Failed to allocate `len+1` bytes.
 * @exception  rb_eArgError    `len` is negative.
 * @return     An instance  of ::rb_cString.  In case  encoding conversion from
 *             "default internal"  to "default external" is  fully defined over
 *             the  given  contents, then  the  return  value  is a  string  of
 *             "default external"  encoding, whose  contents are  the converted
 *             ones.  Otherwise the string is a junk.
 * @warning    It doesn't raise on a conversion failure and silently ends up in
 *             a  corrupted  output.  You  can  know  the failure  by  querying
 *             `valid_encoding?` of the result object.
 */
VALUE rb_external_str_new(const char *ptr, long len);

RBIMPL_ATTR_NONNULL(())
/**
 * Identical to rb_external_str_new(), except it  assumes the passed pointer is
 * a pointer  to a C  string.  It can  also be seen  as a routine  identical to
 * rb_str_new_cstr(),  except  it  generates  a string  of  "default  external"
 * encoding.
 *
 * @param[in]  ptr             A C string.
 * @exception  rb_eNoMemError  Failed to allocate memory.
 * @return     An instance  of ::rb_cString.  In case  encoding conversion from
 *             "default internal"  to "default external" is  fully defined over
 *             the  given  contents, then  the  return  value  is a  string  of
 *             "default external"  encoding, whose  contents are  the converted
 *             ones.  Otherwise the string is a junk.
 * @warning    It doesn't raise on a conversion failure and silently ends up in
 *             a  corrupted  output.  You  can  know  the failure  by  querying
 *             `valid_encoding?` of the result object.
 * @pre        `ptr` must not be a null pointer.
 */
VALUE rb_external_str_new_cstr(const char *ptr);

/**
 * Identical  to  rb_str_new(),  except  it  generates  a  string  of  "locale"
 * encoding.    It   can   also   be   seen   as   a   routine   identical   to
 * rb_external_str_new(),  except it  generates a  string of  "locale" encoding
 * instead of "default external" encoding.
 *
 * @param[in]  ptr             A memory region of `len` bytes length.
 * @param[in]  len             Length  of `ptr`,  in bytes,  not including  the
 *                             terminating NUL character.
 * @exception  rb_eNoMemError  Failed to allocate `len+1` bytes.
 * @exception  rb_eArgError    `len` is negative.
 * @return     An instance  of ::rb_cString.  In case  encoding conversion from
 *             "default internal" to  "locale" is fully defined  over the given
 *             contents,  then  the  return  value  is  a  string  of  "locale"
 *             encoding, whose contents are  the converted ones.  Otherwise the
 *             string is a junk.
 * @warning    It doesn't raise on a conversion failure and silently ends up in
 *             a  corrupted  output.  You  can  know  the failure  by  querying
 *             `valid_encoding?` of the result object.
 */
VALUE rb_locale_str_new(const char *ptr, long len);

RBIMPL_ATTR_NONNULL(())
/**
 * Identical to rb_locale_str_new(), except it  assumes the passed pointer is a
 * pointer  to a  C string.   It can  also be  seen as  a routine  identical to
 * rb_external_str_new_cstr(),  except  it  generates   a  string  of  "locale"
 * encoding instead of "default external".
 *
 * @param[in]  ptr             A C string.
 * @exception  rb_eNoMemError  Failed to allocate memory.
 * @return     An instance  of ::rb_cString.  In case  encoding conversion from
 *             "default internal" to  "locale" is fully defined  over the given
 *             contents,  then  the  return  value  is  a  string  of  "locale"
 *             encoding, whose contents are  the converted ones.  Otherwise the
 *             string is a junk.
 * @warning    It doesn't raise on a conversion failure and silently ends up in
 *             a  corrupted  output.  You  can  know  the failure  by  querying
 *             `valid_encoding?` of the result object.
 * @pre        `ptr` must not be a null pointer.
 */
VALUE rb_locale_str_new_cstr(const char *ptr);

/**
 * Identical  to rb_str_new(),  except it  generates a  string of  "filesystem"
 * encoding.    It   can   also   be   seen   as   a   routine   identical   to
 * rb_external_str_new(), except it generates a string of "filesystem" encoding
 * instead of "default external" encoding.
 *
 * @param[in]  ptr             A memory region of `len` bytes length.
 * @param[in]  len             Length  of `ptr`,  in bytes,  not including  the
 *                             terminating NUL character.
 * @exception  rb_eNoMemError  Failed to allocate `len+1` bytes.
 * @exception  rb_eArgError    `len` is negative.
 * @return     An instance  of ::rb_cString.  In case  encoding conversion from
 *             "default  internal" to  "filesystem" is  fully defined  over the
 *             given  contents,   then  the  return   value  is  a   string  of
 *             "filesystem" encoding,  whose contents  are the  converted ones.
 *             Otherwise the string is a junk.
 * @warning    It doesn't raise on a conversion failure and silently ends up in
 *             a  corrupted  output.  You  can  know  the failure  by  querying
 *             `valid_encoding?` of the result object.
 */
VALUE rb_filesystem_str_new(const char *ptr, long len);

RBIMPL_ATTR_NONNULL(())
/**
 * Identical to  rb_filesystem_str_new(), except it assumes  the passed pointer
 * is a pointer to  a C string.  It can also be seen  as a routine identical to
 * rb_external_str_new_cstr(),  except it  generates a  string of  "filesystem"
 * encoding instead of "default external".
 *
 * @param[in]  ptr             A C string.
 * @exception  rb_eNoMemError  Failed to allocate memory.
 * @return     An instance  of ::rb_cString.  In case  encoding conversion from
 *             "default  internal" to  "filesystem" is  fully defined  over the
 *             given  contents,   then  the  return   value  is  a   string  of
 *             "filesystem" encoding,  whose contents  are the  converted ones.
 *             Otherwise the string is a junk.
 * @warning    It doesn't raise on a conversion failure and silently ends up in
 *             a  corrupted  output.  You  can  know  the failure  by  querying
 *             `valid_encoding?` of the result object.
 * @pre        `ptr` must not be a null pointer.
 */
VALUE rb_filesystem_str_new_cstr(const char *ptr);

/**
 * Allocates  a "string  buffer".   A  string buffer  here  is  an instance  of
 * ::rb_cString, whose  capacity is bigger than  the length of it.   If you can
 * say  that a  string grows  to  a specific  amount  of bytes,  this could  be
 * effective than resizing a string over and over again and again.
 *
 * @param[in]  capa  Designed capacity of the generating string.
 * @return     An empty string, of "binary" encoding, whose capacity is `capa`.
 */
VALUE rb_str_buf_new(long capa);

RBIMPL_ATTR_NONNULL(())
/**
 * This is a rb_str_buf_new() + rb_str_buf_cat() combo.
 *
 * @param[in]  ptr             A C string.
 * @exception  rb_eNoMemError  Failed to allocate memory.
 * @return     An  instance  of  ::rb_cString,   of  "binary"  encoding,  whose
 *             contents are verbatim copy of `ptr`.
 * @pre        `ptr` must not be a null pointer.
 *
 * @internal
 *
 * This must be identical to rb_str_new_cstr(), except done in inefficient way?
 * @shyouhei doesn't understand why this is not a simple alias.
 */
VALUE rb_str_buf_new_cstr(const char *ptr);

/**
 * Allocates a  "temporary" string.  This is  a hidden empty string.   Handy on
 * occasions.
 *
 * @param[in]  len  Designed length of the string.
 * @return     A hidden, empty string.
 * @see        rb_obj_hide()
 */
VALUE rb_str_tmp_new(long len);

/**
 * Identical  to rb_str_new(),  except  it  generates a  string  of "US  ASCII"
 * encoding.  This  is different from  rb_external_str_new(), not only  for the
 * output encoding, but also it doesn't convert the contents.
 *
 * @param[in]  ptr             A memory region of `len` bytes length.
 * @param[in]  len             Length  of `ptr`,  in bytes,  not including  the
 *                             terminating NUL character.
 * @exception  rb_eNoMemError  Failed to allocate `len+1` bytes.
 * @exception  rb_eArgError    `len` is negative.
 * @return     An  instance   of  ::rb_cString,  of  `len`   bytes  length,  of
 *             "US ASCII" encoding, whose contents are verbatim copy of `ptr`.
 */
VALUE rb_usascii_str_new(const char *ptr, long len);

/**
 * Identical to rb_str_new_cstr(),  except it generates a string  of "US ASCII"
 * encoding.   It   can   also   be    seen   as   a   routine   Identical   to
 * rb_usascii_str_new(), except it assumes the passed pointer is a pointer to a
 * C string.
 *
 * @param[in]  ptr             A C string.
 * @exception  rb_eNoMemError  Failed to allocate memory.
 * @exception  rb_eArgError    `ptr` is a null pointer.
 * @return     An  instance  of ::rb_cString,  of  "US  ASCII" encoding,  whose
 *             contents are verbatim copy of `ptr`.
 * @pre        `ptr` must not be a null pointer.
 */
VALUE rb_usascii_str_new_cstr(const char *ptr);

/**
 * Identical to rb_str_new(), except it generates a string of "UTF-8" encoding.
 *
 * @param[in]  ptr             A memory region of `len` bytes length.
 * @param[in]  len             Length  of `ptr`,  in bytes,  not including  the
 *                             terminating NUL character.
 * @exception  rb_eNoMemError  Failed to allocate `len+1` bytes.
 * @exception  rb_eArgError    `len` is negative.
 * @return     An  instance   of  ::rb_cString,  of  `len`   bytes  length,  of
 *             "UTF-8" encoding, whose contents are verbatim copy of `ptr`.
 */
VALUE rb_utf8_str_new(const char *ptr, long len);

/**
 * Identical  to rb_str_new_cstr(),  except it  generates a  string of  "UTF-8"
 * encoding.    It   can   also   be   seen   as   a   routine   Identical   to
 * rb_usascii_str_new(), except it assumes the passed pointer is a pointer to a
 * C string.
 *
 * @param[in]  ptr             A C string.
 * @exception  rb_eNoMemError  Failed to allocate memory.
 * @exception  rb_eArgError    `ptr` is a null pointer.
 * @return     An instance of ::rb_cString, of "UTF-8" encoding, whose contents
 *             are verbatim copy of `ptr`.
 * @pre        `ptr` must not be a null pointer.
 */
VALUE rb_utf8_str_new_cstr(const char *ptr);

/**
 * @name Special strings that are backended by C string literals.
 *
 *  *_str_new_static functions are intended for C string literals.
 *  They require memory in the range [ptr, ptr+len] to always be readable.
 *  Note that this range covers a total of len + 1 bytes.
 *
 * @{
 */

/**
 * Identical to rb_str_new(), except it takes a C string literal.
 *
 * @param[in]  ptr           A C string literal.
 * @param[in]  len           `strlen(ptr)`.
 * @exception  rb_eArgError  `len` out of range of `size_t`.
 * @pre        `ptr` must be a C string constant.
 * @return     An instance of ::rb_cString, of "binary" encoding, whose backend
 *             storage is the passed C string literal.
 * @warning    It is  a very  bad idea to  write to a  C string  literal (often
 *             immediate  SEGV shall  occur).  Consider  return values  of this
 *             function be read-only.
 *
 * @internal
 *
 * Surprisingly it can take NULL, and generates an empty string.
 */
VALUE rb_str_new_static(const char *ptr, long len);

/**
 * Identical to rb_str_new_static(), except it generates a string of "US ASCII"
 * encoding instead of "binary".  It can also be seen as a routine identical to
 * rb_usascii_str_new(), except it takes a C string literal.
 *
 * @param[in]  ptr           A C string literal.
 * @param[in]  len           `strlen(ptr)`.
 * @exception  rb_eArgError  `len` out of range of `size_t`.
 * @pre        `ptr` must be a C string constant.
 * @return     An  instance  of ::rb_cString,  of  "US  ASCII" encoding,  whose
 *             backend storage is the passed C string literal.
 * @warning    It is  a very  bad idea to  write to a  C string  literal (often
 *             immediate  SEGV shall  occur).  Consider  return values  of this
 *             function be read-only.
 */
VALUE rb_usascii_str_new_static(const char *ptr, long len);

/**
 * Identical to  rb_str_new_static(), except it  generates a string  of "UTF-8"
 * encoding instead of "binary".  It can also be seen as a routine identical to
 * rb_utf8_str_new(), except it takes a C string literal.
 *
 * @param[in]  ptr           A C string literal.
 * @param[in]  len           `strlen(ptr)`.
 * @exception  rb_eArgError  `len` out of range of `size_t`.
 * @pre        `ptr` must be a C string constant.
 * @return     An instance of ::rb_cString,  of "UTF-8" encoding, whose backend
 *             storage is the passed C string literal.
 * @warning    It is  a very  bad idea to  write to a  C string  literal (often
 *             immediate  SEGV shall  occur).  Consider  return values  of this
 *             function be read-only.
 */
VALUE rb_utf8_str_new_static(const char *ptr, long len);

/** @} */

/**
 * Identical to rb_interned_str(),  except it takes a Ruby's  string instead of
 * C's.  It can also be seen  as a routine identical to rb_str_new_shared(),
 * except it returns an infamous "f"string.
 *
 * @param[in]  str  An object of ::RString.
 * @return     An instance  of ::rb_cString, either cached  or allocated, which
 *             has the identical encoding, length, and contents with the passed
 *             string.
 * @pre        `str` must not be any arbitrary object except ::RString.
 * @note       Use #StringValue to enforce the precondition.
 *
 * @internal
 *
 * It  actually  finds  or  creates  a fstring  of  the  needed  property,  and
 * destructively modifies  the receiver behind-the-scene  so that it  becomes a
 * shared string whose parent is the returning fstring.
 */
VALUE rb_str_to_interned_str(VALUE str);

/**
 * Identical to rb_str_new(), except it returns an infamous "f"string.  What is
 * a  fstring?  Well  it is  a special  subkind of  strings that  is immutable,
 * deduped globally, and managed by our GC.   It is much like a Symbol (in fact
 * Symbols  are dynamic  these days  and are  backended using  fstrings).  This
 * concept has been  silently introduced at some point in  2.x era.  Since then
 * it  gained  wider acceptance  in  the  core.   Starting from  3.x  extension
 * libraries can also generate ones.
 *
 * @param[in]  ptr           A memory region of `len` bytes length.
 * @param[in]  len           Length  of  `ptr`,  in bytes,  not  including  the
 *                           terminating NUL character.
 * @exception  rb_eArgError  `len` is negative.
 * @return     A  found or  created instance  of ::rb_cString,  of `len`  bytes
 *             length, of  "binary" encoding,  whose contents are  identical to
 *             that of `ptr`.
 * @pre        At  least  `len` bytes  of  continuous  memory region  shall  be
 *             accessible via `ptr`.
 */
VALUE rb_interned_str(const char *ptr, long len);

RBIMPL_ATTR_NONNULL(())
/**
 * Identical to  rb_interned_str(), except it  assumes the passed pointer  is a
 * pointer to a C's  string.  It can also be seen as a  routine identical to
 * rb_str_to_interned_str(), except  it takes a  C's string instead  of Ruby's.
 * Or it can  also be seen as a routine  identical to rb_str_new_cstr(), except
 * it returns an infamous "f"string.
 *
 * @param[in]  ptr             A C string.
 * @exception  rb_eNoMemError  Failed to allocate memory.
 * @return     An  instance  of  ::rb_cString,   of  "binary"  encoding,  whose
 *             contents are verbatim copy of `ptr`.
 * @pre        `ptr` must not be a null pointer.
 */
VALUE rb_interned_str_cstr(const char *ptr);

/**
 * Destroys the given string for no reason.
 *
 * @warning  DO NOT USE IT.
 * @warning  Leave this task to our GC.
 * @warning  It was a bad idea at the first place to let you know about it.
 *
 * @param[out]  str  The string to be executed.
 * @post        The given string no longer exists.
 * @note        Maybe `String#clear` could be what you want.
 *
 * @internal
 *
 * Should have moved this to `internal/string.h`.
 */
void rb_str_free(VALUE str);

/**
 * Replaces the contents of the former with the latter.
 *
 * @param[out]  dst  Destination object.
 * @param[in]   src  Source object.
 * @pre         Both  objects   must  not  be  any   arbitrary  objects  except
 *              ::RString.
 * @post        `dst`'s  former  components  are  abandoned.  It  now  has  the
 *              identical encoding, length, and contents to `src`.
 * @see         rb_str_replace()
 *
 * @internal
 *
 * @shyouhei  doesn't understand  why this  is useful  to extension  libraries.
 * Just use rb_str_replace().  What's wrong with that?
 */
void rb_str_shared_replace(VALUE dst, VALUE src);

/**
 * Identical to  rb_str_cat_cstr(), except  it takes  Ruby's string  instead of
 * C's.  It can also be seen as a routine identical to rb_str_shared_replace(),
 * except it appends instead of replaces.
 *
 * @param[out]  dst                 Destination object.
 * @param[in]   src                 Source object.
 * @exception   rb_eEncCompatError  Can't mix the encodings.
 * @exception   rb_eArgError        Result string too big.
 * @return      The passed `dst`.
 * @pre         Both  objects   must  not  be  any   arbitrary  objects  except
 *              ::RString.
 * @post        `dst`  has  the  contents  of  `src`  appended,  with  encoding
 *              converted into `dst`'s one, into the end of `dst`.
 */
VALUE rb_str_buf_append(VALUE dst, VALUE src);

/** @alias{rb_str_cat} */
VALUE rb_str_buf_cat(VALUE, const char*, long);

/** @alias{rb_str_cat_cstr} */
VALUE rb_str_buf_cat2(VALUE, const char*);

RBIMPL_ATTR_NONNULL(())
/**
 * Identical to  rb_str_cat_cstr(), except  it additionally assumes  the source
 * string be a NUL terminated ASCII string.
 *
 * @param[out]  dst           Destination object.
 * @param[in]   src           Source string.
 * @exception   rb_eArgError  Result string too big.
 * @return      The passed `dst`.
 * @pre         `dst` must not be any arbitrary object except ::RString.
 * @pre         `src` must be a NUL terminated ASCII string.
 * @post        `dst`  has  the  contents  of  `src`  appended,  with  encoding
 *              converted into `dst`'s one, into the end of `dst`.
 */
VALUE rb_str_buf_cat_ascii(VALUE dst, const char *src);

/**
 * Try converting an  object to its stringised representation  using its `to_s`
 * method, if  any.  If  there is  no such thing,  it resorts  to rb_any_to_s()
 * output.
 *
 * @param[in]  obj  Arbitrary ruby object to stringise.
 * @return     An instance of ::rb_cString.
 */
VALUE rb_obj_as_string(VALUE obj);

/**
 * Try converting an object to its stringised representation using its `to_str`
 * method, if any.  If there is no such thing, returns ::RUBY_Qnil.
 *
 * @param[in]  obj            Arbitrary ruby object to stringise.
 * @exception  rb_eTypeError  `obj.to_str` returned something non-String.
 * @retval     RUBY_Qnil      No conversion from obj to String defined.
 * @return     otherwise      Stringised representation of `obj`.
 * @see        rb_io_check_io
 * @see        rb_check_array_type
 * @see        rb_check_hash_type
 */
VALUE rb_check_string_type(VALUE obj);

/**
 * Asserts that  the given  string's encoding is  (Ruby's definition  of) ASCII
 * compatible.
 *
 * @param[in]  obj                 An instance of ::rb_cString.
 * @exception  rb_eEncCompatError  `obj` is ASCII incompatible.
 *
 * @internal
 *
 * @shyouhei doesn't know if this is an  Easter egg or an official feature, but
 * this function  can in fact take  non-strings such as Symbols,  Regexps, IOs,
 * etc.  However if something unsupported is  passed, it causes SEGV.  It seems
 * the feature is kind of untested.
 */
void rb_must_asciicompat(VALUE obj);

/**
 * Duplicates a string.
 *
 * @param[in]  str  String in question to duplicate.
 * @return     A duplicated new instance.
 * @pre        `str` must be of ::RString.
 */
VALUE rb_str_dup(VALUE str);

/**
 * I guess there  is no use case  of this function in  extension libraries, but
 * this is  a routine identical  to rb_str_dup(),  except it always  creates an
 * instance of ::rb_cString regardless of the given object's class.  This makes
 * the most sense when the passed string is formerly hidden by rb_obj_hide().
 *
 * @param[in]  str  A string, possibly hidden.
 * @return     A duplicated new instance of ::rb_cString.
 */
VALUE rb_str_resurrect(VALUE str);

/**
 * Obtains a "temporary  lock" of the string.  This  advisory locking mechanism
 * prevents other  cooperating threads from  tampering the receiver.   The same
 * thing could be done via freeze mechanism,  but this one can also be unlocked
 * using rb_str_unlocktmp().
 *
 * @param[out]  str               String to lock.
 * @exception   rb_eRuntimeError  `str` already locked.
 * @return      The given string.
 * @post        The string is locked.
 */
VALUE rb_str_locktmp(VALUE str);

/**
 * Releases a lock formerly obtained by rb_str_locktmp().
 *
 * @param[out]  str               String to unlock.
 * @exception   rb_eRuntimeError  `str` already unlocked.
 * @return      The given string.
 * @post        The string is locked.
 */
VALUE rb_str_unlocktmp(VALUE str);

/** @alias{rb_str_new_frozen} */
VALUE rb_str_dup_frozen(VALUE);

/** @alias{rb_str_new_frozen} */
#define rb_str_dup_frozen rb_str_new_frozen

/**
 * Generates a new string, concatenating the former to the latter.  It can also
 * be seen as a routine identical  to rb_str_append(), except it doesn't tamper
 * the passed strings to create a new one instead.
 *
 * @param[in]  lhs                 Source string #1.
 * @param[in]  rhs                 Source string #2.
 * @exception  rb_eEncCompatError  Can't mix the encodings.
 * @exception  rb_eArgError        Result string too big.
 * @return     A new string containing `rhs` concatenated to `lhs`.
 * @pre        Both objects must not be any arbitrary objects except ::RString.
 * @note       This  operation  doesn't commute.   Don't  get  confused by  the
 *             "plus"  terminology.   For  historical reasons  there  are  some
 *             noncommutative `+`s in Ruby.  This is one of such things.  There
 *             has been a long discussion around `+`s in programming languages.
 */
VALUE rb_str_plus(VALUE lhs, VALUE rhs);

/**
 * Repetition of a string.
 *
 * @param[in]  str           String to repeat.
 * @param[in]  num           Count, something numeric.
 * @exception  rb_eArgError  `num` is negative.
 * @return     A new string repeating `num` times of `str`.
 */
VALUE rb_str_times(VALUE str, VALUE num);

/**
 * Byte  offset to  character offset  conversion.   This makes  sense when  the
 * receiver is in  a multibyte encoding.  The string's i-th  character does not
 * always sit at its  i-th byte.  This function scans the  contents to find the
 * character index that matches the byte  index.  Generally speaking this is an
 * `O(n)` operation.  Could be slow.
 *
 * @param[in]  str  The string to scan.
 * @param[in]  pos  Offset, in bytes.
 * @return     Offset, in characters.
 */
long rb_str_sublen(VALUE str, long pos);

/**
 * This is the implementation of two-argumented `String#slice`.
 *
 * - Returns the substring of the given `len` found in `str` at offset `beg`:
 *
 *   ```ruby
 *   'foo'[0, 2] # => "fo"
 *   'foo'[0, 0] # => ""
 *   ```
 *
 * - Counts backward from the end of `str` if `beg` is negative:
 *
 *   ```ruby
 *   'foo'[-2, 2] # => "oo"
 *   ```
 *
 * - Special case: returns a  new empty string if `beg` is  equal to the length
 *   of `str`:
 *
 *   ```ruby
 *   'foo'[3, 2] # => ""
 *   ```
 *
 * - Returns a null pointer if `beg` is out of range:
 *
 *   ```ruby
 *   'foo'[4, 2] # => nil
 *   'foo'[-4, 2] # => nil
 *   ```
 *
 * - Returns the trailing substring of `str` if `len` is large:
 *
 *   ```ruby
 *   'foo'[1, 50] # => "oo"
 *   ```
 *
 * - Returns a null pointer if `len` is negative:
 *
 *   ```ruby
 *   'foo'[0, -1] # => nil
 *   ```
 *
 * @param[in]  str        The string to slice.
 * @param[in]  beg        Requested offset of the substring.
 * @param[in]  len        Requested length of the substring.
 * @retval     RUBY_Qnil  Parameters out of range.
 * @retval     otherwise  A  new   string  whose  contents  is   the  specified
 *                        substring of `str`.
 * @pre        `str` must not be any arbitrary objects except ::RString.
 */
VALUE rb_str_substr(VALUE str, long beg, long len);

/**
 * Identical to  rb_str_substr(), except  the numbers  are interpreted  as byte
 * offsets instead of character offsets.
 *
 * @param[in]  str  The string to slice.
 * @param[in]  beg  Requested offset of the substring.
 * @param[in]  len  Requested length of the substring.
 * @return     A new string whose contents is the specified substring of `str`.
 * @pre        `str` must not be any arbitrary objects except ::RString.
 * @pre        `beg` and `len` must not point to OOB contents.
 */
VALUE rb_str_subseq(VALUE str, long beg, long len);

/**
 * Identical  to rb_str_substr(),  except it  returns a  C's string  instead of
 * Ruby's.
 *
 * @param[in]      str        The string to slice.
 * @param[in]      beg        Requested offset of the substring.
 * @param[in,out]  len        Requested length of the substring.
 * @retval         NULL       Parameters out of range.
 * @retval         otherwise  A pointer inside of `str`'s backend storage where
 *                            the specified substring exist.
 * @pre            `str` must not be any arbitrary objects except ::RString.
 * @post           `len` is updated to have the length of the return value.
 */
char *rb_str_subpos(VALUE str, long beg, long *len);

/**
 * Declares that the string is about to be modified.  This for instance let the
 * string have a dedicated backend storage.
 *
 * @param[out]  str               String about to be modified.
 * @exception   rb_eRuntimeError  `str` is `locktmp`-ed.
 * @exception   rb_eFrozenError   `str` is frozen.
 * @pre         `str` must not be any arbitrary objects except ::RString.
 * @post        Upon  successful return  the passed  string is  eligible to  be
 *              modified.
 */
void rb_str_modify(VALUE str);

/**
 * Identical to rb_str_modify(), except it additionally expands the capacity of
 * the receiver.
 *
 * @param[out]  str               Target string to modify.
 * @param[in]   capa              Additional capacity to add.
 * @exception   rb_eArgError      `capa` is negative.
 * @exception   rb_eRuntimeError  `str` is `locktmp`-ed.
 * @exception   rb_eFrozenError   `str` is frozen.
 * @pre         `str` must not be any arbitrary objects except ::RString.
 * @post        Upon successful  return the passed  string is modified  so that
 *              its capacity is increased for `capa` bytes.
 */
void rb_str_modify_expand(VALUE str, long capa);

/**
 * This is the implementation of `String#freeze`.
 *
 * @param[out]  str  Target string to freeze.
 * @return      The passed string.
 * @post        Upon successful return the passed string is frozen.
 */
VALUE rb_str_freeze(VALUE str);

/**
 * Overwrites the  length of the  string.  Typically this  is used to  shrink a
 * string that was formerly expanded.
 *
 * ```CXX
 * extern int fd;
 * auto str = rb_eval_string("'...'");
 * rb_str_modify_expand(str, BUFSIZ);
 * if (auto len = recv(fd, RSTRING_PTR(str), BUFSIZ, 0); len >= 0) {
 *     rb_str_set_len(str, len);
 * }
 * else {
 *     rb_sys_fail("recv(2)");
 * }
 * ```
 *
 * @param[out]  str               String to shrink.
 * @param[in]   len               New length of the string.
 * @exception   rb_eRuntimeError  `str` is `locktmp`-ed.
 * @exception   rb_eFrozenError   `str` is frozen.
 * @pre         `str` must not be any arbitrary objects except ::RString.
 * @post        Upon successful return `str`'s length is set to `len`.
 */
void rb_str_set_len(VALUE str, long len);

/**
 * Overwrites the length of the  string.  In contrast to rb_str_set_len(), this
 * function can also expand a string.
 *
 * @param[out]  str               String to shrink.
 * @param[in]   len               New length of the string.
 * @exception   rb_eArgError      `len` is negative.
 * @exception   rb_eRuntimeError  `str` is `locktmp`-ed.
 * @exception   rb_eFrozenError   `str` is frozen.
 * @return      The passed `str`.
 * @pre         `str` must not be any arbitrary objects except ::RString.
 * @post        Upon successful return `str` is  either expanded or shrunken to
 *              have its length be `len`.
 */
VALUE rb_str_resize(VALUE str, long len);

/**
 * Destructively appends the passed contents to the string.
 *
 * @param[out]  dst           Destination object.
 * @param[in]   src           Contents to append.
 * @param[in]   srclen        Length of `src`.
 * @exception   rb_eArgError  `srclen` is negative.
 * @return      The passed `dst`.
 * @pre         `dst` must not be any arbitrary objects except ::RString.
 * @post        `dst` has the contents of `ptr` appended.
 */
VALUE rb_str_cat(VALUE dst, const char *src, long srclen);

/**
 * Identical to rb_str_cat(), except it assumes the passed pointer is a pointer
 * to a C string.
 *
 * @param[out]  dst           Destination object.
 * @param[in]   src           Contents to append.
 * @exception   rb_eArgError  Result string too big.
 * @exception   rb_eArgError  `src` is a null pointer.
 * @return      The passed `dst`.
 * @pre         `dst` must not be any arbitrary objects except ::RString.
 * @pre         `src` must not be a null pointer.
 * @post        `dst` has the contents of `src` appended.
 */
VALUE rb_str_cat_cstr(VALUE dst, const char *src);

/** @alias{rb_str_cat_cstr} */
VALUE rb_str_cat2(VALUE, const char*);

/**
 * Identical to  rb_str_buf_append(), except  it converts  the right  hand side
 * before concatenating.
 *
 * @param[out]  dst                 Destination object.
 * @param[in]   src                 Source object.
 * @exception   rb_eEncCompatError  Can't mix the encodings.
 * @exception   rb_eArgError        Result string too big.
 * @return      The passed `dst`.
 * @pre         `dst` must not be any arbitrary objects except ::RString.
 * @post        `dst`  has  the  contents  of  `src`  appended,  with  encoding
 *              converted into `dst`'s one, into the end of `dst`.
 */
VALUE rb_str_append(VALUE dst, VALUE src);

/**
 * Identical  to  rb_str_append(), except  it  also  accepts  an integer  as  a
 * codepoint.  This resembles `String#<<`.
 *
 * @param[out]  dst                 Destination object.
 * @param[in]   src                 Source object, String or Numeric.
 * @exception   rb_eRangeError      Source numeric is out of range.
 * @exception   rb_eEncCompatError  Source string too long.
 * @exception   rb_eArgError        Result string too big.
 * @return      The passed `dst`.
 * @pre         `dst` must not be any arbitrary objects except ::RString.
 * @post        `dst`  has  the  contents  of  `src`  appended,  with  encoding
 *              converted into `dst`'s one, into the end of `dst`.
 */
VALUE rb_str_concat(VALUE dst, VALUE src);

/* random.c */

/**
 * This is a universal hash function.
 *
 * @warning    This function changes its value per process.
 * @param[in]  ptr  Target message.
 * @param[in]  len  Length of `ptr` in bytes.
 * @return     A pseudorandom number suitable for Hash's hash value.
 * @see        Aumasson,  JP., Bernstein,  D.J., "SipHash:  A Fast  Short-Input
 *             PRF",  In  proceedings  of   13th  International  Conference  on
 *             Cryptology in  India (INDOCRYPT 2012), LNCS  7668, pp.  489-508,
 *             2012.  http://doi.org/10.1007/978-3-642-34931-7_28
*/
st_index_t rb_memhash(const void *ptr, long len);

/**
 * Starts a series of hashing.  Suppose you have a struct:
 *
 * ```CXX
 * struct foo_tag {
 *     unsigned char bar;
 *     uint32_t baz;
 * };
 * ```
 *
 * It is not a  wise idea to call rb_memhash() over it,  because there could be
 * padding bits.  Instead you should explicitly iterate over each fields:
 *
 * ```CXX
 * foo_tag foo = { 0, 0, };
 * st_index_t hash = 0;
 *
 * hash = rb_hash_start(0);
 * hash = rb_hash_uint(hash, foo.bar);
 * hash = rb_hash_uint32(hash, foo.baz);
 * hash = rb_hash_end(hash);
 * ```
 *
 * @param[in]  i  Initial value.
 * @return     A hash value.
 */
st_index_t rb_hash_start(st_index_t i);

/** @alias{st_hash_uint32} */
#define rb_hash_uint32(h, i) st_hash_uint32((h), (i))

/** @alias{st_hash_uint} */
#define rb_hash_uint(h, i) st_hash_uint((h), (i))

/** @alias{st_hash_end} */
#define rb_hash_end(h) st_hash_end(h)

/* string.c */

/**
 * Calculates a hash value of a string.   This is one of the two functions that
 * constructs struct ::st_hash_type.
 *
 * @param[in]  str  An object of ::RString.
 * @return     A hash value.
 * @pre        `str` must not be any arbitrary object except ::RString.
 *
 * @internal
 *
 * Although safe to call, there must be no particular use case of this function
 * for extension libraries.  Only ruby internals must know about it.
 *
 * This is not a simple alias  of rb_memhash(), because it considers the passed
 * string's encoding as well as its contents.
 */
st_index_t rb_str_hash(VALUE str);

/**
 * Compares two  strings.  This  is one  of the  two functions  that constructs
 * struct ::st_hash_type.
 *
 * @param[in]  str1  A string.
 * @param[in]  str2  Another string.
 * @retval     1     They have identical contents, length, and encodings.
 * @retval     0     Otherwise.
 * @pre        Both   objects   must  not  be  any   arbitrary  objects  except
 *             ::RString.
 *
 * @internal
 *
 * In contrast to  rb_str_hash(), this could be handy for  comparison that only
 * concerns equality.  rb_str_cmp() returns 1, 0, -1.
 */
int rb_str_hash_cmp(VALUE str1, VALUE str2);

/**
 * Checks  if  two   strings  are  comparable  each  other   or  not.   Because
 * rb_str_cmp()  must  return  "lesser  than" or  "greater  than"  information,
 * comparing two strings needs a stricter restriction.  Both sides must be in a
 * same set of strings which have total order.  This is to check that property.
 * Intuitive it  sounds?  But they  can have different encodings.   A character
 * and another might or might not appear in the same order in their codepoints.
 * It is complicated than you think.
 *
 * @param[in]  str1  A string.
 * @param[in]  str2  Another string.
 * @retval     1     They agree on a total order.
 * @retval     0     Otherwise.
 * @pre        Both   objects   must  not  be  any   arbitrary  objects  except
 *             ::RString.
 */
int rb_str_comparable(VALUE str1, VALUE str2);

/**
 * Compares two strings, as in `strcmp(3)`.  This does not consider the current
 * locale, but considers the encodings of both sides instead.
 *
 * @param[in]  lhs  A string.
 * @param[in]  rhs  Another string.
 * @retval     -1   `lhs` is "bigger than" `rhs`.
 * @retval      1   `rhs` is "bigger than" `lhs`.
 * @retval      0    Otherwise, e.g. not comparable.
 * @pre        Both   objects   must  not  be  any   arbitrary  objects  except
 *             ::RString.
 */
int rb_str_cmp(VALUE lhs, VALUE rhs);

/**
 * Equality of two strings.
 *
 * If `str2` is not a String, it  resorts to `str2 == str1`.  Otherwise if they
 * are not comparable, returns ::RUBY_Qfalse.   Otherwise if they have the same
 * contents  and   the  length,   returns  ::RUBY_Qtrue.    Otherwise,  returns
 * ::RUBY_Qfalse.
 *
 * @param[in]  str1         A string.
 * @param[in]  str2         Another string.
 * @retval     RUBY_Qtrue   They are equal.
 * @retval     RUBY_Qfalse  They are either different, or not comparable.
 */
VALUE rb_str_equal(VALUE str1, VALUE str2);

/**
 * Shrinks the given string for the given number of bytes.
 *
 * @param[out]  str               String to squash.
 * @param[in]   len               Number of bytes to reduce.
 * @exception   rb_eRuntimeError  `str` is `locktmp`-ed.
 * @exception   rb_eFrozenError   `str` is frozen.
 * @return      The passed `str`.
 * @pre         `str` must not be any arbitrary objects except ::RString.
 * @post        `str` is shrunken.
 * @warning     Can break a multibyte character in middle.
 *
 * @internal
 *
 * What if `len` is negative?
 */
VALUE rb_str_drop_bytes(VALUE str, long len);

/**
 * Replaces some  (or all) of  the contents of the  given string.  This  is the
 * implementation of three-argumented `String#[]=`.
 *
 * @param[out]  dst               Target string to update.
 * @param[in]   beg               Offset of the affected portion.
 * @param[in]   len               Length of the affected portion.
 * @param[in]   src               Object to be assigned.
 * @exception   rb_eTypeError     `src` has no implicit conversion to String.
 * @exception   rb_eIndexError    `len` is negative, or `beg` is OOB.
 * @exception   rb_eRuntimeError  `dst` is `locktmp`-ed.
 * @exception   rb_eFrozenError   `dst` is frozen.
 * @note        Unlike rb_str_substr(), this function raises.
 * @post        A  portion of  `dst`  from  `beg` to  `len`  is the  stringised
 *              representation of `src`.  If that replacement string is not the
 *              same  length as  the portion  it  is replacing,  `dst` will  be
 *              resized accordingly.
 */
void rb_str_update(VALUE dst, long beg, long len, VALUE src);

/**
 * Replaces the contents  of the former object with the  stringised contents of
 * the latter.
 *
 * @param[out]  dst               Destination object.
 * @param[in]   src               Source object.
 * @exception   rb_eTypeError     `src` has no implicit conversion to String.
 * @exception   rb_eRuntimeError  `dst` is `locktmp`-ed.
 * @exception   rb_eFrozenError   `dst` is frozen.
 * @return      The passed `dst`.
 * @pre        `dst` must not be any arbitrary object except ::RString.
 * @post        `dst`'s  former  components  are  abandoned.  It  now  has  the
 *              identical encoding, length, and contents to `src`.
 */
VALUE rb_str_replace(VALUE dst, VALUE src);

/**
 * Generates a "readable" version of the receiver.
 *
 * @warning    The output is _insecure_.  Never feed one to `eval`.
 * @warning    The output is not always in the same encoding as the given one.
 * @warning    A  character might  or might  not be  escaped, depending  on the
 *             result encoding.
 * @param[in]  str  String to inspect.
 * @return     Its inspection, either  in default internal encoding  if any, or
 *             in default external encoding otherwise.
 * @see        rb_str_dump()
 *
 * @internal
 *
 * This is a  (silent) fix of an actual vulnerability  feeding `inspect` output
 * strings to `eval`:
 * https://github.com/hiki/hiki/commit/8771a6e25198e264a2bf9dc1c102fea2cc8ff975
 *
 * ... and its advisory:
 * http://hikiwiki.org/en/advisory20040712.html
 */
VALUE rb_str_inspect(VALUE str);

/**
 * "Inverse" of rb_eval_string().  Returns a quoted version of the string.  All
 * non-printing characters are replaced by  `\uNNNN` or `\xHH` notation and all
 * special characters are escaped.  The result string is guaranteed to render a
 * string of the same contents when passed to `eval` and friends.
 *
 * @param[in]  str               String to dump.
 * @exception  rb_eRuntimeError  Too  many  escape   sequences  causes  integer
 *                               overflow on the length of the string.
 * @return     An  US-ASCII string  that  includes all  the  necessary info  to
 *             reconstruct the original string.
 */
VALUE rb_str_dump(VALUE str);

/**
 * Divides  the  given string  based  on  the  given  delimiter.  This  is  the
 * 1-argument 0-block version of `String#split`.
 *
 * @param[in]  str            Object in question to split.
 * @param[in]  delim          Delimiter, in C string.
 * @exception  rb_eTypeError  `str` has no implicit conversion to String.
 * @exception  rb_eArgError   `delim` is a null pointer.
 * @return     An array of  strings, which are substrings of  the passed `str`.
 *             If `delim` is an empty C string (i.e. `""`), `str` is split into
 *             each characters.  If `delim` is a C string whose sole content is
 *             a whitespace (i.e.  `" "`), `str` is split  on whitespaces, with
 *             leading  and   trailing  whitespace   and  runs   of  contiguous
 *             whitespace  characters  ignored.    Otherwise,  `str`  is  split
 *             according to `delim`.
 */
VALUE rb_str_split(VALUE str, const char *delim);

/**
 * This is a ::rb_gvar_setter_t that refutes non-string assignments.
 *
 * @exception  rb_eTypeError  Passed something non-string.
 */
rb_gvar_setter_t rb_str_setter;

/* symbol.c */

/**
 * Identical  to  rb_to_symbol(),  except  it assumes  the  receiver  being  an
 * instance of ::RString.
 *
 * @param[in]  str               The name of the id.
 * @exception  rb_eRuntimeError  Too many symbols.
 * @return     A (possibly new) id whose value is the given `str`.
 * @pre        `str` must not be any arbitrary object except ::RString.
 * @note       These   days  Ruby   internally   has  two   kinds  of   symbols
 *             (static/dynamic).   Symbols created  using  this function  would
 *             become dynamic ones; i.e. would  be garbage collected.  It could
 *             be safer for you to use it than alternatives, when applicable.
 */
VALUE rb_str_intern(VALUE str);

/* string.c */

/**
 * This is an rb_sym2str() + rb_str_dup() combo.
 *
 * @param[in]  sym  A symbol to query.
 * @return     A string duplicating the symbol's backend storage.
 *
 * @internal
 *
 * This function  causes SEGV  when the  passed value is  a static  symbol that
 * doesn't exist.
 */
VALUE rb_sym_to_s(VALUE sym);

/**
 * Counts the  number of characters (not  bytes) that are stored  inside of the
 * given string.  This  of course depends on its encoding.   Also this function
 * generally runs  in O(n), because  for instance you  have to scan  the entire
 * string to know how many characters are there in a UTF-8 string.
 *
 * @param[in]  str  Target string to query.
 * @return     Its number of characters.
 */
long rb_str_strlen(VALUE str);

/**
 * Identical to rb_str_strlen(), except it returns the value in ::rb_cInteger.
 *
 * @param[in]  str  Target string to query.
 * @return     Its number of characters.
 */
VALUE rb_str_length(VALUE);

/**
 * "Inverse" of rb_str_sublen().  This function  scans the contents to find the
 * byte index that matches the character  index.  Generally speaking this is an
 * `O(n)` operation.  Could be slow.
 *
 * @param[in]  str  The string to scan.
 * @param[in]  pos  Offset, in characters.
 * @return     Offset, in bytes.
 */
long rb_str_offset(VALUE str, long pos);

RBIMPL_ATTR_PURE()
/**
 * Queries the capacity of the given string.
 *
 * @see        ::RString::capa
 * @param[in]  str  String in question.
 * @return     Its capacity.
 */
size_t rb_str_capacity(VALUE str);

/**
 * Shortens `str` and adds three dots, an  ellipsis, if it is longer than `len`
 * characters.  The length of the returned string in characters is less than or
 * equal to `len`.  If the length of `str` is less than or equal `len`, returns
 * `str` itself.   The encoding of returned  string is equal to  that of passed
 * one.  The class of returned string is equal to that of passed one.
 *
 * @param[in]  str             The string to shorten.
 * @param[in]  len             The maximum string length.
 * @exception  rb_eIndexError  `len` is negative.
 * @retval     str             No need to add ellipsis.
 * @retval     otherwise       A new, shortened string.
 * @note       The length is counted in characters.
 */
VALUE rb_str_ellipsize(VALUE str, long len);

/**
 * "Cleanses" the string.   A string has its encoding and  its contents.  They,
 * in practice,  do not  always fit.  There  are strings in  the wild  that are
 * "broken"; include bit  patterns that are not allowed by  its encoding.  That
 * can  happen  when  a  user  copy&pasted something  bad,  network  input  got
 * clobbered by a middleman, cosmic rays hit the physical memory, and many more
 * occasions.  This function takes such strings, and fills the "broken" portion
 * with the passed replacement bit pattern.
 *
 * This function also takes a ruby block.  That is a neat way to do things, but
 * can be  annoying when the  caller function want to  use a block  for another
 * purpose.
 *
 * @param[in]  str                 Target string to scrub.
 * @param[in]  repl                Replacement  string.  When  it is  a string,
 *                                 this function  takes that as  a replacement.
 *                                 When it is  ::RUBY_Qnil, this function tries
 *                                 to  yield a  block  (if any)  and takes  its
 *                                 evaluated value  as a replacement.   In case
 *                                 of   ::RUBY_Qnil  without   a  block,   this
 *                                 function takes  an encoding-specific default
 *                                 character (`U+FFFD`, for instance) as a last
 *                                 resort.
 * @exception  rb_eTypeError       `repl` is neither string nor nil.
 * @exception  rb_eArgError        `repl` itself is broken.
 * @exception  rb_eEncCompatError  `repl` and `str` are incompatible.
 * @retval     RUBY_Qnil           `str` is already clean.
 * @retval     otherwise           A new, clean string.
 */
VALUE rb_str_scrub(VALUE str, VALUE repl);

/**
 * Searches for  the "successor"  of a string.   This function  is complicated!
 * This is  the only function in  the entire ruby  API (either C or  Ruby) that
 * generates a string out of thin air.  First, the successor to an empty string
 * is a new empty string:
 *
 * ```ruby
 * ''.succ # => ""
 * ```
 *
 * Otherwise  the successor  is  calculated by  "incrementing" characters.  The
 * first character to  be incremented is the rightmost alphanumeric:  or, if no
 * alphanumerics, the rightmost character:
 *
 * ```ruby
 * 'THX1138'.succ # => "THX1139"
 * '<<koala>>'.succ # => "<<koalb>>"
 * '***'.succ # => '**+'
 * ```
 *
 * The  successor to  a digit  is another  digit, "carrying"  to the  next-left
 * character for  a "rollover"  from 9  to 0, and  prepending another  digit if
 * necessary:
 *
 * ```ruby
 * '00'.succ # => "01"
 * '09'.succ # => "10"
 * '99'.succ # => "100"
 * '-9'.succ # => "-10"
 * ```
 *
 * The successor to  a letter is another  letter of the same  case, carrying to
 * the next-left  character for  a rollover,  and prepending  another same-case
 * letter if necessary:
 *
 * ```ruby
 * 'aa'.succ # => "ab"
 * 'az'.succ # => "ba"
 * 'zz'.succ # => "aaa"
 * 'AA'.succ # => "AB"
 * 'AZ'.succ # => "BA"
 * 'ZZ'.succ # => "AAA"
 * ```
 *
 * The successor to  a non-alphanumeric character is the next  character in the
 * underlying  character set's  collating sequence,  carrying to  the next-left
 * character for a rollover, and prepending another character if necessary:
 *
 * ```ruby
 * s = "\u03A1"
 * s.succ # => "\u03A3"  # There is no such thing like \u03A2.
 * s = 255.chr * 3
 * s # => "\xFF\xFF\xFF"
 * s.succ # => "\x01\x00\x00\x00"
 * ```
 *
 * Carrying can occur between and among mixtures of alphanumeric characters:
 *
 * ```ruby
 * s = 'zz99zz99'
 * s.succ # => "aaa00aa00"
 * s = '99zz99zz'
 * s.succ # => "100aa00aa"
 * s = '1.9.9'
 * s.succ # => "2.0.0"
 * ```
 *
 * @param[in]  orig  Predecessor string.
 * @return     Successor string.
 */
VALUE rb_str_succ(VALUE orig);

RBIMPL_ATTR_NONNULL(())
/**
 * @private
 *
 * This is an implementation detail.  Don't bother.
 *
 * @param[in]  str  A C string.
 * @return     `strlen`, casted to `long`.
 */
static inline long
rbimpl_strlen(const char *str)
{
    return RBIMPL_CAST((long)strlen(str));
}

RBIMPL_ATTR_NONNULL(())
/**
 * @private
 *
 * This is an implementation detail.  Don't bother.
 *
 * @param[in]  str  A C string literal.
 * @return     Corresponding Ruby string.
 */
static inline VALUE
rbimpl_str_new_cstr(const char *str)
{
    long len = rbimpl_strlen(str);
    return rb_str_new_static(str, len);
}

RBIMPL_ATTR_NONNULL(())
/**
 * @private
 *
 * This is an implementation detail.  Don't bother.
 *
 * @param[in]  str  A C string literal.
 * @return     Corresponding Ruby string.
 */
static inline VALUE
rbimpl_usascii_str_new_cstr(const char *str)
{
    long len = rbimpl_strlen(str);
    return rb_usascii_str_new_static(str, len);
}

RBIMPL_ATTR_NONNULL(())
/**
 * @private
 *
 * This is an implementation detail.  Don't bother.
 *
 * @param[in]  str  A C string literal.
 * @return     Corresponding Ruby string.
 */
static inline VALUE
rbimpl_utf8_str_new_cstr(const char *str)
{
    long len = rbimpl_strlen(str);
    return rb_utf8_str_new_static(str, len);
}

RBIMPL_ATTR_NONNULL(())
/**
 * @private
 *
 * This is an implementation detail.  Don't bother.
 *
 * @param[in]  str  A C string literal.
 * @return     Corresponding Ruby string.
 */
static inline VALUE
rbimpl_external_str_new_cstr(const char *str)
{
    long len = rbimpl_strlen(str);
    return rb_external_str_new(str, len);
}

RBIMPL_ATTR_NONNULL(())
/**
 * @private
 *
 * This is an implementation detail.  Don't bother.
 *
 * @param[in]  str  A C string literal.
 * @return     Corresponding Ruby string.
 */
static inline VALUE
rbimpl_locale_str_new_cstr(const char *str)
{
    long len = rbimpl_strlen(str);
    return rb_locale_str_new(str, len);
}

RBIMPL_ATTR_NONNULL(())
/**
 * @private
 *
 * This is an implementation detail.  Don't bother.
 *
 * @param[in]  str  A C string literal.
 * @return     Corresponding Ruby string.
 */
static inline VALUE
rbimpl_str_buf_new_cstr(const char *str)
{
    long len = rbimpl_strlen(str);
    VALUE buf = rb_str_buf_new(len);
    return rb_str_buf_cat(buf, str, len);
}

RBIMPL_ATTR_NONNULL(())
/**
 * @private
 *
 * This is an implementation detail.  Don't bother.
 *
 * @param[out]  buf  A string buffer.
 * @param[in]   str  A C string literal.
 * @return      `buf` itself.
 */
static inline VALUE
rbimpl_str_cat_cstr(VALUE buf, const char *str)
{
    long len = rbimpl_strlen(str);
    return rb_str_cat(buf, str, len);
}

RBIMPL_ATTR_NONNULL(())
/**
 * @private
 *
 * This is an implementation detail.  Don't bother.
 *
 * @param[in]  exc  An exception class.
 * @param[in]  str  A C string literal.
 * @return     An instance of `exc`.
 */
static inline VALUE
rbimpl_exc_new_cstr(VALUE exc, const char *str)
{
    long len = rbimpl_strlen(str);
    return rb_exc_new(exc, str, len);
}

/**
 * Allocates an instance of ::rb_cString.
 *
 * @param[in]  str             A memory region of `len` bytes length.
 * @param[in]  len             Length  of `ptr`,  in bytes,  not including  the
 *                             terminating NUL character.
 * @exception  rb_eNoMemError  Failed to allocate `len+1` bytes.
 * @exception  rb_eArgError    `len` is negative.
 * @return     An  instance   of  ::rb_cString,  of  `len`   bytes  length,  of
 *             "binary" encoding, whose contents are verbatim copy of `str`.
 * @pre        At  least  `len` bytes  of  continuous  memory region  shall  be
 *             accessible via `str`.
 */
#define rb_str_new(str, len)                    \
    ((RBIMPL_CONSTANT_P(str) &&                 \
      RBIMPL_CONSTANT_P(len) ?                  \
      rb_str_new_static      :                  \
      rb_str_new) ((str), (len)))

/**
 * Identical to #rb_str_new, except it assumes  the passed pointer is a pointer
 * to a C string.
 *
 * @param[in]  str             A C string.
 * @exception  rb_eNoMemError  Failed to allocate memory.
 * @return     An  instance  of  ::rb_cString,   of  "binary"  encoding,  whose
 *             contents are verbatim copy of `str`.
 * @pre        `str` must not be a null pointer.
 */
#define rb_str_new_cstr(str)                    \
    ((RBIMPL_CONSTANT_P(str) ?                  \
      rbimpl_str_new_cstr    :                  \
      rb_str_new_cstr) (str))

/**
 * Identical  to  #rb_str_new, except  it  generates  a  string of  "US  ASCII"
 * encoding.  This  is different from  rb_external_str_new(), not only  for the
 * output encoding, but also it doesn't convert the contents.
 *
 * @param[in]  str             A memory region of `len` bytes length.
 * @param[in]  len             Length  of `str`,  in bytes,  not including  the
 *                             terminating NUL character.
 * @exception  rb_eNoMemError  Failed to allocate `len+1` bytes.
 * @exception  rb_eArgError    `len` is negative.
 * @return     An  instance   of  ::rb_cString,  of  `len`   bytes  length,  of
 *             "US ASCII" encoding, whose contents are verbatim copy of `str`.
 */
#define rb_usascii_str_new(str, len)            \
    ((RBIMPL_CONSTANT_P(str)    &&              \
      RBIMPL_CONSTANT_P(len)    ?               \
      rb_usascii_str_new_static :               \
      rb_usascii_str_new) ((str), (len)))

/**
 * Identical to #rb_str_new, except it generates a string of "UTF-8" encoding.
 *
 * @param[in]  str             A memory region of `len` bytes length.
 * @param[in]  len             Length  of `str`,  in bytes,  not including  the
 *                             terminating NUL character.
 * @exception  rb_eNoMemError  Failed to allocate `len+1` bytes.
 * @exception  rb_eArgError    `len` is negative.
 * @return     An  instance   of  ::rb_cString,  of  `len`   bytes  length,  of
 *             "UTF-8" encoding, whose contents are verbatim copy of `str`.
 */
#define rb_utf8_str_new(str, len)               \
    ((RBIMPL_CONSTANT_P(str) &&                 \
      RBIMPL_CONSTANT_P(len) ?                  \
      rb_utf8_str_new_static :                  \
      rb_utf8_str_new) ((str), (len)))

/**
 * Identical to  #rb_str_new_cstr, except it  generates a string of  "US ASCII"
 * encoding.    It   can   also   be   seen   as   a   routine   Identical   to
 * #rb_usascii_str_new, except it assumes the passed  pointer is a pointer to a
 * C string.
 *
 * @param[in]  str             A C string.
 * @exception  rb_eNoMemError  Failed to allocate memory.
 * @return     An  instance  of ::rb_cString,  of  "US  ASCII" encoding,  whose
 *             contents are verbatim copy of `str`.
 * @pre        `str` must not be a null pointer.
 */
#define rb_usascii_str_new_cstr(str)            \
    ((RBIMPL_CONSTANT_P(str)      ?             \
      rbimpl_usascii_str_new_cstr :             \
      rb_usascii_str_new_cstr) (str))

/**
 * Identical  to #rb_str_new_cstr,  except  it generates  a  string of  "UTF-8"
 * encoding.  It can  also be seen as a routine  Identical to #rb_utf8_str_new,
 * except it assumes the passed pointer is a pointer to a C string.
 *
 * @param[in]  str             A C string.
 * @exception  rb_eNoMemError  Failed to allocate memory.
 * @return     An instance of ::rb_cString, of "UTF-8" encoding, whose contents
 *             are verbatim copy of `str`.
 * @pre        `str` must not be a null pointer.
 */
#define rb_utf8_str_new_cstr(str)               \
    ((RBIMPL_CONSTANT_P(str)   ?                \
      rbimpl_utf8_str_new_cstr :                \
      rb_utf8_str_new_cstr) (str))

/**
 * Identical  to #rb_str_new_cstr,  except it  generates a  string of  "default
 * external" encoding.
 *
 * @param[in]  str             A C string.
 * @exception  rb_eNoMemError  Failed to allocate memory.
 * @return     An instance  of ::rb_cString.  In case  encoding conversion from
 *             "default internal"  to "default external" is  fully defined over
 *             the  given  contents, then  the  return  value  is a  string  of
 *             "default external"  encoding, whose  contents are  the converted
 *             ones.  Otherwise the string is a junk.
 * @warning    It doesn't raise on a conversion failure and silently ends up in
 *             a  corrupted  output.  You  can  know  the failure  by  querying
 *             `valid_encoding?` of the result object.
 * @pre        `str` must not be a null pointer.
 */
#define rb_external_str_new_cstr(str)           \
    ((RBIMPL_CONSTANT_P(str)       ?            \
      rbimpl_external_str_new_cstr :            \
      rb_external_str_new_cstr) (str))

/**
 * Identical  to #rb_external_str_new_cstr,  except  it generates  a string  of
 * "locale" encoding instead of "default external".
 *
 * @param[in]  str             A C string.
 * @exception  rb_eNoMemError  Failed to allocate memory.
 * @return     An instance  of ::rb_cString.  In case  encoding conversion from
 *             "default internal" to  "locale" is fully defined  over the given
 *             contents,  then  the  return  value  is  a  string  of  "locale"
 *             encoding, whose contents are  the converted ones.  Otherwise the
 *             string is a junk.
 * @warning    It doesn't raise on a conversion failure and silently ends up in
 *             a  corrupted  output.  You  can  know  the failure  by  querying
 *             `valid_encoding?` of the result object.
 * @pre        `str` must not be a null pointer.
 */
#define rb_locale_str_new_cstr(str)             \
    ((RBIMPL_CONSTANT_P(str)     ?              \
      rbimpl_locale_str_new_cstr :              \
      rb_locale_str_new_cstr) (str))

/**
 * Identical to #rb_str_new_cstr, except done differently.
 *
 * @param[in]  str             A C string.
 * @exception  rb_eNoMemError  Failed to allocate memory.
 * @return     An  instance  of  ::rb_cString,   of  "binary"  encoding,  whose
 *             contents are verbatim copy of `str`.
 * @pre        `str` must not be a null pointer.
 */
#define rb_str_buf_new_cstr(str)                \
    ((RBIMPL_CONSTANT_P(str)  ?                 \
      rbimpl_str_buf_new_cstr :                 \
      rb_str_buf_new_cstr) (str))

/**
 * Identical to rb_str_cat(), except it assumes the passed pointer is a pointer
 * to a C string.
 *
 * @param[out]  buf                 Destination object.
 * @param[in]   str                 Contents to append.
 * @exception   rb_eArgError        Result string too big.
 * @return      The passed `buf`.
 * @pre         `buf` must not be any arbitrary objects except ::RString.
 * @pre         `str` must not be a null pointer.
 * @post        `buf` has the contents of `str` appended.
 */
#define rb_str_cat_cstr(buf, str)               \
    ((RBIMPL_CONSTANT_P(str) ?                  \
      rbimpl_str_cat_cstr    :                  \
      rb_str_cat_cstr) ((buf), (str)))

/**
 * Identical to rb_exc_new(), except it assumes the passed pointer is a pointer
 * to a C string.
 *
 * @param[out]  exc  A subclass of ::rb_eException.
 * @param[in]   str  Message to raise.
 * @return      An instance of `exc` whose message is `str`.
 * @pre         `str` must not be a null pointer.
 */
#define rb_exc_new_cstr(exc, str)               \
    ((RBIMPL_CONSTANT_P(str) ?                  \
      rbimpl_exc_new_cstr    :                  \
      rb_exc_new_cstr) ((exc), (str)))

#define rb_str_new2 rb_str_new_cstr                  /**< @old{rb_str_new_cstr} */
#define rb_str_new3 rb_str_new_shared                /**< @old{rb_str_new_shared} */
#define rb_str_new4 rb_str_new_frozen                /**< @old{rb_str_new_frozen} */
#define rb_str_new5 rb_str_new_with_class            /**< @old{rb_str_new_with_class} */
#define rb_str_buf_new2 rb_str_buf_new_cstr          /**< @old{rb_str_buf_new_cstr} */
#define rb_usascii_str_new2 rb_usascii_str_new_cstr  /**< @old{rb_usascii_str_new_cstr} */
#define rb_str_buf_cat rb_str_cat                    /**< @alias{rb_str_cat} */
#define rb_str_buf_cat2 rb_str_cat_cstr              /**< @old{rb_usascii_str_new_cstr} */
#define rb_str_cat2 rb_str_cat_cstr                  /**< @old{rb_str_cat_cstr} */

/**
 * Length of a string literal.
 *
 * @param[in]  str  A C String literal.
 * @return     An  integer constant  expression that  represents the  number of
 *             `str`'s elements, not including the terminating NUL character.
 */
#define rb_strlen_lit(str) ((sizeof(str "") / sizeof(str ""[0])) - 1)

/**
 * Identical to rb_str_new_static(), except it cannot take string variables.
 *
 * @param[in]  str  A C string literal.
 * @pre        `str` must not be a variable.
 * @return     An instance of ::rb_cString, of "binary" encoding, whose backend
 *             storage is the passed C string literal.
 * @warning    It is  a very  bad idea to  write to a  C string  literal (often
 *             immediate  SEGV shall  occur).  Consider  return values  of this
 *             function be read-only.
 */
#define rb_str_new_lit(str) rb_str_new_static((str), rb_strlen_lit(str))

/**
 * Identical  to  rb_usascii_str_new_static(),  except it  cannot  take  string
 * variables.
 *
 * @param[in]  str           A C string literal.
 * @pre        `str` must not be a variable.
 * @return     An  instance  of ::rb_cString,  of  "US  ASCII" encoding,  whose
 *             backend storage is the passed C string literal.
 * @warning    It is  a very  bad idea to  write to a  C string  literal (often
 *             immediate  SEGV shall  occur).  Consider  return values  of this
 *             function be read-only.
 */
#define rb_usascii_str_new_lit(str) rb_usascii_str_new_static((str), rb_strlen_lit(str))

/**
 * Identical  to   rb_utf8_str_new_static(),  except  it  cannot   take  string
 * variables.
 *
 * @param[in]  str           A C string literal.
 * @pre        `str` must not be a variable.
 * @return     An instance of ::rb_cString,  of "UTF-8" encoding, whose backend
 *             storage is the passed C string literal.
 * @warning    It is  a very  bad idea to  write to a  C string  literal (often
 *             immediate  SEGV shall  occur).  Consider  return values  of this
 *             function be read-only.
 */
#define rb_utf8_str_new_lit(str) rb_utf8_str_new_static((str), rb_strlen_lit(str))

/**
 * Identical  to   rb_enc_str_new_static(),  except   it  cannot   take  string
 * variables.
 *
 * @param[in]  str           A C string literal.
 * @param[in]  enc           A pointer to an encoding.
 * @pre        `str` must not be a variable.
 * @return     An  instance  of ::rb_cString,  of  the  passed encoding,  whose
 *             backend storage is the passed C string literal.
 * @warning    It is  a very  bad idea to  write to a  C string  literal (often
 *             immediate  SEGV shall  occur).  Consider  return values  of this
 *             function be read-only.
 */
#define rb_enc_str_new_lit(str, enc) rb_enc_str_new_static((str), rb_strlen_lit(str), (enc))

#define rb_str_new_literal(str) rb_str_new_lit(str)                    /**< @alias{rb_str_new_lit} */
#define rb_usascii_str_new_literal(str) rb_usascii_str_new_lit(str)    /**< @alias{rb_usascii_str_new_lit} */
#define rb_utf8_str_new_literal(str) rb_utf8_str_new_lit(str)          /**< @alias{rb_utf8_str_new_lit} */
#define rb_enc_str_new_literal(str, enc) rb_enc_str_new_lit(str, enc)  /**< @alias{rb_enc_str_new_lit} */

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERN_STRING_H */
ruby/internal/intern/select.h000064400000007552151732674250012315 0ustar00#ifndef RBIMPL_INTERN_SELECT_H                       /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_SELECT_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Public APIs to provide ::rb_fd_select().
 * @note       Functions  and  structs defined  in  this  header file  are  not
 *             necessarily ruby-specific.  They don't need ::VALUE etc.
 */
#include "ruby/internal/config.h"

#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>         /* for NFDBITS (BSD Net/2) */
#endif

#include "ruby/internal/dllexport.h"

/* thread.c */
#if defined(NFDBITS) && defined(HAVE_RB_FD_INIT)
# include "ruby/internal/intern/select/largesize.h"
#elif defined(_WIN32)
# include "ruby/internal/intern/select/win32.h"
# /** Does nothing (defined for compatibility). */
# define rb_fd_resize(n, f) ((void)(f))
#else
# include "ruby/internal/intern/select/posix.h"
# /** Does nothing (defined for compatibility). */
# define rb_fd_resize(n, f) ((void)(f))
#endif

RBIMPL_SYMBOL_EXPORT_BEGIN()

struct timeval;

/**
 * Waits for multiple file descriptors at once.  This is basically a wrapper of
 * system-provided select() with releasing GVL, to allow other Ruby threads run
 * in parallel.
 *
 * @param[in]      nfds       Max FD in everything passed, plus one.
 * @param[in,out]  rfds       Set of FDs to wait for reads.
 * @param[in,out]  wfds       Set of FDs to wait for writes.
 * @param[in,out]  efds       Set of FDs to wait for OOBs.
 * @param[in,out]  timeout    Max blocking duration.
 * @retval         -1         Failed, errno set.
 * @retval          0         Timeout exceeded.
 * @retval         otherwise  Total number of file descriptors returned.
 * @post           `rfds` contains readable FDs.
 * @post           `wfds` contains writable FDs.
 * @post           `efds` contains exceptional FDs.
 * @post           `timeout` is the time left.
 * @note           All pointers are allowed to be null pointers.
 *
 * Although backend  threads can run in  parallel of this function,  touching a
 * file descriptor  from multiple threads  could be problematic.   For instance
 * what happens  when a  thread closes  a file descriptor  that is  selected by
 * someone else, vastly varies among operating systems.  You would better avoid
 * touching an fd from more than one threads.
 *
 * @internal
 *
 * Although  any file  descriptors are  possible here,  it makes  completely no
 * sense to pass  a descriptor that is  not `O_NONBLOCK`.  If you  want to know
 * the reason for  this limitation in detail, you might  find this thread super
 * interesting: https://lkml.org/lkml/2004/10/6/117
 */
int rb_thread_fd_select(int nfds, rb_fdset_t *rfds, rb_fdset_t *wfds, rb_fdset_t *efds, struct timeval *timeout);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERN_SELECT_H */
ruby/internal/intern/load.h000064400000024656151732674250011761 0ustar00#ifndef  RBIMPL_INTERN_LOAD_H                        /*-*-C++-*-vi:se ft=cpp:*/
#define  RBIMPL_INTERN_LOAD_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Public APIs related to ::rb_f_require().
 */
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/* load.c */

/**
 * Loads and executes the Ruby program in the given file.
 *
 * If the path is  an absolute path (e.g. starts with `'/'`),  the file will be
 * loaded  directly using  the  absolute  path.  If  the  path  is an  explicit
 * relative path (e.g. starts with `'./'`  or `'../'`), the file will be loaded
 * using the  relative path  from the current  directory.  Otherwise,  the file
 * will be searched for in the  library directories listed in the `$LOAD_PATH`.
 * If the file is found in a  directory, this function will attempt to load the
 * file relative  to that directory.  If  the file is  not found in any  of the
 * directories in the `$LOAD_PATH`, the file  will be loaded using the relative
 * path from the current directory.
 *
 * If the file doesn't  exist when there is an attempt to  load it, a LoadError
 * will be raised.
 *
 * If the `wrap` parameter is true, the loaded script will be executed under an
 * anonymous module, protecting the calling  program's global namespace.  In no
 * circumstance will  any local variables in  the loaded file be  propagated to
 * the loading environment.
 *
 * @param[in]  path                Pathname of a file to load.
 * @param[in]  wrap                Either to load under an anonymous module.
 * @exception  rb_eTypeError       `path` is not a string.
 * @exception  rb_eArgError        `path` is broken as a pathname.
 * @exception  rb_eEncCompatError  `path` is incompatible with pathnames.
 * @exception  rb_eLoadError       `path` not found.
 * @exception  rb_eException       Any exceptions while loading the contents.
 *
 * @internal
 *
 * It seems this function is under the rule of bootsnap's regime?
 */
void rb_load(VALUE path, int wrap);

/**
 * Identical to  rb_load(), except  it avoids  potential global  escapes.  Such
 * global escapes include exceptions, `throw`, `break`, for example.
 *
 * It first  evaluates the given file  as rb_load() does.  If  no global escape
 * occurred  during the  evaluation,  it `*state`  is set  to  zero on  return.
 * Otherwise, it sets `*state`  to nonzero.  If state is `NULL`,  it is not set
 * in both cases.
 *
 * @param[in]   path   Pathname of a file to load.
 * @param[in]   wrap   Either to load under an anonymous module.
 * @param[out]  state  State of execution.
 * @post        `*state` is set to zero if succeeded.  Nonzero otherwise.
 * @warning     You have to clear the error info with `rb_set_errinfo(Qnil)` if
 *              you decide to ignore the caught exception.
 * @see         rb_load
 * @see         rb_protect
 *
 * @internal
 *
 * Though   not  a   part  of   our  public   API,  `state`   is  in   fact  an
 * enum ruby_tag_type.  You can  see the potential "nonzero"  values by looking
 * at vm_core.h.
 */
void rb_load_protect(VALUE path, int wrap, int *state);

RBIMPL_ATTR_NONNULL(())
/**
 * Queries if  the given  feature has  already been  loaded into  the execution
 * context.  The "feature" head are things like `"json"` or `"socket"`.
 *
 * @param[in]  feature  Name of a library you want to know about.
 * @retval     1        Yes there is.
 * @retval     0        Not yet.
 */
int rb_provided(const char *feature);

RBIMPL_ATTR_NONNULL((1))
/**
 * Identical to  rb_provided(), except it additionally  returns the "canonical"
 * name of the loaded feature.  This can be handy when for instance you want to
 * know the actually loaded library is either `foo.rb` or `foo.so`.
 *
 * @param[in]   feature  Name of a library you want to know about.
 * @param[out]  loading  Return buffer.
 * @retval      1        Yes there is.
 * @retval      0        Not yet.
 */
int rb_feature_provided(const char *feature, const char **loading);

RBIMPL_ATTR_NONNULL(())
/**
 * Declares that the  given feature is already provided by  someone else.  This
 * API can  be handy  when you  have an extension  called `foo.so`  which, when
 * required, also provides functionality of `bar.so`.
 *
 * @param[in]  feature  Name of a library which had already been provided.
 * @post       No further `require` would search `feature`.
 */
void rb_provide(const char *feature);

/**
 * Identical to rb_require_string(),  except it ignores the  first argument for
 * no reason.  There seems to be no reason for 3rd party extension libraries to
 * use it.
 *
 * @param[in]  self              Ignored.  Can be anything.
 * @param[in]  feature           Name of a feature, e.g. `"json"`.
 * @exception  rb_eLoadError     No such feature.
 * @exception  rb_eRuntimeError  `$"` is frozen; unable to push.
 * @retval     RUBY_Qtrue        The feature is loaded for the first time.
 * @retval     RUBY_Qfalse       The feature has already been loaded.
 * @post       `$"` is updated.
 */
VALUE rb_f_require(VALUE self, VALUE feature);

/**
 * Finds and loads the given feature, if absent.
 *
 * If the  feature is an  absolute path (e.g.  starts with `'/'`),  the feature
 * will  be loaded  directly using  the absolute  path.  If  the feature  is an
 * explicit relative  path (e.g.  starts with `'./'`  or `'../'`),  the feature
 * will  be  loaded  using  the  relative  path  from  the  current  directory.
 * Otherwise,  the feature  will be  searched  for in  the library  directories
 * listed in the `$LOAD_PATH`.
 *
 * If the feature has the extension `".rb"`,  it is loaded as a source file; if
 * the extension is `".so"`, `".o"`, or `".dll"`, or the default shared library
 * extension on the  current platform, Ruby loads the shared  library as a Ruby
 * extension.  Otherwise, Ruby tries adding `".rb"`,  `".so"`, and so on to the
 * name until found.   If the file named  cannot be found, a  LoadError will be
 * raised.
 *
 * For  extension  libraries the  given  feature  may  use any  shared  library
 * extension.  For example, on Linux you can require `"socket.dll"` to actually
 * load `socket.so`.
 *
 * The absolute path of the loaded file is added to `$LOADED_FEATURES`.  A file
 * will not be loaded again if its path already appears in there.
 *
 * Any constants or globals within the  loaded source file will be available in
 * the calling program's  global namespace.  However, local  variables will not
 * be propagated to the loading environment.
 *
 * @param[in]  feature           Name of a feature, e.g. `"json"`.
 * @exception  rb_eLoadError     No such feature.
 * @exception  rb_eRuntimeError  `$"` is frozen; unable to push.
 * @retval     RUBY_Qtrue        The feature is loaded for the first time.
 * @retval     RUBY_Qfalse       The feature has already been loaded.
 * @post       `$"` is updated.
 */
VALUE rb_require_string(VALUE feature);

/**
 * Resolves  and  returns  a symbol  of  a  function  in  the  native extension
 * specified by the feature and symbol names. Extensions will use this function
 * to access the symbols provided by other native extensions.
 *
 * @param[in]  feature           Name of a feature, e.g. `"json"`.
 * @param[in]  symbol            Name of a symbol defined by the feature.
 * @return     The resolved symbol of  a function, defined and externed  by the
 *             specified feature.  It may be NULL if the feature is not loaded,
 *             the feature is not extension, or the symbol is not found.
 */
void *rb_ext_resolve_symbol(const char *feature, const char *symbol);

/**
 * This macro  is  to provide  backwards compatibility.  It provides  a  way to
 * define function prototypes and resolving function symbols in a safe way.
 *
 * ```CXX
 * // prototypes
 * #ifdef HAVE_RB_EXT_RESOLVE_SYMBOL
 * VALUE *(*other_extension_func)(VALUE,VALUE);
 * #else
 * VALUE other_extension_func(VALUE);
 * #endif
 *
 * // in Init_xxx()
 * #ifdef HAVE_RB_EXT_RESOLVE_SYMBOL
 * other_extension_func = \
 *     (VALUE(*)(VALUE,VALUE))rb_ext_resolve_symbol(fname, sym_name);
 * if (other_extension_func == NULL) {
 *   // raise your own error
 * }
 * #endif
 * ```
 */
#define HAVE_RB_EXT_RESOLVE_SYMBOL 1

/**
 * @name extension configuration
 * @{
 */

/**
 * Asserts that  the extension  library that  calls this  function is  aware of
 * Ractor.  Multiple Ractors  run without protecting each  other.  This doesn't
 * interface  well   with  C  programs,   unless  designed  with   an  in-depth
 * understanding of  how Ractors work.   Extension libraries are shut  out from
 * Ractors by default.  This API is  to bypass that restriction.  Once after it
 * was called,  successive calls to rb_define_method()  etc. become definitions
 * of methods  that are  aware of  Ractors.  The amendment  would be  in effect
 * until the end of rb_require_string() etc.
 *
 * @param[in]  flag  Either the library is aware of Ractors or not.
 * @post       Methods would be callable form Ractors, if `flag` is true.
 */
void rb_ext_ractor_safe(bool flag);

/** @alias{rb_ext_ractor_safe} */
#define RB_EXT_RACTOR_SAFE(f) rb_ext_ractor_safe(f)

/**
 * This macro  is to provide  backwards compatibility.  It  must be safe  to do
 * something like:
 *
 * ```CXX
 * #ifdef HAVE_RB_EXT_RACTOR_SAFE
 * rb_ext_ractor_safe(true);
 * #endif
 * ```
 */
#define HAVE_RB_EXT_RACTOR_SAFE 1

/** @} */

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERN_LOAD_H */
ruby/internal/intern/struct.h000064400000022312151732674250012351 0ustar00#ifndef RBIMPL_INTERN_STRUCT_H                       /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_STRUCT_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Public APIs related to ::rb_cStruct.
 */
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/intern/vm.h" /* rb_alloc_func_t */
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/* struct.c */

/**
 * Creates an instance of the given struct.
 *
 * @param[in]  klass  The class of the instance to allocate.
 * @param[in]  ...    The fields.
 * @return     Allocated instance of `klass`.
 * @pre        `klass` must be a subclass of ::rb_cStruct.
 * @note       Number of variadic arguments must much that of the passed klass'
 *             fields.
 */
VALUE rb_struct_new(VALUE klass, ...);

/**
 * Defines a struct class.
 *
 * @param[in]  name           Name of the class.
 * @param[in]  ...            Arbitrary number of  `const char*`, terminated by
 *                            NULL.  Each of which are the name of fields.
 * @exception  rb_eNameError  `name` is not a constant name.
 * @exception  rb_eTypeError  `name` is already taken.
 * @exception  rb_eArgError   Duplicated field name.
 * @return     The defined class.
 * @post       Global toplevel constant `name` is defined.
 * @note       `name` is allowed  to be a null pointer.   This function creates
 *             an anonymous struct class then.
 * @note       The GC does not collect nor move classes returned by this
 *             function. They are immortal.
 *
 * @internal
 *
 * Not  seriously  checked but  it  seems  this  function  does not  share  its
 * implementation with how `Struct.new` is implemented...?
 */
VALUE rb_struct_define(const char *name, ...);

RBIMPL_ATTR_NONNULL((2))
/**
 * Identical  to rb_struct_define(),  except  it defines  the  class under  the
 * specified namespace instead of global toplevel.
 *
 * @param[out]  space          Namespace that the defining class shall reside.
 * @param[in]   name           Name of the class.
 * @param[in]   ...            Arbitrary number of `const char*`, terminated by
 *                             NULL.  Each of which are the name of fields.
 * @exception   rb_eNameError  `name` is not a constant name.
 * @exception   rb_eTypeError  `name` is already taken.
 * @exception   rb_eArgError   Duplicated field name.
 * @return      The defined class.
 * @post        `name` is a constant under `space`.
 * @note        In contrast to rb_struct_define(), it doesn't make any sense to
 *              pass  a null pointer to this function.
 * @note        The GC does not collect nor move classes returned by this
 *              function. They are immortal.
 */
VALUE rb_struct_define_under(VALUE space, const char *name, ...);

/**
 * Identical to  rb_struct_new(), except it  takes the  field values as  a Ruby
 * array.
 *
 * @param[in]  klass   The class of the instance to allocate.
 * @param[in]  values  Field values.
 * @return     Allocated instance of `klass`.
 * @pre        `klass` must be a subclass of ::rb_cStruct.
 * @pre        `values` must be an instance of struct ::RArray.
 */
VALUE rb_struct_alloc(VALUE klass, VALUE values);

/**
 * Mass-assigns a struct's fields.
 *
 * @param[out]  self    An instance of a struct class to squash.
 * @param[in]   values  New values.
 * @return      ::RUBY_Qnil.
 */
VALUE rb_struct_initialize(VALUE self, VALUE values);

/**
 * Identical to rb_struct_aref(), except it takes ::ID instead of ::VALUE.
 *
 * @param[in]  self           An instance of a struct class.
 * @param[in]  key            Key to query.
 * @exception  rb_eTypeError  `self` is not a struct.
 * @exception  rb_eNameError  No such field.
 * @return     The value stored at `key` in `self`.
 */
VALUE rb_struct_getmember(VALUE self, ID key);

/**
 * Queries the list of the names of the fields of the given struct class.
 *
 * @param[in]  klass  A subclass of ::rb_cStruct.
 * @return     The list of the names of the fields of `klass`.
 */
VALUE rb_struct_s_members(VALUE klass);

/**
 * Queries the list of the names of the fields of the class of the given struct
 * object.  This is  almost the same as calling  rb_struct_s_members() over the
 * class of the receiver.
 *
 * @internal
 *
 * "Almost"?  What exactly is the difference?
 *
 * @endinternal
 *
 * @param[in]  self  An instance of a subclass of ::rb_cStruct.
 * @return     The list of the names of the fields.
 */
VALUE rb_struct_members(VALUE self);

/**
 * Allocates an  instance of the  given class.   This consequential name  is of
 * course because rb_struct_alloc() not only  allocates but also initialises an
 * instance.  The API design is broken.
 *
 * @param[in]  klass  A subclass of ::rb_cStruct.
 * @return     An allocated instance of `klass`, not initialised.
 */
VALUE rb_struct_alloc_noinit(VALUE klass);

/**
 * Identical to rb_struct_define(), except it does not define accessor methods.
 * You  have to  define them  yourself.   Forget about  the allocator  function
 * parameter; it is  for internal use only.  Extension libraries  are unable to
 * properly allocate a ruby struct, because `RStruct` is opaque.
 *
 * @internal
 *
 * Several flags must be set up properly for ::RUBY_T_STRUCT objects, which are
 * also missing for extension libraries.
 *
 * @endinternal
 *
 * @param[in]  name           Name of the class.
 * @param[in]  super          Superclass of the defining class.
 * @param[in]  func           Must be 0 for extension libraries.
 * @param[in]  ...            Arbitrary number of  `const char*`, terminated by
 *                            NULL.  Each of which are the name of fields.
 * @exception  rb_eNameError  `name` is not a constant name.
 * @exception  rb_eTypeError  `name` is already taken.
 * @exception  rb_eArgError   Duplicated field name.
 * @return     The defined class.
 * @post       Global toplevel constant `name` is defined.
 * @note       `name` is allowed  to be a null pointer.   This function creates
 *             an anonymous struct class then.
 */
VALUE rb_struct_define_without_accessor(const char *name, VALUE super, rb_alloc_func_t func, ...);

RBIMPL_ATTR_NONNULL((2))
/**
 * Identical  to  rb_struct_define_without_accessor(),  except it  defines  the
 * class under the specified namespace instead of global toplevel.  It can also
 * be seen as  a routine identical to rb_struct_define_under(),  except it does
 * not define accessor methods.
 *
 * @param[out]  outer          Namespace that the defining class shall reside.
 * @param[in]   class_name     Name of the class.
 * @param[in]   super          Superclass of the defining class.
 * @param[in]   alloc          Must be 0 for extension libraries.
 * @param[in]   ...            Arbitrary number of `const char*`, terminated by
 *                             NULL.  Each of which are the name of fields.
 * @exception   rb_eNameError  `class_name` is not a constant name.
 * @exception   rb_eTypeError  `class_name` is already taken.
 * @exception   rb_eArgError   Duplicated field name.
 * @return      The defined class.
 * @post        `class_name` is a constant under `outer`.
 * @note        In contrast to  rb_struct_define_without_accessor(), it doesn't
 *              make any sense to pass a null name.
 * @note        The GC does not collect nor move classes returned by this
 *              function. They are immortal.
 */
VALUE rb_struct_define_without_accessor_under(VALUE outer, const char *class_name, VALUE super, rb_alloc_func_t alloc, ...);

/**
 * Defines an anonymous data class.
 *
 * @endinternal
 *
 * @param[in]  super           Superclass  of the  defining  class.   Must be  a
 *                             descendant of ::rb_cData, or 0 as ::rb_cData.
 * @param[in]  ...             Arbitrary number of  `const char*`, terminated by
 *                             NULL.  Each of which are the name of fields.
 * @exception  rb_eArgError    Duplicated field name.
 * @return     The defined class.
 * @note       The GC does not collect nor move classes returned by this
 *             function. They are immortal.
 */
VALUE rb_data_define(VALUE super, ...);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERN_STRUCT_H */
ruby/internal/intern/time.h000064400000014526151732674250011773 0ustar00#ifndef RBIMPL_INTERN_TIME_H                         /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_TIME_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Public APIs related to ::rb_cTime.
 */
#include "ruby/internal/config.h"

#ifdef HAVE_TIME_H
# include <time.h>              /* for time_t */
#endif

#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

struct timespec;
struct timeval;

/* time.c */

RBIMPL_ATTR_NONNULL(())
/**
 * Fills the current time into the given struct.
 *
 * @param[out]  ts                   Return buffer.
 * @exception   rb_eSystemCallError  Access denied for hardware clock.
 * @post        Current time is stored in `*ts`.
 */
void rb_timespec_now(struct timespec *ts);

/**
 * Creates  an  instance of  ::rb_cTime  with  the  given  time and  the  local
 * timezone.
 *
 * @param[in]  sec             Seconds since the UNIX epoch.
 * @param[in]  usec            Subsecond part, in microseconds resolution.
 * @exception  rb_eRangeError  Cannot express the time.
 * @return     An allocated instance of ::rb_cTime.
 */
VALUE rb_time_new(time_t sec, long usec);

/**
 * Identical  to  rb_time_new(), except  it  accepts  the time  in  nanoseconds
 * resolution.
 *
 * @param[in]  sec             Seconds since the UNIX epoch.
 * @param[in]  nsec            Subsecond part, in nanoseconds resolution.
 * @exception  rb_eRangeError  Cannot express the time.
 * @return     An allocated instance of ::rb_cTime.
 */
VALUE rb_time_nano_new(time_t sec, long nsec);

RBIMPL_ATTR_NONNULL(())
/**
 * Creates an instance of ::rb_cTime, with given time and offset.
 *
 * @param[in]  ts            Time specifier.
 * @param[in]  offset        Offset specifier, can take following values:
 *                           - `INT_MAX`: `ts` is in local time.
 *                           - `INT_MAX - 1`: `ts` is in UTC.
 *                           - `-86400` to `86400`: fixed timezone.
 * @exception  rb_eArgError  Malformed `offset`.
 * @return     An allocated instance of ::rb_cTime.
 */
VALUE rb_time_timespec_new(const struct timespec *ts, int offset);

/**
 * Identical to rb_time_timespec_new(), except it  takes Ruby values instead of
 * C structs.
 *
 * @param[in]  timev         Something numeric.  Currently Integers, Rationals,
 *                           and Floats are accepted.
 * @param[in]  off           Offset  specifier.  As  of  2.7  this argument  is
 *                           heavily  extended  to   take  following  kinds  of
 *                           objects:
 *                             - ::RUBY_Qundef ... means UTC.
 *                             - ::rb_cString ... "+12:34" etc.
 *                             - A mysterious  "zone" object.  This  is largely
 *                               undocumented.  However the  initial intent was
 *                               that       we       want       to       accept
 *                               `ActiveSupport::TimeZone`  here.   Other  gems
 *                               could also be possible...   But how to make an
 *                               acceptable class is beyond this document.
 * @exception  rb_eArgError  Malformed `off`.
 * @return     An allocated instance of ::rb_cTime.
 */
VALUE rb_time_num_new(VALUE timev, VALUE off);

/**
 * Creates  a  "time  interval".   This   basically  converts  an  instance  of
 * ::rb_cNumeric  into  a struct  `timeval`,  but  for instance  negative  time
 * interval must not exist.
 *
 * @param[in]  num             An instance of ::rb_cNumeric.
 * @exception  rb_eArgError    `num` is negative.
 * @exception  rb_eRangeError  `num` is out of range of `timeval::tv_sec`.
 * @return     A struct that represents the identical time to `num`.
 */
struct timeval rb_time_interval(VALUE num);

/**
 * Converts an  instance of rb_cTime  to a  struct timeval that  represents the
 * identical point of time.  It can also take something numeric; would consider
 * it as a UNIX time then.
 *
 * @param[in]  time            Instance of either ::rb_cTime or ::rb_cNumeric.
 * @exception  rb_eRangeError  `time` is out of range of `timeval::tv_sec`.
 * @return     A struct that represents the identical time to `num`.
 */
struct timeval rb_time_timeval(VALUE time);

/**
 * Identical to rb_time_timeval(), except for return type.
 *
 * @param[in]  time            Instance of either ::rb_cTime or ::rb_cNumeric.
 * @exception  rb_eRangeError  `time` is out of range of `timeval::tv_sec`.
 * @return     A struct that represents the identical time to `num`.
 */
struct timespec rb_time_timespec(VALUE time);

/**
 * Identical to rb_time_interval(), except for return type.
 *
 * @param[in]  num             An instance of ::rb_cNumeric.
 * @exception  rb_eArgError    `num` is negative.
 * @exception  rb_eRangeError  `num` is out of range of `timespec::tv_sec`.
 * @return     A struct that represents the identical time to `num`.
 */
struct timespec rb_time_timespec_interval(VALUE num);

/**
 * Queries the  offset, in seconds  between the time zone  of the time  and the
 * UTC.
 *
 * @param[in]  time  An instance of ::rb_cTime.
 * @return     Numeric offset.
 */
VALUE rb_time_utc_offset(VALUE time);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERN_TIME_H */
ruby/internal/intern/variable.h000064400000051474151732674250012625 0ustar00#ifndef RBIMPL_INTERN_VARIABLE_H                     /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_VARIABLE_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Public APIs related to names inside of a Ruby program.
 */
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/st.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/* variable.c */

/**
 * Queries the name of a module.
 *
 * @param[in]  mod        An instance of ::rb_cModule.
 * @retval     RUBY_Qnil  `mod` is anonymous.
 * @retval     otherwise  `mod` is onymous.
 */
VALUE rb_mod_name(VALUE mod);

/**
 * Identical  to  rb_mod_name(),  except   it  returns  `#<Class:  ...>`  style
 * inspection for anonymous modules.
 *
 * @param[in]  mod        An instance of ::rb_cModule.
 * @return     An instance of ::rb_cString representing `mod`'s path.
 */
VALUE rb_class_path(VALUE mod);

/**
 * @alias{rb_mod_name}
 *
 * @internal
 *
 * Am I missing something?  Why we have the same thing in different names?
 */
VALUE rb_class_path_cached(VALUE mod);

RBIMPL_ATTR_NONNULL(())
/**
 * Names a class.
 *
 * @param[out]  klass  Target module to name.
 * @param[out]  space  Namespace that `klass` shall reside.
 * @param[in]   name   Name of `klass`.
 * @post        `klass` has `space::klass` name.
 */
void rb_set_class_path(VALUE klass, VALUE space, const char *name);

/**
 * Identical  to rb_set_class_path(),  except  it accepts  the  name as  Ruby's
 * string instead of C's.
 *
 * @param[out]  klass  Target module to name.
 * @param[out]  space  Namespace that `klass` shall reside.
 * @param[in]   name   Name of `klass`.
 * @post        `klass` has `space::klass` name.
 */
void rb_set_class_path_string(VALUE klass, VALUE space, VALUE name);

/**
 * Identical to  rb_path2class(), except it  accepts the path as  Ruby's string
 * instead of C's.
 *
 * @param[in]  path           Path to query.
 * @exception  rb_eArgError   No such constant.
 * @exception  rb_eTypeError  The path resolved to a non-module.
 * @return     Resolved class.
 */
VALUE rb_path_to_class(VALUE path);

RBIMPL_ATTR_NONNULL(())
/**
 * Resolves a `Q::W::E::R`-style path string to the actual class it points.
 *
 * @param[in]  path           Path to query.
 * @exception  rb_eArgError   No such constant.
 * @exception  rb_eTypeError  The path resolved to a non-module.
 * @return     Resolved class.
 */
VALUE rb_path2class(const char *path);

/**
 * Queries the name of the given object's class.
 *
 * @param[in]  obj  Arbitrary object.
 * @return     An instance of ::rb_cString representing `obj`'s class' path.
 */
VALUE rb_class_name(VALUE obj);

/**
 * Kicks the autoload procedure as if it was "touched".
 *
 * @param[out]  space        Namespace where autoload is defined.
 * @param[in]   name         Name of the autoloaded constant.
 * @retval      RUBY_Qfalse  No such autoload.
 * @retval      RUBY_Qtrue   Autoload successfully initiated.
 * @note        As an  autoloaded library is expected  to define `space::name`,
 *              it is  a nature  of this function  to have  process-global side
 *              effects.
 * @note        Multiple threads  can simultaneously call this  API.  It blocks
 *              then.  That must not last indefinitely but can take longer than
 *              you expect.
 *
 * @internal
 *
 * @shyouhei has no idea why extension libraries should use this API.
 */
VALUE rb_autoload_load(VALUE space, ID name);

/**
 * Queries if an autoload is defined at a point.
 *
 * @param[in]  space      Namespace where autoload is defined.
 * @param[in]  name       Name of the autoloaded constant.
 * @retval     RUBY_Qnil  No such autoload.
 * @retval     otherwise  The feature (path) registered at `space::name`.
 */
VALUE rb_autoload_p(VALUE space, ID name);

/**
 * Traces a global variable.
 *
 * @param[in]  argc        Either 1 or 2.
 * @param[in]  argv        Variable name, optionally a Proc.
 * @retval     RUBY_Qnil   No previous tracers.
 * @retval     otherwise   Previous tracers.
 *
 * @internal
 *
 * @shyouhei has no idea why extension libraries should use this API.
 */
VALUE rb_f_trace_var(int argc, const VALUE *argv);

/**
 * Deletes the  passed tracer from the  passed global variable, or  if omitted,
 * deletes everything.
 *
 * @param[in]  argc        Either 1 or 2.
 * @param[in]  argv        Variable name, optionally a Proc.
 * @retval     RUBY_Qnil   No previous tracers.
 * @retval     otherwise   Deleted tracers.
 *
 * @internal
 *
 * @shyouhei has no idea why extension libraries should use this API.
 */
VALUE rb_f_untrace_var(int argc, const VALUE *argv);

/**
 * Queries the list of global variables.
 *
 * @return  The list of the name of the global variables.
 *
 * @internal
 *
 * Above description is in fact inaccurate.  This API interfaces with Ractors.
 */
VALUE rb_f_global_variables(void);

/**
 * Aliases  a global  variable.   Did you  know  that you  can  alias a  global
 * variable?  It is like aliasing methods:
 *
 * ```ruby
 * alias $dst $src
 * ```
 *
 * This C function does the same thing.
 *
 * @param[in]  dst  Destination name.
 * @param[in]  src  Source name.
 * @post       A global  variable named `dst`  is defined to  be an alias  of a
 *             global variable named `src`.
 *
 * @internal
 *
 * Above description is in fact inaccurate.  This API interfaces with Ractors.
 */
void rb_alias_variable(ID dst, ID src);

/**
 * Frees the list of instance variables.   3rd parties need not know, but there
 * are several ways  to store an object's instance variables,  depending on its
 * internal structure.   This function makes  sense when the passed  objects is
 * using so-called "generic" backend storage.  People need not be aware of this
 * working behind-the-scenes.
 *
 * @param[out]  obj  The object in question.
 *
 * @internal
 *
 * This just  destroys the given object.   @shyouhei has no idea  why extension
 * libraries should use this API.
 */
void rb_free_generic_ivar(VALUE obj);

/**
 * Identical to rb_iv_get(), except it accepts the name as an ::ID instead of a
 * C string.
 *
 * @param[in]  obj        Target object.
 * @param[in]  name       Target instance variable to query.
 * @retval     RUBY_nil   No such instance variable.
 * @retval     otherwise  The value assigned to the instance variable.
 */
VALUE rb_ivar_get(VALUE obj, ID name);

/**
 * Identical to rb_iv_set(), except it accepts the name as an ::ID instead of a
 * C string.
 *
 * @param[out]  obj              Target object.
 * @param[in]   name             Target instance variable.
 * @param[in]   val              Value to assign.
 * @exception   rb_eFrozenError  Can't modify `obj`.
 * @exception   rb_eArgError     `obj` has too many instance variables.
 * @return      Passed value.
 * @post        An  instance variable  named  `name` is  defined  if absent  on
 *              `obj`, whose value is set to `val`.
 */
VALUE rb_ivar_set(VALUE obj, ID name, VALUE val);

/**
 * Queries if  the instance variable  is defined  at the object.   This roughly
 * resembles `defined?(@name)` in `obj`'s context.
 *
 * @param[in]  obj          Target object.
 * @param[in]  name         Target instance variable to query.
 * @retval     RUBY_Qtrue   There is an instance variable.
 * @retval     RUBY_Qfalse  No such instance variable.
 */
VALUE rb_ivar_defined(VALUE obj, ID name);

/**
 * Iterates over an object's instance variables.
 *
 * @param[in]  obj   Target object.
 * @param[in]  func  Callback function.
 * @param[in]  arg   Passed as-is to the last argument of `func`.
 */
void rb_ivar_foreach(VALUE obj, int (*func)(ID name, VALUE val, st_data_t arg), st_data_t arg);

/**
 * Number of instance variables defined on an object.
 *
 * @param[in]  obj   Target object.
 * @return     Number of instance variables defined on `obj`.
 */
st_index_t rb_ivar_count(VALUE obj);

/**
 * Identical to rb_ivar_get()
 *
 * @param[in]  obj        Target object.
 * @param[in]  name       Target instance variable to query.
 * @retval     RUBY_nil   No such instance variable.
 * @retval     otherwise  The value assigned to the instance variable.
 *
 * @internal
 *
 * Am I missing something?  Why we have the same thing in different names?
 */
VALUE rb_attr_get(VALUE obj, ID name);

/**
 * Resembles `Object#instance_variables`.
 *
 * @param[in]  obj  Target object to query.
 * @return     An array of instance variable names for the receiver.
 * @note       Simply defining  an accessor  does not create  the corresponding
 *             instance variable.
 */
VALUE rb_obj_instance_variables(VALUE obj);

/**
 * Resembles `Object#remove_instance_variable`.
 *
 * @param[out]  obj   Target object.
 * @param[in]   name  Variable name to remove, either in Symbol or String.
 * @return      What was removed.
 * @pre         Instance variable named `name` is deleted from `obj`.
 */
VALUE rb_obj_remove_instance_variable(VALUE obj, VALUE name);

/**
 * This API is  mysterious.  It has been there since  the initial revision.  No
 * single bits of  documents has ever been written.  The  function name doesn't
 * describe anything.  What should be passed to the argument, or what should be
 * the  return value,  are not  obvious.  Yet  it has  evolved over  time.  The
 * source code is written in counter-intuitive way (as of 3.0).
 *
 * Simply put, don't try to understand this API.
 */
void *rb_mod_const_at(VALUE, void*);

/**
 * This is a variant of rb_mod_const_at().  As a result, it is also mysterious.
 * It _seems_ it iterates over the ancestry  tree of the module.  But what that
 * means is beyond a human brain.
 */
void *rb_mod_const_of(VALUE, void*);

/**
 * This is  another mysterious  API that  comes with no  documents at  all.  It
 * seems it expects  some specific data structure for the  passed pointer.  But
 * the details has  never been made explicit.  It seems  nobody should use this
 * API.
 */
VALUE rb_const_list(void*);

/**
 * Resembles  `Module#constants`.   List  up   the  constants  defined  at  the
 * receiver.  This  includes the  names of constants  in any  included modules,
 * unless `argv[0]` is ::RUBY_Qfalse.
 *
 * The  implementation  makes  no  guarantees  about the  order  in  which  the
 * constants are yielded.
 *
 * @param[in]  argc  Either 0 or 1.
 * @param[in]  argv  Pointer to ::RUBY_Qfalse, if `argc == 1`.
 * @param[in]  recv  Target namespace.
 * @return     An array of symbols, which are constant names under `recv`.
 */
VALUE rb_mod_constants(int argc, const VALUE *argv, VALUE recv);

/**
 * Resembles `Module#remove_const`.
 *
 * @param[out]  space  Target namespace.
 * @param[in]   name   Variable name to remove, either in Symbol or String.
 * @return      What was removed.
 * @pre         Constant named `space::name` is deleted.
 * @note        In case what was removed was in  fact a module or a class, this
 *              operation does  not affect its  name.  Which means  when people
 *              for instance  look at  it using `p`  etc., it  still introduces
 *              itself using the deleted name.  Can confuse people.
 */
VALUE rb_mod_remove_const(VALUE space, VALUE name);

/**
 * Queries if the constant is defined at the namespace.
 *
 * @param[in]  space        Target namespace.
 * @param[in]  name         Target name to query.
 * @retval     RUBY_Qtrue   There is a constant.
 * @retval     RUBY_Qfalse  No such constant.
 *
 * @internal
 *
 * The return values are not typo!  This function returns ruby values casted to
 * `int`.  Completely brain-damaged design.
 */
int rb_const_defined(VALUE space, ID name);

/**
 * Identical to rb_const_defined(), except it  doesn't look for parent classes.
 * For  instance  `Array`  is  a  toplevel  constant,  which  is  visible  from
 * everywhere.  But this  function does not take such things  into account.  It
 * concerns only what is directly defined inside of the given namespace.
 *
 * @param[in]  space        Target namespace.
 * @param[in]  name         Target name to query.
 * @retval     RUBY_Qtrue   There is a constant.
 * @retval     RUBY_Qfalse  No such constant.
 *
 * @internal
 *
 * The return values are not typo!  This function returns ruby values casted to
 * `int`.  Completely brain-damaged design.
 */
int rb_const_defined_at(VALUE space, ID name);

/**
 * Identical  to  rb_const_defined(),  except  it  returns  false  for  private
 * constants.
 *
 * @param[in]  space        Target namespace.
 * @param[in]  name         Target name to query.
 * @retval     RUBY_Qtrue   There is a constant.
 * @retval     RUBY_Qfalse  No such constant.
 *
 * @internal
 *
 * What does "from" mean?  The name sounds quite cryptic.
 *
 * The return values are not typo!  This function returns ruby values casted to
 * `int`.  Completely brain-damaged design.
 */
int rb_const_defined_from(VALUE space, ID name);

/**
 * Identical to rb_const_defined(), except it returns the actual defined value.
 *
 * @param[in]  space          Target namespace.
 * @param[in]  name           Target name to query.
 * @exception  rb_eNameError  No such constant.
 * @return     The defined constant.
 *
 * @internal
 *
 * Above description is in fact inaccurate.  This API interfaces with Ractors.
 */
VALUE rb_const_get(VALUE space, ID name);

/**
 * Identical  to rb_const_defined_at(),  except it  returns the  actual defined
 * value.  It can also be seen as a routine identical to rb_const_get(), except
 * it doesn't look for parent classes.
 *
 * @param[in]  space          Target namespace.
 * @param[in]  name           Target name to query.
 * @exception  rb_eNameError  No such constant.
 * @return     The defined constant.
 *
 * @internal
 *
 * Above description is in fact inaccurate.  This API interfaces with Ractors.
 */
VALUE rb_const_get_at(VALUE space, ID name);

/**
 * Identical  to rb_const_defined_at(),  except it  returns the  actual defined
 * value.  It can also be seen as a routine identical to rb_const_get(), except
 * it doesn't return a private constant.
 *
 * @param[in]  space          Target namespace.
 * @param[in]  name           Target name to query.
 * @exception  rb_eNameError  No such constant.
 * @return     The defined constant.
 *
 * @internal
 *
 * Above description is in fact inaccurate.  This API interfaces with Ractors.
 */
VALUE rb_const_get_from(VALUE space, ID name);

/**
 * Names a constant.
 *
 * @param[out]  space          Target namespace.
 * @param[in]   name           Target name to query.
 * @param[in]   val            Value to define.
 * @exception   rb_eTypeError  `space` is not a module.
 * @post        `name` is a constant under `space`, whose value is `val`.
 * @note        You can reassign.
 *
 * @internal
 *
 * Above description is in fact inaccurate.  This API interfaces with Ractors.
 */
void rb_const_set(VALUE space, ID name, VALUE val);

/**
 * Identical to rb_mod_remove_const(), except it takes the name as ::ID instead
 * of ::VALUE.
 *
 * @param[out]  space  Target namespace.
 * @param[in]   name   Variable name to remove, either in Symbol or String.
 * @return      What was removed.
 * @pre         Constant named `space::name` is deleted.
 * @note        In case what was removed was in  fact a module or a class, this
 *              operation does  not affect its  name.  Which means  when people
 *              for instance  look at  it using `p`  etc., it  still introduces
 *              itself using the deleted name.  Can confuse people.
 */
VALUE rb_const_remove(VALUE space, ID name);

#if 0 /* EXPERIMENTAL: remove if no problem */
RBIMPL_ATTR_NORETURN()
/**
 * This is the default implementation of `Module#const_missing`.
 *
 * @param[in]  space          Target namespace.
 * @param[in]  name           Target name that is nonexistent.
 * @exception  rb_eNameError  Always.
 */
VALUE rb_mod_const_missing(VALUE space, VALUE name);
#endif

/**
 * Queries if the given class has the given class variable.
 *
 * @param[in]  klass        Target class.
 * @param[in]  name         Name to query.
 * @return     RUBY_Qtrue   Yes there is.
 * @return     RUBY_Qfalse  No there isn't.
 * @pre        `klass` must be an instance of rb_cModule.
 *
 * @internal
 *
 * Above description is in fact inaccurate.  This API interfaces with Ractors.
 */
VALUE rb_cvar_defined(VALUE klass, ID name);

/**
 * Assigns a value to a class variable.
 *
 * @param[out]  klass  Target class.
 * @param[in]   name   Variable name.
 * @param[in]   val    Value to be assigned.
 * @post        `klass` has a class variable named `name` whose value is `val`.
 *
 * @internal
 *
 * Above description is in fact inaccurate.  This API interfaces with Ractors.
 */
void rb_cvar_set(VALUE klass, ID name, VALUE val);

/**
 * Obtains a value from a class variable.
 *
 * @param[in]  klass             Target class.
 * @param[in]  name              Variable name.
 * @exception  rb_eNameError     Uninitialised class variable.
 * @exception  rb_eRuntimeError  `[Bug#14541]` situation.
 * @return     Class variable named `name` under `klass`.
 *
 * @internal
 *
 * Above description is in fact inaccurate.  This API interfaces with Ractors.
 */
VALUE rb_cvar_get(VALUE klass, ID name);

RBIMPL_ATTR_NONNULL(())
/**
 * Identical  to rb_cvar_get(),  except  it takes  additional "front"  pointer.
 * This  extra parameter  is a  buffer,  which will  have the  class where  the
 * queried class variable actually resides.
 *
 * @param[in]   klass             Target class.
 * @param[in]   name              Variable name.
 * @param[out]  front             Return buffer.
 * @exception   rb_eNameError     Uninitialised class variable.
 * @exception   rb_eRuntimeError  `[Bug#14541]` situation.
 * @return      Class variable named `name` under `klass`.
 * @post        `front` has the class object,  which is an ancestor of `klass`,
 *              where the queried class variable actually resides.
 *
 * @internal
 *
 * Above description is in fact inaccurate.  This API interfaces with Ractors.
 */
VALUE rb_cvar_find(VALUE klass, ID name, VALUE *front);

RBIMPL_ATTR_NONNULL(())
/**
 * Identical to rb_cvar_set(), except it accepts C's string instead of ::ID.
 *
 * @param[out]  klass  Target class.
 * @param[in]   name   Variable name.
 * @param[in]   val    Value to be assigned.
 * @post        `klass` has a class variable named `name` whose value is `val`.
 */
void rb_cv_set(VALUE klass, const char *name, VALUE val);

RBIMPL_ATTR_NONNULL(())
/**
 * Identical to rb_cvar_get(), except it accepts C's string instead of ::ID.
 *
 * @param[in]  klass             Target class.
 * @param[in]  name              Variable name.
 * @exception  rb_eNameError     Uninitialised class variable.
 * @exception  rb_eRuntimeError  `[Bug#14541]` situation.
 * @return     Class variable named `name` under `klass`.
 */
VALUE rb_cv_get(VALUE klass, const char *name);

RBIMPL_ATTR_NONNULL(())
/**
 * @alias{rb_cv_set}
 *
 * @internal
 *
 * Am I missing something?  Why we have the same thing in different names?
 */
void rb_define_class_variable(VALUE, const char*, VALUE);

/**
 * Resembles `Module#class_variables`.   List up  the variables defined  at the
 * receiver.  This  includes the  names of constants  in any  included modules,
 * unless `argv[0]` is ::RUBY_Qfalse.
 *
 * The  implementation  makes  no  guarantees  about the  order  in  which  the
 * constants are yielded.
 *
 * @param[in]  argc  Either 0 or 1.
 * @param[in]  argv  Pointer to ::RUBY_Qfalse, if `argc == 1`.
 * @param[in]  recv  Target class.
 * @return     An  array  of symbols,  which  are  class variable  names  under
 *             `recv`.
 */
VALUE rb_mod_class_variables(int argc, const VALUE *argv, VALUE recv);

/**
 * Resembles `Module#remove_class_variable`.
 *
 * @param[out]  mod   Target class.
 * @param[in]   name  Variable name to remove, either in Symbol or String.
 * @return      What was removed.
 * @pre         Instance variable named `name` is deleted from `obj`.
 */
VALUE rb_mod_remove_cvar(VALUE mod, VALUE name);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERN_VARIABLE_H */
ruby/internal/intern/signal.h000064400000014620151732674260012306 0ustar00#ifndef RBIMPL_INTERN_SIGNAL_H                       /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_SIGNAL_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Signal handling APIs.
 */
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/* signal.c */

RBIMPL_ATTR_NONNULL(())
/**
 * Sends a signal ("kills") to processes.
 *
 * The first argument is the signal, either in:
 *
 *   - Numerical representation (e.g. `9`), or
 *   - Textual  representation   of  canonical   (e.g.   `:SIGKILL`)   name  or
 *     abbreviated (e.g. `:KILL`) name, either in ::rb_cSymbol or ::rb_cString.
 *
 * All the  remaining arguments are  numerical representations of  process IDs.
 * This function iterates over them to send the specified signal.
 *
 * You can specify both negative PIDs and negative signo to this function:
 *
 *   ```
 *    sig \ pid | >= 1 | == 0 | == -1 | <= -2
 *   ===========+======+======+=======+=======
 *        > 0   |  #1  |  #2  |  #3   |  #4
 *       == 0   |  #5  |  #6  |  #7   |  #8
 *        < 0   |  #9  |  #10 |      #11
 *   ```
 *
 *   - Case #1: When  signo and PID are both positive,  this function sends the
 *     specified signal to the specified process (intuitive).
 *
 *   - Case #2: When  signo is  positive and PID  is zero, this  function sends
 *     that signal to the current process group.
 *
 *   - Case #3: When signo is positive and  PID is -1, this function sends that
 *     signal to everything that the current process is allowed to kill.
 *
 *   - Case #4: When signo  is positive and PID is negative  (but not -1), this
 *     function sends that signal to every  processes in a process group, whose
 *     process group ID is the absolute value of the passed PID.
 *
 *   - Case #5: When  signo  is zero  and PID is  positive, this  function just
 *     checks  for the  existence of  the  specified process  and doesn't  send
 *     anything to  anyone.  In  case the process  is absent  `Errno::ESRCH` is
 *     raised.
 *
 *   - Case #6: When signo and PID are  both zero, this function checks for the
 *     existence of the current process group.   And it must do.  This function
 *     is effectively a no-op then.
 *
 *   - Case #7: When signo is zero and PID is -1, this function checks if there
 *     is any other  process that the current process can  kill.  At least init
 *     (PID 1) must exist, so this must not fail.
 *
 *   - Case #8: When  signo is  zero and  PID is  negative (but  not -1),  this
 *     function checks  if there is a  process group whose process  group ID is
 *     the absolute  value of  the passed  PID.  In case  the process  group is
 *     absent `Errno::ESRCH` is raised.
 *
 *   - Case #9: When signo is negative and PID is positive, this function sends
 *     the absolute value of the passed signo to the process group specified as
 *     the PID.
 *
 *   - Case #10: When signo is negative and  PID is zero, it is highly expected
 *     that this function  sends the absolute value of the  passed signo to the
 *     current  process   group.   Strictly  speaking,  IEEE   Std  1003.1-2017
 *     specifies that  this (`killpg(3posix)` with  an argument of zero)  is an
 *     undefined behaviour.  But no operating system  is known so far that does
 *     things differently.
 *
 *   - Case #11: When  signo and PID  are both negative, the  behaviour of this
 *     function  depends on  how `killpg(3)`  works.  On  Linux, it  seems such
 *     attempt is  strictly prohibited and  `Errno::EINVAL` is raised.   But on
 *     macOS, it seems it  tries to send the signal  actually to the process
 *     group.
 *
 * @note       Above description is in fact different from how `kill(2)` works.
 *             We interpret the passed arguments before passing them through to
 *             system calls.
 * @param[in]  argc                 Number of objects in `argv`.
 * @param[in]  argv                 Signal, followed by target PIDs.
 * @exception  rb_eArgError         Unknown signal name.
 * @exception  rb_eSystemCallError  Various errors sending signal to processes.
 * @return     Something numeric.  The meaning of this return value is unclear.
 *             It seems in case of #1 above, this could be the body count.  But
 *             other cases remain mysterious.
 */
VALUE rb_f_kill(int argc, const VALUE *argv);

RBIMPL_ATTR_PURE()
/**
 * Queries  the name  of  the signal.   It returns  for  instance `"KILL"`  for
 * SIGKILL.
 *
 * @param[in]  signo      Signal number to query.
 * @retval     0          No such signal.
 * @retval     otherwise  A pointer  to a static C  string that is the  name of
 *                        the signal.
 * @warning    Don't free the return value.
 */
const char *ruby_signal_name(int signo);

/**
 * Pretends as if  there was no custom signal handler.   This function sets the
 * signal action to SIG_DFL, then kills itself.
 *
 * @param[in]  sig  The signal.
 * @post       Previous signal handler is lost.
 * @post       Passed signal is sent to the current process.
 *
 * @internal
 *
 * @shyouhei doesn't understand  the needs of this function  being visible from
 * extension libraries.
 */
void ruby_default_signal(int sig);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERN_SIGNAL_H */
ruby/internal/intern/range.h000064400000007747151732674260012141 0ustar00#ifndef RBIMPL_INTERN_RANGE_H                        /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_RANGE_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Public APIs related to ::rb_cRange.
 */
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/* range.c */

/**
 * Creates a new Range.
 *
 * @param[in]  beg           "Left" or "lowest" endpoint of the range.
 * @param[in]  end           "Right" or "highest" endpoint of the range.
 * @param[in]  excl          Whether the range is open-ended.
 * @exception  rb_eArgError  `beg` and `end` are not comparable.
 * @note       These days both  endpoints can be ::RUBY_Qnil,  which means that
 *             endpoint is unbound.
 */
VALUE rb_range_new(VALUE beg, VALUE end, int excl);

RBIMPL_ATTR_NONNULL(())
/**
 * Deconstructs  a numerical  range.  As  the  arguments are  `long` based,  it
 * expects everything are in the `long` domain.
 *
 * @param[in]   range           A range of numerical endpoints.
 * @param[out]  begp            Return value buffer.
 * @param[out]  lenp            Return value buffer.
 * @param[in]   len             Updated length.
 * @param[in]   err             In case `len` is out of range...
 *                                - `0`: returns ::RUBY_Qnil.
 *                                - `1`: raises  ::rb_eRangeError.
 *                                - `2`: `beg` and `len` expanded accordingly.
 * @exception   rb_eTypeError   `range` is not a numerical range.
 * @exception   rb_eRangeError  `range` cannot fit into `long`.
 * @retval      RUBY_Qfalse     `range` is not an ::rb_cRange.
 * @retval      RUBY_Qnil       `len` is out of `range` but `err` is zero.
 * @retval      RUBY_Qtrue      Otherwise.
 * @post        `beg` is the (possibly updated) left endpoint.
 * @post        `len` is the (possibly updated) length of the range.
 *
 * @internal
 *
 * The complex  error handling  switch reflects the  fact that  `Array#[]=` and
 * `String#[]=` behave differently when they take ranges.
 */
VALUE rb_range_beg_len(VALUE range, long *begp, long *lenp, long len, int err);

RBIMPL_ATTR_NONNULL(())
/**
 * Deconstructs a range into its components.
 *
 * @param[in]   range        Range or range-ish object.
 * @param[out]  begp         Return value buffer.
 * @param[out]  endp         Return value buffer.
 * @param[out]  exclp        Return value buffer.
 * @retval      RUBY_Qfalse  `range` is not an instance of ::rb_cRange.
 * @retval      RUBY_Qtrue   Argument pointers are updated.
 * @post        `*begp` is the left endpoint of the range.
 * @post        `*endp` is the right endpoint of the range.
 * @post        `*exclp` is whether the range is open-ended or not.
 */
int rb_range_values(VALUE range, VALUE *begp, VALUE *endp, int *exclp);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERN_RANGE_H */
ruby/internal/intern/random.h000064400000010460151732674260012307 0ustar00#ifndef RBIMPL_INTERN_RANDOM_H                       /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_RANDOM_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      MT19937 backended pseudo random number generator.
 * @see        Matsumoto,  M.,   Nishimura,  T.,  "Mersenne  Twister:   A  623-
 *             dimensionally   equidistributed   uniform  pseudorandom   number
 *             generator", ACM  Trans. on  Modeling and Computer  Simulation, 8
 *             (1): pp 3-30, 1998.  https://doi.org/10.1145/272991.272995
 */
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/* random.c */

/**
 * Generates a 32 bit random number.
 *
 * @return  A random number.
 * @note    Now  that  we  have  ractors,  the  RNG  behind  this  function  is
 *          per-ractor.
 */
unsigned int rb_genrand_int32(void);

/**
 * Generates a `double` random number.
 *
 * @return  A random number.
 * @note    This function shares the RNG with rb_genrand_int32().
 */
double rb_genrand_real(void);

/**
 * Resets the RNG behind rb_genrand_int32()/rb_genrand_real().
 *
 * @post  The (now per-ractor) default RNG's internal state is cleared.
 */
void rb_reset_random_seed(void);

/**
 * Generates a String of random bytes.
 *
 * @param[in,out]  rnd  An instance of ::rb_cRandom.
 * @param[in]      n    Requested number of bytes.
 * @return         An instance of ::rb_cString, of binary, of `n` bytes length,
 *                 whose contents are random bits.
 *
 * @internal
 *
 * @shyouhei doesn't know if this is an  Easter egg or an official feature, but
 * this function can  take a wider range of objects,  such as `Socket::Ifaddr`.
 * The arguments are just silently ignored and the default RNG is used instead,
 * if they are non-RNG.
 */
VALUE rb_random_bytes(VALUE rnd, long n);

/**
 * Identical to rb_genrand_int32(), except it generates using the passed RNG.
 *
 * @param[in,out]  rnd  An instance of ::rb_cRandom.
 * @return         A random number.
 */
unsigned int rb_random_int32(VALUE rnd);

/**
 * Identical to rb_genrand_real(), except it generates using the passed RNG.
 *
 * @param[in,out]  rnd  An instance of ::rb_cRandom.
 * @return         A random number.
 */
double rb_random_real(VALUE rnd);

/**
 * Identical  to  rb_genrand_ulong_limited(),  except it  generates  using  the
 * passed RNG.
 *
 * @param[in,out]  rnd    An instance of ::rb_cRandom.
 * @param[in]      limit  Max possible return value.
 * @return         A random number, distributed in `[0, limit]` interval.
 * @note           Note it can return `limit`.
 * @note           Whether  the  return  value  distributes  uniformly  in  the
 *                 interval or not depends on  how the argument RNG behaves; at
 *                 least in case of MT19937 it does.
 */
unsigned long rb_random_ulong_limited(VALUE rnd, unsigned long limit);

/**
 * Generates a random number whose upper limit is `i`.
 *
 * @param[in]  i  Max possible return value.
 * @return     A random number, uniformly distributed in `[0, limit]` interval.
 * @note       Note it can return `i`.
 */
unsigned long rb_genrand_ulong_limited(unsigned long i);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERN_RANDOM_H */
ruby/internal/intern/class.h000064400000037315151732674260012144 0ustar00#ifndef RBIMPL_INTERN_CLASS_H                        /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_CLASS_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Public APIs related to ::rb_cClass/::rb_cModule.
 */
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/backward/2/stdarg.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/* class.c */

/**
 * Creates a new, anonymous class.
 *
 * @param[in]  super          What would become a parent class.
 * @exception  rb_eTypeError  `super` is not something inheritable.
 * @return     An anonymous class that inherits `super`.
 */
VALUE rb_class_new(VALUE super);

/**
 * The comment  that comes with  this function  says `:nodoc:`.  Not  sure what
 * that means though.
 *
 * @param[out]  clone          Destination object.
 * @param[in]   orig           Source object.
 * @exception   rb_eTypeError  Cannot copy `orig`.
 * @return      The passed `clone`.
 */
VALUE rb_mod_init_copy(VALUE clone, VALUE orig);

/**
 * Asserts that  the given class  can derive a child  class.  A class  might or
 * might not be able to do so; for instance a singleton class cannot.
 *
 * @param[in]  super          Possible super class.
 * @exception  rb_eTypeError  No it cannot.
 * @post       Upon successful return `super` can derive.
 */
void rb_check_inheritable(VALUE super);

/**
 * This is a very badly designed API that creates an anonymous class.
 *
 * @param[in]  id             Discarded for no reason (why...).
 * @param[in]  super          What  would  become  a  parent  class.   0  means
 *                            ::rb_cObject.
 * @exception  rb_eTypeError  `super` is not something inheritable.
 * @return     An anonymous class that inherits `super`.
 * @warning    You must explicitly name the return value.
 */
VALUE rb_define_class_id(ID id, VALUE super);

/**
 * Identical  to rb_define_class_under(),  except  it takes  the  name in  ::ID
 * instead of C's string.
 *
 * @param[out]  outer          A class which contains the new class.
 * @param[in]   id             Name of the new class
 * @param[in]   super          A class from which the new class will derive.
 *                             0 means ::rb_cObject.
 * @exception   rb_eTypeError  The constant name `id`  is already taken but the
 *                             constant is not a class.
 * @exception   rb_eTypeError  The class  is already defined but  the class can
 *                             not be  reopened because  its superclass  is not
 *                             `super`.
 * @exception   rb_eArgError   `super` is NULL.
 * @return      The created class.
 * @post        `outer::id` refers the returned class.
 * @note        If a class named `id` is  already defined and its superclass is
 *              `super`, the function just returns the defined class.
 * @note        The GC does not collect nor move classes returned by this
 *              function. They are immortal.
 */
VALUE rb_define_class_id_under(VALUE outer, ID id, VALUE super);

/**
 * Creates a new, anonymous module.
 *
 * @return An anonymous module.
 */
VALUE rb_module_new(void);


/**
 * Creates a new, anonymous refinement.
 *
 * @return An anonymous refinement.
 */
VALUE rb_refinement_new(void);

/**
 * This is a very badly designed API that creates an anonymous module.
 *
 * @param[in]  id  Discarded for no reason (why...).
 * @return     An anonymous module.
 * @warning    You must explicitly name the return value.
 */
VALUE rb_define_module_id(ID id);

/**
 * Identical  to rb_define_module_under(),  except it  takes the  name in  ::ID
 * instead of C's string.
 *
 * @param[out]  outer          A class which contains the new module.
 * @param[in]   id             Name of the new module
 * @exception   rb_eTypeError  The constant name `id`  is already taken but the
 *                             constant is not a module.
 * @return      The created module.
 * @post        `outer::id` refers the returned module.
 * @note        The GC does not collect nor move classes returned by this
 *              function. They are immortal.
 */
VALUE rb_define_module_id_under(VALUE outer, ID id);

/**
 * Queries the list of  included modules.  It can also be seen  as a routine to
 * first  call rb_mod_ancestors(),  then  rejects non-modules  from the  return
 * value.
 *
 * @param[in]  mod  Class or Module.
 * @return     An array of modules that are either included or prepended in any
 *             of `mod`'s ancestry tree (including itself).
 */
VALUE rb_mod_included_modules(VALUE mod);

/**
 * Queries if the passed module is included by the module.  It can also be seen
 * as a routine to first call rb_mod_included_modules(), then see if the return
 * value contains the passed module.
 *
 * @param[in]  child          A Module.
 * @param[in]  parent         Another Module.
 * @exception  rb_eTypeError  `child` is not an instance of ::rb_cModule.
 * @retval     RUBY_Qtrue     `parent` is  either included or prepended  in any
 *                            of `child`'s ancestry tree (including itself).
 * @return     RUBY_Qfalse    Otherwise.
 */
VALUE rb_mod_include_p(VALUE child, VALUE parent);

/**
 * Queries the  module's ancestors.  This routine gathers classes  and modules
 * that  the  passed  module  either  inherits,  includes,  or  prepends,  then
 * recursively applies  that routine again  and again to the  collected entries
 * until the list doesn't grow up.
 *
 * @param[in]  mod  A module or a class.
 * @return     An array of  classes or modules that  `mod` possibly recursively
 *             inherits, includes, or prepends.
 *
 * @internal
 *
 * Above description  is written  in a  recursive language  but in  practice it
 * computes the return value iteratively.
 */
VALUE rb_mod_ancestors(VALUE mod);

/**
 * Queries the class's descendants. This  routine gathers classes that are
 * subclasses of the given class (or subclasses of those subclasses, etc.),
 * returning an array of classes that have the given class as an ancestor.
 * The returned array does not include the given class or singleton classes.
 *
 * @param[in]  klass A class.
 * @return     An array of classes where `klass` is an ancestor.
 *
 * @internal
 */
VALUE rb_class_descendants(VALUE klass);

/**
 * Queries the class's direct descendants. This  routine gathers classes that are
 * direct subclasses of the given class,
 * returning an array of classes that have the given class as a superclass.
 * The returned array does not include singleton classes.
 *
 * @param[in]  klass A class.
 * @return     An array of classes where `klass` is the `superclass`.
 *
 * @internal
 */
VALUE rb_class_subclasses(VALUE klass);


/**
 *  Returns the attached object for a singleton class.
 *  If the given class is not a singleton class, raises a TypeError.
 *
 * @param[in]  klass A class.
 * @return     The object which has the singleton class `klass`.
 *
 * @internal
 */
VALUE rb_class_attached_object(VALUE klass);

/**
 * Generates an array of symbols, which are the list of method names defined in
 * the passed class.
 *
 * @param[in]  argc          Number of objects of `argv`.
 * @param[in]  argv          Array of  at most  one object, which  controls (if
 *                           any) whether  the return array includes  the names
 *                           of methods defined in ancestors or not.
 * @param[in]  mod           A module or a class.
 * @exception  rb_eArgError  `argc` out of range.
 * @return     An array  of symbols collecting  names of instance  methods that
 *             are not private, defined at `mod`.
 */
VALUE rb_class_instance_methods(int argc, const VALUE *argv, VALUE mod);

/**
 * Identical to rb_class_instance_methods(), except it returns names of methods
 * that are public only.
 *
 * @param[in]  argc          Number of objects of `argv`.
 * @param[in]  argv          Array of  at most  one object, which  controls (if
 *                           any) whether  the return array includes  the names
 *                           of methods defined in ancestors or not.
 * @param[in]  mod           A module or a class.
 * @exception  rb_eArgError  `argc` out of range.
 * @return     An array  of symbols collecting  names of instance  methods that
 *             are public, defined at `mod`.
 */
VALUE rb_class_public_instance_methods(int argc, const VALUE *argv, VALUE mod);

/**
 * Identical to rb_class_instance_methods(), except it returns names of methods
 * that are protected only.
 *
 * @param[in]  argc          Number of objects of `argv`.
 * @param[in]  argv          Array of  at most  one object, which  controls (if
 *                           any) whether  the return array includes  the names
 *                           of methods defined in ancestors or not.
 * @param[in]  mod           A module or a class.
 * @exception  rb_eArgError  `argc` out of range.
 * @return     An array  of symbols collecting  names of instance  methods that
 *             are protected, defined at `mod`.
 */
VALUE rb_class_protected_instance_methods(int argc, const VALUE *argv, VALUE mod);

/**
 * Identical to rb_class_instance_methods(), except it returns names of methods
 * that are private only.
 *
 * @param[in]  argc          Number of objects of `argv`.
 * @param[in]  argv          Array of  at most  one object, which  controls (if
 *                           any) whether  the return array includes  the names
 *                           of methods defined in ancestors or not.
 * @param[in]  mod           A module or a class.
 * @exception  rb_eArgError  `argc` out of range.
 * @return     An array  of symbols collecting  names of instance  methods that
 *             are protected, defined at `mod`.
 */
VALUE rb_class_private_instance_methods(int argc, const VALUE *argv, VALUE mod);

/**
 * Identical  to  rb_class_instance_methods(),  except   it  returns  names  of
 * singleton methods instead of instance methods.
 *
 * @param[in]  argc          Number of objects of `argv`.
 * @param[in]  argv          Array of  at most  one object, which  controls (if
 *                           any) whether  the return array includes  the names
 *                           of methods defined in ancestors or not.
 * @param[in]  obj           Arbitrary ruby object.
 * @exception  rb_eArgError  `argc` out of range.
 * @return     An array  of symbols collecting  names of instance  methods that
 *             are not private, defined at the singleton class of `obj`.
 */
VALUE rb_obj_singleton_methods(int argc, const VALUE *argv, VALUE obj);

/**
 * Identical to rb_define_method(),  except it takes the name of  the method in
 * ::ID instead of C's string.
 *
 * @param[out]  klass  A module or a class.
 * @param[in]   mid    Name of the function.
 * @param[in]   func   The method body.
 * @param[in]   arity  The number of parameters.  See @ref defmethod.
 * @note        There are in fact 18 different prototypes for func.
 * @see         ::ruby::backward::cxxanyargs::define_method::rb_define_method_id
 */
void rb_define_method_id(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int arity);

/* vm_method.c */

/**
 * Inserts a  method entry that hides  previous method definition of  the given
 * name.  This is not a deletion of  a method.  Method of the same name defined
 * in a parent class is kept invisible in this way.
 *
 * @param[out]  mod              The module to insert an undef.
 * @param[in]   mid              Name of the undef.
 * @exception   rb_eTypeError    `klass` is a non-module.
 * @exception   rb_eFrozenError  `klass` is frozen.
 * @exception   rb_eNameError    No such method named `klass#name`.
 * @post        `klass#name` is undefined.
 * @see         rb_undef_method
 *
 * @internal
 *
 * @shyouhei doesn't  understand why this  is not  the ::ID -taking  variant of
 * rb_undef_method(), given rb_remove_method() has its ::ID -taking counterpart
 * named rb_remove_method_id().
 */
void rb_undef(VALUE mod, ID mid);

/* class.c */

RBIMPL_ATTR_NONNULL(())
/**
 * Identical to rb_define_method(), except it defines a protected method.
 *
 * @param[out]  klass  A module or a class.
 * @param[in]   mid    Name of the function.
 * @param[in]   func   The method body.
 * @param[in]   arity  The number of parameters.  See @ref defmethod.
 * @note        There are in fact 18 different prototypes for func.
 * @see         ::ruby::backward::cxxanyargs::define_method::rb_define_protected_method
 */
void rb_define_protected_method(VALUE klass, const char *mid, VALUE (*func)(ANYARGS), int arity);

RBIMPL_ATTR_NONNULL(())
/**
 * Identical to rb_define_method(), except it defines a private method.
 *
 * @param[out]  klass  A module or a class.
 * @param[in]   mid    Name of the function.
 * @param[in]   func   The method body.
 * @param[in]   arity  The number of parameters.  See @ref defmethod.
 * @note        There are in fact 18 different prototypes for func.
 * @see         ::ruby::backward::cxxanyargs::define_method::rb_define_protected_method
 */
void rb_define_private_method(VALUE klass, const char *mid, VALUE (*func)(ANYARGS), int arity);

RBIMPL_ATTR_NONNULL(())
/**
 * Identical to rb_define_method(), except it defines a singleton method.
 *
 * @param[out]  obj    Arbitrary ruby object.
 * @param[in]   mid    Name of the function.
 * @param[in]   func   The method body.
 * @param[in]   arity  The number of parameters.  See @ref defmethod.
 * @note        There are in fact 18 different prototypes for func.
 * @see         ::ruby::backward::cxxanyargs::define_method::rb_define_singleton_method
 */
void rb_define_singleton_method(VALUE obj, const char *mid, VALUE(*func)(ANYARGS), int arity);

/**
 * Finds or creates the singleton class of the passed object.
 *
 * @param[out]  obj            Arbitrary ruby object.
 * @exception   rb_eTypeError  `obj` cannot have its singleton class.
 * @return      A (possibly newly allocated) instance of ::rb_cClass.
 * @post        `obj` has its singleton class, which is the return value.
 * @post        In case `obj` is a class, the returned singleton class also has
 *              its own  singleton class  in order to  keep consistency  of the
 *              inheritance structure of metaclasses.
 * @note        A new  singleton class will  be created  if `obj` did  not have
 *              one.
 * @note        The  singleton  classes   for  ::RUBY_Qnil,  ::RUBY_Qtrue,  and
 *              ::RUBY_Qfalse   are    ::rb_cNilClass,   ::rb_cTrueClass,   and
 *              ::rb_cFalseClass respectively.
 *
 * @internal
 *
 * You can _create_ a singleton class of a frozen object.  Intentional or ...?
 *
 * Nowadays there are wider range of  objects who cannot have singleton classes
 * than before.  For instance some string instances cannot for some reason.
 */
VALUE rb_singleton_class(VALUE obj);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERN_CLASS_H */
ruby/internal/intern/ruby.h000064400000005440151732674260012012 0ustar00#ifndef RBIMPL_INTERN_RUBY_H                         /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_RUBY_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Process-global APIs.
 */
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/* ruby.c */
/** @alias{rb_get_argv} */
#define rb_argv rb_get_argv()

/**
 * The value of `$0` at process bootup.
 *
 * @note  This is just a snapshot of `$0`, not the backend storage of it.  `$0`
 *        could  become something  different because  it is  a writable  global
 *        variable.  Modifying  it for instance affects  `ps(1)` output.  Don't
 *        assume they are synced.
 */
RUBY_EXTERN VALUE rb_argv0;

/* io.c */

/**
 * Queries the arguments passed to the current process that you can access from
 * Ruby as `ARGV`.
 *
 * @return  An array of strings containing arguments passed to the process.
 */
VALUE rb_get_argv(void);

/* ruby.c */

RBIMPL_ATTR_NONNULL(())
/**
 * Loads the given  file.  This function opens the given  pathname for reading,
 * parses the contents as a Ruby  script, and returns an opaque "node" pointer.
 * You can then pass it to ruby_run_node() for evaluation.
 *
 * @param[in]  file  File name, or "-" to read from stdin.
 * @return     Opaque "node" pointer.
 */
void *rb_load_file(const char *file);

/**
 * Identical to rb_load_file(), except it takes the argument as a Ruby's string
 * instead of C's.
 *
 * @param[in]  file  File name, or "-" to read from stdin.
 * @return     Opaque "node" pointer.
 */
void *rb_load_file_str(VALUE file);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERN_RUBY_H */
ruby/internal/intern/proc.h000064400000033044151732674260011775 0ustar00#ifndef RBIMPL_INTERN_PROC_H                         /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_PROC_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Public APIs related to ::rb_cProc.
 */
#include "ruby/internal/dllexport.h"
#include "ruby/internal/iterator.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/* proc.c */

/**
 * Constructs a  Proc object  from implicitly passed  components.  When  a ruby
 * method is  called with a block,  that block is not  explicitly passed around
 * using C level function parameters.   This function gathers all the necessary
 * info to turn them into a Ruby level instance of ::rb_cProc.
 *
 * @exception  rb_eArgError  There is no passed block.
 * @return     An instance of ::rb_cProc.
 */
VALUE rb_block_proc(void);

/**
 * Identical to rb_proc_new(), except it returns a lambda.
 *
 * @exception  rb_eArgError  There is no passed block.
 * @return     An instance of ::rb_cProc.
 */
VALUE rb_block_lambda(void);

/**
 * This is an rb_iterate() + rb_block_proc() combo.
 *
 * ```CXX
 * VALUE
 * my_own_iterator(RB_BLOCK_CALL_FUNC_ARGLIST(y, c))
 * {
 *     const auto plus = rb_intern("+");
 *     return rb_funcall(c, plus, 1, y);
 * }
 *
 * VALUE
 * my_own_method(VALUE self)
 * {
 *     return rb_proc_new(my_own_iterator, self);
 * }
 * ```
 *
 * @param[in]  func          A backend function of a proc.
 * @param[in]  callback_arg  Passed to `func`'s callback_arg.
 * @return     A C-backended proc object.
 *
 */
VALUE rb_proc_new(rb_block_call_func_t func, VALUE callback_arg);

/**
 * Queries if the given object is a proc.
 *
 * @note       This is about the object's data structure, not its class etc.
 * @param[in]  recv         Object in question.
 * @retval     RUBY_Qtrue   It is a proc.
 * @retval     RUBY_Qfalse  Otherwise.
 */
VALUE rb_obj_is_proc(VALUE recv);

/**
 * Evaluates the passed proc with the passed arguments.
 *
 * @param[in]  recv           The proc to call.
 * @param[in]  args           An instance of ::RArray which is the arguments.
 * @exception  rb_eException  Any exceptions happen inside.
 * @return     What the proc evaluates to.
 */
VALUE rb_proc_call(VALUE recv, VALUE args);

/**
 * Identical to rb_proc_call(),  except you can specify how to  handle the last
 * element of the given array.
 *
 * @param[in]  recv             The proc to call.
 * @param[in]  args             An instance of ::RArray which is the arguments.
 * @param[in]  kw_splat         Handling of keyword parameters:
 *   - RB_NO_KEYWORDS           `args`' last is not a keyword argument.
 *   - RB_PASS_KEYWORDS         `args`' last is a keyword argument.
 *   - RB_PASS_CALLED_KEYWORDS  it depends if there is a passed block.
 * @exception  rb_eException    Any exceptions happen inside.
 * @return     What the proc evaluates to.
 */
VALUE rb_proc_call_kw(VALUE recv, VALUE args, int kw_splat);

/**
 * Identical to rb_proc_call(),  except you can additionally  pass another proc
 * object, as a block.  Nowadays procs can take blocks:
 *
 * ```ruby
 * l = -> (positional, optional=nil, *rest, kwarg:, **kwrest, &block) {
 *   #                   ... how can we pass this `&block`?   ^^^^^^
 * }
 * ```
 *
 * And this function is to pass one to such procs.
 *
 * @param[in]  recv           The proc to call.
 * @param[in]  argc           Number of arguments.
 * @param[in]  argv           Arbitrary number of proc arguments.
 * @param[in]  proc           Proc as a passed block.
 * @exception  rb_eException  Any exceptions happen inside.
 * @return     What the proc evaluates to.
 */
VALUE rb_proc_call_with_block(VALUE recv, int argc, const VALUE *argv, VALUE proc);

/**
 * Identical to rb_proc_call_with_block(), except you can specify how to handle
 * the last  element of  the given  array.  It can  also be  seen as  a routine
 * identical  to rb_proc_call_kw(),  except you  can additionally  pass another
 * proc object as a block.
 *
 * @param[in]  recv             The proc to call.
 * @param[in]  argc             Number of arguments.
 * @param[in]  argv             Arbitrary number of proc arguments.
 * @param[in]  proc             Proc as a passed block.
 * @param[in]  kw_splat         Handling of keyword parameters:
 *   - RB_NO_KEYWORDS           `args`' last is not a keyword argument.
 *   - RB_PASS_KEYWORDS         `args`' last is a keyword argument.
 *   - RB_PASS_CALLED_KEYWORDS  it depends if there is a passed block.
 * @exception  rb_eException    Any exceptions happen inside.
 * @return     What the proc evaluates to.
 */
VALUE rb_proc_call_with_block_kw(VALUE recv, int argc, const VALUE *argv, VALUE proc, int kw_splat);

/**
 * Queries the number  of mandatory arguments of the given  Proc.  If its block
 * is declared  to take no  arguments, returns `0`.  If  the block is  known to
 * take  exactly  `n`  arguments,  returns  `n`.  If  the  block  has  optional
 * arguments, returns `-n-1`,  where `n` is the number  of mandatory arguments,
 * with the exception  for blocks that are  not lambdas and have  only a finite
 * number of  optional arguments;  in this latter  case, returns  `n`.  Keyword
 * arguments will be considered as  a single additional argument, that argument
 * being mandatory if any keyword argument is mandatory.
 *
 * @param[in]  recv  Target Proc object.
 * @retval     0     It takes no arguments.
 * @retval     >0    It takes exactly this number of arguments.
 * @retval     <0    It takes optional arguments.
 */
int rb_proc_arity(VALUE recv);

/**
 * Queries if the given object is a lambda.  Instances of ::rb_cProc are either
 * lambda  or  proc.   They  differ  in  several  points.   This  function  can
 * distinguish them without actually evaluating their contents.
 *
 * @param[in]  recv         Target proc object.
 * @retval     RUBY_Qtrue   It is a lambda.
 * @retval     RUBY_Qfalse  Otherwise.
 */
VALUE rb_proc_lambda_p(VALUE recv);

/**
 * Snapshots the  current execution  context and  turn it  into an  instance of
 * ::rb_cBinding.
 *
 * @return  An instance of ::rb_cBinding.
 */
VALUE rb_binding_new(void);

/**
 * Creates a method object.  A method object is a proc-like object that you can
 * "call".  Note  that a  method object  snapshots the method  at the  time the
 * object is created:
 *
 * ```ruby
 * class Foo
 *   def foo
 *     return 1
 *   end
 * end
 *
 * obj = Foo.new.method(:foo)
 *
 * class Foo
 *   def foo
 *     return 2
 *   end
 * end
 *
 * obj.call # => 1, not 2.
 * ```
 *
 * @param[in]  recv               Receiver of the method.
 * @param[in]  mid                Method name, in either String or Symbol.
 * @exception  rb_eNoMethodError  No such method.
 * @return     An instance of ::rb_cMethod.
 */
VALUE rb_obj_method(VALUE recv, VALUE mid);

/**
 * Queries if the given object is a method.
 *
 * @note       This is about the object's data structure, not its class etc.
 * @param[in]  recv         Object in question.
 * @retval     RUBY_Qtrue   It is a method.
 * @retval     RUBY_Qfalse  Otherwise.
 */
VALUE rb_obj_is_method(VALUE recv);

/**
 * Evaluates the passed method with the passed arguments.
 *
 * @param[in]  argc           Number of objects of `argv`.
 * @param[in]  argv           Arbitrary number of method arguments.
 * @param[in]  recv           The method object to call.
 * @exception  rb_eTypeError  `recv` is not a method.
 * @exception  rb_eException  Any exceptions happen inside.
 * @return     What the method returns.
 */
VALUE rb_method_call(int argc, const VALUE *argv, VALUE recv);

/**
 * Identical to rb_method_call(), except you can specify how to handle the last
 * element of the given array.
 *
 * @param[in]  argc             Number of objects of `argv`.
 * @param[in]  argv             Arbitrary number of method arguments.
 * @param[in]  recv             The method object to call.
 * @param[in]  kw_splat         Handling of keyword parameters:
 *   - RB_NO_KEYWORDS           `args`' last is not a keyword argument.
 *   - RB_PASS_KEYWORDS         `args`' last is a keyword argument.
 *   - RB_PASS_CALLED_KEYWORDS  it depends if there is a passed block.
 * @exception  rb_eTypeError    `recv` is not a method.
 * @exception  rb_eException    Any exceptions happen inside.
 * @return     What the method returns.
 */
VALUE rb_method_call_kw(int argc, const VALUE *argv, VALUE recv, int kw_splat);

/**
 * Identical to  rb_proc_call(), except you can  additionally pass a proc  as a
 * block.
 *
 * @param[in]  argc           Number of objects of `argv`.
 * @param[in]  argv           Arbitrary number of method arguments.
 * @param[in]  recv           The method object to call.
 * @param[in]  proc           Proc as a passed block.
 * @exception  rb_eTypeError  `recv` is not a method.
 * @exception  rb_eException  Any exceptions happen inside.
 * @return     What the method returns.
 */
VALUE rb_method_call_with_block(int argc, const VALUE *argv, VALUE recv, VALUE proc);

/**
 * Identical  to rb_method_call_with_block(),  except  you can  specify how  to
 * handle  the last  element of  the given  array.  It  can also  be seen  as a
 * routine identical  to rb_method_call_kw(), except you  can additionally pass
 * another proc object as a block.
 *
 * @param[in]  argc             Number of objects of `argv`.
 * @param[in]  argv             Arbitrary number of method arguments.
 * @param[in]  recv             The method object to call.
 * @param[in]  proc             Proc as a passed block.
 * @param[in]  kw_splat         Handling of keyword parameters:
 *   - RB_NO_KEYWORDS           `args`' last is not a keyword argument.
 *   - RB_PASS_KEYWORDS         `args`' last is a keyword argument.
 *   - RB_PASS_CALLED_KEYWORDS  it depends if there is a passed block.
 * @exception  rb_eTypeError    `recv` is not a method.
 * @exception  rb_eException    Any exceptions happen inside.
 * @return     What the method returns.
 */
VALUE rb_method_call_with_block_kw(int argc, const VALUE *argv, VALUE recv, VALUE proc, int kw_splat);

/**
 * Queries the number of mandatory arguments of the method defined in the given
 * module.  If it is  declared to take no arguments, returns  `0`.  If it takes
 * exactly `n` arguments,  returns `n`.  If it has  optional arguments, returns
 * `-n-1`, where `n`  is the number of mandatory  arguments.  Keyword arguments
 * will  be considered  as a  single additional  argument, that  argument being
 * mandatory if any keyword argument is mandatory.
 *
 * @param[in]  mod   Namespace to search a method for.
 * @param[in]  mid   Method id.
 * @retval     0     It takes no arguments.
 * @retval     >0    It takes exactly this number of arguments.
 * @retval     <0    It takes optional arguments.
 */
int rb_mod_method_arity(VALUE mod, ID mid);

/**
 * Identical to rb_mod_method_arity(), except it searches for singleton methods
 * rather than instance methods.
 *
 * @param[in]  obj   Object to search for a singleton method.
 * @param[in]  mid   Method id.
 * @retval     0     It takes no arguments.
 * @retval     >0    It takes exactly this number of arguments.
 * @retval     <0    It takes optional arguments.
 */
int rb_obj_method_arity(VALUE obj, ID mid);

/* eval.c */

RBIMPL_ATTR_NONNULL((1))
/**
 * Protects a  function call from  potential global escapes from  the function.
 * Such global escapes include exceptions, `throw`, `break`, for example.
 *
 * It first calls the function func with  `args` as the argument.  If no global
 * escape occurred during  the function, it returns the result  and `*state` is
 * zero.  Otherwise, it  returns ::RUBY_Qnil and sets `*state`  to nonzero.  If
 * `state` is `NULL`, it is not set in both cases.
 *
 * @param[in]   func   A function that potentially escapes globally.
 * @param[in]   args   Passed as-is to `func`.
 * @param[out]  state  State of execution.
 * @return      What  `func` returns,  or an  undefined value  when it  did not
 *              return.
 * @post        `*state` is set to zero if succeeded.  Nonzero otherwise.
 * @warning     You have to clear the error info with `rb_set_errinfo(Qnil)` if
 *              you decide to ignore the caught exception.
 * @see         rb_eval_string_protect()
 * @see         rb_load_protect()
 *
 * @internal
 *
 * The "undefined value"  described above is in fact ::RUBY_Qnil  for now.  But
 * @shyouhei doesn't think that we would never change that.
 *
 * Though   not  a   part  of   our  public   API,  `state`   is  in   fact  an
 * enum ruby_tag_type.  You can  see the potential "nonzero"  values by looking
 * at vm_core.h.
 */
VALUE rb_protect(VALUE (*func)(VALUE args), VALUE args, int *state);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERN_PROC_H */
ruby/internal/intern/sprintf.h000064400000014504151732674260012517 0ustar00#ifndef RBIMPL_INTERN_SPRINTF_H                      /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_SPRINTF_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Our own private `printf(3)`.
 */
#include "ruby/internal/attr/format.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/* sprintf.c */

/**
 * Identical to rb_str_format(), except how the arguments are arranged.
 *
 * @param[in]  argc  Number of objects of `argv`.
 * @param[in]  argv  A format string, followed by its arguments.
 * @return     A rendered new instance of ::rb_cString.
 *
 * @internal
 *
 * You can safely pass NULL to `argv`.  Doesn't make any sense though.
 */
VALUE rb_f_sprintf(int argc, const VALUE *argv);

RBIMPL_ATTR_NONNULL((1))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 1, 2)
/**
 * Ruby's extended `sprintf(3)`.   We ended up reinventing  the entire `printf`
 * business because we  don't want to depend on  locales.  OS-provided `printf`
 * routines  might or  might  not,  which caused  instabilities  of the  result
 * strings.
 *
 * The format  sequence is a  mixture of  format specifiers and  other verbatim
 * contents.  Each  format specifier starts with  a `%`, and has  the following
 * structure:
 *
 * ```
 * %[flags][width][.precision][length]conversion
 * ```
 *
 * This  function  supports  flags  of   ` `, `#`,  `+`,  `-`,  `0`,  width  of
 * non-negative  decimal integer  and  `*`, precision  of non-negative  decimal
 * integers and `*`, length of `L`,  `h`, `t`, `z`, `l`, `ll`, `q`, conversions
 * of `A`,  `D`, `E`, `G`, `O`,  `U`, `X`, `a`,  `c`, `d`, `e`, `f`,  `g`, `i`,
 * `n`, `o`, `p`, `s`, `u`, `x`, and `%`.  In case of `_WIN32` it also supports
 * `I`.   And additionally,  it  supports magical  `PRIsVALUE`  macro that  can
 * stringise arbitrary Ruby objects:
 *
 * ```CXX
 * rb_sprintf("|%"PRIsVALUE"|", RUBY_Qtrue); // => "|true|"
 * rb_sprintf("%+"PRIsVALUE, rb_stdin);      // => "#<IO:<STDIN>>"
 * ```
 *
 * @param[in]  fmt  A `printf`-like format specifier.
 * @param[in]  ...  Variadic number of contents to format.
 * @return     A rendered new instance of ::rb_cString.
 *
 * @internal
 *
 * :FIXME:  We can improve this document.
 */
VALUE rb_sprintf(const char *fmt, ...);

RBIMPL_ATTR_NONNULL((1))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 1, 0)
/**
 * Identical to rb_sprintf(), except it takes a `va_list`.
 *
 * @param[in]  fmt  A `printf`-like format specifier.
 * @param[in]  ap   Contents to format.
 * @return     A rendered new instance of ::rb_cString.
 */
VALUE rb_vsprintf(const char *fmt, va_list ap);

RBIMPL_ATTR_NONNULL((2))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 3)
/**
 * Identical to  rb_sprintf(), except  it renders the  output to  the specified
 * object rather than creating a new one.
 *
 * @param[out]  dst            String to modify.
 * @param[in]   fmt            A `printf`-like format specifier.
 * @param[in]   ...            Variadic number of contents to format.
 * @exception   rb_eTypeError  `dst` is not a String.
 * @return      Passed `dst`.
 * @post        `dst` has the rendered output appended to its end.
 */
VALUE rb_str_catf(VALUE dst, const char *fmt, ...);

RBIMPL_ATTR_NONNULL((2))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 0)
/**
 * Identical to  rb_str_catf(), except it  takes a  `va_list`.  It can  also be
 * seen as a  routine identical to rb_vsprintf(), except it  renders the output
 * to the specified object rather than creating a new one.
 *
 * @param[out]  dst            String to modify.
 * @param[in]   fmt            A `printf`-like format specifier.
 * @param[in]   ap             Contents to format.
 * @exception   rb_eTypeError  `dst` is not a String.
 * @return      Passed `dst`.
 * @post        `dst` has the rendered output appended to its end.
 */
VALUE rb_str_vcatf(VALUE dst, const char *fmt, va_list ap);

/**
 * Formats a string.
 *
 * Returns  the string  resulting from  applying `fmt`  to `argv`.   The format
 * sequence  is a  mixture of  format specifiers  and other  verbatim contents.
 * Each format specifier starts with a `%`, and has the following structure:
 *
 * ```
 * %[flags][width][.precision]type
 * ```
 *
 * ...  which is  different from  that of  rb_sprintf().  Because  ruby has  no
 * `short` or `long`, there is no way to specify a "length" of an argument.
 *
 * This function  supports flags  of ` `,  `#`, `+`, `-`,  `<>`, `{}`,  with of
 * non-negative decimal integer and `$`, `*`, precision of non-negative decimal
 * integer and `$`, `*`,  type of `A`, `B`, `E`, `G`, `X`,  `a`, `b`, `c`, `d`,
 * `e`,  `f`, `g`,  `i`, `o`,  `p`,  `s`, `u`,  `x`,  `%`.  This  list is  also
 * (largely the same but) not identical to that of rb_sprintf().
 *
 * @param[in]  argc           Number of objects in `argv`.
 * @param[in]  argv           Format arguments.
 * @param[in]  fmt            A printf-like format specifier.
 * @exception  rb_eTypeError  `fmt` is not a string.
 * @exception  rb_eArgError   Failed to parse `fmt`.
 * @return     A rendered new instance of ::rb_cString.
 * @note       Everything it takes must be Ruby objects.
 *
 */
VALUE rb_str_format(int argc, const VALUE *argv, VALUE fmt);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERN_SPRINTF_H */
ruby/internal/symbol.h000064400000032437151732674260011045 0ustar00#ifndef RBIMPL_SYMBOL_H                              /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_SYMBOL_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #rb_intern
 */
#include "ruby/internal/config.h"

#ifdef STDC_HEADERS
# include <stddef.h>
#endif

#ifdef HAVE_STRING_H
# include <string.h>
#endif

#include "ruby/internal/attr/noalias.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/constant_p.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/has/builtin.h"
#include "ruby/internal/value.h"

#define RB_ID2SYM      rb_id2sym           /**< @alias{rb_id2sym} */
#define RB_SYM2ID      rb_sym2id           /**< @alias{rb_sym2id} */
#define ID2SYM         RB_ID2SYM           /**< @old{RB_ID2SYM} */
#define SYM2ID         RB_SYM2ID           /**< @old{RB_SYM2ID} */
#define CONST_ID_CACHE RUBY_CONST_ID_CACHE /**< @old{RUBY_CONST_ID_CACHE} */
#define CONST_ID       RUBY_CONST_ID       /**< @old{RUBY_CONST_ID} */

/** @cond INTERNAL_MACRO */
#define rb_intern_const rb_intern_const
/** @endcond */

RBIMPL_SYMBOL_EXPORT_BEGIN()

/**
 * Converts an instance of ::rb_cSymbol into an ::ID.
 *
 * @param[in]  obj            An instance of ::rb_cSymbol.
 * @exception  rb_eTypeError  `obj` is not an instance of ::rb_cSymbol.
 * @return     An ::ID of the identical symbol.
 */
ID rb_sym2id(VALUE obj);

/**
 * Allocates an instance of ::rb_cSymbol that has the given id.
 *
 * @param[in]  id           An id.
 * @retval     RUBY_Qfalse  No such id ever existed in the history.
 * @retval     Otherwise    An allocated ::rb_cSymbol instance.
 */
VALUE rb_id2sym(ID id);

RBIMPL_ATTR_NONNULL(())
/**
 * Finds or creates a symbol of the given name.
 *
 * @param[in]  name              The name of the id.
 * @exception  rb_eRuntimeError  Too many symbols.
 * @return     A (possibly new) id whose value is the given name.
 * @note       These days  Ruby internally has  two kinds of symbols  (static /
 *             dynamic).  Symbols  created using  this function would  become a
 *             static one; i.e. would never be  garbage collected.  It is up to
 *             you to avoid memory leaks.  Think twice before using it.
 */
ID rb_intern(const char *name);

/**
 * Identical to  rb_intern(), except  it additionally takes  the length  of the
 * string.  This way you can have a symbol that contains NUL characters.
 *
 * @param[in]  name              The name of the id.
 * @param[in]  len               Length of `name`.
 * @exception  rb_eRuntimeError  Too many symbols.
 * @return     A (possibly new) id whose value is the given name.
 * @note       These   days  Ruby   internally   has  two   kinds  of   symbols
 *             (static/dynamic).   Symbols created  using  this function  would
 *             become static ones;  i.e. would never be  garbage collected.  It
 *             is up  to you to avoid  memory leaks.  Think twice  before using
 *             it.
 */
ID rb_intern2(const char *name, long len);

/**
 * Identical to  rb_intern(), except  it takes an instance of ::rb_cString.
 *
 * @param[in]  str               The name of the id.
 * @pre        `str` must either be an instance of ::rb_cSymbol, or an instance
 *             of ::rb_cString, or responds to `#to_str` method.
 * @exception  rb_eTypeError     Can't convert `str` into ::rb_cString.
 * @exception  rb_eRuntimeError  Too many symbols.
 * @return     A (possibly new) id whose value is the given str.
 * @note       These   days  Ruby   internally   has  two   kinds  of   symbols
 *             (static/dynamic).   Symbols created  using  this function  would
 *             become static ones;  i.e. would never be  garbage collected.  It
 *             is up  to you to avoid  memory leaks.  Think twice  before using
 *             it.
 */
ID rb_intern_str(VALUE str);

/**
 * Retrieves the name mapped to the given id.
 *
 * @param[in]  id         An id to query.
 * @retval     NULL       Unknown id.
 * @retval     otherwise  A name that the id represents.
 * @note       The return value  is managed by the interpreter.   Don't pass it
 *             to free().
 * @note       The underlying name can contain internal NUL bytes, so the return
 *             value might be a truncated representation due to the nature of C
 *             strings.
 * @note       This C string is backed by an underlying Ruby string. The Ruby
 *             string may move during GC compaction which would make this
 *             C string point to invalid memory. Do not use the return value
 *             of this function after a potential GC entry point.
 */
const char *rb_id2name(ID id);

RBIMPL_ATTR_NONNULL(())
/**
 * Detects if  the given name  is already interned or  not.  It first  tries to
 * convert the  argument to  an instance  of ::rb_cString if  it is  neither an
 * instance of ::rb_cString nor ::rb_cSymbol.  The conversion result is written
 * back  to the  variable.   Then queries  if that  name  was already  interned
 * before.  If found it returns such id, otherwise zero.
 *
 * We  eventually introduced  this API  to avoid  inadvertent symbol  pin-down.
 * Before,  there was  no way  to know  if an  ID was  already interned  or not
 * without actually  creating one (== leaking  memory).  By using this  API you
 * can avoid such situations:
 *
 * ```CXX
 * bool does_interning_this_leak_memory(VALUE obj)
 * {
 *     auto tmp = obj;
 *     if (auto id = rb_check_id(&tmp); id) {
 *         return false;
 *     }
 *     else {
 *         return true; // Let GC sweep tmp if necessary.
 *     }
 * }
 * ```
 *
 * @param[in,out]  namep              A pointer to a name to query.
 * @pre            The object referred  by `*namep` must either  be an instance
 *                 of ::rb_cSymbol, or an instance of ::rb_cString, or responds
 *                 to `#to_str` method.
 * @exception      rb_eTypeError      Can't convert `*namep` into ::rb_cString.
 * @exception      rb_eEncodingError  Given string is non-ASCII.
 * @retval         0                  No such id ever existed in the history.
 * @retval         otherwise          The id that represents the given name.
 * @post           The object  that `*namep`  points to  is a  converted result
 *                 object, which  is always an instance  of either ::rb_cSymbol
 *                 or ::rb_cString.
 * @see            https://bugs.ruby-lang.org/issues/5072
 *
 * @internal
 *
 * @shyouhei doesn't know why this has to raise rb_eEncodingError.
 */
ID rb_check_id(volatile VALUE *namep);

/**
 * @copydoc rb_intern_str()
 *
 * @internal
 *
 * :FIXME:  Can anyone  tell us  what is  the difference  between this  one and
 * rb_intern_str()?  As far as @shyouhei reads the implementation it seems what
 * rb_to_id() does is  is just waste some CPU time,  then call rb_intern_str().
 * He hopes he is wrong.
 */
ID rb_to_id(VALUE str);

/**
 * Identical to rb_id2name(), except it returns a frozen Ruby String instead of
 * a C String.
 *
 * @param[in]  id           An id to query.
 * @retval     RUBY_Qfalse  No such id ever existed in the history.
 * @retval     otherwise    An instance of ::rb_cString with the name of id.
 *
 * @internal
 *
 * In reality "rb_id2str() is identical  to rb_id2name() except it returns Ruby
 * string" is just describing things upside down; truth is `rb_id2name(foo)` is
 * a shorthand of `RSTRING_PTR(rb_id2str(foo))`.
 */
VALUE rb_id2str(ID id);

/**
 * Obtain a frozen string representation of a symbol (not including the leading
 * colon). Done without any object allocations.
 *
 * @param[in]  symbol  A ::rb_cSymbol instance to query.
 * @return     A frozen instance of ::rb_cString with the name of `symbol`.
 * @note       This does not create a permanent ::ID using the symbol.
 */
VALUE rb_sym2str(VALUE symbol);

/**
 * Identical  to  rb_intern_str(), except  it  generates  a dynamic  symbol  if
 * necessary.
 *
 * @param[in]  name              The name of the id.
 * @pre        `name`  must  either  be  an instance  of  ::rb_cSymbol,  or  an
 *             instance of ::rb_cString, or responds to `#to_str` method.
 * @exception  rb_eTypeError     Can't convert `name` into ::rb_cString.
 * @exception  rb_eRuntimeError  Too many symbols.
 * @return     A (possibly new) id whose value is the given name.
 * @note       These   days  Ruby   internally   has  two   kinds  of   symbols
 *             (static/dynamic).   Symbols created  using  this function  would
 *             become dynamic ones; i.e. would  be garbage collected.  It could
 *             be safer for you to use it than alternatives, when applicable.
 */
VALUE rb_to_symbol(VALUE name);

RBIMPL_ATTR_NONNULL(())
/**
 * Identical to  rb_check_id(), except it  returns an instance  of ::rb_cSymbol
 * instead.
 *
 * @param[in,out]  namep              A pointer to a name to query.
 * @pre            The object referred  by `*namep` must either  be an instance
 *                 of ::rb_cSymbol, or an instance of ::rb_cString, or responds
 *                 to `#to_str` method.
 * @exception      rb_eTypeError      Can't convert `*namep` into ::rb_cString.
 * @exception      rb_eEncodingError  Given string is non-ASCII.
 * @retval         RUBY_Qnil          No such id ever existed in the history.
 * @retval         otherwise          The id that represents the given name.
 * @post           The object  that `*namep`  points to  is a  converted result
 *                 object, which  is always an instance  of either ::rb_cSymbol
 *                 or ::rb_cString.
 * @see            https://bugs.ruby-lang.org/issues/5072
 *
 * @internal
 *
 * @shyouhei doesn't know why this has to raise rb_eEncodingError.
 */
VALUE rb_check_symbol(volatile VALUE *namep);
RBIMPL_SYMBOL_EXPORT_END()

RBIMPL_ATTR_PURE()
RBIMPL_ATTR_NONNULL(())
/**
 * This  is a  "tiny  optimisation" over  rb_intern().  If  you  pass a  string
 * _literal_, and if your C compiler can special-case strlen of such literal to
 * strength-reduce  into  an  integer  constant expression,  then  this  inline
 * function can precalc a part of conversion.
 *
 * @note       This function also works  happily for non-constant strings.  Why
 *             bother then?  Just apply liberally to everything.
 * @note       But  #rb_intern() could  be faster  on compilers  with statement
 *             expressions, because they can cache the created ::ID.
 * @param[in]  str               The name of the id.
 * @exception  rb_eRuntimeError  Too many symbols.
 * @return     A (possibly new) id whose value is the given str.
 * @note       These days  Ruby internally has  two kinds of symbols  (static /
 *             dynamic).  Symbols  created using  this function would  become a
 *             static one; i.e. would never be  garbage collected.  It is up to
 *             you to avoid memory leaks.  Think twice before using it.
 */
static inline ID
rb_intern_const(const char *str)
{
    size_t len = strlen(str);
    return rb_intern2(str, RBIMPL_CAST((long)len));
}

RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL(())
/**
 * @private
 *
 * This is an implementation detail of #rb_intern().  Just don't use it.
 */
static inline ID
rbimpl_intern_const(ID *ptr, const char *str)
{
    while (! *ptr) {
        *ptr = rb_intern_const(str);
    }

    return *ptr;
}

/**
 * Old implementation detail of rb_intern().
 * @deprecated Does anyone use it?  Preserved for backward compat.
 */
#define RUBY_CONST_ID_CACHE(result, str)                \
    {                                                   \
        static ID rb_intern_id_cache;                   \
        rbimpl_intern_const(&rb_intern_id_cache, (str)); \
        result rb_intern_id_cache;                      \
    }

/**
 * Old implementation detail of rb_intern().
 * @deprecated Does anyone use it?  Preserved for backward compat.
 */
#define RUBY_CONST_ID(var, str) \
    do { \
        static ID rbimpl_id; \
        (var) = rbimpl_intern_const(&rbimpl_id, (str)); \
    } while (0)

#if defined(HAVE_STMT_AND_DECL_IN_EXPR)
/* __builtin_constant_p and statement expression is available
 * since gcc-2.7.2.3 at least. */
#define rb_intern(str) \
    (RBIMPL_CONSTANT_P(str) ? \
     __extension__ ({ \
         static ID rbimpl_id; \
         rbimpl_intern_const(&rbimpl_id, (str)); \
     }) : \
     (rb_intern)(str))
#endif

#endif /* RBIMPL_SYMBOL_H */
ruby/internal/iterator.h000064400000044303151732674260011364 0ustar00#ifndef RBIMPL_ITERATOR_H                            /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_ITERATOR_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Block related APIs.
 */
#include "ruby/internal/attr/deprecated.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/**
 * @private
 *
 * @deprecated  This macro once was a thing in the old days, but makes no sense
 *              any  longer today.   Exists  here  for backwards  compatibility
 *              only.  You can safely forget about it.
 */
#define RB_BLOCK_CALL_FUNC_STRICT 1

/**
 * @private
 *
 * @deprecated  This macro once was a thing in the old days, but makes no sense
 *              any  longer today.   Exists  here  for backwards  compatibility
 *              only.  You can safely forget about it.
 */
#define RUBY_BLOCK_CALL_FUNC_TAKES_BLOCKARG 1

/**
 * Shim for block function parameters.  Historically ::rb_block_call_func_t had
 * only two parameters.  Over time it evolved  to have much more than that.  By
 * using this macro you can absorb such API differences.
 *
 * ```CXX
 * // This works since 2.1.0
 * VALUE my_own_iterator(RB_BLOCK_CALL_FUNC_ARGLIST(y, c));
 * ```
 */
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg) \
    VALUE yielded_arg, VALUE callback_arg, int argc, const VALUE *argv, VALUE blockarg

/**
 * This is the  type of a function that the  interpreter expect for C-backended
 * blocks.  Blocks are  often written in Ruby.  But C  extensions might want to
 * have their own blocks.  In order to  do so authors have to create a separate
 * C function of this type, and pass its pointer to rb_block_call().
 *
 * ```CXX
 * VALUE
 * my_own_iterator(RB_BLOCK_CALL_FUNC_ARGLIST(y, c))
 * {
 *     const auto plus = rb_intern("+");
 *     return rb_funcall(c, plus, 1, y);
 * }
 *
 * VALUE
 * my_own_method(VALUE self)
 * {
 *     const auto each = rb_intern("each");
 *     return rb_block_call(self, each, 0, 0, my_own_iterator, self);
 * }
 * ```
 */
typedef VALUE rb_block_call_func(RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg));

/**
 * Shorthand type that represents an iterator-written-in-C function pointer.
 */
typedef rb_block_call_func *rb_block_call_func_t;

/**
 * This is a shorthand of calling `obj.each`.
 *
 * @param[in]  obj  The receiver.
 * @return     What `obj.each` returns.
 *
 * @internal
 *
 * Does anyone still need it?  This API  was to use with rb_iterate(), which is
 * marked deprecated (see below).  Old idiom to call an iterator was:
 *
 * ```CXX
 * VALUE recv;
 * VALUE iter_func(ANYARGS);
 * VALUE iter_data;
 * rb_iterate(rb_each, recv, iter_func, iter_data);
 * ```
 */
VALUE rb_each(VALUE obj);

/**
 * Yields the block.  In Ruby there is  a concept called a block.  You can pass
 * one to a  method.  In a method, when  called with a block, you  can yield it
 * using this function.
 *
 * ```CXX
 * VALUE
 * iterate(VALUE self)
 * {
 *     extern int get_n(VALUE);
 *     extern VALUE get_v(VALUE, VALUE);
 *     const auto n = get_n(self);
 *
 *     for (int i=0; i<n; i++) {
 *         auto v = get_v(self, i);
 *
 *         rb_yield(v);
 *     }
 *     return self;
 * }
 * ```
 *
 * @param[in]  val                 Passed to the block.
 * @exception  rb_eLocalJumpError  There is no block given.
 * @return     Evaluated value of the given block.
 */
VALUE rb_yield(VALUE val);

/**
 * Identical to rb_yield(),  except it takes variadic number  of parameters and
 * pass them to the block.
 *
 * @param[in]  n                   Number of parameters.
 * @param[in]  ...                 List of arguments passed to the block.
 * @exception  rb_eLocalJumpError  There is no block given.
 * @return     Evaluated value of the given block.
 */
VALUE rb_yield_values(int n, ...);

/**
 * Identical to rb_yield_values(),  except it takes the parameters as a C array
 * instead of variadic arguments.
 *
 * @param[in]  n                   Number of parameters.
 * @param[in]  argv                List of arguments passed to the block.
 * @exception  rb_eLocalJumpError  There is no block given.
 * @return     Evaluated value of the given block.
 */
VALUE rb_yield_values2(int n, const VALUE *argv);

/**
 * Identical to  rb_yield_values2(), except you  can specify how to  handle the
 * last element of the given array.
 *
 * @param[in]  n                   Number of parameters.
 * @param[in]  argv                List of arguments passed to the block.
 * @param[in]  kw_splat            Handling of keyword parameters:
 *   - RB_NO_KEYWORDS              `ary`'s last is not a keyword argument.
 *   - RB_PASS_KEYWORDS            `ary`'s last is a keyword argument.
 *   - RB_PASS_CALLED_KEYWORDS     makes no sense here.
 * @exception  rb_eLocalJumpError  There is no block given.
 * @return     Evaluated value of the given block.
 */
VALUE rb_yield_values_kw(int n, const VALUE *argv, int kw_splat);

/**
 * Identical to  rb_yield_values(), except it  splats an array to  generate the
 * list of parameters.
 *
 * @param[in]  ary                 Array to splat.
 * @exception  rb_eLocalJumpError  There is no block given.
 * @return     Evaluated value of the given block.
 */
VALUE rb_yield_splat(VALUE ary);

/**
 * Identical to rb_yield_splat(), except you can specify how to handle the last
 * element of the given array.
 *
 * @param[in]  ary                 Array to splat.
 * @param[in]  kw_splat            Handling of keyword parameters:
 *   - RB_NO_KEYWORDS              `ary`'s last is not a keyword argument.
 *   - RB_PASS_KEYWORDS            `ary`'s last is a keyword argument.
 *   - RB_PASS_CALLED_KEYWORDS     makes no sense here.
 * @exception  rb_eLocalJumpError  There is no block given.
 * @return     Evaluated value of the given block.
 */
VALUE rb_yield_splat_kw(VALUE ary, int kw_splat);

/**
 * Pass a passed block.
 *
 * Sometimes you  want to "pass" a  block form one method  to another.  Suppose
 * you have this Ruby method `foo`:
 *
 * ```ruby
 * def foo(x, y)
 *   x.open(y) do |*z|
 *     yield(*z)
 *   end
 * end
 * ```
 *
 * And  suppose you  want  to  translate this  into  C.  Then  rb_yield_block()
 * function is usable in this situation.
 *
 * ```CXX
 * VALUE
 * foo_translated_into_C(VALUE self, VALUE x, VALUE y)
 * {
 *     const auto open = rb_intern("open");
 *
 *     return rb_block_call(x, open, 1, &y, rb_yield_block, Qfalse);
 *     //                                   ^^^^^^^^^^^^^^  Here.
 * }
 * ```
 *
 * @see rb_funcall_passing_block
 *
 * @internal
 *
 * @shyouhei  honestly  doesn't understand  why  this  is needed,  given  there
 * already was rb_funcall_passing_block()  at the time it  was implemented.  If
 * somebody knows its raison d'etre, please improve the document :FIXME:
 */
VALUE rb_yield_block(RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)); /* rb_block_call_func */

/**
 * Determines if the current method is given a keyword argument.
 *
 * @retval  false  No keyword argument is given.
 * @retval  true   Keyword argument(s) are given.
 * @ingroup defmethod
 */
int rb_keyword_given_p(void);

/**
 * Determines if the current method is given a block.
 *
 * @retval  false  No block is given.
 * @retval  true   A block is given.
 * @ingroup defmethod
 *
 * @internal
 *
 * This function should have returned a bool.   But at the time it was designed
 * the project was entirely written in K&R C.
 */
int rb_block_given_p(void);

/**
 * Declares that the current method needs a block.
 *
 * @exception  rb_eLocalJumpError  No block given.
 * @ingroup    defmethod
 */
void rb_need_block(void);

#ifndef __cplusplus
RBIMPL_ATTR_DEPRECATED(("by: rb_block_call since 1.9"))
#endif
/**
 * Old way to iterate a block.
 *
 * @deprecated     This is an old API.  Use rb_block_call() instead.
 * @warning        The passed  function must at  least once call a  ruby method
 *                 (to handle interrupts etc.)
 * @param[in]      func1  A function that could yield a value.
 * @param[in,out]  data1  Passed to `func1`
 * @param[in]      proc   A function acts as a block.
 * @param[in,out]  data2  Passed to `proc` as the data2 parameter.
 * @return         What `func1` returns.
 */
VALUE rb_iterate(VALUE (*func1)(VALUE), VALUE data1, rb_block_call_func_t proc, VALUE data2);

#ifdef __cplusplus
namespace ruby {
namespace backward {
/**
 * Old way to iterate a block.
 *
 * @deprecated     This is an old API.  Use rb_block_call() instead.
 * @warning        The passed  function must at  least once call a  ruby method
 *                 (to handle interrupts etc.)
 * @param[in]      iter   A function that could yield a value.
 * @param[in,out]  data1  Passed to `func1`
 * @param[in]      bl     A function acts as a block.
 * @param[in,out]  data2  Passed to `proc` as the data2 parameter.
 * @return         What `func1` returns.
 */
static inline VALUE
rb_iterate_deprecated(VALUE (*iter)(VALUE), VALUE data1, rb_block_call_func_t bl, VALUE data2)
{
    return ::rb_iterate(iter, data1, bl, data2);
}}}

RBIMPL_ATTR_DEPRECATED(("by: rb_block_call since 1.9"))
VALUE rb_iterate(VALUE (*func1)(VALUE), VALUE data1, rb_block_call_func_t proc, VALUE data2);
#endif

/**
 * Identical to  rb_funcallv(), except it  additionally passes a function  as a
 * block.  When the  method yields, `proc` is called with  the yielded value as
 * its first  argument, and  `data2` as  the second.   Yielded values  would be
 * packed into an array if multiple values are yielded at once.
 *
 * @param[in,out]  obj    Receiver.
 * @param[in]      mid    Method signature.
 * @param[in]      argc   Number of arguments.
 * @param[in]      argv   Arguments passed to `obj.mid`.
 * @param[in]      proc   A function acts as a block.
 * @param[in,out]  data2  Passed to `proc` as the data2 parameter.
 * @return         What `obj.mid` returns.
 */
VALUE rb_block_call(VALUE obj, ID mid, int argc, const VALUE *argv, rb_block_call_func_t proc, VALUE data2);

/**
 * Identical to rb_funcallv_kw(), except it additionally passes a function as a
 * block.   It can  also be  seen as  a routine  identical to  rb_block_call(),
 * except it handles keyword-ness of `argv[argc-1]`.
 *
 * @param[in,out]  obj       Receiver.
 * @param[in]      mid       Method signature.
 * @param[in]      argc      Number of arguments including the keywords.
 * @param[in]      argv      Arguments passed to `obj.mid`.
 * @param[in]      proc      A function acts as a block.
 * @param[in,out]  data2     Passed to `proc` as the data2 parameter.
 * @param[in]      kw_splat  Handling of keyword parameters:
 *   - RB_NO_KEYWORDS           `argv`'s last is not a keyword argument.
 *   - RB_PASS_KEYWORDS         `argv`'s last is a keyword argument.
 *   - RB_PASS_CALLED_KEYWORDS  it depends if there is a passed block.
 * @return         What `obj.mid` returns.
 */
VALUE rb_block_call_kw(VALUE obj, ID mid, int argc, const VALUE *argv, rb_block_call_func_t proc, VALUE data2, int kw_splat);

/**
 * Identical  to rb_rescue2(),  except it  does not  take a  list of  exception
 * classes.  This is a shorthand of:
 *
 * ```CXX
 * rb_rescue2(b_proc, data1, r_proc, data2, rb_eStandardError, (VALUE)0);
 * ```
 *
 * @param[in]      b_proc  A function which potentially raises an exception.
 * @param[in,out]  data1   Passed to `b_proc`.
 * @param[in]      r_proc  A function which rescues an exception in `b_proc`.
 * @param[in,out]  data2   The first argument of `r_proc`.
 * @return         The return value of `b_proc`  if no exception occurs, or the
 *                 return value of `r_proc` otherwise.
 * @see            rb_rescue
 * @see            rb_ensure
 * @see            rb_protect
 * @ingroup        exception
 */
VALUE rb_rescue(VALUE (*b_proc)(VALUE), VALUE data1, VALUE (*r_proc)(VALUE, VALUE), VALUE data2);

/**
 * An equivalent of `rescue` clause.
 *
 * First  it calls  the function  `b_proc` with  `data1` as  the argument.   If
 * nothing is thrown the function happily returns the return value of `b_proc`.
 * When `b_proc` raises an exception, and the exception is a kind of one of the
 * given  exception classes,  it  then  calls `r_proc`  with  `data2` and  that
 * exception.  If the exception does not match any of them, it propagates.
 *
 * @param[in]      b_proc  A function which potentially raises an exception.
 * @param[in,out]  data1   Passed to `b_proc`.
 * @param[in]      r_proc  A function which rescues an exception in `b_proc`.
 * @param[in,out]  data2   The first argument of `r_proc`.
 * @param[in]      ...     1 or  more exception classes.  Must be terminated by
 *                         `(VALUE)0`
 * @return         The return value of `b_proc`  if no exception occurs, or the
 *                 return value of `r_proc` otherwise.
 * @see            rb_rescue
 * @see            rb_ensure
 * @see            rb_protect
 * @ingroup        exception
 */
VALUE rb_rescue2(VALUE (*b_proc)(VALUE), VALUE data1, VALUE (*r_proc)(VALUE, VALUE), VALUE data2, ...);

/**
 * Identical to  rb_rescue2(), except  it takes  `va_list` instead  of variadic
 * number  of  arguments.   This  is  exposed to  3rd  parties  because  inline
 * functions use it.  Basically you don't have to bother.
 *
 * @param[in]      b_proc  A function which potentially raises an exception.
 * @param[in,out]  data1   Passed to `b_proc`.
 * @param[in]      r_proc  A function which rescues an exception in `b_proc`.
 * @param[in,out]  data2   The first argument of `r_proc`.
 * @param[in]      ap      1 or  more exception classes.  Must be terminated by
 *                         `(VALUE)0`
 * @return         The return value of `b_proc`  if no exception occurs, or the
 *                 return value of `r_proc` otherwise.
 * @see            rb_rescue
 * @see            rb_ensure
 * @see            rb_protect
 * @ingroup        exception
 */
VALUE rb_vrescue2(VALUE (*b_proc)(VALUE), VALUE data1, VALUE (*r_proc)(VALUE, VALUE), VALUE data2, va_list ap);

/**
 * An equivalent to `ensure` clause.   Calls the function `b_proc` with `data1`
 * as the argument, then calls `e_proc` with `data2` when execution terminated.
 *
 * @param[in]      b_proc     A function representing begin clause.
 * @param[in,out]  data1      Passed to `b_proc`.
 * @param[in]      e_proc     A function representing ensure clause.
 * @param[in,out]  data2      Passed to `e_proc`.
 * @retval         RUBY_Qnil  exception occurred inside of `b_proc`.
 * @retval         otherwise  The return value of `b_proc`.
 * @see            rb_rescue
 * @see            rb_rescue2
 * @see            rb_protect
 * @ingroup        exception
 */
VALUE rb_ensure(VALUE (*b_proc)(VALUE), VALUE data1, VALUE (*e_proc)(VALUE), VALUE data2);

/**
 * Executes the passed block and catches values thrown from inside of it.
 *
 * In case  the block does  not contain any  throw`, this function  returns the
 * value of the last expression evaluated.
 *
 * ```CXX
 * VALUE
 * iter(RB_BLOCK_CALL_FUNC_ARGLIST(yielded, callback))
 * {
 *     return INT2FIX(123);
 * }
 *
 * VALUE
 * method(VALUE self)
 * {
 *     return rb_catch("tag", iter, Qnil); // returns 123
 * }
 * ```
 *
 * In case there do exist `throw`, Ruby searches up its execution context for a
 * `catch` block.   When a matching catch  is found, the block  stops executing
 * and returns that thrown value instead.
 *
 * ```CXX
 * VALUE
 * iter(RB_BLOCK_CALL_FUNC_ARGLIST(yielded, callback))
 * {
 *     rb_throw("tag", 456);
 *     return INT2FIX(123);
 * }
 *
 * VALUE
 * method(VALUE self)
 * {
 *     return rb_catch("tag", iter, Qnil); // returns 456
 * }
 * ```
 *
 * @param[in]      tag   Arbitrary tag string.
 * @param[in]      func  Function pointer that acts as a block.
 * @param[in,out]  data  Extra parameter passed to `func`.
 * @return         Either caught value for `tag`, or the return value of `func`
 *                 if nothing is thrown.
 */
VALUE rb_catch(const char *tag, rb_block_call_func_t func, VALUE data);

/**
 * Identical to rb_catch(), except it catches arbitrary Ruby objects.
 *
 * @param[in]      tag   Arbitrary tag object.
 * @param[in]      func  Function pointer that acts as a block.
 * @param[in,out]  data  Extra parameter passed to `func`.
 * @return         Either caught value for `tag`, or the return value of `func`
 *                 if nothing is thrown.
 */
VALUE rb_catch_obj(VALUE tag, rb_block_call_func_t func, VALUE data);

RBIMPL_ATTR_NORETURN()
/**
 * Transfers control to the end of  the active `catch` block waiting for `tag`.
 * Raises  rb_eUncughtThrow if  there is  no `catch`  block for  the tag.   The
 * second  parameter supplies  a  return  value for  the  `catch` block,  which
 * otherwise defaults to ::RUBY_Qnil.  For examples, see rb_catch().
 *
 * @param[in]  tag               Tag string.
 * @param[in]  val               Value to throw.
 * @exception  rb_eUncughtThrow  There is no corresponding `catch` clause.
 * @note       It never returns.
 */
void rb_throw(const char *tag, VALUE val);

RBIMPL_ATTR_NORETURN()
/**
 * Identical to rb_throw(), except it allows  arbitrary Ruby object to become a
 * tag.
 *
 * @param[in]  tag               Arbitrary object.
 * @param[in]  val               Value to throw.
 * @exception  rb_eUncughtThrow  There is no corresponding `catch` clause.
 * @note       It never returns.
 */
void rb_throw_obj(VALUE tag, VALUE val);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_ITERATOR_H */
ruby/internal/value_type.h000064400000034332151732674260011711 0ustar00#ifndef RBIMPL_VALUE_TYPE_H                          /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_VALUE_TYPE_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines enum ::ruby_value_type.
 */
#include "ruby/internal/assume.h"
#include "ruby/internal/attr/artificial.h"
#include "ruby/internal/attr/cold.h"
#include "ruby/internal/attr/enum_extensibility.h"
#include "ruby/internal/attr/forceinline.h"
#include "ruby/internal/attr/pure.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/constant_p.h"
#include "ruby/internal/core/rbasic.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/error.h"
#include "ruby/internal/has/builtin.h"
#include "ruby/internal/special_consts.h"
#include "ruby/internal/stdbool.h"
#include "ruby/internal/value.h"
#include "ruby/assert.h"

#if defined(T_DATA)
/*
 * :!BEWARE!: (Recent?)   Solaris' <nfs/nfs.h>  have conflicting  definition of
 * T_DATA.  Let us stop here.  Please have a workaround like this:
 *
 * ```C
 * #include <ruby/ruby.h> // <- Include this one first.
 * #undef T_DATA          // <- ... and stick to RUBY_T_DATA forever.
 * #include <nfs/nfs.h>   // <- OS-provided T_DATA introduced.
 * ```
 *
 * See also [ruby-core:4261]
 */
# error Bail out due to conflicting definition of T_DATA.
#endif

#define T_ARRAY    RUBY_T_ARRAY    /**< @old{RUBY_T_ARRAY} */
#define T_BIGNUM   RUBY_T_BIGNUM   /**< @old{RUBY_T_BIGNUM} */
#define T_CLASS    RUBY_T_CLASS    /**< @old{RUBY_T_CLASS} */
#define T_COMPLEX  RUBY_T_COMPLEX  /**< @old{RUBY_T_COMPLEX} */
#define T_DATA     RUBY_T_DATA     /**< @old{RUBY_T_DATA} */
#define T_FALSE    RUBY_T_FALSE    /**< @old{RUBY_T_FALSE} */
#define T_FILE     RUBY_T_FILE     /**< @old{RUBY_T_FILE} */
#define T_FIXNUM   RUBY_T_FIXNUM   /**< @old{RUBY_T_FIXNUM} */
#define T_FLOAT    RUBY_T_FLOAT    /**< @old{RUBY_T_FLOAT} */
#define T_HASH     RUBY_T_HASH     /**< @old{RUBY_T_HASH} */
#define T_ICLASS   RUBY_T_ICLASS   /**< @old{RUBY_T_ICLASS} */
#define T_IMEMO    RUBY_T_IMEMO    /**< @old{RUBY_T_IMEMO} */
#define T_MASK     RUBY_T_MASK     /**< @old{RUBY_T_MASK} */
#define T_MATCH    RUBY_T_MATCH    /**< @old{RUBY_T_MATCH} */
#define T_MODULE   RUBY_T_MODULE   /**< @old{RUBY_T_MODULE} */
#define T_MOVED    RUBY_T_MOVED    /**< @old{RUBY_T_MOVED} */
#define T_NIL      RUBY_T_NIL      /**< @old{RUBY_T_NIL} */
#define T_NODE     RUBY_T_NODE     /**< @old{RUBY_T_NODE} */
#define T_NONE     RUBY_T_NONE     /**< @old{RUBY_T_NONE} */
#define T_OBJECT   RUBY_T_OBJECT   /**< @old{RUBY_T_OBJECT} */
#define T_RATIONAL RUBY_T_RATIONAL /**< @old{RUBY_T_RATIONAL} */
#define T_REGEXP   RUBY_T_REGEXP   /**< @old{RUBY_T_REGEXP} */
#define T_STRING   RUBY_T_STRING   /**< @old{RUBY_T_STRING} */
#define T_STRUCT   RUBY_T_STRUCT   /**< @old{RUBY_T_STRUCT} */
#define T_SYMBOL   RUBY_T_SYMBOL   /**< @old{RUBY_T_SYMBOL} */
#define T_TRUE     RUBY_T_TRUE     /**< @old{RUBY_T_TRUE} */
#define T_UNDEF    RUBY_T_UNDEF    /**< @old{RUBY_T_UNDEF} */
#define T_ZOMBIE   RUBY_T_ZOMBIE   /**< @old{RUBY_T_ZOMBIE} */

#define BUILTIN_TYPE      RB_BUILTIN_TYPE   /**< @old{RB_BUILTIN_TYPE} */
#define DYNAMIC_SYM_P     RB_DYNAMIC_SYM_P  /**< @old{RB_DYNAMIC_SYM_P} */
#define RB_INTEGER_TYPE_P rb_integer_type_p /**< @old{rb_integer_type_p} */
#define SYMBOL_P          RB_SYMBOL_P       /**< @old{RB_SYMBOL_P} */
#define rb_type_p         RB_TYPE_P         /**< @alias{RB_TYPE_P} */

/** @cond INTERNAL_MACRO */
#define RB_BUILTIN_TYPE   RB_BUILTIN_TYPE
#define RB_DYNAMIC_SYM_P  RB_DYNAMIC_SYM_P
#define RB_FLOAT_TYPE_P   RB_FLOAT_TYPE_P
#define RB_SYMBOL_P       RB_SYMBOL_P
#define RB_TYPE_P         RB_TYPE_P
#define Check_Type        Check_Type

#ifdef RBIMPL_VA_OPT_ARGS
# define RBIMPL_ASSERT_TYPE(v, t) \
    RBIMPL_ASSERT_OR_ASSUME(RB_TYPE_P(v, t), "actual type: %d", rb_type(v))
#else
# define RBIMPL_ASSERT_TYPE(v, t) RBIMPL_ASSERT_OR_ASSUME(RB_TYPE_P(v, t))
#endif
/** @endcond */

/** @old{rb_type} */
#define TYPE(_)           RBIMPL_CAST((int)rb_type(_))

/** C-level type of an object. */
enum
RBIMPL_ATTR_ENUM_EXTENSIBILITY(closed)
ruby_value_type {
    RUBY_T_NONE     = 0x00, /**< Non-object (swept etc.) */

    RUBY_T_OBJECT   = 0x01, /**< @see struct ::RObject */
    RUBY_T_CLASS    = 0x02, /**< @see struct ::RClass and ::rb_cClass */
    RUBY_T_MODULE   = 0x03, /**< @see struct ::RClass and ::rb_cModule */
    RUBY_T_FLOAT    = 0x04, /**< @see struct ::RFloat */
    RUBY_T_STRING   = 0x05, /**< @see struct ::RString */
    RUBY_T_REGEXP   = 0x06, /**< @see struct ::RRegexp */
    RUBY_T_ARRAY    = 0x07, /**< @see struct ::RArray */
    RUBY_T_HASH     = 0x08, /**< @see struct ::RHash */
    RUBY_T_STRUCT   = 0x09, /**< @see struct ::RStruct */
    RUBY_T_BIGNUM   = 0x0a, /**< @see struct ::RBignum */
    RUBY_T_FILE     = 0x0b, /**< @see struct ::RFile */
    RUBY_T_DATA     = 0x0c, /**< @see struct ::RTypedData */
    RUBY_T_MATCH    = 0x0d, /**< @see struct ::RMatch */
    RUBY_T_COMPLEX  = 0x0e, /**< @see struct ::RComplex */
    RUBY_T_RATIONAL = 0x0f, /**< @see struct ::RRational */

    RUBY_T_NIL      = 0x11, /**< @see ::RUBY_Qnil */
    RUBY_T_TRUE     = 0x12, /**< @see ::RUBY_Qfalse */
    RUBY_T_FALSE    = 0x13, /**< @see ::RUBY_Qtrue */
    RUBY_T_SYMBOL   = 0x14, /**< @see struct ::RSymbol */
    RUBY_T_FIXNUM   = 0x15, /**< Integers formerly known as Fixnums. */
    RUBY_T_UNDEF    = 0x16, /**< @see ::RUBY_Qundef */

    RUBY_T_IMEMO    = 0x1a, /**< @see struct ::RIMemo */
    RUBY_T_NODE     = 0x1b, /**< @see struct ::RNode */
    RUBY_T_ICLASS   = 0x1c, /**< Hidden classes known as IClasses. */
    RUBY_T_ZOMBIE   = 0x1d, /**< @see struct ::RZombie */
    RUBY_T_MOVED    = 0x1e, /**< @see struct ::RMoved */

    RUBY_T_MASK     = 0x1f  /**< Bitmask of ::ruby_value_type. */
};

RBIMPL_SYMBOL_EXPORT_BEGIN()
RBIMPL_ATTR_COLD()
/**
 * @private
 *
 * This was  the old implementation  of Check_Type(), but they  diverged.  This
 * one remains  for theoretical backwards compatibility.   People normally need
 * not use it.
 *
 * @param[in]  obj            An object.
 * @param[in]  t              A type.
 * @exception  rb_eTypeError  `obj` is not of type `t`.
 * @exception  rb_eFatal      `obj` is corrupt.
 * @post       Upon successful return `obj` is guaranteed to have type `t`.
 *
 * @internal
 *
 * The second argument shall have been enum ::ruby_value_type.  But at the time
 * matz designed this  function he still used  K&R C.  There was  no such thing
 * like a function prototype.  We can no longer change this API.
 */
void rb_check_type(VALUE obj, int t);
RBIMPL_SYMBOL_EXPORT_END()

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Queries the type of the object.
 *
 * @param[in]  obj  Object in question.
 * @pre        `obj` must not be a special constant.
 * @return     The type of `obj`.
 */
static inline enum ruby_value_type
RB_BUILTIN_TYPE(VALUE obj)
{
    RBIMPL_ASSERT_OR_ASSUME(! RB_SPECIAL_CONST_P(obj));

#if 0 && defined __GNUC__ && !defined __clang__
    /* Don't move the access to `flags` before the preceding
     * RB_SPECIAL_CONST_P check. */
    __asm volatile("": : :"memory");
#endif
    VALUE ret = RBASIC(obj)->flags & RUBY_T_MASK;
    return RBIMPL_CAST((enum ruby_value_type)ret);
}

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
/**
 * Queries if the object is an instance of ::rb_cInteger.
 *
 * @param[in]  obj    Object in question.
 * @retval     true   It is.
 * @retval     false  It isn't.
 */
static inline bool
rb_integer_type_p(VALUE obj)
{
    if (RB_FIXNUM_P(obj)) {
        return true;
    }
    else if (RB_SPECIAL_CONST_P(obj)) {
        return false;
    }
    else {
        return RB_BUILTIN_TYPE(obj) == RUBY_T_BIGNUM;
    }
}

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
/**
 * Identical to RB_BUILTIN_TYPE(), except it can also accept special constants.
 *
 * @param[in]  obj  Object in question.
 * @return     The type of `obj`.
 */
static inline enum ruby_value_type
rb_type(VALUE obj)
{
    if (! RB_SPECIAL_CONST_P(obj)) {
        return RB_BUILTIN_TYPE(obj);
    }
    else if (obj == RUBY_Qfalse) {
        return RUBY_T_FALSE;
    }
    else if (obj == RUBY_Qnil) {
        return RUBY_T_NIL;
    }
    else if (obj == RUBY_Qtrue) {
        return RUBY_T_TRUE;
    }
    else if (obj == RUBY_Qundef) {
        return RUBY_T_UNDEF;
    }
    else if (RB_FIXNUM_P(obj)) {
        return RUBY_T_FIXNUM;
    }
    else if (RB_STATIC_SYM_P(obj)) {
        return RUBY_T_SYMBOL;
    }
    else {
        RBIMPL_ASSUME(RB_FLONUM_P(obj));
        return RUBY_T_FLOAT;
    }
}

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Queries if the object is an instance of ::rb_cFloat.
 *
 * @param[in]  obj    Object in question.
 * @retval     true   It is.
 * @retval     false  It isn't.
 */
static inline bool
RB_FLOAT_TYPE_P(VALUE obj)
{
    if (RB_FLONUM_P(obj)) {
        return true;
    }
    else if (RB_SPECIAL_CONST_P(obj)) {
        return false;
    }
    else {
        return RB_BUILTIN_TYPE(obj) == RUBY_T_FLOAT;
    }
}

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Queries if the object is a dynamic symbol.
 *
 * @param[in]  obj    Object in question.
 * @retval     true   It is.
 * @retval     false  It isn't.
 */
static inline bool
RB_DYNAMIC_SYM_P(VALUE obj)
{
    if (RB_SPECIAL_CONST_P(obj)) {
        return false;
    }
    else {
        return RB_BUILTIN_TYPE(obj) == RUBY_T_SYMBOL;
    }
}

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Queries if the object is an instance of ::rb_cSymbol.
 *
 * @param[in]  obj    Object in question.
 * @retval     true   It is.
 * @retval     false  It isn't.
 */
static inline bool
RB_SYMBOL_P(VALUE obj)
{
    return RB_STATIC_SYM_P(obj) || RB_DYNAMIC_SYM_P(obj);
}

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
RBIMPL_ATTR_FORCEINLINE()
/**
 * @private
 *
 * This is an implementation detail of RB_TYPE_P().  Just don't use it.
 *
 * @param[in]  obj    An object.
 * @param[in]  t      A type.
 * @retval     true   `obj` is of type `t`.
 * @retval     false  Otherwise.
 */
static bool
rbimpl_RB_TYPE_P_fastpath(VALUE obj, enum ruby_value_type t)
{
    if (t == RUBY_T_TRUE) {
        return obj == RUBY_Qtrue;
    }
    else if (t == RUBY_T_FALSE) {
        return obj == RUBY_Qfalse;
    }
    else if (t == RUBY_T_NIL) {
        return obj == RUBY_Qnil;
    }
    else if (t == RUBY_T_UNDEF) {
        return obj == RUBY_Qundef;
    }
    else if (t == RUBY_T_FIXNUM) {
        return RB_FIXNUM_P(obj);
    }
    else if (t == RUBY_T_SYMBOL) {
        return RB_SYMBOL_P(obj);
    }
    else if (t == RUBY_T_FLOAT) {
        return RB_FLOAT_TYPE_P(obj);
    }
    else if (RB_SPECIAL_CONST_P(obj)) {
        return false;
    }
    else if (t == RB_BUILTIN_TYPE(obj)) {
        return true;
    }
    else {
        return false;
    }
}

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
/**
 * Queries if the given object is of given type.
 *
 * @param[in]  obj    An object.
 * @param[in]  t      A type.
 * @retval     true   `obj` is of type `t`.
 * @retval     false  Otherwise.
 *
 * @internal
 *
 * This  function is  a super-duper  hot  path.  Optimised  targeting modern  C
 * compilers and x86_64 architecture.
 */
static inline bool
RB_TYPE_P(VALUE obj, enum ruby_value_type t)
{
    if (RBIMPL_CONSTANT_P(t)) {
        return rbimpl_RB_TYPE_P_fastpath(obj, t);
    }
    else {
        return t == rb_type(obj);
    }
}

/** @cond INTERNAL_MACRO */
/* Clang, unlike GCC, cannot propagate __builtin_constant_p beyond function
 * boundary. */
#if defined(__clang__)
# undef RB_TYPE_P
# define RB_TYPE_P(obj, t)                  \
    (RBIMPL_CONSTANT_P(t)                  ? \
     rbimpl_RB_TYPE_P_fastpath((obj), (t)) : \
     (RB_TYPE_P)((obj), (t)))
#endif

/* clang 3.x (4.2 compatible) can't eliminate CSE of RB_BUILTIN_TYPE
 * in inline function and caller function
 * See also 8998c06461ea0bef11b3aeb30b6d2ab71c8762ba
 */
#if RBIMPL_COMPILER_BEFORE(Clang, 4, 0, 0)
# undef rb_integer_type_p
# define rb_integer_type_p(obj)                                 \
    __extension__ ({                                            \
        const VALUE integer_type_obj = (obj);                   \
        (RB_FIXNUM_P(integer_type_obj) ||                       \
         (!RB_SPECIAL_CONST_P(integer_type_obj) &&              \
          RB_BUILTIN_TYPE(integer_type_obj) == RUBY_T_BIGNUM)); \
    })
#endif
/** @endcond */

RBIMPL_ATTR_PURE()
RBIMPL_ATTR_ARTIFICIAL()
/**
 * @private
 * Defined in ruby/internal/core/rtypeddata.h
 */
static inline bool rbimpl_rtypeddata_p(VALUE obj);

RBIMPL_ATTR_ARTIFICIAL()
/**
 * Identical  to  RB_TYPE_P(),  except  it  raises  exceptions  on  predication
 * failure.
 *
 * @param[in]  v              An object.
 * @param[in]  t              A type.
 * @exception  rb_eTypeError  `obj` is not of type `t`.
 * @exception  rb_eFatal      `obj` is corrupt.
 * @post       Upon successful return `obj` is guaranteed to have type `t`.
 */
static inline void
Check_Type(VALUE v, enum ruby_value_type t)
{
    if (RB_UNLIKELY(! RB_TYPE_P(v, t))) {
        goto unexpected_type;
    }
    else if (t == RUBY_T_DATA && rbimpl_rtypeddata_p(v)) {
        /* Typed data is not simple `T_DATA`, see `rb_check_type` */
        goto unexpected_type;
    }
    else {
        return;
    }

  unexpected_type:
    rb_unexpected_type(v, RBIMPL_CAST((int)t));
}

#endif /* RBIMPL_VALUE_TYPE_H */
ruby/internal/warning_push.h000064400000011644151732674260012241 0ustar00#ifndef RBIMPL_WARNING_PUSH_H                        /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_WARNING_PUSH_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Defines #RBIMPL_WARNING_PUSH.
 *
 * ### Q&A ###
 *
 * Q: Why all the macros defined in this file are function-like macros?
 *
 * A: Sigh.   This  is  because of  Doxygen.  Its  `SKIP_FUNCTION_MACROS = YES`
 *    configuration setting  requests us  that if  we want  it to  ignore these
 *    macros,  then we  have to  do  two things:  (1)  let them  be defined  as
 *    function-like macros,  and (2) place  them separately in their  own line,
 *    like below:
 *
 *    ```CXX
 *    // NG -- foo's type  considered something like `unsigned int`.
 *    RBIMPL_WARNING_PUSH
 *    int foo(void);
 *    RBIMPL_WARNING_POP
 *
 *    // OK -- the macros are ignored by Doxygen.
 *    RBIMPL_WARNING_PUSH()
 *    int foo(void);
 *    RBIMPL_WARNING_POP()
 *    ```
 */
#include "ruby/internal/compiler_is.h"
#include "ruby/internal/compiler_since.h"

#if defined(__DOXYGEN__)

/**
 * @private
 *
 * Pushes compiler warning state.
 */
#define RBIMPL_WARNING_PUSH()        __pragma(warning(push))

/**
 * @private
 *
 * Pops compiler warning state.
 */
#define RBIMPL_WARNING_POP()         __pragma(warning(pop))

/**
 * @private
 *
 * Turns a warning into a fatal error.
 *
 * @param  flag  A flag that represents the kind of warnings.
 */
#define RBIMPL_WARNING_ERROR(flag)   __pragma(warning(error: flag))

/**
 * @private
 *
 * Suppresses a warning.
 *
 * @param  flag  A flag that represents the kind of warnings.
 */
#define RBIMPL_WARNING_IGNORED(flag) __pragma(warning(disable: flag))

#elif RBIMPL_COMPILER_SINCE(MSVC, 12, 0, 0)
# /* Not sure exactly when but it seems VC++ 6.0 is a version with it.*/
# define RBIMPL_WARNING_PUSH()        __pragma(warning(push))
# define RBIMPL_WARNING_POP()         __pragma(warning(pop))
# define RBIMPL_WARNING_ERROR(flag)   __pragma(warning(error: flag))
# define RBIMPL_WARNING_IGNORED(flag) __pragma(warning(disable: flag))

#elif RBIMPL_COMPILER_SINCE(Intel, 13, 0, 0)
# define RBIMPL_WARNING_PUSH()        __pragma(warning(push))
# define RBIMPL_WARNING_POP()         __pragma(warning(pop))
# define RBIMPL_WARNING_ERROR(flag)   __pragma(warning(error: flag))
# define RBIMPL_WARNING_IGNORED(flag) __pragma(warning(disable: flag))

#elif RBIMPL_COMPILER_IS(Clang) || RBIMPL_COMPILER_IS(Apple)
# /* Not sure exactly when but it seems LLVM 2.6.0 is a version with it. */
# define RBIMPL_WARNING_PRAGMA0(x)    _Pragma(# x)
# define RBIMPL_WARNING_PRAGMA1(x)    RBIMPL_WARNING_PRAGMA0(clang diagnostic x)
# define RBIMPL_WARNING_PRAGMA2(x, y) RBIMPL_WARNING_PRAGMA1(x # y)
# define RBIMPL_WARNING_PUSH()        RBIMPL_WARNING_PRAGMA1(push)
# define RBIMPL_WARNING_POP()         RBIMPL_WARNING_PRAGMA1(pop)
# define RBIMPL_WARNING_ERROR(flag)   RBIMPL_WARNING_PRAGMA2(error, flag)
# define RBIMPL_WARNING_IGNORED(flag) RBIMPL_WARNING_PRAGMA2(ignored, flag)

#elif RBIMPL_COMPILER_SINCE(GCC, 4, 6, 0)
# /* https://gcc.gnu.org/onlinedocs/gcc-4.6.0/gcc/Diagnostic-Pragmas.html */
# define RBIMPL_WARNING_PRAGMA0(x)    _Pragma(# x)
# define RBIMPL_WARNING_PRAGMA1(x)    RBIMPL_WARNING_PRAGMA0(GCC diagnostic x)
# define RBIMPL_WARNING_PRAGMA2(x, y) RBIMPL_WARNING_PRAGMA1(x # y)
# define RBIMPL_WARNING_PUSH()        RBIMPL_WARNING_PRAGMA1(push)
# define RBIMPL_WARNING_POP()         RBIMPL_WARNING_PRAGMA1(pop)
# define RBIMPL_WARNING_ERROR(flag)   RBIMPL_WARNING_PRAGMA2(error, flag)
# define RBIMPL_WARNING_IGNORED(flag) RBIMPL_WARNING_PRAGMA2(ignored, flag)

#else
# /* :FIXME: improve here */
# define RBIMPL_WARNING_PUSH()        /* void */
# define RBIMPL_WARNING_POP()         /* void */
# define RBIMPL_WARNING_ERROR(flag)   /* void */
# define RBIMPL_WARNING_IGNORED(flag) /* void */
#endif /* _MSC_VER */
/** @endcond */

#endif /* RBIMPL_WARNING_PUSH_H */
ruby/internal/method.h000064400000016121151732674270011011 0ustar00#ifndef RBIMPL_METHOD_H                              /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_METHOD_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Creation and modification of Ruby methods.
 */
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/backward/2/stdarg.h"

/**
 * @defgroup  defmethod  Defining methods
 *
 * There are some APIs to define a method from C.
 * These API takes a C function as a method body.
 *
 * ### Method body functions
 *
 * Method body functions must return a VALUE and
 * can be one of the following form:
 *
 * #### Fixed number of parameters
 *
 * This form is a normal C function, excepting it takes
 * a receiver object as the first argument.
 *
 * ```CXX
 * static VALUE my_method(VALUE self, VALUE x, VALUE y);
 * ```
 *
 * #### argc and argv style
 *
 * This form takes three parameters: argc, argv and self.
 * self is the receiver. argc is the number of arguments.
 * argv is a pointer to an array of the arguments.
 *
 * ```CXX
 * static VALUE my_method(int argc, VALUE *argv, VALUE self);
 * ```
 *
 * #### Ruby array style
 *
 * This form takes two parameters: self and args.
 * self is the receiver. args is an Array object which
 * contains the arguments.
 *
 * ```CXX
 * static VALUE my_method(VALUE self, VALUE args);
 * ```
 *
 * ### Number of parameters
 *
 * Method defining APIs takes the number of parameters which the
 * method will takes. This number is called argc.
 * argc can be:
 *
 *   - Zero or positive number.
 *     This means the method body function takes a fixed number of parameters.
 *
 *   - `-1`.
 *     This means the method body function is "argc and argv" style.
 *
 *   - `-2`.
 *     This means the method body function is "self and args" style.
 *
 * @{
 */

RBIMPL_SYMBOL_EXPORT_BEGIN()

RBIMPL_ATTR_NONNULL(())
/**
 * Defines a method.
 *
 * @param[out]  klass  A module or a class.
 * @param[in]   mid    Name of the function.
 * @param[in]   func   The method body.
 * @param[in]   arity  The number of parameters.  See @ref defmethod.
 * @note        There are in fact 18 different prototypes for func.
 * @see         ::ruby::backward::cxxanyargs::define_method::rb_define_method
 */
void rb_define_method(VALUE klass, const char *mid, VALUE (*func)(ANYARGS), int arity);

RBIMPL_ATTR_NONNULL(())
/**
 * Defines a module function for a module.
 *
 * @param[out]  klass  A module or a class.
 * @param[in]   mid    Name of the function.
 * @param[in]   func   The method body.
 * @param[in]   arity  The number of parameters.  See @ref defmethod.
 * @note        There are in fact 18 different prototypes for func.
 * @see         ::ruby::backward::cxxanyargs::define_method::rb_define_module_function
 */
void rb_define_module_function(VALUE klass, const char *mid, VALUE (*func)(ANYARGS), int arity);

RBIMPL_ATTR_NONNULL(())
/**
 * Defines a global function.
 *
 * @param[in]  mid    Name of the function.
 * @param[in]  func   The method body.
 * @param[in]  arity  The number of parameters.  See @ref defmethod.
 * @note       There are in fact 18 different prototypes for func.
 * @see        ::ruby::backward::cxxanyargs::define_method::rb_define_global_function
 */
void rb_define_global_function(const char *mid, VALUE (*func)(ANYARGS), int arity);

RBIMPL_ATTR_NONNULL(())
/**
 * Defines an undef of a method.  -- What?
 *
 * In ruby, there are two separate concepts called "undef" and "remove_method".
 * The thing you imagine when you  "un-define" a method is remove_method.  This
 * one on the  other hand is masking of a  previous method definition.  Suppose
 * for instance:
 *
 * ```ruby
 * class Foo
 *   def foo
 *   end
 * end
 *
 * class Bar < Foo
 *   def bar
 *     foo
 *   end
 * end
 *
 * class Baz < Foo
 *   undef foo            # <--- (*1)
 * end
 * ```
 *
 * This `undef foo` at `(*1)` must not eliminate `Foo#foo`, because that method
 * is also used from `Bar#bar`.  So  instead of physically executing the target
 * method, `undef` inserts  a special filtering entry to the  class (`Baz` this
 * case).  That entry,  when called, acts as  if there were no  methods at all.
 * But the original can still be accessible, via ways like `Bar#bar` above.
 *
 * @param[out]  klass            The class to insert an undef.
 * @param[in]   name             Name of the undef.
 * @exception   rb_eTypeError    `klass` is a non-module.
 * @exception   rb_eFrozenError  `klass` is frozen.
 * @see         rb_remove_method
 */
void rb_undef_method(VALUE klass, const char *name);

RBIMPL_ATTR_NONNULL(())
/**
 * Defines an alias of a method.
 *
 * @param[in,out]  klass            The class which the original method belongs
 *                                  to; this is also  where the new method will
 *                                  belong to.
 * @param[in]      dst              A new name for the method.
 * @param[in]      src              The original name of the method.
 * @exception      rb_eTypeError    `klass` is a non-module.
 * @exception      rb_eFrozenError  `klass` is frozen.
 * @exception      rb_eNameError    There is  no such method named  as `src` in
 *                                  `klass`.
 *
 * @internal
 *
 * Above  description  is   in  fact  a  bit  inaccurate   because  it  ignores
 * Refinements.
 */
void rb_define_alias(VALUE klass, const char *dst, const char *src);

RBIMPL_ATTR_NONNULL(())
/**
 * Defines public accessor method(s) for an attribute.
 *
 * @param[out]  klass            The class which the attribute will belong to.
 * @param[in]   name             Name of the attribute.
 * @param[in]   read             Whether to define a getter method.
 * @param[in]   write            Whether to define a setter method.
 * @exception   rb_eTypeError    `klass` is a non-module.
 * @exception   rb_eFrozenError  `klass` is frozen.
 * @exception   rb_eNameError    `name` invalid as an attr e.g. an operator.
 */
void rb_define_attr(VALUE klass, const char *name, int read, int write);

/** @} */

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_METHOD_H */
ruby/internal/memory.h000064400000056554151732674270011057 0ustar00#ifndef RBIMPL_MEMORY_H                              /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_MEMORY_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Memory management stuff.
 */
#include "ruby/internal/config.h"

#ifdef STDC_HEADERS
# include <stddef.h>
#endif

#ifdef HAVE_STRING_H
# include <string.h>
#endif

#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif

#ifdef HAVE_ALLOCA_H
# include <alloca.h>
#endif

#if defined(_MSC_VER) && defined(_WIN64)
# include <intrin.h>
# if defined(_M_AMD64)
# pragma intrinsic(_umul128)
# endif
# if defined(_M_ARM64)
# pragma intrinsic(__umulh)
# endif
#endif

#include "ruby/internal/attr/alloc_size.h"
#include "ruby/internal/attr/const.h"
#include "ruby/internal/attr/constexpr.h"
#include "ruby/internal/attr/noalias.h"
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/attr/restrict.h"
#include "ruby/internal/attr/returns_nonnull.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/has/builtin.h"
#include "ruby/internal/stdalign.h"
#include "ruby/internal/stdbool.h"
#include "ruby/internal/stdckdint.h"
#include "ruby/internal/xmalloc.h"
#include "ruby/backward/2/limits.h"
#include "ruby/backward/2/long_long.h"
#include "ruby/backward/2/assume.h"
#include "ruby/defines.h"

/** @cond INTERNAL_MACRO  */

/* Make alloca work the best possible way.  */
#if defined(alloca)
# /* Take that. */
#elif RBIMPL_HAS_BUILTIN(__builtin_alloca)
# define alloca __builtin_alloca
#elif defined(_AIX)
# pragma alloca
#elif defined(__cplusplus)
extern "C" void *alloca(size_t);
#else
extern void *alloca();
#endif

/** @endcond  */

#if defined(__DOXYGEN__)
/**
 * @private
 *
 * Type that is as twice wider as  size_t.  This is an implementation detail of
 * rb_mul_size_overflow().  People should not use it.   This is not a good name
 * either.
 */
typedef uint128_t DSIZE_T;
#elif defined(HAVE_INT128_T) && SIZEOF_SIZE_T <= 8
# define DSIZE_T uint128_t
#elif SIZEOF_SIZE_T * 2 <= SIZEOF_LONG_LONG
# define DSIZE_T unsigned LONG_LONG
#endif

/**
 * @private
 *
 * Maximum  possible  number  of  bytes  that  #RB_ALLOCV  can  allocate  using
 * `alloca`.  Anything  beyond this  is allocated  using rb_alloc_tmp_buffer().
 * This selection is transparent to users.  People don't have to bother.
 */
#ifdef C_ALLOCA
# define RUBY_ALLOCV_LIMIT 0
#else
# define RUBY_ALLOCV_LIMIT 1024
#endif

/**
 * Prevents premature  destruction of local objects.   Ruby's garbage collector
 * is conservative; it  scans the C level machine stack  as well.  Possible in-
 * use Ruby  objects must  remain visible  on stack, to  be properly  marked as
 * such.  However  contemporary C  compilers do not  interface well  with this.
 * Consider the following example:
 *
 * ```CXX
 * auto s = rb_str_new_cstr(" world");
 * auto sptr = RSTRING_PTR(s);
 * auto t = rb_str_new_cstr("hello,"); // Possible GC invocation
 * auto u = rb_str_cat_cstr(t, sptr);
 *
 * RB_GC_GUARD(s); // ensure `s` (and thus `sptr`) do not get GC-ed
 * ```
 *
 * Here, without the #RB_GC_GUARD, the last use of `s` is _before_ the last use
 * of `sptr`.  Compilers  could thus think `s` and `t`  are allowed to overlap.
 * That would eliminate `s`  from the stack, while `sptr` is  still in use.  If
 * our GC  ran at  that very moment,  `s` gets swept  out, which  also destroys
 * `sptr`.  Boom!  You got a SEGV.
 *
 * In order  to prevent this scenario  #RB_GC_GUARD must be placed  _after_ the
 * last use of `sptr`.  Placing  #RB_GC_GUARD before dereferencing `sptr` would
 * be of no use.
 *
 * #RB_GC_GUARD would  not be  necessary at  all in the  above example  if non-
 * inlined  function  calls are  made  on  the  `s`  variable after  `sptr`  is
 * dereferenced.  Thus, in  the above example, calling  any un-inlined function
 * on `s`  such as `rb_str_modify(s);`  will ensure `s`  stays on the  stack or
 * register to prevent a GC invocation from prematurely freeing it.
 *
 * Using the #RB_GC_GUARD  macro is preferable to using  the `volatile` keyword
 * in C.  #RB_GC_GUARD has the following advantages:
 *
 *  - the intent of the macro use is clear.
 *
 *  - #RB_GC_GUARD only affects its call  site.  OTOH `volatile` generates some
 *    extra code every time the variable is used, hurting optimisation.
 *
 *  - `volatile` implementations  may be  buggy/inconsistent in  some compilers
 *    and   architectures.     #RB_GC_GUARD   is   customisable    for   broken
 *    systems/compilers without negatively affecting other systems.
 *
 *  - C++  since C++20  deprecates  `volatile`.  If  you  write your  extension
 *    library in that language there is no escape but to use this macro.
 *
 * @param  v  A variable of ::VALUE type.
 * @post   `v` is still alive.
 */
#ifdef __GNUC__
#define RB_GC_GUARD(v) \
    (*__extension__ ({ \
        volatile VALUE *rb_gc_guarded_ptr = &(v); \
        __asm__("" : : "m"(rb_gc_guarded_ptr)); \
        rb_gc_guarded_ptr; \
    }))
#elif defined _MSC_VER
#define RB_GC_GUARD(v) (*rb_gc_guarded_ptr(&(v)))
#else
#define HAVE_RB_GC_GUARDED_PTR_VAL 1
#define RB_GC_GUARD(v) (*rb_gc_guarded_ptr_val(&(v),(v)))
#endif

/* Casts needed because void* is NOT compatible with others in C++. */

/**
 * Convenient macro that allocates an array of n elements.
 *
 * @param      type            Type of array elements.
 * @param      n               Length of the array.
 * @exception  rb_eNoMemError  No space left for allocation.
 * @exception  rb_eArgError    Integer overflow trying  to calculate the length
 *                             of continuous  memory region of `n`  elements of
 *                             `type`.
 * @return     Storage  instance  that  is  capable of  storing  at  least  `n`
 *             elements of type `type`.
 * @note       It doesn't return NULL, even when `n` is zero.
 * @warning    The return  value shall  be invalidated  exactly once  by either
 *             ruby_xfree(),  ruby_xrealloc(), or  ruby_xrealloc2().   It is  a
 *             failure to pass it to system free(), because the system and Ruby
 *             might or might not share the same malloc() implementation.
 */
#define RB_ALLOC_N(type,n)  RBIMPL_CAST((type *)ruby_xmalloc2((n), sizeof(type)))

/**
 * Shorthand of #RB_ALLOC_N with `n=1`.
 *
 * @param      type            Type of allocation.
 * @exception  rb_eNoMemError  No space left for allocation.
 * @return     Storage instance that can hold an `type` object.
 * @note       It doesn't return NULL.
 * @warning    The return  value shall  be invalidated  exactly once  by either
 *             ruby_xfree(),  ruby_xrealloc(), or  ruby_xrealloc2().   It is  a
 *             failure to pass it to system free(), because the system and Ruby
 *             might or might not share the same malloc() implementation.
 */
#define RB_ALLOC(type)      RBIMPL_CAST((type *)ruby_xmalloc(sizeof(type)))

/**
 * Identical to  #RB_ALLOC_N() but also  nullifies the allocated  region before
 * returning.
 *
 * @param      type            Type of array elements.
 * @param      n               Length of the array.
 * @exception  rb_eNoMemError  No space left for allocation.
 * @exception  rb_eArgError    Integer overflow trying  to calculate the length
 *                             of continuous  memory region of `n`  elements of
 *                             `type`.
 * @return     Storage  instance  that  is  capable of  storing  at  least  `n`
 *             elements of type `type`.
 * @post       Returned array is filled with zeros.
 * @note       It doesn't return NULL, even when `n` is zero.
 * @warning    The return  value shall  be invalidated  exactly once  by either
 *             ruby_xfree(),  ruby_xrealloc(), or  ruby_xrealloc2().   It is  a
 *             failure to pass it to system free(), because the system and Ruby
 *             might or might not share the same malloc() implementation.
 */
#define RB_ZALLOC_N(type,n) RBIMPL_CAST((type *)ruby_xcalloc((n), sizeof(type)))

/**
 * Shorthand of #RB_ZALLOC_N with `n=1`.
 *
 * @param      type            Type of allocation.
 * @exception  rb_eNoMemError  No space left for allocation.
 * @return     Storage instance that can hold an `type` object.
 * @post       Returned object is filled with zeros.
 * @note       It doesn't return NULL.
 * @warning    The return  value shall  be invalidated  exactly once  by either
 *             ruby_xfree(),  ruby_xrealloc(), or  ruby_xrealloc2().   It is  a
 *             failure to pass it to system free(), because the system and Ruby
 *             might or might not share the same malloc() implementation.
 */
#define RB_ZALLOC(type)     (RB_ZALLOC_N(type, 1))

/**
 * Convenient macro that reallocates an array with a new size.
 *
 * @param      var             A variable of `type`,  which points to a storage
 *                             instance  that  was   previously  returned  from
 *                             either
 *                               - ruby_xmalloc(),
 *                               - ruby_xmalloc2(),
 *                               - ruby_xcalloc(),
 *                               - ruby_xrealloc(), or
 *                               - ruby_xrealloc2().
 * @param      type            Type of allocation.
 * @param      n               Requested new size of each element.
 * @exception  rb_eNoMemError  No space left for  allocation.
 * @exception  rb_eArgError    Integer overflow trying  to calculate the length
 *                             of continuous  memory region of `n`  elements of
 *                             `type`.
 * @return     Storage  instance  that  is  capable of  storing  at  least  `n`
 *             elements of type `type`.
 * @pre        The passed variable must point to a valid live storage instance.
 *             It is a  failure to pass a variable that  holds an already-freed
 *             pointer.
 * @note       It doesn't return NULL, even when `n` is zero.
 * @warning    Do not  assume anything  on the alignment  of the  return value.
 *             There is  no guarantee  that it  inherits the  passed argument's
 *             one.
 * @warning    The return  value shall  be invalidated  exactly once  by either
 *             ruby_xfree(),  ruby_xrealloc(), or  ruby_xrealloc2().   It is  a
 *             failure to pass it to system free(), because the system and Ruby
 *             might or might not share the same malloc() implementation.
 */
#define RB_REALLOC_N(var,type,n) \
    ((var) = RBIMPL_CAST((type *)ruby_xrealloc2((void *)(var), (n), sizeof(type))))

/**
 * @deprecated  This  macro is  dangerous (does  not bother  stack overflow  at
 *              all).  #RB_ALLOCV is the modern way to do the same thing.
 * @param       type  Type of array elements.
 * @param       n     Length of the array.
 * @return      A pointer on stack.
 */
#define ALLOCA_N(type,n) \
    RBIMPL_CAST((type *)alloca(rbimpl_size_mul_or_raise(sizeof(type), (n))))

/**
 * Identical to #RB_ALLOCV_N(), except that it allocates a number of bytes and
 * returns a void* .
 *
 * @param   v  A variable to hold the just-in-case opaque Ruby object.
 * @param   n  Size of allocation, in bytes.
 * @return  A void pointer to `n` bytes storage.
 * @note    `n` may be evaluated twice.
 */
#define RB_ALLOCV(v, n)        \
    ((n) < RUBY_ALLOCV_LIMIT ? \
     ((v) = 0, alloca(n)) :    \
     rb_alloc_tmp_buffer(&(v), (n)))

/**
 * Allocates a  memory region, possibly  on stack.   If the given  size exceeds
 * #RUBY_ALLOCV_LIMIT, it allocates a dedicated  opaque ruby object instead and
 * let our GC sweep that region after use.  Either way you can fire-and-forget.
 *
 * ```CXX
 * #include <sys/types.h>
 *
 * VALUE
 * foo(int n)
 * {
 *     VALUE v;
 *     auto ptr = RB_ALLOCV(struct tms, v, n);
 *     ...
 *     // no need to free `ptr`.
 * }
 * ```
 *
 * If you want to  be super-duper polite you can also  explicitly state the end
 * of use of such memory region by calling #RB_ALLOCV_END().
 *
 * @param   type  The type of array elements.
 * @param   v     A variable to hold the just-in-case opaque Ruby object.
 * @param   n     Number of elements requested to allocate.
 * @return  An array of `n` elements of `type`.
 * @note    `n` may be evaluated twice.
 */
#define RB_ALLOCV_N(type, v, n)                             \
    RBIMPL_CAST((type *)                                     \
        (((size_t)(n) < RUBY_ALLOCV_LIMIT / sizeof(type)) ? \
         ((v) = 0, alloca((n) * sizeof(type))) :            \
         rb_alloc_tmp_buffer2(&(v), (n), sizeof(type))))

/**
 * Polite way to declare that the given  array is not used any longer.  Calling
 * this not mandatory.  Our GC can baby-sit  you.  However it is not a very bad
 * idea to use it when possible.  Doing so could reduce memory footprint.
 *
 * @param  v  A variable previously passed to either #RB_ALLOCV/#RB_ALLOCV_N.
 */
#define RB_ALLOCV_END(v) rb_free_tmp_buffer(&(v))

/**
 * Handy macro to erase a region of memory.
 *
 * @param   p     Target pointer.
 * @param   type  Type of `p[0]`
 * @param   n     Length of `p`.
 * @return  `p`.
 * @post    First `n` elements of `p` are squashed.
 */
#define MEMZERO(p,type,n) memset((p), 0, rbimpl_size_mul_or_raise(sizeof(type), (n)))

/**
 * Handy macro to call memcpy.
 *
 * @param   p1    Destination pointer.
 * @param   p2    Source pointer.
 * @param   type  Type of `p2[0]`
 * @param   n     Length of `p2`.
 * @return  `p1`.
 * @post    First `n` elements of `p2` are copied into `p1`.
 */
#define MEMCPY(p1,p2,type,n) ruby_nonempty_memcpy((p1), (p2), rbimpl_size_mul_or_raise(sizeof(type), (n)))

/**
 * Handy macro to call memmove.
 *
 * @param  p1    Destination pointer.
 * @param  p2    Source pointer.
 * @param  type  Type of `p2[0]`
 * @param  n     Length of `p2`.
 * @return `p1`.
 * @post   First `n` elements of `p2` are copied into `p1`.
 */
#define MEMMOVE(p1,p2,type,n) memmove((p1), (p2), rbimpl_size_mul_or_raise(sizeof(type), (n)))

/**
 * Handy macro to call memcmp
 *
 * @param   p1    Target LHS.
 * @param   p2    Target RHS.
 * @param   type  Type of `p1[0]`
 * @param   n     Length of `p1`.
 * @retval  <0    `p1` is "less" than `p2`.
 * @retval  0     `p1` is equal to `p2`.
 * @retval  >0    `p1` is "greater" than `p2`.
 */
#define MEMCMP(p1,p2,type,n) memcmp((p1), (p2), rbimpl_size_mul_or_raise(sizeof(type), (n)))

#define ALLOC_N    RB_ALLOC_N    /**< @old{RB_ALLOC_N} */
#define ALLOC      RB_ALLOC      /**< @old{RB_ALLOC} */
#define ZALLOC_N   RB_ZALLOC_N   /**< @old{RB_ZALLOC_N} */
#define ZALLOC     RB_ZALLOC     /**< @old{RB_ZALLOC} */
#define REALLOC_N  RB_REALLOC_N  /**< @old{RB_REALLOC_N} */
#define ALLOCV     RB_ALLOCV     /**< @old{RB_ALLOCV} */
#define ALLOCV_N   RB_ALLOCV_N   /**< @old{RB_ALLOCV_N} */
#define ALLOCV_END RB_ALLOCV_END /**< @old{RB_ALLOCV_END} */

/**
 * @private
 *
 * This is an implementation detail of rbimpl_size_mul_overflow().
 *
 * @internal
 *
 * Expecting  this struct  to be  eliminated  by function  inlinings.  This  is
 * nothing more than std::variant<std::size_t> if  we could use recent C++, but
 * reality is we cannot.
 */
struct rbimpl_size_mul_overflow_tag {
    bool left;                  /**< Whether overflow happened or not. */
    size_t right;               /**< Multiplication result. */
};

RBIMPL_SYMBOL_EXPORT_BEGIN()
RBIMPL_ATTR_RESTRICT()
RBIMPL_ATTR_RETURNS_NONNULL()
RBIMPL_ATTR_ALLOC_SIZE((2))
RBIMPL_ATTR_NONNULL(())
/**
 * @private
 *
 * This is  an implementation  detail of #RB_ALLOCV().   People don't  use this
 * directly.
 *
 * @param[out]  store  Pointer to a variable.
 * @param[in]   len    Requested number of bytes to allocate.
 * @return      Allocated `len` bytes array.
 * @post        `store` holds the corresponding tmp buffer object.
 */
void *rb_alloc_tmp_buffer(volatile VALUE *store, long len);

RBIMPL_ATTR_RESTRICT()
RBIMPL_ATTR_RETURNS_NONNULL()
RBIMPL_ATTR_ALLOC_SIZE((2,3))
RBIMPL_ATTR_NONNULL(())
/**
 * @private
 *
 * This is an  implementation detail of #RB_ALLOCV_N().  People  don't use this
 * directly.
 *
 * @param[out]  store  Pointer to a variable.
 * @param[in]   len    Requested number of bytes to allocate.
 * @param[in]   count  Number of elements in an array.
 * @return      Allocated `len` bytes array.
 * @post        `store` holds the corresponding tmp buffer object.
 *
 * @internal
 *
 * Although  the  meaning  of  `count` variable  is  clear,  @shyouhei  doesn't
 * understand its needs.
 */
void *rb_alloc_tmp_buffer_with_count(volatile VALUE *store, size_t len,size_t count);

/**
 * @private
 *
 * This is an implementation detail of #RB_ALLOCV_END().  People don't use this
 * directly.
 *
 * @param[out]  store  Pointer to a variable.
 * @pre         `store` is a NULL, or a pointer to a tmp buffer object.
 * @post        `*store` is ::RUBY_Qfalse.
 * @post        The object formerly stored in `store` is destroyed.
 */
void rb_free_tmp_buffer(volatile VALUE *store);

RBIMPL_ATTR_NORETURN()
/**
 * @private
 *
 * This is an  implementation detail of #RB_ALLOCV_N().  People  don't use this
 * directly.
 *
 * @param[in]  x             Arbitrary value.
 * @param[in]  y             Arbitrary value.
 * @exception  rb_eArgError  `x` * `y` would integer overflow.
 */
void ruby_malloc_size_overflow(size_t x, size_t y);

#ifdef HAVE_RB_GC_GUARDED_PTR_VAL
volatile VALUE *rb_gc_guarded_ptr_val(volatile VALUE *ptr, VALUE val);
#endif
RBIMPL_SYMBOL_EXPORT_END()

#ifdef _MSC_VER
# pragma optimize("", off)

/**
 * @private
 *
 * This is an  implementation detail of #RB_GC_GUARD().  People  don't use this
 * directly.
 *
 * @param[in]  ptr  A pointer to an on-stack C variable.
 * @return     `ptr` as-is.
 */
static inline volatile VALUE *
rb_gc_guarded_ptr(volatile VALUE *ptr)
{
    return ptr;
}

# pragma optimize("", on)
#endif

/**
 * @deprecated  This   function   was   an   implementation   detail   of   old
 *              #RB_ALLOCV_N().  We no longer  use it.  @shyouhei suspects that
 *              there are  no actual usage now.   However it was not  marked as
 *              private before.  We cannot delete it any longer.
 * @param[in]   a    Arbitrary value.
 * @param[in]   b    Arbitrary value.
 * @param[in]   max  Possible maximum value.
 * @param[out]  c    A pointer to return the computation result.
 * @retval      1    `c` is insane.
 * @retval      0    `c` is sane.
 * @post        `c` holds `a` * `b`, but could be overflowed.
 */
static inline int
rb_mul_size_overflow(size_t a, size_t b, size_t max, size_t *c)
{
#ifdef DSIZE_T
    RB_GNUC_EXTENSION DSIZE_T da, db, c2;
    da = a;
    db = b;
    c2 = da * db;
    if (c2 > max) return 1;
    *c = RBIMPL_CAST((size_t)c2);
#else
    if (b != 0 && a > max / b) return 1;
    *c = a * b;
#endif
    return 0;
}

#if defined(__DOXYGEN__)
RBIMPL_ATTR_CONSTEXPR(CXX14)
#elif RBIMPL_COMPILER_SINCE(GCC, 7, 0, 0)
RBIMPL_ATTR_CONSTEXPR(CXX14) /* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70507 */
#elif RBIMPL_COMPILER_SINCE(Clang, 7, 0, 0)
RBIMPL_ATTR_CONSTEXPR(CXX14) /* https://bugs.llvm.org/show_bug.cgi?id=37633 */
#endif
RBIMPL_ATTR_CONST()
/**
 * @private
 *
 * This is an  implementation detail of #RB_ALLOCV_N().  People  don't use this
 * directly.
 *
 * @param[in]  x  Arbitrary value.
 * @param[in]  y  Arbitrary value.
 * @return     `{ left, right }`,  where `left` is whether there  is an integer
 *             overflow or not,  and `right` is a  (possibly overflowed) result
 *             of `x` * `y`.
 *
 * @internal
 *
 * This is in fact also an implementation detail of ruby_xmalloc2() etc.
 */
static inline struct rbimpl_size_mul_overflow_tag
rbimpl_size_mul_overflow(size_t x, size_t y)
{
    struct rbimpl_size_mul_overflow_tag ret = { false,  0, };

#if defined(ckd_mul)
    ret.left = ckd_mul(&ret.right, x, y);

#elif RBIMPL_HAS_BUILTIN(__builtin_mul_overflow)
    ret.left = __builtin_mul_overflow(x, y, &ret.right);

#elif defined(DSIZE_T)
    RB_GNUC_EXTENSION DSIZE_T dx = x;
    RB_GNUC_EXTENSION DSIZE_T dy = y;
    RB_GNUC_EXTENSION DSIZE_T dz = dx * dy;
    ret.left  = dz > SIZE_MAX;
    ret.right = RBIMPL_CAST((size_t)dz);

#elif defined(_MSC_VER) && defined(_M_AMD64)
    unsigned __int64 dp = 0;
    unsigned __int64 dz = _umul128(x, y, &dp);
    ret.left  = RBIMPL_CAST((bool)dp);
    ret.right = RBIMPL_CAST((size_t)dz);

#elif defined(_MSC_VER) && defined(_M_ARM64)
    ret.left  = __umulh(x, y) != 0;
    ret.right = x * y;

#else
    /* https://wiki.sei.cmu.edu/confluence/display/c/INT30-C.+Ensure+that+unsigned+integer+operations+do+not+wrap */
    ret.left  = (y != 0) && (x > SIZE_MAX / y);
    ret.right = x * y;
#endif

    return ret;
}

/**
 * @private
 *
 * This is an  implementation detail of #RB_ALLOCV_N().  People  don't use this
 * directly.
 *
 * @param[in]  x             Arbitrary value.
 * @param[in]  y             Arbitrary value.
 * @exception  rb_eArgError  Multiplication could integer overflow.
 * @return     `x` * `y`.
 *
 * @internal
 *
 * This is in fact also an implementation detail of ruby_xmalloc2() etc.
 */
static inline size_t
rbimpl_size_mul_or_raise(size_t x, size_t y)
{
    struct rbimpl_size_mul_overflow_tag size =
        rbimpl_size_mul_overflow(x, y);

    if (RB_LIKELY(! size.left)) {
        return size.right;
    }
    else {
        ruby_malloc_size_overflow(x, y);
        RBIMPL_UNREACHABLE_RETURN(0);
    }
}

/**
 * This is an  implementation detail of #RB_ALLOCV_N().  People  don't use this
 * directly.
 *
 * @param[out]  store   Pointer to a variable.
 * @param[in]   count   Number of elements in an array.
 * @param[in]   elsize  Size of each elements.
 * @return      Region of `count` * `elsize` bytes.
 * @post        `store` holds the corresponding tmp buffer object.
 *
 * @internal
 *
 * We might want to deprecate this function and make a `rbimpl_` counterpart.
 */
static inline void *
rb_alloc_tmp_buffer2(volatile VALUE *store, long count, size_t elsize)
{
    const size_t total_size = rbimpl_size_mul_or_raise(RBIMPL_CAST((size_t)count), elsize);
    const size_t cnt = (total_size + sizeof(VALUE) - 1) / sizeof(VALUE);
    return rb_alloc_tmp_buffer_with_count(store, total_size, cnt);
}

RBIMPL_SYMBOL_EXPORT_BEGIN()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
RBIMPL_ATTR_RETURNS_NONNULL()
/* At least since 2004, glibc's <string.h> annotates memcpy to be
 * __attribute__((__nonnull__(1, 2))).  However it is safe to pass NULL to the
 * source pointer, if n is 0.  Let's wrap memcpy. */
static inline void *
ruby_nonempty_memcpy(void *dest, const void *src, size_t n)
{
    if (n) {
        return memcpy(dest, src, n);
    }
    else {
        return dest;
    }
}
RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_MEMORY_H */
ruby/st.h000064400000016751151732674270006354 0ustar00/* This is a public domain general purpose hash table package
   originally written by Peter Moore @ UCB.

   The hash table data structures were redesigned and the package was
   rewritten by Vladimir Makarov <vmakarov@redhat.com>.  */

#ifndef RUBY_ST_H
#define RUBY_ST_H 1

#if defined(__cplusplus)
extern "C" {
#if 0
} /* satisfy cc-mode */
#endif
#endif

#include "ruby/defines.h"

RUBY_SYMBOL_EXPORT_BEGIN

#if SIZEOF_LONG == SIZEOF_VOIDP
typedef unsigned long st_data_t;
#elif SIZEOF_LONG_LONG == SIZEOF_VOIDP
typedef unsigned LONG_LONG st_data_t;
#else
# error ---->> st.c requires sizeof(void*) == sizeof(long) or sizeof(LONG_LONG) to be compiled. <<----
#endif
#define ST_DATA_T_DEFINED

#ifndef CHAR_BIT
# ifdef HAVE_LIMITS_H
#  include <limits.h>
# else
#  define CHAR_BIT 8
# endif
#endif
#ifndef _
# define _(args) args
#endif
#ifndef ANYARGS
# ifdef __cplusplus
#   define ANYARGS ...
# else
#   define ANYARGS
# endif
#endif

typedef struct st_table st_table;

typedef st_data_t st_index_t;

/* Maximal value of unsigned integer type st_index_t.  */
#define MAX_ST_INDEX_VAL (~(st_index_t) 0)

typedef int st_compare_func(st_data_t, st_data_t);
typedef st_index_t st_hash_func(st_data_t);

typedef char st_check_for_sizeof_st_index_t[SIZEOF_VOIDP == (int)sizeof(st_index_t) ? 1 : -1];
#define SIZEOF_ST_INDEX_T SIZEOF_VOIDP

struct st_hash_type {
    int (*compare)(st_data_t, st_data_t); /* st_compare_func* */
    st_index_t (*hash)(st_data_t);        /* st_hash_func* */
};

#define ST_INDEX_BITS (SIZEOF_ST_INDEX_T * CHAR_BIT)

#if defined(HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR) && defined(HAVE_BUILTIN___BUILTIN_TYPES_COMPATIBLE_P)
# define ST_DATA_COMPATIBLE_P(type) \
   __builtin_choose_expr(__builtin_types_compatible_p(type, st_data_t), 1, 0)
#else
# define ST_DATA_COMPATIBLE_P(type) 0
#endif

typedef struct st_table_entry st_table_entry;

struct st_table_entry; /* defined in st.c */

struct st_table {
    /* Cached features of the table -- see st.c for more details.  */
    unsigned char entry_power, bin_power, size_ind;
    /* How many times the table was rebuilt.  */
    unsigned int rebuilds_num;
    const struct st_hash_type *type;
    /* Number of entries currently in the table.  */
    st_index_t num_entries;
    /* Array of bins used for access by keys.  */
    st_index_t *bins;
    /* Start and bound index of entries in array entries.
       entries_starts and entries_bound are in interval
       [0,allocated_entries].  */
    st_index_t entries_start, entries_bound;
    /* Array of size 2^entry_power.  */
    st_table_entry *entries;
};

#define st_is_member(table,key) st_lookup((table),(key),(st_data_t *)0)

enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE, ST_CHECK, ST_REPLACE};

size_t rb_st_table_size(const struct st_table *tbl);
#define st_table_size rb_st_table_size
st_table *rb_st_init_table(const struct st_hash_type *);
#define st_init_table rb_st_init_table
st_table *rb_st_init_table_with_size(const struct st_hash_type *, st_index_t);
#define st_init_table_with_size rb_st_init_table_with_size
st_table *rb_st_init_numtable(void);
#define st_init_numtable rb_st_init_numtable
st_table *rb_st_init_numtable_with_size(st_index_t);
#define st_init_numtable_with_size rb_st_init_numtable_with_size
st_table *rb_st_init_strtable(void);
#define st_init_strtable rb_st_init_strtable
st_table *rb_st_init_strtable_with_size(st_index_t);
#define st_init_strtable_with_size rb_st_init_strtable_with_size
st_table *rb_st_init_strcasetable(void);
#define st_init_strcasetable rb_st_init_strcasetable
st_table *rb_st_init_strcasetable_with_size(st_index_t);
#define st_init_strcasetable_with_size rb_st_init_strcasetable_with_size
int rb_st_delete(st_table *, st_data_t *, st_data_t *); /* returns 0:notfound 1:deleted */
#define st_delete rb_st_delete
int rb_st_delete_safe(st_table *, st_data_t *, st_data_t *, st_data_t);
#define st_delete_safe rb_st_delete_safe
int rb_st_shift(st_table *, st_data_t *, st_data_t *); /* returns 0:notfound 1:deleted */
#define st_shift rb_st_shift
int rb_st_insert(st_table *, st_data_t, st_data_t);
#define st_insert rb_st_insert
int rb_st_insert2(st_table *, st_data_t, st_data_t, st_data_t (*)(st_data_t));
#define st_insert2 rb_st_insert2
int rb_st_lookup(st_table *, st_data_t, st_data_t *);
#define st_lookup rb_st_lookup
int rb_st_get_key(st_table *, st_data_t, st_data_t *);
#define st_get_key rb_st_get_key
typedef int st_update_callback_func(st_data_t *key, st_data_t *value, st_data_t arg, int existing);
/* *key may be altered, but must equal to the old key, i.e., the
 * results of hash() are same and compare() returns 0, otherwise the
 * behavior is undefined */
int rb_st_update(st_table *table, st_data_t key, st_update_callback_func *func, st_data_t arg);
#define st_update rb_st_update
typedef int st_foreach_callback_func(st_data_t, st_data_t, st_data_t);
typedef int st_foreach_check_callback_func(st_data_t, st_data_t, st_data_t, int);
int rb_st_foreach_with_replace(st_table *tab, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg);
#define st_foreach_with_replace rb_st_foreach_with_replace
int rb_st_foreach(st_table *, st_foreach_callback_func *, st_data_t);
#define st_foreach rb_st_foreach
int rb_st_foreach_check(st_table *, st_foreach_check_callback_func *, st_data_t, st_data_t);
#define st_foreach_check rb_st_foreach_check
st_index_t rb_st_keys(st_table *table, st_data_t *keys, st_index_t size);
#define st_keys rb_st_keys
st_index_t rb_st_keys_check(st_table *table, st_data_t *keys, st_index_t size, st_data_t never);
#define st_keys_check rb_st_keys_check
st_index_t rb_st_values(st_table *table, st_data_t *values, st_index_t size);
#define st_values rb_st_values
st_index_t rb_st_values_check(st_table *table, st_data_t *values, st_index_t size, st_data_t never);
#define st_values_check rb_st_values_check
void rb_st_add_direct(st_table *, st_data_t, st_data_t);
#define st_add_direct rb_st_add_direct
void rb_st_free_table(st_table *);
#define st_free_table rb_st_free_table
void rb_st_cleanup_safe(st_table *, st_data_t);
#define st_cleanup_safe rb_st_cleanup_safe
void rb_st_clear(st_table *);
#define st_clear rb_st_clear
st_table *rb_st_copy(st_table *);
#define st_copy rb_st_copy
CONSTFUNC(int rb_st_numcmp(st_data_t, st_data_t));
#define st_numcmp rb_st_numcmp
CONSTFUNC(st_index_t rb_st_numhash(st_data_t));
#define st_numhash rb_st_numhash
PUREFUNC(int rb_st_locale_insensitive_strcasecmp(const char *s1, const char *s2));
#define st_locale_insensitive_strcasecmp rb_st_locale_insensitive_strcasecmp
PUREFUNC(int rb_st_locale_insensitive_strncasecmp(const char *s1, const char *s2, size_t n));
#define st_locale_insensitive_strncasecmp rb_st_locale_insensitive_strncasecmp
#define st_strcasecmp rb_st_locale_insensitive_strcasecmp
#define st_strncasecmp rb_st_locale_insensitive_strncasecmp
PUREFUNC(size_t rb_st_memsize(const st_table *));
#define st_memsize rb_st_memsize
PUREFUNC(st_index_t rb_st_hash(const void *ptr, size_t len, st_index_t h));
#define st_hash rb_st_hash
CONSTFUNC(st_index_t rb_st_hash_uint32(st_index_t h, uint32_t i));
#define st_hash_uint32 rb_st_hash_uint32
CONSTFUNC(st_index_t rb_st_hash_uint(st_index_t h, st_index_t i));
#define st_hash_uint rb_st_hash_uint
CONSTFUNC(st_index_t rb_st_hash_end(st_index_t h));
#define st_hash_end rb_st_hash_end
CONSTFUNC(st_index_t rb_st_hash_start(st_index_t h));
#define st_hash_start(h) ((st_index_t)(h))

void rb_hash_bulk_insert_into_st_table(long, const VALUE *, VALUE);

RUBY_SYMBOL_EXPORT_END

#if defined(__cplusplus)
#if 0
{ /* satisfy cc-mode */
#endif
}  /* extern "C" { */
#endif

#endif /* RUBY_ST_H */
ruby/random.h000064400000027006151732674270007201 0ustar00#ifndef RUBY_RANDOM_H                                /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_RANDOM_H 1
/**
 * @file
 * @date       Sat May  7 11:51:14 JST 2016
 * @copyright  2007-2020 Yukihiro Matsumoto
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 *
 * This  is a  set of  APIs  to roll  your  own subclass  of ::rb_cRandom.   An
 * illustrative    example     of    such     PRNG    can    be     found    at
 * `ext/-test-/random/loop.c`.
 */

#include "ruby/ruby.h"

/*
 * version
 * 0: before versioning; deprecated
 * 1: added version, flags and init_32bit function
 */
#define RUBY_RANDOM_INTERFACE_VERSION_MAJOR 1
#define RUBY_RANDOM_INTERFACE_VERSION_MINOR 0

#define RUBY_RANDOM_PASTE_VERSION_SUFFIX(x, y, z) x##_##y##_##z
#define RUBY_RANDOM_WITH_VERSION_SUFFIX(name, major, minor) \
    RUBY_RANDOM_PASTE_VERSION_SUFFIX(name, major, minor)
#define rb_random_data_type \
    RUBY_RANDOM_WITH_VERSION_SUFFIX(rb_random_data_type, \
                                    RUBY_RANDOM_INTERFACE_VERSION_MAJOR, \
                                    RUBY_RANDOM_INTERFACE_VERSION_MINOR)
#define RUBY_RANDOM_INTERFACE_VERSION_INITIALIZER \
    {RUBY_RANDOM_INTERFACE_VERSION_MAJOR, RUBY_RANDOM_INTERFACE_VERSION_MINOR}
#define RUBY_RANDOM_INTERFACE_VERSION_MAJOR_MAX 0xff
#define RUBY_RANDOM_INTERFACE_VERSION_MINOR_MAX 0xff

RBIMPL_SYMBOL_EXPORT_BEGIN()

/**
 * Base components of the random interface.
 *
 * @internal
 *
 * Ideally this  could be an  empty class if  we could assume  C++, but in  C a
 * struct must have at least one field.
 */
struct rb_random_struct {
    /** Seed, passed through e.g. `Random.new` */
    VALUE seed;
};
typedef struct rb_random_struct rb_random_t; /**< @see ::rb_random_struct */

RBIMPL_ATTR_NONNULL(())
/**
 * This is the type of functions called when your random object is initialised.
 * Passed buffer  is the seed  object basically.  But in  Ruby a number  can be
 * really big.  This type of functions accept  such big integers as a series of
 * machine words.
 *
 * @param[out]  rng  Your random struct to fill in.
 * @param[in]   buf  Seed, maybe converted from a bignum.
 * @param[in]   len  Number of words of `buf`.
 * @post        `rng` is initialised using the passed seeds.
 */
typedef void rb_random_init_func(rb_random_t *rng, const uint32_t *buf, size_t len);

RBIMPL_ATTR_NONNULL(())
/**
 * This is the type of functions called when your random object is initialised.
 * Passed data is the seed integer.
 *
 * @param[out]  rng  Your random struct to fill in.
 * @param[in]   data Seed, single word.
 * @post        `rng` is initialised using the passed seeds.
 */
typedef void rb_random_init_int32_func(rb_random_t *rng, uint32_t data);

RBIMPL_ATTR_NONNULL(())
/**
 * This is the type of functions  called from your object's `#rand` method.
 *
 * @param[out]  rng  Your random struct to extract an integer from.
 * @return      A random number.
 * @post        `rng` is consumed somehow.
 */
typedef unsigned int rb_random_get_int32_func(rb_random_t *rng);

RBIMPL_ATTR_NONNULL(())
/**
 * This is the type of functions called from your object's `#bytes` method.
 *
 * @param[out]  rng  Your random struct to extract an integer from.
 * @param[out]  buf  Return buffer of at least `len` bytes length.
 * @param[in]   len  Number of bytes of `buf`.
 * @post        `rng` is consumed somehow.
 * @post        `buf` is filled with random bytes.
 */
typedef void rb_random_get_bytes_func(rb_random_t *rng, void *buf, size_t len);

RBIMPL_ATTR_NONNULL(())
/**
 * This is the type of functions called from your object's `#rand` method.
 *
 * @param[out]  rng   Your random struct to extract an integer from.
 * @param[in]   excl  Pass nonzero value here to indicate you don't want 1.0.
 * @return      A random number of range 0.0 to 1.0.
 * @post        `rng` is consumed somehow.
 */
typedef double rb_random_get_real_func(rb_random_t *rng, int excl);

/** PRNG algorithmic interface, analogous to Ruby level classes. */
typedef struct {
    /** Number of bits of seed numbers. */
    size_t default_seed_bits;

    /**
     * Major/minor versions of this interface
     */
    struct {
        uint8_t major, minor;
    } version;

    /**
     * Reserved flags
     */
    uint16_t flags;

    /** Function to initialize from uint32_t array. */
    rb_random_init_func *init;

    /** Function to initialize from single uint32_t. */
    rb_random_init_int32_func *init_int32;

    /** Function to obtain a random integer. */
    rb_random_get_int32_func *get_int32;

    /**
     * Function to obtain a series of random bytes.  If your PRNG have a native
     * method to  yield arbitrary number of  bytes use that to  implement this.
     * But  in   case  you  lack   such  things,  you   can  do  so   by  using
     * rb_rand_bytes_int32()
     *
     * ```CXX
     * extern rb_random_get_int32_func your_get_int32_func;
     *
     * void
     * your_get_byes_func(rb_random_t *rng, void *buf, size_t len)
     * {
     *     rb_rand_bytes_int32(your_get_int32_func, rng, buf, len);
     * }
     * ```
     */
    rb_random_get_bytes_func *get_bytes;

    /**
     * Function to obtain  a random double.  If your PRNG  have a native method
     * to yield a floating point random number use that to implement this.  But
     * in   case   you  lack   such   things,   you   can   do  so   by   using
     * rb_int_pair_to_real().
     *
     * ```CXX
     * extern rb_random_get_int32_func your_get_int32_func;
     *
     * void
     * your_get_real_func(rb_random_t *rng, int excl)
     * {
     *     auto a = your_get_int32_func(rng);
     *     auto b = your_get_int32_func(rng);
     *     return rb_int_pair_to_real(a, b, excl);
     * }
     * ```
     */
    rb_random_get_real_func *get_real;
} rb_random_interface_t;

/**
 * This utility macro defines 4 functions named prefix_init, prefix_init_int32,
 * prefix_get_int32, prefix_get_bytes.
 */
#define RB_RANDOM_INTERFACE_DECLARE(prefix) \
    static void prefix##_init(rb_random_t *, const uint32_t *, size_t); \
    static void prefix##_init_int32(rb_random_t *, uint32_t); \
    static unsigned int prefix##_get_int32(rb_random_t *); \
    static void prefix##_get_bytes(rb_random_t *, void *, size_t)

/**
 * Identical   to   #RB_RANDOM_INTERFACE_DECLARE   except  it   also   declares
 * prefix_get_real.
 */
#define RB_RANDOM_INTERFACE_DECLARE_WITH_REAL(prefix) \
    RB_RANDOM_INTERFACE_DECLARE(prefix); \
    static double prefix##_get_real(rb_random_t *, int)

/**
 * This    utility    macro   expands    to    the    names   declared    using
 * #RB_RANDOM_INTERFACE_DECLARE.    Expected   to   be   used   inside   of   a
 * ::rb_random_interface_t initialiser:
 *
 * ```CXX
 * RB_RANDOM_INTERFACE_DECLARE(foo);
 *
 * static inline constexpr rb_random_interface_t foo_interface = {
 *     32768, // bits
 *     RB_RANDOM_INTERFACE_DEFINE(foo),
 * };
 * ```
 */
#define RB_RANDOM_INTERFACE_DEFINE(prefix) \
    RUBY_RANDOM_INTERFACE_VERSION_INITIALIZER, 0, \
    prefix##_init, \
    prefix##_init_int32, \
    prefix##_get_int32, \
    prefix##_get_bytes

/**
 * Identical   to   #RB_RANDOM_INTERFACE_DEFINE    except   it   also   defines
 * prefix_get_real.
 */
#define RB_RANDOM_INTERFACE_DEFINE_WITH_REAL(prefix) \
    RB_RANDOM_INTERFACE_DEFINE(prefix), \
    prefix##_get_real

#define RB_RANDOM_DEFINE_INIT_INT32_FUNC(prefix) \
    static void prefix##_init_int32(rb_random_t *rnd, uint32_t data) \
    { \
        prefix##_init(rnd, &data, 1); \
    }

#if defined _WIN32 && !defined __CYGWIN__
typedef rb_data_type_t rb_random_data_type_t;
# define RB_RANDOM_PARENT 0
#else

/** This is the type of ::rb_random_data_type. */
typedef const rb_data_type_t rb_random_data_type_t;

/**
 * This utility macro can be used when you define your own PRNG type:
 *
 * ```CXX
 * static inline constexpr rb_random_interface_t your_if = {
 *     0, RB_RANDOM_INTERFACE_DEFINE(your),
 * };
 *
 * static inline constexpr rb_random_data_type_t your_prng_type = {
 *     "your PRNG",
 *     { rb_random_mark, },
 *     RB_RANDOM_PARENT,                 // <<-- HERE
 *     &your_if,
 *     0,
 * }
 * ```
 */
# define RB_RANDOM_PARENT &rb_random_data_type
#endif

/**
 * This macro  is expected  to be  called exactly  once at  the beginning  of a
 * program, possibly from  inside of your `Init_Foo()`  function.  Depending on
 * platforms #RB_RANDOM_PARENT  can require  a fixup.   This routine  does that
 * when necessary.
 */
#define RB_RANDOM_DATA_INIT_PARENT(random_data) \
    rbimpl_random_data_init_parent(&random_data)

/**
 * This   is    the   implementation   of    ::rb_data_type_struct::dmark   for
 * ::rb_random_data_type.  In case  your PRNG does not involve  Ruby objects at
 * all (which is quite likely), you can simply reuse it.
 *
 * @param[out]  ptr  Target to mark, which is a ::rb_random_t this case.
 */
void rb_random_mark(void *ptr);

/**
 * Initialises  an allocated  ::rb_random_t instance.   Call it  from your  own
 * initialiser appropriately.
 *
 * @param[out]  rnd  Your PRNG's base part.
 * @post        `rnd` is filled with an initial state.
 */
void rb_random_base_init(rb_random_t *rnd);

/**
 * Generates a 64 bit floating point number by concatenating two 32bit unsigned
 * integers.
 *
 * @param[in]  a     Most significant 32 bits of the result.
 * @param[in]  b     Least significant 32 bits of the result.
 * @param[in]  excl  Whether the result should exclude 1.0 or not.
 * @return     A double, whose range is either `[0, 1)` or `[0, 1]`.
 * @see        ::rb_random_interface_t::get_real()
 *
 * @internal
 *
 * This in fact has nothing to do with PRNGs.
 */
double rb_int_pair_to_real(uint32_t a, uint32_t b, int excl);

/**
 * Repeatedly calls  the passed function over  and over again until  the passed
 * buffer is filled with random bytes.
 *
 * @param[in]   func  Generator function.
 * @param[out]  prng  Passed as-is to `func`.
 * @param[out]  buff  Return buffer.
 * @param[in]   size  Number of words of `buff`.
 * @post        `buff` is filled with random bytes.
 * @post        `prng` is updated by `func`.
 * @see        ::rb_random_interface_t::get_bytes()
 */
void rb_rand_bytes_int32(rb_random_get_int32_func *func, rb_random_t *prng, void *buff, size_t size);

/**
 * The data that  holds the backend type of ::rb_cRandom.   Used as your PRNG's
 * ::rb_data_type_struct::parent.
 */
RUBY_EXTERN const rb_data_type_t rb_random_data_type;

RBIMPL_SYMBOL_EXPORT_END()

RBIMPL_ATTR_PURE_UNLESS_DEBUG()
/* :TODO: can this function be __attribute__((returns_nonnull)) or not? */
/**
 * Queries the interface of the passed random object.
 *
 * @param[in]  obj  An instance (of a subclass) of ::rb_cRandom.
 * @return     Its corresponding ::rb_random_interface_t interface.
 */
static inline const rb_random_interface_t *
rb_rand_if(VALUE obj)
{
    RBIMPL_ASSERT_OR_ASSUME(RTYPEDDATA_P(obj));
    const struct rb_data_type_struct *t = RTYPEDDATA_TYPE(obj);
    const void *ret = t->data;
    return RBIMPL_CAST((const rb_random_interface_t *)ret);
}

RBIMPL_ATTR_NOALIAS()
/**
 * @private
 *
 * This  is an  implementation detail  of #RB_RANDOM_DATA_INIT_PARENT.   People
 * don't use it directly.
 *
 * @param[out]  random_data  Region to fill.
 * @post        ::rb_random_data_type is filled appropriately.
 */
static inline void
rbimpl_random_data_init_parent(rb_random_data_type_t *random_data)
{
#if defined _WIN32 && !defined __CYGWIN__
    random_data->parent = &rb_random_data_type;
#endif
}

#endif /* RUBY_RANDOM_H */
ruby/assert.h000064400000024375151732674270007230 0ustar00#ifndef RUBY_ASSERT_H                                /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_ASSERT_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @date       Wed May 18 00:21:44 JST 1994
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 */
#include "ruby/internal/assume.h"
#include "ruby/internal/attr/cold.h"
#include "ruby/internal/attr/format.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/dllexport.h"
#include "ruby/backward/2/assume.h"

/* RUBY_NDEBUG  is very  simple:  after everything  described  below are  done,
 * define it with either NDEBUG is undefined (=0) or defined (=1).  It is truly
 * subordinate.
 *
 * RUBY_DEBUG versus NDEBUG is complicated.  Assertions shall be:
 *
 *                      | -UNDEBUG | -DNDEBUG
 *       ---------------+----------+---------
 *       -URUBY_DEBUG   | (*1)     | disabled
 *       -DRUBY_DEBUG=0 | disabled | disabled
 *       -DRUBY_DEBUG=1 | enabled  | (*2)
 *       -DRUBY_DEBUG   | enabled  | (*2)
 *
 * where:
 *
 *   - (*1): Assertions shall  be silently disabled, no warnings,  in favour of
 *     commit 21991e6ca59274e41a472b5256bd3245f6596c90.
 *
 *   - (*2): Compile-time warnings shall be issued.
 */

/** @cond INTERNAL_MACRO */

/*
 * Pro tip: `!!RUBY_DEBUG-1` expands to...
 *
 * - `!!(-1)`  (== `!0`  ==  `1`) when RUBY_DEBUG is defined to be empty,
 * - `(!!0)-1` (== `0-1` == `-1`) when RUBY_DEBUG is defined as 0, and
 * - `(!!n)-1` (== `1-1` ==  `0`) when RUBY_DEBUG is defined as something else.
 */
#if ! defined(RUBY_DEBUG)
# define RBIMPL_RUBY_DEBUG 0
#elif !!RUBY_DEBUG-1 < 0
# define RBIMPL_RUBY_DEBUG 0
#else
# define RBIMPL_RUBY_DEBUG 1
#endif

/*
 * ISO/IEC 9899 (all past versions) says that  "If NDEBUG is defined as a macro
 * name at  the point  in the  source file where  <assert.h> is  included, ..."
 * which means we must not take its defined value into account.
 */
#if defined(NDEBUG)
# define RBIMPL_NDEBUG 1
#else
# define RBIMPL_NDEBUG 0
#endif

/** @endcond */

/* Here we go... */
#undef RUBY_DEBUG
#undef RUBY_NDEBUG
#undef NDEBUG
#if defined(__DOXYGEN__)
# /** Define this macro when you want assertions. */
# define RUBY_DEBUG 0
# /** Define this macro when you don't want assertions. */
# define NDEBUG
# /** This macro is basically the same as #NDEBUG */
# define RUBY_NDEBUG 1

#elif (RBIMPL_NDEBUG == 1) && (RBIMPL_RUBY_DEBUG == 0)
# /* Assertions disabled as per request, no conflicts. */
# define RUBY_DEBUG 0
# define RUBY_NDEBUG 1
# define NDEBUG

#elif (RBIMPL_NDEBUG == 0) && (RBIMPL_RUBY_DEBUG == 1)
# /* Assertions enabled as per request, no conflicts. */
# define RUBY_DEBUG 1
# define RUBY_NDEBUG 0
# /* keep NDEBUG undefined */

#elif (RBIMPL_NDEBUG == 0) && (RBIMPL_RUBY_DEBUG == 0)
# /* The (*1) situation in above diagram. */
# define RUBY_DEBUG 0
# define RUBY_NDEBUG 1
# define NDEBUG

#elif (RBIMPL_NDEBUG == 1) && (RBIMPL_RUBY_DEBUG == 1)
# /* The (*2) situation in above diagram. */
# define RUBY_DEBUG 1
# define RUBY_NDEBUG 0
# /* keep NDEBUG undefined */

# if defined(_MSC_VER)
#  pragma message("NDEBUG is ignored because RUBY_DEBUG>0.")
# elif defined(__GNUC__)
#  pragma GCC warning "NDEBUG is ignored because RUBY_DEBUG>0."
# else
#  error NDEBUG is ignored because RUBY_DEBUG>0.
# endif
#endif
#undef RBIMPL_NDEBUG
#undef RBIMPL_RUBY_DEBUG

/** @cond INTERNAL_MACRO */
#define RBIMPL_ASSERT_NOTHING RBIMPL_CAST((void)0)

RBIMPL_SYMBOL_EXPORT_BEGIN()
RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_COLD()
void rb_assert_failure(const char *file, int line, const char *name, const char *expr);

RBIMPL_ATTR_NORETURN()
RBIMPL_ATTR_COLD()
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 5, 6)
void rb_assert_failure_detail(const char *file, int line, const char *name, const char *expr, const char *fmt, ...);
RBIMPL_SYMBOL_EXPORT_END()

#ifdef RUBY_FUNCTION_NAME_STRING
# define RBIMPL_ASSERT_FUNC RUBY_FUNCTION_NAME_STRING
#else
# define RBIMPL_ASSERT_FUNC RBIMPL_CAST((const char *)0)
#endif

/** @endcond */

/**
 * Prints the given message, and terminates the entire process abnormally.
 *
 * @param  mesg  The message to display.
 */
#if defined(HAVE___VA_OPT__)
# if RBIMPL_HAS_WARNING("-Wgnu-zero-variadic-macro-arguments")
/* __VA_OPT__ is to be used for the zero variadic macro arguments
 * cases. */
RBIMPL_WARNING_IGNORED(-Wgnu-zero-variadic-macro-arguments)
# endif
# define RBIMPL_VA_OPT_ARGS(...) __VA_OPT__(,) __VA_ARGS__

# define RUBY_ASSERT_FAIL(mesg, ...) \
    rb_assert_failure##__VA_OPT__(_detail)( \
        __FILE__, __LINE__, RBIMPL_ASSERT_FUNC, mesg RBIMPL_VA_OPT_ARGS(__VA_ARGS__))
#elif !defined(__cplusplus)
# define RBIMPL_VA_OPT_ARGS(...)

# define RUBY_ASSERT_FAIL(mesg, ...) \
    rb_assert_failure(__FILE__, __LINE__, RBIMPL_ASSERT_FUNC, mesg)
#else
# undef RBIMPL_VA_OPT_ARGS

# define RUBY_ASSERT_FAIL(mesg) \
    rb_assert_failure(__FILE__, __LINE__, RBIMPL_ASSERT_FUNC, mesg)
#endif

/**
 * Asserts that the expression is truthy.  If not aborts with the message.
 *
 * @param  expr  What supposedly evaluates to true.
 * @param  mesg  The message to display on failure.
 */
#if defined(RBIMPL_VA_OPT_ARGS)
# define RUBY_ASSERT_MESG(expr, ...) \
    (RB_LIKELY(expr) ? RBIMPL_ASSERT_NOTHING : RUBY_ASSERT_FAIL(__VA_ARGS__))
#else
# define RUBY_ASSERT_MESG(expr, mesg) \
    (RB_LIKELY(expr) ? RBIMPL_ASSERT_NOTHING : RUBY_ASSERT_FAIL(mesg))
#endif

/**
 * A variant of #RUBY_ASSERT that does not interface with #RUBY_DEBUG.
 *
 * @copydetails #RUBY_ASSERT
 */
#if defined(RBIMPL_VA_OPT_ARGS)
# define RUBY_ASSERT_ALWAYS(expr, ...) \
    RUBY_ASSERT_MESG(expr, #expr RBIMPL_VA_OPT_ARGS(__VA_ARGS__))
#else
# define RUBY_ASSERT_ALWAYS(expr) RUBY_ASSERT_MESG((expr), #expr)
#endif

/**
 * Asserts that the given expression is truthy if and only if #RUBY_DEBUG is truthy.
 *
 * @param  expr  What supposedly evaluates to true.
 */
#if RUBY_DEBUG
# if defined(RBIMPL_VA_OPT_ARGS)
#   define RUBY_ASSERT(expr, ...) \
    RUBY_ASSERT_MESG((expr), #expr RBIMPL_VA_OPT_ARGS(__VA_ARGS__))
# else
#   define RUBY_ASSERT(expr) RUBY_ASSERT_MESG((expr), #expr)
# endif
#else
# if defined(RBIMPL_VA_OPT_ARGS)
#   define RUBY_ASSERT(/* expr, */...) RBIMPL_ASSERT_NOTHING
# else
#   define RUBY_ASSERT(expr) RBIMPL_ASSERT_NOTHING
# endif
#endif

/**
 * A  variant  of   #RUBY_ASSERT  that  interfaces  with   #NDEBUG  instead  of
 * #RUBY_DEBUG.  This almost resembles `assert`  C standard macro, except minor
 * implementation details.
 *
 * @copydetails #RUBY_ASSERT
 */
/* Currently  `RUBY_DEBUG == ! defined(NDEBUG)` is  always true.   There is  no
 * difference any longer between this one and `RUBY_ASSERT`. */
#if defined(NDEBUG)
# if defined(RBIMPL_VA_OPT_ARGS)
#   define RUBY_ASSERT_NDEBUG(/* expr, */...) RBIMPL_ASSERT_NOTHING
# else
#   define RUBY_ASSERT_NDEBUG(expr) RBIMPL_ASSERT_NOTHING
# endif
#else
# if defined(RBIMPL_VA_OPT_ARGS)
#   define RUBY_ASSERT_NDEBUG(expr, ...) \
    RUBY_ASSERT_MESG((expr), #expr RBIMPL_VA_OPT_ARGS(__VA_ARGS__))
# else
#   define RUBY_ASSERT_NDEBUG(expr) RUBY_ASSERT_MESG((expr), #expr)
# endif
#endif

/**
 * @copydoc #RUBY_ASSERT_WHEN
 * @param  mesg  The message to display on failure.
 */
#if RUBY_DEBUG
# if defined(RBIMPL_VA_OPT_ARGS)
#   define RUBY_ASSERT_MESG_WHEN(cond, /* expr, */...)  \
    RUBY_ASSERT_MESG(__VA_ARGS__)
# else
#   define RUBY_ASSERT_MESG_WHEN(cond, expr, mesg) RUBY_ASSERT_MESG((expr), (mesg))
# endif
#else
# if defined(RBIMPL_VA_OPT_ARGS)
#   define RUBY_ASSERT_MESG_WHEN(cond, expr, ...) \
    ((cond) ? RUBY_ASSERT_MESG((expr), __VA_ARGS__) : RBIMPL_ASSERT_NOTHING)
# else
#   define RUBY_ASSERT_MESG_WHEN(cond, expr, mesg) \
    ((cond) ? RUBY_ASSERT_MESG((expr), (mesg)) : RBIMPL_ASSERT_NOTHING)
# endif
#endif

/**
 * A variant  of #RUBY_ASSERT  that asserts when  either #RUBY_DEBUG  or `cond`
 * parameter is truthy.
 *
 * @param  cond  Extra condition that shall hold for assertion to take effect.
 * @param  expr  What supposedly evaluates to true.
 */
#if defined(RBIMPL_VA_OPT_ARGS)
# define RUBY_ASSERT_WHEN(cond, expr, ...) \
    RUBY_ASSERT_MESG_WHEN(cond, expr, #expr RBIMPL_VA_OPT_ARGS(__VA_ARGS__))
#else
# define RUBY_ASSERT_WHEN(cond, expr) RUBY_ASSERT_MESG_WHEN((cond), (expr), #expr)
#endif

/**
 * A variant of #RUBY_ASSERT that  asserts when either #RUBY_DEBUG or built-in
 * type of `obj` is `type`.
 *
 * @param  obj  Object to check its built-in typue.
 * @param  type  Built-in type constant, T_ARRAY, T_STRING, etc.
 */
#define RUBY_ASSERT_BUILTIN_TYPE(obj, type) \
    RUBY_ASSERT(RB_TYPE_P(obj, type), \
                "Actual type is %s", rb_builtin_type_name(BUILTIN_TYPE(obj)))

/**
 * This is either #RUBY_ASSERT or #RBIMPL_ASSUME, depending on #RUBY_DEBUG.
 *
 * @copydetails #RUBY_ASSERT
 */
#if RUBY_DEBUG
# define RBIMPL_ASSERT_OR_ASSUME RUBY_ASSERT_ALWAYS
#elif ! defined(RBIMPL_VA_OPT_ARGS)
# define RBIMPL_ASSERT_OR_ASSUME(expr) RBIMPL_ASSUME(expr)
#elif RBIMPL_COMPILER_BEFORE(Clang, 7, 0, 0)
# /* See commit 67d259c5dccd31fe49d417fec169977712ffdf10 */
# define RBIMPL_ASSERT_OR_ASSUME(...) RBIMPL_ASSERT_NOTHING
#elif defined(RUBY_ASSERT_NOASSUME)
# /* See commit d300a734414ef6de7e8eb563b7cc4389c455ed08 */
# define RBIMPL_ASSERT_OR_ASSUME(...) RBIMPL_ASSERT_NOTHING
#elif ! defined(RBIMPL_HAVE___ASSUME)
# define RBIMPL_ASSERT_OR_ASSUME(...) RBIMPL_ASSERT_NOTHING
#else
# define RBIMPL_ASSERT_OR_ASSUME(expr, ...) RBIMPL_ASSUME(expr)
#endif

#endif /* RUBY_ASSERT_H */
ruby/ruby.h000064400000035370151732674270006705 0ustar00#ifndef RUBY_RUBY_H                                  /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_RUBY_H 1
/**
 * @file
 * @author     $Author$
 * @date       Thu Jun 10 14:26:32 JST 1993
 * @copyright  Copyright (C) 1993-2008 Yukihiro Matsumoto
 * @copyright  Copyright (C) 2000  Network Applied Communication Laboratory, Inc.
 * @copyright  Copyright (C) 2000  Information-technology Promotion Agency, Japan
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 */
#include "ruby/internal/config.h"

/* @shyouhei  doesn't  understand  why  we need  <intrinsics.h>  at  this  very
 * beginning of the entire <ruby.h> circus. */
#ifdef HAVE_INTRINSICS_H
# include <intrinsics.h>
#endif

#include <stdarg.h>

#include "defines.h"
#include "ruby/internal/abi.h"
#include "ruby/internal/anyargs.h"
#include "ruby/internal/arithmetic.h"
#include "ruby/internal/core.h"
#include "ruby/internal/ctype.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/error.h"
#include "ruby/internal/eval.h"
#include "ruby/internal/event.h"
#include "ruby/internal/fl_type.h"
#include "ruby/internal/gc.h"
#include "ruby/internal/glob.h"
#include "ruby/internal/globals.h"
#include "ruby/internal/has/warning.h"
#include "ruby/internal/interpreter.h"
#include "ruby/internal/iterator.h"
#include "ruby/internal/memory.h"
#include "ruby/internal/method.h"
#include "ruby/internal/module.h"
#include "ruby/internal/newobj.h"
#include "ruby/internal/scan_args.h"
#include "ruby/internal/special_consts.h"
#include "ruby/internal/symbol.h"
#include "ruby/internal/value.h"
#include "ruby/internal/value_type.h"
#include "ruby/internal/variable.h"
#include "ruby/assert.h"
#include "ruby/backward/2/assume.h"
#include "ruby/backward/2/inttypes.h"
#include "ruby/backward/2/limits.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/* Module#methods, #singleton_methods and so on return Symbols */
/**
 * @private
 *
 * @deprecated  This macro once was a thing in the old days, but makes no sense
 *              any  longer today.   Exists  here  for backwards  compatibility
 *              only.  You can safely forget about it.
 */
#define USE_SYMBOL_AS_METHOD_NAME 1

/**
 * Converts an object to a path.  It first tries `#to_path` method if any, then
 * falls back to `#to_str` method.
 *
 * @param[in]  obj                 Arbitrary ruby object.
 * @exception  rb_eArgError        `obj` contains a NUL byte.
 * @exception  rb_eTypeError       `obj` is not path-ish.
 * @exception  rb_eEncCompatError  No encoding conversion from `obj` to path.
 * @return     Converted path object.
 */
VALUE rb_get_path(VALUE obj);

/**
 * Ensures that the parameter object is a path.
 *
 * @param[in,out]  v                   Arbitrary ruby object.
 * @exception      rb_eArgError        `v` contains a NUL byte.
 * @exception      rb_eTypeError       `v` is not path-ish.
 * @exception      rb_eEncCompatError  `v` is not path-compatible.
 * @post           `v` is a path.
 */
#define FilePathValue(v) (RB_GC_GUARD(v) = rb_get_path(v))

/**
 * @deprecated  This function is an alias  of rb_get_path() now.  The part that
 *              did "no_checksafe" was deleted.  It  remains here because of no
 *              harm.
 */
VALUE rb_get_path_no_checksafe(VALUE);

/**
 * This macro actually does the same  thing as #FilePathValue now.  The "String"
 * part indicates  that this is  for when a string  is treated like  a pathname,
 * rather  than  the  actual  pathname  on  the  file  systems.   For  examples:
 * `Dir.fnmatch?`, `File.join`, `File.basename`, etc.
 */
#define FilePathStringValue(v) ((v) = rb_get_path(v))

/** @cond INTERNAL_MACRO */
#if defined(HAVE_BUILTIN___BUILTIN_CONSTANT_P) && defined(HAVE_STMT_AND_DECL_IN_EXPR)
# define rb_varargs_argc_check_runtime(argc, vargc) \
    (((argc) <= (vargc)) ? (argc) : \
     (rb_fatal("argc(%d) exceeds actual arguments(%d)", \
               argc, vargc), 0))
# define rb_varargs_argc_valid_p(argc, vargc) \
    ((argc) == 0 ? (vargc) <= 1 : /* [ruby-core:85266] [Bug #14425] */ \
     (argc) == (vargc))
# if defined(HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P)
#   ifdef HAVE_ATTRIBUTE_ERRORFUNC
ERRORFUNC((" argument length doesn't match"), int rb_varargs_bad_length(int,int));
#   else
#     define rb_varargs_bad_length(argc, vargc) \
        ((argc)/rb_varargs_argc_valid_p(argc, vargc))
#   endif
#   define rb_varargs_argc_check(argc, vargc) \
    __builtin_choose_expr(__builtin_constant_p(argc), \
        (rb_varargs_argc_valid_p(argc, vargc) ? (argc) : \
         rb_varargs_bad_length(argc, vargc)), \
        rb_varargs_argc_check_runtime(argc, vargc))
# else
#   define rb_varargs_argc_check(argc, vargc) \
        rb_varargs_argc_check_runtime(argc, vargc)
# endif
#endif
/** @endcond */

/**
 * Queries the name of the passed class.
 *
 * @param[in]  klass  An instance of a class.
 * @return     The name of `klass`.
 * @note       Return value is managed by our GC.  Don't free.
 */
const char *rb_class2name(VALUE klass);

/**
 * Queries the name of the class of the passed object.
 *
 * @param[in]  obj  Arbitrary ruby object.
 * @return     The name of the class of `obj`.
 * @note       Return value is managed by our GC.  Don't free.
 */
const char *rb_obj_classname(VALUE obj);

/**
 * Inspects an object.   It first calls the argument's  `#inspect` method, then
 * feeds its result string into ::rb_stdout.
 *
 * This is identical to Ruby level `Kernel#p`, except it takes only one object.
 *
 * @internal
 *
 * Above description is in fact inaccurate.  This API interfaces with Ractors.
 */
void rb_p(VALUE obj);

/**
 * This function is an optimised version  of calling `#==`.  It checks equality
 * between two  objects by first  doing a fast  identity check using  using C's
 * `==` (same  as `BasicObject#equal?`).  If  that check fails, it  calls `#==`
 * dynamically.   This optimisation  actually affects  semantics, because  when
 * `#==`  returns false  for the  same object  obj, `rb_equal(obj,  obj)` would
 * still  return true.   This happens  for `Float::NAN`,  where `Float::NAN  ==
 * Float::NAN` is `false`, but `rb_equal(Float::NAN, Float::NAN)` is `true`.
 *
 * @param[in]  lhs          Comparison LHS.
 * @param[in]  rhs          Comparison RHS.
 * @retval     RUBY_Qtrue   They are the same.
 * @retval     RUBY_Qfalse  They are different.
 */
VALUE rb_equal(VALUE lhs, VALUE rhs);

/**
 * Identical  to rb_require_string(),  except it  takes C's  string instead  of
 * Ruby's.
 *
 * @param[in]  feature           Name of a feature, e.g. `"json"`.
 * @exception  rb_eLoadError     No such feature.
 * @exception  rb_eRuntimeError  `$"` is frozen; unable to push.
 * @retval     RUBY_Qtrue        The feature is loaded for the first time.
 * @retval     RUBY_Qfalse       The feature has already been loaded.
 * @post       `$"` is updated.
 */
VALUE rb_require(const char *feature);

#include "ruby/intern.h"

/**
 * @private
 *
 * @deprecated  This macro once was a thing in the old days, but makes no sense
 *              any  longer today.   Exists  here  for backwards  compatibility
 *              only.  You can safely forget about it.
 */
#define RUBY_VM 1 /* YARV */

/**
 * @private
 *
 * @deprecated  This macro once was a thing in the old days, but makes no sense
 *              any  longer today.   Exists  here  for backwards  compatibility
 *              only.  You can safely forget about it.
 */
#define HAVE_NATIVETHREAD

/**
 * Queries  if  the thread  which  calls  this  function  is a  ruby's  thread.
 * "Ruby's" in  this context  is a thread  created using one  of our  APIs like
 * rb_thread_create().   There  are  distinctions   between  ruby's  and  other
 * threads.  For instance calling ruby methods  are allowed only from inside of
 * a ruby's thread.
 *
 * @retval  1  The current thread is a Ruby's thread.
 * @retval  0  The current thread is a random thread from outside of Ruby.
 */
int ruby_native_thread_p(void);

/**
 * @private
 *
 * This macro is for internal use.  Must be a mistake to place here.
 */
#define InitVM(ext) {void InitVM_##ext(void);InitVM_##ext();}

RBIMPL_ATTR_NONNULL((3))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 3, 4)
/**
 * Our own locale-insensitive version of `snprintf(3)`.  It can also be seen as
 * a routine  identical to rb_sprintf(),  except it  writes back to  the passed
 * buffer instead of allocating a new Ruby object.
 *
 * @param[out]  str  Return buffer
 * @param[in]   n    Number of bytes of `str`.
 * @param[in]   fmt  A `printf`-like format specifier.
 * @param[in]   ...  Variadic number of contents to format.
 * @return      Number of bytes  that would have been written to  `str`, if `n`
 *              was large enough.  Comparing this  to `n` can give you insights
 *              that the buffer is too small  or too big.  Especially passing 0
 *              to `n`  gives you the exact  number of bytes necessary  to hold
 *              the result string without writing anything to anywhere.
 * @post        `str` holds  up to `n-1`  bytes of formatted contents  (and the
 *              terminating NUL character.)
 */
int ruby_snprintf(char *str, size_t n, char const *fmt, ...);

RBIMPL_ATTR_NONNULL((3))
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 3, 0)
/**
 * Identical to ruby_snprintf(),  except it takes a `va_list`.  It  can also be
 * seen as a  routine identical to rb_vsprintf(), except it  writes back to the
 * passed buffer instead of allocating a new Ruby object.
 *
 * @param[out]  str  Return buffer
 * @param[in]   n    Number of bytes of `str`.
 * @param[in]   fmt  A `printf`-like format specifier.
 * @param[in]   ap   Contents  to format.
 * @return      Number of bytes  that would have been written to  `str`, if `n`
 *              was large enough.  Comparing this  to `n` can give you insights
 *              that the buffer is too small  or too big.  Especially passing 0
 *              to `n`  gives you the exact  number of bytes necessary  to hold
 *              the result string without writing anything to anywhere.
 * @post        `str` holds  up to `n-1`  bytes of formatted contents  (and the
 *              terminating NUL character.)
 */
int ruby_vsnprintf(char *str, size_t n, char const *fmt, va_list ap);

#include <errno.h>

/**
 * @name  Errno handling routines for userland threads
 * @note  POSIX chapter 2 section 3 states  that for each thread  of a process,
 *        the  value of  `errno` shall  not be  affected by  function calls  or
 *        assignments to `errno` by other threads.
 *
 * Soooo this `#define  errno` below seems like a noob  mistake at first sight.
 * If you look at its actual  implementation, the functions are just adding one
 * level of indirection.  It doesn't make any sense sorry?  But yes!  @ko1 told
 * @shyouhei that this is inevitable.
 *
 * The  ultimate  reason is  because  Ruby  now  has N:M  threads  implemented.
 * Threads of that sort  change their context in user land.   A function can be
 * "transferred" between  threads in  middle of their  executions.  Let  us for
 * instance consider:
 *
 * ```cxx
 * void foo()
 * {
 *     auto i = errno;
 *     close(0);
 *     errno = i;
 * }
 * ```
 *
 * This function (if  ran under our Ractor) could change  its running thread at
 * the `close` function.  But the  two `errno` invocations are different!  Look
 * how the source code above is compiled by clang 17 with `-O3` flag @ Linux:
 *
 * ```
 * foo(int):                                # @foo(int)
 *         push    rbp
 *         push    r14
 *         push    rbx
 *         mov     ebx, edi
 *         call    __errno_location@PLT
 *         mov     r14, rax
 *         mov     ebp, dword ptr [rax]
 *         mov     edi, ebx
 *         call    close@PLT
 *         mov     dword ptr [r14], ebp
 *         pop     rbx
 *         pop     r14
 *         pop     rbp
 *         ret
 * ```
 *
 * Notice  how `__errno_location@PLT`  is  `call`-ed only  once.  The  compiler
 * assumes that the location of `errno` does not change during a function call.
 * Sadly this is  no longer true for us.  The  `close@PLT` now changes threads,
 * which should also change where `errno` is stored.
 *
 * With the `#define errno` below the compilation result changes to this:
 *
 * ```
 * foo(int):                                # @foo(int)
 *         push    rbp
 *         push    rbx
 *         push    rax
 *         mov     ebx, edi
 *         call    rb_errno_ptr()@PLT
 *         mov     ebp, dword ptr [rax]
 *         mov     edi, ebx
 *         call    close@PLT
 *         call    rb_errno_ptr()@PLT
 *         mov     dword ptr [rax], ebp
 *         add     rsp, 8
 *         pop     rbx
 *         pop     rbp
 *         ret
 * ```
 *
 * Which fixes the problem.
 */

/**
 * Identical to system `errno`.
 *
 * @return The last set `errno` number.
 */
int rb_errno(void);

/**
 * Set the errno.
 *
 * @param  err  New `errno`.
 * @post   `errno` is now set to `err`.
 */
void rb_errno_set(int err);

/**
 * The location of `errno`
 *
 * @return The (thread-specific) location of `errno`.
 */
int *rb_errno_ptr(void);

/**
 * Not sure if  it is necessary for  extension libraries but this  is where the
 * "bare" errno is located.
 *
 * @return The location of `errno`.
 */
static inline int *
rb_orig_errno_ptr(void)
{
    return &errno;
}

#define rb_orig_errno errno /**< System-provided original `errno`. */
#undef errno
#define errno (*rb_errno_ptr()) /**< Ractor-aware version of `errno`. */

/** @} */


/** @cond INTERNAL_MACRO */
#if RBIMPL_HAS_WARNING("-Wgnu-zero-variadic-macro-arguments")
# /* Skip it; clang -pedantic doesn't like the following */
#elif defined(__GNUC__) && defined(HAVE_VA_ARGS_MACRO) && defined(__OPTIMIZE__)
# define rb_yield_values(argc, ...) \
__extension__({ \
        const int rb_yield_values_argc = (argc); \
        const VALUE rb_yield_values_args[] = {__VA_ARGS__}; \
        const int rb_yield_values_nargs = \
            (int)(sizeof(rb_yield_values_args) / sizeof(VALUE)); \
        rb_yield_values2( \
            rb_varargs_argc_check(rb_yield_values_argc, rb_yield_values_nargs), \
            rb_yield_values_nargs ? rb_yield_values_args : NULL); \
    })

# define rb_funcall(recv, mid, argc, ...) \
__extension__({ \
        const int rb_funcall_argc = (argc); \
        const VALUE rb_funcall_args[] = {__VA_ARGS__}; \
        const int rb_funcall_nargs = \
            (int)(sizeof(rb_funcall_args) / sizeof(VALUE)); \
        rb_funcallv(recv, mid, \
            rb_varargs_argc_check(rb_funcall_argc, rb_funcall_nargs), \
            rb_funcall_nargs ? rb_funcall_args : NULL); \
    })
#endif
/** @endcond */

#ifndef RUBY_DONT_SUBST
#include "ruby/subst.h"
#endif

#if !defined RUBY_EXPORT && !defined RUBY_NO_OLD_COMPATIBILITY
# include "ruby/backward.h"
#endif

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RUBY_RUBY_H */
ruby/io/buffer.h000064400000007744151732674300007602 0ustar00#ifndef RUBY_IO_BUFFER_H
#define RUBY_IO_BUFFER_H
/**
 * @file
 * @author     Samuel Williams
 * @date       Fri  2 Jul 2021 16:29:01 NZST
 * @copyright  Copyright (C) 2021 Samuel Williams
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 */

#pragma once

#include "ruby/ruby.h"
#include "ruby/internal/config.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

// WARNING: This entire interface is experimental and may change in the future!
#define RB_IO_BUFFER_EXPERIMENTAL 1

#define RUBY_IO_BUFFER_VERSION 2

// The `IO::Buffer` class.
RUBY_EXTERN VALUE rb_cIOBuffer;

// The operating system page size.
RUBY_EXTERN size_t RUBY_IO_BUFFER_PAGE_SIZE;

// The default buffer size, usually a (small) multiple of the page size.
// Can be overridden by the RUBY_IO_BUFFER_DEFAULT_SIZE environment variable.
RUBY_EXTERN size_t RUBY_IO_BUFFER_DEFAULT_SIZE;

// Represents the internal state of the buffer.
// More than one flag can be set at a time.
enum rb_io_buffer_flags {
    // The memory in the buffer is owned by someone else.
    // More specifically, it means that someone else owns the buffer and we shouldn't try to resize it.
    RB_IO_BUFFER_EXTERNAL = 1,
    // The memory in the buffer is allocated internally.
    RB_IO_BUFFER_INTERNAL = 2,
    // The memory in the buffer is mapped.
    // A non-private mapping is marked as external.
    RB_IO_BUFFER_MAPPED = 4,

    // A mapped buffer that is also shared.
    RB_IO_BUFFER_SHARED = 8,

    // The buffer is locked and cannot be resized.
    // More specifically, it means we can't change the base address or size.
    // A buffer is typically locked before a system call that uses the data.
    RB_IO_BUFFER_LOCKED = 32,

    // The buffer mapping is private and will not impact other processes or the underlying file.
    RB_IO_BUFFER_PRIVATE = 64,

    // The buffer is read-only and cannot be modified.
    RB_IO_BUFFER_READONLY = 128,

    // The buffer is backed by a file.
    RB_IO_BUFFER_FILE = 256,
};

// Represents the endian of the data types.
enum rb_io_buffer_endian {
    // The least significant units are put first.
    RB_IO_BUFFER_LITTLE_ENDIAN = 4,
    RB_IO_BUFFER_BIG_ENDIAN = 8,

#if defined(WORDS_BIGENDIAN)
    RB_IO_BUFFER_HOST_ENDIAN = RB_IO_BUFFER_BIG_ENDIAN,
#else
    RB_IO_BUFFER_HOST_ENDIAN = RB_IO_BUFFER_LITTLE_ENDIAN,
#endif

    RB_IO_BUFFER_NETWORK_ENDIAN = RB_IO_BUFFER_BIG_ENDIAN
};

VALUE rb_io_buffer_new(void *base, size_t size, enum rb_io_buffer_flags flags);
VALUE rb_io_buffer_map(VALUE io, size_t size, rb_off_t offset, enum rb_io_buffer_flags flags);

VALUE rb_io_buffer_lock(VALUE self);
VALUE rb_io_buffer_unlock(VALUE self);
int rb_io_buffer_try_unlock(VALUE self);

VALUE rb_io_buffer_free(VALUE self);
VALUE rb_io_buffer_free_locked(VALUE self);

// Access the internal buffer and flags. Validates the pointers.
// The points may not remain valid if the source buffer is manipulated.
// Consider using rb_io_buffer_lock if needed.
enum rb_io_buffer_flags rb_io_buffer_get_bytes(VALUE self, void **base, size_t *size);
void rb_io_buffer_get_bytes_for_reading(VALUE self, const void **base, size_t *size);
void rb_io_buffer_get_bytes_for_writing(VALUE self, void **base, size_t *size);

VALUE rb_io_buffer_transfer(VALUE self);
void rb_io_buffer_resize(VALUE self, size_t size);
void rb_io_buffer_clear(VALUE self, uint8_t value, size_t offset, size_t length);

// The length is the minimum required length.
VALUE rb_io_buffer_read(VALUE self, VALUE io, size_t length, size_t offset);
VALUE rb_io_buffer_pread(VALUE self, VALUE io, rb_off_t from, size_t length, size_t offset);
VALUE rb_io_buffer_write(VALUE self, VALUE io, size_t length, size_t offset);
VALUE rb_io_buffer_pwrite(VALUE self, VALUE io, rb_off_t from, size_t length, size_t offset);

RBIMPL_SYMBOL_EXPORT_END()

#endif  /* RUBY_IO_BUFFER_H */
ruby/fiber/scheduler.h000064400000040755151732674300010766 0ustar00#ifndef RUBY_FIBER_SCHEDULER_H                       /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_FIBER_SCHEDULER_H
/**
 * @file
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @brief      Scheduler APIs.
 */
#include "ruby/internal/config.h"

#include <errno.h>

#ifdef STDC_HEADERS
#include <stddef.h> /* size_t */
#endif

#include "ruby/ruby.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/arithmetic.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

#define RUBY_FIBER_SCHEDULER_VERSION 2

struct timeval;

/**
 * Wrap a `ssize_t` and `int errno` into a single `VALUE`. This interface should
 * be used to safely capture results from system calls  like `read` and `write`.
 *
 * You should use `rb_fiber_scheduler_io_result_apply` to unpack the result of
 * this value and update `int errno`.
 *
 * You should not directly try to interpret the result value as it is considered
 * an opaque representation. However, the general representation is an integer
 * in the range of `[-int errno, size_t size]`. Linux generally restricts the
 * result of system calls like `read` and `write` to `<= 2^31` which means this
 * will typically fit within a single FIXNUM.
 *
 * @param[in]  result   The result of the system call.
 * @param[in]  error    The value of `errno`.
 * @return              A `VALUE` which contains the result and/or errno.
 */
static inline VALUE
rb_fiber_scheduler_io_result(ssize_t result, int error)
{
    if (result == -1) {
        return RB_INT2NUM(-error);
    }
    else {
        return RB_SIZE2NUM(result);
    }
}

/**
 * Apply an io result to the local thread, returning the value of the original
 * system call that created it and updating `int errno`.
 *
 * You should not directly try to interpret the result value as it is considered
 * an opaque representation.
 *
 * @param[in]  result   The `VALUE` which contains an errno and/or result size.
 * @post                Updates `int errno` with the value if negative.
 * @return              The original result of the system call.
 */
static inline ssize_t
rb_fiber_scheduler_io_result_apply(VALUE result)
{
    if (RB_FIXNUM_P(result) && RB_NUM2INT(result) < 0) {
        errno = -RB_NUM2INT(result);
        return -1;
    }
    else {
        return RB_NUM2SIZE(result);
    }
}

/**
 * Queries the  current scheduler of  the current  thread that is  calling this
 * function.
 *
 * @retval  RUBY_Qnil  No scheduler has  been set so far to  this thread (which
 *                     is the default).
 * @retval  otherwise  The scheduler that  was last set for  the current thread
 *                     with rb_fiber_scheduler_set().
 */
VALUE rb_fiber_scheduler_get(void);

/**
 * Destructively assigns  the passed  scheduler to that  of the  current thread
 * that is calling this function.  If the scheduler is set, non-blocking fibers
 * (created by `Fiber.new` with `blocking: false`, or by `Fiber.schedule`) call
 * that scheduler's  hook methods on  potentially blocking operations,  and the
 * current  thread  will  call  scheduler's  `#close`  method  on  finalisation
 * (allowing  the  scheduler  to  properly  manage  all  non-finished  fibers).
 * `scheduler`   can   be   an   object   of   any   class   corresponding   to
 * `Fiber::Scheduler` interface. Its implementation is up to the user.
 *
 * @param[in]  scheduler     The scheduler to set.
 * @exception  rb_eArgError  `scheduler` does not conform the interface.
 * @post       Current thread's scheduler is `scheduler`.
 */
VALUE rb_fiber_scheduler_set(VALUE scheduler);

/**
 * Identical to rb_fiber_scheduler_get(), except it also returns ::RUBY_Qnil in
 * case of a blocking fiber.  As blocking fibers do not participate schedulers'
 * scheduling this function can be handy.
 *
 * @retval  RUBY_Qnil  No scheduler is in effect.
 * @retval  otherwise  The scheduler that is in effect, if any.
 */
VALUE rb_fiber_scheduler_current(void);

/**
 * Identical to rb_fiber_scheduler_current(), except it queries for that of the
 * passed thread instead of the implicit current one.
 *
 * @param[in]  thread         Target thread.
 * @exception  rb_eTypeError  `thread` is not a thread.
 * @retval     RUBY_Qnil      No scheduler is in effect in `thread`.
 * @retval     otherwise      The scheduler that is in effect in `thread`.
 */
VALUE rb_fiber_scheduler_current_for_thread(VALUE thread);

/**
 * Converts the passed timeout to an expression that rb_fiber_scheduler_block()
 * etc. expects.
 *
 * @param[in]  timeout    A duration (can be `NULL`).
 * @retval     RUBY_Qnil  No timeout (blocks indefinitely).
 * @retval     otherwise  A timeout object.
 */
VALUE rb_fiber_scheduler_make_timeout(struct timeval *timeout);

/**
 * Closes the passed scheduler object.  This expects the scheduler to wait for
 * all fibers.  Thus the scheduler's main loop tends to start here.
 *
 * @param[in]  scheduler  Target scheduler.
 * @return     What `scheduler.close` returns.
 */
VALUE rb_fiber_scheduler_close(VALUE scheduler);

/**
 * Non-blocking  `sleep`.  Depending  on  scheduler  implementation,  this  for
 * instance switches to another fiber etc.
 *
 * @param[in]  scheduler  Target scheduler.
 * @param[in]  duration   Passed as-is to `scheduler.kernel_sleep`.
 * @return     What `scheduler.kernel_sleep` returns.
 */
VALUE rb_fiber_scheduler_kernel_sleep(VALUE scheduler, VALUE duration);

/**
 * Identical to rb_fiber_scheduler_kernel_sleep(), except  it can pass multiple
 * arguments.
 *
 * @param[in]  scheduler  Target scheduler.
 * @param[in]  argc       Number of objects of `argv`.
 * @param[in]  argv       Passed as-is to `scheduler.kernel_sleep`
 * @return     What `scheduler.kernel_sleep` returns.
 */
VALUE rb_fiber_scheduler_kernel_sleepv(VALUE scheduler, int argc, VALUE * argv);

/* Description TBW */
#if 0
VALUE rb_fiber_scheduler_timeout_after(VALUE scheduler, VALUE timeout, VALUE exception, VALUE message);
VALUE rb_fiber_scheduler_timeout_afterv(VALUE scheduler, int argc, VALUE * argv);
int rb_fiber_scheduler_supports_process_wait(VALUE scheduler);
#endif

/**
 * Non-blocking `waitpid`.  Depending  on  scheduler  implementation, this  for
 * instance switches to another fiber etc.
 *
 * @param[in]  scheduler  Target scheduler.
 * @param[in]  pid        Process ID to wait.
 * @param[in]  flags      Wait flags, e.g. `WUNTRACED`.
 * @return     What `scheduler.process_wait` returns.
 */
VALUE rb_fiber_scheduler_process_wait(VALUE scheduler, rb_pid_t pid, int flags);

/**
 * Non-blocking  wait  for  the  passed   "blocker",  which  is   for  instance
 * `Thread.join` or `Mutex.lock`.  Depending  on scheduler implementation, this
 * for instance switches to another fiber etc.
 *
 * @param[in]  scheduler  Target scheduler.
 * @param[in]  blocker    What blocks the current fiber.
 * @param[in]  timeout    Numeric timeout.
 * @return     What `scheduler.block` returns.
 */
VALUE rb_fiber_scheduler_block(VALUE scheduler, VALUE blocker, VALUE timeout);

/**
 * Wakes up a fiber previously blocked using rb_fiber_scheduler_block().
 *
 * @param[in]  scheduler  Target scheduler.
 * @param[in]  blocker    What was awaited for.
 * @param[in]  fiber      What to unblock.
 * @return     What `scheduler.unblock` returns.
 */
VALUE rb_fiber_scheduler_unblock(VALUE scheduler, VALUE blocker, VALUE fiber);

/**
 * Non-blocking version of rb_io_wait().  Depending on scheduler
 * implementation, this for instance switches to another fiber etc.
 *
 * The  "events" here  is a  Ruby level  integer, which  is an  OR-ed value  of
 * `IO::READABLE`, `IO::WRITABLE`, and `IO::PRIORITY`.
 *
 * @param[in]  scheduler  Target scheduler.
 * @param[in]  io         An io object to wait.
 * @param[in]  events     An integer set of interests.
 * @param[in]  timeout    Numeric timeout.
 * @return     What `scheduler.io_wait` returns.
 */
VALUE rb_fiber_scheduler_io_wait(VALUE scheduler, VALUE io, VALUE events, VALUE timeout);

/**
 * Non-blocking  wait until the passed  IO  is ready  for reading.   This is  a
 * special  case   of  rb_fiber_scheduler_io_wait(),  where  the   interest  is
 * `IO::READABLE` and timeout is never.
 *
 * @param[in]  scheduler  Target scheduler.
 * @param[in]  io         An io object to wait.
 * @return     What `scheduler.io_wait` returns.
 */
VALUE rb_fiber_scheduler_io_wait_readable(VALUE scheduler, VALUE io);

/**
 * Non-blocking  wait until  the passed  IO  is ready  for writing.   This is a
 * special  case   of  rb_fiber_scheduler_io_wait(),  where  the   interest  is
 * `IO::WRITABLE` and timeout is never.
 *
 * @param[in]  scheduler  Target scheduler.
 * @param[in]  io         An io object to wait.
 * @return     What `scheduler.io_wait` returns.
 */
VALUE rb_fiber_scheduler_io_wait_writable(VALUE scheduler, VALUE io);

/**
 * Non-blocking version of `IO.select`.
 *
 * It's possible that this will be emulated using a thread, so you should not
 * rely on it for high performance.
 *
 * @param[in]  scheduler    Target scheduler.
 * @param[in]  readables    An array of readable objects.
 * @param[in]  writables    An array of writable objects.
 * @param[in]  exceptables  An array of objects that might encounter exceptional conditions.
 * @param[in]  timeout      Numeric timeout or nil.
 * @return     What `scheduler.io_select` returns, normally a 3-tuple of arrays of ready objects.
 */
VALUE rb_fiber_scheduler_io_select(VALUE scheduler, VALUE readables, VALUE writables, VALUE exceptables, VALUE timeout);

/**
 * Non-blocking version of `IO.select`, `argv` variant.
 */
VALUE rb_fiber_scheduler_io_selectv(VALUE scheduler, int argc, VALUE *argv);

/**
 * Non-blocking read from the passed IO.
 *
 * @param[in]   scheduler    Target scheduler.
 * @param[in]   io           An io object to read from.
 * @param[in]   buffer       The buffer to read to.
 * @param[in]   length       The minimum number of bytes to read.
 * @param[in]   offset       The offset in the buffer to read from.
 * @retval      RUBY_Qundef  `scheduler` doesn't have `#io_read`.
 * @return      otherwise    What `scheduler.io_read` returns `[-errno, size]`.
 */
VALUE rb_fiber_scheduler_io_read(VALUE scheduler, VALUE io, VALUE buffer, size_t length, size_t offset);

/**
 * Non-blocking write to the passed IO.
 *
 * @param[in]   scheduler    Target scheduler.
 * @param[in]   io           An io object to write to.
 * @param[in]   buffer       The buffer to write from.
 * @param[in]   length       The minimum number of bytes to write.
 * @param[in]   offset       The offset in the buffer to write from.
 * @retval      RUBY_Qundef  `scheduler` doesn't have `#io_write`.
 * @return      otherwise    What `scheduler.io_write` returns `[-errno, size]`.
 */
VALUE rb_fiber_scheduler_io_write(VALUE scheduler, VALUE io, VALUE buffer, size_t length, size_t offset);

/**
 * Non-blocking read from the passed IO at the specified offset.
 *
 * @param[in]   scheduler    Target scheduler.
 * @param[in]   io           An io object to read from.
 * @param[in]   from         The offset to read from.
 * @param[in]   buffer       The buffer to read to.
 * @param[in]   length       The minimum number of bytes to read.
 * @param[in]   offset       The offset in the buffer to read to.
 * @retval      RUBY_Qundef  `scheduler` doesn't have `#io_read`.
 * @return      otherwise    What `scheduler.io_read` returns.
 */
VALUE rb_fiber_scheduler_io_pread(VALUE scheduler, VALUE io, rb_off_t from, VALUE buffer, size_t length, size_t offset);

/**
 * Non-blocking write to the passed IO at the specified offset.
 *
 * @param[in]   scheduler    Target scheduler.
 * @param[in]   io           An io object to write to.
 * @param[in]   from         The offset to write to.
 * @param[in]   buffer       The buffer to write from.
 * @param[in]   length       The minimum number of bytes to write.
 * @param[in]   offset       The offset in the buffer to write from.
 * @retval      RUBY_Qundef  `scheduler` doesn't have `#io_write`.
 * @return      otherwise    What `scheduler.io_write` returns.
 */
VALUE rb_fiber_scheduler_io_pwrite(VALUE scheduler, VALUE io, rb_off_t from, VALUE buffer, size_t length, size_t offset);

/**
 * Non-blocking read from the passed IO using a native buffer.
 *
 * @param[in]   scheduler    Target scheduler.
 * @param[in]   io           An io object to read from.
 * @param[in]   base         The memory to read to.
 * @param[in]   size         Size of the memory.
 * @param[in]   length       The minimum number of bytes to read.
 * @retval      RUBY_Qundef  `scheduler` doesn't have `#io_read`.
 * @return      otherwise    What `scheduler.io_read` returns.
 */
VALUE rb_fiber_scheduler_io_read_memory(VALUE scheduler, VALUE io, void *base, size_t size, size_t length);

/**
 * Non-blocking write to the passed IO using a native buffer.
 *
 * @param[in]   scheduler    Target scheduler.
 * @param[in]   io           An io object to write to.
 * @param[in]   base         The memory to write from.
 * @param[in]   size         Size of the memory.
 * @param[in]   length       The minimum number of bytes to write.
 * @retval      RUBY_Qundef  `scheduler` doesn't have `#io_write`.
 * @return      otherwise    What `scheduler.io_write` returns.
 */
VALUE rb_fiber_scheduler_io_write_memory(VALUE scheduler, VALUE io, const void *base, size_t size, size_t length);

/**
 * Non-blocking pread from the passed IO using a native buffer.
 *
 * @param[in]   scheduler    Target scheduler.
 * @param[in]   io           An io object to read from.
 * @param[in]   from         The offset to read from.
 * @param[in]   base         The memory to read to.
 * @param[in]   size         Size of the memory.
 * @param[in]   length       The minimum number of bytes to read.
 * @retval      RUBY_Qundef  `scheduler` doesn't have `#io_read`.
 * @return      otherwise    What `scheduler.io_read` returns.
 */
VALUE rb_fiber_scheduler_io_pread_memory(VALUE scheduler, VALUE io, rb_off_t from, void *base, size_t size, size_t length);

/**
 * Non-blocking pwrite to the passed IO using a native buffer.
 *
 * @param[in]   scheduler    Target scheduler.
 * @param[in]   io           An io object to write to.
 * @param[in]   from         The offset to write from.
 * @param[in]   base         The memory to write from.
 * @param[in]   size         Size of the memory.
 * @param[in]   length       The minimum number of bytes to write.
 * @retval      RUBY_Qundef  `scheduler` doesn't have `#io_write`.
 * @return      otherwise    What `scheduler.io_write` returns.
 */
VALUE rb_fiber_scheduler_io_pwrite_memory(VALUE scheduler, VALUE io, rb_off_t from, const void *base, size_t size, size_t length);

/**
 * Non-blocking close the given IO.
 *
 * @param[in]  scheduler    Target scheduler.
 * @param[in]  io           An io object to close.
 * @retval     RUBY_Qundef  `scheduler` doesn't have `#io_close`.
 * @return     otherwise    What `scheduler.io_close` returns.
 */
VALUE rb_fiber_scheduler_io_close(VALUE scheduler, VALUE io);

/**
 * Non-blocking DNS lookup.
 *
 * @param[in]  scheduler    Target scheduler.
 * @param[in]  hostname     A host name to query.
 * @retval     RUBY_Qundef  `scheduler` doesn't have `#address_resolve`.
 * @return     otherwise    What `scheduler.address_resolve` returns.
 */
VALUE rb_fiber_scheduler_address_resolve(VALUE scheduler, VALUE hostname);

struct rb_fiber_scheduler_blocking_operation_state {
    void *result;
    int saved_errno;
};

/**
 * Defer the execution of the passed function to the scheduler.
 *
 * @param[in]  scheduler         Target scheduler.
 * @param[in]  function          The function to run.
 * @param[in]  data              The data to pass to the function.
 * @param[in]  unblock_function  The unblock function to use to interrupt the operation.
 * @param[in]  data2             The data to pass to the unblock function.
 * @param[in]  flags             Flags passed to `rb_nogvl`.
 * @param[out] state             The result and errno of the operation.
 * @retval     RUBY_Qundef       `scheduler` doesn't have `#blocking_operation_wait`.
 * @return     otherwise         What `scheduler.blocking_operation_wait` returns.
 */
VALUE rb_fiber_scheduler_blocking_operation_wait(VALUE scheduler, void* (*function)(void *), void *data, rb_unblock_function_t *unblock_function, void *data2, int flags, struct rb_fiber_scheduler_blocking_operation_state *state);

/**
 * Create and schedule a non-blocking fiber.
 *
 */
VALUE rb_fiber_scheduler_fiber(VALUE scheduler, int argc, VALUE *argv, int kw_splat);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RUBY_FIBER_SCHEDULER_H */
ruby/backward.h000064400000002166151732674300007471 0ustar00#ifndef RUBY_RUBY_BACKWARD_H                         /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_RUBY_BACKWARD_H 1
/**
 * @author     Ruby developers <ruby-core@ruby-lang.org>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 */
#include "ruby/internal/value.h"
#include "ruby/internal/interpreter.h"
#include "ruby/backward/2/attributes.h"

#define RBIMPL_ATTR_DEPRECATED_SINCE(ver) RBIMPL_ATTR_DEPRECATED(("since " #ver))
#define RBIMPL_ATTR_DEPRECATED_INTERNAL(ver) RBIMPL_ATTR_DEPRECATED(("since "#ver", also internal"))
#define RBIMPL_ATTR_DEPRECATED_INTERNAL_ONLY() RBIMPL_ATTR_DEPRECATED(("only for internal use"))

RBIMPL_ATTR_DEPRECATED_INTERNAL_ONLY() void rb_clear_constant_cache(void);

/* from version.c */
#if defined(RUBY_SHOW_COPYRIGHT_TO_DIE) && !!(RUBY_SHOW_COPYRIGHT_TO_DIE+0)
# error RUBY_SHOW_COPYRIGHT_TO_DIE is deprecated
#endif

#endif /* RUBY_RUBY_BACKWARD_H */
ruby.h000064400000002543151732674300005712 0ustar00#ifndef RUBY_H                                       /*-*-C++-*-vi:se ft=cpp:*/
#define RUBY_H 1
/**
 * @author     $Author$
 * @date       Sun 10 12:06:15 Jun JST 2007
 * @copyright  2007-2008 Yukihiro Matsumoto
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 */
#define HAVE_RUBY_ATOMIC_H      1
#define HAVE_RUBY_DEBUG_H       1
#define HAVE_RUBY_DEFINES_H     1
#define HAVE_RUBY_ENCODING_H    1
#define HAVE_RUBY_FIBER_SCHEDULER_H 1
#define HAVE_RUBY_INTERN_H      1
#define HAVE_RUBY_IO_H          1
#define HAVE_RUBY_MEMORY_VIEW_H 1
#define HAVE_RUBY_MISSING_H     1
#define HAVE_RUBY_ONIGMO_H      1
#define HAVE_RUBY_ONIGURUMA_H   1
#define HAVE_RUBY_RACTOR_H      1
#define HAVE_RUBY_RANDOM_H      1
#define HAVE_RUBY_RE_H          1
#define HAVE_RUBY_REGEX_H       1
#define HAVE_RUBY_RUBY_H        1
#define HAVE_RUBY_ST_H          1
#define HAVE_RUBY_THREAD_H      1
#define HAVE_RUBY_THREAD_NATIVE_H 1
#define HAVE_RUBY_UTIL_H        1
#define HAVE_RUBY_VERSION_H     1
#define HAVE_RUBY_VM_H          1
#ifdef _WIN32
#define HAVE_RUBY_WIN32_H       1
#endif

#include "ruby/ruby.h"

#endif /* RUBY_H */
libxml2/libxml/parser.h000064400000165622151733237440011076 0ustar00/**
 * @file
 * 
 * @brief Validating XML 1.0 parser
 * 
 * Interfaces, constants and types related to the XML parser.
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */

#ifndef __XML_PARSER_H__
#define __XML_PARSER_H__

#include <libxml/xmlversion.h>
/** @cond ignore */
#define XML_TREE_INTERNALS
/** @endcond */
#include <libxml/tree.h>
#undef XML_TREE_INTERNALS
#include <libxml/dict.h>
#include <libxml/hash.h>
#include <libxml/valid.h>
#include <libxml/entities.h>
#include <libxml/xmlerror.h>
#include <libxml/xmlstring.h>
#include <libxml/xmlmemory.h>
#include <libxml/encoding.h>
#include <libxml/xmlIO.h>
/* for compatibility */
#include <libxml/SAX2.h>
#include <libxml/threads.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * The default version of XML used: 1.0
 */
#define XML_DEFAULT_VERSION	"1.0"

/**
 * Status after parsing a document
 */
typedef enum {
    /** not well-formed */
    XML_STATUS_NOT_WELL_FORMED          = (1 << 0),
    /** not namespace-well-formed */
    XML_STATUS_NOT_NS_WELL_FORMED       = (1 << 1),
    /** DTD validation failed */
    XML_STATUS_DTD_VALIDATION_FAILED    = (1 << 2),
    /** catastrophic failure like OOM or I/O error */
    XML_STATUS_CATASTROPHIC_ERROR       = (1 << 3)
} xmlParserStatus;

/**
 * Resource type for resource loaders
 */
typedef enum {
    /** unknown */
    XML_RESOURCE_UNKNOWN = 0,
    /** main document */
    XML_RESOURCE_MAIN_DOCUMENT,
    /** external DTD */
    XML_RESOURCE_DTD,
    /** external general entity */
    XML_RESOURCE_GENERAL_ENTITY,
    /** external parameter entity */
    XML_RESOURCE_PARAMETER_ENTITY,
    /** XIncluded document */
    XML_RESOURCE_XINCLUDE,
    /** XIncluded text */
    XML_RESOURCE_XINCLUDE_TEXT
} xmlResourceType;

/**
 * Flags for parser input
 */
typedef enum {
    /** The input buffer won't be changed during parsing. */
    XML_INPUT_BUF_STATIC            = (1 << 1),
    /** The input buffer is zero-terminated. (Note that the zero
        byte shouldn't be included in buffer size.) */
    XML_INPUT_BUF_ZERO_TERMINATED   = (1 << 2),
    /** Uncompress gzipped file input */
    XML_INPUT_UNZIP                 = (1 << 3),
    /** Allow network access. Unused internally. */
    XML_INPUT_NETWORK               = (1 << 4),
    /** Allow system catalog to resolve URIs. */
    XML_INPUT_USE_SYS_CATALOG       = (1 << 5)
} xmlParserInputFlags;

/* Deprecated */
typedef void (* xmlParserInputDeallocate)(xmlChar *str);

/**
 * Parser input
 */
struct _xmlParserInput {
    /* Input buffer */
    xmlParserInputBuffer *buf XML_DEPRECATED_MEMBER;
    /**
     * @deprecated Use #xmlCtxtGetInputPosition
     *
     * The filename or URI, if any
     */
    const char *filename;
    /* unused */
    const char *directory XML_DEPRECATED_MEMBER;
    /* Base of the array to parse */
    const xmlChar *base;
    /**
     * @deprecated Use #xmlCtxtGetInputWindow
     *
     * Current char being parsed
     */
    const xmlChar *cur;
    /* end of the array to parse */
    const xmlChar *end;
    /* unused */
    int length XML_DEPRECATED_MEMBER;
    /**
     * @deprecated Use #xmlCtxtGetInputPosition
     *
     * Current line
     */
    int line;
    /**
     * @deprecated Use #xmlCtxtGetInputPosition
     *
     * Current column
     */
    int col;
    /**
     * @deprecated Use #xmlCtxtGetInputPosition
     *
     * How many xmlChars already consumed
     */
    unsigned long consumed;
    /* function to deallocate the base */
    xmlParserInputDeallocate free XML_DEPRECATED_MEMBER;
    /* unused */
    const xmlChar *encoding XML_DEPRECATED_MEMBER;
    /* the version string for entity */
    const xmlChar *version XML_DEPRECATED_MEMBER;
    /* Flags */
    int flags XML_DEPRECATED_MEMBER;
    /* an unique identifier for the entity, unused internally */
    int id XML_DEPRECATED_MEMBER;
    /* unused */
    unsigned long parentConsumed XML_DEPRECATED_MEMBER;
    /* entity, if any */
    xmlEntity *entity XML_DEPRECATED_MEMBER;
};

/** @cond ignore */

typedef struct _xmlParserNodeInfo xmlParserNodeInfo;
typedef xmlParserNodeInfo *xmlParserNodeInfoPtr;

struct _xmlParserNodeInfo {
  const struct _xmlNode* node;
  /* Position & line # that text that created the node begins & ends on */
  unsigned long begin_pos;
  unsigned long begin_line;
  unsigned long end_pos;
  unsigned long end_line;
};

typedef struct _xmlParserNodeInfoSeq xmlParserNodeInfoSeq;
typedef xmlParserNodeInfoSeq *xmlParserNodeInfoSeqPtr;
struct _xmlParserNodeInfoSeq {
  unsigned long maximum;
  unsigned long length;
  xmlParserNodeInfo* buffer;
};

/*
 * Internal type
 */
typedef enum {
    XML_PARSER_EOF = -1,	/* nothing is to be parsed */
    XML_PARSER_START = 0,	/* nothing has been parsed */
    XML_PARSER_MISC,		/* Misc* before int subset */
    XML_PARSER_PI,		/* Within a processing instruction */
    XML_PARSER_DTD,		/* within some DTD content */
    XML_PARSER_PROLOG,		/* Misc* after internal subset */
    XML_PARSER_COMMENT,		/* within a comment */
    XML_PARSER_START_TAG,	/* within a start tag */
    XML_PARSER_CONTENT,		/* within the content */
    XML_PARSER_CDATA_SECTION,	/* within a CDATA section */
    XML_PARSER_END_TAG,		/* within a closing tag */
    XML_PARSER_ENTITY_DECL,	/* within an entity declaration */
    XML_PARSER_ENTITY_VALUE,	/* within an entity value in a decl */
    XML_PARSER_ATTRIBUTE_VALUE,	/* within an attribute value */
    XML_PARSER_SYSTEM_LITERAL,	/* within a SYSTEM value */
    XML_PARSER_EPILOG,		/* the Misc* after the last end tag */
    XML_PARSER_IGNORE,		/* within an IGNORED section */
    XML_PARSER_PUBLIC_LITERAL,	/* within a PUBLIC value */
    XML_PARSER_XML_DECL         /* before XML decl (but after BOM) */
} xmlParserInputState;

/*
 * Internal bits in the 'loadsubset' context member
 */
#define XML_DETECT_IDS		2
#define XML_COMPLETE_ATTRS	4
#define XML_SKIP_IDS		8

/*
 * Internal type. Only XML_PARSE_READER is used.
 */
typedef enum {
    XML_PARSE_UNKNOWN = 0,
    XML_PARSE_DOM = 1,
    XML_PARSE_SAX = 2,
    XML_PARSE_PUSH_DOM = 3,
    XML_PARSE_PUSH_SAX = 4,
    XML_PARSE_READER = 5
} xmlParserMode;

typedef struct _xmlStartTag xmlStartTag;
typedef struct _xmlParserNsData xmlParserNsData;
typedef struct _xmlAttrHashBucket xmlAttrHashBucket;

/** @endcond */

/**
 * Callback for custom resource loaders.
 *
 * `flags` can contain XML_INPUT_UNZIP and XML_INPUT_NETWORK.
 *
 * The URL is resolved using XML catalogs before being passed to
 * the callback.
 *
 * On success, `out` should be set to a new parser input object and
 * XML_ERR_OK should be returned.
 *
 * @param ctxt  parser context
 * @param url  URL or system ID to load
 * @param publicId  publid ID from DTD (optional)
 * @param type  resource type
 * @param flags  flags
 * @param out  result pointer
 * @returns an xmlParserErrors code.
 */
typedef xmlParserErrors
(*xmlResourceLoader)(void *ctxt, const char *url, const char *publicId,
                     xmlResourceType type, xmlParserInputFlags flags,
                     xmlParserInput **out);

/**
 * Parser context
 */
struct _xmlParserCtxt {
    /**
     * @deprecated Use xmlCtxtGetSaxHandler() and
     * xmlCtxtSetSaxHandler().
     *
     * the SAX handler
     */
    struct _xmlSAXHandler *sax;
    /**
     * @deprecated Use #xmlCtxtGetUserData
     *
     * user data for SAX interface, defaults to the context itself
     */
    void *userData;
    /**
     * @deprecated Use xmlCtxtGetDocument()
     *
     * the document being built
     */
    xmlDoc *myDoc;
    /**
     * @deprecated Use xmlCtxtGetStatus()
     *
     * is the document well formed?
     */
    int wellFormed;
    /**
     * @deprecated Use xmlParserOption XML_PARSE_NOENT
     *
     * shall we replace entities?
     */
    int replaceEntities XML_DEPRECATED_MEMBER;
    /**
     * @deprecated Use xmlCtxtGetVersion()
     *
     * the XML version string
     */
    xmlChar *version;
    /**
     * @deprecated Use xmlCtxtGetDeclaredEncoding()
     *
     * the declared encoding, if any
     */
    xmlChar *encoding;
    /**
     * @deprecated Use xmlCtxtGetStandalone()
     *
     * standalone document
     */
    int standalone;

    /**
     * @deprecated Use xmlCtxtIsHtml()
     *
     * non-zero for HTML documents, actually an htmlInsertMode
     */
    int html;

    /* Input stream stack */

    /**
     * Current input stream
     */
    /* TODO: Add accessors, see issue #762 */
    xmlParserInput *input;
    /* Number of current input streams */
    int inputNr;
    /* Max number of input streams */
    int inputMax XML_DEPRECATED_MEMBER;
    /* stack of inputs */
    xmlParserInput **inputTab;

    /* Node analysis stack only used for DOM building */

    /**
     * @deprecated Use #xmlCtxtGetNode
     *
     * The current element.
     */
    xmlNode *node;
    /* Depth of the parsing stack */
    int nodeNr XML_DEPRECATED_MEMBER;
    /* Max depth of the parsing stack */
    int nodeMax XML_DEPRECATED_MEMBER;
    /* array of nodes */
    xmlNode **nodeTab XML_DEPRECATED_MEMBER;

    /* Whether node info should be kept */
    int record_info;
    /* info about each node parsed */
    xmlParserNodeInfoSeq node_seq XML_DEPRECATED_MEMBER;

    /**
     * @deprecated Use xmlCtxtGetLastError()
     *
     * error code
     */
    int errNo;

    /* reference and external subset */
    int hasExternalSubset XML_DEPRECATED_MEMBER;
    /* the internal subset has PE refs */
    int hasPErefs XML_DEPRECATED_MEMBER;
    /* unused */
    int external XML_DEPRECATED_MEMBER;

    /**
     * @deprecated Use xmlCtxtGetStatus()
     *
     * is the document valid
     */
    int valid;
    /**
     * @deprecated Use xmlParserOption XML_PARSE_DTDVALID
     *
     * shall we try to validate?
     */
    int validate XML_DEPRECATED_MEMBER;
    /**
     * @deprecated Use xmlCtxtGetValidCtxt()
     *
     * The validity context
     */
    xmlValidCtxt vctxt;

    /* push parser state */
    xmlParserInputState instate XML_DEPRECATED_MEMBER;
    /* unused */
    int token XML_DEPRECATED_MEMBER;

    /**
     * @deprecated Don't use
     *
     * The main document URI, if available, with its last
     * component stripped.
     */
    char *directory;

    /* Node name stack */

    /* Current parsed Node */
    const xmlChar *name XML_DEPRECATED_MEMBER;
    /* Depth of the parsing stack */
    int nameNr XML_DEPRECATED_MEMBER;
    /* Max depth of the parsing stack */
    int nameMax XML_DEPRECATED_MEMBER;
    /* array of nodes */
    const xmlChar **nameTab XML_DEPRECATED_MEMBER;

    /* unused */
    long nbChars XML_DEPRECATED_MEMBER;
    /* used by progressive parsing lookup */
    long checkIndex XML_DEPRECATED_MEMBER;
    /**
     * @deprecated Use inverted xmlParserOption XML_PARSE_NOBLANKS
     *
     * ugly but ...
     */
    int keepBlanks XML_DEPRECATED_MEMBER;
    /**
     * @deprecated Use xmlCtxtIsStopped()
     *
     * SAX callbacks are disabled
     */
    int disableSAX XML_DEPRECATED_MEMBER;
    /**
     * @deprecated Use xmlCtxtIsInSubset
     *
     * Set if DTD content is parsed.
     *
     * - 0: not in DTD
     * - 1: in internal DTD subset
     * - 2: in external DTD subset
     */
    int inSubset;
    /**
     * @deprecated Use the `name` argument of the
     * `internalSubset` SAX callback or #xmlCtxtGetDocTypeDecl
     *
     * Name of the internal subset (root element type).
     */
    const xmlChar *intSubName;
    /**
     * @deprecated Use the `systemId` argument of the
     * `internalSubset` SAX callback or #xmlCtxtGetDocTypeDecl
     *
     * System identifier (URI) of external the subset.
     */
    xmlChar *extSubURI;
    /**
     * @deprecated Use the `publicId` argument of the
     * `internalSubset` SAX callback or #xmlCtxtGetDocTypeDecl
     *
     * This member is MISNAMED. It contains the *public* identifier
     * of the external subset.
     */
    xmlChar *extSubSystem;

    /* xml:space values */

    /* Should the parser preserve spaces */
    int *space XML_DEPRECATED_MEMBER;
    /* Depth of the parsing stack */
    int spaceNr XML_DEPRECATED_MEMBER;
    /* Max depth of the parsing stack */
    int spaceMax XML_DEPRECATED_MEMBER;
    /* array of space infos */
    int *spaceTab XML_DEPRECATED_MEMBER;

    /* to prevent entity substitution loops */
    int depth XML_DEPRECATED_MEMBER;
    /* unused */
    xmlParserInput *entity XML_DEPRECATED_MEMBER;
    /* unused */
    int charset XML_DEPRECATED_MEMBER;
    /* Those two fields are there to speed up large node parsing */
    int nodelen XML_DEPRECATED_MEMBER;
    int nodemem XML_DEPRECATED_MEMBER;
    /**
     * @deprecated Use xmlParserOption XML_PARSE_PEDANTIC
     *
     * signal pedantic warnings
     */
    int pedantic XML_DEPRECATED_MEMBER;
    /**
     * @deprecated Use xmlCtxtGetPrivate() and xmlCtxtSetPrivate()
     *
     * For user data, libxml won't touch it
     */
    void *_private;
    /**
     * @deprecated Use xmlParserOption XML_PARSE_DTDLOAD,
     * XML_PARSE_DTDATTR or XML_PARSE_SKIP_IDS.
     *
     * Control loading of the external subset and handling of IDs.
     * Other options like `validate` can override this value.
     *
     * - 0: The default behavior is to process IDs and to ignore
     *   the external subset.
     * - XML_DETECT_IDS: Load external subset. This flag is
     *   misnamed. ID handling is only controlled by XML_SKIP_IDS.
     * - XML_COMPLETE_ATTRS: Load external subset and process
     *   default attributes.
     * - XML_SKIP_IDS: Ignore IDs.
     */
    int loadsubset XML_DEPRECATED_MEMBER;
    /* unused */
    int linenumbers XML_DEPRECATED_MEMBER;
    /**
     * @deprecated Use xmlCtxtGetCatalogs() and xmlCtxtSetCatalogs()
     *
     * document's own catalog
     */
    void *catalogs XML_DEPRECATED_MEMBER;
    /**
     * @deprecated Use xmlParserOption XML_PARSE_RECOVER
     * run in recovery mode
     */
    int recovery XML_DEPRECATED_MEMBER;
    /* unused */
    int progressive XML_DEPRECATED_MEMBER;
    /**
     * @deprecated Use xmlCtxtGetDict() and xmlCtxtSetDict()
     *
     * dictionary for the parser
     */
    xmlDict *dict;
    /* array for the attributes callbacks */
    const xmlChar **atts XML_DEPRECATED_MEMBER;
    /* the size of the array */
    int maxatts XML_DEPRECATED_MEMBER;
    /* unused */
    int docdict XML_DEPRECATED_MEMBER;

    /*
     * pre-interned strings
     */
    const xmlChar *str_xml XML_DEPRECATED_MEMBER;
    const xmlChar *str_xmlns XML_DEPRECATED_MEMBER;
    const xmlChar *str_xml_ns XML_DEPRECATED_MEMBER;

    /*
     * Everything below is used only by the new SAX mode
     */

    /* operating in the new SAX mode */
    int sax2 XML_DEPRECATED_MEMBER;
    /* the number of inherited namespaces */
    int nsNr XML_DEPRECATED_MEMBER;
    /* the size of the arrays */
    int nsMax XML_DEPRECATED_MEMBER;
    /* the array of prefix/namespace name */
    const xmlChar **nsTab XML_DEPRECATED_MEMBER;
    /* which attribute were allocated */
    unsigned *attallocs XML_DEPRECATED_MEMBER;
    /* array of data for push */
    xmlStartTag *pushTab XML_DEPRECATED_MEMBER;
    /* defaulted attributes if any */
    xmlHashTable *attsDefault XML_DEPRECATED_MEMBER;
    /* non-CDATA attributes if any */
    xmlHashTable *attsSpecial XML_DEPRECATED_MEMBER;

    /**
     * @deprecated Use xmlCtxtGetStatus()
     *
     * is the document XML Namespace okay
     */
    int nsWellFormed;
    /**
     * @deprecated Use xmlCtxtGetOptions()
     *
     * Extra options
     */
    int options;

    /**
     * @deprecated Use inverted xmlParserOption XML_PARSE_NODICT
     *
     * Use dictionary names for the tree
     */
    int dictNames XML_DEPRECATED_MEMBER;

    /*
     * Those fields are needed only for streaming parsing so far
     */

    /* number of freed element nodes */
    int freeElemsNr XML_DEPRECATED_MEMBER;
    /* List of freed element nodes */
    xmlNode *freeElems XML_DEPRECATED_MEMBER;
    /* number of freed attributes nodes */
    int freeAttrsNr XML_DEPRECATED_MEMBER;
    /* List of freed attributes nodes */
    xmlAttr *freeAttrs XML_DEPRECATED_MEMBER;

    /**
     * @deprecated Use xmlCtxtGetLastError()
     *
     * the complete error information for the last error.
     */
    xmlError lastError XML_DEPRECATED_MEMBER;
    /* the parser mode */
    xmlParserMode parseMode XML_DEPRECATED_MEMBER;
    /* unused */
    unsigned long nbentities XML_DEPRECATED_MEMBER;
    /* size of external entities */
    unsigned long sizeentities XML_DEPRECATED_MEMBER;

    /* for use by HTML non-recursive parser */
    /* Current NodeInfo */
    xmlParserNodeInfo *nodeInfo XML_DEPRECATED_MEMBER;
    /* Depth of the parsing stack */
    int nodeInfoNr XML_DEPRECATED_MEMBER;
    /* Max depth of the parsing stack */
    int nodeInfoMax XML_DEPRECATED_MEMBER;
    /* array of nodeInfos */
    xmlParserNodeInfo *nodeInfoTab XML_DEPRECATED_MEMBER;

    /* we need to label inputs */
    int input_id XML_DEPRECATED_MEMBER;
    /* volume of entity copy */
    unsigned long sizeentcopy XML_DEPRECATED_MEMBER;

    /* quote state for push parser */
    int endCheckState XML_DEPRECATED_MEMBER;
    /* number of errors */
    unsigned short nbErrors XML_DEPRECATED_MEMBER;
    /* number of warnings */
    unsigned short nbWarnings XML_DEPRECATED_MEMBER;
    /* maximum amplification factor */
    unsigned maxAmpl XML_DEPRECATED_MEMBER;

    /* namespace database */
    xmlParserNsData *nsdb XML_DEPRECATED_MEMBER;
    /* allocated size */
    unsigned attrHashMax XML_DEPRECATED_MEMBER;
    /* atttribute hash table */
    xmlAttrHashBucket *attrHash XML_DEPRECATED_MEMBER;

    xmlStructuredErrorFunc errorHandler XML_DEPRECATED_MEMBER;
    void *errorCtxt XML_DEPRECATED_MEMBER;

    xmlResourceLoader resourceLoader XML_DEPRECATED_MEMBER;
    void *resourceCtxt XML_DEPRECATED_MEMBER;

    xmlCharEncConvImpl convImpl XML_DEPRECATED_MEMBER;
    void *convCtxt XML_DEPRECATED_MEMBER;
};

/**
 * A SAX Locator.
 */
struct _xmlSAXLocator {
    const xmlChar *(*getPublicId)(void *ctx);
    const xmlChar *(*getSystemId)(void *ctx);
    int (*getLineNumber)(void *ctx);
    int (*getColumnNumber)(void *ctx);
};

/**
 * SAX callback to resolve external entities.
 *
 * This is only used to load DTDs. The preferred way to install
 * custom resolvers is #xmlCtxtSetResourceLoader.
 *
 * @param ctx  the user data (XML parser context)
 * @param publicId  The public identifier of the entity
 * @param systemId  The system identifier of the entity (URL)
 * @returns the xmlParserInput if inlined or NULL for DOM behaviour.
 */
typedef xmlParserInput *(*resolveEntitySAXFunc) (void *ctx,
				const xmlChar *publicId,
				const xmlChar *systemId);
/**
 * SAX callback for the internal subset.
 *
 * @param ctx  the user data (XML parser context)
 * @param name  the root element name
 * @param publicId  the public identifier
 * @param systemId  the system identifier (e.g. filename or URL)
 */
typedef void (*internalSubsetSAXFunc) (void *ctx,
				const xmlChar *name,
				const xmlChar *publicId,
				const xmlChar *systemId);
/**
 * SAX callback for the external subset.
 *
 * @param ctx  the user data (XML parser context)
 * @param name  the root element name
 * @param publicId  the public identifier
 * @param systemId  the system identifier (e.g. filename or URL)
 */
typedef void (*externalSubsetSAXFunc) (void *ctx,
				const xmlChar *name,
				const xmlChar *publicId,
				const xmlChar *systemId);
/**
 * SAX callback to look up a general entity by name.
 *
 * @param ctx  the user data (XML parser context)
 * @param name  The entity name
 * @returns the xmlEntity if found.
 */
typedef xmlEntity *(*getEntitySAXFunc) (void *ctx,
				const xmlChar *name);
/**
 * SAX callback to look up a parameter entity by name.
 *
 * @param ctx  the user data (XML parser context)
 * @param name  The entity name
 * @returns the xmlEntity if found.
 */
typedef xmlEntity *(*getParameterEntitySAXFunc) (void *ctx,
				const xmlChar *name);
/**
 * SAX callback for entity declarations.
 *
 * @param ctx  the user data (XML parser context)
 * @param name  the entity name
 * @param type  the entity type
 * @param publicId  The public ID of the entity
 * @param systemId  The system ID of the entity
 * @param content  the entity value (without processing).
 */
typedef void (*entityDeclSAXFunc) (void *ctx,
				const xmlChar *name,
				int type,
				const xmlChar *publicId,
				const xmlChar *systemId,
				xmlChar *content);
/**
 * SAX callback for notation declarations.
 *
 * @param ctx  the user data (XML parser context)
 * @param name  The name of the notation
 * @param publicId  The public ID of the notation
 * @param systemId  The system ID of the notation
 */
typedef void (*notationDeclSAXFunc)(void *ctx,
				const xmlChar *name,
				const xmlChar *publicId,
				const xmlChar *systemId);
/**
 * SAX callback for attribute declarations.
 *
 * @param ctx  the user data (XML parser context)
 * @param elem  the name of the element
 * @param fullname  the attribute name
 * @param type  the attribute type
 * @param def  the type of default value
 * @param defaultValue  the attribute default value
 * @param tree  the tree of enumerated value set
 */
typedef void (*attributeDeclSAXFunc)(void *ctx,
				const xmlChar *elem,
				const xmlChar *fullname,
				int type,
				int def,
				const xmlChar *defaultValue,
				xmlEnumeration *tree);
/**
 * SAX callback for element declarations.
 *
 * @param ctx  the user data (XML parser context)
 * @param name  the element name
 * @param type  the element type
 * @param content  the element value tree
 */
typedef void (*elementDeclSAXFunc)(void *ctx,
				const xmlChar *name,
				int type,
				xmlElementContent *content);
/**
 * SAX callback for unparsed entity declarations.
 *
 * @param ctx  the user data (XML parser context)
 * @param name  The name of the entity
 * @param publicId  The public ID of the entity
 * @param systemId  The system ID of the entity
 * @param notationName  the name of the notation
 */
typedef void (*unparsedEntityDeclSAXFunc)(void *ctx,
				const xmlChar *name,
				const xmlChar *publicId,
				const xmlChar *systemId,
				const xmlChar *notationName);
/**
 * This callback receives the "document locator" at startup,
 * which is always the global xmlDefaultSAXLocator.
 *
 * Everything is available on the context, so this is useless in
 * our case.
 *
 * @param ctx  the user data (XML parser context)
 * @param loc  A SAX Locator
 */
typedef void (*setDocumentLocatorSAXFunc) (void *ctx,
				xmlSAXLocator *loc);
/**
 * SAX callback for start of document.
 *
 * @param ctx  the user data (XML parser context)
 */
typedef void (*startDocumentSAXFunc) (void *ctx);
/**
 * SAX callback for end of document.
 *
 * @param ctx  the user data (XML parser context)
 */
typedef void (*endDocumentSAXFunc) (void *ctx);
/**
 * SAX callback for start tags.
 *
 * @param ctx  the user data (XML parser context)
 * @param name  The element name, including namespace prefix
 * @param atts  An array of name/value attributes pairs, NULL terminated
 */
typedef void (*startElementSAXFunc) (void *ctx,
				const xmlChar *name,
				const xmlChar **atts);
/**
 * SAX callback for end tags.
 *
 * @param ctx  the user data (XML parser context)
 * @param name  The element name
 */
typedef void (*endElementSAXFunc) (void *ctx,
				const xmlChar *name);
/**
 * Callback for attributes.
 *
 * @deprecated This typedef is unused.
 *
 * @param ctx  the user data (XML parser context)
 * @param name  The attribute name, including namespace prefix
 * @param value  The attribute value
 */
typedef void (*attributeSAXFunc) (void *ctx,
				const xmlChar *name,
				const xmlChar *value);
/**
 * SAX callback for entity references.
 *
 * @param ctx  the user data (XML parser context)
 * @param name  The entity name
 */
typedef void (*referenceSAXFunc) (void *ctx,
				const xmlChar *name);
/**
 * SAX callback for character data.
 *
 * @param ctx  the user data (XML parser context)
 * @param ch  a xmlChar string
 * @param len  the number of xmlChar
 */
typedef void (*charactersSAXFunc) (void *ctx,
				const xmlChar *ch,
				int len);
/**
 * SAX callback for "ignorable" whitespace.
 *
 * @param ctx  the user data (XML parser context)
 * @param ch  a xmlChar string
 * @param len  the number of xmlChar
 */
typedef void (*ignorableWhitespaceSAXFunc) (void *ctx,
				const xmlChar *ch,
				int len);
/**
 * SAX callback for processing instructions.
 *
 * @param ctx  the user data (XML parser context)
 * @param target  the target name
 * @param data  the PI data's
 */
typedef void (*processingInstructionSAXFunc) (void *ctx,
				const xmlChar *target,
				const xmlChar *data);
/**
 * SAX callback for comments.
 *
 * @param ctx  the user data (XML parser context)
 * @param value  the comment content
 */
typedef void (*commentSAXFunc) (void *ctx,
				const xmlChar *value);
/**
 * SAX callback for CDATA sections.
 *
 * @param ctx  the user data (XML parser context)
 * @param value  The pcdata content
 * @param len  the block length
 */
typedef void (*cdataBlockSAXFunc) (
	                        void *ctx,
				const xmlChar *value,
				int len);
/**
 * SAX callback for warning messages.
 *
 * @param ctx  an XML parser context
 * @param msg  the message to display/transmit
 * @param ...  extra parameters for the message display
 */
typedef void (*warningSAXFunc) (void *ctx,
				const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
/**
 * SAX callback for error messages.
 *
 * @param ctx  an XML parser context
 * @param msg  the message to display/transmit
 * @param ...  extra parameters for the message display
 */
typedef void (*errorSAXFunc) (void *ctx,
				const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
/**
 * SAX callback for fatal error messages.
 *
 * @param ctx  an XML parser context
 * @param msg  the message to display/transmit
 * @param ...  extra parameters for the message display
 */
typedef void (*fatalErrorSAXFunc) (void *ctx,
				const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
/**
 * SAX callback to get standalone status.
 *
 * @param ctx  the user data (XML parser context)
 * @returns 1 if true
 */
typedef int (*isStandaloneSAXFunc) (void *ctx);
/**
 * SAX callback to get internal subset status.
 *
 * @param ctx  the user data (XML parser context)
 * @returns 1 if true
 */
typedef int (*hasInternalSubsetSAXFunc) (void *ctx);

/**
 * SAX callback to get external subset status.
 *
 * @param ctx  the user data (XML parser context)
 * @returns 1 if true
 */
typedef int (*hasExternalSubsetSAXFunc) (void *ctx);

/************************************************************************
 *									*
 *			The SAX version 2 API extensions		*
 *									*
 ************************************************************************/
/**
 * Special constant required for SAX2 handlers.
 */
#define XML_SAX2_MAGIC 0xDEEDBEAF

/**
 * SAX2 callback for start tags.
 *
 * It provides the namespace information for the element, as well as
 * the new namespace declarations on the element.
 *
 * @param ctx  the user data (XML parser context)
 * @param localname  the local name of the element
 * @param prefix  the element namespace prefix if available
 * @param URI  the element namespace name if available
 * @param nb_namespaces  number of namespace definitions on that node
 * @param namespaces  pointer to the array of prefix/URI pairs namespace definitions
 * @param nb_attributes  the number of attributes on that node
 * @param nb_defaulted  the number of defaulted attributes. The defaulted
 *                  ones are at the end of the array
 * @param attributes  pointer to the array of (localname/prefix/URI/value/end)
 *               attribute values.
 */

typedef void (*startElementNsSAX2Func) (void *ctx,
					const xmlChar *localname,
					const xmlChar *prefix,
					const xmlChar *URI,
					int nb_namespaces,
					const xmlChar **namespaces,
					int nb_attributes,
					int nb_defaulted,
					const xmlChar **attributes);

/**
 * SAX2 callback for end tags.
 *
 * It provides the namespace information for the element.
 *
 * @param ctx  the user data (XML parser context)
 * @param localname  the local name of the element
 * @param prefix  the element namespace prefix if available
 * @param URI  the element namespace name if available
 */

typedef void (*endElementNsSAX2Func)   (void *ctx,
					const xmlChar *localname,
					const xmlChar *prefix,
					const xmlChar *URI);

/**
 * Callbacks for SAX parser
 *
 * For DTD-related handlers, it's recommended to either use the
 * original libxml2 handler or set them to NULL if DTDs can be
 * ignored.
 */
struct _xmlSAXHandler {
    /**
     * Called after the start of the document type declaration
     * was parsed.
     *
     * Should typically not be modified.
     */
    internalSubsetSAXFunc internalSubset;
    /**
     * Standalone status. Not invoked by the parser. Not supposed
     * to be changed by applications.
     */
    isStandaloneSAXFunc isStandalone;
    /**
     * Internal subset availability. Not invoked by the parser.
     * Not supposed to be changed by applications.
     */
    hasInternalSubsetSAXFunc hasInternalSubset;
    /**
     * External subset availability. Not invoked by the parser.
     * Not supposed to be changed by applications.
     */
    hasExternalSubsetSAXFunc hasExternalSubset;
    /**
     * Only called when loading external DTDs. Not called to load
     * external entities.
     *
     * Should typically not be modified.
     */
    resolveEntitySAXFunc resolveEntity;
    /**
     * Called when looking up general entities.
     *
     * Should typically not be modified.
     */
    getEntitySAXFunc getEntity;
    /**
     * Called after an entity declaration was parsed.
     *
     * Should typically not be modified.
     */
    entityDeclSAXFunc entityDecl;
    /**
     * Called after a notation declaration was parsed.
     *
     * Should typically not be modified.
     */
    notationDeclSAXFunc notationDecl;
    /**
     * Called after an attribute declaration was parsed.
     *
     * Should typically not be modified.
     */
    attributeDeclSAXFunc attributeDecl;
    /**
     * Called after an element declaration was parsed.
     *
     * Should typically not be modified.
     */
    elementDeclSAXFunc elementDecl;
    /**
     * Called after an unparsed entity declaration was parsed.
     *
     * Should typically not be modified.
     */
    unparsedEntityDeclSAXFunc unparsedEntityDecl;
    /**
     * This callback receives the "document locator" at startup,
     * which is always the global xmlDefaultSAXLocator.
     *
     * Everything is available on the context, so this is useless in
     * our case.
     */
    setDocumentLocatorSAXFunc setDocumentLocator;
    /**
     * Called after the XML declaration was parsed.
     *
     * Use xmlCtxtGetVersion(), xmlCtxtGetDeclaredEncoding() and
     * xmlCtxtGetStandalone() to get data from the XML declaration.
     */
    startDocumentSAXFunc startDocument;
    /**
     * Called at the end of the document.
     */
    endDocumentSAXFunc endDocument;
    /**
     * Legacy start tag handler
     *
     * `startElement` and `endElement` are only used by the legacy SAX1
     * interface and should not be used in new software. If you really
     * have to enable SAX1, the preferred way is set the `initialized`
     * member to 1 instead of XML_SAX2_MAGIC.
     *
     * For backward compatibility, it's also possible to set the
     * `startElementNs` and `endElementNs` handlers to NULL.
     *
     * You can also set the XML_PARSE_SAX1 parser option, but versions
     * older than 2.12.0 will probably crash if this option is provided
     * together with custom SAX callbacks.
     */
    startElementSAXFunc startElement;
    /**
     * See _xmlSAXHandler.startElement
     */
    endElementSAXFunc endElement;
    /**
     * Called after an entity reference was parsed.
     */
    referenceSAXFunc reference;
    /**
     * Called after a character data was parsed.
     */
    charactersSAXFunc characters;
    /**
     * Called after "ignorable" whitespace was parsed.
     *
     * `ignorableWhitespace` should always be set to the same value
     * as `characters`. Otherwise, the parser will try to detect
     * whitespace which is unreliable.
     */
    ignorableWhitespaceSAXFunc ignorableWhitespace;
    /**
     * Called after a processing instruction was parsed.
     */
    processingInstructionSAXFunc processingInstruction;
    /**
     * Called after a comment was parsed.
     */
    commentSAXFunc comment;
    /**
     * Callback for warning messages.
     */
    warningSAXFunc warning;
    /**
     * Callback for error messages.
     */
    errorSAXFunc error;
    /**
     * Unused, all errors go to `error`.
     */
    fatalErrorSAXFunc fatalError;
    /**
     * Called when looking up parameter entities.
     *
     * Should typically not be modified.
     */
    getParameterEntitySAXFunc getParameterEntity;
    /**
     * Called after a CDATA section was parsed.
     */
    cdataBlockSAXFunc cdataBlock;
    /**
     * Called to parse the external subset.
     *
     * Should typically not be modified.
     */
    externalSubsetSAXFunc externalSubset;
    /**
     * Legacy magic value
     *
     * `initialized` should always be set to XML_SAX2_MAGIC to
     * enable the modern SAX2 interface.
     */
    unsigned int initialized;
    /**
     * Application data
     */
    void *_private;
    /**
     * Called after a start tag was parsed.
     */
    startElementNsSAX2Func startElementNs;
    /**
     * Called after an end tag was parsed.
     */
    endElementNsSAX2Func endElementNs;
    /**
     * Structured error handler.
     *
     * Takes precedence over `error` or `warning`, but modern code
     * should use xmlCtxtSetErrorHandler().
     */
    xmlStructuredErrorFunc serror;
};

/**
 * SAX handler, version 1.
 *
 * @deprecated Use version 2 handlers.
 */
typedef struct _xmlSAXHandlerV1 xmlSAXHandlerV1;
typedef xmlSAXHandlerV1 *xmlSAXHandlerV1Ptr;
/**
 * SAX handler, version 1.
 *
 * @deprecated Use version 2 handlers.
 */
struct _xmlSAXHandlerV1 {
    internalSubsetSAXFunc internalSubset;
    isStandaloneSAXFunc isStandalone;
    hasInternalSubsetSAXFunc hasInternalSubset;
    hasExternalSubsetSAXFunc hasExternalSubset;
    resolveEntitySAXFunc resolveEntity;
    getEntitySAXFunc getEntity;
    entityDeclSAXFunc entityDecl;
    notationDeclSAXFunc notationDecl;
    attributeDeclSAXFunc attributeDecl;
    elementDeclSAXFunc elementDecl;
    unparsedEntityDeclSAXFunc unparsedEntityDecl;
    setDocumentLocatorSAXFunc setDocumentLocator;
    startDocumentSAXFunc startDocument;
    endDocumentSAXFunc endDocument;
    startElementSAXFunc startElement;
    endElementSAXFunc endElement;
    referenceSAXFunc reference;
    charactersSAXFunc characters;
    ignorableWhitespaceSAXFunc ignorableWhitespace;
    processingInstructionSAXFunc processingInstruction;
    commentSAXFunc comment;
    warningSAXFunc warning;
    errorSAXFunc error;
    fatalErrorSAXFunc fatalError; /* unused error() get all the errors */
    getParameterEntitySAXFunc getParameterEntity;
    cdataBlockSAXFunc cdataBlock;
    externalSubsetSAXFunc externalSubset;
    unsigned int initialized;
};


/**
 * Callback for external entity loader.
 *
 * The URL is not resolved using XML catalogs before being passed
 * to the callback.
 *
 * @param URL  The URL or system ID of the resource requested
 * @param publicId  The public ID of the resource requested (optional)
 * @param context  the XML parser context
 * @returns the entity input parser or NULL on error.
 */
typedef xmlParserInput *(*xmlExternalEntityLoader) (const char *URL,
					 const char *publicId,
					 xmlParserCtxt *context);

/*
 * Variables
 */

XMLPUBVAR const char *const xmlParserVersion;

/** @cond ignore */

XML_DEPRECATED
XMLPUBVAR const xmlSAXLocator xmlDefaultSAXLocator;
#ifdef LIBXML_SAX1_ENABLED
/**
 * @deprecated Use #xmlSAXVersion or #xmlSAX2InitDefaultSAXHandler
 */
XML_DEPRECATED
XMLPUBVAR const xmlSAXHandlerV1 xmlDefaultSAXHandler;
#endif

XML_DEPRECATED
XMLPUBFUN int *__xmlDoValidityCheckingDefaultValue(void);
XML_DEPRECATED
XMLPUBFUN int *__xmlGetWarningsDefaultValue(void);
XML_DEPRECATED
XMLPUBFUN int *__xmlKeepBlanksDefaultValue(void);
XML_DEPRECATED
XMLPUBFUN int *__xmlLineNumbersDefaultValue(void);
XML_DEPRECATED
XMLPUBFUN int *__xmlLoadExtDtdDefaultValue(void);
XML_DEPRECATED
XMLPUBFUN int *__xmlPedanticParserDefaultValue(void);
XML_DEPRECATED
XMLPUBFUN int *__xmlSubstituteEntitiesDefaultValue(void);

#ifdef LIBXML_OUTPUT_ENABLED
XML_DEPRECATED
XMLPUBFUN int *__xmlIndentTreeOutput(void);
XML_DEPRECATED
XMLPUBFUN const char **__xmlTreeIndentString(void);
XML_DEPRECATED
XMLPUBFUN int *__xmlSaveNoEmptyTags(void);
#endif

/** @endcond */

#ifndef XML_GLOBALS_NO_REDEFINITION
  /**
   * Thread-local setting to enable validation. Defaults to 0.
   *
   * @deprecated Use the parser option XML_PARSE_DTDVALID.
   */
  #define xmlDoValidityCheckingDefaultValue \
    (*__xmlDoValidityCheckingDefaultValue())
  /**
   * Thread-local setting to disable warnings. Defaults to 1.
   *
   * @deprecated Use the parser option XML_PARSE_NOWARNING.
   */
  #define xmlGetWarningsDefaultValue \
    (*__xmlGetWarningsDefaultValue())
  /**
   * Thread-local setting to ignore some whitespace. Defaults
   * to 1.
   *
   * @deprecated Use the parser option XML_PARSE_NOBLANKS.
   */
  #define xmlKeepBlanksDefaultValue (*__xmlKeepBlanksDefaultValue())
  /**
   * Thread-local setting to store line numbers. Defaults
   * to 0, but is always enabled after setting parser options.
   *
   * @deprecated Shouldn't be needed when using parser options.
   */
  #define xmlLineNumbersDefaultValue \
    (*__xmlLineNumbersDefaultValue())
  /**
   * Thread-local setting to enable loading of external DTDs.
   * Defaults to 0.
   *
   * @deprecated Use the parser option XML_PARSE_DTDLOAD.
   */
  #define xmlLoadExtDtdDefaultValue (*__xmlLoadExtDtdDefaultValue())
  /**
   * Thread-local setting to enable pedantic warnings.
   * Defaults to 0.
   *
   * @deprecated Use the parser option XML_PARSE_PEDANTIC.
   */
  #define xmlPedanticParserDefaultValue \
    (*__xmlPedanticParserDefaultValue())
  /**
   * Thread-local setting to enable entity substitution.
   * Defaults to 0.
   *
   * @deprecated Use the parser option XML_PARSE_NOENT.
   */
  #define xmlSubstituteEntitiesDefaultValue \
    (*__xmlSubstituteEntitiesDefaultValue())
  #ifdef LIBXML_OUTPUT_ENABLED
    /**
     * Thread-local setting to disable indenting when
     * formatting output. Defaults to 1.
     *
     * @deprecated Use the xmlsave.h API with option
     * XML_SAVE_NO_INDENT.
     */
    #define xmlIndentTreeOutput (*__xmlIndentTreeOutput())
    /**
     * Thread-local setting to change the indent string.
     * Defaults to two spaces.
     *
     * @deprecated Use the xmlsave.h API and
     * xmlSaveSetIndentString().
     */
    #define xmlTreeIndentString (*__xmlTreeIndentString())
    /**
     * Thread-local setting to disable empty tags when
     * serializing. Defaults to 0.
     *
     * @deprecated Use the xmlsave.h API with option
     * XML_SAVE_NO_EMPTY.
     */
    #define xmlSaveNoEmptyTags (*__xmlSaveNoEmptyTags())
  #endif
#endif

/*
 * Init/Cleanup
 */
XMLPUBFUN void
		xmlInitParser		(void);
XMLPUBFUN void
		xmlCleanupParser	(void);
XML_DEPRECATED
XMLPUBFUN void
		xmlInitGlobals		(void);
XML_DEPRECATED
XMLPUBFUN void
		xmlCleanupGlobals	(void);

/*
 * Input functions
 */
XML_DEPRECATED
XMLPUBFUN int
		xmlParserInputRead	(xmlParserInput *in,
					 int len);
XMLPUBFUN int
		xmlParserInputGrow	(xmlParserInput *in,
					 int len);

/*
 * Basic parsing Interfaces
 */
#ifdef LIBXML_SAX1_ENABLED
XMLPUBFUN xmlDoc *
		xmlParseDoc		(const xmlChar *cur);
XMLPUBFUN xmlDoc *
		xmlParseFile		(const char *filename);
XMLPUBFUN xmlDoc *
		xmlParseMemory		(const char *buffer,
					 int size);
#endif /* LIBXML_SAX1_ENABLED */
XML_DEPRECATED
XMLPUBFUN int
		xmlSubstituteEntitiesDefault(int val);
XMLPUBFUN int
		xmlKeepBlanksDefault	(int val);
XMLPUBFUN void
		xmlStopParser		(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN int
		xmlPedanticParserDefault(int val);
XML_DEPRECATED
XMLPUBFUN int
		xmlLineNumbersDefault	(int val);

XML_DEPRECATED
XMLPUBFUN int
                xmlThrDefSubstituteEntitiesDefaultValue(int v);
XML_DEPRECATED
XMLPUBFUN int
		xmlThrDefKeepBlanksDefaultValue(int v);
XML_DEPRECATED
XMLPUBFUN int
                xmlThrDefPedanticParserDefaultValue(int v);
XML_DEPRECATED
XMLPUBFUN int
                xmlThrDefLineNumbersDefaultValue(int v);
XML_DEPRECATED
XMLPUBFUN int
                xmlThrDefDoValidityCheckingDefaultValue(int v);
XML_DEPRECATED
XMLPUBFUN int
                xmlThrDefGetWarningsDefaultValue(int v);
XML_DEPRECATED
XMLPUBFUN int
                xmlThrDefLoadExtDtdDefaultValue(int v);

#ifdef LIBXML_SAX1_ENABLED
/*
 * Recovery mode
 */
XML_DEPRECATED
XMLPUBFUN xmlDoc *
		xmlRecoverDoc		(const xmlChar *cur);
XML_DEPRECATED
XMLPUBFUN xmlDoc *
		xmlRecoverMemory	(const char *buffer,
					 int size);
XML_DEPRECATED
XMLPUBFUN xmlDoc *
		xmlRecoverFile		(const char *filename);
#endif /* LIBXML_SAX1_ENABLED */

/*
 * Less common routines and SAX interfaces
 */
XMLPUBFUN int
		xmlParseDocument	(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN int
		xmlParseExtParsedEnt	(xmlParserCtxt *ctxt);
#ifdef LIBXML_SAX1_ENABLED
XML_DEPRECATED
XMLPUBFUN int
		xmlSAXUserParseFile	(xmlSAXHandler *sax,
					 void *user_data,
					 const char *filename);
XML_DEPRECATED
XMLPUBFUN int
		xmlSAXUserParseMemory	(xmlSAXHandler *sax,
					 void *user_data,
					 const char *buffer,
					 int size);
XML_DEPRECATED
XMLPUBFUN xmlDoc *
		xmlSAXParseDoc		(xmlSAXHandler *sax,
					 const xmlChar *cur,
					 int recovery);
XML_DEPRECATED
XMLPUBFUN xmlDoc *
		xmlSAXParseMemory	(xmlSAXHandler *sax,
					 const char *buffer,
					 int size,
					 int recovery);
XML_DEPRECATED
XMLPUBFUN xmlDoc *
		xmlSAXParseMemoryWithData (xmlSAXHandler *sax,
					 const char *buffer,
					 int size,
					 int recovery,
					 void *data);
XML_DEPRECATED
XMLPUBFUN xmlDoc *
		xmlSAXParseFile		(xmlSAXHandler *sax,
					 const char *filename,
					 int recovery);
XML_DEPRECATED
XMLPUBFUN xmlDoc *
		xmlSAXParseFileWithData	(xmlSAXHandler *sax,
					 const char *filename,
					 int recovery,
					 void *data);
XML_DEPRECATED
XMLPUBFUN xmlDoc *
		xmlSAXParseEntity	(xmlSAXHandler *sax,
					 const char *filename);
XML_DEPRECATED
XMLPUBFUN xmlDoc *
		xmlParseEntity		(const char *filename);
#endif /* LIBXML_SAX1_ENABLED */

#ifdef LIBXML_VALID_ENABLED
XMLPUBFUN xmlDtd *
		xmlCtxtParseDtd		(xmlParserCtxt *ctxt,
					 xmlParserInput *input,
					 const xmlChar *publicId,
					 const xmlChar *systemId);
XMLPUBFUN int
		xmlCtxtValidateDocument	(xmlParserCtxt *ctxt,
					 xmlDoc *doc);
XMLPUBFUN int
		xmlCtxtValidateDtd	(xmlParserCtxt *ctxt,
					 xmlDoc *doc,
					 xmlDtd *dtd);
XML_DEPRECATED
XMLPUBFUN xmlDtd *
		xmlSAXParseDTD		(xmlSAXHandler *sax,
					 const xmlChar *publicId,
					 const xmlChar *systemId);
XMLPUBFUN xmlDtd *
		xmlParseDTD		(const xmlChar *publicId,
					 const xmlChar *systemId);
XMLPUBFUN xmlDtd *
		xmlIOParseDTD		(xmlSAXHandler *sax,
					 xmlParserInputBuffer *input,
					 xmlCharEncoding enc);
#endif /* LIBXML_VALID_ENABLE */
#ifdef LIBXML_SAX1_ENABLED
XMLPUBFUN int
		xmlParseBalancedChunkMemory(xmlDoc *doc,
					 xmlSAXHandler *sax,
					 void *user_data,
					 int depth,
					 const xmlChar *string,
					 xmlNode **lst);
#endif /* LIBXML_SAX1_ENABLED */
XMLPUBFUN xmlParserErrors
		xmlParseInNodeContext	(xmlNode *node,
					 const char *data,
					 int datalen,
					 int options,
					 xmlNode **lst);
#ifdef LIBXML_SAX1_ENABLED
XMLPUBFUN int
		xmlParseBalancedChunkMemoryRecover(xmlDoc *doc,
                     xmlSAXHandler *sax,
                     void *user_data,
                     int depth,
                     const xmlChar *string,
                     xmlNode **lst,
                     int recover);
XML_DEPRECATED
XMLPUBFUN int
		xmlParseExternalEntity	(xmlDoc *doc,
					 xmlSAXHandler *sax,
					 void *user_data,
					 int depth,
					 const xmlChar *URL,
					 const xmlChar *ID,
					 xmlNode **lst);
#endif /* LIBXML_SAX1_ENABLED */
XMLPUBFUN int
		xmlParseCtxtExternalEntity(xmlParserCtxt *ctx,
					 const xmlChar *URL,
					 const xmlChar *ID,
					 xmlNode **lst);

/*
 * Parser contexts handling.
 */
XMLPUBFUN xmlParserCtxt *
		xmlNewParserCtxt	(void);
XMLPUBFUN xmlParserCtxt *
		xmlNewSAXParserCtxt	(const xmlSAXHandler *sax,
					 void *userData);
XMLPUBFUN int
		xmlInitParserCtxt	(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN void
		xmlClearParserCtxt	(xmlParserCtxt *ctxt);
XMLPUBFUN void
		xmlFreeParserCtxt	(xmlParserCtxt *ctxt);
#ifdef LIBXML_SAX1_ENABLED
XML_DEPRECATED
XMLPUBFUN void
		xmlSetupParserForBuffer	(xmlParserCtxt *ctxt,
					 const xmlChar* buffer,
					 const char *filename);
#endif /* LIBXML_SAX1_ENABLED */
XMLPUBFUN xmlParserCtxt *
		xmlCreateDocParserCtxt	(const xmlChar *cur);

#ifdef LIBXML_PUSH_ENABLED
/*
 * Interfaces for the Push mode.
 */
XMLPUBFUN xmlParserCtxt *
		xmlCreatePushParserCtxt(xmlSAXHandler *sax,
					 void *user_data,
					 const char *chunk,
					 int size,
					 const char *filename);
XMLPUBFUN int
		xmlParseChunk		(xmlParserCtxt *ctxt,
					 const char *chunk,
					 int size,
					 int terminate);
#endif /* LIBXML_PUSH_ENABLED */

/*
 * Special I/O mode.
 */

XMLPUBFUN xmlParserCtxt *
		xmlCreateIOParserCtxt	(xmlSAXHandler *sax,
					 void *user_data,
					 xmlInputReadCallback   ioread,
					 xmlInputCloseCallback  ioclose,
					 void *ioctx,
					 xmlCharEncoding enc);

XMLPUBFUN xmlParserInput *
		xmlNewIOInputStream	(xmlParserCtxt *ctxt,
					 xmlParserInputBuffer *input,
					 xmlCharEncoding enc);

/*
 * Node infos.
 */
XML_DEPRECATED
XMLPUBFUN const xmlParserNodeInfo*
		xmlParserFindNodeInfo	(xmlParserCtxt *ctxt,
				         xmlNode *node);
XML_DEPRECATED
XMLPUBFUN void
		xmlInitNodeInfoSeq	(xmlParserNodeInfoSeq *seq);
XML_DEPRECATED
XMLPUBFUN void
		xmlClearNodeInfoSeq	(xmlParserNodeInfoSeq *seq);
XML_DEPRECATED
XMLPUBFUN unsigned long
		xmlParserFindNodeInfoIndex(xmlParserNodeInfoSeq *seq,
                                         xmlNode *node);
XML_DEPRECATED
XMLPUBFUN void
		xmlParserAddNodeInfo	(xmlParserCtxt *ctxt,
					 xmlParserNodeInfo *info);

/*
 * External entities handling actually implemented in xmlIO.
 */

XMLPUBFUN void
		xmlSetExternalEntityLoader(xmlExternalEntityLoader f);
XMLPUBFUN xmlExternalEntityLoader
		xmlGetExternalEntityLoader(void);
XMLPUBFUN xmlParserInput *
		xmlLoadExternalEntity	(const char *URL,
					 const char *ID,
					 xmlParserCtxt *ctxt);

XML_DEPRECATED
XMLPUBFUN long
		xmlByteConsumed		(xmlParserCtxt *ctxt);

/*
 * New set of simpler/more flexible APIs
 */

/**
 * This is the set of XML parser options that can be passed to
 * #xmlReadDoc, #xmlCtxtSetOptions and other functions.
 */
typedef enum {
    /**
     * Enable "recovery" mode which allows non-wellformed documents.
     * How this mode behaves exactly is unspecified and may change
     * without further notice. Use of this feature is DISCOURAGED.
     *
     * Not supported by the push parser.
     */
    XML_PARSE_RECOVER = 1<<0,
    /**
     * Despite the confusing name, this option enables substitution
     * of entities. The resulting tree won't contain any entity
     * reference nodes.
     *
     * This option also enables loading of external entities (both
     * general and parameter entities) which is dangerous. If you
     * process untrusted data, it's recommended to set the
     * XML_PARSE_NO_XXE option to disable loading of external
     * entities.
     */
    XML_PARSE_NOENT = 1<<1,
    /**
     * Enables loading of an external DTD and the loading and
     * substitution of external parameter entities. Has no effect
     * if XML_PARSE_NO_XXE is set.
     */
    XML_PARSE_DTDLOAD = 1<<2,
    /**
     * Adds default attributes from the DTD to the result document.
     *
     * Implies XML_PARSE_DTDLOAD, but loading of external content
     * can be disabled with XML_PARSE_NO_XXE.
     */
    XML_PARSE_DTDATTR = 1<<3,
    /**
     * This option enables DTD validation which requires to load
     * external DTDs and external entities (both general and
     * parameter entities) unless XML_PARSE_NO_XXE was set.
     *
     * DTD validation is vulnerable to algorithmic complexity
     * attacks and should never be enabled with untrusted input.
     */
    XML_PARSE_DTDVALID = 1<<4,
    /**
     * Disable error and warning reports to the error handlers.
     * Errors are still accessible with xmlCtxtGetLastError().
     */
    XML_PARSE_NOERROR = 1<<5,
    /**
     * Disable warning reports.
     */
    XML_PARSE_NOWARNING = 1<<6,
    /**
     * Enable some pedantic warnings.
     */
    XML_PARSE_PEDANTIC = 1<<7,
    /**
     * Remove some whitespace from the result document. Where to
     * remove whitespace depends on DTD element declarations or a
     * broken heuristic with unfixable bugs. Use of this option is
     * DISCOURAGED.
     *
     * Not supported by the push parser.
     */
    XML_PARSE_NOBLANKS = 1<<8,
    /**
     * Always invoke the deprecated SAX1 startElement and endElement
     * handlers.
     *
     * @deprecated This option will be removed in a future version.
     */
    XML_PARSE_SAX1 = 1<<9,
    /**
     * Enable XInclude processing. This option only affects the
     * xmlTextReader and XInclude interfaces.
     */
    XML_PARSE_XINCLUDE = 1<<10,
    /**
     * Disable network access with the built-in HTTP or FTP clients.
     *
     * After the last built-in network client was removed in 2.15,
     * this option has no effect expect for being passed on to custom
     * resource loaders.
     */
    XML_PARSE_NONET = 1<<11,
    /**
     * Create a document without interned strings, making all
     * strings separate memory allocations.
     */
    XML_PARSE_NODICT = 1<<12,
    /**
     * Remove redundant namespace declarations from the result
     * document.
     */
    XML_PARSE_NSCLEAN = 1<<13,
    /**
     * Output normal text nodes instead of CDATA nodes.
     */
    XML_PARSE_NOCDATA = 1<<14,
    /**
     * Don't generate XInclude start/end nodes when expanding
     * inclusions. This option only affects the xmlTextReader
     * and XInclude interfaces.
     */
    XML_PARSE_NOXINCNODE = 1<<15,
    /**
     * Store small strings directly in the node struct to save
     * memory.
     */
    XML_PARSE_COMPACT = 1<<16,
    /**
     * Use old Name productions from before XML 1.0 Fifth Edition.
     *
     * @deprecated This option will be removed in a future version.
     */
    XML_PARSE_OLD10 = 1<<17,
    /**
     * Don't fix up XInclude xml:base URIs. This option only affects
     * the xmlTextReader and XInclude interfaces.
     */
    XML_PARSE_NOBASEFIX = 1<<18,
    /**
     * Relax some internal limits.
     *
     * Maximum size of text nodes, tags, comments, processing instructions,
     * CDATA sections, entity values
     *
     * normal: 10M
     * huge:    1B
     *
     * Maximum size of names, system literals, pubid literals
     *
     * normal: 50K
     * huge:   10M
     *
     * Maximum nesting depth of elements
     *
     * normal:  256
     * huge:   2048
     *
     * Maximum nesting depth of entities
     *
     * normal: 20
     * huge:   40
     */
    XML_PARSE_HUGE = 1<<19,
    /**
     * Enable an unspecified legacy mode for SAX parsers.
     *
     * @deprecated This option will be removed in a future version.
     */
    XML_PARSE_OLDSAX = 1<<20,
    /**
     * Ignore the encoding in the XML declaration. This option is
     * mostly unneeded these days. The only effect is to enforce
     * UTF-8 decoding of ASCII-like data.
     */
    XML_PARSE_IGNORE_ENC = 1<<21,
    /**
     * Enable reporting of line numbers larger than 65535.
     */
    XML_PARSE_BIG_LINES = 1<<22,
    /**
     * Disables loading of external DTDs or entities.
     *
     * @since 2.13.0
     */
    XML_PARSE_NO_XXE = 1<<23,
    /**
     * Enable input decompression. Setting this option is discouraged
     * to avoid zip bombs.
     *
     * @since 2.14.0
     */
    XML_PARSE_UNZIP = 1<<24,
    /**
     * Disables the global system XML catalog.
     *
     * @since 2.14.0
     */
    XML_PARSE_NO_SYS_CATALOG = 1<<25,
    /**
     * Enable XML catalog processing instructions.
     *
     * @since 2.14.0
     */
    XML_PARSE_CATALOG_PI = 1<<26,
    /**
     * Force the parser to ignore IDs.
     *
     * @since 2.15.0
     */
    XML_PARSE_SKIP_IDS = 1<<27
} xmlParserOption;

XMLPUBFUN void
		xmlCtxtReset		(xmlParserCtxt *ctxt);
XMLPUBFUN int
		xmlCtxtResetPush	(xmlParserCtxt *ctxt,
					 const char *chunk,
					 int size,
					 const char *filename,
					 const char *encoding);
XMLPUBFUN int
		xmlCtxtGetOptions	(xmlParserCtxt *ctxt);
XMLPUBFUN int
		xmlCtxtSetOptions	(xmlParserCtxt *ctxt,
					 int options);
XMLPUBFUN int
		xmlCtxtUseOptions	(xmlParserCtxt *ctxt,
					 int options);
XMLPUBFUN void *
		xmlCtxtGetPrivate	(xmlParserCtxt *ctxt);
XMLPUBFUN void
		xmlCtxtSetPrivate	(xmlParserCtxt *ctxt,
					 void *priv);
XMLPUBFUN void *
		xmlCtxtGetCatalogs	(xmlParserCtxt *ctxt);
XMLPUBFUN void
		xmlCtxtSetCatalogs	(xmlParserCtxt *ctxt,
					 void *catalogs);
XMLPUBFUN xmlDict *
		xmlCtxtGetDict		(xmlParserCtxt *ctxt);
XMLPUBFUN void
		xmlCtxtSetDict		(xmlParserCtxt *ctxt,
					 xmlDict *);
XMLPUBFUN xmlSAXHandler *
		xmlCtxtGetSaxHandler	(xmlParserCtxt *ctxt);
XMLPUBFUN int
		xmlCtxtSetSaxHandler	(xmlParserCtxt *ctxt,
					 const xmlSAXHandler *sax);
XMLPUBFUN xmlDoc *
		xmlCtxtGetDocument	(xmlParserCtxt *ctxt);
XMLPUBFUN int
		xmlCtxtIsHtml		(xmlParserCtxt *ctxt);
XMLPUBFUN int
		xmlCtxtIsStopped	(xmlParserCtxt *ctxt);
XMLPUBFUN int
		xmlCtxtIsInSubset	(xmlParserCtxt *ctxt);
#ifdef LIBXML_VALID_ENABLED
XMLPUBFUN xmlValidCtxt *
		xmlCtxtGetValidCtxt	(xmlParserCtxt *ctxt);
#endif
XMLPUBFUN const xmlChar *
		xmlCtxtGetVersion	(xmlParserCtxt *ctxt);
XMLPUBFUN const xmlChar *
		xmlCtxtGetDeclaredEncoding(xmlParserCtxt *ctxt);
XMLPUBFUN int
		xmlCtxtGetStandalone	(xmlParserCtxt *ctxt);
XMLPUBFUN xmlParserStatus
		xmlCtxtGetStatus	(xmlParserCtxt *ctxt);
XMLPUBFUN void *
		xmlCtxtGetUserData	(xmlParserCtxt *ctxt);
XMLPUBFUN xmlNode *
		xmlCtxtGetNode		(xmlParserCtxt *ctxt);
XMLPUBFUN int
		xmlCtxtGetDocTypeDecl	(xmlParserCtxt *ctxt,
					 const xmlChar **name,
					 const xmlChar **systemId,
					 const xmlChar **publicId);
XMLPUBFUN int
		xmlCtxtGetInputPosition	(xmlParserCtxt *ctxt,
					 int inputIndex,
					 const char **filname,
					 int *line,
					 int *col,
					 unsigned long *bytePos);
XMLPUBFUN int
		xmlCtxtGetInputWindow	(xmlParserCtxt *ctxt,
					 int inputIndex,
					 const xmlChar **startOut,
					 int *sizeInOut,
					 int *offsetOut);
XMLPUBFUN void
		xmlCtxtSetErrorHandler	(xmlParserCtxt *ctxt,
					 xmlStructuredErrorFunc handler,
					 void *data);
XMLPUBFUN void
		xmlCtxtSetResourceLoader(xmlParserCtxt *ctxt,
					 xmlResourceLoader loader,
					 void *vctxt);
XMLPUBFUN void
		xmlCtxtSetCharEncConvImpl(xmlParserCtxt *ctxt,
					 xmlCharEncConvImpl impl,
					 void *vctxt);
XMLPUBFUN void
		xmlCtxtSetMaxAmplification(xmlParserCtxt *ctxt,
					 unsigned maxAmpl);
XMLPUBFUN xmlDoc *
		xmlReadDoc		(const xmlChar *cur,
					 const char *URL,
					 const char *encoding,
					 int options);
XMLPUBFUN xmlDoc *
		xmlReadFile		(const char *URL,
					 const char *encoding,
					 int options);
XMLPUBFUN xmlDoc *
		xmlReadMemory		(const char *buffer,
					 int size,
					 const char *URL,
					 const char *encoding,
					 int options);
XMLPUBFUN xmlDoc *
		xmlReadFd		(int fd,
					 const char *URL,
					 const char *encoding,
					 int options);
XMLPUBFUN xmlDoc *
		xmlReadIO		(xmlInputReadCallback ioread,
					 xmlInputCloseCallback ioclose,
					 void *ioctx,
					 const char *URL,
					 const char *encoding,
					 int options);
XMLPUBFUN xmlDoc *
		xmlCtxtParseDocument	(xmlParserCtxt *ctxt,
					 xmlParserInput *input);
XMLPUBFUN xmlNode *
		xmlCtxtParseContent	(xmlParserCtxt *ctxt,
					 xmlParserInput *input,
					 xmlNode *node,
					 int hasTextDecl);
XMLPUBFUN xmlDoc *
		xmlCtxtReadDoc		(xmlParserCtxt *ctxt,
					 const xmlChar *cur,
					 const char *URL,
					 const char *encoding,
					 int options);
XMLPUBFUN xmlDoc *
		xmlCtxtReadFile		(xmlParserCtxt *ctxt,
					 const char *filename,
					 const char *encoding,
					 int options);
XMLPUBFUN xmlDoc *
		xmlCtxtReadMemory		(xmlParserCtxt *ctxt,
					 const char *buffer,
					 int size,
					 const char *URL,
					 const char *encoding,
					 int options);
XMLPUBFUN xmlDoc *
		xmlCtxtReadFd		(xmlParserCtxt *ctxt,
					 int fd,
					 const char *URL,
					 const char *encoding,
					 int options);
XMLPUBFUN xmlDoc *
		xmlCtxtReadIO		(xmlParserCtxt *ctxt,
					 xmlInputReadCallback ioread,
					 xmlInputCloseCallback ioclose,
					 void *ioctx,
					 const char *URL,
					 const char *encoding,
					 int options);

/*
 * New input API
 */

XMLPUBFUN xmlParserErrors
xmlNewInputFromUrl(const char *url, xmlParserInputFlags flags,
                   xmlParserInput **out);
XMLPUBFUN xmlParserInput *
xmlNewInputFromMemory(const char *url, const void *mem, size_t size,
                      xmlParserInputFlags flags);
XMLPUBFUN xmlParserInput *
xmlNewInputFromString(const char *url, const char *str,
                      xmlParserInputFlags flags);
XMLPUBFUN xmlParserInput *
xmlNewInputFromFd(const char *url, int fd, xmlParserInputFlags flags);
XMLPUBFUN xmlParserInput *
xmlNewInputFromIO(const char *url, xmlInputReadCallback ioRead,
                  xmlInputCloseCallback ioClose, void *ioCtxt,
                  xmlParserInputFlags flags);
XMLPUBFUN xmlParserErrors
xmlInputSetEncodingHandler(xmlParserInput *input,
                           xmlCharEncodingHandler *handler);

/*
 * Library wide options
 */

/**
 * Used to examine the existence of features that can be enabled
 * or disabled at compile-time.
 * They used to be called XML_FEATURE_xxx but this clashed with Expat
 */
typedef enum {
    /** Multithreading support */
    XML_WITH_THREAD = 1,
    /** @deprecated Always available */
    XML_WITH_TREE = 2,
    /** Serialization support */
    XML_WITH_OUTPUT = 3,
    /** Push parser */
    XML_WITH_PUSH = 4,
    /** XML Reader */
    XML_WITH_READER = 5,
    /** Streaming patterns */
    XML_WITH_PATTERN = 6,
    /** XML Writer */
    XML_WITH_WRITER = 7,
    /** Legacy SAX1 API */
    XML_WITH_SAX1 = 8,
    /** @deprecated FTP support was removed */
    XML_WITH_FTP = 9,
    /** @deprecated HTTP support was removed */
    XML_WITH_HTTP = 10,
    /** DTD validation */
    XML_WITH_VALID = 11,
    /** HTML parser */
    XML_WITH_HTML = 12,
    /** Legacy symbols */
    XML_WITH_LEGACY = 13,
    /** Canonical XML */
    XML_WITH_C14N = 14,
    /** XML Catalogs */
    XML_WITH_CATALOG = 15,
    /** XPath */
    XML_WITH_XPATH = 16,
    /** XPointer */
    XML_WITH_XPTR = 17,
    /** XInclude */
    XML_WITH_XINCLUDE = 18,
    /** iconv */
    XML_WITH_ICONV = 19,
    /** Built-in ISO-8859-X */
    XML_WITH_ISO8859X = 20,
    /** @deprecated Removed */
    XML_WITH_UNICODE = 21,
    /** Regular expressions */
    XML_WITH_REGEXP = 22,
    /** @deprecated Same as XML_WITH_REGEXP */
    XML_WITH_AUTOMATA = 23,
    /** @deprecated Removed */
    XML_WITH_EXPR = 24,
    /** XML Schemas */
    XML_WITH_SCHEMAS = 25,
    /** Schematron */
    XML_WITH_SCHEMATRON = 26,
    /** Loadable modules */
    XML_WITH_MODULES = 27,
    /** Debugging API */
    XML_WITH_DEBUG = 28,
    /** @deprecated Removed */
    XML_WITH_DEBUG_MEM = 29,
    /** @deprecated Removed */
    XML_WITH_DEBUG_RUN = 30,
    /** GZIP compression */
    XML_WITH_ZLIB = 31,
    /** ICU */
    XML_WITH_ICU = 32,
    /** @deprecated LZMA support was removed */
    XML_WITH_LZMA = 33,
    /** RELAXNG, since 2.14 */
    XML_WITH_RELAXNG = 34,
    XML_WITH_NONE = 99999 /* just to be sure of allocation size */
} xmlFeature;

XMLPUBFUN int
		xmlHasFeature		(xmlFeature feature);

#ifdef __cplusplus
}
#endif
#endif /* __XML_PARSER_H__ */
libxml2/libxml/nanohttp.h000064400000004140151733237440011420 0ustar00/**
 * @file
 * 
 * @brief minimal HTTP implementation
 * 
 * minimal HTTP implementation allowing to fetch resources
 *              like external subset.
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */

#ifndef __NANO_HTTP_H__
#define __NANO_HTTP_H__

#include <libxml/xmlversion.h>

#ifdef LIBXML_HTTP_STUBS_ENABLED

#ifdef __cplusplus
extern "C" {
#endif
XML_DEPRECATED
XMLPUBFUN void
	xmlNanoHTTPInit		(void);
XML_DEPRECATED
XMLPUBFUN void
	xmlNanoHTTPCleanup	(void);
XML_DEPRECATED
XMLPUBFUN void
	xmlNanoHTTPScanProxy	(const char *URL);
XML_DEPRECATED
XMLPUBFUN int
	xmlNanoHTTPFetch	(const char *URL,
				 const char *filename,
				 char **contentType);
XML_DEPRECATED
XMLPUBFUN void *
	xmlNanoHTTPMethod	(const char *URL,
				 const char *method,
				 const char *input,
				 char **contentType,
				 const char *headers,
				 int   ilen);
XML_DEPRECATED
XMLPUBFUN void *
	xmlNanoHTTPMethodRedir	(const char *URL,
				 const char *method,
				 const char *input,
				 char **contentType,
				 char **redir,
				 const char *headers,
				 int   ilen);
XML_DEPRECATED
XMLPUBFUN void *
	xmlNanoHTTPOpen		(const char *URL,
				 char **contentType);
XML_DEPRECATED
XMLPUBFUN void *
	xmlNanoHTTPOpenRedir	(const char *URL,
				 char **contentType,
				 char **redir);
XML_DEPRECATED
XMLPUBFUN int
	xmlNanoHTTPReturnCode	(void *ctx);
XML_DEPRECATED
XMLPUBFUN const char *
	xmlNanoHTTPAuthHeader	(void *ctx);
XML_DEPRECATED
XMLPUBFUN const char *
	xmlNanoHTTPRedir	(void *ctx);
XML_DEPRECATED
XMLPUBFUN int
	xmlNanoHTTPContentLength( void * ctx );
XML_DEPRECATED
XMLPUBFUN const char *
	xmlNanoHTTPEncoding	(void *ctx);
XML_DEPRECATED
XMLPUBFUN const char *
	xmlNanoHTTPMimeType	(void *ctx);
XML_DEPRECATED
XMLPUBFUN int
	xmlNanoHTTPRead		(void *ctx,
				 void *dest,
				 int len);
#ifdef LIBXML_OUTPUT_ENABLED
XML_DEPRECATED
XMLPUBFUN int
	xmlNanoHTTPSave		(void *ctxt,
				 const char *filename);
#endif /* LIBXML_OUTPUT_ENABLED */
XML_DEPRECATED
XMLPUBFUN void
	xmlNanoHTTPClose	(void *ctx);
#ifdef __cplusplus
}
#endif

#endif /* LIBXML_HTTP_STUBS_ENABLED */
#endif /* __NANO_HTTP_H__ */
libxml2/libxml/xmlstring.h000064400000012200151733237440011610 0ustar00/**
 * @file
 * 
 * @brief set of routines to process strings
 * 
 * type and interfaces needed for the internal string handling
 *              of the library, especially UTF8 processing.
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */

#ifndef __XML_STRING_H__
#define __XML_STRING_H__

#include <stdarg.h>
#include <libxml/xmlversion.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * This is a basic byte in an UTF-8 encoded string.
 * It's unsigned allowing to pinpoint case where char * are assigned
 * to xmlChar * (possibly making serialization back impossible).
 */
typedef unsigned char xmlChar;

/**
 * Macro to cast a string to an xmlChar * when one know its safe.
 */
#define BAD_CAST (xmlChar *)

/*
 * xmlChar handling
 */
XMLPUBFUN xmlChar *
                xmlStrdup                (const xmlChar *cur);
XMLPUBFUN xmlChar *
                xmlStrndup               (const xmlChar *cur,
                                         int len);
XMLPUBFUN xmlChar *
                xmlCharStrndup           (const char *cur,
                                         int len);
XMLPUBFUN xmlChar *
                xmlCharStrdup            (const char *cur);
XMLPUBFUN xmlChar *
                xmlStrsub                (const xmlChar *str,
                                         int start,
                                         int len);
XMLPUBFUN const xmlChar *
                xmlStrchr                (const xmlChar *str,
                                         xmlChar val);
XMLPUBFUN const xmlChar *
                xmlStrstr                (const xmlChar *str,
                                         const xmlChar *val);
XMLPUBFUN const xmlChar *
                xmlStrcasestr            (const xmlChar *str,
                                         const xmlChar *val);
XMLPUBFUN int
                xmlStrcmp                (const xmlChar *str1,
                                         const xmlChar *str2);
XMLPUBFUN int
                xmlStrncmp               (const xmlChar *str1,
                                         const xmlChar *str2,
                                         int len);
XMLPUBFUN int
                xmlStrcasecmp            (const xmlChar *str1,
                                         const xmlChar *str2);
XMLPUBFUN int
                xmlStrncasecmp           (const xmlChar *str1,
                                         const xmlChar *str2,
                                         int len);
XMLPUBFUN int
                xmlStrEqual              (const xmlChar *str1,
                                         const xmlChar *str2);
XMLPUBFUN int
                xmlStrQEqual             (const xmlChar *pref,
                                         const xmlChar *name,
                                         const xmlChar *str);
XMLPUBFUN int
                xmlStrlen                (const xmlChar *str);
XMLPUBFUN xmlChar *
                xmlStrcat                (xmlChar *cur,
                                         const xmlChar *add);
XMLPUBFUN xmlChar *
                xmlStrncat               (xmlChar *cur,
                                         const xmlChar *add,
                                         int len);
XMLPUBFUN xmlChar *
                xmlStrncatNew            (const xmlChar *str1,
                                         const xmlChar *str2,
                                         int len);
XMLPUBFUN int
                xmlStrPrintf             (xmlChar *buf,
                                         int len,
                                         const char *msg,
                                         ...) LIBXML_ATTR_FORMAT(3,4);
XMLPUBFUN int
                xmlStrVPrintf                (xmlChar *buf,
                                         int len,
                                         const char *msg,
                                         va_list ap) LIBXML_ATTR_FORMAT(3,0);

XMLPUBFUN int
        xmlGetUTF8Char                   (const unsigned char *utf,
                                         int *len);
XMLPUBFUN int
        xmlCheckUTF8                     (const unsigned char *utf);
XMLPUBFUN int
        xmlUTF8Strsize                   (const xmlChar *utf,
                                         int len);
XMLPUBFUN xmlChar *
        xmlUTF8Strndup                   (const xmlChar *utf,
                                         int len);
XMLPUBFUN const xmlChar *
        xmlUTF8Strpos                    (const xmlChar *utf,
                                         int pos);
XMLPUBFUN int
        xmlUTF8Strloc                    (const xmlChar *utf,
                                         const xmlChar *utfchar);
XMLPUBFUN xmlChar *
        xmlUTF8Strsub                    (const xmlChar *utf,
                                         int start,
                                         int len);
XMLPUBFUN int
        xmlUTF8Strlen                    (const xmlChar *utf);
XMLPUBFUN int
        xmlUTF8Size                      (const xmlChar *utf);
XMLPUBFUN int
        xmlUTF8Charcmp                   (const xmlChar *utf1,
                                         const xmlChar *utf2);

#ifdef __cplusplus
}
#endif
#endif /* __XML_STRING_H__ */
libxml2/libxml/xmlmodule.h000064400000002206151733237440011574 0ustar00/**
 * @file
 *
 * @brief Dynamic module loading
 *
 * API for dynamic module loading. Only used by old libxslt versions
 * and subject to removal.
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Joel W. Reed
 */

#ifndef __XML_MODULE_H__
#define __XML_MODULE_H__

#include <libxml/xmlversion.h>

#ifdef LIBXML_MODULES_ENABLED

#ifdef __cplusplus
extern "C" {
#endif

/**
 * A handle to a dynamically loaded module
 */
typedef struct _xmlModule xmlModule;
typedef xmlModule *xmlModulePtr;

/**
 * enumeration of options that can be passed down to #xmlModuleOpen
 */
typedef enum {
    XML_MODULE_LAZY = 1,	/* lazy binding */
    XML_MODULE_LOCAL= 2		/* local binding */
} xmlModuleOption;

XML_DEPRECATED
XMLPUBFUN xmlModule *xmlModuleOpen	(const char *filename,
						 int options);

XML_DEPRECATED
XMLPUBFUN int xmlModuleSymbol		(xmlModule *module,
						 const char* name,
						 void **result);

XML_DEPRECATED
XMLPUBFUN int xmlModuleClose		(xmlModule *module);

XML_DEPRECATED
XMLPUBFUN int xmlModuleFree		(xmlModule *module);

#ifdef __cplusplus
}
#endif

#endif /* LIBXML_MODULES_ENABLED */

#endif /*__XML_MODULE_H__ */
libxml2/libxml/xmlschemas.h000064400000015422151733237440011736 0ustar00/**
 * @file
 * 
 * @brief incomplete XML Schemas structure implementation
 * 
 * interface to the XML Schemas handling and schema validity
 *              checking, it is incomplete right now.
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */


#ifndef __XML_SCHEMA_H__
#define __XML_SCHEMA_H__

#include <libxml/xmlversion.h>

#ifdef LIBXML_SCHEMAS_ENABLED

#include <stdio.h>
#include <libxml/encoding.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xmlerror.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * This error codes are obsolete; not used any more.
 */
typedef enum {
    XML_SCHEMAS_ERR_OK		= 0,
    XML_SCHEMAS_ERR_NOROOT	= 1,
    XML_SCHEMAS_ERR_UNDECLAREDELEM,
    XML_SCHEMAS_ERR_NOTTOPLEVEL,
    XML_SCHEMAS_ERR_MISSING,
    XML_SCHEMAS_ERR_WRONGELEM,
    XML_SCHEMAS_ERR_NOTYPE,
    XML_SCHEMAS_ERR_NOROLLBACK,
    XML_SCHEMAS_ERR_ISABSTRACT,
    XML_SCHEMAS_ERR_NOTEMPTY,
    XML_SCHEMAS_ERR_ELEMCONT,
    XML_SCHEMAS_ERR_HAVEDEFAULT,
    XML_SCHEMAS_ERR_NOTNILLABLE,
    XML_SCHEMAS_ERR_EXTRACONTENT,
    XML_SCHEMAS_ERR_INVALIDATTR,
    XML_SCHEMAS_ERR_INVALIDELEM,
    XML_SCHEMAS_ERR_NOTDETERMINIST,
    XML_SCHEMAS_ERR_CONSTRUCT,
    XML_SCHEMAS_ERR_INTERNAL,
    XML_SCHEMAS_ERR_NOTSIMPLE,
    XML_SCHEMAS_ERR_ATTRUNKNOWN,
    XML_SCHEMAS_ERR_ATTRINVALID,
    XML_SCHEMAS_ERR_VALUE,
    XML_SCHEMAS_ERR_FACET,
    XML_SCHEMAS_ERR_,
    XML_SCHEMAS_ERR_XXX
} xmlSchemaValidError;

/*
* ATTENTION: Change xmlSchemaSetValidOptions's check
* for invalid values, if adding to the validation
* options below.
*/
/**
 * This is the set of XML Schema validation options.
 */
typedef enum {
    XML_SCHEMA_VAL_VC_I_CREATE			= 1<<0
	/* Default/fixed: create an attribute node
	* or an element's text node on the instance.
	*/
} xmlSchemaValidOption;

/*
    XML_SCHEMA_VAL_XSI_ASSEMBLE			= 1<<1,
	* assemble schemata using
	* xsi:schemaLocation and
	* xsi:noNamespaceSchemaLocation
*/

/** XML schema */
typedef struct _xmlSchema xmlSchema;
typedef xmlSchema *xmlSchemaPtr;

/**
 * Signature of an error callback from an XSD validation
 *
 * @param ctx  the validation context
 * @param msg  the message
 * @param ... extra arguments
 */
typedef void (*xmlSchemaValidityErrorFunc)
                 (void *ctx, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);

/**
 * Signature of a warning callback from an XSD validation
 *
 * @param ctx  the validation context
 * @param msg  the message
 * @param ... extra arguments
 */
typedef void (*xmlSchemaValidityWarningFunc)
                 (void *ctx, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);

/** Schema parser context */
typedef struct _xmlSchemaParserCtxt xmlSchemaParserCtxt;
typedef xmlSchemaParserCtxt *xmlSchemaParserCtxtPtr;

/** Schema validation context */
typedef struct _xmlSchemaValidCtxt xmlSchemaValidCtxt;
typedef xmlSchemaValidCtxt *xmlSchemaValidCtxtPtr;

/**
 * A schemas validation locator, a callback called by the validator.
 * This is used when file or node information are not available
 * to find out what file and line number are affected
 *
 * @param ctx  user provided context
 * @param file  returned file information
 * @param line  returned line information
 * @returns 0 in case of success and -1 in case of error
 */

typedef int (*xmlSchemaValidityLocatorFunc) (void *ctx,
                           const char **file, unsigned long *line);

/*
 * Interfaces for parsing.
 */
XMLPUBFUN xmlSchemaParserCtxt *
	    xmlSchemaNewParserCtxt	(const char *URL);
XMLPUBFUN xmlSchemaParserCtxt *
	    xmlSchemaNewMemParserCtxt	(const char *buffer,
					 int size);
XMLPUBFUN xmlSchemaParserCtxt *
	    xmlSchemaNewDocParserCtxt	(xmlDoc *doc);
XMLPUBFUN void
	    xmlSchemaFreeParserCtxt	(xmlSchemaParserCtxt *ctxt);
XMLPUBFUN void
	    xmlSchemaSetParserErrors	(xmlSchemaParserCtxt *ctxt,
					 xmlSchemaValidityErrorFunc err,
					 xmlSchemaValidityWarningFunc warn,
					 void *ctx);
XMLPUBFUN void
	    xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxt *ctxt,
					 xmlStructuredErrorFunc serror,
					 void *ctx);
XMLPUBFUN int
	    xmlSchemaGetParserErrors	(xmlSchemaParserCtxt *ctxt,
					xmlSchemaValidityErrorFunc * err,
					xmlSchemaValidityWarningFunc * warn,
					void **ctx);
XMLPUBFUN void
	    xmlSchemaSetResourceLoader	(xmlSchemaParserCtxt *ctxt,
					 xmlResourceLoader loader,
					 void *data);
XMLPUBFUN int
	    xmlSchemaIsValid		(xmlSchemaValidCtxt *ctxt);

XMLPUBFUN xmlSchema *
	    xmlSchemaParse		(xmlSchemaParserCtxt *ctxt);
XMLPUBFUN void
	    xmlSchemaFree		(xmlSchema *schema);
#ifdef LIBXML_DEBUG_ENABLED
XMLPUBFUN void
	    xmlSchemaDump		(FILE *output,
					 xmlSchema *schema);
#endif /* LIBXML_DEBUG_ENABLED */
/*
 * Interfaces for validating
 */
XMLPUBFUN void
	    xmlSchemaSetValidErrors	(xmlSchemaValidCtxt *ctxt,
					 xmlSchemaValidityErrorFunc err,
					 xmlSchemaValidityWarningFunc warn,
					 void *ctx);
XMLPUBFUN void
	    xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxt *ctxt,
					 xmlStructuredErrorFunc serror,
					 void *ctx);
XMLPUBFUN int
	    xmlSchemaGetValidErrors	(xmlSchemaValidCtxt *ctxt,
					 xmlSchemaValidityErrorFunc *err,
					 xmlSchemaValidityWarningFunc *warn,
					 void **ctx);
XMLPUBFUN int
	    xmlSchemaSetValidOptions	(xmlSchemaValidCtxt *ctxt,
					 int options);
XMLPUBFUN void
            xmlSchemaValidateSetFilename(xmlSchemaValidCtxt *vctxt,
	                                 const char *filename);
XMLPUBFUN int
	    xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxt *ctxt);

XMLPUBFUN xmlSchemaValidCtxt *
	    xmlSchemaNewValidCtxt	(xmlSchema *schema);
XMLPUBFUN void
	    xmlSchemaFreeValidCtxt	(xmlSchemaValidCtxt *ctxt);
XMLPUBFUN int
	    xmlSchemaValidateDoc	(xmlSchemaValidCtxt *ctxt,
					 xmlDoc *instance);
XMLPUBFUN int
            xmlSchemaValidateOneElement (xmlSchemaValidCtxt *ctxt,
			                 xmlNode *elem);
XMLPUBFUN int
	    xmlSchemaValidateStream	(xmlSchemaValidCtxt *ctxt,
					 xmlParserInputBuffer *input,
					 xmlCharEncoding enc,
					 const xmlSAXHandler *sax,
					 void *user_data);
XMLPUBFUN int
	    xmlSchemaValidateFile	(xmlSchemaValidCtxt *ctxt,
					 const char * filename,
					 int options);

XMLPUBFUN xmlParserCtxt *
	    xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxt *ctxt);

/**
 * Interface to insert Schemas SAX validation in a SAX stream
 */
typedef struct _xmlSchemaSAXPlug xmlSchemaSAXPlugStruct;
typedef xmlSchemaSAXPlugStruct *xmlSchemaSAXPlugPtr;

XMLPUBFUN xmlSchemaSAXPlugStruct *
            xmlSchemaSAXPlug		(xmlSchemaValidCtxt *ctxt,
					 xmlSAXHandler **sax,
					 void **user_data);
XMLPUBFUN int
            xmlSchemaSAXUnplug		(xmlSchemaSAXPlugStruct *plug);


XMLPUBFUN void
            xmlSchemaValidateSetLocator	(xmlSchemaValidCtxt *vctxt,
					 xmlSchemaValidityLocatorFunc f,
					 void *ctxt);

#ifdef __cplusplus
}
#endif

#endif /* LIBXML_SCHEMAS_ENABLED */
#endif /* __XML_SCHEMA_H__ */
libxml2/libxml/tree.h000064400000116463151733237440010540 0ustar00/**
 * @file
 *
 * @brief Document tree API
 *
 * Data structures and functions to build, modify, query and
 * serialize XML and HTML document trees. Also contains the
 * buffer API.
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */

#ifndef XML_TREE_INTERNALS

/*
 * Emulate circular dependency for backward compatibility
 */
#include <libxml/parser.h>

#else /* XML_TREE_INTERNALS */

#ifndef __XML_TREE_H__
/** @cond ignore */
#define __XML_TREE_H__
/** @endcond */

#include <stdio.h>
#include <limits.h>
#include <libxml/xmlversion.h>
#include <libxml/xmlstring.h>
#include <libxml/xmlmemory.h>
#include <libxml/xmlregexp.h>

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Backward compatibility
 */
/** @cond ignore */
#define xmlBufferAllocScheme XML_BUFFER_ALLOC_EXACT
#define xmlDefaultBufferSize 4096
#define XML_GET_CONTENT(n) \
    ((n)->type == XML_ELEMENT_NODE ? NULL : (n)->content)
#define XML_GET_LINE(n)	xmlGetLineNo(n)
/** @endcond */

/*
 * Some of the basic types pointer to structures:
 */
/* xmlIO.h */
/**
 * Parser input buffer
 *
 * This struct and all related functions should ultimately
 * be removed from the public interface.
 */
typedef struct _xmlParserInputBuffer xmlParserInputBuffer;
typedef xmlParserInputBuffer *xmlParserInputBufferPtr;

/** Output buffer */
typedef struct _xmlOutputBuffer xmlOutputBuffer;
typedef xmlOutputBuffer *xmlOutputBufferPtr;

/* parser.h */
/** Parser input */
typedef struct _xmlParserInput xmlParserInput;
typedef xmlParserInput *xmlParserInputPtr;

/** Parser context */
typedef struct _xmlParserCtxt xmlParserCtxt;
typedef xmlParserCtxt *xmlParserCtxtPtr;

/** SAX locator */
typedef struct _xmlSAXLocator xmlSAXLocator;
typedef xmlSAXLocator *xmlSAXLocatorPtr;

/** SAX handler */
typedef struct _xmlSAXHandler xmlSAXHandler;
typedef xmlSAXHandler *xmlSAXHandlerPtr;

/* entities.h */
/** Entity declaration */
typedef struct _xmlEntity xmlEntity;
typedef xmlEntity *xmlEntityPtr;

/**
 * Removed, buffers always use XML_BUFFER_ALLOC_IO now.
 */
typedef enum {
    XML_BUFFER_ALLOC_DOUBLEIT,	/* double each time one need to grow */
    XML_BUFFER_ALLOC_EXACT,	/* grow only to the minimal size */
    XML_BUFFER_ALLOC_IMMUTABLE, /* immutable buffer, deprecated */
    XML_BUFFER_ALLOC_IO,	/* special allocation scheme used for I/O */
    XML_BUFFER_ALLOC_HYBRID,	/* exact up to a threshold, and doubleit thereafter */
    XML_BUFFER_ALLOC_BOUNDED	/* limit the upper size of the buffer */
} xmlBufferAllocationScheme;

/** Buffer type */
typedef struct _xmlBuffer xmlBuffer;
typedef xmlBuffer *xmlBufferPtr;
/**
 * A buffer structure, this old construct is limited to 2GB and
 * is being deprecated, use API with xmlBuf instead.
 */
struct _xmlBuffer {
    /**
     * @deprecated Use #xmlBufferContent
     *
     * The buffer content UTF8
     */
    xmlChar *content XML_DEPRECATED_MEMBER;
    /**
     * @deprecated Use #xmlBufferLength
     *
     * The buffer size used
     */
    unsigned int use XML_DEPRECATED_MEMBER;
    /* The buffer size */
    unsigned int size XML_DEPRECATED_MEMBER;
    /* The realloc method */
    xmlBufferAllocationScheme alloc XML_DEPRECATED_MEMBER;
    /* in IO mode we may have a different base */
    xmlChar *contentIO XML_DEPRECATED_MEMBER;
};

/** Buffer with 64-bit support */
typedef struct _xmlBuf xmlBuf;
typedef xmlBuf *xmlBufPtr;

/**
 * Macro used to express that the API use the new buffers for
 * xmlParserInputBuffer and xmlOutputBuffer. The change was
 * introduced in 2.9.0.
 */
#define LIBXML2_NEW_BUFFER

/**
 * This is the namespace for the special xml: prefix predefined in the
 * XML Namespace specification.
 */
#define XML_XML_NAMESPACE \
    (const xmlChar *) "http://www.w3.org/XML/1998/namespace"

/**
 * This is the name for the special xml:id attribute
 */
#define XML_XML_ID (const xmlChar *) "xml:id"

/**
 * The different element types carried by an XML tree.
 *
 * NOTE: This is synchronized with DOM Level 1 values.
 *       See http://www.w3.org/TR/REC-DOM-Level-1/
 *
 * Actually this had diverged a bit, and XML_DTD_NODE is used instead
 * of XML_DOCUMENT_TYPE_NODE.
 */
typedef enum {
    /**
     * An element.
     *
     * Objects of this type are an xmlNode.
     */
    XML_ELEMENT_NODE=		1,
    /**
     * An attribute.
     *
     * Objects of this type are an xmlAttr.
     */
    XML_ATTRIBUTE_NODE=		2,
    /**
     * A text node.
     *
     * Objects of this type are an xmlNode.
     */
    XML_TEXT_NODE=		3,
    /**
     * A CDATA section.
     *
     * Objects of this type are an xmlNode.
     */
    XML_CDATA_SECTION_NODE=	4,
    /**
     * An entity reference.
     *
     * Objects of this type are an xmlNode. The `children` member
     * points to the entity declaration if available.
     */
    XML_ENTITY_REF_NODE=	5,
    /** unused */
    XML_ENTITY_NODE=		6,
    /**
     * A processing instruction.
     *
     * Objects of this type are an xmlNode.
     */
    XML_PI_NODE=		7,
    /**
     * A comment.
     *
     * Objects of this type are an xmlNode.
     */
    XML_COMMENT_NODE=		8,
    /**
     * A document.
     *
     * Objects of this type are an xmlDoc.
     */
    XML_DOCUMENT_NODE=		9,
    /** unused */
    XML_DOCUMENT_TYPE_NODE=	10,
    /**
     * A document fragment.
     *
     * Objects of this type are an xmlNode.
     */
    XML_DOCUMENT_FRAG_NODE=	11,
    /** A notation, unused */
    XML_NOTATION_NODE=		12,
    /**
     * An HTML document.
     *
     * Objects of this type are an xmlDoc.
     */
    XML_HTML_DOCUMENT_NODE=	13,
    /**
     * A document type definition.
     *
     * Objects of this type are an xmlDtd.
     */
    XML_DTD_NODE=		14,
    /**
     * An element declaration.
     *
     * Objects of this type are an xmlElement.
     */
    XML_ELEMENT_DECL=		15,
    /**
     * An attribute declaration.
     *
     * Objects of this type are an xmlAttribute.
     */
    XML_ATTRIBUTE_DECL=		16,
    /**
     * An entity declaration.
     *
     * Objects of this type are an xmlEntity.
     */
    XML_ENTITY_DECL=		17,
    /**
     * An XPath namespace node.
     *
     * Can only be returned by the XPath engine. Objects of this
     * type are an xmlNs which has a completely different layout
     * than xmlNode. The `next` member contains a pointer to the
     * xmlNode element to which the namespace applies.
     *
     * Nodes of this type must be handled with extreme care to
     * avoid type confusion bugs.
     */
    XML_NAMESPACE_DECL=		18,
    /**
     * An XInclude start marker.
     *
     * Objects of this type are an xmlNode. Inserted as preceding
     * sibling of XIncluded content.
     */
    XML_XINCLUDE_START=		19,
    /**
     * An XInclude end marker.
     *
     * Objects of this type are an xmlNode. Inserted as following
     * sibling of XIncluded content.
     */
    XML_XINCLUDE_END=		20
    /* XML_DOCB_DOCUMENT_NODE=	21 */ /* removed */
} xmlElementType;

/** @cond IGNORE */
/* For backward compatibility */
#define XML_DOCB_DOCUMENT_NODE 21
/** @endcond */

/** Notation declaration */
typedef struct _xmlNotation xmlNotation;
typedef xmlNotation *xmlNotationPtr;
/**
 * A DTD Notation definition.
 *
 * Should be treated as opaque. Accessing members directly
 * is deprecated.
 */
struct _xmlNotation {
    /** Notation name */
    const xmlChar               *name;
    /** Public identifier, if any */
    const xmlChar               *PublicID;
    /** System identifier, if any */
    const xmlChar               *SystemID;
};

/**
 * A DTD Attribute type definition.
 */
typedef enum {
    XML_ATTRIBUTE_CDATA = 1,
    XML_ATTRIBUTE_ID,
    XML_ATTRIBUTE_IDREF	,
    XML_ATTRIBUTE_IDREFS,
    XML_ATTRIBUTE_ENTITY,
    XML_ATTRIBUTE_ENTITIES,
    XML_ATTRIBUTE_NMTOKEN,
    XML_ATTRIBUTE_NMTOKENS,
    XML_ATTRIBUTE_ENUMERATION,
    XML_ATTRIBUTE_NOTATION
} xmlAttributeType;

/**
 * A DTD Attribute default definition.
 */
typedef enum {
    XML_ATTRIBUTE_NONE = 1,
    XML_ATTRIBUTE_REQUIRED,
    XML_ATTRIBUTE_IMPLIED,
    XML_ATTRIBUTE_FIXED
} xmlAttributeDefault;

/** Enumeration in a DTD */
typedef struct _xmlEnumeration xmlEnumeration;
typedef xmlEnumeration *xmlEnumerationPtr;
/**
 * List structure used when there is an enumeration in DTDs.
 *
 * Should be treated as opaque. Accessing members directly
 * is deprecated.
 */
struct _xmlEnumeration {
    /** next enumeration */
    struct _xmlEnumeration    *next XML_DEPRECATED_MEMBER;
    /** value */
    const xmlChar            *name XML_DEPRECATED_MEMBER;
};

/** Attribute declaration */
typedef struct _xmlAttribute xmlAttribute;
typedef xmlAttribute *xmlAttributePtr;
/**
 * An Attribute declaration in a DTD.
 *
 * Should be treated as opaque. Accessing members directly
 * is deprecated.
 */
struct _xmlAttribute {
    /** application data */
    void           *_private;
    /** XML_ATTRIBUTE_DECL */
    xmlElementType          type;
    /** attribute name */
    const xmlChar          *name;
    /** NULL */
    struct _xmlNode    *children;
    /** NULL */
    struct _xmlNode        *last;
    /** DTD */
    struct _xmlDtd       *parent;
    /** next sibling */
    struct _xmlNode        *next;
    /** previous sibling */
    struct _xmlNode        *prev;
    /** containing document */
    struct _xmlDoc          *doc;

    /** next in hash table */
    struct _xmlAttribute  *nexth;
    /** attribute type */
    xmlAttributeType       atype;
    /** attribute default */
    xmlAttributeDefault      def;
    /** default value */
    xmlChar *defaultValue;
    /** enumeration tree if any */
    xmlEnumeration         *tree XML_DEPRECATED_MEMBER;
    /** namespace prefix if any */
    const xmlChar        *prefix;
    /** element name */
    const xmlChar          *elem;
};

/**
 * Possible definitions of element content types.
 */
typedef enum {
    XML_ELEMENT_CONTENT_PCDATA = 1,
    XML_ELEMENT_CONTENT_ELEMENT,
    XML_ELEMENT_CONTENT_SEQ,
    XML_ELEMENT_CONTENT_OR
} xmlElementContentType;

/**
 * Possible definitions of element content occurrences.
 */
typedef enum {
    XML_ELEMENT_CONTENT_ONCE = 1,
    XML_ELEMENT_CONTENT_OPT,
    XML_ELEMENT_CONTENT_MULT,
    XML_ELEMENT_CONTENT_PLUS
} xmlElementContentOccur;

/** Element content in element declarations */
typedef struct _xmlElementContent xmlElementContent;
typedef xmlElementContent *xmlElementContentPtr;
/**
 * An XML Element content as stored after parsing an element definition
 * in a DTD.
 *
 * Should be treated as opaque. Accessing members directly
 * is deprecated.
 */
struct _xmlElementContent {
    /** PCDATA, ELEMENT, SEQ or OR */
    xmlElementContentType     type XML_DEPRECATED_MEMBER;
    /** ONCE, OPT, MULT or PLUS */
    xmlElementContentOccur    ocur XML_DEPRECATED_MEMBER;
    /** element name */
    const xmlChar             *name XML_DEPRECATED_MEMBER;
    /** first child */
    struct _xmlElementContent *c1 XML_DEPRECATED_MEMBER;
    /** second child */
    struct _xmlElementContent *c2 XML_DEPRECATED_MEMBER;
    /** parent */
    struct _xmlElementContent *parent XML_DEPRECATED_MEMBER;
    /** namespace prefix */
    const xmlChar             *prefix XML_DEPRECATED_MEMBER;
};

/**
 * The different possibilities for an element content type.
 */
typedef enum {
    XML_ELEMENT_TYPE_UNDEFINED = 0,
    XML_ELEMENT_TYPE_EMPTY = 1,
    XML_ELEMENT_TYPE_ANY,
    XML_ELEMENT_TYPE_MIXED,
    XML_ELEMENT_TYPE_ELEMENT
} xmlElementTypeVal;

/** Element declaration */
typedef struct _xmlElement xmlElement;
typedef xmlElement *xmlElementPtr;
/**
 * An XML Element declaration from a DTD.
 *
 * Should be treated as opaque. Accessing members directly
 * is deprecated.
 */
struct _xmlElement {
    /** application data */
    void           *_private;
    /** XML_ELEMENT_DECL */
    xmlElementType          type;
    /** element name */
    const xmlChar          *name;
    /** NULL */
    struct _xmlNode    *children;
    /** NULL */
    struct _xmlNode        *last;
    /** -> DTD */
    struct _xmlDtd       *parent;
    /** next sibling */
    struct _xmlNode        *next;
    /** previous sibling */
    struct _xmlNode        *prev;
    /** containing document */
    struct _xmlDoc          *doc;

    /** element type */
    xmlElementTypeVal      etype;
    /** allowed element content */
    xmlElementContent *content;
    /** list of declared attributes */
    xmlAttribute     *attributes;
    /** namespace prefix if any */
    const xmlChar        *prefix;
#ifdef LIBXML_REGEXP_ENABLED
    /** validating regexp */
    xmlRegexp         *contModel XML_DEPRECATED_MEMBER;
#else
    void	      *contModel XML_DEPRECATED_MEMBER;
#endif
};


/**
 * A namespace declaration node.
 */
#define XML_LOCAL_NAMESPACE XML_NAMESPACE_DECL
typedef xmlElementType xmlNsType;

/** Namespace declaration */
typedef struct _xmlNs xmlNs;
typedef xmlNs *xmlNsPtr;
/**
 * An XML namespace.
 * Note that prefix == NULL is valid, it defines the default namespace
 * within the subtree (until overridden).
 *
 * xmlNsType is unified with xmlElementType.
 *
 * Note that the XPath engine returns XPath namespace nodes as
 * xmlNs cast to xmlNode. This is a terrible design decision that
 * can easily cause type confusion errors. In this case, the `next`
 * member points to the xmlNode element to which the namespace
 * node belongs.
 */
struct _xmlNs {
    /** next namespace */
    struct _xmlNs  *next;
    /** XML_NAMESPACE_DECL */
    xmlNsType      type;
    /** namespace URI */
    const xmlChar *href;
    /** namespace prefix */
    const xmlChar *prefix;
    /** application data */
    void           *_private;
    /** normally an xmlDoc */
    struct _xmlDoc *context XML_DEPRECATED_MEMBER;
};

/** Document type definition (DTD) */
typedef struct _xmlDtd xmlDtd;
typedef xmlDtd *xmlDtdPtr;
/**
 * An XML DTD, as defined by <!DOCTYPE ... There is actually one for
 * the internal subset and for the external subset.
 *
 * Should be treated as opaque. Accessing members directly
 * is deprecated.
 */
struct _xmlDtd {
    /** application data */
    void           *_private;
    /** XML_DTD_NODE */
    xmlElementType  type;
    /** name of the DTD */
    const xmlChar *name;
    /** first child */
    struct _xmlNode *children;
    /** last child */
    struct _xmlNode *last;
    /** parent node */
    struct _xmlDoc  *parent;
    /** next sibling */
    struct _xmlNode *next;
    /** previous sibling */
    struct _xmlNode *prev;
    /** containing document */
    struct _xmlDoc  *doc;

    /* End of common part */

    /** hash table for notations if any */
    void          *notations;
    /** hash table for elements if any */
    void          *elements;
    /** hash table for attributes if any */
    void          *attributes;
    /** hash table for entities if any */
    void          *entities;
    /** public identifier */
    xmlChar *ExternalID;
    /** system identifier */
    xmlChar *SystemID;
    /** hash table for parameter entities if any */
    void          *pentities;
};

/** Attribute of an element */
typedef struct _xmlAttr xmlAttr;
typedef xmlAttr *xmlAttrPtr;
/**
 * An attribute of element.
 */
struct _xmlAttr {
    /** application data */
    void           *_private;
    /** XML_ATTRIBUTE_NODE */
    xmlElementType   type;
    /** local name */
    const xmlChar   *name;
    /** first child */
    struct _xmlNode *children;
    /** last child */
    struct _xmlNode *last;
    /** parent node */
    struct _xmlNode *parent;
    /** next sibling */
    struct _xmlAttr *next;
    /** previous sibling */
    struct _xmlAttr *prev;
    /** containing document */
    struct _xmlDoc  *doc;
    /** namespace if any */
    xmlNs           *ns;
    /** attribute type if validating */
    xmlAttributeType atype;
    /** for type/PSVI information */
    void            *psvi;
    /** ID struct if any */
    struct _xmlID   *id XML_DEPRECATED_MEMBER;
};

/** Extra data for ID attributes */
typedef struct _xmlID xmlID;
typedef xmlID *xmlIDPtr;
/**
 * An XML ID instance.
 *
 * Should be treated as opaque. Accessing members directly
 * is deprecated.
 */
struct _xmlID {
    /* next ID */
    struct _xmlID    *next XML_DEPRECATED_MEMBER;
    /* The ID name */
    xmlChar *value XML_DEPRECATED_MEMBER;
    /* The attribute holding it */
    xmlAttr          *attr XML_DEPRECATED_MEMBER;
    /* The attribute if attr is not available */
    const xmlChar    *name XML_DEPRECATED_MEMBER;
    /* The line number if attr is not available */
    int               lineno XML_DEPRECATED_MEMBER;
    /* The document holding the ID */
    struct _xmlDoc   *doc XML_DEPRECATED_MEMBER;
};

/** @cond ignore */
typedef struct _xmlRef xmlRef;
typedef xmlRef *xmlRefPtr;
/*
 * An XML IDREF instance.
 */
struct _xmlRef {
    /* next Ref */
    struct _xmlRef    *next XML_DEPRECATED_MEMBER;
    /* The Ref name */
    const xmlChar     *value XML_DEPRECATED_MEMBER;
    /* The attribute holding it */
    xmlAttr          *attr XML_DEPRECATED_MEMBER;
    /* The attribute if attr is not available */
    const xmlChar    *name XML_DEPRECATED_MEMBER;
    /* The line number if attr is not available */
    int               lineno XML_DEPRECATED_MEMBER;
};
/** @endcond */

/** Generic node type in an XML or HTML tree */
typedef struct _xmlNode xmlNode;
typedef xmlNode *xmlNodePtr;
/**
 * Generic node type in an XML or HTML tree.
 *
 * This is used for
 *
 * - XML_ELEMENT_NODE
 * - XML_TEXT_NODE
 * - XML_CDATA_SECTION_NODE
 * - XML_ENTITY_REF_NODE
 * - XML_PI_NODE
 * - XML_COMMENT_NODE
 * - XML_DOCUMENT_FRAG_NODE
 * - XML_XINCLUDE_START_NODE
 * - XML_XINCLUDE_END_NODE
 *
 * Other node types have a different struct layout than xmlNode,
 * see xmlElementType. Except for XML_NAMESPACE_DECL all nodes
 * share the following members at the same offset:
 *
 * - `_private`
 * - `type` (also for XML_NAMESPACE_DECL)
 * - `name`
 * - `children`
 * - `last`
 * - `parent`
 * - `next`
 * - `prev`
 * - `doc`
 *
 * xmlNode and xmlAttr also share the `ns` member.
 */
struct _xmlNode {
    /** Application data. Often used by language bindings. */
    void           *_private;
    /** Type enum, an xmlElementType value */
    xmlElementType   type;
    /**
     * Name of the node.
     *
     * - Local name of elements or attributes. As a corner case,
     *   this can also contain Names which are invalid QNames in
     *   non-namespace-wellformed documents.
     * - Name of entity references
     * - Target of processing instructions
     * - Fixed string for text and comments
     * - Unused otherwise
     */
    const xmlChar   *name;
    /** First child. Entity declaration of entity references. */
    struct _xmlNode *children;
    /** Last child */
    struct _xmlNode *last;
    /** Parent node. NULL for documents or unlinked root nodes. */
    struct _xmlNode *parent;
    /** Next sibling */
    struct _xmlNode *next;
    /** Previous sibling */
    struct _xmlNode *prev;
    /**
     * Associated document.
     *
     * Used to access DTDs, entities, ID tables, dictionary or
     * other document properties. All children of a node share the
     * same document.
     */
    struct _xmlDoc  *doc;

    /* End of common part */

    /** Namespace of element if any */
    xmlNs           *ns;
    /**
     * Content of text, comment, PI nodes.
     *
     * Sort index for elements after calling #xmlXPathOrderDocElems.
     * Content of internal entities for entity references.
     */
    xmlChar         *content;
    /**
     * First attribute of element.
     *
     * Also used to store small strings with XML_PARSE_COMPACT.
     */
    struct _xmlAttr *properties;
    /** First namespace definition of element */
    xmlNs           *nsDef;
    /** For type/PSVI information */
    void            *psvi;
    /** Line number */
    unsigned short   line;
    /** Extra data for XPath/XSLT */
    unsigned short   extra;
};

/**
 * Set of properties of the document as found by the parser.
 * Some of them are linked to similarly named xmlParserOption.
 */
typedef enum {
    /** document is XML well formed */
    XML_DOC_WELLFORMED		= 1<<0,
    /** document is Namespace valid */
    XML_DOC_NSVALID		= 1<<1,
    /** parsed with old XML-1.0 parser */
    XML_DOC_OLD10		= 1<<2,
    /** DTD validation was successful */
    XML_DOC_DTDVALID		= 1<<3,
    /** XInclude substitution was done */
    XML_DOC_XINCLUDE		= 1<<4,
    /** Document was built using the API and not by parsing an instance */
    XML_DOC_USERBUILT		= 1<<5,
    /** built for internal processing */
    XML_DOC_INTERNAL		= 1<<6,
    /** parsed or built HTML document */
    XML_DOC_HTML		= 1<<7
} xmlDocProperties;

/** XML or HTML document */
typedef struct _xmlDoc xmlDoc;
typedef xmlDoc *xmlDocPtr;
/**
 * An XML or HTML document.
 */
struct _xmlDoc {
    /** application data */
    void           *_private;
    /** XML_DOCUMENT_NODE or XML_HTML_DOCUMENT_NODE */
    xmlElementType  type;
    /** NULL */
    char           *name;
    /** first child */
    struct _xmlNode *children;
    /** last child */
    struct _xmlNode *last;
    /** parent node */
    struct _xmlNode *parent;
    /** next sibling */
    struct _xmlNode *next;
    /** previous sibling */
    struct _xmlNode *prev;
    /** reference to itself */
    struct _xmlDoc  *doc;

    /* End of common part */

    /** level of zlib compression */
    int             compression;
    /**
     * standalone document (no external refs)
     *
     * - 1 if standalone="yes",
     * - 0 if standalone="no",
     * - -1 if there is no XML declaration,
     * - -2 if there is an XML declaration, but no
     *   standalone attribute was specified
     */
    int             standalone;
    /** internal subset */
    struct _xmlDtd  *intSubset;
    /** external subset */
    struct _xmlDtd  *extSubset;
    /** used to hold the XML namespace if needed */
    struct _xmlNs   *oldNs;
    /** version string from XML declaration */
    xmlChar  *version;
    /** actual encoding if any */
    xmlChar  *encoding;
    /** hash table for ID attributes if any */
    void           *ids;
    /** hash table for IDREFs attributes if any */
    void           *refs XML_DEPRECATED_MEMBER;
    /** URI of the document */
    xmlChar  *URL;
    /** unused */
    int             charset;
    /** dict used to allocate names if any */
    struct _xmlDict *dict;
    /** for type/PSVI information */
    void           *psvi;
    /** xmlParserOption enum used to parse the document */
    int             parseFlags;
    /** xmlDocProperties of the document */
    int             properties;
};


/** Context for DOM wrapper operations */
typedef struct _xmlDOMWrapCtxt xmlDOMWrapCtxt;
typedef xmlDOMWrapCtxt *xmlDOMWrapCtxtPtr;

/**
 * A function called to acquire namespaces (xmlNs) from the wrapper.
 *
 * @param ctxt  a DOM wrapper context
 * @param node  the context node (element or attribute)
 * @param nsName  the requested namespace name
 * @param nsPrefix  the requested namespace prefix
 * @returns an xmlNs or NULL in case of an error.
 */
typedef xmlNs *(*xmlDOMWrapAcquireNsFunction) (xmlDOMWrapCtxt *ctxt,
						 xmlNode *node,
						 const xmlChar *nsName,
						 const xmlChar *nsPrefix);

/**
 * Context for DOM wrapper-operations.
 */
struct _xmlDOMWrapCtxt {
    void * _private;
    /*
    * The type of this context, just in case we need specialized
    * contexts in the future.
    */
    int type;
    /*
    * Internal namespace map used for various operations.
    */
    void * namespaceMap;
    /*
    * Use this one to acquire an xmlNs intended for node->ns.
    * (Note that this is not intended for elem->nsDef).
    */
    xmlDOMWrapAcquireNsFunction getNsForNodeFunc;
};

/**
 * Signature for the registration callback of a created node
 *
 * @param node  the current node
 */
typedef void (*xmlRegisterNodeFunc) (xmlNode *node);

/**
 * Signature for the deregistration callback of a discarded node
 *
 * @param node  the current node
 */
typedef void (*xmlDeregisterNodeFunc) (xmlNode *node);

/**
 * Macro for compatibility naming layer with libxml1. Maps
 * to "children."
 */
#ifndef xmlChildrenNode
#define xmlChildrenNode children
#endif

/**
 * Macro for compatibility naming layer with libxml1. Maps
 * to "children".
 */
#ifndef xmlRootNode
#define xmlRootNode children
#endif

/*
 * Variables.
 */

/** @cond ignore */

XML_DEPRECATED
XMLPUBFUN xmlRegisterNodeFunc *__xmlRegisterNodeDefaultValue(void);
XML_DEPRECATED
XMLPUBFUN xmlDeregisterNodeFunc *__xmlDeregisterNodeDefaultValue(void);

#ifndef XML_GLOBALS_NO_REDEFINITION
  #define xmlRegisterNodeDefaultValue \
    (*__xmlRegisterNodeDefaultValue())
  #define xmlDeregisterNodeDefaultValue \
    (*__xmlDeregisterNodeDefaultValue())
#endif

/** @endcond */

/*
 * Some helper functions
 */
XMLPUBFUN int
		xmlValidateNCName	(const xmlChar *value,
					 int space);

XMLPUBFUN int
		xmlValidateQName	(const xmlChar *value,
					 int space);
XMLPUBFUN int
		xmlValidateName		(const xmlChar *value,
					 int space);
XMLPUBFUN int
		xmlValidateNMToken	(const xmlChar *value,
					 int space);

XMLPUBFUN xmlChar *
		xmlBuildQName		(const xmlChar *ncname,
					 const xmlChar *prefix,
					 xmlChar *memory,
					 int len);
XMLPUBFUN xmlChar *
		xmlSplitQName2		(const xmlChar *name,
					 xmlChar **prefix);
XMLPUBFUN const xmlChar *
		xmlSplitQName3		(const xmlChar *name,
					 int *len);

/*
 * Creating/freeing new structures.
 */
XMLPUBFUN xmlDtd *
		xmlCreateIntSubset	(xmlDoc *doc,
					 const xmlChar *name,
					 const xmlChar *publicId,
					 const xmlChar *systemId);
XMLPUBFUN xmlDtd *
		xmlNewDtd		(xmlDoc *doc,
					 const xmlChar *name,
					 const xmlChar *publicId,
					 const xmlChar *systemId);
XMLPUBFUN xmlDtd *
		xmlGetIntSubset		(const xmlDoc *doc);
XMLPUBFUN void
		xmlFreeDtd		(xmlDtd *cur);
XMLPUBFUN xmlNs *
		xmlNewNs		(xmlNode *node,
					 const xmlChar *href,
					 const xmlChar *prefix);
XMLPUBFUN void
		xmlFreeNs		(xmlNs *cur);
XMLPUBFUN void
		xmlFreeNsList		(xmlNs *cur);
XMLPUBFUN xmlDoc *
		xmlNewDoc		(const xmlChar *version);
XMLPUBFUN void
		xmlFreeDoc		(xmlDoc *cur);
XMLPUBFUN xmlAttr *
		xmlNewDocProp		(xmlDoc *doc,
					 const xmlChar *name,
					 const xmlChar *value);
XMLPUBFUN xmlAttr *
		xmlNewProp		(xmlNode *node,
					 const xmlChar *name,
					 const xmlChar *value);
XMLPUBFUN xmlAttr *
		xmlNewNsProp		(xmlNode *node,
					 xmlNs *ns,
					 const xmlChar *name,
					 const xmlChar *value);
XMLPUBFUN xmlAttr *
		xmlNewNsPropEatName	(xmlNode *node,
					 xmlNs *ns,
					 xmlChar *name,
					 const xmlChar *value);
XMLPUBFUN void
		xmlFreePropList		(xmlAttr *cur);
XMLPUBFUN void
		xmlFreeProp		(xmlAttr *cur);
XMLPUBFUN xmlAttr *
		xmlCopyProp		(xmlNode *target,
					 xmlAttr *cur);
XMLPUBFUN xmlAttr *
		xmlCopyPropList		(xmlNode *target,
					 xmlAttr *cur);
XMLPUBFUN xmlDtd *
		xmlCopyDtd		(xmlDtd *dtd);
XMLPUBFUN xmlDoc *
		xmlCopyDoc		(xmlDoc *doc,
					 int recursive);
/*
 * Creating new nodes.
 */
XMLPUBFUN xmlNode *
		xmlNewDocNode		(xmlDoc *doc,
					 xmlNs *ns,
					 const xmlChar *name,
					 const xmlChar *content);
XMLPUBFUN xmlNode *
		xmlNewDocNodeEatName	(xmlDoc *doc,
					 xmlNs *ns,
					 xmlChar *name,
					 const xmlChar *content);
XMLPUBFUN xmlNode *
		xmlNewNode		(xmlNs *ns,
					 const xmlChar *name);
XMLPUBFUN xmlNode *
		xmlNewNodeEatName	(xmlNs *ns,
					 xmlChar *name);
XMLPUBFUN xmlNode *
		xmlNewChild		(xmlNode *parent,
					 xmlNs *ns,
					 const xmlChar *name,
					 const xmlChar *content);
XMLPUBFUN xmlNode *
		xmlNewDocText		(const xmlDoc *doc,
					 const xmlChar *content);
XMLPUBFUN xmlNode *
		xmlNewText		(const xmlChar *content);
XMLPUBFUN xmlNode *
		xmlNewDocPI		(xmlDoc *doc,
					 const xmlChar *name,
					 const xmlChar *content);
XMLPUBFUN xmlNode *
		xmlNewPI		(const xmlChar *name,
					 const xmlChar *content);
XMLPUBFUN xmlNode *
		xmlNewDocTextLen	(xmlDoc *doc,
					 const xmlChar *content,
					 int len);
XMLPUBFUN xmlNode *
		xmlNewTextLen		(const xmlChar *content,
					 int len);
XMLPUBFUN xmlNode *
		xmlNewDocComment	(xmlDoc *doc,
					 const xmlChar *content);
XMLPUBFUN xmlNode *
		xmlNewComment		(const xmlChar *content);
XMLPUBFUN xmlNode *
		xmlNewCDataBlock	(xmlDoc *doc,
					 const xmlChar *content,
					 int len);
XMLPUBFUN xmlNode *
		xmlNewCharRef		(xmlDoc *doc,
					 const xmlChar *name);
XMLPUBFUN xmlNode *
		xmlNewReference		(const xmlDoc *doc,
					 const xmlChar *name);
XMLPUBFUN xmlNode *
		xmlCopyNode		(xmlNode *node,
					 int recursive);
XMLPUBFUN xmlNode *
		xmlDocCopyNode		(xmlNode *node,
					 xmlDoc *doc,
					 int recursive);
XMLPUBFUN xmlNode *
		xmlDocCopyNodeList	(xmlDoc *doc,
					 xmlNode *node);
XMLPUBFUN xmlNode *
		xmlCopyNodeList		(xmlNode *node);
XMLPUBFUN xmlNode *
		xmlNewTextChild		(xmlNode *parent,
					 xmlNs *ns,
					 const xmlChar *name,
					 const xmlChar *content);
XMLPUBFUN xmlNode *
		xmlNewDocRawNode	(xmlDoc *doc,
					 xmlNs *ns,
					 const xmlChar *name,
					 const xmlChar *content);
XMLPUBFUN xmlNode *
		xmlNewDocFragment	(xmlDoc *doc);

/*
 * Navigating.
 */
XMLPUBFUN long
		xmlGetLineNo		(const xmlNode *node);
XMLPUBFUN xmlChar *
		xmlGetNodePath		(const xmlNode *node);
XMLPUBFUN xmlNode *
		xmlDocGetRootElement	(const xmlDoc *doc);
XMLPUBFUN xmlNode *
		xmlGetLastChild		(const xmlNode *parent);
XMLPUBFUN int
		xmlNodeIsText		(const xmlNode *node);
XMLPUBFUN int
		xmlIsBlankNode		(const xmlNode *node);

/*
 * Changing the structure.
 */
XMLPUBFUN xmlNode *
		xmlDocSetRootElement	(xmlDoc *doc,
					 xmlNode *root);
XMLPUBFUN void
		xmlNodeSetName		(xmlNode *cur,
					 const xmlChar *name);
XMLPUBFUN xmlNode *
		xmlAddChild		(xmlNode *parent,
					 xmlNode *cur);
XMLPUBFUN xmlNode *
		xmlAddChildList		(xmlNode *parent,
					 xmlNode *cur);
XMLPUBFUN xmlNode *
		xmlReplaceNode		(xmlNode *old,
					 xmlNode *cur);
XMLPUBFUN xmlNode *
		xmlAddPrevSibling	(xmlNode *cur,
					 xmlNode *elem);
XMLPUBFUN xmlNode *
		xmlAddSibling		(xmlNode *cur,
					 xmlNode *elem);
XMLPUBFUN xmlNode *
		xmlAddNextSibling	(xmlNode *cur,
					 xmlNode *elem);
XMLPUBFUN void
		xmlUnlinkNode		(xmlNode *cur);
XMLPUBFUN xmlNode *
		xmlTextMerge		(xmlNode *first,
					 xmlNode *second);
XMLPUBFUN int
		xmlTextConcat		(xmlNode *node,
					 const xmlChar *content,
					 int len);
XMLPUBFUN void
		xmlFreeNodeList		(xmlNode *cur);
XMLPUBFUN void
		xmlFreeNode		(xmlNode *cur);
XMLPUBFUN int
		xmlSetTreeDoc		(xmlNode *tree,
					 xmlDoc *doc);
XMLPUBFUN int
		xmlSetListDoc		(xmlNode *list,
					 xmlDoc *doc);
/*
 * Namespaces.
 */
XMLPUBFUN xmlNs *
		xmlSearchNs		(xmlDoc *doc,
					 xmlNode *node,
					 const xmlChar *nameSpace);
XMLPUBFUN xmlNs *
		xmlSearchNsByHref	(xmlDoc *doc,
					 xmlNode *node,
					 const xmlChar *href);
XMLPUBFUN int
		xmlGetNsListSafe	(const xmlDoc *doc,
					 const xmlNode *node,
					 xmlNs ***out);
XMLPUBFUN xmlNs **
		xmlGetNsList		(const xmlDoc *doc,
					 const xmlNode *node);

XMLPUBFUN void
		xmlSetNs		(xmlNode *node,
					 xmlNs *ns);
XMLPUBFUN xmlNs *
		xmlCopyNamespace	(xmlNs *cur);
XMLPUBFUN xmlNs *
		xmlCopyNamespaceList	(xmlNs *cur);

/*
 * Changing the content.
 */
XMLPUBFUN xmlAttr *
		xmlSetProp		(xmlNode *node,
					 const xmlChar *name,
					 const xmlChar *value);
XMLPUBFUN xmlAttr *
		xmlSetNsProp		(xmlNode *node,
					 xmlNs *ns,
					 const xmlChar *name,
					 const xmlChar *value);
XMLPUBFUN int
		xmlNodeGetAttrValue	(const xmlNode *node,
					 const xmlChar *name,
					 const xmlChar *nsUri,
					 xmlChar **out);
XMLPUBFUN xmlChar *
		xmlGetNoNsProp		(const xmlNode *node,
					 const xmlChar *name);
XMLPUBFUN xmlChar *
		xmlGetProp		(const xmlNode *node,
					 const xmlChar *name);
XMLPUBFUN xmlAttr *
		xmlHasProp		(const xmlNode *node,
					 const xmlChar *name);
XMLPUBFUN xmlAttr *
		xmlHasNsProp		(const xmlNode *node,
					 const xmlChar *name,
					 const xmlChar *nameSpace);
XMLPUBFUN xmlChar *
		xmlGetNsProp		(const xmlNode *node,
					 const xmlChar *name,
					 const xmlChar *nameSpace);
XMLPUBFUN xmlNode *
		xmlStringGetNodeList	(const xmlDoc *doc,
					 const xmlChar *value);
XMLPUBFUN xmlNode *
		xmlStringLenGetNodeList	(const xmlDoc *doc,
					 const xmlChar *value,
					 int len);
XMLPUBFUN xmlChar *
		xmlNodeListGetString	(xmlDoc *doc,
					 const xmlNode *list,
					 int inLine);
XMLPUBFUN xmlChar *
		xmlNodeListGetRawString	(const xmlDoc *doc,
					 const xmlNode *list,
					 int inLine);
XMLPUBFUN int
		xmlNodeSetContent	(xmlNode *cur,
					 const xmlChar *content);
XMLPUBFUN int
		xmlNodeSetContentLen	(xmlNode *cur,
					 const xmlChar *content,
					 int len);
XMLPUBFUN int
		xmlNodeAddContent	(xmlNode *cur,
					 const xmlChar *content);
XMLPUBFUN int
		xmlNodeAddContentLen	(xmlNode *cur,
					 const xmlChar *content,
					 int len);
XMLPUBFUN xmlChar *
		xmlNodeGetContent	(const xmlNode *cur);

XMLPUBFUN int
		xmlNodeBufGetContent	(xmlBuffer *buffer,
					 const xmlNode *cur);
XMLPUBFUN int
		xmlBufGetNodeContent	(xmlBuf *buf,
					 const xmlNode *cur);

XMLPUBFUN xmlChar *
		xmlNodeGetLang		(const xmlNode *cur);
XMLPUBFUN int
		xmlNodeGetSpacePreserve	(const xmlNode *cur);
XMLPUBFUN int
		xmlNodeSetLang		(xmlNode *cur,
					 const xmlChar *lang);
XMLPUBFUN int
		xmlNodeSetSpacePreserve (xmlNode *cur,
					 int val);
XMLPUBFUN int
		xmlNodeGetBaseSafe	(const xmlDoc *doc,
					 const xmlNode *cur,
					 xmlChar **baseOut);
XMLPUBFUN xmlChar *
		xmlNodeGetBase		(const xmlDoc *doc,
					 const xmlNode *cur);
XMLPUBFUN int
		xmlNodeSetBase		(xmlNode *cur,
					 const xmlChar *uri);

/*
 * Removing content.
 */
XMLPUBFUN int
		xmlRemoveProp		(xmlAttr *cur);
XMLPUBFUN int
		xmlUnsetNsProp		(xmlNode *node,
					 xmlNs *ns,
					 const xmlChar *name);
XMLPUBFUN int
		xmlUnsetProp		(xmlNode *node,
					 const xmlChar *name);

#ifdef LIBXML_OUTPUT_ENABLED
XMLPUBFUN void xmlAttrSerializeTxtContent(xmlBuffer *buf,
					 xmlDoc *doc,
					 xmlAttr *attr,
					 const xmlChar *string);
#endif /* LIBXML_OUTPUT_ENABLED */

/*
 * Namespace handling.
 */
XMLPUBFUN int
		xmlReconciliateNs	(xmlDoc *doc,
					 xmlNode *tree);

#ifdef LIBXML_OUTPUT_ENABLED
/*
 * Saving.
 */
XMLPUBFUN void
		xmlDocDumpFormatMemory	(xmlDoc *cur,
					 xmlChar **mem,
					 int *size,
					 int format);
XMLPUBFUN void
		xmlDocDumpMemory	(xmlDoc *cur,
					 xmlChar **mem,
					 int *size);
XMLPUBFUN void
		xmlDocDumpMemoryEnc	(xmlDoc *out_doc,
					 xmlChar **doc_txt_ptr,
					 int * doc_txt_len,
					 const char *txt_encoding);
XMLPUBFUN void
		xmlDocDumpFormatMemoryEnc(xmlDoc *out_doc,
					 xmlChar **doc_txt_ptr,
					 int * doc_txt_len,
					 const char *txt_encoding,
					 int format);
XMLPUBFUN int
		xmlDocFormatDump	(FILE *f,
					 xmlDoc *cur,
					 int format);
XMLPUBFUN int
		xmlDocDump		(FILE *f,
					 xmlDoc *cur);
XMLPUBFUN void
		xmlElemDump		(FILE *f,
					 xmlDoc *doc,
					 xmlNode *cur);
XMLPUBFUN int
		xmlSaveFile		(const char *filename,
					 xmlDoc *cur);
XMLPUBFUN int
		xmlSaveFormatFile	(const char *filename,
					 xmlDoc *cur,
					 int format);
XMLPUBFUN size_t
		xmlBufNodeDump		(xmlBuf *buf,
					 xmlDoc *doc,
					 xmlNode *cur,
					 int level,
					 int format);
XMLPUBFUN int
		xmlNodeDump		(xmlBuffer *buf,
					 xmlDoc *doc,
					 xmlNode *cur,
					 int level,
					 int format);

XMLPUBFUN int
		xmlSaveFileTo		(xmlOutputBuffer *buf,
					 xmlDoc *cur,
					 const char *encoding);
XMLPUBFUN int
		xmlSaveFormatFileTo     (xmlOutputBuffer *buf,
					 xmlDoc *cur,
				         const char *encoding,
				         int format);
XMLPUBFUN void
		xmlNodeDumpOutput	(xmlOutputBuffer *buf,
					 xmlDoc *doc,
					 xmlNode *cur,
					 int level,
					 int format,
					 const char *encoding);

XMLPUBFUN int
		xmlSaveFormatFileEnc    (const char *filename,
					 xmlDoc *cur,
					 const char *encoding,
					 int format);

XMLPUBFUN int
		xmlSaveFileEnc		(const char *filename,
					 xmlDoc *cur,
					 const char *encoding);

#endif /* LIBXML_OUTPUT_ENABLED */
/*
 * XHTML
 */
XMLPUBFUN int
		xmlIsXHTML		(const xmlChar *systemID,
					 const xmlChar *publicID);

/*
 * Compression.
 */
XMLPUBFUN int
		xmlGetDocCompressMode	(const xmlDoc *doc);
XMLPUBFUN void
		xmlSetDocCompressMode	(xmlDoc *doc,
					 int mode);
XML_DEPRECATED
XMLPUBFUN int
		xmlGetCompressMode	(void);
XML_DEPRECATED
XMLPUBFUN void
		xmlSetCompressMode	(int mode);

/*
* DOM-wrapper helper functions.
*/
XMLPUBFUN xmlDOMWrapCtxt *
		xmlDOMWrapNewCtxt	(void);
XMLPUBFUN void
		xmlDOMWrapFreeCtxt	(xmlDOMWrapCtxt *ctxt);
XMLPUBFUN int
	    xmlDOMWrapReconcileNamespaces(xmlDOMWrapCtxt *ctxt,
					 xmlNode *elem,
					 int options);
XMLPUBFUN int
	    xmlDOMWrapAdoptNode		(xmlDOMWrapCtxt *ctxt,
					 xmlDoc *sourceDoc,
					 xmlNode *node,
					 xmlDoc *destDoc,
					 xmlNode *destParent,
					 int options);
XMLPUBFUN int
	    xmlDOMWrapRemoveNode	(xmlDOMWrapCtxt *ctxt,
					 xmlDoc *doc,
					 xmlNode *node,
					 int options);
XMLPUBFUN int
	    xmlDOMWrapCloneNode		(xmlDOMWrapCtxt *ctxt,
					 xmlDoc *sourceDoc,
					 xmlNode *node,
					 xmlNode **clonedNode,
					 xmlDoc *destDoc,
					 xmlNode *destParent,
					 int deep,
					 int options);

/*
 * 5 interfaces from DOM ElementTraversal, but different in entities
 * traversal.
 */
XMLPUBFUN unsigned long
            xmlChildElementCount        (xmlNode *parent);
XMLPUBFUN xmlNode *
            xmlNextElementSibling       (xmlNode *node);
XMLPUBFUN xmlNode *
            xmlFirstElementChild        (xmlNode *parent);
XMLPUBFUN xmlNode *
            xmlLastElementChild         (xmlNode *parent);
XMLPUBFUN xmlNode *
            xmlPreviousElementSibling   (xmlNode *node);

XML_DEPRECATED
XMLPUBFUN xmlRegisterNodeFunc
	    xmlRegisterNodeDefault	(xmlRegisterNodeFunc func);
XML_DEPRECATED
XMLPUBFUN xmlDeregisterNodeFunc
	    xmlDeregisterNodeDefault	(xmlDeregisterNodeFunc func);
XML_DEPRECATED
XMLPUBFUN xmlRegisterNodeFunc
            xmlThrDefRegisterNodeDefault(xmlRegisterNodeFunc func);
XML_DEPRECATED
XMLPUBFUN xmlDeregisterNodeFunc
            xmlThrDefDeregisterNodeDefault(xmlDeregisterNodeFunc func);

/*
 * Handling Buffers, the old ones see `xmlBuf` for the new ones.
 */

XML_DEPRECATED
XMLPUBFUN void
		xmlSetBufferAllocationScheme(xmlBufferAllocationScheme scheme);
XML_DEPRECATED
XMLPUBFUN xmlBufferAllocationScheme
		xmlGetBufferAllocationScheme(void);

XMLPUBFUN xmlBuffer *
		xmlBufferCreate		(void);
XMLPUBFUN xmlBuffer *
		xmlBufferCreateSize	(size_t size);
XMLPUBFUN xmlBuffer *
		xmlBufferCreateStatic	(void *mem,
					 size_t size);
XML_DEPRECATED
XMLPUBFUN int
		xmlBufferResize		(xmlBuffer *buf,
					 unsigned int size);
XMLPUBFUN void
		xmlBufferFree		(xmlBuffer *buf);
XMLPUBFUN int
		xmlBufferDump		(FILE *file,
					 xmlBuffer *buf);
XMLPUBFUN int
		xmlBufferAdd		(xmlBuffer *buf,
					 const xmlChar *str,
					 int len);
XMLPUBFUN int
		xmlBufferAddHead	(xmlBuffer *buf,
					 const xmlChar *str,
					 int len);
XMLPUBFUN int
		xmlBufferCat		(xmlBuffer *buf,
					 const xmlChar *str);
XMLPUBFUN int
		xmlBufferCCat		(xmlBuffer *buf,
					 const char *str);
XML_DEPRECATED
XMLPUBFUN int
		xmlBufferShrink		(xmlBuffer *buf,
					 unsigned int len);
XML_DEPRECATED
XMLPUBFUN int
		xmlBufferGrow		(xmlBuffer *buf,
					 unsigned int len);
XMLPUBFUN void
		xmlBufferEmpty		(xmlBuffer *buf);
XMLPUBFUN const xmlChar*
		xmlBufferContent	(const xmlBuffer *buf);
XMLPUBFUN xmlChar*
		xmlBufferDetach         (xmlBuffer *buf);
XMLPUBFUN void
		xmlBufferSetAllocationScheme(xmlBuffer *buf,
					 xmlBufferAllocationScheme scheme);
XMLPUBFUN int
		xmlBufferLength		(const xmlBuffer *buf);
XMLPUBFUN void
		xmlBufferWriteCHAR	(xmlBuffer *buf,
					 const xmlChar *string);
XMLPUBFUN void
		xmlBufferWriteChar	(xmlBuffer *buf,
					 const char *string);
XMLPUBFUN void
		xmlBufferWriteQuotedString(xmlBuffer *buf,
					 const xmlChar *string);

/*
 * A few public routines for xmlBuf. As those are expected to be used
 * mostly internally the bulk of the routines are internal in buf.h
 */
XMLPUBFUN xmlChar*       xmlBufContent	(const xmlBuf* buf);
XMLPUBFUN xmlChar*       xmlBufEnd      (xmlBuf *buf);
XMLPUBFUN size_t         xmlBufUse      (xmlBuf *buf);
XMLPUBFUN size_t         xmlBufShrink	(xmlBuf *buf, size_t len);

#ifdef __cplusplus
}
#endif

#endif /* __XML_TREE_H__ */

#endif /* XML_TREE_INTERNALS */

libxml2/libxml/xmlerror.h000064400000114647151733237440011455 0ustar00/**
 * @file
 * 
 * @brief Error handling
 * 
 * API for error reporting and callbacks.
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */

#ifndef __XML_ERROR_H__
#define __XML_ERROR_H__

#include <libxml/xmlversion.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * Set generic error callback.
 *
 * @deprecated Use #xmlSetGenericErrorFunc
 */
#define initGenericErrorDefaultFunc(h) \
    xmlSetGenericErrorFunc(NULL, (h) ? *((xmlGenericErrorFunc *) (h)) : NULL)

/**
 * Indicates the level of an error
 */
typedef enum {
    /** Success */
    XML_ERR_NONE = 0,
    /**
     * A warning
     *
     * When parsing XML, warnings are only reported to error
     * handlers.
     */
    XML_ERR_WARNING = 1,
    /**
     * An error
     *
     * When parsing XML, this is used for recoverable errors like
     *
     * - namespace errors
     * - validity errors when validating
     * - certain undeclared entities
     * - ID uniqueness and xml:id errors
     *
     * Note that some recoverable errors in the sense of the XML
     * spec are reported as warnings.
     *
     * In other contexts, this may be used for unrecoverable
     * errors.
     */
    XML_ERR_ERROR = 2,
    /**
     * A fatal error
     *
     * When parsing XML, a "fatal error" according to the XML spec.
     * This typically means that the document isn't well-formed.
     *
     * This also includes OOM and I/O errors, resource limit
     * exhaustion, unexpected errors from other libraries and
     * invalid argument errors.
     */
    XML_ERR_FATAL = 3
} xmlErrorLevel;

/**
 * Indicates where an error may have come from
 */
typedef enum {
    /** Unknown */
    XML_FROM_NONE = 0,
    /** The XML parser */
    XML_FROM_PARSER,
    /** The tree module (unused) */
    XML_FROM_TREE,
    /** The XML Namespace module */
    XML_FROM_NAMESPACE,
    /** The XML DTD validation with parser context */
    XML_FROM_DTD,
    /** The HTML parser */
    XML_FROM_HTML,
    /** The memory allocator (unused) */
    XML_FROM_MEMORY,
    /** The serialization code */
    XML_FROM_OUTPUT,
    /** The Input/Output stack */
    XML_FROM_IO,
    /** The FTP module (unused) */
    XML_FROM_FTP,
    /** The HTTP module (unused) */
    XML_FROM_HTTP,
    /** The XInclude processing */
    XML_FROM_XINCLUDE,
    /** The XPath module */
    XML_FROM_XPATH,
    /** The XPointer module */
    XML_FROM_XPOINTER,
    /** The regular expressions module */
    XML_FROM_REGEXP,
    /** The W3C XML Schemas Datatype module */
    XML_FROM_DATATYPE,
    /** The W3C XML Schemas parser module */
    XML_FROM_SCHEMASP,
    /** The W3C XML Schemas validation module */
    XML_FROM_SCHEMASV,
    /** The Relax-NG parser module */
    XML_FROM_RELAXNGP,
    /** The Relax-NG validator module */
    XML_FROM_RELAXNGV,
    /** The Catalog module */
    XML_FROM_CATALOG,
    /** The Canonicalization module */
    XML_FROM_C14N,
    /** The XSLT engine from libxslt (unused) */
    XML_FROM_XSLT,
    /** The XML DTD validation with valid context */
    XML_FROM_VALID,
    /** The error checking module (unused) */
    XML_FROM_CHECK,
    /** The xmlwriter module */
    XML_FROM_WRITER,
    /** The dynamically loaded module module (unused) */
    XML_FROM_MODULE,
    /** The module handling character conversion (unused) */
    XML_FROM_I18N,
    /** The Schematron validator module */
    XML_FROM_SCHEMATRONV,
    /** The buffers module (unused) */
    XML_FROM_BUFFER,
    /** The URI module (unused) */
    XML_FROM_URI
} xmlErrorDomain;

/** Structured error */
typedef struct _xmlError xmlError;
typedef xmlError *xmlErrorPtr;
/**
 * An object containing information about an error.
 */
struct _xmlError {
    /** An xmlErrorDomain value. */
    int		domain;
    /** The error code, e.g. an xmlParserErrors. */
    int		code;
    /** Human-readable error message. */
    char       *message;
    /** Error level. */
    xmlErrorLevel level;
    /** Filename if available */
    char       *file;
    /** Line number if available */
    int		line;
    /** Extra string information. */
    char       *str1;
    /** Extra string information. */
    char       *str2;
    /** Extra string information. */
    char       *str3;
    /** Extra number information. */
    int		int1;
    /** Column number if available. */
    int		int2;
    /** Parser context if available */
    void       *ctxt;
    /** Node if available */
    void       *node;
};

/**
 * Error codes. Note that only some codes are documented.
 */
typedef enum {
    /** Success. */
    XML_ERR_OK = 0,
    /** Internal assertion failure. */
    XML_ERR_INTERNAL_ERROR, /* 1 */
    /** Out of memory */
    XML_ERR_NO_MEMORY, /* 2 */
    XML_ERR_DOCUMENT_START, /* 3 */
    XML_ERR_DOCUMENT_EMPTY, /* 4 */
    XML_ERR_DOCUMENT_END, /* 5 */
    XML_ERR_INVALID_HEX_CHARREF, /* 6 */
    XML_ERR_INVALID_DEC_CHARREF, /* 7 */
    XML_ERR_INVALID_CHARREF, /* 8 */
    XML_ERR_INVALID_CHAR, /* 9 */
    XML_ERR_CHARREF_AT_EOF, /* 10 */
    XML_ERR_CHARREF_IN_PROLOG, /* 11 */
    XML_ERR_CHARREF_IN_EPILOG, /* 12 */
    XML_ERR_CHARREF_IN_DTD, /* 13 */
    XML_ERR_ENTITYREF_AT_EOF, /* 14 */
    XML_ERR_ENTITYREF_IN_PROLOG, /* 15 */
    XML_ERR_ENTITYREF_IN_EPILOG, /* 16 */
    XML_ERR_ENTITYREF_IN_DTD, /* 17 */
    XML_ERR_PEREF_AT_EOF, /* 18 */
    XML_ERR_PEREF_IN_PROLOG, /* 19 */
    XML_ERR_PEREF_IN_EPILOG, /* 20 */
    XML_ERR_PEREF_IN_INT_SUBSET, /* 21 */
    XML_ERR_ENTITYREF_NO_NAME, /* 22 */
    XML_ERR_ENTITYREF_SEMICOL_MISSING, /* 23 */
    XML_ERR_PEREF_NO_NAME, /* 24 */
    XML_ERR_PEREF_SEMICOL_MISSING, /* 25 */
    XML_ERR_UNDECLARED_ENTITY, /* 26 */
    XML_WAR_UNDECLARED_ENTITY, /* 27 */
    XML_ERR_UNPARSED_ENTITY, /* 28 */
    XML_ERR_ENTITY_IS_EXTERNAL, /* 29 */
    XML_ERR_ENTITY_IS_PARAMETER, /* 30 */
    XML_ERR_UNKNOWN_ENCODING, /* 31 */
    /** Unsupported character encoding. */
    XML_ERR_UNSUPPORTED_ENCODING, /* 32 */
    XML_ERR_STRING_NOT_STARTED, /* 33 */
    XML_ERR_STRING_NOT_CLOSED, /* 34 */
    XML_ERR_NS_DECL_ERROR, /* 35 */
    XML_ERR_ENTITY_NOT_STARTED, /* 36 */
    XML_ERR_ENTITY_NOT_FINISHED, /* 37 */
    XML_ERR_LT_IN_ATTRIBUTE, /* 38 */
    XML_ERR_ATTRIBUTE_NOT_STARTED, /* 39 */
    XML_ERR_ATTRIBUTE_NOT_FINISHED, /* 40 */
    XML_ERR_ATTRIBUTE_WITHOUT_VALUE, /* 41 */
    XML_ERR_ATTRIBUTE_REDEFINED, /* 42 */
    XML_ERR_LITERAL_NOT_STARTED, /* 43 */
    XML_ERR_LITERAL_NOT_FINISHED, /* 44 */
    XML_ERR_COMMENT_NOT_FINISHED, /* 45 */
    XML_ERR_PI_NOT_STARTED, /* 46 */
    XML_ERR_PI_NOT_FINISHED, /* 47 */
    XML_ERR_NOTATION_NOT_STARTED, /* 48 */
    XML_ERR_NOTATION_NOT_FINISHED, /* 49 */
    XML_ERR_ATTLIST_NOT_STARTED, /* 50 */
    XML_ERR_ATTLIST_NOT_FINISHED, /* 51 */
    XML_ERR_MIXED_NOT_STARTED, /* 52 */
    XML_ERR_MIXED_NOT_FINISHED, /* 53 */
    XML_ERR_ELEMCONTENT_NOT_STARTED, /* 54 */
    XML_ERR_ELEMCONTENT_NOT_FINISHED, /* 55 */
    XML_ERR_XMLDECL_NOT_STARTED, /* 56 */
    XML_ERR_XMLDECL_NOT_FINISHED, /* 57 */
    XML_ERR_CONDSEC_NOT_STARTED, /* 58 */
    XML_ERR_CONDSEC_NOT_FINISHED, /* 59 */
    XML_ERR_EXT_SUBSET_NOT_FINISHED, /* 60 */
    XML_ERR_DOCTYPE_NOT_FINISHED, /* 61 */
    XML_ERR_MISPLACED_CDATA_END, /* 62 */
    XML_ERR_CDATA_NOT_FINISHED, /* 63 */
    XML_ERR_RESERVED_XML_NAME, /* 64 */
    XML_ERR_SPACE_REQUIRED, /* 65 */
    XML_ERR_SEPARATOR_REQUIRED, /* 66 */
    XML_ERR_NMTOKEN_REQUIRED, /* 67 */
    XML_ERR_NAME_REQUIRED, /* 68 */
    XML_ERR_PCDATA_REQUIRED, /* 69 */
    XML_ERR_URI_REQUIRED, /* 70 */
    XML_ERR_PUBID_REQUIRED, /* 71 */
    XML_ERR_LT_REQUIRED, /* 72 */
    XML_ERR_GT_REQUIRED, /* 73 */
    XML_ERR_LTSLASH_REQUIRED, /* 74 */
    XML_ERR_EQUAL_REQUIRED, /* 75 */
    XML_ERR_TAG_NAME_MISMATCH, /* 76 */
    XML_ERR_TAG_NOT_FINISHED, /* 77 */
    XML_ERR_STANDALONE_VALUE, /* 78 */
    XML_ERR_ENCODING_NAME, /* 79 */
    XML_ERR_HYPHEN_IN_COMMENT, /* 80 */
    XML_ERR_INVALID_ENCODING, /* 81 */
    XML_ERR_EXT_ENTITY_STANDALONE, /* 82 */
    XML_ERR_CONDSEC_INVALID, /* 83 */
    XML_ERR_VALUE_REQUIRED, /* 84 */
    XML_ERR_NOT_WELL_BALANCED, /* 85 */
    XML_ERR_EXTRA_CONTENT, /* 86 */
    XML_ERR_ENTITY_CHAR_ERROR, /* 87 */
    XML_ERR_ENTITY_PE_INTERNAL, /* 88 */
    XML_ERR_ENTITY_LOOP, /* 89 */
    XML_ERR_ENTITY_BOUNDARY, /* 90 */
    XML_ERR_INVALID_URI, /* 91 */
    XML_ERR_URI_FRAGMENT, /* 92 */
    XML_WAR_CATALOG_PI, /* 93 */
    XML_ERR_NO_DTD, /* 94 */
    XML_ERR_CONDSEC_INVALID_KEYWORD, /* 95 */
    XML_ERR_VERSION_MISSING, /* 96 */
    XML_WAR_UNKNOWN_VERSION, /* 97 */
    XML_WAR_LANG_VALUE, /* 98 */
    XML_WAR_NS_URI, /* 99 */
    XML_WAR_NS_URI_RELATIVE, /* 100 */
    XML_ERR_MISSING_ENCODING, /* 101 */
    XML_WAR_SPACE_VALUE, /* 102 */
    XML_ERR_NOT_STANDALONE, /* 103 */
    XML_ERR_ENTITY_PROCESSING, /* 104 */
    XML_ERR_NOTATION_PROCESSING, /* 105 */
    XML_WAR_NS_COLUMN, /* 106 */
    XML_WAR_ENTITY_REDEFINED, /* 107 */
    XML_ERR_UNKNOWN_VERSION, /* 108 */
    XML_ERR_VERSION_MISMATCH, /* 109 */
    XML_ERR_NAME_TOO_LONG, /* 110 */
    XML_ERR_USER_STOP, /* 111 */
    XML_ERR_COMMENT_ABRUPTLY_ENDED, /* 112 */
    XML_WAR_ENCODING_MISMATCH, /* 113 */
    /**
     * Internal resource limit like maximum amplification
     * factor exceeded.
     */
    XML_ERR_RESOURCE_LIMIT, /* 114 */
    /** Invalid argument. */
    XML_ERR_ARGUMENT, /* 115 */
    /** Unexpected error from the OS or an external library. */
    XML_ERR_SYSTEM, /* 116 */
    XML_ERR_REDECL_PREDEF_ENTITY, /* 117 */
    XML_ERR_INT_SUBSET_NOT_FINISHED, /* 118 */
    XML_NS_ERR_XML_NAMESPACE = 200,
    XML_NS_ERR_UNDEFINED_NAMESPACE, /* 201 */
    XML_NS_ERR_QNAME, /* 202 */
    XML_NS_ERR_ATTRIBUTE_REDEFINED, /* 203 */
    XML_NS_ERR_EMPTY, /* 204 */
    XML_NS_ERR_COLON, /* 205 */
    XML_DTD_ATTRIBUTE_DEFAULT = 500,
    XML_DTD_ATTRIBUTE_REDEFINED, /* 501 */
    XML_DTD_ATTRIBUTE_VALUE, /* 502 */
    XML_DTD_CONTENT_ERROR, /* 503 */
    XML_DTD_CONTENT_MODEL, /* 504 */
    XML_DTD_CONTENT_NOT_DETERMINIST, /* 505 */
    XML_DTD_DIFFERENT_PREFIX, /* 506 */
    XML_DTD_ELEM_DEFAULT_NAMESPACE, /* 507 */
    XML_DTD_ELEM_NAMESPACE, /* 508 */
    XML_DTD_ELEM_REDEFINED, /* 509 */
    XML_DTD_EMPTY_NOTATION, /* 510 */
    XML_DTD_ENTITY_TYPE, /* 511 */
    XML_DTD_ID_FIXED, /* 512 */
    XML_DTD_ID_REDEFINED, /* 513 */
    XML_DTD_ID_SUBSET, /* 514 */
    XML_DTD_INVALID_CHILD, /* 515 */
    XML_DTD_INVALID_DEFAULT, /* 516 */
    XML_DTD_LOAD_ERROR, /* 517 */
    XML_DTD_MISSING_ATTRIBUTE, /* 518 */
    XML_DTD_MIXED_CORRUPT, /* 519 */
    XML_DTD_MULTIPLE_ID, /* 520 */
    XML_DTD_NO_DOC, /* 521 */
    XML_DTD_NO_DTD, /* 522 */
    XML_DTD_NO_ELEM_NAME, /* 523 */
    XML_DTD_NO_PREFIX, /* 524 */
    XML_DTD_NO_ROOT, /* 525 */
    XML_DTD_NOTATION_REDEFINED, /* 526 */
    XML_DTD_NOTATION_VALUE, /* 527 */
    XML_DTD_NOT_EMPTY, /* 528 */
    XML_DTD_NOT_PCDATA, /* 529 */
    XML_DTD_NOT_STANDALONE, /* 530 */
    XML_DTD_ROOT_NAME, /* 531 */
    XML_DTD_STANDALONE_WHITE_SPACE, /* 532 */
    XML_DTD_UNKNOWN_ATTRIBUTE, /* 533 */
    XML_DTD_UNKNOWN_ELEM, /* 534 */
    XML_DTD_UNKNOWN_ENTITY, /* 535 */
    XML_DTD_UNKNOWN_ID, /* 536 */
    XML_DTD_UNKNOWN_NOTATION, /* 537 */
    XML_DTD_STANDALONE_DEFAULTED, /* 538 */
    XML_DTD_XMLID_VALUE, /* 539 */
    XML_DTD_XMLID_TYPE, /* 540 */
    XML_DTD_DUP_TOKEN, /* 541 */
    XML_HTML_STRUCURE_ERROR = 800,
    XML_HTML_UNKNOWN_TAG, /* 801 */
    XML_HTML_INCORRECTLY_OPENED_COMMENT, /* 802 */
    XML_RNGP_ANYNAME_ATTR_ANCESTOR = 1000,
    XML_RNGP_ATTR_CONFLICT, /* 1001 */
    XML_RNGP_ATTRIBUTE_CHILDREN, /* 1002 */
    XML_RNGP_ATTRIBUTE_CONTENT, /* 1003 */
    XML_RNGP_ATTRIBUTE_EMPTY, /* 1004 */
    XML_RNGP_ATTRIBUTE_NOOP, /* 1005 */
    XML_RNGP_CHOICE_CONTENT, /* 1006 */
    XML_RNGP_CHOICE_EMPTY, /* 1007 */
    XML_RNGP_CREATE_FAILURE, /* 1008 */
    XML_RNGP_DATA_CONTENT, /* 1009 */
    XML_RNGP_DEF_CHOICE_AND_INTERLEAVE, /* 1010 */
    XML_RNGP_DEFINE_CREATE_FAILED, /* 1011 */
    XML_RNGP_DEFINE_EMPTY, /* 1012 */
    XML_RNGP_DEFINE_MISSING, /* 1013 */
    XML_RNGP_DEFINE_NAME_MISSING, /* 1014 */
    XML_RNGP_ELEM_CONTENT_EMPTY, /* 1015 */
    XML_RNGP_ELEM_CONTENT_ERROR, /* 1016 */
    XML_RNGP_ELEMENT_EMPTY, /* 1017 */
    XML_RNGP_ELEMENT_CONTENT, /* 1018 */
    XML_RNGP_ELEMENT_NAME, /* 1019 */
    XML_RNGP_ELEMENT_NO_CONTENT, /* 1020 */
    XML_RNGP_ELEM_TEXT_CONFLICT, /* 1021 */
    XML_RNGP_EMPTY, /* 1022 */
    XML_RNGP_EMPTY_CONSTRUCT, /* 1023 */
    XML_RNGP_EMPTY_CONTENT, /* 1024 */
    XML_RNGP_EMPTY_NOT_EMPTY, /* 1025 */
    XML_RNGP_ERROR_TYPE_LIB, /* 1026 */
    XML_RNGP_EXCEPT_EMPTY, /* 1027 */
    XML_RNGP_EXCEPT_MISSING, /* 1028 */
    XML_RNGP_EXCEPT_MULTIPLE, /* 1029 */
    XML_RNGP_EXCEPT_NO_CONTENT, /* 1030 */
    XML_RNGP_EXTERNALREF_EMTPY, /* 1031 */
    XML_RNGP_EXTERNAL_REF_FAILURE, /* 1032 */
    XML_RNGP_EXTERNALREF_RECURSE, /* 1033 */
    XML_RNGP_FORBIDDEN_ATTRIBUTE, /* 1034 */
    XML_RNGP_FOREIGN_ELEMENT, /* 1035 */
    XML_RNGP_GRAMMAR_CONTENT, /* 1036 */
    XML_RNGP_GRAMMAR_EMPTY, /* 1037 */
    XML_RNGP_GRAMMAR_MISSING, /* 1038 */
    XML_RNGP_GRAMMAR_NO_START, /* 1039 */
    XML_RNGP_GROUP_ATTR_CONFLICT, /* 1040 */
    XML_RNGP_HREF_ERROR, /* 1041 */
    XML_RNGP_INCLUDE_EMPTY, /* 1042 */
    XML_RNGP_INCLUDE_FAILURE, /* 1043 */
    XML_RNGP_INCLUDE_RECURSE, /* 1044 */
    XML_RNGP_INTERLEAVE_ADD, /* 1045 */
    XML_RNGP_INTERLEAVE_CREATE_FAILED, /* 1046 */
    XML_RNGP_INTERLEAVE_EMPTY, /* 1047 */
    XML_RNGP_INTERLEAVE_NO_CONTENT, /* 1048 */
    XML_RNGP_INVALID_DEFINE_NAME, /* 1049 */
    XML_RNGP_INVALID_URI, /* 1050 */
    XML_RNGP_INVALID_VALUE, /* 1051 */
    XML_RNGP_MISSING_HREF, /* 1052 */
    XML_RNGP_NAME_MISSING, /* 1053 */
    XML_RNGP_NEED_COMBINE, /* 1054 */
    XML_RNGP_NOTALLOWED_NOT_EMPTY, /* 1055 */
    XML_RNGP_NSNAME_ATTR_ANCESTOR, /* 1056 */
    XML_RNGP_NSNAME_NO_NS, /* 1057 */
    XML_RNGP_PARAM_FORBIDDEN, /* 1058 */
    XML_RNGP_PARAM_NAME_MISSING, /* 1059 */
    XML_RNGP_PARENTREF_CREATE_FAILED, /* 1060 */
    XML_RNGP_PARENTREF_NAME_INVALID, /* 1061 */
    XML_RNGP_PARENTREF_NO_NAME, /* 1062 */
    XML_RNGP_PARENTREF_NO_PARENT, /* 1063 */
    XML_RNGP_PARENTREF_NOT_EMPTY, /* 1064 */
    XML_RNGP_PARSE_ERROR, /* 1065 */
    XML_RNGP_PAT_ANYNAME_EXCEPT_ANYNAME, /* 1066 */
    XML_RNGP_PAT_ATTR_ATTR, /* 1067 */
    XML_RNGP_PAT_ATTR_ELEM, /* 1068 */
    XML_RNGP_PAT_DATA_EXCEPT_ATTR, /* 1069 */
    XML_RNGP_PAT_DATA_EXCEPT_ELEM, /* 1070 */
    XML_RNGP_PAT_DATA_EXCEPT_EMPTY, /* 1071 */
    XML_RNGP_PAT_DATA_EXCEPT_GROUP, /* 1072 */
    XML_RNGP_PAT_DATA_EXCEPT_INTERLEAVE, /* 1073 */
    XML_RNGP_PAT_DATA_EXCEPT_LIST, /* 1074 */
    XML_RNGP_PAT_DATA_EXCEPT_ONEMORE, /* 1075 */
    XML_RNGP_PAT_DATA_EXCEPT_REF, /* 1076 */
    XML_RNGP_PAT_DATA_EXCEPT_TEXT, /* 1077 */
    XML_RNGP_PAT_LIST_ATTR, /* 1078 */
    XML_RNGP_PAT_LIST_ELEM, /* 1079 */
    XML_RNGP_PAT_LIST_INTERLEAVE, /* 1080 */
    XML_RNGP_PAT_LIST_LIST, /* 1081 */
    XML_RNGP_PAT_LIST_REF, /* 1082 */
    XML_RNGP_PAT_LIST_TEXT, /* 1083 */
    XML_RNGP_PAT_NSNAME_EXCEPT_ANYNAME, /* 1084 */
    XML_RNGP_PAT_NSNAME_EXCEPT_NSNAME, /* 1085 */
    XML_RNGP_PAT_ONEMORE_GROUP_ATTR, /* 1086 */
    XML_RNGP_PAT_ONEMORE_INTERLEAVE_ATTR, /* 1087 */
    XML_RNGP_PAT_START_ATTR, /* 1088 */
    XML_RNGP_PAT_START_DATA, /* 1089 */
    XML_RNGP_PAT_START_EMPTY, /* 1090 */
    XML_RNGP_PAT_START_GROUP, /* 1091 */
    XML_RNGP_PAT_START_INTERLEAVE, /* 1092 */
    XML_RNGP_PAT_START_LIST, /* 1093 */
    XML_RNGP_PAT_START_ONEMORE, /* 1094 */
    XML_RNGP_PAT_START_TEXT, /* 1095 */
    XML_RNGP_PAT_START_VALUE, /* 1096 */
    XML_RNGP_PREFIX_UNDEFINED, /* 1097 */
    XML_RNGP_REF_CREATE_FAILED, /* 1098 */
    XML_RNGP_REF_CYCLE, /* 1099 */
    XML_RNGP_REF_NAME_INVALID, /* 1100 */
    XML_RNGP_REF_NO_DEF, /* 1101 */
    XML_RNGP_REF_NO_NAME, /* 1102 */
    XML_RNGP_REF_NOT_EMPTY, /* 1103 */
    XML_RNGP_START_CHOICE_AND_INTERLEAVE, /* 1104 */
    XML_RNGP_START_CONTENT, /* 1105 */
    XML_RNGP_START_EMPTY, /* 1106 */
    XML_RNGP_START_MISSING, /* 1107 */
    XML_RNGP_TEXT_EXPECTED, /* 1108 */
    XML_RNGP_TEXT_HAS_CHILD, /* 1109 */
    XML_RNGP_TYPE_MISSING, /* 1110 */
    XML_RNGP_TYPE_NOT_FOUND, /* 1111 */
    XML_RNGP_TYPE_VALUE, /* 1112 */
    XML_RNGP_UNKNOWN_ATTRIBUTE, /* 1113 */
    XML_RNGP_UNKNOWN_COMBINE, /* 1114 */
    XML_RNGP_UNKNOWN_CONSTRUCT, /* 1115 */
    XML_RNGP_UNKNOWN_TYPE_LIB, /* 1116 */
    XML_RNGP_URI_FRAGMENT, /* 1117 */
    XML_RNGP_URI_NOT_ABSOLUTE, /* 1118 */
    XML_RNGP_VALUE_EMPTY, /* 1119 */
    XML_RNGP_VALUE_NO_CONTENT, /* 1120 */
    XML_RNGP_XMLNS_NAME, /* 1121 */
    XML_RNGP_XML_NS, /* 1122 */
    XML_XPATH_EXPRESSION_OK = 1200,
    XML_XPATH_NUMBER_ERROR, /* 1201 */
    XML_XPATH_UNFINISHED_LITERAL_ERROR, /* 1202 */
    XML_XPATH_START_LITERAL_ERROR, /* 1203 */
    XML_XPATH_VARIABLE_REF_ERROR, /* 1204 */
    XML_XPATH_UNDEF_VARIABLE_ERROR, /* 1205 */
    XML_XPATH_INVALID_PREDICATE_ERROR, /* 1206 */
    XML_XPATH_EXPR_ERROR, /* 1207 */
    XML_XPATH_UNCLOSED_ERROR, /* 1208 */
    XML_XPATH_UNKNOWN_FUNC_ERROR, /* 1209 */
    XML_XPATH_INVALID_OPERAND, /* 1210 */
    XML_XPATH_INVALID_TYPE, /* 1211 */
    XML_XPATH_INVALID_ARITY, /* 1212 */
    XML_XPATH_INVALID_CTXT_SIZE, /* 1213 */
    XML_XPATH_INVALID_CTXT_POSITION, /* 1214 */
    XML_XPATH_MEMORY_ERROR, /* 1215 */
    XML_XPTR_SYNTAX_ERROR, /* 1216 */
    XML_XPTR_RESOURCE_ERROR, /* 1217 */
    XML_XPTR_SUB_RESOURCE_ERROR, /* 1218 */
    XML_XPATH_UNDEF_PREFIX_ERROR, /* 1219 */
    XML_XPATH_ENCODING_ERROR, /* 1220 */
    XML_XPATH_INVALID_CHAR_ERROR, /* 1221 */
    XML_TREE_INVALID_HEX = 1300,
    XML_TREE_INVALID_DEC, /* 1301 */
    XML_TREE_UNTERMINATED_ENTITY, /* 1302 */
    XML_TREE_NOT_UTF8, /* 1303 */
    XML_SAVE_NOT_UTF8 = 1400,
    XML_SAVE_CHAR_INVALID, /* 1401 */
    XML_SAVE_NO_DOCTYPE, /* 1402 */
    XML_SAVE_UNKNOWN_ENCODING, /* 1403 */
    XML_REGEXP_COMPILE_ERROR = 1450,
    XML_IO_UNKNOWN = 1500,
    XML_IO_EACCES, /* 1501 */
    XML_IO_EAGAIN, /* 1502 */
    XML_IO_EBADF, /* 1503 */
    XML_IO_EBADMSG, /* 1504 */
    XML_IO_EBUSY, /* 1505 */
    XML_IO_ECANCELED, /* 1506 */
    XML_IO_ECHILD, /* 1507 */
    XML_IO_EDEADLK, /* 1508 */
    XML_IO_EDOM, /* 1509 */
    XML_IO_EEXIST, /* 1510 */
    XML_IO_EFAULT, /* 1511 */
    XML_IO_EFBIG, /* 1512 */
    XML_IO_EINPROGRESS, /* 1513 */
    XML_IO_EINTR, /* 1514 */
    XML_IO_EINVAL, /* 1515 */
    XML_IO_EIO, /* 1516 */
    XML_IO_EISDIR, /* 1517 */
    XML_IO_EMFILE, /* 1518 */
    XML_IO_EMLINK, /* 1519 */
    XML_IO_EMSGSIZE, /* 1520 */
    XML_IO_ENAMETOOLONG, /* 1521 */
    XML_IO_ENFILE, /* 1522 */
    XML_IO_ENODEV, /* 1523 */
    /** File not found. */
    XML_IO_ENOENT, /* 1524 */
    XML_IO_ENOEXEC, /* 1525 */
    XML_IO_ENOLCK, /* 1526 */
    XML_IO_ENOMEM, /* 1527 */
    XML_IO_ENOSPC, /* 1528 */
    XML_IO_ENOSYS, /* 1529 */
    XML_IO_ENOTDIR, /* 1530 */
    XML_IO_ENOTEMPTY, /* 1531 */
    XML_IO_ENOTSUP, /* 1532 */
    XML_IO_ENOTTY, /* 1533 */
    XML_IO_ENXIO, /* 1534 */
    XML_IO_EPERM, /* 1535 */
    XML_IO_EPIPE, /* 1536 */
    XML_IO_ERANGE, /* 1537 */
    XML_IO_EROFS, /* 1538 */
    XML_IO_ESPIPE, /* 1539 */
    XML_IO_ESRCH, /* 1540 */
    XML_IO_ETIMEDOUT, /* 1541 */
    XML_IO_EXDEV, /* 1542 */
    XML_IO_NETWORK_ATTEMPT, /* 1543 */
    XML_IO_ENCODER, /* 1544 */
    XML_IO_FLUSH, /* 1545 */
    XML_IO_WRITE, /* 1546 */
    XML_IO_NO_INPUT, /* 1547 */
    XML_IO_BUFFER_FULL, /* 1548 */
    XML_IO_LOAD_ERROR, /* 1549 */
    XML_IO_ENOTSOCK, /* 1550 */
    XML_IO_EISCONN, /* 1551 */
    XML_IO_ECONNREFUSED, /* 1552 */
    XML_IO_ENETUNREACH, /* 1553 */
    XML_IO_EADDRINUSE, /* 1554 */
    XML_IO_EALREADY, /* 1555 */
    XML_IO_EAFNOSUPPORT, /* 1556 */
    XML_IO_UNSUPPORTED_PROTOCOL, /* 1557 */
    XML_XINCLUDE_RECURSION=1600,
    XML_XINCLUDE_PARSE_VALUE, /* 1601 */
    XML_XINCLUDE_ENTITY_DEF_MISMATCH, /* 1602 */
    XML_XINCLUDE_NO_HREF, /* 1603 */
    XML_XINCLUDE_NO_FALLBACK, /* 1604 */
    XML_XINCLUDE_HREF_URI, /* 1605 */
    XML_XINCLUDE_TEXT_FRAGMENT, /* 1606 */
    XML_XINCLUDE_TEXT_DOCUMENT, /* 1607 */
    XML_XINCLUDE_INVALID_CHAR, /* 1608 */
    XML_XINCLUDE_BUILD_FAILED, /* 1609 */
    XML_XINCLUDE_UNKNOWN_ENCODING, /* 1610 */
    XML_XINCLUDE_MULTIPLE_ROOT, /* 1611 */
    XML_XINCLUDE_XPTR_FAILED, /* 1612 */
    XML_XINCLUDE_XPTR_RESULT, /* 1613 */
    XML_XINCLUDE_INCLUDE_IN_INCLUDE, /* 1614 */
    XML_XINCLUDE_FALLBACKS_IN_INCLUDE, /* 1615 */
    XML_XINCLUDE_FALLBACK_NOT_IN_INCLUDE, /* 1616 */
    XML_XINCLUDE_DEPRECATED_NS, /* 1617 */
    XML_XINCLUDE_FRAGMENT_ID, /* 1618 */
    XML_CATALOG_MISSING_ATTR = 1650,
    XML_CATALOG_ENTRY_BROKEN, /* 1651 */
    XML_CATALOG_PREFER_VALUE, /* 1652 */
    XML_CATALOG_NOT_CATALOG, /* 1653 */
    XML_CATALOG_RECURSION, /* 1654 */
    XML_SCHEMAP_PREFIX_UNDEFINED = 1700,
    XML_SCHEMAP_ATTRFORMDEFAULT_VALUE, /* 1701 */
    XML_SCHEMAP_ATTRGRP_NONAME_NOREF, /* 1702 */
    XML_SCHEMAP_ATTR_NONAME_NOREF, /* 1703 */
    XML_SCHEMAP_COMPLEXTYPE_NONAME_NOREF, /* 1704 */
    XML_SCHEMAP_ELEMFORMDEFAULT_VALUE, /* 1705 */
    XML_SCHEMAP_ELEM_NONAME_NOREF, /* 1706 */
    XML_SCHEMAP_EXTENSION_NO_BASE, /* 1707 */
    XML_SCHEMAP_FACET_NO_VALUE, /* 1708 */
    XML_SCHEMAP_FAILED_BUILD_IMPORT, /* 1709 */
    XML_SCHEMAP_GROUP_NONAME_NOREF, /* 1710 */
    XML_SCHEMAP_IMPORT_NAMESPACE_NOT_URI, /* 1711 */
    XML_SCHEMAP_IMPORT_REDEFINE_NSNAME, /* 1712 */
    XML_SCHEMAP_IMPORT_SCHEMA_NOT_URI, /* 1713 */
    XML_SCHEMAP_INVALID_BOOLEAN, /* 1714 */
    XML_SCHEMAP_INVALID_ENUM, /* 1715 */
    XML_SCHEMAP_INVALID_FACET, /* 1716 */
    XML_SCHEMAP_INVALID_FACET_VALUE, /* 1717 */
    XML_SCHEMAP_INVALID_MAXOCCURS, /* 1718 */
    XML_SCHEMAP_INVALID_MINOCCURS, /* 1719 */
    XML_SCHEMAP_INVALID_REF_AND_SUBTYPE, /* 1720 */
    XML_SCHEMAP_INVALID_WHITE_SPACE, /* 1721 */
    XML_SCHEMAP_NOATTR_NOREF, /* 1722 */
    XML_SCHEMAP_NOTATION_NO_NAME, /* 1723 */
    XML_SCHEMAP_NOTYPE_NOREF, /* 1724 */
    XML_SCHEMAP_REF_AND_SUBTYPE, /* 1725 */
    XML_SCHEMAP_RESTRICTION_NONAME_NOREF, /* 1726 */
    XML_SCHEMAP_SIMPLETYPE_NONAME, /* 1727 */
    XML_SCHEMAP_TYPE_AND_SUBTYPE, /* 1728 */
    XML_SCHEMAP_UNKNOWN_ALL_CHILD, /* 1729 */
    XML_SCHEMAP_UNKNOWN_ANYATTRIBUTE_CHILD, /* 1730 */
    XML_SCHEMAP_UNKNOWN_ATTR_CHILD, /* 1731 */
    XML_SCHEMAP_UNKNOWN_ATTRGRP_CHILD, /* 1732 */
    XML_SCHEMAP_UNKNOWN_ATTRIBUTE_GROUP, /* 1733 */
    XML_SCHEMAP_UNKNOWN_BASE_TYPE, /* 1734 */
    XML_SCHEMAP_UNKNOWN_CHOICE_CHILD, /* 1735 */
    XML_SCHEMAP_UNKNOWN_COMPLEXCONTENT_CHILD, /* 1736 */
    XML_SCHEMAP_UNKNOWN_COMPLEXTYPE_CHILD, /* 1737 */
    XML_SCHEMAP_UNKNOWN_ELEM_CHILD, /* 1738 */
    XML_SCHEMAP_UNKNOWN_EXTENSION_CHILD, /* 1739 */
    XML_SCHEMAP_UNKNOWN_FACET_CHILD, /* 1740 */
    XML_SCHEMAP_UNKNOWN_FACET_TYPE, /* 1741 */
    XML_SCHEMAP_UNKNOWN_GROUP_CHILD, /* 1742 */
    XML_SCHEMAP_UNKNOWN_IMPORT_CHILD, /* 1743 */
    XML_SCHEMAP_UNKNOWN_LIST_CHILD, /* 1744 */
    XML_SCHEMAP_UNKNOWN_NOTATION_CHILD, /* 1745 */
    XML_SCHEMAP_UNKNOWN_PROCESSCONTENT_CHILD, /* 1746 */
    XML_SCHEMAP_UNKNOWN_REF, /* 1747 */
    XML_SCHEMAP_UNKNOWN_RESTRICTION_CHILD, /* 1748 */
    XML_SCHEMAP_UNKNOWN_SCHEMAS_CHILD, /* 1749 */
    XML_SCHEMAP_UNKNOWN_SEQUENCE_CHILD, /* 1750 */
    XML_SCHEMAP_UNKNOWN_SIMPLECONTENT_CHILD, /* 1751 */
    XML_SCHEMAP_UNKNOWN_SIMPLETYPE_CHILD, /* 1752 */
    XML_SCHEMAP_UNKNOWN_TYPE, /* 1753 */
    XML_SCHEMAP_UNKNOWN_UNION_CHILD, /* 1754 */
    XML_SCHEMAP_ELEM_DEFAULT_FIXED, /* 1755 */
    XML_SCHEMAP_REGEXP_INVALID, /* 1756 */
    XML_SCHEMAP_FAILED_LOAD, /* 1757 */
    XML_SCHEMAP_NOTHING_TO_PARSE, /* 1758 */
    XML_SCHEMAP_NOROOT, /* 1759 */
    XML_SCHEMAP_REDEFINED_GROUP, /* 1760 */
    XML_SCHEMAP_REDEFINED_TYPE, /* 1761 */
    XML_SCHEMAP_REDEFINED_ELEMENT, /* 1762 */
    XML_SCHEMAP_REDEFINED_ATTRGROUP, /* 1763 */
    XML_SCHEMAP_REDEFINED_ATTR, /* 1764 */
    XML_SCHEMAP_REDEFINED_NOTATION, /* 1765 */
    XML_SCHEMAP_FAILED_PARSE, /* 1766 */
    XML_SCHEMAP_UNKNOWN_PREFIX, /* 1767 */
    XML_SCHEMAP_DEF_AND_PREFIX, /* 1768 */
    XML_SCHEMAP_UNKNOWN_INCLUDE_CHILD, /* 1769 */
    XML_SCHEMAP_INCLUDE_SCHEMA_NOT_URI, /* 1770 */
    XML_SCHEMAP_INCLUDE_SCHEMA_NO_URI, /* 1771 */
    XML_SCHEMAP_NOT_SCHEMA, /* 1772 */
    XML_SCHEMAP_UNKNOWN_MEMBER_TYPE, /* 1773 */
    XML_SCHEMAP_INVALID_ATTR_USE, /* 1774 */
    XML_SCHEMAP_RECURSIVE, /* 1775 */
    XML_SCHEMAP_SUPERNUMEROUS_LIST_ITEM_TYPE, /* 1776 */
    XML_SCHEMAP_INVALID_ATTR_COMBINATION, /* 1777 */
    XML_SCHEMAP_INVALID_ATTR_INLINE_COMBINATION, /* 1778 */
    XML_SCHEMAP_MISSING_SIMPLETYPE_CHILD, /* 1779 */
    XML_SCHEMAP_INVALID_ATTR_NAME, /* 1780 */
    XML_SCHEMAP_REF_AND_CONTENT, /* 1781 */
    XML_SCHEMAP_CT_PROPS_CORRECT_1, /* 1782 */
    XML_SCHEMAP_CT_PROPS_CORRECT_2, /* 1783 */
    XML_SCHEMAP_CT_PROPS_CORRECT_3, /* 1784 */
    XML_SCHEMAP_CT_PROPS_CORRECT_4, /* 1785 */
    XML_SCHEMAP_CT_PROPS_CORRECT_5, /* 1786 */
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, /* 1787 */
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1, /* 1788 */
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2, /* 1789 */
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2, /* 1790 */
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3, /* 1791 */
    XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER, /* 1792 */
    XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE, /* 1793 */
    XML_SCHEMAP_UNION_NOT_EXPRESSIBLE, /* 1794 */
    XML_SCHEMAP_SRC_IMPORT_3_1, /* 1795 */
    XML_SCHEMAP_SRC_IMPORT_3_2, /* 1796 */
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1, /* 1797 */
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2, /* 1798 */
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3, /* 1799 */
    XML_SCHEMAP_COS_CT_EXTENDS_1_3, /* 1800 */
    XML_SCHEMAV_NOROOT = 1801,
    XML_SCHEMAV_UNDECLAREDELEM, /* 1802 */
    XML_SCHEMAV_NOTTOPLEVEL, /* 1803 */
    XML_SCHEMAV_MISSING, /* 1804 */
    XML_SCHEMAV_WRONGELEM, /* 1805 */
    XML_SCHEMAV_NOTYPE, /* 1806 */
    XML_SCHEMAV_NOROLLBACK, /* 1807 */
    XML_SCHEMAV_ISABSTRACT, /* 1808 */
    XML_SCHEMAV_NOTEMPTY, /* 1809 */
    XML_SCHEMAV_ELEMCONT, /* 1810 */
    XML_SCHEMAV_HAVEDEFAULT, /* 1811 */
    XML_SCHEMAV_NOTNILLABLE, /* 1812 */
    XML_SCHEMAV_EXTRACONTENT, /* 1813 */
    XML_SCHEMAV_INVALIDATTR, /* 1814 */
    XML_SCHEMAV_INVALIDELEM, /* 1815 */
    XML_SCHEMAV_NOTDETERMINIST, /* 1816 */
    XML_SCHEMAV_CONSTRUCT, /* 1817 */
    XML_SCHEMAV_INTERNAL, /* 1818 */
    XML_SCHEMAV_NOTSIMPLE, /* 1819 */
    XML_SCHEMAV_ATTRUNKNOWN, /* 1820 */
    XML_SCHEMAV_ATTRINVALID, /* 1821 */
    XML_SCHEMAV_VALUE, /* 1822 */
    XML_SCHEMAV_FACET, /* 1823 */
    XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, /* 1824 */
    XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2, /* 1825 */
    XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3, /* 1826 */
    XML_SCHEMAV_CVC_TYPE_3_1_1, /* 1827 */
    XML_SCHEMAV_CVC_TYPE_3_1_2, /* 1828 */
    XML_SCHEMAV_CVC_FACET_VALID, /* 1829 */
    XML_SCHEMAV_CVC_LENGTH_VALID, /* 1830 */
    XML_SCHEMAV_CVC_MINLENGTH_VALID, /* 1831 */
    XML_SCHEMAV_CVC_MAXLENGTH_VALID, /* 1832 */
    XML_SCHEMAV_CVC_MININCLUSIVE_VALID, /* 1833 */
    XML_SCHEMAV_CVC_MAXINCLUSIVE_VALID, /* 1834 */
    XML_SCHEMAV_CVC_MINEXCLUSIVE_VALID, /* 1835 */
    XML_SCHEMAV_CVC_MAXEXCLUSIVE_VALID, /* 1836 */
    XML_SCHEMAV_CVC_TOTALDIGITS_VALID, /* 1837 */
    XML_SCHEMAV_CVC_FRACTIONDIGITS_VALID, /* 1838 */
    XML_SCHEMAV_CVC_PATTERN_VALID, /* 1839 */
    XML_SCHEMAV_CVC_ENUMERATION_VALID, /* 1840 */
    XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, /* 1841 */
    XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2, /* 1842 */
    XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, /* 1843 */
    XML_SCHEMAV_CVC_COMPLEX_TYPE_2_4, /* 1844 */
    XML_SCHEMAV_CVC_ELT_1, /* 1845 */
    XML_SCHEMAV_CVC_ELT_2, /* 1846 */
    XML_SCHEMAV_CVC_ELT_3_1, /* 1847 */
    XML_SCHEMAV_CVC_ELT_3_2_1, /* 1848 */
    XML_SCHEMAV_CVC_ELT_3_2_2, /* 1849 */
    XML_SCHEMAV_CVC_ELT_4_1, /* 1850 */
    XML_SCHEMAV_CVC_ELT_4_2, /* 1851 */
    XML_SCHEMAV_CVC_ELT_4_3, /* 1852 */
    XML_SCHEMAV_CVC_ELT_5_1_1, /* 1853 */
    XML_SCHEMAV_CVC_ELT_5_1_2, /* 1854 */
    XML_SCHEMAV_CVC_ELT_5_2_1, /* 1855 */
    XML_SCHEMAV_CVC_ELT_5_2_2_1, /* 1856 */
    XML_SCHEMAV_CVC_ELT_5_2_2_2_1, /* 1857 */
    XML_SCHEMAV_CVC_ELT_5_2_2_2_2, /* 1858 */
    XML_SCHEMAV_CVC_ELT_6, /* 1859 */
    XML_SCHEMAV_CVC_ELT_7, /* 1860 */
    XML_SCHEMAV_CVC_ATTRIBUTE_1, /* 1861 */
    XML_SCHEMAV_CVC_ATTRIBUTE_2, /* 1862 */
    XML_SCHEMAV_CVC_ATTRIBUTE_3, /* 1863 */
    XML_SCHEMAV_CVC_ATTRIBUTE_4, /* 1864 */
    XML_SCHEMAV_CVC_COMPLEX_TYPE_3_1, /* 1865 */
    XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, /* 1866 */
    XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, /* 1867 */
    XML_SCHEMAV_CVC_COMPLEX_TYPE_4, /* 1868 */
    XML_SCHEMAV_CVC_COMPLEX_TYPE_5_1, /* 1869 */
    XML_SCHEMAV_CVC_COMPLEX_TYPE_5_2, /* 1870 */
    XML_SCHEMAV_ELEMENT_CONTENT, /* 1871 */
    XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING, /* 1872 */
    XML_SCHEMAV_CVC_COMPLEX_TYPE_1, /* 1873 */
    XML_SCHEMAV_CVC_AU, /* 1874 */
    XML_SCHEMAV_CVC_TYPE_1, /* 1875 */
    XML_SCHEMAV_CVC_TYPE_2, /* 1876 */
    XML_SCHEMAV_CVC_IDC, /* 1877 */
    XML_SCHEMAV_CVC_WILDCARD, /* 1878 */
    XML_SCHEMAV_MISC, /* 1879 */
    XML_XPTR_UNKNOWN_SCHEME = 1900,
    XML_XPTR_CHILDSEQ_START, /* 1901 */
    XML_XPTR_EVAL_FAILED, /* 1902 */
    XML_XPTR_EXTRA_OBJECTS, /* 1903 */
    XML_C14N_CREATE_CTXT = 1950,
    XML_C14N_REQUIRES_UTF8, /* 1951 */
    XML_C14N_CREATE_STACK, /* 1952 */
    XML_C14N_INVALID_NODE, /* 1953 */
    XML_C14N_UNKNOW_NODE, /* 1954 */
    XML_C14N_RELATIVE_NAMESPACE, /* 1955 */
    XML_FTP_PASV_ANSWER = 2000,
    XML_FTP_EPSV_ANSWER, /* 2001 */
    XML_FTP_ACCNT, /* 2002 */
    XML_FTP_URL_SYNTAX, /* 2003 */
    XML_HTTP_URL_SYNTAX = 2020,
    XML_HTTP_USE_IP, /* 2021 */
    XML_HTTP_UNKNOWN_HOST, /* 2022 */
    XML_SCHEMAP_SRC_SIMPLE_TYPE_1 = 3000,
    XML_SCHEMAP_SRC_SIMPLE_TYPE_2, /* 3001 */
    XML_SCHEMAP_SRC_SIMPLE_TYPE_3, /* 3002 */
    XML_SCHEMAP_SRC_SIMPLE_TYPE_4, /* 3003 */
    XML_SCHEMAP_SRC_RESOLVE, /* 3004 */
    XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE, /* 3005 */
    XML_SCHEMAP_SRC_LIST_ITEMTYPE_OR_SIMPLETYPE, /* 3006 */
    XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES, /* 3007 */
    XML_SCHEMAP_ST_PROPS_CORRECT_1, /* 3008 */
    XML_SCHEMAP_ST_PROPS_CORRECT_2, /* 3009 */
    XML_SCHEMAP_ST_PROPS_CORRECT_3, /* 3010 */
    XML_SCHEMAP_COS_ST_RESTRICTS_1_1, /* 3011 */
    XML_SCHEMAP_COS_ST_RESTRICTS_1_2, /* 3012 */
    XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1, /* 3013 */
    XML_SCHEMAP_COS_ST_RESTRICTS_1_3_2, /* 3014 */
    XML_SCHEMAP_COS_ST_RESTRICTS_2_1, /* 3015 */
    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1, /* 3016 */
    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2, /* 3017 */
    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1, /* 3018 */
    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2, /* 3019 */
    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3, /* 3020 */
    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4, /* 3021 */
    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_5, /* 3022 */
    XML_SCHEMAP_COS_ST_RESTRICTS_3_1, /* 3023 */
    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1, /* 3024 */
    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2, /* 3025 */
    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2, /* 3026 */
    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1, /* 3027 */
    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3, /* 3028 */
    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4, /* 3029 */
    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_5, /* 3030 */
    XML_SCHEMAP_COS_ST_DERIVED_OK_2_1, /* 3031 */
    XML_SCHEMAP_COS_ST_DERIVED_OK_2_2, /* 3032 */
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, /* 3033 */
    XML_SCHEMAP_S4S_ELEM_MISSING, /* 3034 */
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, /* 3035 */
    XML_SCHEMAP_S4S_ATTR_MISSING, /* 3036 */
    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, /* 3037 */
    XML_SCHEMAP_SRC_ELEMENT_1, /* 3038 */
    XML_SCHEMAP_SRC_ELEMENT_2_1, /* 3039 */
    XML_SCHEMAP_SRC_ELEMENT_2_2, /* 3040 */
    XML_SCHEMAP_SRC_ELEMENT_3, /* 3041 */
    XML_SCHEMAP_P_PROPS_CORRECT_1, /* 3042 */
    XML_SCHEMAP_P_PROPS_CORRECT_2_1, /* 3043 */
    XML_SCHEMAP_P_PROPS_CORRECT_2_2, /* 3044 */
    XML_SCHEMAP_E_PROPS_CORRECT_2, /* 3045 */
    XML_SCHEMAP_E_PROPS_CORRECT_3, /* 3046 */
    XML_SCHEMAP_E_PROPS_CORRECT_4, /* 3047 */
    XML_SCHEMAP_E_PROPS_CORRECT_5, /* 3048 */
    XML_SCHEMAP_E_PROPS_CORRECT_6, /* 3049 */
    XML_SCHEMAP_SRC_INCLUDE, /* 3050 */
    XML_SCHEMAP_SRC_ATTRIBUTE_1, /* 3051 */
    XML_SCHEMAP_SRC_ATTRIBUTE_2, /* 3052 */
    XML_SCHEMAP_SRC_ATTRIBUTE_3_1, /* 3053 */
    XML_SCHEMAP_SRC_ATTRIBUTE_3_2, /* 3054 */
    XML_SCHEMAP_SRC_ATTRIBUTE_4, /* 3055 */
    XML_SCHEMAP_NO_XMLNS, /* 3056 */
    XML_SCHEMAP_NO_XSI, /* 3057 */
    XML_SCHEMAP_COS_VALID_DEFAULT_1, /* 3058 */
    XML_SCHEMAP_COS_VALID_DEFAULT_2_1, /* 3059 */
    XML_SCHEMAP_COS_VALID_DEFAULT_2_2_1, /* 3060 */
    XML_SCHEMAP_COS_VALID_DEFAULT_2_2_2, /* 3061 */
    XML_SCHEMAP_CVC_SIMPLE_TYPE, /* 3062 */
    XML_SCHEMAP_COS_CT_EXTENDS_1_1, /* 3063 */
    XML_SCHEMAP_SRC_IMPORT_1_1, /* 3064 */
    XML_SCHEMAP_SRC_IMPORT_1_2, /* 3065 */
    XML_SCHEMAP_SRC_IMPORT_2, /* 3066 */
    XML_SCHEMAP_SRC_IMPORT_2_1, /* 3067 */
    XML_SCHEMAP_SRC_IMPORT_2_2, /* 3068 */
    XML_SCHEMAP_INTERNAL, /* 3069 non-W3C */
    XML_SCHEMAP_NOT_DETERMINISTIC, /* 3070 non-W3C */
    XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_1, /* 3071 */
    XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_2, /* 3072 */
    XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3, /* 3073 */
    XML_SCHEMAP_MG_PROPS_CORRECT_1, /* 3074 */
    XML_SCHEMAP_MG_PROPS_CORRECT_2, /* 3075 */
    XML_SCHEMAP_SRC_CT_1, /* 3076 */
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3, /* 3077 */
    XML_SCHEMAP_AU_PROPS_CORRECT_2, /* 3078 */
    XML_SCHEMAP_A_PROPS_CORRECT_2, /* 3079 */
    XML_SCHEMAP_C_PROPS_CORRECT, /* 3080 */
    XML_SCHEMAP_SRC_REDEFINE, /* 3081 */
    XML_SCHEMAP_SRC_IMPORT, /* 3082 */
    XML_SCHEMAP_WARN_SKIP_SCHEMA, /* 3083 */
    XML_SCHEMAP_WARN_UNLOCATED_SCHEMA, /* 3084 */
    XML_SCHEMAP_WARN_ATTR_REDECL_PROH, /* 3085 */
    XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, /* 3085 */
    XML_SCHEMAP_AG_PROPS_CORRECT, /* 3086 */
    XML_SCHEMAP_COS_CT_EXTENDS_1_2, /* 3087 */
    XML_SCHEMAP_AU_PROPS_CORRECT, /* 3088 */
    XML_SCHEMAP_A_PROPS_CORRECT_3, /* 3089 */
    XML_SCHEMAP_COS_ALL_LIMITED, /* 3090 */
    XML_SCHEMATRONV_ASSERT = 4000, /* 4000 */
    XML_SCHEMATRONV_REPORT,
    XML_MODULE_OPEN = 4900, /* 4900 */
    XML_MODULE_CLOSE, /* 4901 */
    XML_CHECK_FOUND_ELEMENT = 5000,
    XML_CHECK_FOUND_ATTRIBUTE, /* 5001 */
    XML_CHECK_FOUND_TEXT, /* 5002 */
    XML_CHECK_FOUND_CDATA, /* 5003 */
    XML_CHECK_FOUND_ENTITYREF, /* 5004 */
    XML_CHECK_FOUND_ENTITY, /* 5005 */
    XML_CHECK_FOUND_PI, /* 5006 */
    XML_CHECK_FOUND_COMMENT, /* 5007 */
    XML_CHECK_FOUND_DOCTYPE, /* 5008 */
    XML_CHECK_FOUND_FRAGMENT, /* 5009 */
    XML_CHECK_FOUND_NOTATION, /* 5010 */
    XML_CHECK_UNKNOWN_NODE, /* 5011 */
    XML_CHECK_ENTITY_TYPE, /* 5012 */
    XML_CHECK_NO_PARENT, /* 5013 */
    XML_CHECK_NO_DOC, /* 5014 */
    XML_CHECK_NO_NAME, /* 5015 */
    XML_CHECK_NO_ELEM, /* 5016 */
    XML_CHECK_WRONG_DOC, /* 5017 */
    XML_CHECK_NO_PREV, /* 5018 */
    XML_CHECK_WRONG_PREV, /* 5019 */
    XML_CHECK_NO_NEXT, /* 5020 */
    XML_CHECK_WRONG_NEXT, /* 5021 */
    XML_CHECK_NOT_DTD, /* 5022 */
    XML_CHECK_NOT_ATTR, /* 5023 */
    XML_CHECK_NOT_ATTR_DECL, /* 5024 */
    XML_CHECK_NOT_ELEM_DECL, /* 5025 */
    XML_CHECK_NOT_ENTITY_DECL, /* 5026 */
    XML_CHECK_NOT_NS_DECL, /* 5027 */
    XML_CHECK_NO_HREF, /* 5028 */
    XML_CHECK_WRONG_PARENT,/* 5029 */
    XML_CHECK_NS_SCOPE, /* 5030 */
    XML_CHECK_NS_ANCESTOR, /* 5031 */
    XML_CHECK_NOT_UTF8, /* 5032 */
    XML_CHECK_NO_DICT, /* 5033 */
    XML_CHECK_NOT_NCNAME, /* 5034 */
    XML_CHECK_OUTSIDE_DICT, /* 5035 */
    XML_CHECK_WRONG_NAME, /* 5036 */
    XML_CHECK_NAME_NOT_NULL, /* 5037 */
    XML_I18N_NO_NAME = 6000,
    XML_I18N_NO_HANDLER, /* 6001 */
    XML_I18N_EXCESS_HANDLER, /* 6002 */
    XML_I18N_CONV_FAILED, /* 6003 */
    XML_I18N_NO_OUTPUT, /* 6004 */
    XML_BUF_OVERFLOW = 7000
} xmlParserErrors;

/**
 * Generic error callback.
 *
 * @deprecated in favor of structured errors.
 * @param ctx  user data
 * @param msg  printf-like format string
 * @param ...  arguments to format
 */
typedef void (*xmlGenericErrorFunc) (void *ctx,
				 const char *msg,
				 ...) LIBXML_ATTR_FORMAT(2,3);
/**
 * Structured error callback receiving an xmlError.
 *
 * @param userData  user provided data for the error callback
 * @param error  the error being raised
 */
typedef void (*xmlStructuredErrorFunc) (void *userData, const xmlError *error);

/** @cond ignore */
XML_DEPRECATED
XMLPUBFUN const xmlError *__xmlLastError(void);
XMLPUBFUN xmlGenericErrorFunc *__xmlGenericError(void);
XMLPUBFUN void **__xmlGenericErrorContext(void);
XMLPUBFUN xmlStructuredErrorFunc *__xmlStructuredError(void);
XMLPUBFUN void **__xmlStructuredErrorContext(void);
/** @endcond */

#ifndef XML_GLOBALS_NO_REDEFINITION
  /**
   * Thread-local variable containing the last reported error.
   *
   * @deprecated Use xmlGetLastError().
   */
  #define xmlLastError (*__xmlLastError())
  /**
   * Thread-local variable containing the generic error callback.
   *
   * @deprecated See xmlSetStructuredErrorFunc().
   */
  #define xmlGenericError (*__xmlGenericError())
  /**
   * Thread-local variable containing user data for the generic
   * error handler.
   *
   * @deprecated See xmlSetStructuredErrorFunc().
   */
  #define xmlGenericErrorContext (*__xmlGenericErrorContext())
  /**
   * Thread-local variable containing the structured error
   * callback.
   *
   * @deprecated See xmlSetStructuredErrorFunc().
   */
  #define xmlStructuredError (*__xmlStructuredError())
  /**
   * Thread-local variable containing user data for the
   * structured error handler.
   *
   * @deprecated See xmlSetStructuredErrorFunc().
   */
  #define xmlStructuredErrorContext (*__xmlStructuredErrorContext())
#endif

XMLPUBFUN void
    xmlSetGenericErrorFunc	(void *ctx,
				 xmlGenericErrorFunc handler);
XMLPUBFUN void
    xmlSetStructuredErrorFunc	(void *ctx,
				 xmlStructuredErrorFunc handler);

XML_DEPRECATED
XMLPUBFUN void
    xmlThrDefSetGenericErrorFunc(void *ctx,
                                 xmlGenericErrorFunc handler);
XML_DEPRECATED
XMLPUBFUN void
    xmlThrDefSetStructuredErrorFunc(void *ctx,
                                 xmlStructuredErrorFunc handler);

/*
 * Legacy error handlers.
 */
XMLPUBFUN void
    xmlParserError		(void *ctx,
				 const char *msg,
				 ...) LIBXML_ATTR_FORMAT(2,3);
XMLPUBFUN void
    xmlParserWarning		(void *ctx,
				 const char *msg,
				 ...) LIBXML_ATTR_FORMAT(2,3);
XMLPUBFUN void
    xmlParserValidityError	(void *ctx,
				 const char *msg,
				 ...) LIBXML_ATTR_FORMAT(2,3);
XMLPUBFUN void
    xmlParserValidityWarning	(void *ctx,
				 const char *msg,
				 ...) LIBXML_ATTR_FORMAT(2,3);
struct _xmlParserInput;
XMLPUBFUN void
    xmlParserPrintFileInfo	(struct _xmlParserInput *input);
XMLPUBFUN void
    xmlParserPrintFileContext	(struct _xmlParserInput *input);
XMLPUBFUN void
xmlFormatError			(const xmlError *err,
				 xmlGenericErrorFunc channel,
				 void *data);

/*
 * Extended error information routines
 */
XMLPUBFUN const xmlError *
    xmlGetLastError		(void);
XMLPUBFUN void
    xmlResetLastError		(void);
XMLPUBFUN const xmlError *
    xmlCtxtGetLastError		(void *ctx);
XMLPUBFUN void
    xmlCtxtResetLastError	(void *ctx);
XMLPUBFUN void
    xmlResetError		(xmlError *err);
XMLPUBFUN int
    xmlCopyError		(const xmlError *from,
				 xmlError *to);

#ifdef __cplusplus
}
#endif
#endif /* __XML_ERROR_H__ */
libxml2/libxml/xpathInternals.h000064400000042560151733237440012601 0ustar00/**
 * @file
 * 
 * @brief internal interfaces for XML Path Language implementation
 * 
 * internal interfaces for XML Path Language implementation
 *              used to build new modules on top of XPath like XPointer and
 *              XSLT
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */

#ifndef __XML_XPATH_INTERNALS_H__
#define __XML_XPATH_INTERNALS_H__

#include <stdio.h>
#include <libxml/xmlversion.h>
#include <libxml/xpath.h>

#ifdef LIBXML_XPATH_ENABLED

#ifdef __cplusplus
extern "C" {
#endif

/**
 * Push a value on the stack
 *
 * @deprecated Use #xmlXPathValuePush
 */
#define valuePush xmlXPathValuePush
/**
 * Pop a value from the stack
 *
 * @deprecated Use #xmlXPathValuePop
 */
#define valuePop xmlXPathValuePop

/************************************************************************
 *									*
 *			Helpers						*
 *									*
 ************************************************************************/

/*
 * Many of these macros may later turn into functions. They
 * shouldn't be used in \#ifdef's preprocessor instructions.
 */
/**
 * Raises an error.
 *
 * @param ctxt  an XPath parser context
 * @param err  an xmlXPathError code
 */
#define xmlXPathSetError(ctxt, err)					\
    { xmlXPatherror((ctxt), __FILE__, __LINE__, (err));			\
      if ((ctxt) != NULL) (ctxt)->error = (err); }

/**
 * Raises an XPATH_INVALID_ARITY error.
 *
 * @param ctxt  an XPath parser context
 */
#define xmlXPathSetArityError(ctxt)					\
    xmlXPathSetError((ctxt), XPATH_INVALID_ARITY)

/**
 * Raises an XPATH_INVALID_TYPE error.
 *
 * @param ctxt  an XPath parser context
 */
#define xmlXPathSetTypeError(ctxt)					\
    xmlXPathSetError((ctxt), XPATH_INVALID_TYPE)

/**
 * Get the error code of an XPath context.
 *
 * @param ctxt  an XPath parser context
 * @returns the context error.
 */
#define xmlXPathGetError(ctxt)	  ((ctxt)->error)

/**
 * Check if an XPath error was raised.
 *
 * @param ctxt  an XPath parser context
 * @returns true if an error has been raised, false otherwise.
 */
#define xmlXPathCheckError(ctxt)  ((ctxt)->error != XPATH_EXPRESSION_OK)

/**
 * Get the document of an XPath context.
 *
 * @param ctxt  an XPath parser context
 * @returns the context document.
 */
#define xmlXPathGetDocument(ctxt)	((ctxt)->context->doc)

/**
 * Get the context node of an XPath context.
 *
 * @param ctxt  an XPath parser context
 * @returns the context node.
 */
#define xmlXPathGetContextNode(ctxt)	((ctxt)->context->node)

XMLPUBFUN int
		xmlXPathPopBoolean	(xmlXPathParserContext *ctxt);
XMLPUBFUN double
		xmlXPathPopNumber	(xmlXPathParserContext *ctxt);
XMLPUBFUN xmlChar *
		xmlXPathPopString	(xmlXPathParserContext *ctxt);
XMLPUBFUN xmlNodeSet *
		xmlXPathPopNodeSet	(xmlXPathParserContext *ctxt);
XMLPUBFUN void *
		xmlXPathPopExternal	(xmlXPathParserContext *ctxt);

/**
 * Pushes the boolean `val` on the context stack.
 *
 * @param ctxt  an XPath parser context
 * @param val  a boolean
 */
#define xmlXPathReturnBoolean(ctxt, val)				\
    valuePush((ctxt), xmlXPathNewBoolean(val))

/**
 * Pushes true on the context stack.
 *
 * @param ctxt  an XPath parser context
 */
#define xmlXPathReturnTrue(ctxt)   xmlXPathReturnBoolean((ctxt), 1)

/**
 * Pushes false on the context stack.
 *
 * @param ctxt  an XPath parser context
 */
#define xmlXPathReturnFalse(ctxt)  xmlXPathReturnBoolean((ctxt), 0)

/**
 * Pushes the double `val` on the context stack.
 *
 * @param ctxt  an XPath parser context
 * @param val  a double
 */
#define xmlXPathReturnNumber(ctxt, val)					\
    valuePush((ctxt), xmlXPathNewFloat(val))

/**
 * Pushes the string `str` on the context stack.
 *
 * @param ctxt  an XPath parser context
 * @param str  a string
 */
#define xmlXPathReturnString(ctxt, str)					\
    valuePush((ctxt), xmlXPathWrapString(str))

/**
 * Pushes an empty string on the stack.
 *
 * @param ctxt  an XPath parser context
 */
#define xmlXPathReturnEmptyString(ctxt)					\
    valuePush((ctxt), xmlXPathNewCString(""))

/**
 * Pushes the node-set `ns` on the context stack.
 *
 * @param ctxt  an XPath parser context
 * @param ns  a node-set
 */
#define xmlXPathReturnNodeSet(ctxt, ns)					\
    valuePush((ctxt), xmlXPathWrapNodeSet(ns))

/**
 * Pushes an empty node-set on the context stack.
 *
 * @param ctxt  an XPath parser context
 */
#define xmlXPathReturnEmptyNodeSet(ctxt)				\
    valuePush((ctxt), xmlXPathNewNodeSet(NULL))

/**
 * Pushes user data on the context stack.
 *
 * @param ctxt  an XPath parser context
 * @param val  user data
 */
#define xmlXPathReturnExternal(ctxt, val)				\
    valuePush((ctxt), xmlXPathWrapExternal(val))

/**
 * Check if the current value on the XPath stack is a node set or
 * an XSLT value tree.
 *
 * @param ctxt  an XPath parser context
 * @returns true if the current object on the stack is a node-set.
 */
#define xmlXPathStackIsNodeSet(ctxt)					\
    (((ctxt)->value != NULL)						\
     && (((ctxt)->value->type == XPATH_NODESET)				\
         || ((ctxt)->value->type == XPATH_XSLT_TREE)))

/**
 * Checks if the current value on the XPath stack is an external
 * object.
 *
 * @param ctxt  an XPath parser context
 * @returns true if the current object on the stack is an external
 * object.
 */
#define xmlXPathStackIsExternal(ctxt)					\
	((ctxt->value != NULL) && (ctxt->value->type == XPATH_USERS))

/**
 * Empties a node-set.
 *
 * @param ns  a node-set
 */
#define xmlXPathEmptyNodeSet(ns)					\
    { while ((ns)->nodeNr > 0) (ns)->nodeTab[--(ns)->nodeNr] = NULL; }

/**
 * Macro to return from the function if an XPath error was detected.
 */
#define CHECK_ERROR							\
    if (ctxt->error != XPATH_EXPRESSION_OK) return

/**
 * Macro to return 0 from the function if an XPath error was detected.
 */
#define CHECK_ERROR0							\
    if (ctxt->error != XPATH_EXPRESSION_OK) return(0)

/**
 * Macro to raise an XPath error and return.
 *
 * @param X  the error code
 */
#define XP_ERROR(X)							\
    { xmlXPathErr(ctxt, X); return; }

/**
 * Macro to raise an XPath error and return 0.
 *
 * @param X  the error code
 */
#define XP_ERROR0(X)							\
    { xmlXPathErr(ctxt, X); return(0); }

/**
 * Macro to check that the value on top of the XPath stack is of a given
 * type.
 *
 * @param typeval  the XPath type
 */
#define CHECK_TYPE(typeval)						\
    if ((ctxt->value == NULL) || (ctxt->value->type != typeval))	\
        XP_ERROR(XPATH_INVALID_TYPE)

/**
 * Macro to check that the value on top of the XPath stack is of a given
 * type. Return(0) in case of failure
 *
 * @param typeval  the XPath type
 */
#define CHECK_TYPE0(typeval)						\
    if ((ctxt->value == NULL) || (ctxt->value->type != typeval))	\
        XP_ERROR0(XPATH_INVALID_TYPE)

/**
 * Macro to check that the number of args passed to an XPath function matches.
 *
 * @param x  the number of expected args
 */
#define CHECK_ARITY(x)							\
    if (ctxt == NULL) return;						\
    if (nargs != (x))							\
        XP_ERROR(XPATH_INVALID_ARITY);					\
    if (ctxt->valueNr < (x))						\
        XP_ERROR(XPATH_STACK_ERROR);

/**
 * Macro to try to cast the value on the top of the XPath stack to a string.
 */
#define CAST_TO_STRING							\
    if ((ctxt->value != NULL) && (ctxt->value->type != XPATH_STRING))	\
        xmlXPathStringFunction(ctxt, 1);

/**
 * Macro to try to cast the value on the top of the XPath stack to a number.
 */
#define CAST_TO_NUMBER							\
    if ((ctxt->value != NULL) && (ctxt->value->type != XPATH_NUMBER))	\
        xmlXPathNumberFunction(ctxt, 1);

/**
 * Macro to try to cast the value on the top of the XPath stack to a boolean.
 */
#define CAST_TO_BOOLEAN							\
    if ((ctxt->value != NULL) && (ctxt->value->type != XPATH_BOOLEAN))	\
        xmlXPathBooleanFunction(ctxt, 1);

/*
 * Variable Lookup forwarding.
 */

XMLPUBFUN void
	xmlXPathRegisterVariableLookup	(xmlXPathContext *ctxt,
					 xmlXPathVariableLookupFunc f,
					 void *data);

/*
 * Function Lookup forwarding.
 */

XMLPUBFUN void
	    xmlXPathRegisterFuncLookup	(xmlXPathContext *ctxt,
					 xmlXPathFuncLookupFunc f,
					 void *funcCtxt);

/*
 * Error reporting.
 */
XMLPUBFUN void
		xmlXPatherror	(xmlXPathParserContext *ctxt,
				 const char *file,
				 int line,
				 int no);

XMLPUBFUN void
		xmlXPathErr	(xmlXPathParserContext *ctxt,
				 int error);

#ifdef LIBXML_DEBUG_ENABLED
XMLPUBFUN void
		xmlXPathDebugDumpObject	(FILE *output,
					 xmlXPathObject *cur,
					 int depth);
XMLPUBFUN void
	    xmlXPathDebugDumpCompExpr(FILE *output,
					 xmlXPathCompExpr *comp,
					 int depth);
#endif
/**
 * NodeSet handling.
 */
XMLPUBFUN int
		xmlXPathNodeSetContains		(xmlNodeSet *cur,
						 xmlNode *val);
XMLPUBFUN xmlNodeSet *
		xmlXPathDifference		(xmlNodeSet *nodes1,
						 xmlNodeSet *nodes2);
XMLPUBFUN xmlNodeSet *
		xmlXPathIntersection		(xmlNodeSet *nodes1,
						 xmlNodeSet *nodes2);

XMLPUBFUN xmlNodeSet *
		xmlXPathDistinctSorted		(xmlNodeSet *nodes);
XMLPUBFUN xmlNodeSet *
		xmlXPathDistinct		(xmlNodeSet *nodes);

XMLPUBFUN int
		xmlXPathHasSameNodes		(xmlNodeSet *nodes1,
						 xmlNodeSet *nodes2);

XMLPUBFUN xmlNodeSet *
		xmlXPathNodeLeadingSorted	(xmlNodeSet *nodes,
						 xmlNode *node);
XMLPUBFUN xmlNodeSet *
		xmlXPathLeadingSorted		(xmlNodeSet *nodes1,
						 xmlNodeSet *nodes2);
XMLPUBFUN xmlNodeSet *
		xmlXPathNodeLeading		(xmlNodeSet *nodes,
						 xmlNode *node);
XMLPUBFUN xmlNodeSet *
		xmlXPathLeading			(xmlNodeSet *nodes1,
						 xmlNodeSet *nodes2);

XMLPUBFUN xmlNodeSet *
		xmlXPathNodeTrailingSorted	(xmlNodeSet *nodes,
						 xmlNode *node);
XMLPUBFUN xmlNodeSet *
		xmlXPathTrailingSorted		(xmlNodeSet *nodes1,
						 xmlNodeSet *nodes2);
XMLPUBFUN xmlNodeSet *
		xmlXPathNodeTrailing		(xmlNodeSet *nodes,
						 xmlNode *node);
XMLPUBFUN xmlNodeSet *
		xmlXPathTrailing		(xmlNodeSet *nodes1,
						 xmlNodeSet *nodes2);


/**
 * Extending a context.
 */

XMLPUBFUN int
		xmlXPathRegisterNs		(xmlXPathContext *ctxt,
						 const xmlChar *prefix,
						 const xmlChar *ns_uri);
XMLPUBFUN const xmlChar *
		xmlXPathNsLookup		(xmlXPathContext *ctxt,
						 const xmlChar *prefix);
XMLPUBFUN void
		xmlXPathRegisteredNsCleanup	(xmlXPathContext *ctxt);

XMLPUBFUN int
		xmlXPathRegisterFunc		(xmlXPathContext *ctxt,
						 const xmlChar *name,
						 xmlXPathFunction f);
XMLPUBFUN int
		xmlXPathRegisterFuncNS		(xmlXPathContext *ctxt,
						 const xmlChar *name,
						 const xmlChar *ns_uri,
						 xmlXPathFunction f);
XMLPUBFUN int
		xmlXPathRegisterVariable	(xmlXPathContext *ctxt,
						 const xmlChar *name,
						 xmlXPathObject *value);
XMLPUBFUN int
		xmlXPathRegisterVariableNS	(xmlXPathContext *ctxt,
						 const xmlChar *name,
						 const xmlChar *ns_uri,
						 xmlXPathObject *value);
XMLPUBFUN xmlXPathFunction
		xmlXPathFunctionLookup		(xmlXPathContext *ctxt,
						 const xmlChar *name);
XMLPUBFUN xmlXPathFunction
		xmlXPathFunctionLookupNS	(xmlXPathContext *ctxt,
						 const xmlChar *name,
						 const xmlChar *ns_uri);
XMLPUBFUN void
		xmlXPathRegisteredFuncsCleanup	(xmlXPathContext *ctxt);
XMLPUBFUN xmlXPathObject *
		xmlXPathVariableLookup		(xmlXPathContext *ctxt,
						 const xmlChar *name);
XMLPUBFUN xmlXPathObject *
		xmlXPathVariableLookupNS	(xmlXPathContext *ctxt,
						 const xmlChar *name,
						 const xmlChar *ns_uri);
XMLPUBFUN void
		xmlXPathRegisteredVariablesCleanup(xmlXPathContext *ctxt);

/**
 * Utilities to extend XPath.
 */
XMLPUBFUN xmlXPathParserContext *
		  xmlXPathNewParserContext	(const xmlChar *str,
						 xmlXPathContext *ctxt);
XMLPUBFUN void
		xmlXPathFreeParserContext	(xmlXPathParserContext *ctxt);

XMLPUBFUN xmlXPathObject *
		xmlXPathValuePop		(xmlXPathParserContext *ctxt);
XMLPUBFUN int
		xmlXPathValuePush		(xmlXPathParserContext *ctxt,
						 xmlXPathObject *value);

XMLPUBFUN xmlXPathObject *
		xmlXPathNewString		(const xmlChar *val);
XMLPUBFUN xmlXPathObject *
		xmlXPathNewCString		(const char *val);
XMLPUBFUN xmlXPathObject *
		xmlXPathWrapString		(xmlChar *val);
XMLPUBFUN xmlXPathObject *
		xmlXPathWrapCString		(char * val);
XMLPUBFUN xmlXPathObject *
		xmlXPathNewFloat		(double val);
XMLPUBFUN xmlXPathObject *
		xmlXPathNewBoolean		(int val);
XMLPUBFUN xmlXPathObject *
		xmlXPathNewNodeSet		(xmlNode *val);
XMLPUBFUN xmlXPathObject *
		xmlXPathNewValueTree		(xmlNode *val);
XMLPUBFUN int
		xmlXPathNodeSetAdd		(xmlNodeSet *cur,
						 xmlNode *val);
XMLPUBFUN int
		xmlXPathNodeSetAddUnique	(xmlNodeSet *cur,
						 xmlNode *val);
XMLPUBFUN int
		xmlXPathNodeSetAddNs		(xmlNodeSet *cur,
						 xmlNode *node,
						 xmlNs *ns);
XMLPUBFUN void
		xmlXPathNodeSetSort		(xmlNodeSet *set);

XMLPUBFUN void
		xmlXPathRoot			(xmlXPathParserContext *ctxt);
XML_DEPRECATED
XMLPUBFUN void
		xmlXPathEvalExpr		(xmlXPathParserContext *ctxt);
XMLPUBFUN xmlChar *
		xmlXPathParseName		(xmlXPathParserContext *ctxt);
XMLPUBFUN xmlChar *
		xmlXPathParseNCName		(xmlXPathParserContext *ctxt);

/*
 * Existing functions.
 */
XMLPUBFUN double
		xmlXPathStringEvalNumber	(const xmlChar *str);
XMLPUBFUN int
		xmlXPathEvaluatePredicateResult (xmlXPathParserContext *ctxt,
						 xmlXPathObject *res);
XMLPUBFUN void
		xmlXPathRegisterAllFunctions	(xmlXPathContext *ctxt);
XMLPUBFUN xmlNodeSet *
		xmlXPathNodeSetMerge		(xmlNodeSet *val1,
						 xmlNodeSet *val2);
XMLPUBFUN void
		xmlXPathNodeSetDel		(xmlNodeSet *cur,
						 xmlNode *val);
XMLPUBFUN void
		xmlXPathNodeSetRemove		(xmlNodeSet *cur,
						 int val);
XMLPUBFUN xmlXPathObject *
		xmlXPathNewNodeSetList		(xmlNodeSet *val);
XMLPUBFUN xmlXPathObject *
		xmlXPathWrapNodeSet		(xmlNodeSet *val);
XMLPUBFUN xmlXPathObject *
		xmlXPathWrapExternal		(void *val);

XMLPUBFUN int xmlXPathEqualValues(xmlXPathParserContext *ctxt);
XMLPUBFUN int xmlXPathNotEqualValues(xmlXPathParserContext *ctxt);
XMLPUBFUN int xmlXPathCompareValues(xmlXPathParserContext *ctxt, int inf, int strict);
XMLPUBFUN void xmlXPathValueFlipSign(xmlXPathParserContext *ctxt);
XMLPUBFUN void xmlXPathAddValues(xmlXPathParserContext *ctxt);
XMLPUBFUN void xmlXPathSubValues(xmlXPathParserContext *ctxt);
XMLPUBFUN void xmlXPathMultValues(xmlXPathParserContext *ctxt);
XMLPUBFUN void xmlXPathDivValues(xmlXPathParserContext *ctxt);
XMLPUBFUN void xmlXPathModValues(xmlXPathParserContext *ctxt);

XMLPUBFUN int xmlXPathIsNodeType(const xmlChar *name);

/*
 * Some of the axis navigation routines.
 */
XMLPUBFUN xmlNode *xmlXPathNextSelf(xmlXPathParserContext *ctxt,
			xmlNode *cur);
XMLPUBFUN xmlNode *xmlXPathNextChild(xmlXPathParserContext *ctxt,
			xmlNode *cur);
XMLPUBFUN xmlNode *xmlXPathNextDescendant(xmlXPathParserContext *ctxt,
			xmlNode *cur);
XMLPUBFUN xmlNode *xmlXPathNextDescendantOrSelf(xmlXPathParserContext *ctxt,
			xmlNode *cur);
XMLPUBFUN xmlNode *xmlXPathNextParent(xmlXPathParserContext *ctxt,
			xmlNode *cur);
XMLPUBFUN xmlNode *xmlXPathNextAncestorOrSelf(xmlXPathParserContext *ctxt,
			xmlNode *cur);
XMLPUBFUN xmlNode *xmlXPathNextFollowingSibling(xmlXPathParserContext *ctxt,
			xmlNode *cur);
XMLPUBFUN xmlNode *xmlXPathNextFollowing(xmlXPathParserContext *ctxt,
			xmlNode *cur);
XMLPUBFUN xmlNode *xmlXPathNextNamespace(xmlXPathParserContext *ctxt,
			xmlNode *cur);
XMLPUBFUN xmlNode *xmlXPathNextAttribute(xmlXPathParserContext *ctxt,
			xmlNode *cur);
XMLPUBFUN xmlNode *xmlXPathNextPreceding(xmlXPathParserContext *ctxt,
			xmlNode *cur);
XMLPUBFUN xmlNode *xmlXPathNextAncestor(xmlXPathParserContext *ctxt,
			xmlNode *cur);
XMLPUBFUN xmlNode *xmlXPathNextPrecedingSibling(xmlXPathParserContext *ctxt,
			xmlNode *cur);
/*
 * The official core of XPath functions.
 */
XMLPUBFUN void xmlXPathLastFunction(xmlXPathParserContext *ctxt, int nargs);
XMLPUBFUN void xmlXPathPositionFunction(xmlXPathParserContext *ctxt, int nargs);
XMLPUBFUN void xmlXPathCountFunction(xmlXPathParserContext *ctxt, int nargs);
XMLPUBFUN void xmlXPathIdFunction(xmlXPathParserContext *ctxt, int nargs);
XMLPUBFUN void xmlXPathLocalNameFunction(xmlXPathParserContext *ctxt, int nargs);
XMLPUBFUN void xmlXPathNamespaceURIFunction(xmlXPathParserContext *ctxt, int nargs);
XMLPUBFUN void xmlXPathStringFunction(xmlXPathParserContext *ctxt, int nargs);
XMLPUBFUN void xmlXPathStringLengthFunction(xmlXPathParserContext *ctxt, int nargs);
XMLPUBFUN void xmlXPathConcatFunction(xmlXPathParserContext *ctxt, int nargs);
XMLPUBFUN void xmlXPathContainsFunction(xmlXPathParserContext *ctxt, int nargs);
XMLPUBFUN void xmlXPathStartsWithFunction(xmlXPathParserContext *ctxt, int nargs);
XMLPUBFUN void xmlXPathSubstringFunction(xmlXPathParserContext *ctxt, int nargs);
XMLPUBFUN void xmlXPathSubstringBeforeFunction(xmlXPathParserContext *ctxt, int nargs);
XMLPUBFUN void xmlXPathSubstringAfterFunction(xmlXPathParserContext *ctxt, int nargs);
XMLPUBFUN void xmlXPathNormalizeFunction(xmlXPathParserContext *ctxt, int nargs);
XMLPUBFUN void xmlXPathTranslateFunction(xmlXPathParserContext *ctxt, int nargs);
XMLPUBFUN void xmlXPathNotFunction(xmlXPathParserContext *ctxt, int nargs);
XMLPUBFUN void xmlXPathTrueFunction(xmlXPathParserContext *ctxt, int nargs);
XMLPUBFUN void xmlXPathFalseFunction(xmlXPathParserContext *ctxt, int nargs);
XMLPUBFUN void xmlXPathLangFunction(xmlXPathParserContext *ctxt, int nargs);
XMLPUBFUN void xmlXPathNumberFunction(xmlXPathParserContext *ctxt, int nargs);
XMLPUBFUN void xmlXPathSumFunction(xmlXPathParserContext *ctxt, int nargs);
XMLPUBFUN void xmlXPathFloorFunction(xmlXPathParserContext *ctxt, int nargs);
XMLPUBFUN void xmlXPathCeilingFunction(xmlXPathParserContext *ctxt, int nargs);
XMLPUBFUN void xmlXPathRoundFunction(xmlXPathParserContext *ctxt, int nargs);
XMLPUBFUN void xmlXPathBooleanFunction(xmlXPathParserContext *ctxt, int nargs);

/**
 * Really internal functions
 */
XMLPUBFUN void xmlXPathNodeSetFreeNs(xmlNs *ns);

#ifdef __cplusplus
}
#endif

#endif /* LIBXML_XPATH_ENABLED */
#endif /* ! __XML_XPATH_INTERNALS_H__ */
libxml2/libxml/xmlreader.h000064400000030363151733237440011556 0ustar00/**
 * @file
 * 
 * @brief the XMLReader implementation
 * 
 * API of the XML streaming API based on C\# interfaces.
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */

#ifndef __XML_XMLREADER_H__
#define __XML_XMLREADER_H__

#include <libxml/xmlversion.h>
#include <libxml/tree.h>
#include <libxml/xmlerror.h>
#include <libxml/xmlIO.h>
#ifdef LIBXML_RELAXNG_ENABLED
#include <libxml/relaxng.h>
#endif
#ifdef LIBXML_SCHEMAS_ENABLED
#include <libxml/xmlschemas.h>
#endif
#include <libxml/parser.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * How severe an error callback is when the per-reader error callback API
 * is used.
 */
typedef enum {
    XML_PARSER_SEVERITY_VALIDITY_WARNING = 1,
    XML_PARSER_SEVERITY_VALIDITY_ERROR = 2,
    XML_PARSER_SEVERITY_WARNING = 3,
    XML_PARSER_SEVERITY_ERROR = 4
} xmlParserSeverities;

#ifdef LIBXML_READER_ENABLED

/**
 * Internal state values for the reader.
 */
typedef enum {
    XML_TEXTREADER_MODE_INITIAL = 0,
    XML_TEXTREADER_MODE_INTERACTIVE = 1,
    XML_TEXTREADER_MODE_ERROR = 2,
    XML_TEXTREADER_MODE_EOF =3,
    XML_TEXTREADER_MODE_CLOSED = 4,
    XML_TEXTREADER_MODE_READING = 5
} xmlTextReaderMode;

/**
 * Some common options to use with #xmlTextReaderSetParserProp, but it
 * is better to use xmlParserOption and the xmlReaderNewxxx and
 * xmlReaderForxxx APIs now.
 */
typedef enum {
    /* load external DTD */
    XML_PARSER_LOADDTD = 1,
    /* use default attributes */
    XML_PARSER_DEFAULTATTRS = 2,
    /* DTD validation */
    XML_PARSER_VALIDATE = 3,
    /* substitute entities */
    XML_PARSER_SUBST_ENTITIES = 4
} xmlParserProperties;

/**
 * Predefined constants for the different types of nodes.
 */
typedef enum {
    /** unknown or error */
    XML_READER_TYPE_NONE = 0,
    /** element */
    XML_READER_TYPE_ELEMENT = 1,
    /** attribute */
    XML_READER_TYPE_ATTRIBUTE = 2,
    /** text */
    XML_READER_TYPE_TEXT = 3,
    /** CDATA section */
    XML_READER_TYPE_CDATA = 4,
    /** entity reference */
    XML_READER_TYPE_ENTITY_REFERENCE = 5,
    /** unused */
    XML_READER_TYPE_ENTITY = 6,
    /** processing instruction */
    XML_READER_TYPE_PROCESSING_INSTRUCTION = 7,
    /** comment */
    XML_READER_TYPE_COMMENT = 8,
    /** document */
    XML_READER_TYPE_DOCUMENT = 9,
    /** unused */
    XML_READER_TYPE_DOCUMENT_TYPE = 10,
    /** document fragment */
    XML_READER_TYPE_DOCUMENT_FRAGMENT = 11,
    /** notation, unused */
    XML_READER_TYPE_NOTATION = 12,
    /** whitespace */
    XML_READER_TYPE_WHITESPACE = 13,
    /** significant whitespace */
    XML_READER_TYPE_SIGNIFICANT_WHITESPACE = 14,
    /** end of element */
    XML_READER_TYPE_END_ELEMENT = 15,
    /** unused */
    XML_READER_TYPE_END_ENTITY = 16,
    /** unused */
    XML_READER_TYPE_XML_DECLARATION = 17
} xmlReaderTypes;

/** xmlReader context */
typedef struct _xmlTextReader xmlTextReader;
typedef xmlTextReader *xmlTextReaderPtr;

/*
 * Constructors & Destructor
 */
XMLPUBFUN xmlTextReader *
			xmlNewTextReader	(xmlParserInputBuffer *input,
	                                         const char *URI);
XMLPUBFUN xmlTextReader *
			xmlNewTextReaderFilename(const char *URI);

XMLPUBFUN void
			xmlFreeTextReader	(xmlTextReader *reader);

XMLPUBFUN int
            xmlTextReaderSetup(xmlTextReader *reader,
                   xmlParserInputBuffer *input, const char *URL,
                   const char *encoding, int options);
XMLPUBFUN void
            xmlTextReaderSetMaxAmplification(xmlTextReader *reader,
                   unsigned maxAmpl);
XMLPUBFUN const xmlError *
            xmlTextReaderGetLastError(xmlTextReader *reader);

/*
 * Iterators
 */
XMLPUBFUN int
			xmlTextReaderRead	(xmlTextReader *reader);

#ifdef LIBXML_WRITER_ENABLED
XMLPUBFUN xmlChar *
			xmlTextReaderReadInnerXml(xmlTextReader *reader);

XMLPUBFUN xmlChar *
			xmlTextReaderReadOuterXml(xmlTextReader *reader);
#endif

XMLPUBFUN xmlChar *
			xmlTextReaderReadString	(xmlTextReader *reader);
XMLPUBFUN int
			xmlTextReaderReadAttributeValue(xmlTextReader *reader);

/*
 * Attributes of the node
 */
XMLPUBFUN int
			xmlTextReaderAttributeCount(xmlTextReader *reader);
XMLPUBFUN int
			xmlTextReaderDepth	(xmlTextReader *reader);
XMLPUBFUN int
			xmlTextReaderHasAttributes(xmlTextReader *reader);
XMLPUBFUN int
			xmlTextReaderHasValue(xmlTextReader *reader);
XMLPUBFUN int
			xmlTextReaderIsDefault	(xmlTextReader *reader);
XMLPUBFUN int
			xmlTextReaderIsEmptyElement(xmlTextReader *reader);
XMLPUBFUN int
			xmlTextReaderNodeType	(xmlTextReader *reader);
XMLPUBFUN int
			xmlTextReaderQuoteChar	(xmlTextReader *reader);
XMLPUBFUN int
			xmlTextReaderReadState	(xmlTextReader *reader);
XMLPUBFUN int
                        xmlTextReaderIsNamespaceDecl(xmlTextReader *reader);

XMLPUBFUN const xmlChar *
		    xmlTextReaderConstBaseUri	(xmlTextReader *reader);
XMLPUBFUN const xmlChar *
		    xmlTextReaderConstLocalName	(xmlTextReader *reader);
XMLPUBFUN const xmlChar *
		    xmlTextReaderConstName	(xmlTextReader *reader);
XMLPUBFUN const xmlChar *
		    xmlTextReaderConstNamespaceUri(xmlTextReader *reader);
XMLPUBFUN const xmlChar *
		    xmlTextReaderConstPrefix	(xmlTextReader *reader);
XMLPUBFUN const xmlChar *
		    xmlTextReaderConstXmlLang	(xmlTextReader *reader);
XMLPUBFUN const xmlChar *
		    xmlTextReaderConstString	(xmlTextReader *reader,
						 const xmlChar *str);
XMLPUBFUN const xmlChar *
		    xmlTextReaderConstValue	(xmlTextReader *reader);

/*
 * use the Const version of the routine for
 * better performance and simpler code
 */
XMLPUBFUN xmlChar *
			xmlTextReaderBaseUri	(xmlTextReader *reader);
XMLPUBFUN xmlChar *
			xmlTextReaderLocalName	(xmlTextReader *reader);
XMLPUBFUN xmlChar *
			xmlTextReaderName	(xmlTextReader *reader);
XMLPUBFUN xmlChar *
			xmlTextReaderNamespaceUri(xmlTextReader *reader);
XMLPUBFUN xmlChar *
			xmlTextReaderPrefix	(xmlTextReader *reader);
XMLPUBFUN xmlChar *
			xmlTextReaderXmlLang	(xmlTextReader *reader);
XMLPUBFUN xmlChar *
			xmlTextReaderValue	(xmlTextReader *reader);

/*
 * Methods of the XmlTextReader
 */
XMLPUBFUN int
		    xmlTextReaderClose		(xmlTextReader *reader);
XMLPUBFUN xmlChar *
		    xmlTextReaderGetAttributeNo	(xmlTextReader *reader,
						 int no);
XMLPUBFUN xmlChar *
		    xmlTextReaderGetAttribute	(xmlTextReader *reader,
						 const xmlChar *name);
XMLPUBFUN xmlChar *
		    xmlTextReaderGetAttributeNs	(xmlTextReader *reader,
						 const xmlChar *localName,
						 const xmlChar *namespaceURI);
XMLPUBFUN xmlParserInputBuffer *
		    xmlTextReaderGetRemainder	(xmlTextReader *reader);
XMLPUBFUN xmlChar *
		    xmlTextReaderLookupNamespace(xmlTextReader *reader,
						 const xmlChar *prefix);
XMLPUBFUN int
		    xmlTextReaderMoveToAttributeNo(xmlTextReader *reader,
						 int no);
XMLPUBFUN int
		    xmlTextReaderMoveToAttribute(xmlTextReader *reader,
						 const xmlChar *name);
XMLPUBFUN int
		    xmlTextReaderMoveToAttributeNs(xmlTextReader *reader,
						 const xmlChar *localName,
						 const xmlChar *namespaceURI);
XMLPUBFUN int
		    xmlTextReaderMoveToFirstAttribute(xmlTextReader *reader);
XMLPUBFUN int
		    xmlTextReaderMoveToNextAttribute(xmlTextReader *reader);
XMLPUBFUN int
		    xmlTextReaderMoveToElement	(xmlTextReader *reader);
XMLPUBFUN int
		    xmlTextReaderNormalization	(xmlTextReader *reader);
XMLPUBFUN const xmlChar *
		    xmlTextReaderConstEncoding  (xmlTextReader *reader);

/*
 * Extensions
 */
XMLPUBFUN int
		    xmlTextReaderSetParserProp	(xmlTextReader *reader,
						 int prop,
						 int value);
XMLPUBFUN int
		    xmlTextReaderGetParserProp	(xmlTextReader *reader,
						 int prop);
XMLPUBFUN xmlNode *
		    xmlTextReaderCurrentNode	(xmlTextReader *reader);

XMLPUBFUN int
            xmlTextReaderGetParserLineNumber(xmlTextReader *reader);

XMLPUBFUN int
            xmlTextReaderGetParserColumnNumber(xmlTextReader *reader);

XMLPUBFUN xmlNode *
		    xmlTextReaderPreserve	(xmlTextReader *reader);
#ifdef LIBXML_PATTERN_ENABLED
XMLPUBFUN int
		    xmlTextReaderPreservePattern(xmlTextReader *reader,
						 const xmlChar *pattern,
						 const xmlChar **namespaces);
#endif /* LIBXML_PATTERN_ENABLED */
XMLPUBFUN xmlDoc *
		    xmlTextReaderCurrentDoc	(xmlTextReader *reader);
XMLPUBFUN xmlNode *
		    xmlTextReaderExpand		(xmlTextReader *reader);
XMLPUBFUN int
		    xmlTextReaderNext		(xmlTextReader *reader);
XMLPUBFUN int
		    xmlTextReaderNextSibling	(xmlTextReader *reader);
XMLPUBFUN int
		    xmlTextReaderIsValid	(xmlTextReader *reader);
#ifdef LIBXML_RELAXNG_ENABLED
XMLPUBFUN int
		    xmlTextReaderRelaxNGValidate(xmlTextReader *reader,
						 const char *rng);
XMLPUBFUN int
		    xmlTextReaderRelaxNGValidateCtxt(xmlTextReader *reader,
						 xmlRelaxNGValidCtxt *ctxt,
						 int options);

XMLPUBFUN int
		    xmlTextReaderRelaxNGSetSchema(xmlTextReader *reader,
						 xmlRelaxNG *schema);
#endif
#ifdef LIBXML_SCHEMAS_ENABLED
XMLPUBFUN int
		    xmlTextReaderSchemaValidate	(xmlTextReader *reader,
						 const char *xsd);
XMLPUBFUN int
		    xmlTextReaderSchemaValidateCtxt(xmlTextReader *reader,
						 xmlSchemaValidCtxt *ctxt,
						 int options);
XMLPUBFUN int
		    xmlTextReaderSetSchema	(xmlTextReader *reader,
						 xmlSchema *schema);
#endif
XMLPUBFUN const xmlChar *
		    xmlTextReaderConstXmlVersion(xmlTextReader *reader);
XMLPUBFUN int
		    xmlTextReaderStandalone     (xmlTextReader *reader);


/*
 * Index lookup
 */
XMLPUBFUN long
		xmlTextReaderByteConsumed	(xmlTextReader *reader);

/*
 * New more complete APIs for simpler creation and reuse of readers
 */
XMLPUBFUN xmlTextReader *
		xmlReaderWalker		(xmlDoc *doc);
XMLPUBFUN xmlTextReader *
		xmlReaderForDoc		(const xmlChar * cur,
					 const char *URL,
					 const char *encoding,
					 int options);
XMLPUBFUN xmlTextReader *
		xmlReaderForFile	(const char *filename,
					 const char *encoding,
					 int options);
XMLPUBFUN xmlTextReader *
		xmlReaderForMemory	(const char *buffer,
					 int size,
					 const char *URL,
					 const char *encoding,
					 int options);
XMLPUBFUN xmlTextReader *
		xmlReaderForFd		(int fd,
					 const char *URL,
					 const char *encoding,
					 int options);
XMLPUBFUN xmlTextReader *
		xmlReaderForIO		(xmlInputReadCallback ioread,
					 xmlInputCloseCallback ioclose,
					 void *ioctx,
					 const char *URL,
					 const char *encoding,
					 int options);

XMLPUBFUN int
		xmlReaderNewWalker	(xmlTextReader *reader,
					 xmlDoc *doc);
XMLPUBFUN int
		xmlReaderNewDoc		(xmlTextReader *reader,
					 const xmlChar * cur,
					 const char *URL,
					 const char *encoding,
					 int options);
XMLPUBFUN int
		xmlReaderNewFile	(xmlTextReader *reader,
					 const char *filename,
					 const char *encoding,
					 int options);
XMLPUBFUN int
		xmlReaderNewMemory	(xmlTextReader *reader,
					 const char *buffer,
					 int size,
					 const char *URL,
					 const char *encoding,
					 int options);
XMLPUBFUN int
		xmlReaderNewFd		(xmlTextReader *reader,
					 int fd,
					 const char *URL,
					 const char *encoding,
					 int options);
XMLPUBFUN int
		xmlReaderNewIO		(xmlTextReader *reader,
					 xmlInputReadCallback ioread,
					 xmlInputCloseCallback ioclose,
					 void *ioctx,
					 const char *URL,
					 const char *encoding,
					 int options);
/*
 * Error handling extensions
 */
typedef void *  xmlTextReaderLocatorPtr;

/**
 * Signature of an error callback from a reader parser
 *
 * @param arg  the user argument
 * @param msg  the message
 * @param severity  the severity of the error
 * @param locator  a locator indicating where the error occurred
 */
typedef void (*xmlTextReaderErrorFunc)(void *arg,
					       const char *msg,
					       xmlParserSeverities severity,
					       xmlTextReaderLocatorPtr locator);
XMLPUBFUN int
	    xmlTextReaderLocatorLineNumber(xmlTextReaderLocatorPtr locator);
XMLPUBFUN xmlChar *
	    xmlTextReaderLocatorBaseURI (xmlTextReaderLocatorPtr locator);
XMLPUBFUN void
	    xmlTextReaderSetErrorHandler(xmlTextReader *reader,
					 xmlTextReaderErrorFunc f,
					 void *arg);
XMLPUBFUN void
	    xmlTextReaderSetStructuredErrorHandler(xmlTextReader *reader,
						   xmlStructuredErrorFunc f,
						   void *arg);
XMLPUBFUN void
	    xmlTextReaderGetErrorHandler(xmlTextReader *reader,
					 xmlTextReaderErrorFunc *f,
					 void **arg);

XMLPUBFUN void
	    xmlTextReaderSetResourceLoader(xmlTextReader *reader,
					   xmlResourceLoader loader,
					   void *data);

#endif /* LIBXML_READER_ENABLED */

#ifdef __cplusplus
}
#endif

#endif /* __XML_XMLREADER_H__ */

libxml2/libxml/SAX2.h000064400000010213151733237440010300 0ustar00/**
 * @file
 * 
 * @brief SAX2 parser interface used to build the DOM tree
 * 
 * those are the default SAX2 interfaces used by
 *              the library when building DOM tree.
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */


#ifndef __XML_SAX2_H__
#define __XML_SAX2_H__

#include <libxml/xmlversion.h>
#include <libxml/parser.h>

#ifdef __cplusplus
extern "C" {
#endif
XMLPUBFUN const xmlChar *
		xmlSAX2GetPublicId		(void *ctx);
XMLPUBFUN const xmlChar *
		xmlSAX2GetSystemId		(void *ctx);
XMLPUBFUN void
		xmlSAX2SetDocumentLocator	(void *ctx,
						 xmlSAXLocator *loc);

XMLPUBFUN int
		xmlSAX2GetLineNumber		(void *ctx);
XMLPUBFUN int
		xmlSAX2GetColumnNumber		(void *ctx);

XMLPUBFUN int
		xmlSAX2IsStandalone		(void *ctx);
XMLPUBFUN int
		xmlSAX2HasInternalSubset	(void *ctx);
XMLPUBFUN int
		xmlSAX2HasExternalSubset	(void *ctx);

XMLPUBFUN void
		xmlSAX2InternalSubset		(void *ctx,
						 const xmlChar *name,
						 const xmlChar *publicId,
						 const xmlChar *systemId);
XMLPUBFUN void
		xmlSAX2ExternalSubset		(void *ctx,
						 const xmlChar *name,
						 const xmlChar *publicId,
						 const xmlChar *systemId);
XMLPUBFUN xmlEntity *
		xmlSAX2GetEntity		(void *ctx,
						 const xmlChar *name);
XMLPUBFUN xmlEntity *
		xmlSAX2GetParameterEntity	(void *ctx,
						 const xmlChar *name);
XMLPUBFUN xmlParserInput *
		xmlSAX2ResolveEntity		(void *ctx,
						 const xmlChar *publicId,
						 const xmlChar *systemId);

XMLPUBFUN void
		xmlSAX2EntityDecl		(void *ctx,
						 const xmlChar *name,
						 int type,
						 const xmlChar *publicId,
						 const xmlChar *systemId,
						 xmlChar *content);
XMLPUBFUN void
		xmlSAX2AttributeDecl		(void *ctx,
						 const xmlChar *elem,
						 const xmlChar *fullname,
						 int type,
						 int def,
						 const xmlChar *defaultValue,
						 xmlEnumeration *tree);
XMLPUBFUN void
		xmlSAX2ElementDecl		(void *ctx,
						 const xmlChar *name,
						 int type,
						 xmlElementContent *content);
XMLPUBFUN void
		xmlSAX2NotationDecl		(void *ctx,
						 const xmlChar *name,
						 const xmlChar *publicId,
						 const xmlChar *systemId);
XMLPUBFUN void
		xmlSAX2UnparsedEntityDecl	(void *ctx,
						 const xmlChar *name,
						 const xmlChar *publicId,
						 const xmlChar *systemId,
						 const xmlChar *notationName);

XMLPUBFUN void
		xmlSAX2StartDocument		(void *ctx);
XMLPUBFUN void
		xmlSAX2EndDocument		(void *ctx);
XML_DEPRECATED
XMLPUBFUN void
		xmlSAX2StartElement		(void *ctx,
						 const xmlChar *fullname,
						 const xmlChar **atts);
XML_DEPRECATED
XMLPUBFUN void
		xmlSAX2EndElement		(void *ctx,
						 const xmlChar *name);
XMLPUBFUN void
		xmlSAX2StartElementNs		(void *ctx,
						 const xmlChar *localname,
						 const xmlChar *prefix,
						 const xmlChar *URI,
						 int nb_namespaces,
						 const xmlChar **namespaces,
						 int nb_attributes,
						 int nb_defaulted,
						 const xmlChar **attributes);
XMLPUBFUN void
		xmlSAX2EndElementNs		(void *ctx,
						 const xmlChar *localname,
						 const xmlChar *prefix,
						 const xmlChar *URI);
XMLPUBFUN void
		xmlSAX2Reference		(void *ctx,
						 const xmlChar *name);
XMLPUBFUN void
		xmlSAX2Characters		(void *ctx,
						 const xmlChar *ch,
						 int len);
XMLPUBFUN void
		xmlSAX2IgnorableWhitespace	(void *ctx,
						 const xmlChar *ch,
						 int len);
XMLPUBFUN void
		xmlSAX2ProcessingInstruction	(void *ctx,
						 const xmlChar *target,
						 const xmlChar *data);
XMLPUBFUN void
		xmlSAX2Comment			(void *ctx,
						 const xmlChar *value);
XMLPUBFUN void
		xmlSAX2CDataBlock		(void *ctx,
						 const xmlChar *value,
						 int len);

#ifdef LIBXML_SAX1_ENABLED
XML_DEPRECATED
XMLPUBFUN int
		xmlSAXDefaultVersion		(int version);
#endif /* LIBXML_SAX1_ENABLED */

XMLPUBFUN int
		xmlSAXVersion			(xmlSAXHandler *hdlr,
						 int version);
XMLPUBFUN void
		xmlSAX2InitDefaultSAXHandler    (xmlSAXHandler *hdlr,
						 int warning);
#ifdef LIBXML_HTML_ENABLED
XMLPUBFUN void
		xmlSAX2InitHtmlDefaultSAXHandler(xmlSAXHandler *hdlr);
XML_DEPRECATED
XMLPUBFUN void
		htmlDefaultSAXHandlerInit	(void);
#endif
XML_DEPRECATED
XMLPUBFUN void
		xmlDefaultSAXHandlerInit	(void);
#ifdef __cplusplus
}
#endif
#endif /* __XML_SAX2_H__ */
libxml2/libxml/xpath.h000064400000034644151733237440010725 0ustar00/**
 * @file
 * 
 * @brief XML Path Language implementation
 * 
 * API for the XML Path Language implementation
 *
 * XML Path Language implementation
 * XPath is a language for addressing parts of an XML document,
 * designed to be used by both XSLT and XPointer
 *     http://www.w3.org/TR/xpath
 *
 * Implements
 * W3C Recommendation 16 November 1999
 *     http://www.w3.org/TR/1999/REC-xpath-19991116
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */

#ifndef __XML_XPATH_H__
#define __XML_XPATH_H__

#include <libxml/xmlversion.h>

#ifdef LIBXML_XPATH_ENABLED

#include <libxml/xmlerror.h>
#include <libxml/tree.h>
#include <libxml/hash.h>

#ifdef __cplusplus
extern "C" {
#endif

/** XPath context */
typedef struct _xmlXPathContext xmlXPathContext;
typedef xmlXPathContext *xmlXPathContextPtr;
/** XPath parser and evaluation context */
typedef struct _xmlXPathParserContext xmlXPathParserContext;
typedef xmlXPathParserContext *xmlXPathParserContextPtr;

/**
 * The set of XPath error codes.
 */

typedef enum {
    XPATH_EXPRESSION_OK = 0,
    XPATH_NUMBER_ERROR,
    XPATH_UNFINISHED_LITERAL_ERROR,
    XPATH_START_LITERAL_ERROR,
    XPATH_VARIABLE_REF_ERROR,
    XPATH_UNDEF_VARIABLE_ERROR,
    XPATH_INVALID_PREDICATE_ERROR,
    XPATH_EXPR_ERROR,
    XPATH_UNCLOSED_ERROR,
    XPATH_UNKNOWN_FUNC_ERROR,
    XPATH_INVALID_OPERAND,
    XPATH_INVALID_TYPE,
    XPATH_INVALID_ARITY,
    XPATH_INVALID_CTXT_SIZE,
    XPATH_INVALID_CTXT_POSITION,
    XPATH_MEMORY_ERROR,
    XPTR_SYNTAX_ERROR,
    XPTR_RESOURCE_ERROR,
    XPTR_SUB_RESOURCE_ERROR,
    XPATH_UNDEF_PREFIX_ERROR,
    XPATH_ENCODING_ERROR,
    XPATH_INVALID_CHAR_ERROR,
    XPATH_INVALID_CTXT,
    XPATH_STACK_ERROR,
    XPATH_FORBID_VARIABLE_ERROR,
    XPATH_OP_LIMIT_EXCEEDED,
    XPATH_RECURSION_LIMIT_EXCEEDED
} xmlXPathError;

/** XPath node set */
typedef struct _xmlNodeSet xmlNodeSet;
typedef xmlNodeSet *xmlNodeSetPtr;
/**
 * A node-set (an unordered collection of nodes without duplicates).
 */
struct _xmlNodeSet {
    /** number of nodes in the set */
    int nodeNr;
    /** size of the array as allocated */
    int nodeMax;
    /** array of nodes in no particular order */
    xmlNode **nodeTab;
};

/**
 * An expression is evaluated to yield an object, which
 * has one of the following four basic types:
 *
 *   - node-set
 *   - boolean
 *   - number
 *   - string
 */
typedef enum {
    XPATH_UNDEFINED = 0,
    XPATH_NODESET = 1,
    XPATH_BOOLEAN = 2,
    XPATH_NUMBER = 3,
    XPATH_STRING = 4,
    XPATH_USERS = 8,
    XPATH_XSLT_TREE = 9  /* An XSLT value tree, non modifiable */
} xmlXPathObjectType;

/** @cond IGNORE */
#define XPATH_POINT 5
#define XPATH_RANGE 6
#define XPATH_LOCATIONSET 7
/** @endcond */

/** XPath object */
typedef struct _xmlXPathObject xmlXPathObject;
typedef xmlXPathObject *xmlXPathObjectPtr;
/**
 * An XPath object
 */
struct _xmlXPathObject {
    /** object type */
    xmlXPathObjectType type;
    /** node set */
    xmlNodeSet *nodesetval;
    /** boolean */
    int boolval;
    /** number */
    double floatval;
    /** string */
    xmlChar *stringval;
    void *user;
    int index;
    void *user2;
    int index2;
};

/** @cond ignore */

/*
 * unused
 */
typedef int (*xmlXPathConvertFunc) (xmlXPathObject *obj, int type);
typedef struct _xmlXPathType xmlXPathType;
typedef xmlXPathType *xmlXPathTypePtr;
struct _xmlXPathType {
    const xmlChar         *name;		/* the type name */
    xmlXPathConvertFunc func;		/* the conversion function */
};

/*
 * unused
 */
typedef struct _xmlXPathVariable xmlXPathVariable;
typedef xmlXPathVariable *xmlXPathVariablePtr;
struct _xmlXPathVariable {
    const xmlChar       *name;		/* the variable name */
    xmlXPathObject *value;		/* the value */
};

/*
 * unused
 */
typedef void (*xmlXPathEvalFunc)(xmlXPathParserContext *ctxt,
	                         int nargs);
typedef struct _xmlXPathFunct xmlXPathFunct;
typedef xmlXPathFunct *xmlXPathFuncPtr;
struct _xmlXPathFunct {
    const xmlChar      *name;		/* the function name */
    xmlXPathEvalFunc func;		/* the evaluation function */
};

/*
 * unused
 */
typedef xmlXPathObject *(*xmlXPathAxisFunc) (xmlXPathParserContext *ctxt,
				 xmlXPathObject *cur);
typedef struct _xmlXPathAxis xmlXPathAxis;
typedef xmlXPathAxis *xmlXPathAxisPtr;
struct _xmlXPathAxis {
    const xmlChar      *name;		/* the axis name */
    xmlXPathAxisFunc func;		/* the search function */
};

/** @endcond */

/**
 * An XPath function.
 * The arguments (if any) are popped out from the context stack
 * and the result is pushed on the stack.
 *
 * @param ctxt  the XPath interprestation context
 * @param nargs  the number of arguments
 */

typedef void (*xmlXPathFunction) (xmlXPathParserContext *ctxt, int nargs);

/*
 * Function and Variable Lookup.
 */

/**
 * Prototype for callbacks used to plug variable lookup in the XPath
 * engine.
 *
 * @param ctxt  an XPath context
 * @param name  name of the variable
 * @param ns_uri  the namespace name hosting this variable
 * @returns the XPath object value or NULL if not found.
 */
typedef xmlXPathObject *(*xmlXPathVariableLookupFunc) (void *ctxt,
                                         const xmlChar *name,
                                         const xmlChar *ns_uri);

/**
 * Prototype for callbacks used to plug function lookup in the XPath
 * engine.
 *
 * @param ctxt  an XPath context
 * @param name  name of the function
 * @param ns_uri  the namespace name hosting this function
 * @returns the XPath function or NULL if not found.
 */
typedef xmlXPathFunction (*xmlXPathFuncLookupFunc) (void *ctxt,
					 const xmlChar *name,
					 const xmlChar *ns_uri);

/**
 * Flags for XPath engine compilation and runtime
 */
/**
 * check namespaces at compilation
 */
#define XML_XPATH_CHECKNS (1<<0)
/**
 * forbid variables in expression
 */
#define XML_XPATH_NOVAR	  (1<<1)

/**
 * Expression evaluation occurs with respect to a context.
 * he context consists of:
 *    - a node (the context node)
 *    - a node list (the context node list)
 *    - a set of variable bindings
 *    - a function library
 *    - the set of namespace declarations in scope for the expression
 * Following the switch to hash tables, this need to be trimmed up at
 * the next binary incompatible release.
 * The node may be modified when the context is passed to libxml2
 * for an XPath evaluation so you may need to initialize it again
 * before the next call.
 */
struct _xmlXPathContext {
    /** The current document */
    xmlDoc *doc;
    /** The current node */
    xmlNode *node;

    /* unused (hash table) */
    int nb_variables_unused;
    /* unused (hash table) */
    int max_variables_unused;
    /* Hash table of defined variables */
    xmlHashTable *varHash;

    /* number of defined types */
    int nb_types;
    /* max number of types */
    int max_types;
    /* Array of defined types */
    xmlXPathType *types;

    /* unused (hash table) */
    int nb_funcs_unused;
    /* unused (hash table) */
    int max_funcs_unused;
    /* Hash table of defined funcs */
    xmlHashTable *funcHash;

    /* number of defined axis */
    int nb_axis;
    /* max number of axis */
    int max_axis;
    /* Array of defined axis */
    xmlXPathAxis *axis;

    /* Array of namespaces */
    xmlNs **namespaces;
    /* number of namespace in scope */
    int nsNr;
    /* function to free */
    void *user;

    /** the context size */
    int contextSize;
    /** the proximity position */
    int proximityPosition;

    /* is this an XPointer context? */
    int xptr;
    /* for here() */
    xmlNode *here;
    /* for origin() */
    xmlNode *origin;

    /* The namespaces hash table */
    xmlHashTable *nsHash;
    /* variable lookup func */
    xmlXPathVariableLookupFunc varLookupFunc;
    /* variable lookup data */
    void *varLookupData;

    /* needed for XSLT */
    void *extra;

    /* The function name when calling a function */
    const xmlChar *function;
    /* The namespace URI when calling a function */
    const xmlChar *functionURI;

    /* function lookup func */
    xmlXPathFuncLookupFunc funcLookupFunc;
    /* function lookup data */
    void *funcLookupData;

    /* Array of temp namespaces */
    xmlNs **tmpNsList;
    /* number of namespaces in scope */
    int tmpNsNr;

    /* user specific data block */
    void *userData;
    /* the callback in case of errors */
    xmlStructuredErrorFunc error;
    /* the last error */
    xmlError lastError;
    /* the source node XSLT */
    xmlNode *debugNode;

    /* dictionary if any */
    xmlDict *dict;

    /** flags to control compilation */
    int flags;

    /* Cache for reusal of XPath objects */
    void *cache;

    /* Resource limits */
    unsigned long opLimit;
    unsigned long opCount;
    int depth;
};

/** Compiled XPath expression */
typedef struct _xmlXPathCompExpr xmlXPathCompExpr;
typedef xmlXPathCompExpr *xmlXPathCompExprPtr;

/**
 * An XPath parser context. It contains pure parsing information,
 * an xmlXPathContext, and the stack of objects.
 *
 * This struct is used for evaluation as well and misnamed.
 */
struct _xmlXPathParserContext {
    /* the current char being parsed */
    const xmlChar *cur;
    /* the full expression */
    const xmlChar *base;

    /** error code */
    int error;

    /** the evaluation context */
    xmlXPathContext    *context;
    /** the current value */
    xmlXPathObject       *value;
    /* number of values stacked */
    int                 valueNr;
    /* max number of values stacked */
    int                valueMax;
    /* stack of values */
    xmlXPathObject **valueTab;

    /* the precompiled expression */
    xmlXPathCompExpr *comp;
    /* it this an XPointer expression */
    int xptr;
    /* used for walking preceding axis */
    xmlNode           *ancestor;

    /* always zero for compatibility */
    int              valueFrame;
};

/************************************************************************
 *									*
 *			Public API					*
 *									*
 ************************************************************************/

/**
 * Objects and Nodesets handling
 */

/** @cond ignore */

XML_DEPRECATED
XMLPUBVAR double xmlXPathNAN;
XML_DEPRECATED
XMLPUBVAR double xmlXPathPINF;
XML_DEPRECATED
XMLPUBVAR double xmlXPathNINF;

/* These macros may later turn into functions */
/**
 * Implement a functionality similar to the DOM NodeList.length.
 *
 * @param ns  a node-set
 * @returns the number of nodes in the node-set.
 */
#define xmlXPathNodeSetGetLength(ns) ((ns) ? (ns)->nodeNr : 0)
/**
 * Implements a functionality similar to the DOM NodeList.item().
 *
 * @param ns  a node-set
 * @param index  index of a node in the set
 * @returns the xmlNode at the given `index` in `ns` or NULL if
 *         `index` is out of range (0 to length-1)
 */
#define xmlXPathNodeSetItem(ns, index)				\
		((((ns) != NULL) &&				\
		  ((index) >= 0) && ((index) < (ns)->nodeNr)) ?	\
		 (ns)->nodeTab[(index)]				\
		 : NULL)
/**
 * Checks whether `ns` is empty or not.
 *
 * @param ns  a node-set
 * @returns %TRUE if `ns` is an empty node-set.
 */
#define xmlXPathNodeSetIsEmpty(ns)                                      \
    (((ns) == NULL) || ((ns)->nodeNr == 0) || ((ns)->nodeTab == NULL))

/** @endcond */

XMLPUBFUN void
		    xmlXPathFreeObject		(xmlXPathObject *obj);
XMLPUBFUN xmlNodeSet *
		    xmlXPathNodeSetCreate	(xmlNode *val);
XMLPUBFUN void
		    xmlXPathFreeNodeSetList	(xmlXPathObject *obj);
XMLPUBFUN void
		    xmlXPathFreeNodeSet		(xmlNodeSet *obj);
XMLPUBFUN xmlXPathObject *
		    xmlXPathObjectCopy		(xmlXPathObject *val);
XMLPUBFUN int
		    xmlXPathCmpNodes		(xmlNode *node1,
						 xmlNode *node2);
/**
 * Conversion functions to basic types.
 */
XMLPUBFUN int
		    xmlXPathCastNumberToBoolean	(double val);
XMLPUBFUN int
		    xmlXPathCastStringToBoolean	(const xmlChar * val);
XMLPUBFUN int
		    xmlXPathCastNodeSetToBoolean(xmlNodeSet *ns);
XMLPUBFUN int
		    xmlXPathCastToBoolean	(xmlXPathObject *val);

XMLPUBFUN double
		    xmlXPathCastBooleanToNumber	(int val);
XMLPUBFUN double
		    xmlXPathCastStringToNumber	(const xmlChar * val);
XMLPUBFUN double
		    xmlXPathCastNodeToNumber	(xmlNode *node);
XMLPUBFUN double
		    xmlXPathCastNodeSetToNumber	(xmlNodeSet *ns);
XMLPUBFUN double
		    xmlXPathCastToNumber	(xmlXPathObject *val);

XMLPUBFUN xmlChar *
		    xmlXPathCastBooleanToString	(int val);
XMLPUBFUN xmlChar *
		    xmlXPathCastNumberToString	(double val);
XMLPUBFUN xmlChar *
		    xmlXPathCastNodeToString	(xmlNode *node);
XMLPUBFUN xmlChar *
		    xmlXPathCastNodeSetToString	(xmlNodeSet *ns);
XMLPUBFUN xmlChar *
		    xmlXPathCastToString	(xmlXPathObject *val);

XMLPUBFUN xmlXPathObject *
		    xmlXPathConvertBoolean	(xmlXPathObject *val);
XMLPUBFUN xmlXPathObject *
		    xmlXPathConvertNumber	(xmlXPathObject *val);
XMLPUBFUN xmlXPathObject *
		    xmlXPathConvertString	(xmlXPathObject *val);

/**
 * Context handling.
 */
XMLPUBFUN xmlXPathContext *
		    xmlXPathNewContext		(xmlDoc *doc);
XMLPUBFUN void
		    xmlXPathFreeContext		(xmlXPathContext *ctxt);
XMLPUBFUN void
		    xmlXPathSetErrorHandler(xmlXPathContext *ctxt,
					    xmlStructuredErrorFunc handler,
					    void *context);
XMLPUBFUN int
		    xmlXPathContextSetCache(xmlXPathContext *ctxt,
				            int active,
					    int value,
					    int options);
/**
 * Evaluation functions.
 */
XMLPUBFUN long
		    xmlXPathOrderDocElems	(xmlDoc *doc);
XMLPUBFUN int
		    xmlXPathSetContextNode	(xmlNode *node,
						 xmlXPathContext *ctx);
XMLPUBFUN xmlXPathObject *
		    xmlXPathNodeEval		(xmlNode *node,
						 const xmlChar *str,
						 xmlXPathContext *ctx);
XMLPUBFUN xmlXPathObject *
		    xmlXPathEval		(const xmlChar *str,
						 xmlXPathContext *ctx);
XMLPUBFUN xmlXPathObject *
		    xmlXPathEvalExpression	(const xmlChar *str,
						 xmlXPathContext *ctxt);
XMLPUBFUN int
		    xmlXPathEvalPredicate	(xmlXPathContext *ctxt,
						 xmlXPathObject *res);
/**
 * Separate compilation/evaluation entry points.
 */
XMLPUBFUN xmlXPathCompExpr *
		    xmlXPathCompile		(const xmlChar *str);
XMLPUBFUN xmlXPathCompExpr *
		    xmlXPathCtxtCompile		(xmlXPathContext *ctxt,
						 const xmlChar *str);
XMLPUBFUN xmlXPathObject *
		    xmlXPathCompiledEval	(xmlXPathCompExpr *comp,
						 xmlXPathContext *ctx);
XMLPUBFUN int
		    xmlXPathCompiledEvalToBoolean(xmlXPathCompExpr *comp,
						 xmlXPathContext *ctxt);
XMLPUBFUN void
		    xmlXPathFreeCompExpr	(xmlXPathCompExpr *comp);

XML_DEPRECATED
XMLPUBFUN void
		    xmlXPathInit		(void);
XMLPUBFUN int
		xmlXPathIsNaN	(double val);
XMLPUBFUN int
		xmlXPathIsInf	(double val);

#ifdef __cplusplus
}
#endif

#endif /* LIBXML_XPATH_ENABLED */
#endif /* ! __XML_XPATH_H__ */
libxml2/libxml/xmlunicode.h000064400000000431151733237440011733 0ustar00/**
 * @file
 * 
 * @brief Unicode character APIs
 * 
 * API for the Unicode character APIs
 *
 * Deprecated, don't use.
 */

#ifndef __XML_UNICODE_H__
#define __XML_UNICODE_H__

#ifdef __GNUC__
  #warning "libxml/xmlunicode.h is deprecated"
#endif

#endif /* __XML_UNICODE_H__ */
libxml2/libxml/HTMLtree.h000064400000005214151733237440011214 0ustar00/**
 * @file
 * 
 * @brief HTML documents
 * 
 * This modules implements functions to work with HTML documents,
 * most of them related to serialization.
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */

#ifndef __HTML_TREE_H__
#define __HTML_TREE_H__

#include <stdio.h>
#include <libxml/xmlversion.h>
#include <libxml/tree.h>
#include <libxml/HTMLparser.h>

#ifdef LIBXML_HTML_ENABLED

#ifdef __cplusplus
extern "C" {
#endif

/* Deprecated */
/** @cond ignore */
#define HTML_TEXT_NODE		XML_TEXT_NODE
#define HTML_ENTITY_REF_NODE	XML_ENTITY_REF_NODE
#define HTML_COMMENT_NODE	XML_COMMENT_NODE
#define HTML_PRESERVE_NODE	XML_CDATA_SECTION_NODE
#define HTML_PI_NODE		XML_PI_NODE
/** @endcond */

XMLPUBFUN xmlDoc *
		htmlNewDoc		(const xmlChar *URI,
					 const xmlChar *ExternalID);
XMLPUBFUN xmlDoc *
		htmlNewDocNoDtD		(const xmlChar *URI,
					 const xmlChar *ExternalID);
XMLPUBFUN const xmlChar *
		htmlGetMetaEncoding	(xmlDoc *doc);
XMLPUBFUN int
		htmlSetMetaEncoding	(xmlDoc *doc,
					 const xmlChar *encoding);
#ifdef LIBXML_OUTPUT_ENABLED
XMLPUBFUN void
		htmlDocDumpMemory	(xmlDoc *cur,
					 xmlChar **mem,
					 int *size);
XMLPUBFUN void
		htmlDocDumpMemoryFormat	(xmlDoc *cur,
					 xmlChar **mem,
					 int *size,
					 int format);
XMLPUBFUN int
		htmlSaveFile		(const char *filename,
					 xmlDoc *cur);
XMLPUBFUN int
		htmlSaveFileEnc		(const char *filename,
					 xmlDoc *cur,
					 const char *encoding);
XMLPUBFUN int
		htmlSaveFileFormat	(const char *filename,
					 xmlDoc *cur,
					 const char *encoding,
					 int format);
XMLPUBFUN int
		htmlNodeDump		(xmlBuffer *buf,
					 xmlDoc *doc,
					 xmlNode *cur);
XMLPUBFUN int
		htmlDocDump		(FILE *f,
					 xmlDoc *cur);
XMLPUBFUN void
		htmlNodeDumpFile	(FILE *out,
					 xmlDoc *doc,
					 xmlNode *cur);
XMLPUBFUN int
		htmlNodeDumpFileFormat	(FILE *out,
					 xmlDoc *doc,
					 xmlNode *cur,
					 const char *encoding,
					 int format);

XMLPUBFUN void
		htmlNodeDumpOutput	(xmlOutputBuffer *buf,
					 xmlDoc *doc,
					 xmlNode *cur,
					 const char *encoding);
XMLPUBFUN void
		htmlNodeDumpFormatOutput(xmlOutputBuffer *buf,
					 xmlDoc *doc,
					 xmlNode *cur,
					 const char *encoding,
					 int format);
XMLPUBFUN void
		htmlDocContentDumpOutput(xmlOutputBuffer *buf,
					 xmlDoc *cur,
					 const char *encoding);
XMLPUBFUN void
		htmlDocContentDumpFormatOutput(xmlOutputBuffer *buf,
					 xmlDoc *cur,
					 const char *encoding,
					 int format);

#endif /* LIBXML_OUTPUT_ENABLED */

XML_DEPRECATED
XMLPUBFUN int
		htmlIsBooleanAttr	(const xmlChar *name);


#ifdef __cplusplus
}
#endif

#endif /* LIBXML_HTML_ENABLED */

#endif /* __HTML_TREE_H__ */

libxml2/libxml/xmlsave.h000064400000006624151733237440011255 0ustar00/**
 * @file
 * 
 * @brief XML/HTML serializer
 * 
 * API to save documents or subtrees of documents.
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */

#ifndef __XML_XMLSAVE_H__
#define __XML_XMLSAVE_H__

#include <libxml/xmlversion.h>
#include <libxml/tree.h>
#include <libxml/encoding.h>
#include <libxml/xmlIO.h>

#ifdef LIBXML_OUTPUT_ENABLED
#ifdef __cplusplus
extern "C" {
#endif

/**
 * This is the set of XML save options that can be passed down
 * to the #xmlSaveToFd and similar calls.
 */
typedef enum {
    /**
     * Format output. This adds newlines and enables indenting
     * by default.
     */
    XML_SAVE_FORMAT     = 1<<0,
    /**
     * Don't emit an XML declaration.
     */
    XML_SAVE_NO_DECL    = 1<<1,
    /**
     * Don't emit empty tags.
     */
    XML_SAVE_NO_EMPTY	= 1<<2,
    /**
     * Don't serialize as XHTML.
     */
    XML_SAVE_NO_XHTML	= 1<<3,
    /**
     * Always serialize as XHTML.
     */
    XML_SAVE_XHTML	= 1<<4,
    /**
     * Serialize HTML documents as XML.
     */
    XML_SAVE_AS_XML     = 1<<5,
    /**
     * Serialize XML documents as HTML.
     */
    XML_SAVE_AS_HTML    = 1<<6,
    /**
     * Format with non-significant whitespace.
     * TODO: What does this mean?
     */
    XML_SAVE_WSNONSIG   = 1<<7,
    /**
     * Always emit empty tags. This is the default unless the
     * deprecated thread-local setting xmlSaveNoEmptyTags is
     * set to 1.
     *
     * @since 2.14
     */
    XML_SAVE_EMPTY      = 1<<8,
    /**
     * Don't indent output when formatting.
     *
     * @since 2.14
     */
    XML_SAVE_NO_INDENT  = 1<<9,
    /**
     * Always indent output when formatting. This is the default
     * unless the deprecated thread-local setting
     * xmlIndentTreeOutput is set to 0.
     *
     * @since 2.14
     */
    XML_SAVE_INDENT     = 1<<10
} xmlSaveOption;

/** XML and HTML serializer */
typedef struct _xmlSaveCtxt xmlSaveCtxt;
typedef xmlSaveCtxt *xmlSaveCtxtPtr;

XMLPUBFUN xmlSaveCtxt *
		xmlSaveToFd		(int fd,
					 const char *encoding,
					 int options);
XMLPUBFUN xmlSaveCtxt *
		xmlSaveToFilename	(const char *filename,
					 const char *encoding,
					 int options);

XMLPUBFUN xmlSaveCtxt *
		xmlSaveToBuffer		(xmlBuffer *buffer,
					 const char *encoding,
					 int options);

XMLPUBFUN xmlSaveCtxt *
		xmlSaveToIO		(xmlOutputWriteCallback iowrite,
					 xmlOutputCloseCallback ioclose,
					 void *ioctx,
					 const char *encoding,
					 int options);

XMLPUBFUN long
		xmlSaveDoc		(xmlSaveCtxt *ctxt,
					 xmlDoc *doc);
XMLPUBFUN long
		xmlSaveTree		(xmlSaveCtxt *ctxt,
					 xmlNode *node);

XMLPUBFUN int
		xmlSaveFlush		(xmlSaveCtxt *ctxt);
XMLPUBFUN int
		xmlSaveClose		(xmlSaveCtxt *ctxt);
XMLPUBFUN xmlParserErrors
		xmlSaveFinish		(xmlSaveCtxt *ctxt);
XMLPUBFUN int
		xmlSaveSetIndentString	(xmlSaveCtxt *ctxt,
					 const char *indent);
XML_DEPRECATED
XMLPUBFUN int
		xmlSaveSetEscape	(xmlSaveCtxt *ctxt,
					 xmlCharEncodingOutputFunc escape);
XML_DEPRECATED
XMLPUBFUN int
		xmlSaveSetAttrEscape	(xmlSaveCtxt *ctxt,
					 xmlCharEncodingOutputFunc escape);

XML_DEPRECATED
XMLPUBFUN int
                xmlThrDefIndentTreeOutput(int v);
XML_DEPRECATED
XMLPUBFUN const char *
                xmlThrDefTreeIndentString(const char * v);
XML_DEPRECATED
XMLPUBFUN int
                xmlThrDefSaveNoEmptyTags(int v);

#ifdef __cplusplus
}
#endif

#endif /* LIBXML_OUTPUT_ENABLED */
#endif /* __XML_XMLSAVE_H__ */


libxml2/libxml/uri.h000064400000005247151733237440010375 0ustar00/**
 * @file
 *
 * @brief library of generic URI related routines
 * 
 * library of generic URI related routines
 *              Implements RFC 2396
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */

#ifndef __XML_URI_H__
#define __XML_URI_H__

#include <stdio.h>
#include <libxml/xmlversion.h>
#include <libxml/xmlstring.h>

#ifdef __cplusplus
extern "C" {
#endif

/** Parsed URI */
typedef struct _xmlURI xmlURI;
typedef xmlURI *xmlURIPtr;
/**
 * A parsed URI reference.
 *
 * This is a struct containing the various fields
 * as described in RFC 2396 but separated for further processing.
 *
 * Note: query is a deprecated field which is incorrectly unescaped.
 * query_raw takes precedence over query if the former is set.
 * See: http://mail.gnome.org/archives/xml/2007-April/thread.html\#00127
 */
struct _xmlURI {
    char *scheme;	/* the URI scheme */
    char *opaque;	/* opaque part */
    char *authority;	/* the authority part */
    char *server;	/* the server part */
    char *user;		/* the user part */
    int port;		/* the port number */
    char *path;		/* the path string */
    char *query;	/* the query string (deprecated - use with caution) */
    char *fragment;	/* the fragment identifier */
    int  cleanup;	/* parsing potentially unclean URI */
    char *query_raw;	/* the query string (as it appears in the URI) */
};

XMLPUBFUN xmlURI *
		xmlCreateURI		(void);
XMLPUBFUN int
		xmlBuildURISafe		(const xmlChar *URI,
					 const xmlChar *base,
					 xmlChar **out);
XMLPUBFUN xmlChar *
		xmlBuildURI		(const xmlChar *URI,
					 const xmlChar *base);
XMLPUBFUN int
		xmlBuildRelativeURISafe	(const xmlChar *URI,
					 const xmlChar *base,
					 xmlChar **out);
XMLPUBFUN xmlChar *
		xmlBuildRelativeURI	(const xmlChar *URI,
					 const xmlChar *base);
XMLPUBFUN xmlURI *
		xmlParseURI		(const char *str);
XMLPUBFUN int
		xmlParseURISafe		(const char *str,
					 xmlURI **uri);
XMLPUBFUN xmlURI *
		xmlParseURIRaw		(const char *str,
					 int raw);
XMLPUBFUN int
		xmlParseURIReference	(xmlURI *uri,
					 const char *str);
XMLPUBFUN xmlChar *
		xmlSaveUri		(xmlURI *uri);
XMLPUBFUN void
		xmlPrintURI		(FILE *stream,
					 xmlURI *uri);
XMLPUBFUN xmlChar *
		xmlURIEscapeStr         (const xmlChar *str,
					 const xmlChar *list);
XMLPUBFUN char *
		xmlURIUnescapeString	(const char *str,
					 int len,
					 char *target);
XMLPUBFUN int
		xmlNormalizeURIPath	(char *path);
XMLPUBFUN xmlChar *
		xmlURIEscape		(const xmlChar *str);
XMLPUBFUN void
		xmlFreeURI		(xmlURI *uri);
XMLPUBFUN xmlChar*
		xmlCanonicPath		(const xmlChar *path);
XMLPUBFUN xmlChar*
		xmlPathToURI		(const xmlChar *path);

#ifdef __cplusplus
}
#endif
#endif /* __XML_URI_H__ */
libxml2/libxml/xmlexports.h000064400000004556151733237440012025 0ustar00/**
 * @file
 * 
 * @brief macros for marking symbols as exportable/importable.
 * 
 * macros for marking symbols as exportable/importable.
 *
 * @copyright See Copyright for the status of this software.
 */

#ifndef __XML_EXPORTS_H__
#define __XML_EXPORTS_H__

/*
 * Symbol visibility
 */

#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(LIBXML_STATIC)
  #if defined(IN_LIBXML)
    #define XMLPUBFUN __declspec(dllexport)
    #define XMLPUBVAR __declspec(dllexport) extern
  #else
    #define XMLPUBFUN __declspec(dllimport)
    #define XMLPUBVAR __declspec(dllimport) extern
  #endif
#else /* not Windows */
  #define XMLPUBFUN
  #define XMLPUBVAR extern
#endif /* platform switch */

/* Compatibility */
#define XMLCALL
#define XMLCDECL
#ifndef LIBXML_DLL_IMPORT
  #define LIBXML_DLL_IMPORT XMLPUBVAR
#endif

/*
 * Attributes
 */

#if !defined(__clang__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)
  #define LIBXML_ATTR_ALLOC_SIZE(x) __attribute__((alloc_size(x)))
#else
  #define LIBXML_ATTR_ALLOC_SIZE(x)
#endif

#if __GNUC__ * 100 + __GNUC_MINOR__ >= 303
  #define LIBXML_ATTR_FORMAT(fmt,args) \
    __attribute__((__format__(__printf__,fmt,args)))
#else
  #define LIBXML_ATTR_FORMAT(fmt,args)
#endif

#ifndef XML_DEPRECATED
  #if defined(IN_LIBXML)
    #define XML_DEPRECATED
  #elif __GNUC__ * 100 + __GNUC_MINOR__ >= 405
    /* GCC 4.5+ supports deprecated with message */
    #define XML_DEPRECATED __attribute__((deprecated("See https://gnome.pages.gitlab.gnome.org/libxml2/html/deprecated.html")))
  #elif __GNUC__ * 100 + __GNUC_MINOR__ >= 301
    /* GCC 3.1+ supports deprecated without message */
    #define XML_DEPRECATED __attribute__((deprecated))
  #elif defined(_MSC_VER) && _MSC_VER >= 1400
    /* Available since Visual Studio 2005 */
    #define XML_DEPRECATED __declspec(deprecated("See https://gnome.pages.gitlab.gnome.org/libxml2/html/deprecated.html"))
  #else
    #define XML_DEPRECATED
  #endif
#endif

#ifndef XML_DEPRECATED_MEMBER
  #if defined(IN_LIBXML)
    #define XML_DEPRECATED_MEMBER
  #elif __GNUC__ * 100 + __GNUC_MINOR__ >= 301
    #define XML_DEPRECATED_MEMBER __attribute__((deprecated))
  #else
    #define XML_DEPRECATED_MEMBER
  #endif
#endif

/*
 * Originally declared in xmlversion.h which is generated
 */

#ifdef __cplusplus
extern "C" {
#endif

XMLPUBFUN void xmlCheckVersion(int version);

#ifdef __cplusplus
}
#endif

#endif /* __XML_EXPORTS_H__ */


libxml2/libxml/xmlversion.h000064400000007632151733237440012004 0ustar00/**
 * @file
 *
 * @brief compile-time version information
 *
 * compile-time version information for the XML library
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */

#ifndef __XML_VERSION_H__
#define __XML_VERSION_H__

/**
 * the version string like "1.2.3"
 */
#define LIBXML_DOTTED_VERSION "2.15.1"

/**
 * the version number: 1.2.3 value is 10203
 */
#define LIBXML_VERSION 21501

/**
 * the version number string, 1.2.3 value is "10203"
 */
#define LIBXML_VERSION_STRING "21501"

/**
 * extra version information, used to show a git commit description
 */
#define LIBXML_VERSION_EXTRA ""

/**
 * Macro to check that the libxml version in use is compatible with
 * the version the software has been compiled against
 */
#define LIBXML_TEST_VERSION xmlCheckVersion(21501);

#if 1
/**
 * Whether the thread support is configured in
 */
#define LIBXML_THREAD_ENABLED
#endif

#if 0
/**
 * Whether the allocation hooks are per-thread
 */
#define LIBXML_THREAD_ALLOC_ENABLED
#endif

/**
 * Always enabled since 2.14.0
 */
#define LIBXML_TREE_ENABLED

#if 1
/**
 * Whether the serialization/saving support is configured in
 */
#define LIBXML_OUTPUT_ENABLED
#endif

#if 1
/**
 * Whether the push parsing interfaces are configured in
 */
#define LIBXML_PUSH_ENABLED
#endif

#if 1
/**
 * Whether the xmlReader parsing interface is configured in
 */
#define LIBXML_READER_ENABLED
#endif

#if 1
/**
 * Whether the xmlPattern node selection interface is configured in
 */
#define LIBXML_PATTERN_ENABLED
#endif

#if 1
/**
 * Whether the xmlWriter saving interface is configured in
 */
#define LIBXML_WRITER_ENABLED
#endif

#if 1
/**
 * Whether the older SAX1 interface is configured in
 */
#define LIBXML_SAX1_ENABLED
#endif

#if 0
/**
 * HTTP support was removed in 2.15
 */
#define LIBXML_HTTP_STUBS_ENABLED
#endif

#if 1
/**
 * Whether the DTD validation support is configured in
 */
#define LIBXML_VALID_ENABLED
#endif

#if 1
/**
 * Whether the HTML support is configured in
 */
#define LIBXML_HTML_ENABLED
#endif

/*
 * Removed in 2.14
 */
#undef LIBXML_LEGACY_ENABLED

#if 1
/**
 * Whether the Canonicalization support is configured in
 */
#define LIBXML_C14N_ENABLED
#endif

#if 1
/**
 * Whether the Catalog support is configured in
 */
#define LIBXML_CATALOG_ENABLED
#define LIBXML_SGML_CATALOG_ENABLED
#endif

#if 1
/**
 * Whether XPath is configured in
 */
#define LIBXML_XPATH_ENABLED
#endif

#if 1
/**
 * Whether XPointer is configured in
 */
#define LIBXML_XPTR_ENABLED
#endif

#if 1
/**
 * Whether XInclude is configured in
 */
#define LIBXML_XINCLUDE_ENABLED
#endif

#if 1
/**
 * Whether iconv support is available
 */
#define LIBXML_ICONV_ENABLED
#endif

#if 0
/**
 * Whether icu support is available
 */
#define LIBXML_ICU_ENABLED
#endif

#if 1
/**
 * Whether ISO-8859-* support is made available in case iconv is not
 */
#define LIBXML_ISO8859X_ENABLED
#endif

#if 1
/**
 * Whether Debugging module is configured in
 */
#define LIBXML_DEBUG_ENABLED
#endif

/*
 * Removed in 2.14
 */
#undef LIBXML_UNICODE_ENABLED

#if 1
/**
 * Whether the regular expressions interfaces are compiled in
 */
#define LIBXML_REGEXP_ENABLED
#endif

#if 1
/**
 * Whether the automata interfaces are compiled in
 */
#define LIBXML_AUTOMATA_ENABLED
#endif

#if 1
/**
 * Whether the RelaxNG validation interfaces are compiled in
 */
#define LIBXML_RELAXNG_ENABLED
#endif

#if 1
/**
 * Whether the Schemas validation interfaces are compiled in
 */
#define LIBXML_SCHEMAS_ENABLED
#endif

#if 0
/**
 * Whether the Schematron validation interfaces are compiled in
 */
#define LIBXML_SCHEMATRON_ENABLED
#endif

#if 1
/**
 * Whether the module interfaces are compiled in
 */
#define LIBXML_MODULES_ENABLED
/**
 * the string suffix used by dynamic modules (usually shared libraries)
 */
#define LIBXML_MODULE_EXTENSION ".so" 
#endif

#if 0
/**
 * Whether the Zlib support is compiled in
 */
#define LIBXML_ZLIB_ENABLED
#endif

#include <libxml/xmlexports.h>

#endif


libxml2/libxml/pattern.h000064400000005053151733237440011246 0ustar00/**
 * @file
 * 
 * @brief pattern expression handling
 * 
 * allows to compile and test pattern expressions for nodes
 *              either in a tree or based on a parser state.
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */

#ifndef __XML_PATTERN_H__
#define __XML_PATTERN_H__

#include <libxml/xmlversion.h>
#include <libxml/tree.h>
#include <libxml/dict.h>

#ifdef LIBXML_PATTERN_ENABLED

#ifdef __cplusplus
extern "C" {
#endif

/**
 * A compiled (XPath based) pattern to select nodes
 */
typedef struct _xmlPattern xmlPattern;
typedef xmlPattern *xmlPatternPtr;

/**
 * Internal type. This is the set of options affecting the behaviour
 * of pattern matching with this module.
 */
typedef enum {
    XML_PATTERN_DEFAULT		= 0,	/* simple pattern match */
    XML_PATTERN_XPATH		= 1<<0,	/* standard XPath pattern */
    XML_PATTERN_XSSEL		= 1<<1,	/* XPath subset for schema selector */
    XML_PATTERN_XSFIELD		= 1<<2	/* XPath subset for schema field */
} xmlPatternFlags;

XMLPUBFUN void
			xmlFreePattern		(xmlPattern *comp);

XMLPUBFUN void
			xmlFreePatternList	(xmlPattern *comp);

XMLPUBFUN xmlPattern *
			xmlPatterncompile	(const xmlChar *pattern,
						 xmlDict *dict,
						 int flags,
						 const xmlChar **namespaces);
XMLPUBFUN int
			xmlPatternCompileSafe	(const xmlChar *pattern,
						 xmlDict *dict,
						 int flags,
						 const xmlChar **namespaces,
						 xmlPattern **patternOut);
XMLPUBFUN int
			xmlPatternMatch		(xmlPattern *comp,
						 xmlNode *node);

/** State object for streaming interface */
typedef struct _xmlStreamCtxt xmlStreamCtxt;
typedef xmlStreamCtxt *xmlStreamCtxtPtr;

XMLPUBFUN int
			xmlPatternStreamable	(xmlPattern *comp);
XMLPUBFUN int
			xmlPatternMaxDepth	(xmlPattern *comp);
XMLPUBFUN int
			xmlPatternMinDepth	(xmlPattern *comp);
XMLPUBFUN int
			xmlPatternFromRoot	(xmlPattern *comp);
XMLPUBFUN xmlStreamCtxt *
			xmlPatternGetStreamCtxt	(xmlPattern *comp);
XMLPUBFUN void
			xmlFreeStreamCtxt	(xmlStreamCtxt *stream);
XMLPUBFUN int
			xmlStreamPushNode	(xmlStreamCtxt *stream,
						 const xmlChar *name,
						 const xmlChar *ns,
						 int nodeType);
XMLPUBFUN int
			xmlStreamPush		(xmlStreamCtxt *stream,
						 const xmlChar *name,
						 const xmlChar *ns);
XMLPUBFUN int
			xmlStreamPushAttr	(xmlStreamCtxt *stream,
						 const xmlChar *name,
						 const xmlChar *ns);
XMLPUBFUN int
			xmlStreamPop		(xmlStreamCtxt *stream);
XMLPUBFUN int
			xmlStreamWantsAnyNode	(xmlStreamCtxt *stream);
#ifdef __cplusplus
}
#endif

#endif /* LIBXML_PATTERN_ENABLED */

#endif /* __XML_PATTERN_H__ */
libxml2/libxml/xinclude.h000064400000005473151733237440011412 0ustar00/**
 * @file
 *
 * @brief Implementation of XInclude 1.0
 *
 * API to process XML Inclusions.
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */

#ifndef __XML_XINCLUDE_H__
#define __XML_XINCLUDE_H__

#include <libxml/xmlversion.h>
#include <libxml/xmlerror.h>
#include <libxml/tree.h>
#include <libxml/parser.h>

#ifdef LIBXML_XINCLUDE_ENABLED

#ifdef __cplusplus
extern "C" {
#endif

/**
 * Macro defining the Xinclude namespace: http://www.w3.org/2003/XInclude
 */
#define XINCLUDE_NS (const xmlChar *) "http://www.w3.org/2003/XInclude"
/**
 * Macro defining the draft Xinclude namespace: http://www.w3.org/2001/XInclude
 */
#define XINCLUDE_OLD_NS (const xmlChar *) "http://www.w3.org/2001/XInclude"
/**
 * Macro defining "include"
 */
#define XINCLUDE_NODE (const xmlChar *) "include"
/**
 * Macro defining "fallback"
 */
#define XINCLUDE_FALLBACK (const xmlChar *) "fallback"
/**
 * Macro defining "href"
 */
#define XINCLUDE_HREF (const xmlChar *) "href"
/**
 * Macro defining "parse"
 */
#define XINCLUDE_PARSE (const xmlChar *) "parse"
/**
 * Macro defining "xml"
 */
#define XINCLUDE_PARSE_XML (const xmlChar *) "xml"
/**
 * Macro defining "text"
 */
#define XINCLUDE_PARSE_TEXT (const xmlChar *) "text"
/**
 * Macro defining "encoding"
 */
#define XINCLUDE_PARSE_ENCODING (const xmlChar *) "encoding"
/**
 * Macro defining "xpointer"
 */
#define XINCLUDE_PARSE_XPOINTER (const xmlChar *) "xpointer"

/** XInclude context */
typedef struct _xmlXIncludeCtxt xmlXIncludeCtxt;
typedef xmlXIncludeCtxt *xmlXIncludeCtxtPtr;

/*
 * standalone processing
 */
XMLPUBFUN int
		xmlXIncludeProcess	(xmlDoc *doc);
XMLPUBFUN int
		xmlXIncludeProcessFlags	(xmlDoc *doc,
					 int flags);
XMLPUBFUN int
		xmlXIncludeProcessFlagsData(xmlDoc *doc,
					 int flags,
					 void *data);
XMLPUBFUN int
                xmlXIncludeProcessTreeFlagsData(xmlNode *tree,
                                         int flags,
                                         void *data);
XMLPUBFUN int
		xmlXIncludeProcessTree	(xmlNode *tree);
XMLPUBFUN int
		xmlXIncludeProcessTreeFlags(xmlNode *tree,
					 int flags);
/*
 * contextual processing
 */
XMLPUBFUN xmlXIncludeCtxt *
		xmlXIncludeNewContext	(xmlDoc *doc);
XMLPUBFUN int
		xmlXIncludeSetFlags	(xmlXIncludeCtxt *ctxt,
					 int flags);
XMLPUBFUN void
		xmlXIncludeSetErrorHandler(xmlXIncludeCtxt *ctxt,
					 xmlStructuredErrorFunc handler,
					 void *data);
XMLPUBFUN void
		xmlXIncludeSetResourceLoader(xmlXIncludeCtxt *ctxt,
					 xmlResourceLoader loader,
					 void *data);
XMLPUBFUN int
		xmlXIncludeGetLastError	(xmlXIncludeCtxt *ctxt);
XMLPUBFUN void
		xmlXIncludeFreeContext	(xmlXIncludeCtxt *ctxt);
XMLPUBFUN int
		xmlXIncludeProcessNode	(xmlXIncludeCtxt *ctxt,
					 xmlNode *tree);
#ifdef __cplusplus
}
#endif

#endif /* LIBXML_XINCLUDE_ENABLED */

#endif /* __XML_XINCLUDE_H__ */
libxml2/libxml/catalog.h000064400000011643151733237450011206 0ustar00/**
 * @file
 *
 * @brief interfaces to the Catalog handling system
 * 
 * the catalog module implements the support for
 * XML Catalogs and SGML catalogs
 *
 * SGML Open Technical Resolution TR9401:1997.
 * http://www.jclark.com/sp/catalog.htm
 *
 * XML Catalogs Working Draft 06 August 2001
 * http://www.oasis-open.org/committees/entity/spec-2001-08-06.html
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */

#ifndef __XML_CATALOG_H__
#define __XML_CATALOG_H__

#include <stdio.h>

#include <libxml/xmlversion.h>
#include <libxml/xmlstring.h>
#include <libxml/tree.h>

#ifdef LIBXML_CATALOG_ENABLED

#ifdef __cplusplus
extern "C" {
#endif

/**
 * The namespace for the XML Catalogs elements.
 */
#define XML_CATALOGS_NAMESPACE					\
    (const xmlChar *) "urn:oasis:names:tc:entity:xmlns:xml:catalog"
/**
 * The specific XML Catalog Processing Instruction name.
 */
#define XML_CATALOG_PI						\
    (const xmlChar *) "oasis-xml-catalog"

/** @cond ignore */

/*
 * The API is voluntarily limited to general cataloging.
 */
typedef enum {
    XML_CATA_PREFER_NONE = 0,
    XML_CATA_PREFER_PUBLIC = 1,
    XML_CATA_PREFER_SYSTEM
} xmlCatalogPrefer;

typedef enum {
    XML_CATA_ALLOW_NONE = 0,
    XML_CATA_ALLOW_GLOBAL = 1,
    XML_CATA_ALLOW_DOCUMENT = 2,
    XML_CATA_ALLOW_ALL = 3
} xmlCatalogAllow;

/** @endcond */

/** XML catalog */
typedef struct _xmlCatalog xmlCatalog;
typedef xmlCatalog *xmlCatalogPtr;

/*
 * Operations on a given catalog.
 */
XML_DEPRECATED
XMLPUBFUN xmlCatalog *
		xmlNewCatalog		(int sgml);
XML_DEPRECATED
XMLPUBFUN xmlCatalog *
		xmlLoadACatalog		(const char *filename);
#ifdef LIBXML_SGML_CATALOG_ENABLED
XML_DEPRECATED
XMLPUBFUN xmlCatalog *
		xmlLoadSGMLSuperCatalog	(const char *filename);
XML_DEPRECATED
XMLPUBFUN int
		xmlConvertSGMLCatalog	(xmlCatalog *catal);
#endif /* LIBXML_SGML_CATALOG_ENABLED */
XML_DEPRECATED
XMLPUBFUN int
		xmlACatalogAdd		(xmlCatalog *catal,
					 const xmlChar *type,
					 const xmlChar *orig,
					 const xmlChar *replace);
XML_DEPRECATED
XMLPUBFUN int
		xmlACatalogRemove	(xmlCatalog *catal,
					 const xmlChar *value);
XML_DEPRECATED
XMLPUBFUN xmlChar *
		xmlACatalogResolve	(xmlCatalog *catal,
					 const xmlChar *pubID,
	                                 const xmlChar *sysID);
XML_DEPRECATED
XMLPUBFUN xmlChar *
		xmlACatalogResolveSystem(xmlCatalog *catal,
					 const xmlChar *sysID);
XML_DEPRECATED
XMLPUBFUN xmlChar *
		xmlACatalogResolvePublic(xmlCatalog *catal,
					 const xmlChar *pubID);
XML_DEPRECATED
XMLPUBFUN xmlChar *
		xmlACatalogResolveURI	(xmlCatalog *catal,
					 const xmlChar *URI);
#ifdef LIBXML_OUTPUT_ENABLED
XML_DEPRECATED
XMLPUBFUN void
		xmlACatalogDump		(xmlCatalog *catal,
					 FILE *out);
#endif /* LIBXML_OUTPUT_ENABLED */
XML_DEPRECATED
XMLPUBFUN void
		xmlFreeCatalog		(xmlCatalog *catal);
XML_DEPRECATED
XMLPUBFUN int
		xmlCatalogIsEmpty	(xmlCatalog *catal);

/*
 * Global operations.
 */
XMLPUBFUN void
		xmlInitializeCatalog	(void);
XMLPUBFUN int
		xmlLoadCatalog		(const char *filename);
XMLPUBFUN void
		xmlLoadCatalogs		(const char *paths);
XMLPUBFUN void
		xmlCatalogCleanup	(void);
#ifdef LIBXML_OUTPUT_ENABLED
XMLPUBFUN void
		xmlCatalogDump		(FILE *out);
#endif /* LIBXML_OUTPUT_ENABLED */
XMLPUBFUN xmlChar *
		xmlCatalogResolve	(const xmlChar *pubID,
	                                 const xmlChar *sysID);
XMLPUBFUN xmlChar *
		xmlCatalogResolveSystem	(const xmlChar *sysID);
XMLPUBFUN xmlChar *
		xmlCatalogResolvePublic	(const xmlChar *pubID);
XMLPUBFUN xmlChar *
		xmlCatalogResolveURI	(const xmlChar *URI);
XMLPUBFUN int
		xmlCatalogAdd		(const xmlChar *type,
					 const xmlChar *orig,
					 const xmlChar *replace);
XMLPUBFUN int
		xmlCatalogRemove	(const xmlChar *value);
XML_DEPRECATED
XMLPUBFUN xmlDoc *
		xmlParseCatalogFile	(const char *filename);
#ifdef LIBXML_SGML_CATALOG_ENABLED
XML_DEPRECATED
XMLPUBFUN int
		xmlCatalogConvert	(void);
#endif /* LIBXML_SGML_CATALOG_ENABLED */

/*
 * Strictly minimal interfaces for per-document catalogs used
 * by the parser.
 */
XMLPUBFUN void
		xmlCatalogFreeLocal	(void *catalogs);
XMLPUBFUN void *
		xmlCatalogAddLocal	(void *catalogs,
					 const xmlChar *URL);
XMLPUBFUN xmlChar *
		xmlCatalogLocalResolve	(void *catalogs,
					 const xmlChar *pubID,
	                                 const xmlChar *sysID);
XMLPUBFUN xmlChar *
		xmlCatalogLocalResolveURI(void *catalogs,
					 const xmlChar *URI);
/*
 * Preference settings.
 */
XMLPUBFUN int
		xmlCatalogSetDebug	(int level);
XML_DEPRECATED
XMLPUBFUN xmlCatalogPrefer
		xmlCatalogSetDefaultPrefer(xmlCatalogPrefer prefer);
XMLPUBFUN void
		xmlCatalogSetDefaults	(xmlCatalogAllow allow);
XMLPUBFUN xmlCatalogAllow
		xmlCatalogGetDefaults	(void);


/* DEPRECATED interfaces */
XML_DEPRECATED
XMLPUBFUN const xmlChar *
		xmlCatalogGetSystem	(const xmlChar *sysID);
XML_DEPRECATED
XMLPUBFUN const xmlChar *
		xmlCatalogGetPublic	(const xmlChar *pubID);

#ifdef __cplusplus
}
#endif
#endif /* LIBXML_CATALOG_ENABLED */
#endif /* __XML_CATALOG_H__ */
libxml2/libxml/relaxng.h000064400000013647151733237450011242 0ustar00/**
 * @file
 * 
 * @brief implementation of the Relax-NG validation
 * 
 * implementation of the Relax-NG validation
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */

#ifndef __XML_RELAX_NG__
#define __XML_RELAX_NG__

#include <libxml/xmlversion.h>
#include <libxml/xmlerror.h>
#include <libxml/xmlstring.h>
#include <libxml/tree.h>
#include <libxml/parser.h>

#ifdef LIBXML_RELAXNG_ENABLED

#ifdef __cplusplus
extern "C" {
#endif

/** RelaxNG schema */
typedef struct _xmlRelaxNG xmlRelaxNG;
typedef xmlRelaxNG *xmlRelaxNGPtr;


/**
 * Signature of an error callback from a Relax-NG validation
 *
 * @param ctx  the validation context
 * @param msg  the message
 * @param ... extra arguments
 */
typedef void (*xmlRelaxNGValidityErrorFunc) (void *ctx,
						      const char *msg,
						      ...) LIBXML_ATTR_FORMAT(2,3);

/**
 * Signature of a warning callback from a Relax-NG validation
 *
 * @param ctx  the validation context
 * @param msg  the message
 * @param ... extra arguments
 */
typedef void (*xmlRelaxNGValidityWarningFunc) (void *ctx,
							const char *msg,
							...) LIBXML_ATTR_FORMAT(2,3);

/** RelaxNG parser context */
typedef struct _xmlRelaxNGParserCtxt xmlRelaxNGParserCtxt;
typedef xmlRelaxNGParserCtxt *xmlRelaxNGParserCtxtPtr;

/** RelaxNG validation context */
typedef struct _xmlRelaxNGValidCtxt xmlRelaxNGValidCtxt;
typedef xmlRelaxNGValidCtxt *xmlRelaxNGValidCtxtPtr;

/**
 * List of possible Relax NG validation errors
 */
typedef enum {
    XML_RELAXNG_OK = 0,
    XML_RELAXNG_ERR_MEMORY,
    XML_RELAXNG_ERR_TYPE,
    XML_RELAXNG_ERR_TYPEVAL,
    XML_RELAXNG_ERR_DUPID,
    XML_RELAXNG_ERR_TYPECMP,
    XML_RELAXNG_ERR_NOSTATE,
    XML_RELAXNG_ERR_NODEFINE,
    XML_RELAXNG_ERR_LISTEXTRA,
    XML_RELAXNG_ERR_LISTEMPTY,
    XML_RELAXNG_ERR_INTERNODATA,
    XML_RELAXNG_ERR_INTERSEQ,
    XML_RELAXNG_ERR_INTEREXTRA,
    XML_RELAXNG_ERR_ELEMNAME,
    XML_RELAXNG_ERR_ATTRNAME,
    XML_RELAXNG_ERR_ELEMNONS,
    XML_RELAXNG_ERR_ATTRNONS,
    XML_RELAXNG_ERR_ELEMWRONGNS,
    XML_RELAXNG_ERR_ATTRWRONGNS,
    XML_RELAXNG_ERR_ELEMEXTRANS,
    XML_RELAXNG_ERR_ATTREXTRANS,
    XML_RELAXNG_ERR_ELEMNOTEMPTY,
    XML_RELAXNG_ERR_NOELEM,
    XML_RELAXNG_ERR_NOTELEM,
    XML_RELAXNG_ERR_ATTRVALID,
    XML_RELAXNG_ERR_CONTENTVALID,
    XML_RELAXNG_ERR_EXTRACONTENT,
    XML_RELAXNG_ERR_INVALIDATTR,
    XML_RELAXNG_ERR_DATAELEM,
    XML_RELAXNG_ERR_VALELEM,
    XML_RELAXNG_ERR_LISTELEM,
    XML_RELAXNG_ERR_DATATYPE,
    XML_RELAXNG_ERR_VALUE,
    XML_RELAXNG_ERR_LIST,
    XML_RELAXNG_ERR_NOGRAMMAR,
    XML_RELAXNG_ERR_EXTRADATA,
    XML_RELAXNG_ERR_LACKDATA,
    XML_RELAXNG_ERR_INTERNAL,
    XML_RELAXNG_ERR_ELEMWRONG,
    XML_RELAXNG_ERR_TEXTWRONG
} xmlRelaxNGValidErr;

/**
 * List of possible Relax NG Parser flags
 */
typedef enum {
    XML_RELAXNGP_NONE = 0,
    XML_RELAXNGP_FREE_DOC = 1,
    XML_RELAXNGP_CRNG = 2
} xmlRelaxNGParserFlag;

XMLPUBFUN int
		    xmlRelaxNGInitTypes		(void);
XML_DEPRECATED
XMLPUBFUN void
		    xmlRelaxNGCleanupTypes	(void);

/*
 * Interfaces for parsing.
 */
XMLPUBFUN xmlRelaxNGParserCtxt *
		    xmlRelaxNGNewParserCtxt	(const char *URL);
XMLPUBFUN xmlRelaxNGParserCtxt *
		    xmlRelaxNGNewMemParserCtxt	(const char *buffer,
						 int size);
XMLPUBFUN xmlRelaxNGParserCtxt *
		    xmlRelaxNGNewDocParserCtxt	(xmlDoc *doc);

XMLPUBFUN int
		    xmlRelaxParserSetFlag	(xmlRelaxNGParserCtxt *ctxt,
						 int flag);

XMLPUBFUN void
		    xmlRelaxNGFreeParserCtxt	(xmlRelaxNGParserCtxt *ctxt);
XMLPUBFUN void
		    xmlRelaxNGSetParserErrors(xmlRelaxNGParserCtxt *ctxt,
					 xmlRelaxNGValidityErrorFunc err,
					 xmlRelaxNGValidityWarningFunc warn,
					 void *ctx);
XMLPUBFUN int
		    xmlRelaxNGGetParserErrors(xmlRelaxNGParserCtxt *ctxt,
					 xmlRelaxNGValidityErrorFunc *err,
					 xmlRelaxNGValidityWarningFunc *warn,
					 void **ctx);
XMLPUBFUN void
		    xmlRelaxNGSetParserStructuredErrors(
					 xmlRelaxNGParserCtxt *ctxt,
					 xmlStructuredErrorFunc serror,
					 void *ctx);
XMLPUBFUN void
		    xmlRelaxNGSetResourceLoader	(xmlRelaxNGParserCtxt *ctxt,
						 xmlResourceLoader loader,
						 void *vctxt);
XMLPUBFUN xmlRelaxNG *
		    xmlRelaxNGParse		(xmlRelaxNGParserCtxt *ctxt);
XMLPUBFUN void
		    xmlRelaxNGFree		(xmlRelaxNG *schema);
#ifdef LIBXML_DEBUG_ENABLED
XMLPUBFUN void
		    xmlRelaxNGDump		(FILE *output,
					 xmlRelaxNG *schema);
#endif /* LIBXML_DEBUG_ENABLED */
#ifdef LIBXML_OUTPUT_ENABLED
XMLPUBFUN void
		    xmlRelaxNGDumpTree	(FILE * output,
					 xmlRelaxNG *schema);
#endif /* LIBXML_OUTPUT_ENABLED */
/*
 * Interfaces for validating
 */
XMLPUBFUN void
		    xmlRelaxNGSetValidErrors(xmlRelaxNGValidCtxt *ctxt,
					 xmlRelaxNGValidityErrorFunc err,
					 xmlRelaxNGValidityWarningFunc warn,
					 void *ctx);
XMLPUBFUN int
		    xmlRelaxNGGetValidErrors(xmlRelaxNGValidCtxt *ctxt,
					 xmlRelaxNGValidityErrorFunc *err,
					 xmlRelaxNGValidityWarningFunc *warn,
					 void **ctx);
XMLPUBFUN void
			xmlRelaxNGSetValidStructuredErrors(xmlRelaxNGValidCtxt *ctxt,
					  xmlStructuredErrorFunc serror, void *ctx);
XMLPUBFUN xmlRelaxNGValidCtxt *
		    xmlRelaxNGNewValidCtxt	(xmlRelaxNG *schema);
XMLPUBFUN void
		    xmlRelaxNGFreeValidCtxt	(xmlRelaxNGValidCtxt *ctxt);
XMLPUBFUN int
		    xmlRelaxNGValidateDoc	(xmlRelaxNGValidCtxt *ctxt,
						 xmlDoc *doc);
/*
 * Interfaces for progressive validation when possible
 */
XMLPUBFUN int
		    xmlRelaxNGValidatePushElement	(xmlRelaxNGValidCtxt *ctxt,
					 xmlDoc *doc,
					 xmlNode *elem);
XMLPUBFUN int
		    xmlRelaxNGValidatePushCData	(xmlRelaxNGValidCtxt *ctxt,
					 const xmlChar *data,
					 int len);
XMLPUBFUN int
		    xmlRelaxNGValidatePopElement	(xmlRelaxNGValidCtxt *ctxt,
					 xmlDoc *doc,
					 xmlNode *elem);
XMLPUBFUN int
		    xmlRelaxNGValidateFullElement	(xmlRelaxNGValidCtxt *ctxt,
					 xmlDoc *doc,
					 xmlNode *elem);
XMLPUBFUN void
                    xmlRelaxNGValidCtxtClearErrors(xmlRelaxNGValidCtxt* ctxt);

#ifdef __cplusplus
}
#endif

#endif /* LIBXML_RELAXNG_ENABLED */

#endif /* __XML_RELAX_NG__ */
libxml2/libxml/xmlregexp.h000064400000004625151733237450011611 0ustar00/**
 * @file
 * 
 * @brief Regular expressions
 * 
 * A regular expression engine used for DTD and XML Schema
 * validation.
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */

#ifndef __XML_REGEXP_H__
#define __XML_REGEXP_H__

#include <stdio.h>
#include <libxml/xmlversion.h>
#include <libxml/xmlstring.h>

#ifdef LIBXML_REGEXP_ENABLED

#ifdef __cplusplus
extern "C" {
#endif

/**
 * A libxml regular expression
 */
typedef struct _xmlRegexp xmlRegexp;
typedef xmlRegexp *xmlRegexpPtr;

/**
 * A libxml progressive regular expression evaluation context
 */
typedef struct _xmlRegExecCtxt xmlRegExecCtxt;
typedef xmlRegExecCtxt *xmlRegExecCtxtPtr;

/*
 * The POSIX like API
 */
XMLPUBFUN xmlRegexp *
		    xmlRegexpCompile	(const xmlChar *regexp);
XMLPUBFUN void			 xmlRegFreeRegexp(xmlRegexp *regexp);
XMLPUBFUN int
		    xmlRegexpExec	(xmlRegexp *comp,
					 const xmlChar *value);
XML_DEPRECATED
XMLPUBFUN void
		    xmlRegexpPrint	(FILE *output,
					 xmlRegexp *regexp);
XMLPUBFUN int
		    xmlRegexpIsDeterminist(xmlRegexp *comp);

/**
 * Callback function when doing a transition in the automata
 *
 * @param exec  the regular expression context
 * @param token  the current token string
 * @param transdata  transition data
 * @param inputdata  input data
 */
typedef void (*xmlRegExecCallbacks) (xmlRegExecCtxt *exec,
	                             const xmlChar *token,
				     void *transdata,
				     void *inputdata);

/*
 * The progressive API
 */
XML_DEPRECATED
XMLPUBFUN xmlRegExecCtxt *
		    xmlRegNewExecCtxt	(xmlRegexp *comp,
					 xmlRegExecCallbacks callback,
					 void *data);
XML_DEPRECATED
XMLPUBFUN void
		    xmlRegFreeExecCtxt	(xmlRegExecCtxt *exec);
XML_DEPRECATED
XMLPUBFUN int
		    xmlRegExecPushString(xmlRegExecCtxt *exec,
					 const xmlChar *value,
					 void *data);
XML_DEPRECATED
XMLPUBFUN int
		    xmlRegExecPushString2(xmlRegExecCtxt *exec,
					 const xmlChar *value,
					 const xmlChar *value2,
					 void *data);

XML_DEPRECATED
XMLPUBFUN int
		    xmlRegExecNextValues(xmlRegExecCtxt *exec,
					 int *nbval,
					 int *nbneg,
					 xmlChar **values,
					 int *terminal);
XML_DEPRECATED
XMLPUBFUN int
		    xmlRegExecErrInfo	(xmlRegExecCtxt *exec,
					 const xmlChar **string,
					 int *nbval,
					 int *nbneg,
					 xmlChar **values,
					 int *terminal);

#ifdef __cplusplus
}
#endif

#endif /* LIBXML_REGEXP_ENABLED */

#endif /*__XML_REGEXP_H__ */
libxml2/libxml/entities.h000064400000010433151733237450011414 0ustar00/**
 * @file
 * 
 * @brief XML entities
 * 
 * This module provides an API to work with XML entities.
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */

#ifndef __XML_ENTITIES_H__
#define __XML_ENTITIES_H__

#include <libxml/xmlversion.h>
#define XML_TREE_INTERNALS
#include <libxml/tree.h>
#undef XML_TREE_INTERNALS

#ifdef __cplusplus
extern "C" {
#endif

/**
 * The different entity types.
 */
typedef enum {
    /** internal general entity */
    XML_INTERNAL_GENERAL_ENTITY = 1,
    /** external general parsed entity */
    XML_EXTERNAL_GENERAL_PARSED_ENTITY = 2,
    /** external general unparsed entity */
    XML_EXTERNAL_GENERAL_UNPARSED_ENTITY = 3,
    /** internal parameter entity */
    XML_INTERNAL_PARAMETER_ENTITY = 4,
    /** external parameter entity */
    XML_EXTERNAL_PARAMETER_ENTITY = 5,
    /** internal predefined entity */
    XML_INTERNAL_PREDEFINED_ENTITY = 6
} xmlEntityType;

/**
 * An entity declaration
 */
struct _xmlEntity {
    /** application data */
    void           *_private;
    /** XML_ENTITY_DECL, must be second ! */
    xmlElementType          type;
    /** Entity name */
    const xmlChar          *name;
    /** First child link */
    struct _xmlNode    *children;
    /** Last child link */
    struct _xmlNode        *last;
    /** -> DTD */
    struct _xmlDtd       *parent;
    /** next sibling link  */
    struct _xmlNode        *next;
    /** previous sibling link  */
    struct _xmlNode        *prev;
    /** the containing document */
    struct _xmlDoc          *doc;

    /** content without ref substitution */
    xmlChar                *orig;
    /** content or ndata if unparsed */
    xmlChar             *content;
    /** the content length */
    int                   length;
    /** The entity type */
    xmlEntityType          etype;
    /** External identifier for PUBLIC */
    const xmlChar    *ExternalID;
    /** URI for a SYSTEM or PUBLIC Entity */
    const xmlChar      *SystemID;

    /** unused */
    struct _xmlEntity     *nexte;
    /** the full URI as computed */
    const xmlChar           *URI;
    /** unused */
    int                    owner;
    /** various flags */
    int                    flags;
    /** expanded size */
    unsigned long   expandedSize;
};

typedef struct _xmlHashTable xmlEntitiesTable;
typedef xmlEntitiesTable *xmlEntitiesTablePtr;

XMLPUBFUN xmlEntity *
			xmlNewEntity		(xmlDoc *doc,
						 const xmlChar *name,
						 int type,
						 const xmlChar *publicId,
						 const xmlChar *systemId,
						 const xmlChar *content);
XMLPUBFUN void
			xmlFreeEntity		(xmlEntity *entity);
XMLPUBFUN int
			xmlAddEntity		(xmlDoc *doc,
						 int extSubset,
						 const xmlChar *name,
						 int type,
						 const xmlChar *publicId,
						 const xmlChar *systemId,
						 const xmlChar *content,
						 xmlEntity **out);
XMLPUBFUN xmlEntity *
			xmlAddDocEntity		(xmlDoc *doc,
						 const xmlChar *name,
						 int type,
						 const xmlChar *publicId,
						 const xmlChar *systemId,
						 const xmlChar *content);
XMLPUBFUN xmlEntity *
			xmlAddDtdEntity		(xmlDoc *doc,
						 const xmlChar *name,
						 int type,
						 const xmlChar *publicId,
						 const xmlChar *systemId,
						 const xmlChar *content);
XMLPUBFUN xmlEntity *
			xmlGetPredefinedEntity	(const xmlChar *name);
XMLPUBFUN xmlEntity *
			xmlGetDocEntity		(const xmlDoc *doc,
						 const xmlChar *name);
XMLPUBFUN xmlEntity *
			xmlGetDtdEntity		(xmlDoc *doc,
						 const xmlChar *name);
XMLPUBFUN xmlEntity *
			xmlGetParameterEntity	(xmlDoc *doc,
						 const xmlChar *name);
XMLPUBFUN xmlChar *
			xmlEncodeEntitiesReentrant(xmlDoc *doc,
						 const xmlChar *input);
XMLPUBFUN xmlChar *
			xmlEncodeSpecialChars	(const xmlDoc *doc,
						 const xmlChar *input);
XML_DEPRECATED
XMLPUBFUN xmlEntitiesTable *
			xmlCreateEntitiesTable	(void);
XML_DEPRECATED
XMLPUBFUN xmlEntitiesTable *
			xmlCopyEntitiesTable	(xmlEntitiesTable *table);
XML_DEPRECATED
XMLPUBFUN void
			xmlFreeEntitiesTable	(xmlEntitiesTable *table);
#ifdef LIBXML_OUTPUT_ENABLED
XML_DEPRECATED
XMLPUBFUN void
			xmlDumpEntitiesTable	(xmlBuffer *buf,
						 xmlEntitiesTable *table);
XML_DEPRECATED
XMLPUBFUN void
			xmlDumpEntityDecl	(xmlBuffer *buf,
						 xmlEntity *ent);
#endif /* LIBXML_OUTPUT_ENABLED */

#ifdef __cplusplus
}
#endif

# endif /* __XML_ENTITIES_H__ */
libxml2/libxml/xmlIO.h000064400000026512151733237450010625 0ustar00/**
 * @file
 * 
 * @brief I/O interfaces used by the parser
 * 
 * Functions and datatypes for parser input and output.
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */

#ifndef __XML_IO_H__
#define __XML_IO_H__

#include <stdio.h>
#include <libxml/xmlversion.h>
#include <libxml/encoding.h>
#define XML_TREE_INTERNALS
#include <libxml/tree.h>
#undef XML_TREE_INTERNALS

#ifdef __cplusplus
extern "C" {
#endif

/**
 * Callback used in the I/O Input API to detect if the current handler
 * can provide input functionality for this resource.
 *
 * @param filename  the filename or URI
 * @returns 1 if yes and 0 if another Input module should be used
 */
typedef int (*xmlInputMatchCallback) (const char *filename);
/**
 * Callback used in the I/O Input API to open the resource
 *
 * @param filename  the filename or URI
 * @returns an Input context or NULL in case or error
 */
typedef void * (*xmlInputOpenCallback) (const char *filename);
/**
 * Callback used in the I/O Input API to read the resource
 *
 * @param context  an Input context
 * @param buffer  the buffer to store data read
 * @param len  the length of the buffer in bytes
 * @returns the number of bytes read or -1 in case of error
 */
typedef int (*xmlInputReadCallback) (void * context, char * buffer, int len);
/**
 * Callback used in the I/O Input API to close the resource
 *
 * @param context  an Input context
 * @returns 0 or -1 in case of error
 */
typedef int (*xmlInputCloseCallback) (void * context);

#ifdef LIBXML_OUTPUT_ENABLED
/**
 * Callback used in the I/O Output API to detect if the current handler
 * can provide output functionality for this resource.
 *
 * @param filename  the filename or URI
 * @returns 1 if yes and 0 if another Output module should be used
 */
typedef int (*xmlOutputMatchCallback) (const char *filename);
/**
 * Callback used in the I/O Output API to open the resource
 *
 * @param filename  the filename or URI
 * @returns an Output context or NULL in case or error
 */
typedef void * (*xmlOutputOpenCallback) (const char *filename);
/**
 * Callback used in the I/O Output API to write to the resource
 *
 * @param context  an Output context
 * @param buffer  the buffer of data to write
 * @param len  the length of the buffer in bytes
 * @returns the number of bytes written or -1 in case of error
 */
typedef int (*xmlOutputWriteCallback) (void * context, const char * buffer,
                                       int len);
/**
 * Callback used in the I/O Output API to close the resource
 *
 * @param context  an Output context
 * @returns 0 or -1 in case of error
 */
typedef int (*xmlOutputCloseCallback) (void * context);
#endif /* LIBXML_OUTPUT_ENABLED */

/**
 * Signature for the function doing the lookup for a suitable input method
 * corresponding to an URI.
 *
 * @param URI  the URI to read from
 * @param enc  the requested source encoding
 * @returns the new xmlParserInputBuffer in case of success or NULL if no
 *         method was found.
 */
typedef xmlParserInputBuffer *
(*xmlParserInputBufferCreateFilenameFunc)(const char *URI, xmlCharEncoding enc);

/**
 * Signature for the function doing the lookup for a suitable output method
 * corresponding to an URI.
 *
 * @param URI  the URI to write to
 * @param encoder  the requested target encoding
 * @param compression  compression level
 * @returns the new xmlOutputBuffer in case of success or NULL if no
 *         method was found.
 */
typedef xmlOutputBuffer *
(*xmlOutputBufferCreateFilenameFunc)(const char *URI,
        xmlCharEncodingHandler *encoder, int compression);

/**
 * Parser input buffer
 *
 * This struct and all related functions should ultimately
 * be removed from the public interface.
 */
struct _xmlParserInputBuffer {
    void*                  context XML_DEPRECATED_MEMBER;
    xmlInputReadCallback   readcallback XML_DEPRECATED_MEMBER;
    xmlInputCloseCallback  closecallback XML_DEPRECATED_MEMBER;

    /* I18N conversions to UTF-8 */
    xmlCharEncodingHandler *encoder XML_DEPRECATED_MEMBER;

    /* Local buffer encoded in UTF-8 */
    xmlBuf *buffer XML_DEPRECATED_MEMBER;
    /* if encoder != NULL buffer for raw input */
    xmlBuf *raw XML_DEPRECATED_MEMBER;
    /* -1=unknown, 0=not compressed, 1=compressed */
    int	compressed XML_DEPRECATED_MEMBER;
    int error XML_DEPRECATED_MEMBER;
    /* amount consumed from raw */
    unsigned long rawconsumed XML_DEPRECATED_MEMBER;
};


#ifdef LIBXML_OUTPUT_ENABLED
/**
 * Output buffer
 */
struct _xmlOutputBuffer {
    void*                   context;
    xmlOutputWriteCallback  writecallback;
    xmlOutputCloseCallback  closecallback;

    /* I18N conversions to UTF-8 */
    xmlCharEncodingHandler *encoder;

    /* Local buffer encoded in UTF-8 or ISOLatin */
    xmlBuf *buffer;
    /* if encoder != NULL buffer for output */
    xmlBuf *conv;
    /* total number of byte written */
    int written;
    int error;
};
#endif /* LIBXML_OUTPUT_ENABLED */

/** @cond ignore */

XML_DEPRECATED
XMLPUBFUN xmlParserInputBufferCreateFilenameFunc *
__xmlParserInputBufferCreateFilenameValue(void);
XML_DEPRECATED
XMLPUBFUN xmlOutputBufferCreateFilenameFunc *
__xmlOutputBufferCreateFilenameValue(void);

#ifndef XML_GLOBALS_NO_REDEFINITION
  #define xmlParserInputBufferCreateFilenameValue \
    (*__xmlParserInputBufferCreateFilenameValue())
  #define xmlOutputBufferCreateFilenameValue \
    (*__xmlOutputBufferCreateFilenameValue())
#endif

/** @endcond */

/*
 * Interfaces for input
 */
XMLPUBFUN void
	xmlCleanupInputCallbacks		(void);

XMLPUBFUN int
	xmlPopInputCallbacks			(void);

XMLPUBFUN void
	xmlRegisterDefaultInputCallbacks	(void);
XMLPUBFUN xmlParserInputBuffer *
	xmlAllocParserInputBuffer		(xmlCharEncoding enc);

XMLPUBFUN xmlParserInputBuffer *
	xmlParserInputBufferCreateFilename	(const char *URI,
                                                 xmlCharEncoding enc);
XML_DEPRECATED
XMLPUBFUN xmlParserInputBuffer *
	xmlParserInputBufferCreateFile		(FILE *file,
                                                 xmlCharEncoding enc);
XMLPUBFUN xmlParserInputBuffer *
	xmlParserInputBufferCreateFd		(int fd,
	                                         xmlCharEncoding enc);
XMLPUBFUN xmlParserInputBuffer *
	xmlParserInputBufferCreateMem		(const char *mem, int size,
	                                         xmlCharEncoding enc);
XMLPUBFUN xmlParserInputBuffer *
	xmlParserInputBufferCreateStatic	(const char *mem, int size,
	                                         xmlCharEncoding enc);
XMLPUBFUN xmlParserInputBuffer *
	xmlParserInputBufferCreateIO		(xmlInputReadCallback   ioread,
						 xmlInputCloseCallback  ioclose,
						 void *ioctx,
	                                         xmlCharEncoding enc);
XML_DEPRECATED
XMLPUBFUN int
	xmlParserInputBufferRead		(xmlParserInputBuffer *in,
						 int len);
XML_DEPRECATED
XMLPUBFUN int
	xmlParserInputBufferGrow		(xmlParserInputBuffer *in,
						 int len);
XML_DEPRECATED
XMLPUBFUN int
	xmlParserInputBufferPush		(xmlParserInputBuffer *in,
						 int len,
						 const char *buf);
XMLPUBFUN void
	xmlFreeParserInputBuffer		(xmlParserInputBuffer *in);
XMLPUBFUN char *
	xmlParserGetDirectory			(const char *filename);

XMLPUBFUN int
	xmlRegisterInputCallbacks		(xmlInputMatchCallback matchFunc,
						 xmlInputOpenCallback openFunc,
						 xmlInputReadCallback readFunc,
						 xmlInputCloseCallback closeFunc);

XMLPUBFUN xmlParserInputBuffer *
	__xmlParserInputBufferCreateFilename(const char *URI,
						xmlCharEncoding enc);

#ifdef LIBXML_OUTPUT_ENABLED
/*
 * Interfaces for output
 */
XMLPUBFUN void
	xmlCleanupOutputCallbacks		(void);
XMLPUBFUN int
	xmlPopOutputCallbacks			(void);
XMLPUBFUN void
	xmlRegisterDefaultOutputCallbacks(void);
XMLPUBFUN xmlOutputBuffer *
	xmlAllocOutputBuffer		(xmlCharEncodingHandler *encoder);

XMLPUBFUN xmlOutputBuffer *
	xmlOutputBufferCreateFilename	(const char *URI,
					 xmlCharEncodingHandler *encoder,
					 int compression);

XMLPUBFUN xmlOutputBuffer *
	xmlOutputBufferCreateFile	(FILE *file,
					 xmlCharEncodingHandler *encoder);

XMLPUBFUN xmlOutputBuffer *
	xmlOutputBufferCreateBuffer	(xmlBuffer *buffer,
					 xmlCharEncodingHandler *encoder);

XMLPUBFUN xmlOutputBuffer *
	xmlOutputBufferCreateFd		(int fd,
					 xmlCharEncodingHandler *encoder);

XMLPUBFUN xmlOutputBuffer *
	xmlOutputBufferCreateIO		(xmlOutputWriteCallback   iowrite,
					 xmlOutputCloseCallback  ioclose,
					 void *ioctx,
					 xmlCharEncodingHandler *encoder);

/* Couple of APIs to get the output without digging into the buffers */
XMLPUBFUN const xmlChar *
        xmlOutputBufferGetContent       (xmlOutputBuffer *out);
XMLPUBFUN size_t
        xmlOutputBufferGetSize          (xmlOutputBuffer *out);

XMLPUBFUN int
	xmlOutputBufferWrite		(xmlOutputBuffer *out,
					 int len,
					 const char *buf);
XMLPUBFUN int
	xmlOutputBufferWriteString	(xmlOutputBuffer *out,
					 const char *str);
XMLPUBFUN int
	xmlOutputBufferWriteEscape	(xmlOutputBuffer *out,
					 const xmlChar *str,
					 xmlCharEncodingOutputFunc escaping);

XMLPUBFUN int
	xmlOutputBufferFlush		(xmlOutputBuffer *out);
XMLPUBFUN int
	xmlOutputBufferClose		(xmlOutputBuffer *out);

XMLPUBFUN int
	xmlRegisterOutputCallbacks	(xmlOutputMatchCallback matchFunc,
					 xmlOutputOpenCallback openFunc,
					 xmlOutputWriteCallback writeFunc,
					 xmlOutputCloseCallback closeFunc);

XMLPUBFUN xmlOutputBuffer *
	__xmlOutputBufferCreateFilename(const char *URI,
                              xmlCharEncodingHandler *encoder,
                              int compression);
#endif /* LIBXML_OUTPUT_ENABLED */

XML_DEPRECATED
XMLPUBFUN xmlParserInput *
	xmlCheckHTTPInput		(xmlParserCtxt *ctxt,
					 xmlParserInput *ret);

XML_DEPRECATED
XMLPUBFUN xmlParserInput *
	xmlNoNetExternalEntityLoader	(const char *URL,
					 const char *ID,
					 xmlParserCtxt *ctxt);

XML_DEPRECATED
XMLPUBFUN xmlChar *
	xmlNormalizeWindowsPath		(const xmlChar *path);

XML_DEPRECATED
XMLPUBFUN int
	xmlCheckFilename		(const char *path);

XML_DEPRECATED
XMLPUBFUN int
	xmlFileMatch			(const char *filename);
XML_DEPRECATED
XMLPUBFUN void *
	xmlFileOpen			(const char *filename);
XML_DEPRECATED
XMLPUBFUN int
	xmlFileRead			(void * context,
					 char * buffer,
					 int len);
XML_DEPRECATED
XMLPUBFUN int
	xmlFileClose			(void * context);

#ifdef LIBXML_HTTP_STUBS_ENABLED
/** @cond IGNORE */
XML_DEPRECATED
XMLPUBFUN int
	xmlIOHTTPMatch			(const char *filename);
XML_DEPRECATED
XMLPUBFUN void *
	xmlIOHTTPOpen			(const char *filename);
#ifdef LIBXML_OUTPUT_ENABLED
XML_DEPRECATED
XMLPUBFUN void
	xmlRegisterHTTPPostCallbacks	(void );
XML_DEPRECATED
XMLPUBFUN void *
	xmlIOHTTPOpenW			(const char * post_uri,
					 int   compression );
#endif /* LIBXML_OUTPUT_ENABLED */
XML_DEPRECATED
XMLPUBFUN int
	xmlIOHTTPRead			(void * context,
					 char * buffer,
					 int len);
XML_DEPRECATED
XMLPUBFUN int
	xmlIOHTTPClose			(void * context);
/** @endcond */
#endif /* LIBXML_HTTP_STUBS_ENABLED */

XMLPUBFUN xmlParserInputBufferCreateFilenameFunc
	xmlParserInputBufferCreateFilenameDefault(
		xmlParserInputBufferCreateFilenameFunc func);
XMLPUBFUN xmlOutputBufferCreateFilenameFunc
	xmlOutputBufferCreateFilenameDefault(
		xmlOutputBufferCreateFilenameFunc func);
XML_DEPRECATED
XMLPUBFUN xmlOutputBufferCreateFilenameFunc
	xmlThrDefOutputBufferCreateFilenameDefault(
		xmlOutputBufferCreateFilenameFunc func);
XML_DEPRECATED
XMLPUBFUN xmlParserInputBufferCreateFilenameFunc
	xmlThrDefParserInputBufferCreateFilenameDefault(
		xmlParserInputBufferCreateFilenameFunc func);

#ifdef __cplusplus
}
#endif

#endif /* __XML_IO_H__ */
libxml2/libxml/schemasInternals.h000064400000055334151733237450013104 0ustar00/**
 * @file
 * 
 * @brief internal interfaces for XML Schemas
 * 
 * internal interfaces for the XML Schemas handling
 *              and schema validity checking
 *		The Schemas development is a Work In Progress.
 *              Some of those interfaces are not guaranteed to be API or ABI stable !
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */


#ifndef __XML_SCHEMA_INTERNALS_H__
#define __XML_SCHEMA_INTERNALS_H__

#include <libxml/xmlversion.h>

#ifdef LIBXML_SCHEMAS_ENABLED

#include <libxml/xmlregexp.h>
#include <libxml/hash.h>
#include <libxml/dict.h>
#include <libxml/tree.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * Schema value type
 */
typedef enum {
    XML_SCHEMAS_UNKNOWN = 0,
    XML_SCHEMAS_STRING = 1,
    XML_SCHEMAS_NORMSTRING = 2,
    XML_SCHEMAS_DECIMAL = 3,
    XML_SCHEMAS_TIME = 4,
    XML_SCHEMAS_GDAY = 5,
    XML_SCHEMAS_GMONTH = 6,
    XML_SCHEMAS_GMONTHDAY = 7,
    XML_SCHEMAS_GYEAR = 8,
    XML_SCHEMAS_GYEARMONTH = 9,
    XML_SCHEMAS_DATE = 10,
    XML_SCHEMAS_DATETIME = 11,
    XML_SCHEMAS_DURATION = 12,
    XML_SCHEMAS_FLOAT = 13,
    XML_SCHEMAS_DOUBLE = 14,
    XML_SCHEMAS_BOOLEAN = 15,
    XML_SCHEMAS_TOKEN = 16,
    XML_SCHEMAS_LANGUAGE = 17,
    XML_SCHEMAS_NMTOKEN = 18,
    XML_SCHEMAS_NMTOKENS = 19,
    XML_SCHEMAS_NAME = 20,
    XML_SCHEMAS_QNAME = 21,
    XML_SCHEMAS_NCNAME = 22,
    XML_SCHEMAS_ID = 23,
    XML_SCHEMAS_IDREF = 24,
    XML_SCHEMAS_IDREFS = 25,
    XML_SCHEMAS_ENTITY = 26,
    XML_SCHEMAS_ENTITIES = 27,
    XML_SCHEMAS_NOTATION = 28,
    XML_SCHEMAS_ANYURI = 29,
    XML_SCHEMAS_INTEGER = 30,
    XML_SCHEMAS_NPINTEGER = 31,
    XML_SCHEMAS_NINTEGER = 32,
    XML_SCHEMAS_NNINTEGER = 33,
    XML_SCHEMAS_PINTEGER = 34,
    XML_SCHEMAS_INT = 35,
    XML_SCHEMAS_UINT = 36,
    XML_SCHEMAS_LONG = 37,
    XML_SCHEMAS_ULONG = 38,
    XML_SCHEMAS_SHORT = 39,
    XML_SCHEMAS_USHORT = 40,
    XML_SCHEMAS_BYTE = 41,
    XML_SCHEMAS_UBYTE = 42,
    XML_SCHEMAS_HEXBINARY = 43,
    XML_SCHEMAS_BASE64BINARY = 44,
    XML_SCHEMAS_ANYTYPE = 45,
    XML_SCHEMAS_ANYSIMPLETYPE = 46
} xmlSchemaValType;

/**
 * XML Schemas defines multiple type of types.
 */
typedef enum {
    XML_SCHEMA_TYPE_BASIC = 1, /* A built-in datatype */
    XML_SCHEMA_TYPE_ANY,
    XML_SCHEMA_TYPE_FACET,
    XML_SCHEMA_TYPE_SIMPLE,
    XML_SCHEMA_TYPE_COMPLEX,
    XML_SCHEMA_TYPE_SEQUENCE = 6,
    XML_SCHEMA_TYPE_CHOICE,
    XML_SCHEMA_TYPE_ALL,
    XML_SCHEMA_TYPE_SIMPLE_CONTENT,
    XML_SCHEMA_TYPE_COMPLEX_CONTENT,
    XML_SCHEMA_TYPE_UR,
    XML_SCHEMA_TYPE_RESTRICTION,
    XML_SCHEMA_TYPE_EXTENSION,
    XML_SCHEMA_TYPE_ELEMENT,
    XML_SCHEMA_TYPE_ATTRIBUTE,
    XML_SCHEMA_TYPE_ATTRIBUTEGROUP,
    XML_SCHEMA_TYPE_GROUP,
    XML_SCHEMA_TYPE_NOTATION,
    XML_SCHEMA_TYPE_LIST,
    XML_SCHEMA_TYPE_UNION,
    XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
    XML_SCHEMA_TYPE_IDC_UNIQUE,
    XML_SCHEMA_TYPE_IDC_KEY,
    XML_SCHEMA_TYPE_IDC_KEYREF,
    XML_SCHEMA_TYPE_PARTICLE = 25,
    XML_SCHEMA_TYPE_ATTRIBUTE_USE,
    XML_SCHEMA_FACET_MININCLUSIVE = 1000,
    XML_SCHEMA_FACET_MINEXCLUSIVE,
    XML_SCHEMA_FACET_MAXINCLUSIVE,
    XML_SCHEMA_FACET_MAXEXCLUSIVE,
    XML_SCHEMA_FACET_TOTALDIGITS,
    XML_SCHEMA_FACET_FRACTIONDIGITS,
    XML_SCHEMA_FACET_PATTERN,
    XML_SCHEMA_FACET_ENUMERATION,
    XML_SCHEMA_FACET_WHITESPACE,
    XML_SCHEMA_FACET_LENGTH,
    XML_SCHEMA_FACET_MAXLENGTH,
    XML_SCHEMA_FACET_MINLENGTH,
    XML_SCHEMA_EXTRA_QNAMEREF = 2000,
    XML_SCHEMA_EXTRA_ATTR_USE_PROHIB
} xmlSchemaTypeType;

/**
 * Schema content type
 */
typedef enum {
    XML_SCHEMA_CONTENT_UNKNOWN = 0,
    XML_SCHEMA_CONTENT_EMPTY = 1,
    XML_SCHEMA_CONTENT_ELEMENTS,
    XML_SCHEMA_CONTENT_MIXED,
    XML_SCHEMA_CONTENT_SIMPLE,
    XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS, /* Obsolete */
    XML_SCHEMA_CONTENT_BASIC,
    XML_SCHEMA_CONTENT_ANY
} xmlSchemaContentType;

/** Schema value */
typedef struct _xmlSchemaVal xmlSchemaVal;
typedef xmlSchemaVal *xmlSchemaValPtr;

/** Schema type */
typedef struct _xmlSchemaType xmlSchemaType;
typedef xmlSchemaType *xmlSchemaTypePtr;

/** Schema facet */
typedef struct _xmlSchemaFacet xmlSchemaFacet;
typedef xmlSchemaFacet *xmlSchemaFacetPtr;

/** Schema annotation */
typedef struct _xmlSchemaAnnot xmlSchemaAnnot;
typedef xmlSchemaAnnot *xmlSchemaAnnotPtr;
/**
 * Annotation
 */
struct _xmlSchemaAnnot {
    struct _xmlSchemaAnnot *next;
    xmlNode *content;         /* the annotation */
};

/**
 * Skip unknown attribute from validation
 * Obsolete, not used anymore.
 */
#define XML_SCHEMAS_ANYATTR_SKIP        1
/**
 * Ignore validation non definition on attributes
 * Obsolete, not used anymore.
 */
#define XML_SCHEMAS_ANYATTR_LAX                2
/**
 * Apply strict validation rules on attributes
 * Obsolete, not used anymore.
 */
#define XML_SCHEMAS_ANYATTR_STRICT        3
/**
 * Skip unknown attribute from validation
 */
#define XML_SCHEMAS_ANY_SKIP        1
/**
 * Used by wildcards.
 * Validate if type found, don't worry if not found
 */
#define XML_SCHEMAS_ANY_LAX                2
/**
 * Used by wildcards.
 * Apply strict validation rules
 */
#define XML_SCHEMAS_ANY_STRICT        3
/**
 * Used by wildcards.
 * The attribute is prohibited.
 */
#define XML_SCHEMAS_ATTR_USE_PROHIBITED 0
/**
 * The attribute is required.
 */
#define XML_SCHEMAS_ATTR_USE_REQUIRED 1
/**
 * The attribute is optional.
 */
#define XML_SCHEMAS_ATTR_USE_OPTIONAL 2
/**
 * allow elements in no namespace
 */
#define XML_SCHEMAS_ATTR_GLOBAL        1 << 0
/**
 * allow elements in no namespace
 */
#define XML_SCHEMAS_ATTR_NSDEFAULT        1 << 7
/**
 * this is set when the "type" and "ref" references
 * have been resolved.
 */
#define XML_SCHEMAS_ATTR_INTERNAL_RESOLVED        1 << 8
/**
 * the attribute has a fixed value
 */
#define XML_SCHEMAS_ATTR_FIXED        1 << 9

/** Schema attribute definition */
typedef struct _xmlSchemaAttribute xmlSchemaAttribute;
typedef xmlSchemaAttribute *xmlSchemaAttributePtr;
/**
 * An attribute definition.
 */
struct _xmlSchemaAttribute {
    xmlSchemaTypeType type;
    struct _xmlSchemaAttribute *next; /* the next attribute (not used?) */
    const xmlChar *name; /* the name of the declaration */
    const xmlChar *id; /* Deprecated; not used */
    const xmlChar *ref; /* Deprecated; not used */
    const xmlChar *refNs; /* Deprecated; not used */
    const xmlChar *typeName; /* the local name of the type definition */
    const xmlChar *typeNs; /* the ns URI of the type definition */
    xmlSchemaAnnot *annot;

    xmlSchemaType *base; /* Deprecated; not used */
    int occurs; /* Deprecated; not used */
    const xmlChar *defValue; /* The initial value of the value constraint */
    xmlSchemaType *subtypes; /* the type definition */
    xmlNode *node;
    const xmlChar *targetNamespace;
    int flags;
    const xmlChar *refPrefix; /* Deprecated; not used */
    xmlSchemaVal *defVal; /* The compiled value constraint */
    xmlSchemaAttribute *refDecl; /* Deprecated; not used */
};

/** Linked list of schema attributes */
typedef struct _xmlSchemaAttributeLink xmlSchemaAttributeLink;
typedef xmlSchemaAttributeLink *xmlSchemaAttributeLinkPtr;
/**
 * Used to build a list of attribute uses on complexType definitions.
 * WARNING: Deprecated; not used.
 */
struct _xmlSchemaAttributeLink {
    struct _xmlSchemaAttributeLink *next;/* the next attribute link ... */
    struct _xmlSchemaAttribute *attr;/* the linked attribute */
};

/**
 * If the wildcard is complete.
 */
#define XML_SCHEMAS_WILDCARD_COMPLETE 1 << 0

/** Namespace wildcard */
typedef struct _xmlSchemaWildcardNs xmlSchemaWildcardNs;
typedef xmlSchemaWildcardNs *xmlSchemaWildcardNsPtr;
/**
 * Used to build a list of namespaces on wildcards.
 */
struct _xmlSchemaWildcardNs {
    struct _xmlSchemaWildcardNs *next;/* the next constraint link ... */
    const xmlChar *value;/* the value */
};

/** Name wildcard */
typedef struct _xmlSchemaWildcard xmlSchemaWildcard;
typedef xmlSchemaWildcard *xmlSchemaWildcardPtr;
/**
 * A wildcard.
 */
struct _xmlSchemaWildcard {
    xmlSchemaTypeType type;        /* The kind of type */
    const xmlChar *id; /* Deprecated; not used */
    xmlSchemaAnnot *annot;
    xmlNode *node;
    int minOccurs; /* Deprecated; not used */
    int maxOccurs; /* Deprecated; not used */
    int processContents;
    int any; /* Indicates if the ns constraint is of ##any */
    xmlSchemaWildcardNs *nsSet; /* The list of allowed namespaces */
    xmlSchemaWildcardNs *negNsSet; /* The negated namespace */
    int flags;
};

/**
 * The attribute wildcard has been built.
 */
#define XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED 1 << 0
/**
 * The attribute group has been defined.
 */
#define XML_SCHEMAS_ATTRGROUP_GLOBAL 1 << 1
/**
 * Marks the attr group as marked; used for circular checks.
 */
#define XML_SCHEMAS_ATTRGROUP_MARKED 1 << 2

/**
 * The attr group was redefined.
 */
#define XML_SCHEMAS_ATTRGROUP_REDEFINED 1 << 3
/**
 * Whether this attr. group contains attr. group references.
 */
#define XML_SCHEMAS_ATTRGROUP_HAS_REFS 1 << 4

/** Attribute group */
typedef struct _xmlSchemaAttributeGroup xmlSchemaAttributeGroup;
typedef xmlSchemaAttributeGroup *xmlSchemaAttributeGroupPtr;
/**
 * An attribute group definition.
 *
 * xmlSchemaAttribute and xmlSchemaAttributeGroup start of structures
 * must be kept similar
 */
struct _xmlSchemaAttributeGroup {
    xmlSchemaTypeType type;        /* The kind of type */
    struct _xmlSchemaAttribute *next;/* the next attribute if in a group ... */
    const xmlChar *name;
    const xmlChar *id;
    const xmlChar *ref; /* Deprecated; not used */
    const xmlChar *refNs; /* Deprecated; not used */
    xmlSchemaAnnot *annot;

    xmlSchemaAttribute *attributes; /* Deprecated; not used */
    xmlNode *node;
    int flags;
    xmlSchemaWildcard *attributeWildcard;
    const xmlChar *refPrefix; /* Deprecated; not used */
    xmlSchemaAttributeGroup *refItem; /* Deprecated; not used */
    const xmlChar *targetNamespace;
    void *attrUses;
};

/** Linked list of schema types */
typedef struct _xmlSchemaTypeLink xmlSchemaTypeLink;
typedef xmlSchemaTypeLink *xmlSchemaTypeLinkPtr;
/**
 * Used to build a list of types (e.g. member types of
 * simpleType with variety "union").
 */
struct _xmlSchemaTypeLink {
    struct _xmlSchemaTypeLink *next;/* the next type link ... */
    xmlSchemaType *type;/* the linked type */
};

/** Linked list of schema facets */
typedef struct _xmlSchemaFacetLink xmlSchemaFacetLink;
typedef xmlSchemaFacetLink *xmlSchemaFacetLinkPtr;
/**
 * Used to build a list of facets.
 */
struct _xmlSchemaFacetLink {
    struct _xmlSchemaFacetLink *next;/* the next facet link ... */
    xmlSchemaFacet *facet;/* the linked facet */
};

/**
 * the element content type is mixed
 */
#define XML_SCHEMAS_TYPE_MIXED                1 << 0
/**
 * the simple or complex type has a derivation method of "extension".
 */
#define XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION                1 << 1
/**
 * the simple or complex type has a derivation method of "restriction".
 */
#define XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION                1 << 2
/**
 * the type is global
 */
#define XML_SCHEMAS_TYPE_GLOBAL                1 << 3
/**
 * the complexType owns an attribute wildcard, i.e.
 * it can be freed by the complexType
 */
#define XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD    1 << 4 /* Obsolete. */
/**
 * the simpleType has a variety of "absent".
 * TODO: Actually not necessary :-/, since if
 * none of the variety flags occur then it's
 * automatically absent.
 */
#define XML_SCHEMAS_TYPE_VARIETY_ABSENT    1 << 5
/**
 * the simpleType has a variety of "list".
 */
#define XML_SCHEMAS_TYPE_VARIETY_LIST    1 << 6
/**
 * the simpleType has a variety of "union".
 */
#define XML_SCHEMAS_TYPE_VARIETY_UNION    1 << 7
/**
 * the simpleType has a variety of "union".
 */
#define XML_SCHEMAS_TYPE_VARIETY_ATOMIC    1 << 8
/**
 * the complexType has a final of "extension".
 */
#define XML_SCHEMAS_TYPE_FINAL_EXTENSION    1 << 9
/**
 * the simpleType/complexType has a final of "restriction".
 */
#define XML_SCHEMAS_TYPE_FINAL_RESTRICTION    1 << 10
/**
 * the simpleType has a final of "list".
 */
#define XML_SCHEMAS_TYPE_FINAL_LIST    1 << 11
/**
 * the simpleType has a final of "union".
 */
#define XML_SCHEMAS_TYPE_FINAL_UNION    1 << 12
/**
 * the simpleType has a final of "default".
 */
#define XML_SCHEMAS_TYPE_FINAL_DEFAULT    1 << 13
/**
 * Marks the item as a builtin primitive.
 */
#define XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE    1 << 14
/**
 * Marks the item as marked; used for circular checks.
 */
#define XML_SCHEMAS_TYPE_MARKED        1 << 16
/**
 * the complexType did not specify 'block' so use the default of the
 * `<schema>` item.
 */
#define XML_SCHEMAS_TYPE_BLOCK_DEFAULT    1 << 17
/**
 * the complexType has a 'block' of "extension".
 */
#define XML_SCHEMAS_TYPE_BLOCK_EXTENSION    1 << 18
/**
 * the complexType has a 'block' of "restriction".
 */
#define XML_SCHEMAS_TYPE_BLOCK_RESTRICTION    1 << 19
/**
 * the simple/complexType is abstract.
 */
#define XML_SCHEMAS_TYPE_ABSTRACT    1 << 20
/**
 * indicates if the facets need a computed value
 */
#define XML_SCHEMAS_TYPE_FACETSNEEDVALUE    1 << 21
/**
 * indicates that the type was typefixed
 */
#define XML_SCHEMAS_TYPE_INTERNAL_RESOLVED    1 << 22
/**
 * indicates that the type is invalid
 */
#define XML_SCHEMAS_TYPE_INTERNAL_INVALID    1 << 23
/**
 * a whitespace-facet value of "preserve"
 */
#define XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE    1 << 24
/**
 * a whitespace-facet value of "replace"
 */
#define XML_SCHEMAS_TYPE_WHITESPACE_REPLACE    1 << 25
/**
 * a whitespace-facet value of "collapse"
 */
#define XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE    1 << 26
/**
 * has facets
 */
#define XML_SCHEMAS_TYPE_HAS_FACETS    1 << 27
/**
 * indicates if the facets (pattern) need a normalized value
 */
#define XML_SCHEMAS_TYPE_NORMVALUENEEDED    1 << 28

/**
 * First stage of fixup was done.
 */
#define XML_SCHEMAS_TYPE_FIXUP_1    1 << 29

/**
 * The type was redefined.
 */
#define XML_SCHEMAS_TYPE_REDEFINED    1 << 30
#if 0
/**
 * The type redefines an other type.
 */
#define XML_SCHEMAS_TYPE_REDEFINING    1 << 31
#endif

/**
 * Schemas type definition.
 */
struct _xmlSchemaType {
    xmlSchemaTypeType type; /* The kind of type */
    struct _xmlSchemaType *next; /* the next type if in a sequence ... */
    const xmlChar *name;
    const xmlChar *id ; /* Deprecated; not used */
    const xmlChar *ref; /* Deprecated; not used */
    const xmlChar *refNs; /* Deprecated; not used */
    xmlSchemaAnnot *annot;
    xmlSchemaType *subtypes;
    xmlSchemaAttribute *attributes; /* Deprecated; not used */
    xmlNode *node;
    int minOccurs; /* Deprecated; not used */
    int maxOccurs; /* Deprecated; not used */

    int flags;
    xmlSchemaContentType contentType;
    const xmlChar *base; /* Base type's local name */
    const xmlChar *baseNs; /* Base type's target namespace */
    xmlSchemaType *baseType; /* The base type component */
    xmlSchemaFacet *facets; /* Local facets */
    struct _xmlSchemaType *redef; /* Deprecated; not used */
    int recurse; /* Obsolete */
    xmlSchemaAttributeLink **attributeUses; /* Deprecated; not used */
    xmlSchemaWildcard *attributeWildcard;
    int builtInType; /* Type of built-in types. */
    xmlSchemaTypeLink *memberTypes; /* member-types if a union type. */
    xmlSchemaFacetLink *facetSet; /* All facets (incl. inherited) */
    const xmlChar *refPrefix; /* Deprecated; not used */
    xmlSchemaType *contentTypeDef; /* Used for the simple content of complex types.
                                        Could we use @subtypes for this? */
    xmlRegexp *contModel; /* Holds the automaton of the content model */
    const xmlChar *targetNamespace;
    void *attrUses;
};

/**
 * the element is nillable
 */
#define XML_SCHEMAS_ELEM_NILLABLE        1 << 0
/**
 * the element is global
 */
#define XML_SCHEMAS_ELEM_GLOBAL                1 << 1
/**
 * the element has a default value
 */
#define XML_SCHEMAS_ELEM_DEFAULT        1 << 2
/**
 * the element has a fixed value
 */
#define XML_SCHEMAS_ELEM_FIXED                1 << 3
/**
 * the element is abstract
 */
#define XML_SCHEMAS_ELEM_ABSTRACT        1 << 4
/**
 * the element is top level
 * obsolete: use XML_SCHEMAS_ELEM_GLOBAL instead
 */
#define XML_SCHEMAS_ELEM_TOPLEVEL        1 << 5
/**
 * the element is a reference to a type
 */
#define XML_SCHEMAS_ELEM_REF                1 << 6
/**
 * allow elements in no namespace
 * Obsolete, not used anymore.
 */
#define XML_SCHEMAS_ELEM_NSDEFAULT        1 << 7
/**
 * this is set when "type", "ref", "substitutionGroup"
 * references have been resolved.
 */
#define XML_SCHEMAS_ELEM_INTERNAL_RESOLVED        1 << 8
 /**
 * a helper flag for the search of circular references.
 */
#define XML_SCHEMAS_ELEM_CIRCULAR        1 << 9
/**
 * the "block" attribute is absent
 */
#define XML_SCHEMAS_ELEM_BLOCK_ABSENT        1 << 10
/**
 * disallowed substitutions are absent
 */
#define XML_SCHEMAS_ELEM_BLOCK_EXTENSION        1 << 11
/**
 * disallowed substitutions: "restriction"
 */
#define XML_SCHEMAS_ELEM_BLOCK_RESTRICTION        1 << 12
/**
 * disallowed substitutions: "substitution"
 */
#define XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION        1 << 13
/**
 * substitution group exclusions are absent
 */
#define XML_SCHEMAS_ELEM_FINAL_ABSENT        1 << 14
/**
 * substitution group exclusions: "extension"
 */
#define XML_SCHEMAS_ELEM_FINAL_EXTENSION        1 << 15
/**
 * substitution group exclusions: "restriction"
 */
#define XML_SCHEMAS_ELEM_FINAL_RESTRICTION        1 << 16
/**
 * the declaration is a substitution group head
 */
#define XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD        1 << 17
/**
 * this is set when the elem decl has been checked against
 * all constraints
 */
#define XML_SCHEMAS_ELEM_INTERNAL_CHECKED        1 << 18

/** Schema element definition */
typedef struct _xmlSchemaElement xmlSchemaElement;
typedef xmlSchemaElement *xmlSchemaElementPtr;
/**
 * An element definition.
 *
 * xmlSchemaType, xmlSchemaFacet and xmlSchemaElement start of
 * structures must be kept similar
 */
struct _xmlSchemaElement {
    xmlSchemaTypeType type; /* The kind of type */
    struct _xmlSchemaType *next; /* Not used? */
    const xmlChar *name;
    const xmlChar *id; /* Deprecated; not used */
    const xmlChar *ref; /* Deprecated; not used */
    const xmlChar *refNs; /* Deprecated; not used */
    xmlSchemaAnnot *annot;
    xmlSchemaType *subtypes; /* the type definition */
    xmlSchemaAttribute *attributes;
    xmlNode *node;
    int minOccurs; /* Deprecated; not used */
    int maxOccurs; /* Deprecated; not used */

    int flags;
    const xmlChar *targetNamespace;
    const xmlChar *namedType;
    const xmlChar *namedTypeNs;
    const xmlChar *substGroup;
    const xmlChar *substGroupNs;
    const xmlChar *scope;
    const xmlChar *value; /* The original value of the value constraint. */
    struct _xmlSchemaElement *refDecl; /* This will now be used for the
                                          substitution group affiliation */
    xmlRegexp *contModel; /* Obsolete for WXS, maybe used for RelaxNG */
    xmlSchemaContentType contentType;
    const xmlChar *refPrefix; /* Deprecated; not used */
    xmlSchemaVal *defVal; /* The compiled value constraint. */
    void *idcs; /* The identity-constraint defs */
};

/**
 * unknown facet handling
 */
#define XML_SCHEMAS_FACET_UNKNOWN        0
/**
 * preserve the type of the facet
 */
#define XML_SCHEMAS_FACET_PRESERVE        1
/**
 * replace the type of the facet
 */
#define XML_SCHEMAS_FACET_REPLACE        2
/**
 * collapse the types of the facet
 */
#define XML_SCHEMAS_FACET_COLLAPSE        3
/**
 * A facet definition.
 */
struct _xmlSchemaFacet {
    xmlSchemaTypeType type;        /* The kind of type */
    struct _xmlSchemaFacet *next;/* the next type if in a sequence ... */
    const xmlChar *value; /* The original value */
    const xmlChar *id; /* Obsolete */
    xmlSchemaAnnot *annot;
    xmlNode *node;
    int fixed; /* XML_SCHEMAS_FACET_PRESERVE, etc. */
    int whitespace;
    xmlSchemaVal *val; /* The compiled value */
    xmlRegexp      *regexp; /* The regex for patterns */
};

/** Schema notation */
typedef struct _xmlSchemaNotation xmlSchemaNotation;
typedef xmlSchemaNotation *xmlSchemaNotationPtr;
/**
 * A notation definition.
 */
struct _xmlSchemaNotation {
    xmlSchemaTypeType type; /* The kind of type */
    const xmlChar *name;
    xmlSchemaAnnot *annot;
    const xmlChar *identifier;
    const xmlChar *targetNamespace;
};

/*
* TODO: Actually all those flags used for the schema should sit
* on the schema parser context, since they are used only
* during parsing an XML schema document, and not available
* on the component level as per spec.
*/
/**
 * Reflects elementFormDefault == qualified in
 * an XML schema document.
 */
#define XML_SCHEMAS_QUALIF_ELEM                1 << 0
/**
 * Reflects attributeFormDefault == qualified in
 * an XML schema document.
 */
#define XML_SCHEMAS_QUALIF_ATTR            1 << 1
/**
 * the schema has "extension" in the set of finalDefault.
 */
#define XML_SCHEMAS_FINAL_DEFAULT_EXTENSION        1 << 2
/**
 * the schema has "restriction" in the set of finalDefault.
 */
#define XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION            1 << 3
/**
 * the schema has "list" in the set of finalDefault.
 */
#define XML_SCHEMAS_FINAL_DEFAULT_LIST            1 << 4
/**
 * the schema has "union" in the set of finalDefault.
 */
#define XML_SCHEMAS_FINAL_DEFAULT_UNION            1 << 5
/**
 * the schema has "extension" in the set of blockDefault.
 */
#define XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION            1 << 6
/**
 * the schema has "restriction" in the set of blockDefault.
 */
#define XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION            1 << 7
/**
 * the schema has "substitution" in the set of blockDefault.
 */
#define XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION            1 << 8
/**
 * the schema is currently including an other schema with
 * no target namespace.
 */
#define XML_SCHEMAS_INCLUDING_CONVERT_NS            1 << 9
/**
 * A Schemas definition
 */
struct _xmlSchema {
    const xmlChar *name; /* schema name */
    const xmlChar *targetNamespace; /* the target namespace */
    const xmlChar *version;
    const xmlChar *id; /* Obsolete */
    xmlDoc *doc;
    xmlSchemaAnnot *annot;
    int flags;

    xmlHashTable *typeDecl;
    xmlHashTable *attrDecl;
    xmlHashTable *attrgrpDecl;
    xmlHashTable *elemDecl;
    xmlHashTable *notaDecl;

    xmlHashTable *schemasImports;

    void *_private;        /* unused by the library for users or bindings */
    xmlHashTable *groupDecl;
    xmlDict        *dict;
    void *includes;     /* the includes, this is opaque for now */
    int preserve;        /* whether to free the document */
    int counter; /* used to give anonymous components unique names */
    xmlHashTable *idcDef; /* All identity-constraint defs. */
    void *volatiles; /* Obsolete */
};

XMLPUBFUN void         xmlSchemaFreeType        (xmlSchemaType *type);
XMLPUBFUN void         xmlSchemaFreeWildcard(xmlSchemaWildcard *wildcard);

#ifdef __cplusplus
}
#endif

#endif /* LIBXML_SCHEMAS_ENABLED */
#endif /* __XML_SCHEMA_INTERNALS_H__ */
libxml2/libxml/hash.h000064400000015462151733237450010522 0ustar00/**
 * @file
 * 
 * @brief Chained hash tables
 * 
 * This module implements the hash table support used in
 *		various places in the library.
 *
 * @copyright See Copyright for the status of this software.
 */

#ifndef __XML_HASH_H__
#define __XML_HASH_H__

#include <libxml/xmlversion.h>
#include <libxml/dict.h>
#include <libxml/xmlstring.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * Hash table mapping strings to pointers
 *
 * Also supports lookup using two or three strings as key.
 */
typedef struct _xmlHashTable xmlHashTable;
typedef xmlHashTable *xmlHashTablePtr;

/*
 * Recent version of gcc produce a warning when a function pointer is assigned
 * to an object pointer, or vice versa.  The following macro is a dirty hack
 * to allow suppression of the warning.  If your architecture has function
 * pointers which are a different size than a void pointer, there may be some
 * serious trouble within the library.
 */
/**
 * Macro to do a casting from an object pointer to a
 * function pointer without encountering a warning from
 * gcc
 *
 * \#define XML_CAST_FPTR(fptr) (*(void **)(&fptr))
 * This macro violated ISO C aliasing rules (gcc4 on s390 broke)
 * so it is disabled now
 *
 * @param fptr  pointer to a function
 */

#define XML_CAST_FPTR(fptr) fptr

/*
 * function types:
 */
/**
 * Callback to free data from a hash.
 *
 * @param payload  the data in the hash
 * @param name  the name associated
 */
typedef void (*xmlHashDeallocator)(void *payload, const xmlChar *name);
/**
 * Callback to copy data from a hash.
 *
 * @param payload  the data in the hash
 * @param name  the name associated
 * @returns a copy of the data or NULL in case of error.
 */
typedef void *(*xmlHashCopier)(void *payload, const xmlChar *name);
/**
 * Callback when scanning data in a hash with the simple scanner.
 *
 * @param payload  the data in the hash
 * @param data  extra scanner data
 * @param name  the name associated
 */
typedef void (*xmlHashScanner)(void *payload, void *data, const xmlChar *name);
/**
 * Callback when scanning data in a hash with the full scanner.
 *
 * @param payload  the data in the hash
 * @param data  extra scanner data
 * @param name  the name associated
 * @param name2  the second name associated
 * @param name3  the third name associated
 */
typedef void (*xmlHashScannerFull)(void *payload, void *data,
				   const xmlChar *name, const xmlChar *name2,
				   const xmlChar *name3);

/*
 * Constructor and destructor.
 */
XMLPUBFUN xmlHashTable *
		xmlHashCreate		(int size);
XMLPUBFUN xmlHashTable *
		xmlHashCreateDict	(int size,
					 xmlDict *dict);
XMLPUBFUN void
		xmlHashFree		(xmlHashTable *hash,
					 xmlHashDeallocator dealloc);
XMLPUBFUN void
		xmlHashDefaultDeallocator(void *entry,
					 const xmlChar *name);

/*
 * Add a new entry to the hash table.
 */
XMLPUBFUN int
		xmlHashAdd		(xmlHashTable *hash,
		                         const xmlChar *name,
		                         void *userdata);
XMLPUBFUN int
		xmlHashAddEntry		(xmlHashTable *hash,
		                         const xmlChar *name,
		                         void *userdata);
XMLPUBFUN int
		xmlHashUpdateEntry	(xmlHashTable *hash,
		                         const xmlChar *name,
		                         void *userdata,
					 xmlHashDeallocator dealloc);
XMLPUBFUN int
		xmlHashAdd2		(xmlHashTable *hash,
		                         const xmlChar *name,
		                         const xmlChar *name2,
		                         void *userdata);
XMLPUBFUN int
		xmlHashAddEntry2	(xmlHashTable *hash,
		                         const xmlChar *name,
		                         const xmlChar *name2,
		                         void *userdata);
XMLPUBFUN int
		xmlHashUpdateEntry2	(xmlHashTable *hash,
		                         const xmlChar *name,
		                         const xmlChar *name2,
		                         void *userdata,
					 xmlHashDeallocator dealloc);
XMLPUBFUN int
		xmlHashAdd3		(xmlHashTable *hash,
		                         const xmlChar *name,
		                         const xmlChar *name2,
		                         const xmlChar *name3,
		                         void *userdata);
XMLPUBFUN int
		xmlHashAddEntry3	(xmlHashTable *hash,
		                         const xmlChar *name,
		                         const xmlChar *name2,
		                         const xmlChar *name3,
		                         void *userdata);
XMLPUBFUN int
		xmlHashUpdateEntry3	(xmlHashTable *hash,
		                         const xmlChar *name,
		                         const xmlChar *name2,
		                         const xmlChar *name3,
		                         void *userdata,
					 xmlHashDeallocator dealloc);

/*
 * Remove an entry from the hash table.
 */
XMLPUBFUN int
		xmlHashRemoveEntry	(xmlHashTable *hash,
					 const xmlChar *name,
					 xmlHashDeallocator dealloc);
XMLPUBFUN int
		xmlHashRemoveEntry2	(xmlHashTable *hash,
					 const xmlChar *name,
					 const xmlChar *name2,
					 xmlHashDeallocator dealloc);
XMLPUBFUN int 
		xmlHashRemoveEntry3	(xmlHashTable *hash,
					 const xmlChar *name,
					 const xmlChar *name2,
					 const xmlChar *name3,
					 xmlHashDeallocator dealloc);

/*
 * Retrieve the payload.
 */
XMLPUBFUN void *
		xmlHashLookup		(xmlHashTable *hash,
					 const xmlChar *name);
XMLPUBFUN void *
		xmlHashLookup2		(xmlHashTable *hash,
					 const xmlChar *name,
					 const xmlChar *name2);
XMLPUBFUN void *
		xmlHashLookup3		(xmlHashTable *hash,
					 const xmlChar *name,
					 const xmlChar *name2,
					 const xmlChar *name3);
XMLPUBFUN void *
		xmlHashQLookup		(xmlHashTable *hash,
					 const xmlChar *prefix,
					 const xmlChar *name);
XMLPUBFUN void *
		xmlHashQLookup2		(xmlHashTable *hash,
					 const xmlChar *prefix,
					 const xmlChar *name,
					 const xmlChar *prefix2,
					 const xmlChar *name2);
XMLPUBFUN void *
		xmlHashQLookup3		(xmlHashTable *hash,
					 const xmlChar *prefix,
					 const xmlChar *name,
					 const xmlChar *prefix2,
					 const xmlChar *name2,
					 const xmlChar *prefix3,
					 const xmlChar *name3);

/*
 * Helpers.
 */
XMLPUBFUN xmlHashTable *
		xmlHashCopySafe		(xmlHashTable *hash,
					 xmlHashCopier copy,
					 xmlHashDeallocator dealloc);
XMLPUBFUN xmlHashTable *
		xmlHashCopy		(xmlHashTable *hash,
					 xmlHashCopier copy);
XMLPUBFUN int
		xmlHashSize		(xmlHashTable *hash);
XMLPUBFUN void
		xmlHashScan		(xmlHashTable *hash,
					 xmlHashScanner scan,
					 void *data);
XMLPUBFUN void
		xmlHashScan3		(xmlHashTable *hash,
					 const xmlChar *name,
					 const xmlChar *name2,
					 const xmlChar *name3,
					 xmlHashScanner scan,
					 void *data);
XMLPUBFUN void
		xmlHashScanFull		(xmlHashTable *hash,
					 xmlHashScannerFull scan,
					 void *data);
XMLPUBFUN void
		xmlHashScanFull3	(xmlHashTable *hash,
					 const xmlChar *name,
					 const xmlChar *name2,
					 const xmlChar *name3,
					 xmlHashScannerFull scan,
					 void *data);
#ifdef __cplusplus
}
#endif
#endif /* ! __XML_HASH_H__ */
libxml2/libxml/xmlmemory.h000064400000011672151733237450011627 0ustar00/**
 * @file
 * 
 * @brief interface for the memory allocator
 * 
 * provides interfaces for the memory allocator,
 *              including debugging capabilities.
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */


#ifndef __DEBUG_MEMORY_ALLOC__
#define __DEBUG_MEMORY_ALLOC__

#include <stdio.h>
#include <libxml/xmlversion.h>

#ifdef __cplusplus
extern "C" {
#endif

/*
 * The XML memory wrapper support 4 basic overloadable functions.
 */
/**
 * Signature for a free() implementation.
 *
 * @param mem  an already allocated block of memory
 */
typedef void (*xmlFreeFunc)(void *mem);
/**
 * Signature for a malloc() implementation.
 *
 * @param size  the size requested in bytes
 * @returns a pointer to the newly allocated block or NULL in case of error.
 */
typedef void *(*xmlMallocFunc)(size_t size) LIBXML_ATTR_ALLOC_SIZE(1);

/**
 * Signature for a realloc() implementation.
 *
 * @param mem  an already allocated block of memory
 * @param size  the new size requested in bytes
 * @returns a pointer to the newly reallocated block or NULL in case of error.
 */
typedef void *(*xmlReallocFunc)(void *mem, size_t size);

/**
 * Signature for an strdup() implementation.
 *
 * @param str  a zero terminated string
 * @returns the copy of the string or NULL in case of error.
 */
typedef char *(*xmlStrdupFunc)(const char *str);

/*
 * In general the memory allocation entry points are not kept
 * thread specific but this can be overridden by LIBXML_THREAD_ALLOC_ENABLED
 *    - xmlMalloc
 *    - xmlMallocAtomic
 *    - xmlRealloc
 *    - xmlMemStrdup
 *    - xmlFree
 */
#ifdef LIBXML_THREAD_ALLOC_ENABLED

XMLPUBFUN xmlMallocFunc *__xmlMalloc(void);
XMLPUBFUN xmlMallocFunc *__xmlMallocAtomic(void);
XMLPUBFUN xmlReallocFunc *__xmlRealloc(void);
XMLPUBFUN xmlFreeFunc *__xmlFree(void);
XMLPUBFUN xmlStrdupFunc *__xmlMemStrdup(void);

#ifndef XML_GLOBALS_NO_REDEFINITION
  #define xmlMalloc (*__xmlMalloc())
  #define xmlMallocAtomic (*__xmlMallocAtomic())
  #define xmlRealloc (*__xmlRealloc())
  #define xmlFree (*__xmlFree())
  #define xmlMemStrdup (*__xmlMemStrdup())
#endif

#else

/**
 * The variable holding the libxml malloc() implementation
 */
XMLPUBVAR xmlMallocFunc xmlMalloc;
/**
 * The variable holding the libxml malloc() implementation for atomic
 * data (i.e. blocks not containing pointers), useful when using a
 * garbage collecting allocator.
 *
 * @deprecated Use #xmlMalloc
 */
XMLPUBVAR xmlMallocFunc xmlMallocAtomic;
/**
 * The variable holding the libxml realloc() implementation
 */
XMLPUBVAR xmlReallocFunc xmlRealloc;
/**
 * The variable holding the libxml free() implementation
 */
XMLPUBVAR xmlFreeFunc xmlFree;
/**
 * The variable holding the libxml strdup() implementation
 */
XMLPUBVAR xmlStrdupFunc xmlMemStrdup;

#endif

/*
 * The way to overload the existing functions.
 * The xmlGc function have an extra entry for atomic block
 * allocations useful for garbage collected memory allocators
 */
XMLPUBFUN int
	xmlMemSetup	(xmlFreeFunc freeFunc,
			 xmlMallocFunc mallocFunc,
			 xmlReallocFunc reallocFunc,
			 xmlStrdupFunc strdupFunc);
XMLPUBFUN int
	xmlMemGet	(xmlFreeFunc *freeFunc,
			 xmlMallocFunc *mallocFunc,
			 xmlReallocFunc *reallocFunc,
			 xmlStrdupFunc *strdupFunc);
XML_DEPRECATED
XMLPUBFUN int
	xmlGcMemSetup	(xmlFreeFunc freeFunc,
			 xmlMallocFunc mallocFunc,
			 xmlMallocFunc mallocAtomicFunc,
			 xmlReallocFunc reallocFunc,
			 xmlStrdupFunc strdupFunc);
XML_DEPRECATED
XMLPUBFUN int
	xmlGcMemGet	(xmlFreeFunc *freeFunc,
			 xmlMallocFunc *mallocFunc,
			 xmlMallocFunc *mallocAtomicFunc,
			 xmlReallocFunc *reallocFunc,
			 xmlStrdupFunc *strdupFunc);

/*
 * Initialization of the memory layer.
 */
XML_DEPRECATED
XMLPUBFUN int
	xmlInitMemory	(void);

/*
 * Cleanup of the memory layer.
 */
XML_DEPRECATED
XMLPUBFUN void
                xmlCleanupMemory        (void);
/*
 * These are specific to the XML debug memory wrapper.
 */
XMLPUBFUN size_t
	xmlMemSize	(void *ptr);
XMLPUBFUN int
	xmlMemUsed	(void);
XMLPUBFUN int
	xmlMemBlocks	(void);
XML_DEPRECATED
XMLPUBFUN void
	xmlMemDisplay	(FILE *fp);
XML_DEPRECATED
XMLPUBFUN void
	xmlMemDisplayLast(FILE *fp, long nbBytes);
XML_DEPRECATED
XMLPUBFUN void
	xmlMemShow	(FILE *fp, int nr);
XML_DEPRECATED
XMLPUBFUN void
	xmlMemoryDump	(void);
XMLPUBFUN void *
	xmlMemMalloc	(size_t size) LIBXML_ATTR_ALLOC_SIZE(1);
XMLPUBFUN void *
	xmlMemRealloc	(void *ptr,size_t size);
XMLPUBFUN void
	xmlMemFree	(void *ptr);
XMLPUBFUN char *
	xmlMemoryStrdup	(const char *str);
XML_DEPRECATED
XMLPUBFUN void *
	xmlMallocLoc	(size_t size, const char *file, int line) LIBXML_ATTR_ALLOC_SIZE(1);
XML_DEPRECATED
XMLPUBFUN void *
	xmlReallocLoc	(void *ptr, size_t size, const char *file, int line);
XML_DEPRECATED
XMLPUBFUN void *
	xmlMallocAtomicLoc (size_t size, const char *file, int line) LIBXML_ATTR_ALLOC_SIZE(1);
XML_DEPRECATED
XMLPUBFUN char *
	xmlMemStrdupLoc	(const char *str, const char *file, int line);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif  /* __DEBUG_MEMORY_ALLOC__ */

libxml2/libxml/xlink.h000064400000012044151733237450010715 0ustar00/**
 * @file
 * 
 * @brief unfinished XLink detection module
 * 
 * This module is deprecated, don't use.
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */

#ifndef __XML_XLINK_H__
#define __XML_XLINK_H__

#include <libxml/xmlversion.h>
#include <libxml/tree.h>

#ifdef LIBXML_XPTR_ENABLED

#ifdef __cplusplus
extern "C" {
#endif

/** @cond ignore */

/**
 * Various defines for the various Link properties.
 *
 * NOTE: the link detection layer will try to resolve QName expansion
 *       of namespaces. If "foo" is the prefix for "http://foo.com/"
 *       then the link detection layer will expand role="foo:myrole"
 *       to "http://foo.com/:myrole".
 * NOTE: the link detection layer will expand URI-References found on
 *       href attributes by using the base mechanism if found.
 */
typedef xmlChar *xlinkHRef;
typedef xmlChar *xlinkRole;
typedef xmlChar *xlinkTitle;

typedef enum {
    XLINK_TYPE_NONE = 0,
    XLINK_TYPE_SIMPLE,
    XLINK_TYPE_EXTENDED,
    XLINK_TYPE_EXTENDED_SET
} xlinkType;

typedef enum {
    XLINK_SHOW_NONE = 0,
    XLINK_SHOW_NEW,
    XLINK_SHOW_EMBED,
    XLINK_SHOW_REPLACE
} xlinkShow;

typedef enum {
    XLINK_ACTUATE_NONE = 0,
    XLINK_ACTUATE_AUTO,
    XLINK_ACTUATE_ONREQUEST
} xlinkActuate;

/** @endcond */

/**
 * This is the prototype for the link detection routine.
 * It calls the default link detection callbacks upon link detection.
 *
 * @param ctx  user data pointer
 * @param node  the node to check
 */
typedef void (*xlinkNodeDetectFunc) (void *ctx, xmlNode *node);

/*
 * The link detection module interact with the upper layers using
 * a set of callback registered at parsing time.
 */

/**
 * This is the prototype for a simple link detection callback.
 *
 * @param ctx  user data pointer
 * @param node  the node carrying the link
 * @param href  the target of the link
 * @param role  the role string
 * @param title  the link title
 */
typedef void
(*xlinkSimpleLinkFunk)	(void *ctx,
			 xmlNode *node,
			 const xlinkHRef href,
			 const xlinkRole role,
			 const xlinkTitle title);

/**
 * This is the prototype for a extended link detection callback.
 *
 * @param ctx  user data pointer
 * @param node  the node carrying the link
 * @param nbLocators  the number of locators detected on the link
 * @param hrefs  pointer to the array of locator hrefs
 * @param roles  pointer to the array of locator roles
 * @param nbArcs  the number of arcs detected on the link
 * @param from  pointer to the array of source roles found on the arcs
 * @param to  pointer to the array of target roles found on the arcs
 * @param show  array of values for the show attributes found on the arcs
 * @param actuate  array of values for the actuate attributes found on the arcs
 * @param nbTitles  the number of titles detected on the link
 * @param titles  array of titles detected on the link
 * @param langs  array of xml:lang values for the titles
 */
typedef void
(*xlinkExtendedLinkFunk)(void *ctx,
			 xmlNode *node,
			 int nbLocators,
			 const xlinkHRef *hrefs,
			 const xlinkRole *roles,
			 int nbArcs,
			 const xlinkRole *from,
			 const xlinkRole *to,
			 xlinkShow *show,
			 xlinkActuate *actuate,
			 int nbTitles,
			 const xlinkTitle *titles,
			 const xmlChar **langs);

/**
 * This is the prototype for a extended link set detection callback.
 *
 * @param ctx  user data pointer
 * @param node  the node carrying the link
 * @param nbLocators  the number of locators detected on the link
 * @param hrefs  pointer to the array of locator hrefs
 * @param roles  pointer to the array of locator roles
 * @param nbTitles  the number of titles detected on the link
 * @param titles  array of titles detected on the link
 * @param langs  array of xml:lang values for the titles
 */
typedef void
(*xlinkExtendedLinkSetFunk)	(void *ctx,
				 xmlNode *node,
				 int nbLocators,
				 const xlinkHRef *hrefs,
				 const xlinkRole *roles,
				 int nbTitles,
				 const xlinkTitle *titles,
				 const xmlChar **langs);

typedef struct _xlinkHandler xlinkHandler;
typedef xlinkHandler *xlinkHandlerPtr;
/**
 * This is the structure containing a set of Links detection callbacks.
 *
 * There is no default xlink callbacks, if one want to get link
 * recognition activated, those call backs must be provided before parsing.
 */
struct _xlinkHandler {
    xlinkSimpleLinkFunk simple;
    xlinkExtendedLinkFunk extended;
    xlinkExtendedLinkSetFunk set;
};

/*
 * The default detection routine, can be overridden, they call the default
 * detection callbacks.
 */

XML_DEPRECATED
XMLPUBFUN xlinkNodeDetectFunc
		xlinkGetDefaultDetect	(void);
XML_DEPRECATED
XMLPUBFUN void
		xlinkSetDefaultDetect	(xlinkNodeDetectFunc func);

/*
 * Routines to set/get the default handlers.
 */
XML_DEPRECATED
XMLPUBFUN xlinkHandler *
		xlinkGetDefaultHandler	(void);
XML_DEPRECATED
XMLPUBFUN void
		xlinkSetDefaultHandler	(xlinkHandler *handler);

/*
 * Link detection module itself.
 */
XML_DEPRECATED
XMLPUBFUN xlinkType
		xlinkIsLink		(xmlDoc *doc,
					 xmlNode *node);

#ifdef __cplusplus
}
#endif

#endif /* LIBXML_XPTR_ENABLED */

#endif /* __XML_XLINK_H__ */
libxml2/libxml/HTMLparser.h000064400000024564151733237450011563 0ustar00/**
 * @file
 * 
 * @brief HTML parser, doesn't support HTML5
 * 
 * This module orginally implemented an HTML parser based on the
 * (underspecified) HTML 4.0 spec. As of 2.14, the tokenizer
 * conforms to HTML5. Tree construction still follows a custom,
 * unspecified algorithm with many differences to HTML5.
 *
 * The parser defaults to ISO-8859-1, the default encoding of
 * HTTP/1.0.
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */

#ifndef __HTML_PARSER_H__
#define __HTML_PARSER_H__
#include <libxml/xmlversion.h>
#include <libxml/parser.h>

#ifdef LIBXML_HTML_ENABLED

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Backward compatibility
 */
#define UTF8ToHtml htmlUTF8ToHtml
#define htmlDefaultSubelement(elt) elt->defaultsubelt
#define htmlElementAllowedHereDesc(parent,elt) \
	htmlElementAllowedHere((parent), (elt)->name)
#define htmlRequiredAttrs(elt) (elt)->attrs_req

/*
 * Most of the back-end structures from XML and HTML are shared.
 */
/** Same as xmlParserCtxt */
typedef xmlParserCtxt htmlParserCtxt;
typedef xmlParserCtxtPtr htmlParserCtxtPtr;
typedef xmlParserNodeInfo htmlParserNodeInfo;
/** Same as xmlSAXHandler */
typedef xmlSAXHandler htmlSAXHandler;
typedef xmlSAXHandlerPtr htmlSAXHandlerPtr;
/** Same as xmlParserInput */
typedef xmlParserInput htmlParserInput;
typedef xmlParserInputPtr htmlParserInputPtr;
typedef xmlDocPtr htmlDocPtr;
typedef xmlNodePtr htmlNodePtr;

/** @cond ignore */

/*
 * Internal description of an HTML element, representing HTML 4.01
 * and XHTML 1.0 (which share the same structure).
 */
typedef struct _htmlElemDesc htmlElemDesc;
typedef htmlElemDesc *htmlElemDescPtr;
struct _htmlElemDesc {
    const char *name;	/* The tag name */
    char startTag;      /* unused */
    char endTag;        /* Whether the end tag can be implied */
    char saveEndTag;    /* unused */
    char empty;         /* Is this an empty element ? */
    char depr;          /* unused */
    char dtd;           /* unused */
    char isinline;      /* is this a block 0 or inline 1 element */
    const char *desc;   /* the description */

    const char** subelts XML_DEPRECATED_MEMBER;
    const char* defaultsubelt XML_DEPRECATED_MEMBER;
    const char** attrs_opt XML_DEPRECATED_MEMBER;
    const char** attrs_depr XML_DEPRECATED_MEMBER;
    const char** attrs_req XML_DEPRECATED_MEMBER;

    int dataMode;
};

/*
 * Internal description of an HTML entity.
 */
typedef struct _htmlEntityDesc htmlEntityDesc;
typedef htmlEntityDesc *htmlEntityDescPtr;
struct _htmlEntityDesc {
    unsigned int value;	/* the UNICODE value for the character */
    const char *name;	/* The entity name */
    const char *desc;   /* the description */
};

#ifdef LIBXML_SAX1_ENABLED
/**
 * @deprecated Use #xmlSAX2InitHtmlDefaultSAXHandler
 */
XML_DEPRECATED
XMLPUBVAR const xmlSAXHandlerV1 htmlDefaultSAXHandler;
#endif /* LIBXML_SAX1_ENABLED */

/** @endcond */

/*
 * There is only few public functions.
 */
XML_DEPRECATED
XMLPUBFUN void
			htmlInitAutoClose	(void);
XML_DEPRECATED
XMLPUBFUN const htmlElemDesc *
			htmlTagLookup	(const xmlChar *tag);
XML_DEPRECATED
XMLPUBFUN const htmlEntityDesc *
			htmlEntityLookup(const xmlChar *name);
XML_DEPRECATED
XMLPUBFUN const htmlEntityDesc *
			htmlEntityValueLookup(unsigned int value);

XML_DEPRECATED
XMLPUBFUN int
			htmlIsAutoClosed(xmlDoc *doc,
					 xmlNode *elem);
XML_DEPRECATED
XMLPUBFUN int
			htmlAutoCloseTag(xmlDoc *doc,
					 const xmlChar *name,
					 xmlNode *elem);
XML_DEPRECATED
XMLPUBFUN const htmlEntityDesc *
			htmlParseEntityRef(htmlParserCtxt *ctxt,
					 const xmlChar **str);
XML_DEPRECATED
XMLPUBFUN int
			htmlParseCharRef(htmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN void
			htmlParseElement(htmlParserCtxt *ctxt);

XMLPUBFUN htmlParserCtxt *
			htmlNewParserCtxt(void);
XMLPUBFUN htmlParserCtxt *
			htmlNewSAXParserCtxt(const htmlSAXHandler *sax,
					     void *userData);

XMLPUBFUN htmlParserCtxt *
			htmlCreateMemoryParserCtxt(const char *buffer,
						   int size);

XMLPUBFUN int
			htmlParseDocument(htmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN xmlDoc *
			htmlSAXParseDoc	(const xmlChar *cur,
					 const char *encoding,
					 htmlSAXHandler *sax,
					 void *userData);
XMLPUBFUN xmlDoc *
			htmlParseDoc	(const xmlChar *cur,
					 const char *encoding);
XMLPUBFUN htmlParserCtxt *
			htmlCreateFileParserCtxt(const char *filename,
	                                         const char *encoding);
XML_DEPRECATED
XMLPUBFUN xmlDoc *
			htmlSAXParseFile(const char *filename,
					 const char *encoding,
					 htmlSAXHandler *sax,
					 void *userData);
XMLPUBFUN xmlDoc *
			htmlParseFile	(const char *filename,
					 const char *encoding);
XML_DEPRECATED
XMLPUBFUN int
			htmlUTF8ToHtml	(unsigned char *out,
					 int *outlen,
					 const unsigned char *in,
					 int *inlen);
XML_DEPRECATED
XMLPUBFUN int
			htmlEncodeEntities(unsigned char *out,
					 int *outlen,
					 const unsigned char *in,
					 int *inlen, int quoteChar);
XML_DEPRECATED
XMLPUBFUN int
			htmlIsScriptAttribute(const xmlChar *name);
XML_DEPRECATED
XMLPUBFUN int
			htmlHandleOmittedElem(int val);

#ifdef LIBXML_PUSH_ENABLED
/*
 * Interfaces for the Push mode.
 */
XMLPUBFUN htmlParserCtxt *
			htmlCreatePushParserCtxt(htmlSAXHandler *sax,
						 void *user_data,
						 const char *chunk,
						 int size,
						 const char *filename,
						 xmlCharEncoding enc);
XMLPUBFUN int
			htmlParseChunk		(htmlParserCtxt *ctxt,
						 const char *chunk,
						 int size,
						 int terminate);
#endif /* LIBXML_PUSH_ENABLED */

XMLPUBFUN void
			htmlFreeParserCtxt	(htmlParserCtxt *ctxt);

/*
 * New set of simpler/more flexible APIs
 */

/**
 * This is the set of HTML parser options that can be passed to
 * #htmlReadDoc, #htmlCtxtSetOptions and other functions.
 */
typedef enum {
    /**
     * No effect as of 2.14.0.
     */
    HTML_PARSE_RECOVER = 1<<0,
    /**
     * Do not default to a doctype if none was found.
     */
    HTML_PARSE_NODEFDTD = 1<<2,
    /**
     * Disable error and warning reports to the error handlers.
     * Errors are still accessible with xmlCtxtGetLastError().
     */
    HTML_PARSE_NOERROR = 1<<5,
    /**
     * Disable warning reports.
     */
    HTML_PARSE_NOWARNING = 1<<6,
    /**
     * No effect.
     */
    HTML_PARSE_PEDANTIC = 1<<7,
    /**
     * Remove some text nodes containing only whitespace from the
     * result document. Which nodes are removed depends on a conservative
     * heuristic. The reindenting feature of the serialization code relies
     * on this option to be set when parsing. Use of this option is
     * DISCOURAGED.
     */
    HTML_PARSE_NOBLANKS = 1<<8,
    /**
     * No effect.
     */
    HTML_PARSE_NONET = 1<<11,
    /**
     * Do not add implied html, head or body elements.
     */
    HTML_PARSE_NOIMPLIED = 1<<13,
    /**
     * Store small strings directly in the node struct to save
     * memory.
    */
    HTML_PARSE_COMPACT = 1<<16,
    /**
     * Relax some internal limits. See XML_PARSE_HUGE in xmlParserOption.
     *
     * @since 2.14.0
     *
     * Use XML_PARSE_HUGE with older versions.
     */
    HTML_PARSE_HUGE = 1<<19,
    /**
     * Ignore the encoding in the HTML declaration. This option is
     * mostly unneeded these days. The only effect is to enforce
     * ISO-8859-1 decoding of ASCII-like data.
     */
    HTML_PARSE_IGNORE_ENC =1<<21,
    /**
     * Enable reporting of line numbers larger than 65535.
     *
     * @since 2.14.0
     *
     * Use XML_PARSE_BIG_LINES with older versions.
     */
    HTML_PARSE_BIG_LINES = 1<<22,
    /**
     * Make the tokenizer emit a SAX callback for each token. This results
     * in unbalanced invocations of startElement and endElement.
     *
     * For now, this is only usable to tokenize HTML5 with custom SAX
     * callbacks. A tree builder isn't implemented yet.
     *
     * @since 2.14.0
    */
    HTML_PARSE_HTML5 = 1<<26
} htmlParserOption;

XMLPUBFUN void
		htmlCtxtReset		(htmlParserCtxt *ctxt);
XMLPUBFUN int
		htmlCtxtSetOptions	(htmlParserCtxt *ctxt,
					 int options);
XMLPUBFUN int
		htmlCtxtUseOptions	(htmlParserCtxt *ctxt,
					 int options);
XMLPUBFUN xmlDoc *
		htmlReadDoc		(const xmlChar *cur,
					 const char *URL,
					 const char *encoding,
					 int options);
XMLPUBFUN xmlDoc *
		htmlReadFile		(const char *URL,
					 const char *encoding,
					 int options);
XMLPUBFUN xmlDoc *
		htmlReadMemory		(const char *buffer,
					 int size,
					 const char *URL,
					 const char *encoding,
					 int options);
XMLPUBFUN xmlDoc *
		htmlReadFd		(int fd,
					 const char *URL,
					 const char *encoding,
					 int options);
XMLPUBFUN xmlDoc *
		htmlReadIO		(xmlInputReadCallback ioread,
					 xmlInputCloseCallback ioclose,
					 void *ioctx,
					 const char *URL,
					 const char *encoding,
					 int options);
XMLPUBFUN xmlDoc *
		htmlCtxtParseDocument	(htmlParserCtxt *ctxt,
					 xmlParserInput *input);
XMLPUBFUN xmlDoc *
		htmlCtxtReadDoc		(xmlParserCtxt *ctxt,
					 const xmlChar *cur,
					 const char *URL,
					 const char *encoding,
					 int options);
XMLPUBFUN xmlDoc *
		htmlCtxtReadFile		(xmlParserCtxt *ctxt,
					 const char *filename,
					 const char *encoding,
					 int options);
XMLPUBFUN xmlDoc *
		htmlCtxtReadMemory		(xmlParserCtxt *ctxt,
					 const char *buffer,
					 int size,
					 const char *URL,
					 const char *encoding,
					 int options);
XMLPUBFUN xmlDoc *
		htmlCtxtReadFd		(xmlParserCtxt *ctxt,
					 int fd,
					 const char *URL,
					 const char *encoding,
					 int options);
XMLPUBFUN xmlDoc *
		htmlCtxtReadIO		(xmlParserCtxt *ctxt,
					 xmlInputReadCallback ioread,
					 xmlInputCloseCallback ioclose,
					 void *ioctx,
					 const char *URL,
					 const char *encoding,
					 int options);

/**
 * deprecated content model
 */
typedef enum {
  HTML_NA = 0 ,		/* something we don't check at all */
  HTML_INVALID = 0x1 ,
  HTML_DEPRECATED = 0x2 ,
  HTML_VALID = 0x4 ,
  HTML_REQUIRED = 0xc /* VALID bit set so ( & HTML_VALID ) is TRUE */
} htmlStatus ;

/* Using htmlElemDesc rather than name here, to emphasise the fact
   that otherwise there's a lookup overhead
*/
XML_DEPRECATED
XMLPUBFUN htmlStatus htmlAttrAllowed(const htmlElemDesc*, const xmlChar*, int) ;
XML_DEPRECATED
XMLPUBFUN int htmlElementAllowedHere(const htmlElemDesc*, const xmlChar*) ;
XML_DEPRECATED
XMLPUBFUN htmlStatus htmlElementStatusHere(const htmlElemDesc*, const htmlElemDesc*) ;
XML_DEPRECATED
XMLPUBFUN htmlStatus htmlNodeStatus(xmlNode *, int) ;

#ifdef __cplusplus
}
#endif

#endif /* LIBXML_HTML_ENABLED */
#endif /* __HTML_PARSER_H__ */
libxml2/libxml/valid.h000064400000027160151733237450010674 0ustar00/**
 * @file
 * 
 * @brief DTD validator
 * 
 * API to handle XML Document Type Definitions and validate
 * documents.
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */


#ifndef __XML_VALID_H__
#define __XML_VALID_H__

#include <libxml/xmlversion.h>
#include <libxml/xmlerror.h>
#define XML_TREE_INTERNALS
#include <libxml/tree.h>
#undef XML_TREE_INTERNALS
#include <libxml/list.h>
#include <libxml/xmlautomata.h>
#include <libxml/xmlregexp.h>

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Validation state added for non-deterministic content model.
 */
typedef struct _xmlValidState xmlValidState;
typedef xmlValidState *xmlValidStatePtr;

/**
 * Report a validity error.
 *
 * @param ctx  user data (usually an xmlValidCtxt)
 * @param msg  printf-like format string
 * @param ...  arguments to format
 */
typedef void (*xmlValidityErrorFunc) (void *ctx,
			     const char *msg,
			     ...) LIBXML_ATTR_FORMAT(2,3);

/**
 * Report a validity warning.
 *
 * @param ctx  user data (usually an xmlValidCtxt)
 * @param msg  printf-like format string
 * @param ...  arguments to format
 */
typedef void (*xmlValidityWarningFunc) (void *ctx,
			       const char *msg,
			       ...) LIBXML_ATTR_FORMAT(2,3);

typedef struct _xmlValidCtxt xmlValidCtxt;
typedef xmlValidCtxt *xmlValidCtxtPtr;
/**
 * An xmlValidCtxt is used for error reporting when validating.
 */
struct _xmlValidCtxt {
    void *userData;			/* user specific data block */
    xmlValidityErrorFunc error;		/* the callback in case of errors */
    xmlValidityWarningFunc warning;	/* the callback in case of warning */

    /* Node analysis stack used when validating within entities */
    xmlNode           *node;          /* Current parsed Node */
    int                nodeNr;        /* Depth of the parsing stack */
    int                nodeMax;       /* Max depth of the parsing stack */
    xmlNode          **nodeTab;       /* array of nodes */

    unsigned int         flags;       /* internal flags */
    xmlDoc                *doc;       /* the document */
    int                  valid;       /* temporary validity check result */

    /* state state used for non-determinist content validation */
    xmlValidState     *vstate;        /* current state */
    int                vstateNr;      /* Depth of the validation stack */
    int                vstateMax;     /* Max depth of the validation stack */
    xmlValidState     *vstateTab;     /* array of validation states */

#ifdef LIBXML_REGEXP_ENABLED
    xmlAutomata              *am;     /* the automata */
    xmlAutomataState      *state;     /* used to build the automata */
#else
    void                     *am;
    void                  *state;
#endif
};

typedef struct _xmlHashTable xmlNotationTable;
typedef xmlNotationTable *xmlNotationTablePtr;

typedef struct _xmlHashTable xmlElementTable;
typedef xmlElementTable *xmlElementTablePtr;

typedef struct _xmlHashTable xmlAttributeTable;
typedef xmlAttributeTable *xmlAttributeTablePtr;

typedef struct _xmlHashTable xmlIDTable;
typedef xmlIDTable *xmlIDTablePtr;

typedef struct _xmlHashTable xmlRefTable;
typedef xmlRefTable *xmlRefTablePtr;

/* Notation */
XMLPUBFUN xmlNotation *
		xmlAddNotationDecl	(xmlValidCtxt *ctxt,
					 xmlDtd *dtd,
					 const xmlChar *name,
					 const xmlChar *publicId,
					 const xmlChar *systemId);
XML_DEPRECATED
XMLPUBFUN xmlNotationTable *
		xmlCopyNotationTable	(xmlNotationTable *table);
XML_DEPRECATED
XMLPUBFUN void
		xmlFreeNotationTable	(xmlNotationTable *table);
#ifdef LIBXML_OUTPUT_ENABLED
XML_DEPRECATED
XMLPUBFUN void
		xmlDumpNotationDecl	(xmlBuffer *buf,
					 xmlNotation *nota);
/* XML_DEPRECATED, still used in lxml */
XMLPUBFUN void
		xmlDumpNotationTable	(xmlBuffer *buf,
					 xmlNotationTable *table);
#endif /* LIBXML_OUTPUT_ENABLED */

/* Element Content */
XML_DEPRECATED
XMLPUBFUN xmlElementContent *
		xmlNewElementContent	(const xmlChar *name,
					 xmlElementContentType type);
XML_DEPRECATED
XMLPUBFUN xmlElementContent *
		xmlCopyElementContent	(xmlElementContent *content);
XML_DEPRECATED
XMLPUBFUN void
		xmlFreeElementContent	(xmlElementContent *cur);
XML_DEPRECATED
XMLPUBFUN xmlElementContent *
		xmlNewDocElementContent	(xmlDoc *doc,
					 const xmlChar *name,
					 xmlElementContentType type);
XML_DEPRECATED
XMLPUBFUN xmlElementContent *
		xmlCopyDocElementContent(xmlDoc *doc,
					 xmlElementContent *content);
XML_DEPRECATED
XMLPUBFUN void
		xmlFreeDocElementContent(xmlDoc *doc,
					 xmlElementContent *cur);
XML_DEPRECATED
XMLPUBFUN void
		xmlSnprintfElementContent(char *buf,
					 int size,
	                                 xmlElementContent *content,
					 int englob);
#ifdef LIBXML_OUTPUT_ENABLED
XML_DEPRECATED
XMLPUBFUN void
		xmlSprintfElementContent(char *buf,
	                                 xmlElementContent *content,
					 int englob);
#endif /* LIBXML_OUTPUT_ENABLED */

/* Element */
XMLPUBFUN xmlElement *
		xmlAddElementDecl	(xmlValidCtxt *ctxt,
					 xmlDtd *dtd,
					 const xmlChar *name,
					 xmlElementTypeVal type,
					 xmlElementContent *content);
XML_DEPRECATED
XMLPUBFUN xmlElementTable *
		xmlCopyElementTable	(xmlElementTable *table);
XML_DEPRECATED
XMLPUBFUN void
		xmlFreeElementTable	(xmlElementTable *table);
#ifdef LIBXML_OUTPUT_ENABLED
XML_DEPRECATED
XMLPUBFUN void
		xmlDumpElementTable	(xmlBuffer *buf,
					 xmlElementTable *table);
XML_DEPRECATED
XMLPUBFUN void
		xmlDumpElementDecl	(xmlBuffer *buf,
					 xmlElement *elem);
#endif /* LIBXML_OUTPUT_ENABLED */

/* Enumeration */
XML_DEPRECATED
XMLPUBFUN xmlEnumeration *
		xmlCreateEnumeration	(const xmlChar *name);
/* XML_DEPRECATED, needed for custom attributeDecl SAX handler */
XMLPUBFUN void
		xmlFreeEnumeration	(xmlEnumeration *cur);
XML_DEPRECATED
XMLPUBFUN xmlEnumeration *
		xmlCopyEnumeration	(xmlEnumeration *cur);

/* Attribute */
XMLPUBFUN xmlAttribute *
		xmlAddAttributeDecl	(xmlValidCtxt *ctxt,
					 xmlDtd *dtd,
					 const xmlChar *elem,
					 const xmlChar *name,
					 const xmlChar *ns,
					 xmlAttributeType type,
					 xmlAttributeDefault def,
					 const xmlChar *defaultValue,
					 xmlEnumeration *tree);
XML_DEPRECATED
XMLPUBFUN xmlAttributeTable *
		xmlCopyAttributeTable  (xmlAttributeTable *table);
XML_DEPRECATED
XMLPUBFUN void
		xmlFreeAttributeTable  (xmlAttributeTable *table);
#ifdef LIBXML_OUTPUT_ENABLED
XML_DEPRECATED
XMLPUBFUN void
		xmlDumpAttributeTable  (xmlBuffer *buf,
					xmlAttributeTable *table);
XML_DEPRECATED
XMLPUBFUN void
		xmlDumpAttributeDecl   (xmlBuffer *buf,
					xmlAttribute *attr);
#endif /* LIBXML_OUTPUT_ENABLED */

/* IDs */
XMLPUBFUN int
		xmlAddIDSafe	       (xmlAttr *attr,
					const xmlChar *value);
XMLPUBFUN xmlID *
		xmlAddID	       (xmlValidCtxt *ctxt,
					xmlDoc *doc,
					const xmlChar *value,
					xmlAttr *attr);
XMLPUBFUN void
		xmlFreeIDTable	       (xmlIDTable *table);
XMLPUBFUN xmlAttr *
		xmlGetID	       (xmlDoc *doc,
					const xmlChar *ID);
XMLPUBFUN int
		xmlIsID		       (xmlDoc *doc,
					xmlNode *elem,
					xmlAttr *attr);
XMLPUBFUN int
		xmlRemoveID	       (xmlDoc *doc,
					xmlAttr *attr);

/* IDREFs */
XML_DEPRECATED
XMLPUBFUN xmlRef *
		xmlAddRef	       (xmlValidCtxt *ctxt,
					xmlDoc *doc,
					const xmlChar *value,
					xmlAttr *attr);
XML_DEPRECATED
XMLPUBFUN void
		xmlFreeRefTable	       (xmlRefTable *table);
XML_DEPRECATED
XMLPUBFUN int
		xmlIsRef	       (xmlDoc *doc,
					xmlNode *elem,
					xmlAttr *attr);
XML_DEPRECATED
XMLPUBFUN int
		xmlRemoveRef	       (xmlDoc *doc,
					xmlAttr *attr);
XML_DEPRECATED
XMLPUBFUN xmlList *
		xmlGetRefs	       (xmlDoc *doc,
					const xmlChar *ID);

/**
 * The public function calls related to validity checking.
 */
#ifdef LIBXML_VALID_ENABLED
/* Allocate/Release Validation Contexts */
XMLPUBFUN xmlValidCtxt *
		xmlNewValidCtxt(void);
XMLPUBFUN void
		xmlFreeValidCtxt(xmlValidCtxt *);

XML_DEPRECATED
XMLPUBFUN int
		xmlValidateRoot		(xmlValidCtxt *ctxt,
					 xmlDoc *doc);
XML_DEPRECATED
XMLPUBFUN int
		xmlValidateElementDecl	(xmlValidCtxt *ctxt,
					 xmlDoc *doc,
		                         xmlElement *elem);
XML_DEPRECATED
XMLPUBFUN xmlChar *
		xmlValidNormalizeAttributeValue(xmlDoc *doc,
					 xmlNode *elem,
					 const xmlChar *name,
					 const xmlChar *value);
XML_DEPRECATED
XMLPUBFUN xmlChar *
		xmlValidCtxtNormalizeAttributeValue(xmlValidCtxt *ctxt,
					 xmlDoc *doc,
					 xmlNode *elem,
					 const xmlChar *name,
					 const xmlChar *value);
XML_DEPRECATED
XMLPUBFUN int
		xmlValidateAttributeDecl(xmlValidCtxt *ctxt,
					 xmlDoc *doc,
		                         xmlAttribute *attr);
XML_DEPRECATED
XMLPUBFUN int
		xmlValidateAttributeValue(xmlAttributeType type,
					 const xmlChar *value);
XML_DEPRECATED
XMLPUBFUN int
		xmlValidateNotationDecl	(xmlValidCtxt *ctxt,
					 xmlDoc *doc,
		                         xmlNotation *nota);
XMLPUBFUN int
		xmlValidateDtd		(xmlValidCtxt *ctxt,
					 xmlDoc *doc,
					 xmlDtd *dtd);
XML_DEPRECATED
XMLPUBFUN int
		xmlValidateDtdFinal	(xmlValidCtxt *ctxt,
					 xmlDoc *doc);
XMLPUBFUN int
		xmlValidateDocument	(xmlValidCtxt *ctxt,
					 xmlDoc *doc);
XMLPUBFUN int
		xmlValidateElement	(xmlValidCtxt *ctxt,
					 xmlDoc *doc,
					 xmlNode *elem);
XML_DEPRECATED
XMLPUBFUN int
		xmlValidateOneElement	(xmlValidCtxt *ctxt,
					 xmlDoc *doc,
		                         xmlNode *elem);
XML_DEPRECATED
XMLPUBFUN int
		xmlValidateOneAttribute	(xmlValidCtxt *ctxt,
					 xmlDoc *doc,
					 xmlNode 	*elem,
					 xmlAttr *attr,
					 const xmlChar *value);
XML_DEPRECATED
XMLPUBFUN int
		xmlValidateOneNamespace	(xmlValidCtxt *ctxt,
					 xmlDoc *doc,
					 xmlNode *elem,
					 const xmlChar *prefix,
					 xmlNs *ns,
					 const xmlChar *value);
XML_DEPRECATED
XMLPUBFUN int
		xmlValidateDocumentFinal(xmlValidCtxt *ctxt,
					 xmlDoc *doc);
XML_DEPRECATED
XMLPUBFUN int
		xmlValidateNotationUse	(xmlValidCtxt *ctxt,
					 xmlDoc *doc,
					 const xmlChar *notationName);
#endif /* LIBXML_VALID_ENABLED */

XML_DEPRECATED
XMLPUBFUN int
		xmlIsMixedElement	(xmlDoc *doc,
					 const xmlChar *name);
XMLPUBFUN xmlAttribute *
		xmlGetDtdAttrDesc	(xmlDtd *dtd,
					 const xmlChar *elem,
					 const xmlChar *name);
XMLPUBFUN xmlAttribute *
		xmlGetDtdQAttrDesc	(xmlDtd *dtd,
					 const xmlChar *elem,
					 const xmlChar *name,
					 const xmlChar *prefix);
XMLPUBFUN xmlNotation *
		xmlGetDtdNotationDesc	(xmlDtd *dtd,
					 const xmlChar *name);
XMLPUBFUN xmlElement *
		xmlGetDtdQElementDesc	(xmlDtd *dtd,
					 const xmlChar *name,
					 const xmlChar *prefix);
XMLPUBFUN xmlElement *
		xmlGetDtdElementDesc	(xmlDtd *dtd,
					 const xmlChar *name);

#ifdef LIBXML_VALID_ENABLED

XMLPUBFUN int
		xmlValidGetPotentialChildren(xmlElementContent *ctree,
					 const xmlChar **names,
					 int *len,
					 int max);

/* only needed for `xmllint --insert` */
XMLPUBFUN int
		xmlValidGetValidElements(xmlNode *prev,
					 xmlNode *next,
					 const xmlChar **names,
					 int max);
XMLPUBFUN int
		xmlValidateNameValue	(const xmlChar *value);
XMLPUBFUN int
		xmlValidateNamesValue	(const xmlChar *value);
XMLPUBFUN int
		xmlValidateNmtokenValue	(const xmlChar *value);
XMLPUBFUN int
		xmlValidateNmtokensValue(const xmlChar *value);

#ifdef LIBXML_REGEXP_ENABLED
/*
 * Validation based on the regexp support
 */
XML_DEPRECATED
XMLPUBFUN int
		xmlValidBuildContentModel(xmlValidCtxt *ctxt,
					 xmlElement *elem);

XML_DEPRECATED
XMLPUBFUN int
		xmlValidatePushElement	(xmlValidCtxt *ctxt,
					 xmlDoc *doc,
					 xmlNode *elem,
					 const xmlChar *qname);
XML_DEPRECATED
XMLPUBFUN int
		xmlValidatePushCData	(xmlValidCtxt *ctxt,
					 const xmlChar *data,
					 int len);
XML_DEPRECATED
XMLPUBFUN int
		xmlValidatePopElement	(xmlValidCtxt *ctxt,
					 xmlDoc *doc,
					 xmlNode *elem,
					 const xmlChar *qname);
#endif /* LIBXML_REGEXP_ENABLED */

#endif /* LIBXML_VALID_ENABLED */

#ifdef __cplusplus
}
#endif
#endif /* __XML_VALID_H__ */
libxml2/libxml/encoding.h000064400000023207151733237450011361 0ustar00/**
 * @file
 * 
 * @brief Character encoding conversion functions
 * 
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */

#ifndef __XML_CHAR_ENCODING_H__
#define __XML_CHAR_ENCODING_H__

#include <libxml/xmlversion.h>
#include <libxml/xmlerror.h>

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Backward compatibility
 */
/** @cond ignore */
#define UTF8Toisolat1 xmlUTF8ToIsolat1
#define isolat1ToUTF8 xmlIsolat1ToUTF8
/** @endcond */

/**
 * Encoding conversion errors
 */
typedef enum {
    /** Success */
    XML_ENC_ERR_SUCCESS     =  0,
    /** Internal or unclassified error */
    XML_ENC_ERR_INTERNAL    = -1,
    /** Invalid or untranslatable input sequence */
    XML_ENC_ERR_INPUT       = -2,
    /** Not enough space in output buffer */
    XML_ENC_ERR_SPACE       = -3,
    /** Out-of-memory error */
    XML_ENC_ERR_MEMORY      = -4
} xmlCharEncError;

/**
 * Predefined values for some standard encodings.
 */
typedef enum {
    /** No char encoding detected */
    XML_CHAR_ENCODING_ERROR=   -1,
    /** No char encoding detected */
    XML_CHAR_ENCODING_NONE=	0,
    /** UTF-8 */
    XML_CHAR_ENCODING_UTF8=	1,
    /** UTF-16 little endian */
    XML_CHAR_ENCODING_UTF16LE=	2,
    /** UTF-16 big endian */
    XML_CHAR_ENCODING_UTF16BE=	3,
    /** UCS-4 little endian */
    XML_CHAR_ENCODING_UCS4LE=	4,
    /** UCS-4 big endian */
    XML_CHAR_ENCODING_UCS4BE=	5,
    /** EBCDIC uh! */
    XML_CHAR_ENCODING_EBCDIC=	6,
    /** UCS-4 unusual ordering */
    XML_CHAR_ENCODING_UCS4_2143=7,
    /** UCS-4 unusual ordering */
    XML_CHAR_ENCODING_UCS4_3412=8,
    /** UCS-2 */
    XML_CHAR_ENCODING_UCS2=	9,
    /** ISO-8859-1 ISO Latin 1 */
    XML_CHAR_ENCODING_8859_1=	10,
    /** ISO-8859-2 ISO Latin 2 */
    XML_CHAR_ENCODING_8859_2=	11,
    /** ISO-8859-3 */
    XML_CHAR_ENCODING_8859_3=	12,
    /** ISO-8859-4 */
    XML_CHAR_ENCODING_8859_4=	13,
    /** ISO-8859-5 */
    XML_CHAR_ENCODING_8859_5=	14,
    /** ISO-8859-6 */
    XML_CHAR_ENCODING_8859_6=	15,
    /** ISO-8859-7 */
    XML_CHAR_ENCODING_8859_7=	16,
    /** ISO-8859-8 */
    XML_CHAR_ENCODING_8859_8=	17,
    /** ISO-8859-9 */
    XML_CHAR_ENCODING_8859_9=	18,
    /** ISO-2022-JP */
    XML_CHAR_ENCODING_2022_JP=  19,
    /** Shift_JIS */
    XML_CHAR_ENCODING_SHIFT_JIS=20,
    /** EUC-JP */
    XML_CHAR_ENCODING_EUC_JP=   21,
    /** pure ASCII */
    XML_CHAR_ENCODING_ASCII=    22,
    /** UTF-16 native, available since 2.14 */
    XML_CHAR_ENCODING_UTF16=	23,
    /** HTML (output only), available since 2.14 */
    XML_CHAR_ENCODING_HTML=	24,
    /** ISO-8859-10, available since 2.14 */
    XML_CHAR_ENCODING_8859_10=	25,
    /** ISO-8859-11, available since 2.14 */
    XML_CHAR_ENCODING_8859_11=	26,
    /** ISO-8859-13, available since 2.14 */
    XML_CHAR_ENCODING_8859_13=	27,
    /** ISO-8859-14, available since 2.14 */
    XML_CHAR_ENCODING_8859_14=	28,
    /** ISO-8859-15, available since 2.14 */
    XML_CHAR_ENCODING_8859_15=	29,
    /** ISO-8859-16, available since 2.14 */
    XML_CHAR_ENCODING_8859_16=	30,
    /** windows-1252, available since 2.15 */
    XML_CHAR_ENCODING_WINDOWS_1252 = 31
} xmlCharEncoding;

/**
 * Encoding conversion flags
 */
typedef enum {
    /** Create converter for input (conversion to UTF-8) */
    XML_ENC_INPUT = (1 << 0),
    /** Create converter for output (conversion from UTF-8) */
    XML_ENC_OUTPUT = (1 << 1),
    /** Use HTML5 mappings */
    XML_ENC_HTML = (1 << 2)
} xmlCharEncFlags;

/**
 * Convert characters to UTF-8.
 *
 * On success, the value of `inlen` after return is the number of
 * bytes consumed and `outlen` is the number of bytes produced.
 *
 * @param out  a pointer to an array of bytes to store the UTF-8 result
 * @param outlen  the length of `out`
 * @param in  a pointer to an array of chars in the original encoding
 * @param inlen  the length of `in`
 * @returns the number of bytes written or an xmlCharEncError code.
 */
typedef int (*xmlCharEncodingInputFunc)(unsigned char *out, int *outlen,
                                        const unsigned char *in, int *inlen);


/**
 * Convert characters from UTF-8.
 *
 * On success, the value of `inlen` after return is the number of
 * bytes consumed and `outlen` is the number of bytes produced.
 *
 * @param out  a pointer to an array of bytes to store the result
 * @param outlen  the length of `out`
 * @param in  a pointer to an array of UTF-8 chars
 * @param inlen  the length of `in`
 * @returns the number of bytes written or an xmlCharEncError code.
 */
typedef int (*xmlCharEncodingOutputFunc)(unsigned char *out, int *outlen,
                                         const unsigned char *in, int *inlen);


/**
 * Convert between character encodings.
 *
 * The value of `inlen` after return is the number of bytes consumed
 * and `outlen` is the number of bytes produced.
 *
 * If the converter can consume partial multi-byte sequences, the
 * `flush` flag can be used to detect truncated sequences at EOF.
 * Otherwise, the flag can be ignored.
 *
 * @param vctxt  conversion context
 * @param out  a pointer to an array of bytes to store the result
 * @param outlen  the length of `out`
 * @param in  a pointer to an array of input bytes
 * @param inlen  the length of `in`
 * @param flush  end of input
 * @returns an xmlCharEncError code.
 */
typedef xmlCharEncError
(*xmlCharEncConvFunc)(void *vctxt, unsigned char *out, int *outlen,
                      const unsigned char *in, int *inlen, int flush);

/**
 * Free a conversion context.
 *
 * @param vctxt  conversion context
 */
typedef void
(*xmlCharEncConvCtxtDtor)(void *vctxt);

/** Character encoding converter */
typedef struct _xmlCharEncodingHandler xmlCharEncodingHandler;
typedef xmlCharEncodingHandler *xmlCharEncodingHandlerPtr;
/**
 * A character encoding conversion handler for non UTF-8 encodings.
 *
 * This structure will be made private.
 */
struct _xmlCharEncodingHandler {
    char *name XML_DEPRECATED_MEMBER;
    union {
        xmlCharEncConvFunc func;
        xmlCharEncodingInputFunc legacyFunc;
    } input XML_DEPRECATED_MEMBER;
    union {
        xmlCharEncConvFunc func;
        xmlCharEncodingOutputFunc legacyFunc;
    } output XML_DEPRECATED_MEMBER;
    void *inputCtxt XML_DEPRECATED_MEMBER;
    void *outputCtxt XML_DEPRECATED_MEMBER;
    xmlCharEncConvCtxtDtor ctxtDtor XML_DEPRECATED_MEMBER;
    int flags XML_DEPRECATED_MEMBER;
};

/**
 * If this function returns XML_ERR_OK, it must fill the `out`
 * pointer with an encoding handler. The handler can be obtained
 * from #xmlCharEncNewCustomHandler.
 *
 * `flags` can contain XML_ENC_INPUT, XML_ENC_OUTPUT or both.
 *
 * @param vctxt  user data
 * @param name  encoding name
 * @param flags  bit mask of flags
 * @param out  pointer to resulting handler
 * @returns an xmlParserErrors code.
 */
typedef xmlParserErrors
(*xmlCharEncConvImpl)(void *vctxt, const char *name, xmlCharEncFlags flags,
                      xmlCharEncodingHandler **out);

/*
 * Interfaces for encoding handlers.
 */
XML_DEPRECATED
XMLPUBFUN void
	xmlInitCharEncodingHandlers	(void);
XML_DEPRECATED
XMLPUBFUN void
	xmlCleanupCharEncodingHandlers	(void);
XML_DEPRECATED
XMLPUBFUN void
	xmlRegisterCharEncodingHandler	(xmlCharEncodingHandler *handler);
XMLPUBFUN xmlParserErrors
	xmlLookupCharEncodingHandler	(xmlCharEncoding enc,
					 xmlCharEncodingHandler **out);
XMLPUBFUN xmlParserErrors
	xmlOpenCharEncodingHandler	(const char *name,
					 int output,
					 xmlCharEncodingHandler **out);
XMLPUBFUN xmlParserErrors
	xmlCreateCharEncodingHandler	(const char *name,
					 xmlCharEncFlags flags,
					 xmlCharEncConvImpl impl,
					 void *implCtxt,
					 xmlCharEncodingHandler **out);
XMLPUBFUN xmlCharEncodingHandler *
	xmlGetCharEncodingHandler	(xmlCharEncoding enc);
XMLPUBFUN xmlCharEncodingHandler *
	xmlFindCharEncodingHandler	(const char *name);
XML_DEPRECATED
XMLPUBFUN xmlCharEncodingHandler *
	xmlNewCharEncodingHandler	(const char *name,
					 xmlCharEncodingInputFunc input,
					 xmlCharEncodingOutputFunc output);
XMLPUBFUN xmlParserErrors
	xmlCharEncNewCustomHandler	(const char *name,
					 xmlCharEncConvFunc input,
					 xmlCharEncConvFunc output,
					 xmlCharEncConvCtxtDtor ctxtDtor,
					 void *inputCtxt,
					 void *outputCtxt,
					 xmlCharEncodingHandler **out);

/*
 * Interfaces for encoding names and aliases.
 */
XML_DEPRECATED
XMLPUBFUN int
	xmlAddEncodingAlias		(const char *name,
					 const char *alias);
XML_DEPRECATED
XMLPUBFUN int
	xmlDelEncodingAlias		(const char *alias);
XML_DEPRECATED
XMLPUBFUN const char *
	xmlGetEncodingAlias		(const char *alias);
XML_DEPRECATED
XMLPUBFUN void
	xmlCleanupEncodingAliases	(void);
XMLPUBFUN xmlCharEncoding
	xmlParseCharEncoding		(const char *name);
XMLPUBFUN const char *
	xmlGetCharEncodingName		(xmlCharEncoding enc);

/*
 * Interfaces directly used by the parsers.
 */
XMLPUBFUN xmlCharEncoding
	xmlDetectCharEncoding		(const unsigned char *in,
					 int len);

struct _xmlBuffer;
XMLPUBFUN int
	xmlCharEncOutFunc		(xmlCharEncodingHandler *handler,
					 struct _xmlBuffer *out,
					 struct _xmlBuffer *in);

XMLPUBFUN int
	xmlCharEncInFunc		(xmlCharEncodingHandler *handler,
					 struct _xmlBuffer *out,
					 struct _xmlBuffer *in);
XML_DEPRECATED
XMLPUBFUN int
	xmlCharEncFirstLine		(xmlCharEncodingHandler *handler,
					 struct _xmlBuffer *out,
					 struct _xmlBuffer *in);
XMLPUBFUN int
	xmlCharEncCloseFunc		(xmlCharEncodingHandler *handler);

/*
 * Export a few useful functions
 */
#ifdef LIBXML_OUTPUT_ENABLED
XMLPUBFUN int
	xmlUTF8ToIsolat1		(unsigned char *out,
					 int *outlen,
					 const unsigned char *in,
					 int *inlen);
#endif /* LIBXML_OUTPUT_ENABLED */
XMLPUBFUN int
	xmlIsolat1ToUTF8		(unsigned char *out,
					 int *outlen,
					 const unsigned char *in,
					 int *inlen);
#ifdef __cplusplus
}
#endif

#endif /* __XML_CHAR_ENCODING_H__ */
libxml2/libxml/c14n.h000064400000005165151733237450010343 0ustar00/**
 * @file
 * 
 * @brief Provide Canonical XML and Exclusive XML Canonicalization
 * 
 * the c14n modules provides a
 *
 * "Canonical XML" implementation
 * http://www.w3.org/TR/xml-c14n
 *
 * and an
 *
 * "Exclusive XML Canonicalization" implementation
 * http://www.w3.org/TR/xml-exc-c14n

 * @copyright See Copyright for the status of this software.
 *
 * @author Aleksey Sanin
 */
#ifndef __XML_C14N_H__
#define __XML_C14N_H__

#include <libxml/xmlversion.h>

#ifdef LIBXML_C14N_ENABLED

#include <libxml/tree.h>
#include <libxml/xpath.h>

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/*
 * XML Canonicalization
 * http://www.w3.org/TR/xml-c14n
 *
 * Exclusive XML Canonicalization
 * http://www.w3.org/TR/xml-exc-c14n
 *
 * Canonical form of an XML document could be created if and only if
 *  a) default attributes (if any) are added to all nodes
 *  b) all character and parsed entity references are resolved
 * In order to achieve this in libxml2 the document MUST be loaded with
 * following options: XML_PARSE_DTDATTR | XML_PARSE_NOENT
 */

/**
 * Predefined values for C14N modes
 */
typedef enum {
    /** Original C14N 1.0 spec */
    XML_C14N_1_0            = 0,
    /** Exclusive C14N 1.0 spec */
    XML_C14N_EXCLUSIVE_1_0  = 1,
    /** C14N 1.1 spec */
    XML_C14N_1_1            = 2
} xmlC14NMode;

XMLPUBFUN int
		xmlC14NDocSaveTo	(xmlDoc *doc,
					 xmlNodeSet *nodes,
					 int mode, /* a xmlC14NMode */
					 xmlChar **inclusive_ns_prefixes,
					 int with_comments,
					 xmlOutputBuffer *buf);

XMLPUBFUN int
		xmlC14NDocDumpMemory	(xmlDoc *doc,
					 xmlNodeSet *nodes,
					 int mode, /* a xmlC14NMode */
					 xmlChar **inclusive_ns_prefixes,
					 int with_comments,
					 xmlChar **doc_txt_ptr);

XMLPUBFUN int
		xmlC14NDocSave		(xmlDoc *doc,
					 xmlNodeSet *nodes,
					 int mode, /* a xmlC14NMode */
					 xmlChar **inclusive_ns_prefixes,
					 int with_comments,
					 const char* filename,
					 int compression);


/**
 * This is the core C14N function
 */
/**
 * Signature for a C14N callback on visible nodes
 *
 * @param user_data  user data
 * @param node  the current node
 * @param parent  the parent node
 * @returns 1 if the node should be included
 */
typedef int (*xmlC14NIsVisibleCallback)	(void* user_data,
					 xmlNode *node,
					 xmlNode *parent);

XMLPUBFUN int
		xmlC14NExecute		(xmlDoc *doc,
					 xmlC14NIsVisibleCallback is_visible_callback,
					 void* user_data,
					 int mode, /* a xmlC14NMode */
					 xmlChar **inclusive_ns_prefixes,
					 int with_comments,
					 xmlOutputBuffer *buf);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* LIBXML_C14N_ENABLED */
#endif /* __XML_C14N_H__ */

libxml2/libxml/xmlwriter.h000064400000047770151733237450011643 0ustar00/**
 * @file
 * 
 * @brief text writing API for XML
 * 
 * text writing API for XML
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Alfred Mickautsch
 */

#ifndef __XML_XMLWRITER_H__
#define __XML_XMLWRITER_H__

#include <libxml/xmlversion.h>

#ifdef LIBXML_WRITER_ENABLED

#include <stdarg.h>
#include <libxml/xmlIO.h>
#include <libxml/list.h>
#include <libxml/xmlstring.h>

#ifdef __cplusplus
extern "C" {
#endif

    /** Writer object */
    typedef struct _xmlTextWriter xmlTextWriter;
    typedef xmlTextWriter *xmlTextWriterPtr;

/*
 * Constructors & Destructor
 */
    XMLPUBFUN xmlTextWriter *
        xmlNewTextWriter(xmlOutputBuffer *out);
    XMLPUBFUN xmlTextWriter *
        xmlNewTextWriterFilename(const char *uri, int compression);
    XMLPUBFUN xmlTextWriter *
        xmlNewTextWriterMemory(xmlBuffer *buf, int compression);
    XMLPUBFUN xmlTextWriter *
        xmlNewTextWriterPushParser(xmlParserCtxt *ctxt, int compression);
    XMLPUBFUN xmlTextWriter *
        xmlNewTextWriterDoc(xmlDoc ** doc, int compression);
    XMLPUBFUN xmlTextWriter *
        xmlNewTextWriterTree(xmlDoc *doc, xmlNode *node,
                             int compression);
    XMLPUBFUN void xmlFreeTextWriter(xmlTextWriter *writer);

/*
 * Functions
 */


/*
 * Document
 */
    XMLPUBFUN int
        xmlTextWriterStartDocument(xmlTextWriter *writer,
                                   const char *version,
                                   const char *encoding,
                                   const char *standalone);
    XMLPUBFUN int xmlTextWriterEndDocument(xmlTextWriter *
                                                   writer);

/*
 * Comments
 */
    XMLPUBFUN int xmlTextWriterStartComment(xmlTextWriter *
                                                    writer);
    XMLPUBFUN int xmlTextWriterEndComment(xmlTextWriter *writer);
    XMLPUBFUN int
        xmlTextWriterWriteFormatComment(xmlTextWriter *writer,
                                        const char *format, ...)
					LIBXML_ATTR_FORMAT(2,3);
    XMLPUBFUN int
        xmlTextWriterWriteVFormatComment(xmlTextWriter *writer,
                                         const char *format,
                                         va_list argptr)
					 LIBXML_ATTR_FORMAT(2,0);
    XMLPUBFUN int xmlTextWriterWriteComment(xmlTextWriter *
                                                    writer,
                                                    const xmlChar *
                                                    content);

/*
 * Elements
 */
    XMLPUBFUN int
        xmlTextWriterStartElement(xmlTextWriter *writer,
                                  const xmlChar * name);
    XMLPUBFUN int xmlTextWriterStartElementNS(xmlTextWriter *
                                                      writer,
                                                      const xmlChar *
                                                      prefix,
                                                      const xmlChar * name,
                                                      const xmlChar *
                                                      namespaceURI);
    XMLPUBFUN int xmlTextWriterEndElement(xmlTextWriter *writer);
    XMLPUBFUN int xmlTextWriterFullEndElement(xmlTextWriter *
                                                      writer);

/*
 * Elements conveniency functions
 */
    XMLPUBFUN int
        xmlTextWriterWriteFormatElement(xmlTextWriter *writer,
                                        const xmlChar * name,
                                        const char *format, ...)
					LIBXML_ATTR_FORMAT(3,4);
    XMLPUBFUN int
        xmlTextWriterWriteVFormatElement(xmlTextWriter *writer,
                                         const xmlChar * name,
                                         const char *format,
                                         va_list argptr)
					 LIBXML_ATTR_FORMAT(3,0);
    XMLPUBFUN int xmlTextWriterWriteElement(xmlTextWriter *
                                                    writer,
                                                    const xmlChar * name,
                                                    const xmlChar *
                                                    content);
    XMLPUBFUN int
        xmlTextWriterWriteFormatElementNS(xmlTextWriter *writer,
                                          const xmlChar * prefix,
                                          const xmlChar * name,
                                          const xmlChar * namespaceURI,
                                          const char *format, ...)
					  LIBXML_ATTR_FORMAT(5,6);
    XMLPUBFUN int
        xmlTextWriterWriteVFormatElementNS(xmlTextWriter *writer,
                                           const xmlChar * prefix,
                                           const xmlChar * name,
                                           const xmlChar * namespaceURI,
                                           const char *format,
                                           va_list argptr)
					   LIBXML_ATTR_FORMAT(5,0);
    XMLPUBFUN int xmlTextWriterWriteElementNS(xmlTextWriter *
                                                      writer,
                                                      const xmlChar *
                                                      prefix,
                                                      const xmlChar * name,
                                                      const xmlChar *
                                                      namespaceURI,
                                                      const xmlChar *
                                                      content);

/*
 * Text
 */
    XMLPUBFUN int
        xmlTextWriterWriteFormatRaw(xmlTextWriter *writer,
                                    const char *format, ...)
				    LIBXML_ATTR_FORMAT(2,3);
    XMLPUBFUN int
        xmlTextWriterWriteVFormatRaw(xmlTextWriter *writer,
                                     const char *format, va_list argptr)
				     LIBXML_ATTR_FORMAT(2,0);
    XMLPUBFUN int
        xmlTextWriterWriteRawLen(xmlTextWriter *writer,
                                 const xmlChar * content, int len);
    XMLPUBFUN int
        xmlTextWriterWriteRaw(xmlTextWriter *writer,
                              const xmlChar * content);
    XMLPUBFUN int xmlTextWriterWriteFormatString(xmlTextWriter *
                                                         writer,
                                                         const char
                                                         *format, ...)
							 LIBXML_ATTR_FORMAT(2,3);
    XMLPUBFUN int xmlTextWriterWriteVFormatString(xmlTextWriter *
                                                          writer,
                                                          const char
                                                          *format,
                                                          va_list argptr)
							  LIBXML_ATTR_FORMAT(2,0);
    XMLPUBFUN int xmlTextWriterWriteString(xmlTextWriter *writer,
                                                   const xmlChar *
                                                   content);
    XMLPUBFUN int xmlTextWriterWriteBase64(xmlTextWriter *writer,
                                                   const char *data,
                                                   int start, int len);
    XMLPUBFUN int xmlTextWriterWriteBinHex(xmlTextWriter *writer,
                                                   const char *data,
                                                   int start, int len);

/*
 * Attributes
 */
    XMLPUBFUN int
        xmlTextWriterStartAttribute(xmlTextWriter *writer,
                                    const xmlChar * name);
    XMLPUBFUN int xmlTextWriterStartAttributeNS(xmlTextWriter *
                                                        writer,
                                                        const xmlChar *
                                                        prefix,
                                                        const xmlChar *
                                                        name,
                                                        const xmlChar *
                                                        namespaceURI);
    XMLPUBFUN int xmlTextWriterEndAttribute(xmlTextWriter *
                                                    writer);

/*
 * Attributes conveniency functions
 */
    XMLPUBFUN int
        xmlTextWriterWriteFormatAttribute(xmlTextWriter *writer,
                                          const xmlChar * name,
                                          const char *format, ...)
					  LIBXML_ATTR_FORMAT(3,4);
    XMLPUBFUN int
        xmlTextWriterWriteVFormatAttribute(xmlTextWriter *writer,
                                           const xmlChar * name,
                                           const char *format,
                                           va_list argptr)
					   LIBXML_ATTR_FORMAT(3,0);
    XMLPUBFUN int xmlTextWriterWriteAttribute(xmlTextWriter *
                                                      writer,
                                                      const xmlChar * name,
                                                      const xmlChar *
                                                      content);
    XMLPUBFUN int
        xmlTextWriterWriteFormatAttributeNS(xmlTextWriter *writer,
                                            const xmlChar * prefix,
                                            const xmlChar * name,
                                            const xmlChar * namespaceURI,
                                            const char *format, ...)
					    LIBXML_ATTR_FORMAT(5,6);
    XMLPUBFUN int
        xmlTextWriterWriteVFormatAttributeNS(xmlTextWriter *writer,
                                             const xmlChar * prefix,
                                             const xmlChar * name,
                                             const xmlChar * namespaceURI,
                                             const char *format,
                                             va_list argptr)
					     LIBXML_ATTR_FORMAT(5,0);
    XMLPUBFUN int xmlTextWriterWriteAttributeNS(xmlTextWriter *
                                                        writer,
                                                        const xmlChar *
                                                        prefix,
                                                        const xmlChar *
                                                        name,
                                                        const xmlChar *
                                                        namespaceURI,
                                                        const xmlChar *
                                                        content);

/*
 * PI's
 */
    XMLPUBFUN int
        xmlTextWriterStartPI(xmlTextWriter *writer,
                             const xmlChar * target);
    XMLPUBFUN int xmlTextWriterEndPI(xmlTextWriter *writer);

/*
 * PI conveniency functions
 */
    XMLPUBFUN int
        xmlTextWriterWriteFormatPI(xmlTextWriter *writer,
                                   const xmlChar * target,
                                   const char *format, ...)
				   LIBXML_ATTR_FORMAT(3,4);
    XMLPUBFUN int
        xmlTextWriterWriteVFormatPI(xmlTextWriter *writer,
                                    const xmlChar * target,
                                    const char *format, va_list argptr)
				    LIBXML_ATTR_FORMAT(3,0);
    XMLPUBFUN int
        xmlTextWriterWritePI(xmlTextWriter *writer,
                             const xmlChar * target,
                             const xmlChar * content);

/**
 * This macro maps to #xmlTextWriterWritePI
 */
#define xmlTextWriterWriteProcessingInstruction xmlTextWriterWritePI

/*
 * CDATA
 */
    XMLPUBFUN int xmlTextWriterStartCDATA(xmlTextWriter *writer);
    XMLPUBFUN int xmlTextWriterEndCDATA(xmlTextWriter *writer);

/*
 * CDATA conveniency functions
 */
    XMLPUBFUN int
        xmlTextWriterWriteFormatCDATA(xmlTextWriter *writer,
                                      const char *format, ...)
				      LIBXML_ATTR_FORMAT(2,3);
    XMLPUBFUN int
        xmlTextWriterWriteVFormatCDATA(xmlTextWriter *writer,
                                       const char *format, va_list argptr)
				       LIBXML_ATTR_FORMAT(2,0);
    XMLPUBFUN int
        xmlTextWriterWriteCDATA(xmlTextWriter *writer,
                                const xmlChar * content);

/*
 * DTD
 */
    XMLPUBFUN int
        xmlTextWriterStartDTD(xmlTextWriter *writer,
                              const xmlChar * name,
                              const xmlChar * pubid,
                              const xmlChar * sysid);
    XMLPUBFUN int xmlTextWriterEndDTD(xmlTextWriter *writer);

/*
 * DTD conveniency functions
 */
    XMLPUBFUN int
        xmlTextWriterWriteFormatDTD(xmlTextWriter *writer,
                                    const xmlChar * name,
                                    const xmlChar * pubid,
                                    const xmlChar * sysid,
                                    const char *format, ...)
				    LIBXML_ATTR_FORMAT(5,6);
    XMLPUBFUN int
        xmlTextWriterWriteVFormatDTD(xmlTextWriter *writer,
                                     const xmlChar * name,
                                     const xmlChar * pubid,
                                     const xmlChar * sysid,
                                     const char *format, va_list argptr)
				     LIBXML_ATTR_FORMAT(5,0);
    XMLPUBFUN int
        xmlTextWriterWriteDTD(xmlTextWriter *writer,
                              const xmlChar * name,
                              const xmlChar * pubid,
                              const xmlChar * sysid,
                              const xmlChar * subset);

/**
 * this macro maps to #xmlTextWriterWriteDTD
 */
#define xmlTextWriterWriteDocType xmlTextWriterWriteDTD

/*
 * DTD element definition
 */
    XMLPUBFUN int
        xmlTextWriterStartDTDElement(xmlTextWriter *writer,
                                     const xmlChar * name);
    XMLPUBFUN int xmlTextWriterEndDTDElement(xmlTextWriter *
                                                     writer);

/*
 * DTD element definition conveniency functions
 */
    XMLPUBFUN int
        xmlTextWriterWriteFormatDTDElement(xmlTextWriter *writer,
                                           const xmlChar * name,
                                           const char *format, ...)
					   LIBXML_ATTR_FORMAT(3,4);
    XMLPUBFUN int
        xmlTextWriterWriteVFormatDTDElement(xmlTextWriter *writer,
                                            const xmlChar * name,
                                            const char *format,
                                            va_list argptr)
					    LIBXML_ATTR_FORMAT(3,0);
    XMLPUBFUN int xmlTextWriterWriteDTDElement(xmlTextWriter *
                                                       writer,
                                                       const xmlChar *
                                                       name,
                                                       const xmlChar *
                                                       content);

/*
 * DTD attribute list definition
 */
    XMLPUBFUN int
        xmlTextWriterStartDTDAttlist(xmlTextWriter *writer,
                                     const xmlChar * name);
    XMLPUBFUN int xmlTextWriterEndDTDAttlist(xmlTextWriter *
                                                     writer);

/*
 * DTD attribute list definition conveniency functions
 */
    XMLPUBFUN int
        xmlTextWriterWriteFormatDTDAttlist(xmlTextWriter *writer,
                                           const xmlChar * name,
                                           const char *format, ...)
					   LIBXML_ATTR_FORMAT(3,4);
    XMLPUBFUN int
        xmlTextWriterWriteVFormatDTDAttlist(xmlTextWriter *writer,
                                            const xmlChar * name,
                                            const char *format,
                                            va_list argptr)
					    LIBXML_ATTR_FORMAT(3,0);
    XMLPUBFUN int xmlTextWriterWriteDTDAttlist(xmlTextWriter *
                                                       writer,
                                                       const xmlChar *
                                                       name,
                                                       const xmlChar *
                                                       content);

/*
 * DTD entity definition
 */
    XMLPUBFUN int
        xmlTextWriterStartDTDEntity(xmlTextWriter *writer,
                                    int pe, const xmlChar * name);
    XMLPUBFUN int xmlTextWriterEndDTDEntity(xmlTextWriter *
                                                    writer);

/*
 * DTD entity definition conveniency functions
 */
    XMLPUBFUN int
        xmlTextWriterWriteFormatDTDInternalEntity(xmlTextWriter *writer,
                                                  int pe,
                                                  const xmlChar * name,
                                                  const char *format, ...)
						  LIBXML_ATTR_FORMAT(4,5);
    XMLPUBFUN int
        xmlTextWriterWriteVFormatDTDInternalEntity(xmlTextWriter *writer,
                                                   int pe,
                                                   const xmlChar * name,
                                                   const char *format,
                                                   va_list argptr)
						   LIBXML_ATTR_FORMAT(4,0);
    XMLPUBFUN int
        xmlTextWriterWriteDTDInternalEntity(xmlTextWriter *writer,
                                            int pe,
                                            const xmlChar * name,
                                            const xmlChar * content);
    XMLPUBFUN int
        xmlTextWriterWriteDTDExternalEntity(xmlTextWriter *writer,
                                            int pe,
                                            const xmlChar * name,
                                            const xmlChar * pubid,
                                            const xmlChar * sysid,
                                            const xmlChar * ndataid);
    XMLPUBFUN int
        xmlTextWriterWriteDTDExternalEntityContents(xmlTextWriter *
                                                    writer,
                                                    const xmlChar * pubid,
                                                    const xmlChar * sysid,
                                                    const xmlChar *
                                                    ndataid);
    XMLPUBFUN int xmlTextWriterWriteDTDEntity(xmlTextWriter *
                                                      writer, int pe,
                                                      const xmlChar * name,
                                                      const xmlChar *
                                                      pubid,
                                                      const xmlChar *
                                                      sysid,
                                                      const xmlChar *
                                                      ndataid,
                                                      const xmlChar *
                                                      content);

/*
 * DTD notation definition
 */
    XMLPUBFUN int
        xmlTextWriterWriteDTDNotation(xmlTextWriter *writer,
                                      const xmlChar * name,
                                      const xmlChar * pubid,
                                      const xmlChar * sysid);

/*
 * Indentation
 */
    XMLPUBFUN int
        xmlTextWriterSetIndent(xmlTextWriter *writer, int indent);
    XMLPUBFUN int
        xmlTextWriterSetIndentString(xmlTextWriter *writer,
                                     const xmlChar * str);

    XMLPUBFUN int
        xmlTextWriterSetQuoteChar(xmlTextWriter *writer, xmlChar quotechar);


/*
 * misc
 */
    XMLPUBFUN int xmlTextWriterFlush(xmlTextWriter *writer);
    XMLPUBFUN int xmlTextWriterClose(xmlTextWriter *writer);

#ifdef __cplusplus
}
#endif

#endif /* LIBXML_WRITER_ENABLED */

#endif                          /* __XML_XMLWRITER_H__ */
libxml2/libxml/globals.h000064400000001117151733237450011212 0ustar00/**
 * @file
 * 
 * @brief interface for all global variables of the library
 * 
 * Deprecated, don't use
 *
 * @copyright See Copyright for the status of this software.
 */

#ifndef __XML_GLOBALS_H
#define __XML_GLOBALS_H

#include <libxml/xmlversion.h>

/*
 * This file was required to access global variables until version v2.12.0.
 *
 * These includes are for backward compatibility.
 */
#include <libxml/HTMLparser.h>
#include <libxml/parser.h>
#include <libxml/xmlerror.h>
#include <libxml/xmlIO.h>
#include <libxml/xmlsave.h>
#include <libxml/threads.h>

#endif /* __XML_GLOBALS_H */
libxml2/libxml/xmlschemastypes.h000064400000010676151733237450013032 0ustar00/**
 * @file
 * 
 * @brief implementation of XML Schema Datatypes
 * 
 * module providing the XML Schema Datatypes implementation
 *              both definition and validity checking
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */


#ifndef __XML_SCHEMA_TYPES_H__
#define __XML_SCHEMA_TYPES_H__

#include <libxml/xmlversion.h>

#ifdef LIBXML_SCHEMAS_ENABLED

#include <libxml/schemasInternals.h>
#include <libxml/xmlschemas.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * Schema whitespace value type
 */
typedef enum {
    XML_SCHEMA_WHITESPACE_UNKNOWN = 0,
    XML_SCHEMA_WHITESPACE_PRESERVE = 1,
    XML_SCHEMA_WHITESPACE_REPLACE = 2,
    XML_SCHEMA_WHITESPACE_COLLAPSE = 3
} xmlSchemaWhitespaceValueType;

XMLPUBFUN int
		xmlSchemaInitTypes		(void);
XML_DEPRECATED
XMLPUBFUN void
		xmlSchemaCleanupTypes		(void);
XMLPUBFUN xmlSchemaType *
		xmlSchemaGetPredefinedType	(const xmlChar *name,
						 const xmlChar *ns);
XMLPUBFUN int
		xmlSchemaValidatePredefinedType	(xmlSchemaType *type,
						 const xmlChar *value,
						 xmlSchemaVal **val);
XMLPUBFUN int
		xmlSchemaValPredefTypeNode	(xmlSchemaType *type,
						 const xmlChar *value,
						 xmlSchemaVal **val,
						 xmlNode *node);
XMLPUBFUN int
		xmlSchemaValidateFacet		(xmlSchemaType *base,
						 xmlSchemaFacet *facet,
						 const xmlChar *value,
						 xmlSchemaVal *val);
XMLPUBFUN int
		xmlSchemaValidateFacetWhtsp	(xmlSchemaFacet *facet,
						 xmlSchemaWhitespaceValueType fws,
						 xmlSchemaValType valType,
						 const xmlChar *value,
						 xmlSchemaVal *val,
						 xmlSchemaWhitespaceValueType ws);
XMLPUBFUN void
		xmlSchemaFreeValue		(xmlSchemaVal *val);
XMLPUBFUN xmlSchemaFacet *
		xmlSchemaNewFacet		(void);
XMLPUBFUN int
		xmlSchemaCheckFacet		(xmlSchemaFacet *facet,
						 xmlSchemaType *typeDecl,
						 xmlSchemaParserCtxt *ctxt,
						 const xmlChar *name);
XMLPUBFUN void
		xmlSchemaFreeFacet		(xmlSchemaFacet *facet);
XMLPUBFUN int
		xmlSchemaCompareValues		(xmlSchemaVal *x,
						 xmlSchemaVal *y);
XMLPUBFUN xmlSchemaType *
    xmlSchemaGetBuiltInListSimpleTypeItemType	(xmlSchemaType *type);
XMLPUBFUN int
    xmlSchemaValidateListSimpleTypeFacet	(xmlSchemaFacet *facet,
						 const xmlChar *value,
						 unsigned long actualLen,
						 unsigned long *expectedLen);
XMLPUBFUN xmlSchemaType *
		xmlSchemaGetBuiltInType		(xmlSchemaValType type);
XMLPUBFUN int
		xmlSchemaIsBuiltInTypeFacet	(xmlSchemaType *type,
						 int facetType);
XMLPUBFUN xmlChar *
		xmlSchemaCollapseString		(const xmlChar *value);
XMLPUBFUN xmlChar *
		xmlSchemaWhiteSpaceReplace	(const xmlChar *value);
XMLPUBFUN unsigned long 
		xmlSchemaGetFacetValueAsULong	(xmlSchemaFacet *facet);
XMLPUBFUN int
		xmlSchemaValidateLengthFacet	(xmlSchemaType *type,
						 xmlSchemaFacet *facet,
						 const xmlChar *value,
						 xmlSchemaVal *val,
						 unsigned long *length);
XMLPUBFUN int
		xmlSchemaValidateLengthFacetWhtsp(xmlSchemaFacet *facet,
						  xmlSchemaValType valType,
						  const xmlChar *value,
						  xmlSchemaVal *val,
						  unsigned long *length,
						  xmlSchemaWhitespaceValueType ws);
XMLPUBFUN int
		xmlSchemaValPredefTypeNodeNoNorm(xmlSchemaType *type,
						 const xmlChar *value,
						 xmlSchemaVal **val,
						 xmlNode *node);
XMLPUBFUN int
		xmlSchemaGetCanonValue		(xmlSchemaVal *val,
						 const xmlChar **retValue);
XMLPUBFUN int
		xmlSchemaGetCanonValueWhtsp	(xmlSchemaVal *val,
						 const xmlChar **retValue,
						 xmlSchemaWhitespaceValueType ws);
XMLPUBFUN int
		xmlSchemaValueAppend		(xmlSchemaVal *prev,
						 xmlSchemaVal *cur);
XMLPUBFUN xmlSchemaVal *
		xmlSchemaValueGetNext		(xmlSchemaVal *cur);
XMLPUBFUN const xmlChar *
		xmlSchemaValueGetAsString	(xmlSchemaVal *val);
XMLPUBFUN int
		xmlSchemaValueGetAsBoolean	(xmlSchemaVal *val);
XMLPUBFUN xmlSchemaVal *
		xmlSchemaNewStringValue		(xmlSchemaValType type,
						 const xmlChar *value);
XMLPUBFUN xmlSchemaVal *
		xmlSchemaNewNOTATIONValue	(const xmlChar *name,
						 const xmlChar *ns);
XMLPUBFUN xmlSchemaVal *
		xmlSchemaNewQNameValue		(const xmlChar *namespaceName,
						 const xmlChar *localName);
XMLPUBFUN int
		xmlSchemaCompareValuesWhtsp	(xmlSchemaVal *x,
						 xmlSchemaWhitespaceValueType xws,
						 xmlSchemaVal *y,
						 xmlSchemaWhitespaceValueType yws);
XMLPUBFUN xmlSchemaVal *
		xmlSchemaCopyValue		(xmlSchemaVal *val);
XMLPUBFUN xmlSchemaValType
		xmlSchemaGetValType		(xmlSchemaVal *val);

#ifdef __cplusplus
}
#endif

#endif /* LIBXML_SCHEMAS_ENABLED */
#endif /* __XML_SCHEMA_TYPES_H__ */
libxml2/libxml/schematron.h000064400000010243151733237450011732 0ustar00/**
 * @file
 * 
 * @brief XML Schematron implementation
 * 
 * interface to the XML Schematron validity checking.
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */


#ifndef __XML_SCHEMATRON_H__
#define __XML_SCHEMATRON_H__

#include <libxml/xmlversion.h>

#ifdef LIBXML_SCHEMATRON_ENABLED

#include <libxml/xmlerror.h>
#include <libxml/tree.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * Schematron validation options
 */
typedef enum {
    /** quiet no report */
    XML_SCHEMATRON_OUT_QUIET = 1 << 0,
    /** build a textual report */
    XML_SCHEMATRON_OUT_TEXT = 1 << 1,
    /** output SVRL */
    XML_SCHEMATRON_OUT_XML = 1 << 2,
    /** output via xmlStructuredErrorFunc */
    XML_SCHEMATRON_OUT_ERROR = 1 << 3,
    /** output to a file descriptor */
    XML_SCHEMATRON_OUT_FILE = 1 << 8,
    /** output to a buffer */
    XML_SCHEMATRON_OUT_BUFFER = 1 << 9,
    /** output to I/O mechanism */
    XML_SCHEMATRON_OUT_IO = 1 << 10
} xmlSchematronValidOptions;

/** Schematron schema */
typedef struct _xmlSchematron xmlSchematron;
typedef xmlSchematron *xmlSchematronPtr;

/**
 * Signature of an error callback from a Schematron validation
 *
 * @param ctx  the validation context
 * @param msg  the message
 * @param ... extra arguments
 */
typedef void (*xmlSchematronValidityErrorFunc) (void *ctx, const char *msg, ...);

/**
 * Signature of a warning callback from a Schematron validation
 *
 * @param ctx  the validation context
 * @param msg  the message
 * @param ... extra arguments
 */
typedef void (*xmlSchematronValidityWarningFunc) (void *ctx, const char *msg, ...);

/** Schematron parser context */
typedef struct _xmlSchematronParserCtxt xmlSchematronParserCtxt;
typedef xmlSchematronParserCtxt *xmlSchematronParserCtxtPtr;

/** Schematron validation context */
typedef struct _xmlSchematronValidCtxt xmlSchematronValidCtxt;
typedef xmlSchematronValidCtxt *xmlSchematronValidCtxtPtr;

/*
 * Interfaces for parsing.
 */
XMLPUBFUN xmlSchematronParserCtxt *
	    xmlSchematronNewParserCtxt	(const char *URL);
XMLPUBFUN xmlSchematronParserCtxt *
	    xmlSchematronNewMemParserCtxt(const char *buffer,
					 int size);
XMLPUBFUN xmlSchematronParserCtxt *
	    xmlSchematronNewDocParserCtxt(xmlDoc *doc);
XMLPUBFUN void
	    xmlSchematronFreeParserCtxt	(xmlSchematronParserCtxt *ctxt);
/*****
XMLPUBFUN void
	    xmlSchematronSetParserErrors(xmlSchematronParserCtxt *ctxt,
					 xmlSchematronValidityErrorFunc err,
					 xmlSchematronValidityWarningFunc warn,
					 void *ctx);
XMLPUBFUN int
		xmlSchematronGetParserErrors(xmlSchematronParserCtxt *ctxt,
					xmlSchematronValidityErrorFunc * err,
					xmlSchematronValidityWarningFunc * warn,
					void **ctx);
XMLPUBFUN int
		xmlSchematronIsValid	(xmlSchematronValidCtxt *ctxt);
 *****/
XMLPUBFUN xmlSchematron *
	    xmlSchematronParse		(xmlSchematronParserCtxt *ctxt);
XMLPUBFUN void
	    xmlSchematronFree		(xmlSchematron *schema);
/*
 * Interfaces for validating
 */
XMLPUBFUN void
	    xmlSchematronSetValidStructuredErrors(
	                                  xmlSchematronValidCtxt *ctxt,
					  xmlStructuredErrorFunc serror,
					  void *ctx);
/******
XMLPUBFUN void
	    xmlSchematronSetValidErrors	(xmlSchematronValidCtxt *ctxt,
					 xmlSchematronValidityErrorFunc err,
					 xmlSchematronValidityWarningFunc warn,
					 void *ctx);
XMLPUBFUN int
	    xmlSchematronGetValidErrors	(xmlSchematronValidCtxt *ctxt,
					 xmlSchematronValidityErrorFunc *err,
					 xmlSchematronValidityWarningFunc *warn,
					 void **ctx);
XMLPUBFUN int
	    xmlSchematronSetValidOptions(xmlSchematronValidCtxt *ctxt,
					 int options);
XMLPUBFUN int
	    xmlSchematronValidCtxtGetOptions(xmlSchematronValidCtxt *ctxt);
XMLPUBFUN int
            xmlSchematronValidateOneElement (xmlSchematronValidCtxt *ctxt,
			                 xmlNode *elem);
 *******/

XMLPUBFUN xmlSchematronValidCtxt *
	    xmlSchematronNewValidCtxt	(xmlSchematron *schema,
					 int options);
XMLPUBFUN void
	    xmlSchematronFreeValidCtxt	(xmlSchematronValidCtxt *ctxt);
XMLPUBFUN int
	    xmlSchematronValidateDoc	(xmlSchematronValidCtxt *ctxt,
					 xmlDoc *instance);

#ifdef __cplusplus
}
#endif

#endif /* LIBXML_SCHEMATRON_ENABLED */
#endif /* __XML_SCHEMATRON_H__ */
libxml2/libxml/list.h000064400000006104151733237460010544 0ustar00/**
 * @file
 * 
 * @brief lists interfaces
 * 
 * this module implement the list support used in
 * various place in the library.
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Gary Pennington
 */

#ifndef __XML_LINK_INCLUDE__
#define __XML_LINK_INCLUDE__

#include <libxml/xmlversion.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * Linked list item
 *
 * @deprecated Don't use in new code.
 */
typedef struct _xmlLink xmlLink;
typedef xmlLink *xmlLinkPtr;

/**
 * Linked list
 *
 * @deprecated Don't use in new code.
 */
typedef struct _xmlList xmlList;
typedef xmlList *xmlListPtr;

/**
 * Callback function used to free data from a list.
 *
 * @param lk  the data to deallocate
 */
typedef void (*xmlListDeallocator) (xmlLink *lk);
/**
 * Callback function used to compare 2 data.
 *
 * @param data0  the first data
 * @param data1  the second data
 * @returns 0 is equality, -1 or 1 otherwise depending on the ordering.
 */
typedef int  (*xmlListDataCompare) (const void *data0, const void *data1);
/**
 * Callback function used when walking a list with #xmlListWalk.
 *
 * @param data  the data found in the list
 * @param user  extra user provided data to the walker
 * @returns 0 to stop walking the list, 1 otherwise.
 */
typedef int (*xmlListWalker) (const void *data, void *user);

/* Creation/Deletion */
XMLPUBFUN xmlList *
		xmlListCreate		(xmlListDeallocator deallocator,
	                                 xmlListDataCompare compare);
XMLPUBFUN void
		xmlListDelete		(xmlList *l);

/* Basic Operators */
XMLPUBFUN void *
		xmlListSearch		(xmlList *l,
					 void *data);
XMLPUBFUN void *
		xmlListReverseSearch	(xmlList *l,
					 void *data);
XMLPUBFUN int
		xmlListInsert		(xmlList *l,
					 void *data) ;
XMLPUBFUN int
		xmlListAppend		(xmlList *l,
					 void *data) ;
XMLPUBFUN int
		xmlListRemoveFirst	(xmlList *l,
					 void *data);
XMLPUBFUN int
		xmlListRemoveLast	(xmlList *l,
					 void *data);
XMLPUBFUN int
		xmlListRemoveAll	(xmlList *l,
					 void *data);
XMLPUBFUN void
		xmlListClear		(xmlList *l);
XMLPUBFUN int
		xmlListEmpty		(xmlList *l);
XMLPUBFUN xmlLink *
		xmlListFront		(xmlList *l);
XMLPUBFUN xmlLink *
		xmlListEnd		(xmlList *l);
XMLPUBFUN int
		xmlListSize		(xmlList *l);

XMLPUBFUN void
		xmlListPopFront		(xmlList *l);
XMLPUBFUN void
		xmlListPopBack		(xmlList *l);
XMLPUBFUN int
		xmlListPushFront	(xmlList *l,
					 void *data);
XMLPUBFUN int
		xmlListPushBack		(xmlList *l,
					 void *data);

/* Advanced Operators */
XMLPUBFUN void
		xmlListReverse		(xmlList *l);
XMLPUBFUN void
		xmlListSort		(xmlList *l);
XMLPUBFUN void
		xmlListWalk		(xmlList *l,
					 xmlListWalker walker,
					 void *user);
XMLPUBFUN void
		xmlListReverseWalk	(xmlList *l,
					 xmlListWalker walker,
					 void *user);
XMLPUBFUN void
		xmlListMerge		(xmlList *l1,
					 xmlList *l2);
XMLPUBFUN xmlList *
		xmlListDup		(xmlList *old);
XMLPUBFUN int
		xmlListCopy		(xmlList *cur,
					 xmlList *old);
/* Link operators */
XMLPUBFUN void *
		xmlLinkGetData          (xmlLink *lk);

/* xmlListUnique() */
/* xmlListSwap */

#ifdef __cplusplus
}
#endif

#endif /* __XML_LINK_INCLUDE__ */
libxml2/libxml/chvalid.h000064400000011325151733237460011204 0ustar00/**
 * @file
 *
 * @brief Unicode character range checking
 *
 * this module exports interfaces for the character
 *               range validation APIs
 */

#ifndef __XML_CHVALID_H__
#define __XML_CHVALID_H__

#include <libxml/xmlversion.h>
#include <libxml/xmlstring.h>

#ifdef __cplusplus
extern "C" {
#endif

/** @cond ignore */

/*
 * Define our typedefs and structures
 *
 */
typedef struct _xmlChSRange xmlChSRange;
typedef xmlChSRange *xmlChSRangePtr;
struct _xmlChSRange {
    unsigned short	low;
    unsigned short	high;
};

typedef struct _xmlChLRange xmlChLRange;
typedef xmlChLRange *xmlChLRangePtr;
struct _xmlChLRange {
    unsigned int	low;
    unsigned int	high;
};

typedef struct _xmlChRangeGroup xmlChRangeGroup;
typedef xmlChRangeGroup *xmlChRangeGroupPtr;
struct _xmlChRangeGroup {
    int			nbShortRange;
    int			nbLongRange;
    const xmlChSRange	*shortRange;	/* points to an array of ranges */
    const xmlChLRange	*longRange;
};

XMLPUBVAR const xmlChRangeGroup xmlIsBaseCharGroup;
XMLPUBVAR const xmlChRangeGroup xmlIsCharGroup;
XMLPUBVAR const xmlChRangeGroup xmlIsCombiningGroup;
XMLPUBVAR const xmlChRangeGroup xmlIsDigitGroup;
XMLPUBVAR const xmlChRangeGroup xmlIsExtenderGroup;
XMLPUBVAR const xmlChRangeGroup xmlIsIdeographicGroup;
XMLPUBVAR const unsigned char xmlIsPubidChar_tab[256];

/**
 * Range checking routine
 */
XMLPUBFUN int
		xmlCharInRange(unsigned int val, const xmlChRangeGroup *group);

/** @endcond */

/**
 * Automatically generated by genChRanges.py
 *
 * @param c  char to validate
 */
#define xmlIsBaseChar_ch(c)	(((0x41 <= (c)) && ((c) <= 0x5a)) || \
				 ((0x61 <= (c)) && ((c) <= 0x7a)) || \
				 ((0xc0 <= (c)) && ((c) <= 0xd6)) || \
				 ((0xd8 <= (c)) && ((c) <= 0xf6)) || \
				  (0xf8 <= (c)))

/**
 * Automatically generated by genChRanges.py
 *
 * @param c  char to validate
 */
#define xmlIsBaseCharQ(c)	(((c) < 0x100) ? \
				 xmlIsBaseChar_ch((c)) : \
				 xmlCharInRange((c), &xmlIsBaseCharGroup))

/**
 * Automatically generated by genChRanges.py
 *
 * @param c  char to validate
 */
#define xmlIsBlank_ch(c)	(((c) == 0x20) || \
				 ((0x9 <= (c)) && ((c) <= 0xa)) || \
				 ((c) == 0xd))

/**
 * Automatically generated by genChRanges.py
 *
 * @param c  char to validate
 */
#define xmlIsBlankQ(c)		(((c) < 0x100) ? \
				 xmlIsBlank_ch((c)) : 0)


/**
 * Automatically generated by genChRanges.py
 *
 * @param c  char to validate
 */
#define xmlIsChar_ch(c)		(((0x9 <= (c)) && ((c) <= 0xa)) || \
				 ((c) == 0xd) || \
				  (0x20 <= (c)))

/**
 * Automatically generated by genChRanges.py
 *
 * @param c  char to validate
 */
#define xmlIsCharQ(c)		(((c) < 0x100) ? \
				 xmlIsChar_ch((c)) :\
				(((0x100 <= (c)) && ((c) <= 0xd7ff)) || \
				 ((0xe000 <= (c)) && ((c) <= 0xfffd)) || \
				 ((0x10000 <= (c)) && ((c) <= 0x10ffff))))

/**
 * Automatically generated by genChRanges.py
 *
 * @param c  char to validate
 */
#define xmlIsCombiningQ(c)	(((c) < 0x100) ? \
				 0 : \
				 xmlCharInRange((c), &xmlIsCombiningGroup))

/**
 * Automatically generated by genChRanges.py
 *
 * @param c  char to validate
 */
#define xmlIsDigit_ch(c)	(((0x30 <= (c)) && ((c) <= 0x39)))

/**
 * Automatically generated by genChRanges.py
 *
 * @param c  char to validate
 */
#define xmlIsDigitQ(c)		(((c) < 0x100) ? \
				 xmlIsDigit_ch((c)) : \
				 xmlCharInRange((c), &xmlIsDigitGroup))

/**
 * Automatically generated by genChRanges.py
 *
 * @param c  char to validate
 */
#define xmlIsExtender_ch(c)	(((c) == 0xb7))

/**
 * Automatically generated by genChRanges.py
 *
 * @param c  char to validate
 */
#define xmlIsExtenderQ(c)	(((c) < 0x100) ? \
				 xmlIsExtender_ch((c)) : \
				 xmlCharInRange((c), &xmlIsExtenderGroup))

/**
 * Automatically generated by genChRanges.py
 *
 * @param c  char to validate
 */
#define xmlIsIdeographicQ(c)	(((c) < 0x100) ? \
				 0 :\
				(((0x4e00 <= (c)) && ((c) <= 0x9fa5)) || \
				 ((c) == 0x3007) || \
				 ((0x3021 <= (c)) && ((c) <= 0x3029))))

/**
 * Automatically generated by genChRanges.py
 *
 * @param c  char to validate
 */
#define xmlIsPubidChar_ch(c)	(xmlIsPubidChar_tab[(c)])

/**
 * Automatically generated by genChRanges.py
 *
 * @param c  char to validate
 */
#define xmlIsPubidCharQ(c)	(((c) < 0x100) ? \
				 xmlIsPubidChar_ch((c)) : 0)

XML_DEPRECATED
XMLPUBFUN int
		xmlIsBaseChar(unsigned int ch);
XML_DEPRECATED
XMLPUBFUN int
		xmlIsBlank(unsigned int ch);
XML_DEPRECATED
XMLPUBFUN int
		xmlIsChar(unsigned int ch);
XML_DEPRECATED
XMLPUBFUN int
		xmlIsCombining(unsigned int ch);
XML_DEPRECATED
XMLPUBFUN int
		xmlIsDigit(unsigned int ch);
XML_DEPRECATED
XMLPUBFUN int
		xmlIsExtender(unsigned int ch);
XML_DEPRECATED
XMLPUBFUN int
		xmlIsIdeographic(unsigned int ch);
XML_DEPRECATED
XMLPUBFUN int
		xmlIsPubidChar(unsigned int ch);

#ifdef __cplusplus
}
#endif
#endif /* __XML_CHVALID_H__ */
libxml2/libxml/dict.h000064400000003364151733237460010521 0ustar00/**
 * @file
 * 
 * @brief string dictionary
 * 
 * dictionary of reusable strings, just used to avoid allocation
 *         and freeing operations.
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */

#ifndef __XML_DICT_H__
#define __XML_DICT_H__

#include <stddef.h>
#include <libxml/xmlversion.h>
#include <libxml/xmlstring.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * Dictionary (pool for interned strings)
 */
typedef struct _xmlDict xmlDict;
typedef xmlDict *xmlDictPtr;

/*
 * Initializer
 */
XML_DEPRECATED
XMLPUBFUN int  xmlInitializeDict(void);

/*
 * Constructor and destructor.
 */
XMLPUBFUN xmlDict *
			xmlDictCreate	(void);
XMLPUBFUN size_t
			xmlDictSetLimit	(xmlDict *dict,
                                         size_t limit);
XMLPUBFUN size_t
			xmlDictGetUsage (xmlDict *dict);
XMLPUBFUN xmlDict *
			xmlDictCreateSub(xmlDict *sub);
XMLPUBFUN int
			xmlDictReference(xmlDict *dict);
XMLPUBFUN void
			xmlDictFree	(xmlDict *dict);

/*
 * Lookup of entry in the dictionary.
 */
XMLPUBFUN const xmlChar *
			xmlDictLookup	(xmlDict *dict,
		                         const xmlChar *name,
		                         int len);
XMLPUBFUN const xmlChar *
			xmlDictExists	(xmlDict *dict,
		                         const xmlChar *name,
		                         int len);
XMLPUBFUN const xmlChar *
			xmlDictQLookup	(xmlDict *dict,
		                         const xmlChar *prefix,
		                         const xmlChar *name);
XMLPUBFUN int
			xmlDictOwns	(xmlDict *dict,
					 const xmlChar *str);
XMLPUBFUN int
			xmlDictSize	(xmlDict *dict);

/*
 * Cleanup function
 */
XML_DEPRECATED
XMLPUBFUN void
                        xmlDictCleanup  (void);

#ifdef __cplusplus
}
#endif
#endif /* ! __XML_DICT_H__ */
libxml2/libxml/threads.h000064400000003040151733237460011217 0ustar00/**
 * @file
 *
 * @brief interfaces for thread handling
 * 
 * set of generic threading related routines
 *              should work with pthreads, Windows native or TLS threads
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */

#ifndef __XML_THREADS_H__
#define __XML_THREADS_H__

#include <libxml/xmlversion.h>

#ifdef __cplusplus
extern "C" {
#endif

/** Mutual exclusion object */
typedef struct _xmlMutex xmlMutex;
typedef xmlMutex *xmlMutexPtr;

/** Reentrant mutual exclusion object */
typedef struct _xmlRMutex xmlRMutex;
typedef xmlRMutex *xmlRMutexPtr;

XMLPUBFUN int
			xmlCheckThreadLocalStorage(void);

XMLPUBFUN xmlMutex *
			xmlNewMutex	(void);
XMLPUBFUN void
			xmlMutexLock	(xmlMutex *tok);
XMLPUBFUN void
			xmlMutexUnlock	(xmlMutex *tok);
XMLPUBFUN void
			xmlFreeMutex	(xmlMutex *tok);

XMLPUBFUN xmlRMutex *
			xmlNewRMutex	(void);
XMLPUBFUN void
			xmlRMutexLock	(xmlRMutex *tok);
XMLPUBFUN void
			xmlRMutexUnlock	(xmlRMutex *tok);
XMLPUBFUN void
			xmlFreeRMutex	(xmlRMutex *tok);

/*
 * Library wide APIs.
 */
XML_DEPRECATED
XMLPUBFUN void
			xmlInitThreads	(void);
XMLPUBFUN void
			xmlLockLibrary	(void);
XMLPUBFUN void
			xmlUnlockLibrary(void);
XML_DEPRECATED
XMLPUBFUN void
			xmlCleanupThreads(void);

/** @cond IGNORE */
#if defined(LIBXML_THREAD_ENABLED) && defined(_WIN32) && \
    defined(LIBXML_STATIC_FOR_DLL)
int
xmlDllMain(void *hinstDLL, unsigned long fdwReason,
           void *lpvReserved);
#endif
/** @endcond */

#ifdef __cplusplus
}
#endif


#endif /* __XML_THREADS_H__ */
libxml2/libxml/parserInternals.h000064400000033031151733237460012744 0ustar00/**
 * @file
 * 
 * @brief Internals routines and limits exported by the parser.
 * 
 * Except for some I/O-related functions, most of these macros and
 * functions are deprecated.
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */

#ifndef __XML_PARSER_INTERNALS_H__
#define __XML_PARSER_INTERNALS_H__

#include <libxml/xmlversion.h>
#include <libxml/parser.h>
#include <libxml/HTMLparser.h>
#include <libxml/chvalid.h>
#include <libxml/SAX2.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * Push an input on the stack.
 *
 * @deprecated Use #xmlCtxtPushInput
 */
#define inputPush xmlCtxtPushInput
/**
 * Pop an input from the stack.
 *
 * @deprecated Use #xmlCtxtPushInput
 */
#define inputPop xmlCtxtPopInput
/**
 * Maximum element nesting depth (without XML_PARSE_HUGE).
 */
#define xmlParserMaxDepth 256

/**
 * Maximum size allowed for a single text node when building a tree.
 * This is not a limitation of the parser but a safety boundary feature,
 * use XML_PARSE_HUGE option to override it.
 * Introduced in 2.9.0
 */
#define XML_MAX_TEXT_LENGTH 10000000

/**
 * Maximum size allowed when XML_PARSE_HUGE is set.
 */
#define XML_MAX_HUGE_LENGTH 1000000000

/**
 * Maximum size allowed for a markup identifier.
 * This is not a limitation of the parser but a safety boundary feature,
 * use XML_PARSE_HUGE option to override it.
 * Note that with the use of parsing dictionaries overriding the limit
 * may result in more runtime memory usage in face of "unfriendly' content
 * Introduced in 2.9.0
 */
#define XML_MAX_NAME_LENGTH 50000

/**
 * Maximum size allowed by the parser for a dictionary by default
 * This is not a limitation of the parser but a safety boundary feature,
 * use XML_PARSE_HUGE option to override it.
 * Introduced in 2.9.0
 */
#define XML_MAX_DICTIONARY_LIMIT 100000000

/**
 * Maximum size allowed by the parser for ahead lookup
 * This is an upper boundary enforced by the parser to avoid bad
 * behaviour on "unfriendly' content
 * Introduced in 2.9.0
 */
#define XML_MAX_LOOKUP_LIMIT 10000000

/**
 * Identifiers can be longer, but this will be more costly
 * at runtime.
 */
#define XML_MAX_NAMELEN 100

/************************************************************************
 *									*
 * UNICODE version of the macros.					*
 *									*
 ************************************************************************/
/**
 * Macro to check the following production in the XML spec:
 *
 *     [2] Char ::= #x9 | #xA | #xD | [#x20...]
 *
 * any byte character in the accepted range
 *
 * @param c  an byte value (int)
 */
#define IS_BYTE_CHAR(c)	 xmlIsChar_ch(c)

/**
 * Macro to check the following production in the XML spec:
 *
 *     [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD]
 *                      | [#x10000-#x10FFFF]
 *
 * any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.
 *
 * @param c  an UNICODE value (int)
 */
#define IS_CHAR(c)   xmlIsCharQ(c)

/**
 * Behaves like IS_CHAR on single-byte value
 *
 * @param c  an xmlChar (usually an unsigned char)
 */
#define IS_CHAR_CH(c)  xmlIsChar_ch(c)

/**
 * Macro to check the following production in the XML spec:
 *
 *     [3] S ::= (#x20 | #x9 | #xD | #xA)+
 * @param c  an UNICODE value (int)
 */
#define IS_BLANK(c)  xmlIsBlankQ(c)

/**
 * Behaviour same as IS_BLANK
 *
 * @param c  an xmlChar value (normally unsigned char)
 */
#define IS_BLANK_CH(c)  xmlIsBlank_ch(c)

/**
 * Macro to check the following production in the XML spec:
 *
 *     [85] BaseChar ::= ... long list see REC ...
 * @param c  an UNICODE value (int)
 */
#define IS_BASECHAR(c) xmlIsBaseCharQ(c)

/**
 * Macro to check the following production in the XML spec:
 *
 *     [88] Digit ::= ... long list see REC ...
 * @param c  an UNICODE value (int)
 */
#define IS_DIGIT(c) xmlIsDigitQ(c)

/**
 * Behaves like IS_DIGIT but with a single byte argument
 *
 * @param c  an xmlChar value (usually an unsigned char)
 */
#define IS_DIGIT_CH(c)  xmlIsDigit_ch(c)

/**
 * Macro to check the following production in the XML spec:
 *
 *     [87] CombiningChar ::= ... long list see REC ...
 * @param c  an UNICODE value (int)
 */
#define IS_COMBINING(c) xmlIsCombiningQ(c)

/**
 * Always false (all combining chars > 0xff)
 *
 * @param c  an xmlChar (usually an unsigned char)
 */
#define IS_COMBINING_CH(c) 0

/**
 * Macro to check the following production in the XML spec:
 *
 *     [89] Extender ::= #x00B7 | #x02D0 | #x02D1 | #x0387 | #x0640 |
 *                       #x0E46 | #x0EC6 | #x3005 | [#x3031-#x3035] |
 *                       [#x309D-#x309E] | [#x30FC-#x30FE]
 * @param c  an UNICODE value (int)
 */
#define IS_EXTENDER(c) xmlIsExtenderQ(c)

/**
 * Behaves like IS_EXTENDER but with a single-byte argument
 *
 * @param c  an xmlChar value (usually an unsigned char)
 */
#define IS_EXTENDER_CH(c)  xmlIsExtender_ch(c)

/**
 * Macro to check the following production in the XML spec:
 *
 *     [86] Ideographic ::= [#x4E00-#x9FA5] | #x3007 | [#x3021-#x3029]
 * @param c  an UNICODE value (int)
 */
#define IS_IDEOGRAPHIC(c) xmlIsIdeographicQ(c)

/**
 * Macro to check the following production in the XML spec:
 *
 *     [84] Letter ::= BaseChar | Ideographic
 * @param c  an UNICODE value (int)
 */
#define IS_LETTER(c) (IS_BASECHAR(c) || IS_IDEOGRAPHIC(c))

/**
 * Macro behaves like IS_LETTER, but only check base chars
 *
 * @param c  an xmlChar value (normally unsigned char)
 */
#define IS_LETTER_CH(c) xmlIsBaseChar_ch(c)

/**
 * Macro to check [a-zA-Z]
 *
 * @param c  an xmlChar value
 */
#define IS_ASCII_LETTER(c)	((0x61 <= ((c) | 0x20)) && \
                                 (((c) | 0x20) <= 0x7a))

/**
 * Macro to check [0-9]
 *
 * @param c  an xmlChar value
 */
#define IS_ASCII_DIGIT(c)	((0x30 <= (c)) && ((c) <= 0x39))

/**
 * Macro to check the following production in the XML spec:
 *
 *     [13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] |
 *                        [-'()+,./:=?;!*#@$_%]
 * @param c  an UNICODE value (int)
 */
#define IS_PUBIDCHAR(c)	xmlIsPubidCharQ(c)

/**
 * Same as IS_PUBIDCHAR but for single-byte value
 *
 * @param c  an xmlChar value (normally unsigned char)
 */
#define IS_PUBIDCHAR_CH(c) xmlIsPubidChar_ch(c)

/*
 * Global variables used for predefined strings.
 */
/** @cond ignore */
XMLPUBVAR const xmlChar xmlStringText[];
XMLPUBVAR const xmlChar xmlStringTextNoenc[];
XML_DEPRECATED
XMLPUBVAR const xmlChar xmlStringComment[];
/** @endcond */

XML_DEPRECATED
XMLPUBFUN int                   xmlIsLetter     (int c);

/*
 * Parser context.
 */
XMLPUBFUN xmlParserCtxt *
			xmlCreateFileParserCtxt	(const char *filename);
XMLPUBFUN xmlParserCtxt *
			xmlCreateURLParserCtxt	(const char *filename,
						 int options);
XMLPUBFUN xmlParserCtxt *
			xmlCreateMemoryParserCtxt(const char *buffer,
						 int size);
XML_DEPRECATED
XMLPUBFUN xmlParserCtxt *
			xmlCreateEntityParserCtxt(const xmlChar *URL,
						 const xmlChar *ID,
						 const xmlChar *base);
XMLPUBFUN void
			xmlCtxtErrMemory	(xmlParserCtxt *ctxt);
XMLPUBFUN int
			xmlSwitchEncoding	(xmlParserCtxt *ctxt,
						 xmlCharEncoding enc);
XMLPUBFUN int
			xmlSwitchEncodingName	(xmlParserCtxt *ctxt,
						 const char *encoding);
XMLPUBFUN int
			xmlSwitchToEncoding	(xmlParserCtxt *ctxt,
					 xmlCharEncodingHandler *handler);
XML_DEPRECATED
XMLPUBFUN int
			xmlSwitchInputEncoding	(xmlParserCtxt *ctxt,
						 xmlParserInput *input,
					 xmlCharEncodingHandler *handler);

/*
 * Input Streams.
 */
XMLPUBFUN xmlParserInput *
			xmlNewStringInputStream	(xmlParserCtxt *ctxt,
						 const xmlChar *buffer);
XML_DEPRECATED
XMLPUBFUN xmlParserInput *
			xmlNewEntityInputStream	(xmlParserCtxt *ctxt,
						 xmlEntity *entity);
XMLPUBFUN int
			xmlCtxtPushInput	(xmlParserCtxt *ctxt,
						 xmlParserInput *input);
XMLPUBFUN xmlParserInput *
			xmlCtxtPopInput		(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN int
			xmlPushInput		(xmlParserCtxt *ctxt,
						 xmlParserInput *input);
XML_DEPRECATED
XMLPUBFUN xmlChar
			xmlPopInput		(xmlParserCtxt *ctxt);
XMLPUBFUN void
			xmlFreeInputStream	(xmlParserInput *input);
XMLPUBFUN xmlParserInput *
			xmlNewInputFromFile	(xmlParserCtxt *ctxt,
						 const char *filename);
XMLPUBFUN xmlParserInput *
			xmlNewInputStream	(xmlParserCtxt *ctxt);

/*
 * Namespaces.
 */
XMLPUBFUN xmlChar *
			xmlSplitQName		(xmlParserCtxt *ctxt,
						 const xmlChar *name,
						 xmlChar **prefix);

/*
 * Generic production rules.
 */
XML_DEPRECATED
XMLPUBFUN const xmlChar *
			xmlParseName		(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN xmlChar *
			xmlParseNmtoken		(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN xmlChar *
			xmlParseEntityValue	(xmlParserCtxt *ctxt,
						 xmlChar **orig);
XML_DEPRECATED
XMLPUBFUN xmlChar *
			xmlParseAttValue	(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN xmlChar *
			xmlParseSystemLiteral	(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN xmlChar *
			xmlParsePubidLiteral	(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN void
			xmlParseCharData	(xmlParserCtxt *ctxt,
						 int cdata);
XML_DEPRECATED
XMLPUBFUN xmlChar *
			xmlParseExternalID	(xmlParserCtxt *ctxt,
						 xmlChar **publicId,
						 int strict);
XML_DEPRECATED
XMLPUBFUN void
			xmlParseComment		(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN const xmlChar *
			xmlParsePITarget	(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN void
			xmlParsePI		(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN void
			xmlParseNotationDecl	(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN void
			xmlParseEntityDecl	(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN int
			xmlParseDefaultDecl	(xmlParserCtxt *ctxt,
						 xmlChar **value);
XML_DEPRECATED
XMLPUBFUN xmlEnumeration *
			xmlParseNotationType	(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN xmlEnumeration *
			xmlParseEnumerationType	(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN int
			xmlParseEnumeratedType	(xmlParserCtxt *ctxt,
						 xmlEnumeration **tree);
XML_DEPRECATED
XMLPUBFUN int
			xmlParseAttributeType	(xmlParserCtxt *ctxt,
						 xmlEnumeration **tree);
XML_DEPRECATED
XMLPUBFUN void
			xmlParseAttributeListDecl(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN xmlElementContent *
			xmlParseElementMixedContentDecl
						(xmlParserCtxt *ctxt,
						 int inputchk);
XML_DEPRECATED
XMLPUBFUN xmlElementContent *
			xmlParseElementChildrenContentDecl
						(xmlParserCtxt *ctxt,
						 int inputchk);
XML_DEPRECATED
XMLPUBFUN int
			xmlParseElementContentDecl(xmlParserCtxt *ctxt,
						 const xmlChar *name,
						 xmlElementContent **result);
XML_DEPRECATED
XMLPUBFUN int
			xmlParseElementDecl	(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN void
			xmlParseMarkupDecl	(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN int
			xmlParseCharRef		(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN xmlEntity *
			xmlParseEntityRef	(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN void
			xmlParseReference	(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN void
			xmlParsePEReference	(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN void
			xmlParseDocTypeDecl	(xmlParserCtxt *ctxt);
#ifdef LIBXML_SAX1_ENABLED
XML_DEPRECATED
XMLPUBFUN const xmlChar *
			xmlParseAttribute	(xmlParserCtxt *ctxt,
						 xmlChar **value);
XML_DEPRECATED
XMLPUBFUN const xmlChar *
			xmlParseStartTag	(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN void
			xmlParseEndTag		(xmlParserCtxt *ctxt);
#endif /* LIBXML_SAX1_ENABLED */
XML_DEPRECATED
XMLPUBFUN void
			xmlParseCDSect		(xmlParserCtxt *ctxt);
XMLPUBFUN void
			xmlParseContent		(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN void
			xmlParseElement		(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN xmlChar *
			xmlParseVersionNum	(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN xmlChar *
			xmlParseVersionInfo	(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN xmlChar *
			xmlParseEncName		(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN const xmlChar *
			xmlParseEncodingDecl	(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN int
			xmlParseSDDecl		(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN void
			xmlParseXMLDecl		(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN void
			xmlParseTextDecl	(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN void
			xmlParseMisc		(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN void
			xmlParseExternalSubset	(xmlParserCtxt *ctxt,
						 const xmlChar *publicId,
						 const xmlChar *systemId);

/** @cond ignore */
#define XML_SUBSTITUTE_NONE	0
#define XML_SUBSTITUTE_REF	1
#define XML_SUBSTITUTE_PEREF	2
#define XML_SUBSTITUTE_BOTH	3
/** @endcond */
XML_DEPRECATED
XMLPUBFUN xmlChar *
		xmlStringDecodeEntities		(xmlParserCtxt *ctxt,
						 const xmlChar *str,
						 int what,
						 xmlChar end,
						 xmlChar  end2,
						 xmlChar end3);
XML_DEPRECATED
XMLPUBFUN xmlChar *
		xmlStringLenDecodeEntities	(xmlParserCtxt *ctxt,
						 const xmlChar *str,
						 int len,
						 int what,
						 xmlChar end,
						 xmlChar  end2,
						 xmlChar end3);

/*
 * other commodities shared between parser.c and parserInternals.
 */
XML_DEPRECATED
XMLPUBFUN int			xmlSkipBlankChars	(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN int			xmlStringCurrentChar	(xmlParserCtxt *ctxt,
						 const xmlChar *cur,
						 int *len);
XML_DEPRECATED
XMLPUBFUN void			xmlParserHandlePEReference(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN int			xmlCheckLanguageID	(const xmlChar *lang);

/*
 * Really core function shared with HTML parser.
 */
XML_DEPRECATED
XMLPUBFUN int			xmlCurrentChar		(xmlParserCtxt *ctxt,
						 int *len);
XML_DEPRECATED
XMLPUBFUN int		xmlCopyCharMultiByte	(xmlChar *out,
						 int val);
XML_DEPRECATED
XMLPUBFUN int			xmlCopyChar		(int len,
						 xmlChar *out,
						 int val);
XML_DEPRECATED
XMLPUBFUN void			xmlNextChar		(xmlParserCtxt *ctxt);
XML_DEPRECATED
XMLPUBFUN void			xmlParserInputShrink	(xmlParserInput *in);

#ifdef __cplusplus
}
#endif
#endif /* __XML_PARSER_INTERNALS_H__ */
libxml2/libxml/nanoftp.h000064400000000503151733237460011233 0ustar00/**
 * @file
 * 
 * @brief Removed legacy symbols for an outdated FTP client
 * 
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */

#ifndef __NANO_FTP_H__
#define __NANO_FTP_H__

#ifdef __GNUC__
  #warning "libxml/nanoftp.h is deprecated"
#endif

#endif /* __NANO_FTP_H__ */
libxml2/libxml/debugXML.h000064400000003167151733237460011246 0ustar00/**
 * @file
 * 
 * @brief Tree debugging APIs
 * 
 * Interfaces to a set of routines used for debugging the tree
 *              produced by the XML parser.
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */

#ifndef __DEBUG_XML__
#define __DEBUG_XML__
#include <stdio.h>
#include <libxml/xmlversion.h>
#include <libxml/tree.h>

#ifdef LIBXML_DEBUG_ENABLED

#include <libxml/xpath.h>

#ifdef __cplusplus
extern "C" {
#endif

/*
 * The standard Dump routines.
 */
XMLPUBFUN void
	xmlDebugDumpString	(FILE *output,
				 const xmlChar *str);
XMLPUBFUN void
	xmlDebugDumpAttr	(FILE *output,
				 xmlAttr *attr,
				 int depth);
XMLPUBFUN void
	xmlDebugDumpAttrList	(FILE *output,
				 xmlAttr *attr,
				 int depth);
XMLPUBFUN void
	xmlDebugDumpOneNode	(FILE *output,
				 xmlNode *node,
				 int depth);
XMLPUBFUN void
	xmlDebugDumpNode	(FILE *output,
				 xmlNode *node,
				 int depth);
XMLPUBFUN void
	xmlDebugDumpNodeList	(FILE *output,
				 xmlNode *node,
				 int depth);
XMLPUBFUN void
	xmlDebugDumpDocumentHead(FILE *output,
				 xmlDoc *doc);
XMLPUBFUN void
	xmlDebugDumpDocument	(FILE *output,
				 xmlDoc *doc);
XMLPUBFUN void
	xmlDebugDumpDTD		(FILE *output,
				 xmlDtd *dtd);
XMLPUBFUN void
	xmlDebugDumpEntities	(FILE *output,
				 xmlDoc *doc);

/****************************************************************
 *								*
 *			Checking routines			*
 *								*
 ****************************************************************/

XMLPUBFUN int
	xmlDebugCheckDocument	(FILE * output,
				 xmlDoc *doc);

#ifdef __cplusplus
}
#endif

#endif /* LIBXML_DEBUG_ENABLED */
#endif /* __DEBUG_XML__ */
libxml2/libxml/xmlautomata.h000064400000007461151733237460012134 0ustar00/**
 * @file
 * 
 * @brief API to build regexp automata
 * 
 * These are internal functions and shouldn't be used.
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */

#ifndef __XML_AUTOMATA_H__
#define __XML_AUTOMATA_H__

#include <libxml/xmlversion.h>

#ifdef LIBXML_REGEXP_ENABLED

#include <libxml/xmlstring.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * A libxml automata description
 *
 * It can be compiled into a regexp
 */
typedef struct _xmlAutomata xmlAutomata;
typedef xmlAutomata *xmlAutomataPtr;

/**
 * A state in the automata description
 */
typedef struct _xmlAutomataState xmlAutomataState;
typedef xmlAutomataState *xmlAutomataStatePtr;

/*
 * Building API
 */
XML_DEPRECATED
XMLPUBFUN xmlAutomata *
		    xmlNewAutomata		(void);
XML_DEPRECATED
XMLPUBFUN void
		    xmlFreeAutomata		(xmlAutomata *am);

XML_DEPRECATED
XMLPUBFUN xmlAutomataState *
		    xmlAutomataGetInitState	(xmlAutomata *am);
XML_DEPRECATED
XMLPUBFUN int
		    xmlAutomataSetFinalState	(xmlAutomata *am,
						 xmlAutomataState *state);
XML_DEPRECATED
XMLPUBFUN xmlAutomataState *
		    xmlAutomataNewState		(xmlAutomata *am);
XML_DEPRECATED
XMLPUBFUN xmlAutomataState *
		    xmlAutomataNewTransition	(xmlAutomata *am,
						 xmlAutomataState *from,
						 xmlAutomataState *to,
						 const xmlChar *token,
						 void *data);
XML_DEPRECATED
XMLPUBFUN xmlAutomataState *
		    xmlAutomataNewTransition2	(xmlAutomata *am,
						 xmlAutomataState *from,
						 xmlAutomataState *to,
						 const xmlChar *token,
						 const xmlChar *token2,
						 void *data);
XML_DEPRECATED
XMLPUBFUN xmlAutomataState *
                    xmlAutomataNewNegTrans	(xmlAutomata *am,
						 xmlAutomataState *from,
						 xmlAutomataState *to,
						 const xmlChar *token,
						 const xmlChar *token2,
						 void *data);

XML_DEPRECATED
XMLPUBFUN xmlAutomataState *
		    xmlAutomataNewCountTrans	(xmlAutomata *am,
						 xmlAutomataState *from,
						 xmlAutomataState *to,
						 const xmlChar *token,
						 int min,
						 int max,
						 void *data);
XML_DEPRECATED
XMLPUBFUN xmlAutomataState *
		    xmlAutomataNewCountTrans2	(xmlAutomata *am,
						 xmlAutomataState *from,
						 xmlAutomataState *to,
						 const xmlChar *token,
						 const xmlChar *token2,
						 int min,
						 int max,
						 void *data);
XML_DEPRECATED
XMLPUBFUN xmlAutomataState *
		    xmlAutomataNewOnceTrans	(xmlAutomata *am,
						 xmlAutomataState *from,
						 xmlAutomataState *to,
						 const xmlChar *token,
						 int min,
						 int max,
						 void *data);
XML_DEPRECATED
XMLPUBFUN xmlAutomataState *
		    xmlAutomataNewOnceTrans2	(xmlAutomata *am,
						 xmlAutomataState *from,
						 xmlAutomataState *to,
						 const xmlChar *token,
						 const xmlChar *token2,
						 int min,
						 int max,
						 void *data);
XML_DEPRECATED
XMLPUBFUN xmlAutomataState *
		    xmlAutomataNewAllTrans	(xmlAutomata *am,
						 xmlAutomataState *from,
						 xmlAutomataState *to,
						 int lax);
XML_DEPRECATED
XMLPUBFUN xmlAutomataState *
		    xmlAutomataNewEpsilon	(xmlAutomata *am,
						 xmlAutomataState *from,
						 xmlAutomataState *to);
XML_DEPRECATED
XMLPUBFUN xmlAutomataState *
		    xmlAutomataNewCountedTrans	(xmlAutomata *am,
						 xmlAutomataState *from,
						 xmlAutomataState *to,
						 int counter);
XML_DEPRECATED
XMLPUBFUN xmlAutomataState *
		    xmlAutomataNewCounterTrans	(xmlAutomata *am,
						 xmlAutomataState *from,
						 xmlAutomataState *to,
						 int counter);
XML_DEPRECATED
XMLPUBFUN int
		    xmlAutomataNewCounter	(xmlAutomata *am,
						 int min,
						 int max);

XML_DEPRECATED
XMLPUBFUN struct _xmlRegexp *
		    xmlAutomataCompile		(xmlAutomata *am);
XML_DEPRECATED
XMLPUBFUN int
		    xmlAutomataIsDeterminist	(xmlAutomata *am);

#ifdef __cplusplus
}
#endif

#endif /* LIBXML_REGEXP_ENABLED */

#endif /* __XML_AUTOMATA_H__ */
libxml2/libxml/SAX.h000064400000000613151733237460010223 0ustar00/**
 * @file
 * 
 * @brief Old SAX version 1 handler, deprecated
 * 
 * @deprecated set of SAX version 1 interfaces used to
 *              build the DOM tree.
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */

#ifndef __XML_SAX_H__
#define __XML_SAX_H__

#ifdef __GNUC__
  #warning "libxml/SAX.h is deprecated"
#endif

#endif /* __XML_SAX_H__ */
libxml2/libxml/xpointer.h000064400000001642151733237460011443 0ustar00/**
 * @file
 *
 * @brief XPointer framework and schemes
 *
 * API to evaluate XPointer expressions. The following schemes are
 * supported:
 *
 * - element()
 * - xmlns()
 * - xpath1()
 *
 * xpointer() is an alias for the xpath1() scheme. The point and
 * range extensions are not supported.
 *
 * @copyright See Copyright for the status of this software.
 *
 * @author Daniel Veillard
 */

#ifndef __XML_XPTR_H__
#define __XML_XPTR_H__

#include <libxml/xmlversion.h>

#ifdef LIBXML_XPTR_ENABLED

#include <libxml/tree.h>
#include <libxml/xpath.h>

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Functions.
 */
XML_DEPRECATED
XMLPUBFUN xmlXPathContext *
		    xmlXPtrNewContext		(xmlDoc *doc,
						 xmlNode *here,
						 xmlNode *origin);
XMLPUBFUN xmlXPathObject *
		    xmlXPtrEval			(const xmlChar *str,
						 xmlXPathContext *ctx);

#ifdef __cplusplus
}
#endif

#endif /* LIBXML_XPTR_ENABLED */
#endif /* __XML_XPTR_H__ */
openssl/dso.h000064400000047362151733316540007211 0ustar00/* dso.h */
/*
 * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project
 * 2000.
 */
/* ====================================================================
 * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#ifndef HEADER_DSO_H
# define HEADER_DSO_H

# include <openssl/crypto.h>

#ifdef __cplusplus
extern "C" {
#endif

/* These values are used as commands to DSO_ctrl() */
# define DSO_CTRL_GET_FLAGS      1
# define DSO_CTRL_SET_FLAGS      2
# define DSO_CTRL_OR_FLAGS       3

/*
 * By default, DSO_load() will translate the provided filename into a form
 * typical for the platform (more specifically the DSO_METHOD) using the
 * dso_name_converter function of the method. Eg. win32 will transform "blah"
 * into "blah.dll", and dlfcn will transform it into "libblah.so". The
 * behaviour can be overriden by setting the name_converter callback in the
 * DSO object (using DSO_set_name_converter()). This callback could even
 * utilise the DSO_METHOD's converter too if it only wants to override
 * behaviour for one or two possible DSO methods. However, the following flag
 * can be set in a DSO to prevent *any* native name-translation at all - eg.
 * if the caller has prompted the user for a path to a driver library so the
 * filename should be interpreted as-is.
 */
# define DSO_FLAG_NO_NAME_TRANSLATION            0x01
/*
 * An extra flag to give if only the extension should be added as
 * translation.  This is obviously only of importance on Unix and other
 * operating systems where the translation also may prefix the name with
 * something, like 'lib', and ignored everywhere else. This flag is also
 * ignored if DSO_FLAG_NO_NAME_TRANSLATION is used at the same time.
 */
# define DSO_FLAG_NAME_TRANSLATION_EXT_ONLY      0x02

/*
 * The following flag controls the translation of symbol names to upper case.
 * This is currently only being implemented for OpenVMS.
 */
# define DSO_FLAG_UPCASE_SYMBOL                  0x10

/*
 * This flag loads the library with public symbols. Meaning: The exported
 * symbols of this library are public to all libraries loaded after this
 * library. At the moment only implemented in unix.
 */
# define DSO_FLAG_GLOBAL_SYMBOLS                 0x20

typedef void (*DSO_FUNC_TYPE) (void);

typedef struct dso_st DSO;

/*
 * The function prototype used for method functions (or caller-provided
 * callbacks) that transform filenames. They are passed a DSO structure
 * pointer (or NULL if they are to be used independantly of a DSO object) and
 * a filename to transform. They should either return NULL (if there is an
 * error condition) or a newly allocated string containing the transformed
 * form that the caller will need to free with OPENSSL_free() when done.
 */
typedef char *(*DSO_NAME_CONVERTER_FUNC)(DSO *, const char *);
/*
 * The function prototype used for method functions (or caller-provided
 * callbacks) that merge two file specifications. They are passed a DSO
 * structure pointer (or NULL if they are to be used independantly of a DSO
 * object) and two file specifications to merge. They should either return
 * NULL (if there is an error condition) or a newly allocated string
 * containing the result of merging that the caller will need to free with
 * OPENSSL_free() when done. Here, merging means that bits and pieces are
 * taken from each of the file specifications and added together in whatever
 * fashion that is sensible for the DSO method in question.  The only rule
 * that really applies is that if the two specification contain pieces of the
 * same type, the copy from the first string takes priority.  One could see
 * it as the first specification is the one given by the user and the second
 * being a bunch of defaults to add on if they're missing in the first.
 */
typedef char *(*DSO_MERGER_FUNC)(DSO *, const char *, const char *);

typedef struct dso_meth_st {
    const char *name;
    /*
     * Loads a shared library, NB: new DSO_METHODs must ensure that a
     * successful load populates the loaded_filename field, and likewise a
     * successful unload OPENSSL_frees and NULLs it out.
     */
    int (*dso_load) (DSO *dso);
    /* Unloads a shared library */
    int (*dso_unload) (DSO *dso);
    /* Binds a variable */
    void *(*dso_bind_var) (DSO *dso, const char *symname);
    /*
     * Binds a function - assumes a return type of DSO_FUNC_TYPE. This should
     * be cast to the real function prototype by the caller. Platforms that
     * don't have compatible representations for different prototypes (this
     * is possible within ANSI C) are highly unlikely to have shared
     * libraries at all, let alone a DSO_METHOD implemented for them.
     */
    DSO_FUNC_TYPE (*dso_bind_func) (DSO *dso, const char *symname);
/* I don't think this would actually be used in any circumstances. */
# if 0
    /* Unbinds a variable */
    int (*dso_unbind_var) (DSO *dso, char *symname, void *symptr);
    /* Unbinds a function */
    int (*dso_unbind_func) (DSO *dso, char *symname, DSO_FUNC_TYPE symptr);
# endif
    /*
     * The generic (yuck) "ctrl()" function. NB: Negative return values
     * (rather than zero) indicate errors.
     */
    long (*dso_ctrl) (DSO *dso, int cmd, long larg, void *parg);
    /*
     * The default DSO_METHOD-specific function for converting filenames to a
     * canonical native form.
     */
    DSO_NAME_CONVERTER_FUNC dso_name_converter;
    /*
     * The default DSO_METHOD-specific function for converting filenames to a
     * canonical native form.
     */
    DSO_MERGER_FUNC dso_merger;
    /* [De]Initialisation handlers. */
    int (*init) (DSO *dso);
    int (*finish) (DSO *dso);
    /* Return pathname of the module containing location */
    int (*pathbyaddr) (void *addr, char *path, int sz);
    /* Perform global symbol lookup, i.e. among *all* modules */
    void *(*globallookup) (const char *symname);
} DSO_METHOD;

/**********************************************************************/
/* The low-level handle type used to refer to a loaded shared library */

struct dso_st {
    DSO_METHOD *meth;
    /*
     * Standard dlopen uses a (void *). Win32 uses a HANDLE. VMS doesn't use
     * anything but will need to cache the filename for use in the dso_bind
     * handler. All in all, let each method control its own destiny.
     * "Handles" and such go in a STACK.
     */
    STACK_OF(void) *meth_data;
    int references;
    int flags;
    /*
     * For use by applications etc ... use this for your bits'n'pieces, don't
     * touch meth_data!
     */
    CRYPTO_EX_DATA ex_data;
    /*
     * If this callback function pointer is set to non-NULL, then it will be
     * used in DSO_load() in place of meth->dso_name_converter. NB: This
     * should normally set using DSO_set_name_converter().
     */
    DSO_NAME_CONVERTER_FUNC name_converter;
    /*
     * If this callback function pointer is set to non-NULL, then it will be
     * used in DSO_load() in place of meth->dso_merger. NB: This should
     * normally set using DSO_set_merger().
     */
    DSO_MERGER_FUNC merger;
    /*
     * This is populated with (a copy of) the platform-independant filename
     * used for this DSO.
     */
    char *filename;
    /*
     * This is populated with (a copy of) the translated filename by which
     * the DSO was actually loaded. It is NULL iff the DSO is not currently
     * loaded. NB: This is here because the filename translation process may
     * involve a callback being invoked more than once not only to convert to
     * a platform-specific form, but also to try different filenames in the
     * process of trying to perform a load. As such, this variable can be
     * used to indicate (a) whether this DSO structure corresponds to a
     * loaded library or not, and (b) the filename with which it was actually
     * loaded.
     */
    char *loaded_filename;
};

DSO *DSO_new(void);
DSO *DSO_new_method(DSO_METHOD *method);
int DSO_free(DSO *dso);
int DSO_flags(DSO *dso);
int DSO_up_ref(DSO *dso);
long DSO_ctrl(DSO *dso, int cmd, long larg, void *parg);

/*
 * This function sets the DSO's name_converter callback. If it is non-NULL,
 * then it will be used instead of the associated DSO_METHOD's function. If
 * oldcb is non-NULL then it is set to the function pointer value being
 * replaced. Return value is non-zero for success.
 */
int DSO_set_name_converter(DSO *dso, DSO_NAME_CONVERTER_FUNC cb,
                           DSO_NAME_CONVERTER_FUNC *oldcb);
/*
 * These functions can be used to get/set the platform-independant filename
 * used for a DSO. NB: set will fail if the DSO is already loaded.
 */
const char *DSO_get_filename(DSO *dso);
int DSO_set_filename(DSO *dso, const char *filename);
/*
 * This function will invoke the DSO's name_converter callback to translate a
 * filename, or if the callback isn't set it will instead use the DSO_METHOD's
 * converter. If "filename" is NULL, the "filename" in the DSO itself will be
 * used. If the DSO_FLAG_NO_NAME_TRANSLATION flag is set, then the filename is
 * simply duplicated. NB: This function is usually called from within a
 * DSO_METHOD during the processing of a DSO_load() call, and is exposed so
 * that caller-created DSO_METHODs can do the same thing. A non-NULL return
 * value will need to be OPENSSL_free()'d.
 */
char *DSO_convert_filename(DSO *dso, const char *filename);
/*
 * This function will invoke the DSO's merger callback to merge two file
 * specifications, or if the callback isn't set it will instead use the
 * DSO_METHOD's merger.  A non-NULL return value will need to be
 * OPENSSL_free()'d.
 */
char *DSO_merge(DSO *dso, const char *filespec1, const char *filespec2);
/*
 * If the DSO is currently loaded, this returns the filename that it was
 * loaded under, otherwise it returns NULL. So it is also useful as a test as
 * to whether the DSO is currently loaded. NB: This will not necessarily
 * return the same value as DSO_convert_filename(dso, dso->filename), because
 * the DSO_METHOD's load function may have tried a variety of filenames (with
 * and/or without the aid of the converters) before settling on the one it
 * actually loaded.
 */
const char *DSO_get_loaded_filename(DSO *dso);

void DSO_set_default_method(DSO_METHOD *meth);
DSO_METHOD *DSO_get_default_method(void);
DSO_METHOD *DSO_get_method(DSO *dso);
DSO_METHOD *DSO_set_method(DSO *dso, DSO_METHOD *meth);

/*
 * The all-singing all-dancing load function, you normally pass NULL for the
 * first and third parameters. Use DSO_up and DSO_free for subsequent
 * reference count handling. Any flags passed in will be set in the
 * constructed DSO after its init() function but before the load operation.
 * If 'dso' is non-NULL, 'flags' is ignored.
 */
DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags);

/* This function binds to a variable inside a shared library. */
void *DSO_bind_var(DSO *dso, const char *symname);

/* This function binds to a function inside a shared library. */
DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname);

/*
 * This method is the default, but will beg, borrow, or steal whatever method
 * should be the default on any particular platform (including
 * DSO_METH_null() if necessary).
 */
DSO_METHOD *DSO_METHOD_openssl(void);

/*
 * This method is defined for all platforms - if a platform has no DSO
 * support then this will be the only method!
 */
DSO_METHOD *DSO_METHOD_null(void);

/*
 * If DSO_DLFCN is defined, the standard dlfcn.h-style functions (dlopen,
 * dlclose, dlsym, etc) will be used and incorporated into this method. If
 * not, this method will return NULL.
 */
DSO_METHOD *DSO_METHOD_dlfcn(void);

/*
 * If DSO_DL is defined, the standard dl.h-style functions (shl_load,
 * shl_unload, shl_findsym, etc) will be used and incorporated into this
 * method. If not, this method will return NULL.
 */
DSO_METHOD *DSO_METHOD_dl(void);

/* If WIN32 is defined, use DLLs. If not, return NULL. */
DSO_METHOD *DSO_METHOD_win32(void);

/* If VMS is defined, use shared images. If not, return NULL. */
DSO_METHOD *DSO_METHOD_vms(void);

/*
 * This function writes null-terminated pathname of DSO module containing
 * 'addr' into 'sz' large caller-provided 'path' and returns the number of
 * characters [including trailing zero] written to it. If 'sz' is 0 or
 * negative, 'path' is ignored and required amount of charachers [including
 * trailing zero] to accomodate pathname is returned. If 'addr' is NULL, then
 * pathname of cryptolib itself is returned. Negative or zero return value
 * denotes error.
 */
int DSO_pathbyaddr(void *addr, char *path, int sz);

/*
 * This function should be used with caution! It looks up symbols in *all*
 * loaded modules and if module gets unloaded by somebody else attempt to
 * dereference the pointer is doomed to have fatal consequences. Primary
 * usage for this function is to probe *core* system functionality, e.g.
 * check if getnameinfo(3) is available at run-time without bothering about
 * OS-specific details such as libc.so.versioning or where does it actually
 * reside: in libc itself or libsocket.
 */
void *DSO_global_lookup(const char *name);

/* If BeOS is defined, use shared images. If not, return NULL. */
DSO_METHOD *DSO_METHOD_beos(void);

/* BEGIN ERROR CODES */
/*
 * The following lines are auto generated by the script mkerr.pl. Any changes
 * made after this point may be overwritten when the script is next run.
 */
void ERR_load_DSO_strings(void);

/* Error codes for the DSO functions. */

/* Function codes. */
# define DSO_F_BEOS_BIND_FUNC                             144
# define DSO_F_BEOS_BIND_VAR                              145
# define DSO_F_BEOS_LOAD                                  146
# define DSO_F_BEOS_NAME_CONVERTER                        147
# define DSO_F_BEOS_UNLOAD                                148
# define DSO_F_DLFCN_BIND_FUNC                            100
# define DSO_F_DLFCN_BIND_VAR                             101
# define DSO_F_DLFCN_LOAD                                 102
# define DSO_F_DLFCN_MERGER                               130
# define DSO_F_DLFCN_NAME_CONVERTER                       123
# define DSO_F_DLFCN_UNLOAD                               103
# define DSO_F_DL_BIND_FUNC                               104
# define DSO_F_DL_BIND_VAR                                105
# define DSO_F_DL_LOAD                                    106
# define DSO_F_DL_MERGER                                  131
# define DSO_F_DL_NAME_CONVERTER                          124
# define DSO_F_DL_UNLOAD                                  107
# define DSO_F_DSO_BIND_FUNC                              108
# define DSO_F_DSO_BIND_VAR                               109
# define DSO_F_DSO_CONVERT_FILENAME                       126
# define DSO_F_DSO_CTRL                                   110
# define DSO_F_DSO_FREE                                   111
# define DSO_F_DSO_GET_FILENAME                           127
# define DSO_F_DSO_GET_LOADED_FILENAME                    128
# define DSO_F_DSO_GLOBAL_LOOKUP                          139
# define DSO_F_DSO_LOAD                                   112
# define DSO_F_DSO_MERGE                                  132
# define DSO_F_DSO_NEW_METHOD                             113
# define DSO_F_DSO_PATHBYADDR                             140
# define DSO_F_DSO_SET_FILENAME                           129
# define DSO_F_DSO_SET_NAME_CONVERTER                     122
# define DSO_F_DSO_UP_REF                                 114
# define DSO_F_GLOBAL_LOOKUP_FUNC                         138
# define DSO_F_PATHBYADDR                                 137
# define DSO_F_VMS_BIND_SYM                               115
# define DSO_F_VMS_LOAD                                   116
# define DSO_F_VMS_MERGER                                 133
# define DSO_F_VMS_UNLOAD                                 117
# define DSO_F_WIN32_BIND_FUNC                            118
# define DSO_F_WIN32_BIND_VAR                             119
# define DSO_F_WIN32_GLOBALLOOKUP                         142
# define DSO_F_WIN32_GLOBALLOOKUP_FUNC                    143
# define DSO_F_WIN32_JOINER                               135
# define DSO_F_WIN32_LOAD                                 120
# define DSO_F_WIN32_MERGER                               134
# define DSO_F_WIN32_NAME_CONVERTER                       125
# define DSO_F_WIN32_PATHBYADDR                           141
# define DSO_F_WIN32_SPLITTER                             136
# define DSO_F_WIN32_UNLOAD                               121

/* Reason codes. */
# define DSO_R_CTRL_FAILED                                100
# define DSO_R_DSO_ALREADY_LOADED                         110
# define DSO_R_EMPTY_FILE_STRUCTURE                       113
# define DSO_R_FAILURE                                    114
# define DSO_R_FILENAME_TOO_BIG                           101
# define DSO_R_FINISH_FAILED                              102
# define DSO_R_INCORRECT_FILE_SYNTAX                      115
# define DSO_R_LOAD_FAILED                                103
# define DSO_R_NAME_TRANSLATION_FAILED                    109
# define DSO_R_NO_FILENAME                                111
# define DSO_R_NO_FILE_SPECIFICATION                      116
# define DSO_R_NULL_HANDLE                                104
# define DSO_R_SET_FILENAME_FAILED                        112
# define DSO_R_STACK_ERROR                                105
# define DSO_R_SYM_FAILURE                                106
# define DSO_R_UNLOAD_FAILED                              107
# define DSO_R_UNSUPPORTED                                108

#ifdef  __cplusplus
}
#endif
#endif
openssl/ossl_typ.h000064400000017230151733316540010267 0ustar00/* ====================================================================
 * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#ifndef HEADER_OPENSSL_TYPES_H
# define HEADER_OPENSSL_TYPES_H

#ifdef  __cplusplus
extern "C" {
#endif

# include <openssl/e_os2.h>

# ifdef NO_ASN1_TYPEDEFS
#  define ASN1_INTEGER            ASN1_STRING
#  define ASN1_ENUMERATED         ASN1_STRING
#  define ASN1_BIT_STRING         ASN1_STRING
#  define ASN1_OCTET_STRING       ASN1_STRING
#  define ASN1_PRINTABLESTRING    ASN1_STRING
#  define ASN1_T61STRING          ASN1_STRING
#  define ASN1_IA5STRING          ASN1_STRING
#  define ASN1_UTCTIME            ASN1_STRING
#  define ASN1_GENERALIZEDTIME    ASN1_STRING
#  define ASN1_TIME               ASN1_STRING
#  define ASN1_GENERALSTRING      ASN1_STRING
#  define ASN1_UNIVERSALSTRING    ASN1_STRING
#  define ASN1_BMPSTRING          ASN1_STRING
#  define ASN1_VISIBLESTRING      ASN1_STRING
#  define ASN1_UTF8STRING         ASN1_STRING
#  define ASN1_BOOLEAN            int
#  define ASN1_NULL               int
# else
typedef struct asn1_string_st ASN1_INTEGER;
typedef struct asn1_string_st ASN1_ENUMERATED;
typedef struct asn1_string_st ASN1_BIT_STRING;
typedef struct asn1_string_st ASN1_OCTET_STRING;
typedef struct asn1_string_st ASN1_PRINTABLESTRING;
typedef struct asn1_string_st ASN1_T61STRING;
typedef struct asn1_string_st ASN1_IA5STRING;
typedef struct asn1_string_st ASN1_GENERALSTRING;
typedef struct asn1_string_st ASN1_UNIVERSALSTRING;
typedef struct asn1_string_st ASN1_BMPSTRING;
typedef struct asn1_string_st ASN1_UTCTIME;
typedef struct asn1_string_st ASN1_TIME;
typedef struct asn1_string_st ASN1_GENERALIZEDTIME;
typedef struct asn1_string_st ASN1_VISIBLESTRING;
typedef struct asn1_string_st ASN1_UTF8STRING;
typedef struct asn1_string_st ASN1_STRING;
typedef int ASN1_BOOLEAN;
typedef int ASN1_NULL;
# endif

typedef struct asn1_object_st ASN1_OBJECT;

typedef struct ASN1_ITEM_st ASN1_ITEM;
typedef struct asn1_pctx_st ASN1_PCTX;

# ifdef OPENSSL_SYS_WIN32
#  undef X509_NAME
#  undef X509_EXTENSIONS
#  undef X509_CERT_PAIR
#  undef PKCS7_ISSUER_AND_SERIAL
#  undef OCSP_REQUEST
#  undef OCSP_RESPONSE
# endif

# ifdef BIGNUM
#  undef BIGNUM
# endif
typedef struct bignum_st BIGNUM;
typedef struct bignum_ctx BN_CTX;
typedef struct bn_blinding_st BN_BLINDING;
typedef struct bn_mont_ctx_st BN_MONT_CTX;
typedef struct bn_recp_ctx_st BN_RECP_CTX;
typedef struct bn_gencb_st BN_GENCB;

typedef struct buf_mem_st BUF_MEM;

typedef struct evp_cipher_st EVP_CIPHER;
typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX;
typedef struct env_md_st EVP_MD;
typedef struct env_md_ctx_st EVP_MD_CTX;
typedef struct evp_pkey_st EVP_PKEY;

typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD;

typedef struct evp_pkey_method_st EVP_PKEY_METHOD;
typedef struct evp_pkey_ctx_st EVP_PKEY_CTX;

typedef struct dh_st DH;
typedef struct dh_method DH_METHOD;

typedef struct dsa_st DSA;
typedef struct dsa_method DSA_METHOD;

typedef struct rsa_st RSA;
typedef struct rsa_meth_st RSA_METHOD;

typedef struct rand_meth_st RAND_METHOD;

typedef struct ecdh_method ECDH_METHOD;
typedef struct ecdsa_method ECDSA_METHOD;

typedef struct x509_st X509;
typedef struct X509_algor_st X509_ALGOR;
typedef struct X509_crl_st X509_CRL;
typedef struct x509_crl_method_st X509_CRL_METHOD;
typedef struct x509_revoked_st X509_REVOKED;
typedef struct X509_name_st X509_NAME;
typedef struct X509_pubkey_st X509_PUBKEY;
typedef struct x509_store_st X509_STORE;
typedef struct x509_store_ctx_st X509_STORE_CTX;

typedef struct pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO;

typedef struct v3_ext_ctx X509V3_CTX;
typedef struct conf_st CONF;

typedef struct store_st STORE;
typedef struct store_method_st STORE_METHOD;

typedef struct ui_st UI;
typedef struct ui_method_st UI_METHOD;

typedef struct st_ERR_FNS ERR_FNS;

typedef struct engine_st ENGINE;
typedef struct ssl_st SSL;
typedef struct ssl_ctx_st SSL_CTX;

typedef struct comp_method_st COMP_METHOD;

typedef struct X509_POLICY_NODE_st X509_POLICY_NODE;
typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL;
typedef struct X509_POLICY_TREE_st X509_POLICY_TREE;
typedef struct X509_POLICY_CACHE_st X509_POLICY_CACHE;

typedef struct AUTHORITY_KEYID_st AUTHORITY_KEYID;
typedef struct DIST_POINT_st DIST_POINT;
typedef struct ISSUING_DIST_POINT_st ISSUING_DIST_POINT;
typedef struct NAME_CONSTRAINTS_st NAME_CONSTRAINTS;

  /* If placed in pkcs12.h, we end up with a circular depency with pkcs7.h */
# define DECLARE_PKCS12_STACK_OF(type)/* Nothing */
# define IMPLEMENT_PKCS12_STACK_OF(type)/* Nothing */

typedef struct crypto_ex_data_st CRYPTO_EX_DATA;
/* Callback types for crypto.h */
typedef int CRYPTO_EX_new (void *parent, void *ptr, CRYPTO_EX_DATA *ad,
                           int idx, long argl, void *argp);
typedef void CRYPTO_EX_free (void *parent, void *ptr, CRYPTO_EX_DATA *ad,
                             int idx, long argl, void *argp);
typedef int CRYPTO_EX_dup (CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from,
                           void *from_d, int idx, long argl, void *argp);

typedef struct ocsp_req_ctx_st OCSP_REQ_CTX;
typedef struct ocsp_response_st OCSP_RESPONSE;
typedef struct ocsp_responder_id_st OCSP_RESPID;

#ifdef  __cplusplus
}
#endif
#endif                          /* def HEADER_OPENSSL_TYPES_H */
openssl/pqueue.h000064400000007131151733316550007717 0ustar00/* crypto/pqueue/pqueue.h */
/*
 * DTLS implementation written by Nagendra Modadugu
 * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
 */
/* ====================================================================
 * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#ifndef HEADER_PQUEUE_H
# define HEADER_PQUEUE_H

# include <stdio.h>
# include <stdlib.h>
# include <string.h>

#ifdef  __cplusplus
extern "C" {
#endif
typedef struct _pqueue *pqueue;

typedef struct _pitem {
    unsigned char priority[8];  /* 64-bit value in big-endian encoding */
    void *data;
    struct _pitem *next;
} pitem;

typedef struct _pitem *piterator;

pitem *pitem_new(unsigned char *prio64be, void *data);
void pitem_free(pitem *item);

pqueue pqueue_new(void);
void pqueue_free(pqueue pq);

pitem *pqueue_insert(pqueue pq, pitem *item);
pitem *pqueue_peek(pqueue pq);
pitem *pqueue_pop(pqueue pq);
pitem *pqueue_find(pqueue pq, unsigned char *prio64be);
pitem *pqueue_iterator(pqueue pq);
pitem *pqueue_next(piterator *iter);

void pqueue_print(pqueue pq);
int pqueue_size(pqueue pq);

#ifdef  __cplusplus
}
#endif
#endif                          /* ! HEADER_PQUEUE_H */
openssl/rand.h000064400000015350151733316550007341 0ustar00/* crypto/rand/rand.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#ifndef HEADER_RAND_H
# define HEADER_RAND_H

# include <stdlib.h>
# include <openssl/ossl_typ.h>
# include <openssl/e_os2.h>

# if defined(OPENSSL_SYS_WINDOWS)
#  include <windows.h>
# endif

#ifdef  __cplusplus
extern "C" {
#endif

# if defined(OPENSSL_FIPS)
#  define FIPS_RAND_SIZE_T size_t
# endif

/* Already defined in ossl_typ.h */
/* typedef struct rand_meth_st RAND_METHOD; */

struct rand_meth_st {
    void (*seed) (const void *buf, int num);
    int (*bytes) (unsigned char *buf, int num);
    void (*cleanup) (void);
    void (*add) (const void *buf, int num, double entropy);
    int (*pseudorand) (unsigned char *buf, int num);
    int (*status) (void);
};

# ifdef BN_DEBUG
extern int rand_predictable;
# endif

int RAND_set_rand_method(const RAND_METHOD *meth);
const RAND_METHOD *RAND_get_rand_method(void);
# ifndef OPENSSL_NO_ENGINE
int RAND_set_rand_engine(ENGINE *engine);
# endif
RAND_METHOD *RAND_SSLeay(void);
void RAND_cleanup(void);
int RAND_bytes(unsigned char *buf, int num);
int RAND_pseudo_bytes(unsigned char *buf, int num);
void RAND_seed(const void *buf, int num);
void RAND_add(const void *buf, int num, double entropy);
int RAND_load_file(const char *file, long max_bytes);
int RAND_write_file(const char *file);
const char *RAND_file_name(char *file, size_t num);
int RAND_status(void);
int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes);
int RAND_egd(const char *path);
int RAND_egd_bytes(const char *path, int bytes);
int RAND_poll(void);

# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)

void RAND_screen(void);
int RAND_event(UINT, WPARAM, LPARAM);

# endif

# ifdef OPENSSL_FIPS
void RAND_set_fips_drbg_type(int type, int flags);
int RAND_init_fips(void);
# endif

/* BEGIN ERROR CODES */
/*
 * The following lines are auto generated by the script mkerr.pl. Any changes
 * made after this point may be overwritten when the script is next run.
 */
void ERR_load_RAND_strings(void);

/* Error codes for the RAND functions. */

/* Function codes. */
# define RAND_F_ENG_RAND_GET_RAND_METHOD                  108
# define RAND_F_FIPS_RAND                                 103
# define RAND_F_FIPS_RAND_BYTES                           102
# define RAND_F_FIPS_RAND_SET_DT                          106
# define RAND_F_FIPS_X931_SET_DT                          106
# define RAND_F_FIPS_SET_DT                               104
# define RAND_F_FIPS_SET_PRNG_SEED                        107
# define RAND_F_FIPS_SET_TEST_MODE                        105
# define RAND_F_RAND_GET_RAND_METHOD                      101
# define RAND_F_RAND_INIT_FIPS                            109
# define RAND_F_SSLEAY_RAND_BYTES                         100

/* Reason codes. */
# define RAND_R_DUAL_EC_DRBG_DISABLED                     114
# define RAND_R_ERROR_INITIALISING_DRBG                   112
# define RAND_R_ERROR_INSTANTIATING_DRBG                  113
# define RAND_R_NON_FIPS_METHOD                           105
# define RAND_R_NOT_IN_TEST_MODE                          106
# define RAND_R_NO_FIPS_RANDOM_METHOD_SET                 111
# define RAND_R_NO_KEY_SET                                107
# define RAND_R_PRNG_ASKING_FOR_TOO_MUCH                  101
# define RAND_R_PRNG_ERROR                                108
# define RAND_R_PRNG_KEYED                                109
# define RAND_R_PRNG_NOT_REKEYED                          102
# define RAND_R_PRNG_NOT_RESEEDED                         103
# define RAND_R_PRNG_NOT_SEEDED                           100
# define RAND_R_PRNG_SEED_MUST_NOT_MATCH_KEY              110
# define RAND_R_PRNG_STUCK                                104

#ifdef  __cplusplus
}
#endif
#endif
openssl/txt_db.h000064400000011027151733316550007676 0ustar00/* crypto/txt_db/txt_db.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#ifndef HEADER_TXT_DB_H
# define HEADER_TXT_DB_H

# include <openssl/opensslconf.h>
# ifndef OPENSSL_NO_BIO
#  include <openssl/bio.h>
# endif
# include <openssl/stack.h>
# include <openssl/lhash.h>

# define DB_ERROR_OK                     0
# define DB_ERROR_MALLOC                 1
# define DB_ERROR_INDEX_CLASH            2
# define DB_ERROR_INDEX_OUT_OF_RANGE     3
# define DB_ERROR_NO_INDEX               4
# define DB_ERROR_INSERT_INDEX_CLASH     5

#ifdef  __cplusplus
extern "C" {
#endif

typedef OPENSSL_STRING *OPENSSL_PSTRING;
DECLARE_SPECIAL_STACK_OF(OPENSSL_PSTRING, OPENSSL_STRING)

typedef struct txt_db_st {
    int num_fields;
    STACK_OF(OPENSSL_PSTRING) *data;
    LHASH_OF(OPENSSL_STRING) **index;
    int (**qual) (OPENSSL_STRING *);
    long error;
    long arg1;
    long arg2;
    OPENSSL_STRING *arg_row;
} TXT_DB;

# ifndef OPENSSL_NO_BIO
TXT_DB *TXT_DB_read(BIO *in, int num);
long TXT_DB_write(BIO *out, TXT_DB *db);
# else
TXT_DB *TXT_DB_read(char *in, int num);
long TXT_DB_write(char *out, TXT_DB *db);
# endif
int TXT_DB_create_index(TXT_DB *db, int field, int (*qual) (OPENSSL_STRING *),
                        LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp);
void TXT_DB_free(TXT_DB *db);
OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx,
                                    OPENSSL_STRING *value);
int TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *value);

#ifdef  __cplusplus
}
#endif

#endif
openssl/dh.h000064400000040724151733316550007013 0ustar00/* crypto/dh/dh.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#ifndef HEADER_DH_H
# define HEADER_DH_H

# include <openssl/e_os2.h>

# ifdef OPENSSL_NO_DH
#  error DH is disabled.
# endif

# ifndef OPENSSL_NO_BIO
#  include <openssl/bio.h>
# endif
# include <openssl/ossl_typ.h>
# ifndef OPENSSL_NO_DEPRECATED
#  include <openssl/bn.h>
# endif

# ifndef OPENSSL_DH_MAX_MODULUS_BITS
#  define OPENSSL_DH_MAX_MODULUS_BITS    10000
# endif

# define OPENSSL_DH_FIPS_MIN_MODULUS_BITS 1024
# define OPENSSL_DH_FIPS_MIN_MODULUS_BITS_GEN 2048

# define DH_FLAG_CACHE_MONT_P     0x01

/*
 * new with 0.9.7h; the built-in DH
 * implementation now uses constant time
 * modular exponentiation for secret exponents
 * by default. This flag causes the
 * faster variable sliding window method to
 * be used for all exponents.
 */
# define DH_FLAG_NO_EXP_CONSTTIME 0x02

/*
 * If this flag is set the DH method is FIPS compliant and can be used in
 * FIPS mode. This is set in the validated module method. If an application
 * sets this flag in its own methods it is its reposibility to ensure the
 * result is compliant.
 */

# define DH_FLAG_FIPS_METHOD                     0x0400

/*
 * If this flag is set the operations normally disabled in FIPS mode are
 * permitted it is then the applications responsibility to ensure that the
 * usage is compliant.
 */

# define DH_FLAG_NON_FIPS_ALLOW                  0x0400

#ifdef  __cplusplus
extern "C" {
#endif

/* Already defined in ossl_typ.h */
/* typedef struct dh_st DH; */
/* typedef struct dh_method DH_METHOD; */

struct dh_method {
    const char *name;
    /* Methods here */
    int (*generate_key) (DH *dh);
    int (*compute_key) (unsigned char *key, const BIGNUM *pub_key, DH *dh);
    /* Can be null */
    int (*bn_mod_exp) (const DH *dh, BIGNUM *r, const BIGNUM *a,
                       const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
                       BN_MONT_CTX *m_ctx);
    int (*init) (DH *dh);
    int (*finish) (DH *dh);
    int flags;
    char *app_data;
    /* If this is non-NULL, it will be used to generate parameters */
    int (*generate_params) (DH *dh, int prime_len, int generator,
                            BN_GENCB *cb);
};

struct dh_st {
    /*
     * This first argument is used to pick up errors when a DH is passed
     * instead of a EVP_PKEY
     */
    int pad;
    int version;
    BIGNUM *p;
    BIGNUM *g;
    long length;                /* optional */
    BIGNUM *pub_key;            /* g^x % p */
    BIGNUM *priv_key;           /* x */
    int flags;
    BN_MONT_CTX *method_mont_p;
    /* Place holders if we want to do X9.42 DH */
    BIGNUM *q;
    BIGNUM *j;
    unsigned char *seed;
    int seedlen;
    BIGNUM *counter;
    int references;
    CRYPTO_EX_DATA ex_data;
    const DH_METHOD *meth;
    ENGINE *engine;
};

# define DH_GENERATOR_2          2
/* #define DH_GENERATOR_3       3 */
# define DH_GENERATOR_5          5

/* DH_check error codes */
# define DH_CHECK_P_NOT_PRIME            0x01
# define DH_CHECK_P_NOT_SAFE_PRIME       0x02
# define DH_UNABLE_TO_CHECK_GENERATOR    0x04
# define DH_NOT_SUITABLE_GENERATOR       0x08
# define DH_CHECK_Q_NOT_PRIME            0x10
# define DH_CHECK_INVALID_Q_VALUE        0x20
# define DH_CHECK_INVALID_J_VALUE        0x40

/* DH_check_pub_key error codes */
# define DH_CHECK_PUBKEY_TOO_SMALL       0x01
# define DH_CHECK_PUBKEY_TOO_LARGE       0x02
# define DH_CHECK_PUBKEY_INVALID         0x04

/*
 * primes p where (p-1)/2 is prime too are called "safe"; we define this for
 * backward compatibility:
 */
# define DH_CHECK_P_NOT_STRONG_PRIME     DH_CHECK_P_NOT_SAFE_PRIME

# define d2i_DHparams_fp(fp,x) \
    (DH *)ASN1_d2i_fp((char *(*)())DH_new, \
                      (char *(*)())d2i_DHparams, \
                      (fp), \
                      (unsigned char **)(x))
# define i2d_DHparams_fp(fp,x) \
    ASN1_i2d_fp(i2d_DHparams,(fp), (unsigned char *)(x))
# define d2i_DHparams_bio(bp,x) \
    ASN1_d2i_bio_of(DH, DH_new, d2i_DHparams, bp, x)
# define i2d_DHparams_bio(bp,x) \
    ASN1_i2d_bio_of_const(DH,i2d_DHparams,bp,x)

# define d2i_DHxparams_fp(fp,x) \
    (DH *)ASN1_d2i_fp((char *(*)())DH_new, \
                      (char *(*)())d2i_DHxparams, \
                      (fp), \
                      (unsigned char **)(x))
# define i2d_DHxparams_fp(fp,x) \
    ASN1_i2d_fp(i2d_DHxparams,(fp), (unsigned char *)(x))
# define d2i_DHxparams_bio(bp,x) \
    ASN1_d2i_bio_of(DH, DH_new, d2i_DHxparams, bp, x)
# define i2d_DHxparams_bio(bp,x) \
    ASN1_i2d_bio_of_const(DH, i2d_DHxparams, bp, x)

DH *DHparams_dup(DH *);

const DH_METHOD *DH_OpenSSL(void);

void DH_set_default_method(const DH_METHOD *meth);
const DH_METHOD *DH_get_default_method(void);
int DH_set_method(DH *dh, const DH_METHOD *meth);
DH *DH_new_method(ENGINE *engine);

DH *DH_new(void);
void DH_free(DH *dh);
int DH_up_ref(DH *dh);
int DH_size(const DH *dh);
int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
                        CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
int DH_set_ex_data(DH *d, int idx, void *arg);
void *DH_get_ex_data(DH *d, int idx);

/* Deprecated version */
# ifndef OPENSSL_NO_DEPRECATED
DH *DH_generate_parameters(int prime_len, int generator,
                           void (*callback) (int, int, void *), void *cb_arg);
# endif                         /* !defined(OPENSSL_NO_DEPRECATED) */

/* New version */
int DH_generate_parameters_ex(DH *dh, int prime_len, int generator,
                              BN_GENCB *cb);

int DH_check(const DH *dh, int *codes);
int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *codes);
int DH_generate_key(DH *dh);
int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh);
int DH_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh);
DH *d2i_DHparams(DH **a, const unsigned char **pp, long length);
int i2d_DHparams(const DH *a, unsigned char **pp);
DH *d2i_DHxparams(DH **a, const unsigned char **pp, long length);
int i2d_DHxparams(const DH *a, unsigned char **pp);
# ifndef OPENSSL_NO_FP_API
int DHparams_print_fp(FILE *fp, const DH *x);
# endif
# ifndef OPENSSL_NO_BIO
int DHparams_print(BIO *bp, const DH *x);
# else
int DHparams_print(char *bp, const DH *x);
# endif

/* RFC 5114 parameters */
DH *DH_get_1024_160(void);
DH *DH_get_2048_224(void);
DH *DH_get_2048_256(void);

# ifndef OPENSSL_NO_CMS
/* RFC2631 KDF */
int DH_KDF_X9_42(unsigned char *out, size_t outlen,
                 const unsigned char *Z, size_t Zlen,
                 ASN1_OBJECT *key_oid,
                 const unsigned char *ukm, size_t ukmlen, const EVP_MD *md);
# endif

# define EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \
                        EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, len, NULL)

# define EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \
                        EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN, len, NULL)

# define EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \
                        EVP_PKEY_CTRL_DH_PARAMGEN_TYPE, typ, NULL)

# define EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, gen) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \
                        EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR, gen, NULL)

# define EVP_PKEY_CTX_set_dh_rfc5114(ctx, gen) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_PARAMGEN, \
                        EVP_PKEY_CTRL_DH_RFC5114, gen, NULL)

# define EVP_PKEY_CTX_set_dhx_rfc5114(ctx, gen) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_PARAMGEN, \
                        EVP_PKEY_CTRL_DH_RFC5114, gen, NULL)

# define EVP_PKEY_CTX_set_dh_kdf_type(ctx, kdf) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
                                EVP_PKEY_OP_DERIVE, \
                                EVP_PKEY_CTRL_DH_KDF_TYPE, kdf, NULL)

# define EVP_PKEY_CTX_get_dh_kdf_type(ctx) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
                                EVP_PKEY_OP_DERIVE, \
                                EVP_PKEY_CTRL_DH_KDF_TYPE, -2, NULL)

# define EVP_PKEY_CTX_set0_dh_kdf_oid(ctx, oid) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
                                EVP_PKEY_OP_DERIVE, \
                                EVP_PKEY_CTRL_DH_KDF_OID, 0, (void *)oid)

# define EVP_PKEY_CTX_get0_dh_kdf_oid(ctx, poid) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
                                EVP_PKEY_OP_DERIVE, \
                                EVP_PKEY_CTRL_GET_DH_KDF_OID, 0, (void *)poid)

# define EVP_PKEY_CTX_set_dh_kdf_md(ctx, md) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
                                EVP_PKEY_OP_DERIVE, \
                                EVP_PKEY_CTRL_DH_KDF_MD, 0, (void *)md)

# define EVP_PKEY_CTX_get_dh_kdf_md(ctx, pmd) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
                                EVP_PKEY_OP_DERIVE, \
                                EVP_PKEY_CTRL_GET_DH_KDF_MD, 0, (void *)pmd)

# define EVP_PKEY_CTX_set_dh_kdf_outlen(ctx, len) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
                                EVP_PKEY_OP_DERIVE, \
                                EVP_PKEY_CTRL_DH_KDF_OUTLEN, len, NULL)

# define EVP_PKEY_CTX_get_dh_kdf_outlen(ctx, plen) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
                                EVP_PKEY_OP_DERIVE, \
                        EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN, 0, (void *)plen)

# define EVP_PKEY_CTX_set0_dh_kdf_ukm(ctx, p, plen) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
                                EVP_PKEY_OP_DERIVE, \
                                EVP_PKEY_CTRL_DH_KDF_UKM, plen, (void *)p)

# define EVP_PKEY_CTX_get0_dh_kdf_ukm(ctx, p) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
                                EVP_PKEY_OP_DERIVE, \
                                EVP_PKEY_CTRL_GET_DH_KDF_UKM, 0, (void *)p)

# define EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN     (EVP_PKEY_ALG_CTRL + 1)
# define EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR     (EVP_PKEY_ALG_CTRL + 2)
# define EVP_PKEY_CTRL_DH_RFC5114                (EVP_PKEY_ALG_CTRL + 3)
# define EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN  (EVP_PKEY_ALG_CTRL + 4)
# define EVP_PKEY_CTRL_DH_PARAMGEN_TYPE          (EVP_PKEY_ALG_CTRL + 5)
# define EVP_PKEY_CTRL_DH_KDF_TYPE               (EVP_PKEY_ALG_CTRL + 6)
# define EVP_PKEY_CTRL_DH_KDF_MD                 (EVP_PKEY_ALG_CTRL + 7)
# define EVP_PKEY_CTRL_GET_DH_KDF_MD             (EVP_PKEY_ALG_CTRL + 8)
# define EVP_PKEY_CTRL_DH_KDF_OUTLEN             (EVP_PKEY_ALG_CTRL + 9)
# define EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN         (EVP_PKEY_ALG_CTRL + 10)
# define EVP_PKEY_CTRL_DH_KDF_UKM                (EVP_PKEY_ALG_CTRL + 11)
# define EVP_PKEY_CTRL_GET_DH_KDF_UKM            (EVP_PKEY_ALG_CTRL + 12)
# define EVP_PKEY_CTRL_DH_KDF_OID                (EVP_PKEY_ALG_CTRL + 13)
# define EVP_PKEY_CTRL_GET_DH_KDF_OID            (EVP_PKEY_ALG_CTRL + 14)

/* KDF types */
# define EVP_PKEY_DH_KDF_NONE                            1
# define EVP_PKEY_DH_KDF_X9_42                           2

/* BEGIN ERROR CODES */
/*
 * The following lines are auto generated by the script mkerr.pl. Any changes
 * made after this point may be overwritten when the script is next run.
 */
void ERR_load_DH_strings(void);

/* Error codes for the DH functions. */

/* Function codes. */
# define DH_F_COMPUTE_KEY                                 102
# define DH_F_DHPARAMS_PRINT_FP                           101
# define DH_F_DH_BUILTIN_GENPARAMS                        106
# define DH_F_DH_CMS_DECRYPT                              117
# define DH_F_DH_CMS_SET_PEERKEY                          118
# define DH_F_DH_CMS_SET_SHARED_INFO                      119
# define DH_F_DH_COMPUTE_KEY                              114
# define DH_F_DH_GENERATE_KEY                             115
# define DH_F_DH_GENERATE_PARAMETERS_EX                   116
# define DH_F_DH_NEW_METHOD                               105
# define DH_F_DH_PARAM_DECODE                             107
# define DH_F_DH_PRIV_DECODE                              110
# define DH_F_DH_PRIV_ENCODE                              111
# define DH_F_DH_PUB_DECODE                               108
# define DH_F_DH_PUB_ENCODE                               109
# define DH_F_DO_DH_PRINT                                 100
# define DH_F_GENERATE_KEY                                103
# define DH_F_GENERATE_PARAMETERS                         104
# define DH_F_PKEY_DH_DERIVE                              112
# define DH_F_PKEY_DH_KEYGEN                              113

/* Reason codes. */
# define DH_R_BAD_GENERATOR                               101
# define DH_R_BN_DECODE_ERROR                             109
# define DH_R_BN_ERROR                                    106
# define DH_R_DECODE_ERROR                                104
# define DH_R_INVALID_PUBKEY                              102
# define DH_R_KDF_PARAMETER_ERROR                         112
# define DH_R_KEYS_NOT_SET                                108
# define DH_R_KEY_SIZE_TOO_SMALL                          110
# define DH_R_MODULUS_TOO_LARGE                           103
# define DH_R_NON_FIPS_METHOD                             111
# define DH_R_NO_PARAMETERS_SET                           107
# define DH_R_NO_PRIVATE_VALUE                            100
# define DH_R_PARAMETER_ENCODING_ERROR                    105
# define DH_R_PEER_KEY_ERROR                              113
# define DH_R_SHARED_INFO_ERROR                           114

#ifdef  __cplusplus
}
#endif
#endif
openssl/fips_rand.h000064400000016160151733316550010362 0ustar00/* ====================================================================
 * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#ifndef HEADER_FIPS_RAND_H
# define HEADER_FIPS_RAND_H

# include <openssl/aes.h>
# include <openssl/evp.h>
# include <openssl/hmac.h>
# include <openssl/rand.h>

# ifdef OPENSSL_FIPS

#  ifdef  __cplusplus
extern "C" {
#  endif

    int FIPS_x931_set_key(const unsigned char *key, int keylen);
    int FIPS_x931_seed(const void *buf, int num);
    int FIPS_x931_bytes(unsigned char *out, int outlen);

    int FIPS_x931_test_mode(void);
    void FIPS_x931_reset(void);
    int FIPS_x931_set_dt(unsigned char *dt);

    int FIPS_x931_status(void);

    const RAND_METHOD *FIPS_x931_method(void);

    typedef struct drbg_ctx_st DRBG_CTX;
/* DRBG external flags */
/* Flag for CTR mode only: use derivation function ctr_df */
#  define DRBG_FLAG_CTR_USE_DF            0x1
/* PRNG is in test state */
#  define DRBG_FLAG_TEST                  0x2

    DRBG_CTX *FIPS_drbg_new(int type, unsigned int flags);
    int FIPS_drbg_init(DRBG_CTX *dctx, int type, unsigned int flags);
    int FIPS_drbg_instantiate(DRBG_CTX *dctx,
                              const unsigned char *pers, size_t perslen);
    int FIPS_drbg_reseed(DRBG_CTX *dctx, const unsigned char *adin,
                         size_t adinlen);
    int FIPS_drbg_generate(DRBG_CTX *dctx, unsigned char *out, size_t outlen,
                           int prediction_resistance,
                           const unsigned char *adin, size_t adinlen);

    int FIPS_drbg_uninstantiate(DRBG_CTX *dctx);
    void FIPS_drbg_free(DRBG_CTX *dctx);

    int FIPS_drbg_set_callbacks(DRBG_CTX *dctx,
                                size_t (*get_entropy) (DRBG_CTX *ctx,
                                                       unsigned char **pout,
                                                       int entropy,
                                                       size_t min_len,
                                                       size_t max_len),
                                void (*cleanup_entropy) (DRBG_CTX *ctx,
                                                         unsigned char *out,
                                                         size_t olen),
                                size_t entropy_blocklen,
                                size_t (*get_nonce) (DRBG_CTX *ctx,
                                                     unsigned char **pout,
                                                     int entropy,
                                                     size_t min_len,
                                                     size_t max_len),
                                void (*cleanup_nonce) (DRBG_CTX *ctx,
                                                       unsigned char *out,
                                                       size_t olen));

    int FIPS_drbg_set_rand_callbacks(DRBG_CTX *dctx,
                                     size_t (*get_adin) (DRBG_CTX *ctx,
                                                         unsigned char
                                                         **pout),
                                     void (*cleanup_adin) (DRBG_CTX *ctx,
                                                           unsigned char *out,
                                                           size_t olen),
                                     int (*rand_seed_cb) (DRBG_CTX *ctx,
                                                          const void *buf,
                                                          int num),
                                     int (*rand_add_cb) (DRBG_CTX *ctx,
                                                         const void *buf,
                                                         int num,
                                                         double entropy));

    void *FIPS_drbg_get_app_data(DRBG_CTX *ctx);
    void FIPS_drbg_set_app_data(DRBG_CTX *ctx, void *app_data);
    size_t FIPS_drbg_get_blocklength(DRBG_CTX *dctx);
    int FIPS_drbg_get_strength(DRBG_CTX *dctx);
    void FIPS_drbg_set_check_interval(DRBG_CTX *dctx, int interval);
    void FIPS_drbg_set_reseed_interval(DRBG_CTX *dctx, int interval);

    int FIPS_drbg_health_check(DRBG_CTX *dctx);

    DRBG_CTX *FIPS_get_default_drbg(void);
    const RAND_METHOD *FIPS_drbg_method(void);

    int FIPS_rand_set_method(const RAND_METHOD *meth);
    const RAND_METHOD *FIPS_rand_get_method(void);

    void FIPS_rand_set_bits(int nbits);

    int FIPS_rand_strength(void);

/* 1.0.0 compat functions */
    int FIPS_rand_set_key(const unsigned char *key, FIPS_RAND_SIZE_T keylen);
    int FIPS_rand_seed(const void *buf, FIPS_RAND_SIZE_T num);
    int FIPS_rand_bytes(unsigned char *out, FIPS_RAND_SIZE_T outlen);
    int FIPS_rand_test_mode(void);
    void FIPS_rand_reset(void);
    int FIPS_rand_set_dt(unsigned char *dt);
    int FIPS_rand_status(void);
    const RAND_METHOD *FIPS_rand_method(void);

#  ifdef  __cplusplus
}
#  endif
# endif
#endif
openssl/des.h000064400000026762151733316550007201 0ustar00/* crypto/des/des.h */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#ifndef HEADER_NEW_DES_H
# define HEADER_NEW_DES_H

# include <openssl/e_os2.h>     /* OPENSSL_EXTERN, OPENSSL_NO_DES, DES_LONG
                                 * (via openssl/opensslconf.h */

# ifdef OPENSSL_NO_DES
#  error DES is disabled.
# endif

# ifdef OPENSSL_BUILD_SHLIBCRYPTO
#  undef OPENSSL_EXTERN
#  define OPENSSL_EXTERN OPENSSL_EXPORT
# endif

#ifdef  __cplusplus
extern "C" {
#endif

typedef unsigned char DES_cblock[8];
typedef /* const */ unsigned char const_DES_cblock[8];
/*
 * With "const", gcc 2.8.1 on Solaris thinks that DES_cblock * and
 * const_DES_cblock * are incompatible pointer types.
 */

typedef struct DES_ks {
    union {
        DES_cblock cblock;
        /*
         * make sure things are correct size on machines with 8 byte longs
         */
        DES_LONG deslong[2];
    } ks[16];
} DES_key_schedule;

# ifndef OPENSSL_DISABLE_OLD_DES_SUPPORT
#  ifndef OPENSSL_ENABLE_OLD_DES_SUPPORT
#   define OPENSSL_ENABLE_OLD_DES_SUPPORT
#  endif
# endif

# ifdef OPENSSL_ENABLE_OLD_DES_SUPPORT
#  include <openssl/des_old.h>
# endif

# define DES_KEY_SZ      (sizeof(DES_cblock))
# define DES_SCHEDULE_SZ (sizeof(DES_key_schedule))

# define DES_ENCRYPT     1
# define DES_DECRYPT     0

# define DES_CBC_MODE    0
# define DES_PCBC_MODE   1

# define DES_ecb2_encrypt(i,o,k1,k2,e) \
        DES_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))

# define DES_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
        DES_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))

# define DES_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
        DES_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))

# define DES_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
        DES_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))

OPENSSL_DECLARE_GLOBAL(int, DES_check_key); /* defaults to false */
# define DES_check_key OPENSSL_GLOBAL_REF(DES_check_key)
OPENSSL_DECLARE_GLOBAL(int, DES_rw_mode); /* defaults to DES_PCBC_MODE */
# define DES_rw_mode OPENSSL_GLOBAL_REF(DES_rw_mode)

const char *DES_options(void);
void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output,
                      DES_key_schedule *ks1, DES_key_schedule *ks2,
                      DES_key_schedule *ks3, int enc);
DES_LONG DES_cbc_cksum(const unsigned char *input, DES_cblock *output,
                       long length, DES_key_schedule *schedule,
                       const_DES_cblock *ivec);
/* DES_cbc_encrypt does not update the IV!  Use DES_ncbc_encrypt instead. */
void DES_cbc_encrypt(const unsigned char *input, unsigned char *output,
                     long length, DES_key_schedule *schedule,
                     DES_cblock *ivec, int enc);
void DES_ncbc_encrypt(const unsigned char *input, unsigned char *output,
                      long length, DES_key_schedule *schedule,
                      DES_cblock *ivec, int enc);
void DES_xcbc_encrypt(const unsigned char *input, unsigned char *output,
                      long length, DES_key_schedule *schedule,
                      DES_cblock *ivec, const_DES_cblock *inw,
                      const_DES_cblock *outw, int enc);
void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits,
                     long length, DES_key_schedule *schedule,
                     DES_cblock *ivec, int enc);
void DES_ecb_encrypt(const_DES_cblock *input, DES_cblock *output,
                     DES_key_schedule *ks, int enc);

/*
 * This is the DES encryption function that gets called by just about every
 * other DES routine in the library.  You should not use this function except
 * to implement 'modes' of DES.  I say this because the functions that call
 * this routine do the conversion from 'char *' to long, and this needs to be
 * done to make sure 'non-aligned' memory access do not occur.  The
 * characters are loaded 'little endian'. Data is a pointer to 2 unsigned
 * long's and ks is the DES_key_schedule to use.  enc, is non zero specifies
 * encryption, zero if decryption.
 */
void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc);

/*
 * This functions is the same as DES_encrypt1() except that the DES initial
 * permutation (IP) and final permutation (FP) have been left out.  As for
 * DES_encrypt1(), you should not use this function. It is used by the
 * routines in the library that implement triple DES. IP() DES_encrypt2()
 * DES_encrypt2() DES_encrypt2() FP() is the same as DES_encrypt1()
 * DES_encrypt1() DES_encrypt1() except faster :-).
 */
void DES_encrypt2(DES_LONG *data, DES_key_schedule *ks, int enc);

void DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1,
                  DES_key_schedule *ks2, DES_key_schedule *ks3);
void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1,
                  DES_key_schedule *ks2, DES_key_schedule *ks3);
void DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output,
                          long length,
                          DES_key_schedule *ks1, DES_key_schedule *ks2,
                          DES_key_schedule *ks3, DES_cblock *ivec, int enc);
void DES_ede3_cbcm_encrypt(const unsigned char *in, unsigned char *out,
                           long length,
                           DES_key_schedule *ks1, DES_key_schedule *ks2,
                           DES_key_schedule *ks3,
                           DES_cblock *ivec1, DES_cblock *ivec2, int enc);
void DES_ede3_cfb64_encrypt(const unsigned char *in, unsigned char *out,
                            long length, DES_key_schedule *ks1,
                            DES_key_schedule *ks2, DES_key_schedule *ks3,
                            DES_cblock *ivec, int *num, int enc);
void DES_ede3_cfb_encrypt(const unsigned char *in, unsigned char *out,
                          int numbits, long length, DES_key_schedule *ks1,
                          DES_key_schedule *ks2, DES_key_schedule *ks3,
                          DES_cblock *ivec, int enc);
void DES_ede3_ofb64_encrypt(const unsigned char *in, unsigned char *out,
                            long length, DES_key_schedule *ks1,
                            DES_key_schedule *ks2, DES_key_schedule *ks3,
                            DES_cblock *ivec, int *num);
# if 0
void DES_xwhite_in2out(const_DES_cblock *DES_key, const_DES_cblock *in_white,
                       DES_cblock *out_white);
# endif

int DES_enc_read(int fd, void *buf, int len, DES_key_schedule *sched,
                 DES_cblock *iv);
int DES_enc_write(int fd, const void *buf, int len, DES_key_schedule *sched,
                  DES_cblock *iv);
char *DES_fcrypt(const char *buf, const char *salt, char *ret);
char *DES_crypt(const char *buf, const char *salt);
void DES_ofb_encrypt(const unsigned char *in, unsigned char *out, int numbits,
                     long length, DES_key_schedule *schedule,
                     DES_cblock *ivec);
void DES_pcbc_encrypt(const unsigned char *input, unsigned char *output,
                      long length, DES_key_schedule *schedule,
                      DES_cblock *ivec, int enc);
DES_LONG DES_quad_cksum(const unsigned char *input, DES_cblock output[],
                        long length, int out_count, DES_cblock *seed);
int DES_random_key(DES_cblock *ret);
void DES_set_odd_parity(DES_cblock *key);
int DES_check_key_parity(const_DES_cblock *key);
int DES_is_weak_key(const_DES_cblock *key);
/*
 * DES_set_key (= set_key = DES_key_sched = key_sched) calls
 * DES_set_key_checked if global variable DES_check_key is set,
 * DES_set_key_unchecked otherwise.
 */
int DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule);
int DES_key_sched(const_DES_cblock *key, DES_key_schedule *schedule);
int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule);
void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule);
void DES_string_to_key(const char *str, DES_cblock *key);
void DES_string_to_2keys(const char *str, DES_cblock *key1, DES_cblock *key2);
void DES_cfb64_encrypt(const unsigned char *in, unsigned char *out,
                       long length, DES_key_schedule *schedule,
                       DES_cblock *ivec, int *num, int enc);
void DES_ofb64_encrypt(const unsigned char *in, unsigned char *out,
                       long length, DES_key_schedule *schedule,
                       DES_cblock *ivec, int *num);

int DES_read_password(DES_cblock *key, const char *prompt, int verify);
int DES_read_2passwords(DES_cblock *key1, DES_cblock *key2,
                        const char *prompt, int verify);

# define DES_fixup_key_parity DES_set_odd_parity

#ifdef  __cplusplus
}
#endif

#endif
openssl/dtls1.h000064400000021526151733316550007446 0ustar00/* ssl/dtls1.h */
/*
 * DTLS implementation written by Nagendra Modadugu
 * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
 */
/* ====================================================================
 * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#ifndef HEADER_DTLS1_H
# define HEADER_DTLS1_H

# include <openssl/buffer.h>
# include <openssl/pqueue.h>
# ifdef OPENSSL_SYS_VMS
#  include <resource.h>
#  include <sys/timeb.h>
# endif
# ifdef OPENSSL_SYS_WIN32
/* Needed for struct timeval */
#  include <winsock.h>
# elif defined(OPENSSL_SYS_NETWARE) && !defined(_WINSOCK2API_)
#  include <sys/timeval.h>
# else
#  if defined(OPENSSL_SYS_VXWORKS)
#   include <sys/times.h>
#  else
#   include <sys/time.h>
#  endif
# endif

#ifdef  __cplusplus
extern "C" {
#endif

# define DTLS1_VERSION                   0xFEFF
# define DTLS1_2_VERSION                 0xFEFD
# define DTLS_MAX_VERSION                DTLS1_2_VERSION
# define DTLS1_VERSION_MAJOR             0xFE

# define DTLS1_BAD_VER                   0x0100

/* Special value for method supporting multiple versions */
# define DTLS_ANY_VERSION                0x1FFFF

# if 0
/* this alert description is not specified anywhere... */
#  define DTLS1_AD_MISSING_HANDSHAKE_MESSAGE    110
# endif

/* lengths of messages */
# define DTLS1_COOKIE_LENGTH                     256

# define DTLS1_RT_HEADER_LENGTH                  13

# define DTLS1_HM_HEADER_LENGTH                  12

# define DTLS1_HM_BAD_FRAGMENT                   -2
# define DTLS1_HM_FRAGMENT_RETRY                 -3

# define DTLS1_CCS_HEADER_LENGTH                  1

# ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
#  define DTLS1_AL_HEADER_LENGTH                   7
# else
#  define DTLS1_AL_HEADER_LENGTH                   2
# endif

# ifndef OPENSSL_NO_SSL_INTERN

#  ifndef OPENSSL_NO_SCTP
#   define DTLS1_SCTP_AUTH_LABEL   "EXPORTER_DTLS_OVER_SCTP"
#  endif

/* Max MTU overhead we know about so far is 40 for IPv6 + 8 for UDP */
#  define DTLS1_MAX_MTU_OVERHEAD                   48

typedef struct dtls1_bitmap_st {
    unsigned long map;          /* track 32 packets on 32-bit systems and 64
                                 * - on 64-bit systems */
    unsigned char max_seq_num[8]; /* max record number seen so far, 64-bit
                                   * value in big-endian encoding */
} DTLS1_BITMAP;

struct dtls1_retransmit_state {
    EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */
    EVP_MD_CTX *write_hash;     /* used for mac generation */
#  ifndef OPENSSL_NO_COMP
    COMP_CTX *compress;         /* compression */
#  else
    char *compress;
#  endif
    SSL_SESSION *session;
    unsigned short epoch;
};

struct hm_header_st {
    unsigned char type;
    unsigned long msg_len;
    unsigned short seq;
    unsigned long frag_off;
    unsigned long frag_len;
    unsigned int is_ccs;
    struct dtls1_retransmit_state saved_retransmit_state;
};

struct ccs_header_st {
    unsigned char type;
    unsigned short seq;
};

struct dtls1_timeout_st {
    /* Number of read timeouts so far */
    unsigned int read_timeouts;
    /* Number of write timeouts so far */
    unsigned int write_timeouts;
    /* Number of alerts received so far */
    unsigned int num_alerts;
};

typedef struct record_pqueue_st {
    unsigned short epoch;
    pqueue q;
} record_pqueue;

typedef struct hm_fragment_st {
    struct hm_header_st msg_header;
    unsigned char *fragment;
    unsigned char *reassembly;
} hm_fragment;

typedef struct dtls1_state_st {
    unsigned int send_cookie;
    unsigned char cookie[DTLS1_COOKIE_LENGTH];
    unsigned char rcvd_cookie[DTLS1_COOKIE_LENGTH];
    unsigned int cookie_len;
    /*
     * The current data and handshake epoch.  This is initially
     * undefined, and starts at zero once the initial handshake is
     * completed
     */
    unsigned short r_epoch;
    unsigned short w_epoch;
    /* records being received in the current epoch */
    DTLS1_BITMAP bitmap;
    /* renegotiation starts a new set of sequence numbers */
    DTLS1_BITMAP next_bitmap;
    /* handshake message numbers */
    unsigned short handshake_write_seq;
    unsigned short next_handshake_write_seq;
    unsigned short handshake_read_seq;
    /* save last sequence number for retransmissions */
    unsigned char last_write_sequence[8];
    /* Received handshake records (processed and unprocessed) */
    record_pqueue unprocessed_rcds;
    record_pqueue processed_rcds;
    /* Buffered handshake messages */
    pqueue buffered_messages;
    /* Buffered (sent) handshake records */
    pqueue sent_messages;
    /*
     * Buffered application records. Only for records between CCS and
     * Finished to prevent either protocol violation or unnecessary message
     * loss.
     */
    record_pqueue buffered_app_data;
    unsigned int mtu;           /* max DTLS packet size */
    struct hm_header_st w_msg_hdr;
    struct hm_header_st r_msg_hdr;
    struct dtls1_timeout_st timeout;
    /*
     * Indicates when the last handshake msg or heartbeat sent will timeout
     */
    struct timeval next_timeout;
    /* Timeout duration */
    unsigned short timeout_duration;
    /*
     * storage for Alert/Handshake protocol data received but not yet
     * processed by ssl3_read_bytes:
     */
    unsigned char alert_fragment[DTLS1_AL_HEADER_LENGTH];
    unsigned int alert_fragment_len;
    unsigned char handshake_fragment[DTLS1_HM_HEADER_LENGTH];
    unsigned int handshake_fragment_len;
    unsigned int retransmitting;
    /*
     * Set when the handshake is ready to process peer's ChangeCipherSpec message.
     * Cleared after the message has been processed.
     */
    unsigned int change_cipher_spec_ok;
    /* Is set when listening for new connections with dtls1_listen() */
    unsigned int listen;
    unsigned int link_mtu;      /* max on-the-wire DTLS packet size */
#  ifndef OPENSSL_NO_SCTP
    /* used when SSL_ST_XX_FLUSH is entered */
    int next_state;
    int shutdown_received;
#  endif
} DTLS1_STATE;

typedef struct dtls1_record_data_st {
    unsigned char *packet;
    unsigned int packet_length;
    SSL3_BUFFER rbuf;
    SSL3_RECORD rrec;
#  ifndef OPENSSL_NO_SCTP
    struct bio_dgram_sctp_rcvinfo recordinfo;
#  endif
} DTLS1_RECORD_DATA;

# endif

/* Timeout multipliers (timeout slice is defined in apps/timeouts.h */
# define DTLS1_TMO_READ_COUNT                      2
# define DTLS1_TMO_WRITE_COUNT                     2

# define DTLS1_TMO_ALERT_COUNT                     12

#ifdef  __cplusplus
}
#endif
#endif
openssl/ssl3.h000064400000101001151733316550007266 0ustar00/* ssl/ssl3.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */
/* ====================================================================
 * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */
/* ====================================================================
 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
 * ECC cipher suite support in OpenSSL originally developed by
 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
 */

#ifndef HEADER_SSL3_H
# define HEADER_SSL3_H

# ifndef OPENSSL_NO_COMP
#  include <openssl/comp.h>
# endif
# include <openssl/buffer.h>
# include <openssl/evp.h>
# include <openssl/ssl.h>

#ifdef  __cplusplus
extern "C" {
#endif

/*
 * Signalling cipher suite value from RFC 5746
 * (TLS_EMPTY_RENEGOTIATION_INFO_SCSV)
 */
# define SSL3_CK_SCSV                            0x030000FF

/*
 * Signalling cipher suite value from draft-ietf-tls-downgrade-scsv-00
 * (TLS_FALLBACK_SCSV)
 */
# define SSL3_CK_FALLBACK_SCSV                   0x03005600

# define SSL3_CK_RSA_NULL_MD5                    0x03000001
# define SSL3_CK_RSA_NULL_SHA                    0x03000002
# define SSL3_CK_RSA_RC4_40_MD5                  0x03000003
# define SSL3_CK_RSA_RC4_128_MD5                 0x03000004
# define SSL3_CK_RSA_RC4_128_SHA                 0x03000005
# define SSL3_CK_RSA_RC2_40_MD5                  0x03000006
# define SSL3_CK_RSA_IDEA_128_SHA                0x03000007
# define SSL3_CK_RSA_DES_40_CBC_SHA              0x03000008
# define SSL3_CK_RSA_DES_64_CBC_SHA              0x03000009
# define SSL3_CK_RSA_DES_192_CBC3_SHA            0x0300000A

# define SSL3_CK_DH_DSS_DES_40_CBC_SHA           0x0300000B
# define SSL3_CK_DH_DSS_DES_64_CBC_SHA           0x0300000C
# define SSL3_CK_DH_DSS_DES_192_CBC3_SHA         0x0300000D
# define SSL3_CK_DH_RSA_DES_40_CBC_SHA           0x0300000E
# define SSL3_CK_DH_RSA_DES_64_CBC_SHA           0x0300000F
# define SSL3_CK_DH_RSA_DES_192_CBC3_SHA         0x03000010

# define SSL3_CK_EDH_DSS_DES_40_CBC_SHA          0x03000011
# define SSL3_CK_DHE_DSS_DES_40_CBC_SHA          SSL3_CK_EDH_DSS_DES_40_CBC_SHA
# define SSL3_CK_EDH_DSS_DES_64_CBC_SHA          0x03000012
# define SSL3_CK_DHE_DSS_DES_64_CBC_SHA          SSL3_CK_EDH_DSS_DES_64_CBC_SHA
# define SSL3_CK_EDH_DSS_DES_192_CBC3_SHA        0x03000013
# define SSL3_CK_DHE_DSS_DES_192_CBC3_SHA        SSL3_CK_EDH_DSS_DES_192_CBC3_SHA
# define SSL3_CK_EDH_RSA_DES_40_CBC_SHA          0x03000014
# define SSL3_CK_DHE_RSA_DES_40_CBC_SHA          SSL3_CK_EDH_RSA_DES_40_CBC_SHA
# define SSL3_CK_EDH_RSA_DES_64_CBC_SHA          0x03000015
# define SSL3_CK_DHE_RSA_DES_64_CBC_SHA          SSL3_CK_EDH_RSA_DES_64_CBC_SHA
# define SSL3_CK_EDH_RSA_DES_192_CBC3_SHA        0x03000016
# define SSL3_CK_DHE_RSA_DES_192_CBC3_SHA        SSL3_CK_EDH_RSA_DES_192_CBC3_SHA

# define SSL3_CK_ADH_RC4_40_MD5                  0x03000017
# define SSL3_CK_ADH_RC4_128_MD5                 0x03000018
# define SSL3_CK_ADH_DES_40_CBC_SHA              0x03000019
# define SSL3_CK_ADH_DES_64_CBC_SHA              0x0300001A
# define SSL3_CK_ADH_DES_192_CBC_SHA             0x0300001B

# if 0
#  define SSL3_CK_FZA_DMS_NULL_SHA                0x0300001C
#  define SSL3_CK_FZA_DMS_FZA_SHA                 0x0300001D
#  if 0                         /* Because it clashes with KRB5, is never
                                 * used any more, and is safe to remove
                                 * according to David Hopwood
                                 * <david.hopwood@zetnet.co.uk> of the
                                 * ietf-tls list */
#   define SSL3_CK_FZA_DMS_RC4_SHA                 0x0300001E
#  endif
# endif

/*
 * VRS Additional Kerberos5 entries
 */
# define SSL3_CK_KRB5_DES_64_CBC_SHA             0x0300001E
# define SSL3_CK_KRB5_DES_192_CBC3_SHA           0x0300001F
# define SSL3_CK_KRB5_RC4_128_SHA                0x03000020
# define SSL3_CK_KRB5_IDEA_128_CBC_SHA           0x03000021
# define SSL3_CK_KRB5_DES_64_CBC_MD5             0x03000022
# define SSL3_CK_KRB5_DES_192_CBC3_MD5           0x03000023
# define SSL3_CK_KRB5_RC4_128_MD5                0x03000024
# define SSL3_CK_KRB5_IDEA_128_CBC_MD5           0x03000025

# define SSL3_CK_KRB5_DES_40_CBC_SHA             0x03000026
# define SSL3_CK_KRB5_RC2_40_CBC_SHA             0x03000027
# define SSL3_CK_KRB5_RC4_40_SHA                 0x03000028
# define SSL3_CK_KRB5_DES_40_CBC_MD5             0x03000029
# define SSL3_CK_KRB5_RC2_40_CBC_MD5             0x0300002A
# define SSL3_CK_KRB5_RC4_40_MD5                 0x0300002B

# define SSL3_TXT_RSA_NULL_MD5                   "NULL-MD5"
# define SSL3_TXT_RSA_NULL_SHA                   "NULL-SHA"
# define SSL3_TXT_RSA_RC4_40_MD5                 "EXP-RC4-MD5"
# define SSL3_TXT_RSA_RC4_128_MD5                "RC4-MD5"
# define SSL3_TXT_RSA_RC4_128_SHA                "RC4-SHA"
# define SSL3_TXT_RSA_RC2_40_MD5                 "EXP-RC2-CBC-MD5"
# define SSL3_TXT_RSA_IDEA_128_SHA               "IDEA-CBC-SHA"
# define SSL3_TXT_RSA_DES_40_CBC_SHA             "EXP-DES-CBC-SHA"
# define SSL3_TXT_RSA_DES_64_CBC_SHA             "DES-CBC-SHA"
# define SSL3_TXT_RSA_DES_192_CBC3_SHA           "DES-CBC3-SHA"

# define SSL3_TXT_DH_DSS_DES_40_CBC_SHA          "EXP-DH-DSS-DES-CBC-SHA"
# define SSL3_TXT_DH_DSS_DES_64_CBC_SHA          "DH-DSS-DES-CBC-SHA"
# define SSL3_TXT_DH_DSS_DES_192_CBC3_SHA        "DH-DSS-DES-CBC3-SHA"
# define SSL3_TXT_DH_RSA_DES_40_CBC_SHA          "EXP-DH-RSA-DES-CBC-SHA"
# define SSL3_TXT_DH_RSA_DES_64_CBC_SHA          "DH-RSA-DES-CBC-SHA"
# define SSL3_TXT_DH_RSA_DES_192_CBC3_SHA        "DH-RSA-DES-CBC3-SHA"

# define SSL3_TXT_DHE_DSS_DES_40_CBC_SHA         "EXP-DHE-DSS-DES-CBC-SHA"
# define SSL3_TXT_DHE_DSS_DES_64_CBC_SHA         "DHE-DSS-DES-CBC-SHA"
# define SSL3_TXT_DHE_DSS_DES_192_CBC3_SHA       "DHE-DSS-DES-CBC3-SHA"
# define SSL3_TXT_DHE_RSA_DES_40_CBC_SHA         "EXP-DHE-RSA-DES-CBC-SHA"
# define SSL3_TXT_DHE_RSA_DES_64_CBC_SHA         "DHE-RSA-DES-CBC-SHA"
# define SSL3_TXT_DHE_RSA_DES_192_CBC3_SHA       "DHE-RSA-DES-CBC3-SHA"

/*
 * This next block of six "EDH" labels is for backward compatibility with
 * older versions of OpenSSL.  New code should use the six "DHE" labels above
 * instead:
 */
# define SSL3_TXT_EDH_DSS_DES_40_CBC_SHA         "EXP-EDH-DSS-DES-CBC-SHA"
# define SSL3_TXT_EDH_DSS_DES_64_CBC_SHA         "EDH-DSS-DES-CBC-SHA"
# define SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA       "EDH-DSS-DES-CBC3-SHA"
# define SSL3_TXT_EDH_RSA_DES_40_CBC_SHA         "EXP-EDH-RSA-DES-CBC-SHA"
# define SSL3_TXT_EDH_RSA_DES_64_CBC_SHA         "EDH-RSA-DES-CBC-SHA"
# define SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA       "EDH-RSA-DES-CBC3-SHA"

# define SSL3_TXT_ADH_RC4_40_MD5                 "EXP-ADH-RC4-MD5"
# define SSL3_TXT_ADH_RC4_128_MD5                "ADH-RC4-MD5"
# define SSL3_TXT_ADH_DES_40_CBC_SHA             "EXP-ADH-DES-CBC-SHA"
# define SSL3_TXT_ADH_DES_64_CBC_SHA             "ADH-DES-CBC-SHA"
# define SSL3_TXT_ADH_DES_192_CBC_SHA            "ADH-DES-CBC3-SHA"

# if 0
#  define SSL3_TXT_FZA_DMS_NULL_SHA               "FZA-NULL-SHA"
#  define SSL3_TXT_FZA_DMS_FZA_SHA                "FZA-FZA-CBC-SHA"
#  define SSL3_TXT_FZA_DMS_RC4_SHA                "FZA-RC4-SHA"
# endif

# define SSL3_TXT_KRB5_DES_64_CBC_SHA            "KRB5-DES-CBC-SHA"
# define SSL3_TXT_KRB5_DES_192_CBC3_SHA          "KRB5-DES-CBC3-SHA"
# define SSL3_TXT_KRB5_RC4_128_SHA               "KRB5-RC4-SHA"
# define SSL3_TXT_KRB5_IDEA_128_CBC_SHA          "KRB5-IDEA-CBC-SHA"
# define SSL3_TXT_KRB5_DES_64_CBC_MD5            "KRB5-DES-CBC-MD5"
# define SSL3_TXT_KRB5_DES_192_CBC3_MD5          "KRB5-DES-CBC3-MD5"
# define SSL3_TXT_KRB5_RC4_128_MD5               "KRB5-RC4-MD5"
# define SSL3_TXT_KRB5_IDEA_128_CBC_MD5          "KRB5-IDEA-CBC-MD5"

# define SSL3_TXT_KRB5_DES_40_CBC_SHA            "EXP-KRB5-DES-CBC-SHA"
# define SSL3_TXT_KRB5_RC2_40_CBC_SHA            "EXP-KRB5-RC2-CBC-SHA"
# define SSL3_TXT_KRB5_RC4_40_SHA                "EXP-KRB5-RC4-SHA"
# define SSL3_TXT_KRB5_DES_40_CBC_MD5            "EXP-KRB5-DES-CBC-MD5"
# define SSL3_TXT_KRB5_RC2_40_CBC_MD5            "EXP-KRB5-RC2-CBC-MD5"
# define SSL3_TXT_KRB5_RC4_40_MD5                "EXP-KRB5-RC4-MD5"

# define SSL3_SSL_SESSION_ID_LENGTH              32
# define SSL3_MAX_SSL_SESSION_ID_LENGTH          32

# define SSL3_MASTER_SECRET_SIZE                 48
# define SSL3_RANDOM_SIZE                        32
# define SSL3_SESSION_ID_SIZE                    32
# define SSL3_RT_HEADER_LENGTH                   5

# define SSL3_HM_HEADER_LENGTH                  4

# ifndef SSL3_ALIGN_PAYLOAD
 /*
  * Some will argue that this increases memory footprint, but it's not
  * actually true. Point is that malloc has to return at least 64-bit aligned
  * pointers, meaning that allocating 5 bytes wastes 3 bytes in either case.
  * Suggested pre-gaping simply moves these wasted bytes from the end of
  * allocated region to its front, but makes data payload aligned, which
  * improves performance:-)
  */
#  define SSL3_ALIGN_PAYLOAD                     8
# else
#  if (SSL3_ALIGN_PAYLOAD&(SSL3_ALIGN_PAYLOAD-1))!=0
#   error "insane SSL3_ALIGN_PAYLOAD"
#   undef SSL3_ALIGN_PAYLOAD
#  endif
# endif

/*
 * This is the maximum MAC (digest) size used by the SSL library. Currently
 * maximum of 20 is used by SHA1, but we reserve for future extension for
 * 512-bit hashes.
 */

# define SSL3_RT_MAX_MD_SIZE                     64

/*
 * Maximum block size used in all ciphersuites. Currently 16 for AES.
 */

# define SSL_RT_MAX_CIPHER_BLOCK_SIZE            16

# define SSL3_RT_MAX_EXTRA                       (16384)

/* Maximum plaintext length: defined by SSL/TLS standards */
# define SSL3_RT_MAX_PLAIN_LENGTH                16384
/* Maximum compression overhead: defined by SSL/TLS standards */
# define SSL3_RT_MAX_COMPRESSED_OVERHEAD         1024

/*
 * The standards give a maximum encryption overhead of 1024 bytes. In
 * practice the value is lower than this. The overhead is the maximum number
 * of padding bytes (256) plus the mac size.
 */
# define SSL3_RT_MAX_ENCRYPTED_OVERHEAD  (256 + SSL3_RT_MAX_MD_SIZE)

/*
 * OpenSSL currently only uses a padding length of at most one block so the
 * send overhead is smaller.
 */

# define SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \
                        (SSL_RT_MAX_CIPHER_BLOCK_SIZE + SSL3_RT_MAX_MD_SIZE)

/* If compression isn't used don't include the compression overhead */

# ifdef OPENSSL_NO_COMP
#  define SSL3_RT_MAX_COMPRESSED_LENGTH           SSL3_RT_MAX_PLAIN_LENGTH
# else
#  define SSL3_RT_MAX_COMPRESSED_LENGTH   \
                (SSL3_RT_MAX_PLAIN_LENGTH+SSL3_RT_MAX_COMPRESSED_OVERHEAD)
# endif
# define SSL3_RT_MAX_ENCRYPTED_LENGTH    \
                (SSL3_RT_MAX_ENCRYPTED_OVERHEAD+SSL3_RT_MAX_COMPRESSED_LENGTH)
# define SSL3_RT_MAX_PACKET_SIZE         \
                (SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH)

# define SSL3_MD_CLIENT_FINISHED_CONST   "\x43\x4C\x4E\x54"
# define SSL3_MD_SERVER_FINISHED_CONST   "\x53\x52\x56\x52"

# define SSL3_VERSION                    0x0300
# define SSL3_VERSION_MAJOR              0x03
# define SSL3_VERSION_MINOR              0x00

# define SSL3_RT_CHANGE_CIPHER_SPEC      20
# define SSL3_RT_ALERT                   21
# define SSL3_RT_HANDSHAKE               22
# define SSL3_RT_APPLICATION_DATA        23
# define TLS1_RT_HEARTBEAT               24

/* Pseudo content types to indicate additional parameters */
# define TLS1_RT_CRYPTO                  0x1000
# define TLS1_RT_CRYPTO_PREMASTER        (TLS1_RT_CRYPTO | 0x1)
# define TLS1_RT_CRYPTO_CLIENT_RANDOM    (TLS1_RT_CRYPTO | 0x2)
# define TLS1_RT_CRYPTO_SERVER_RANDOM    (TLS1_RT_CRYPTO | 0x3)
# define TLS1_RT_CRYPTO_MASTER           (TLS1_RT_CRYPTO | 0x4)

# define TLS1_RT_CRYPTO_READ             0x0000
# define TLS1_RT_CRYPTO_WRITE            0x0100
# define TLS1_RT_CRYPTO_MAC              (TLS1_RT_CRYPTO | 0x5)
# define TLS1_RT_CRYPTO_KEY              (TLS1_RT_CRYPTO | 0x6)
# define TLS1_RT_CRYPTO_IV               (TLS1_RT_CRYPTO | 0x7)
# define TLS1_RT_CRYPTO_FIXED_IV         (TLS1_RT_CRYPTO | 0x8)

/* Pseudo content type for SSL/TLS header info */
# define SSL3_RT_HEADER                  0x100

# define SSL3_AL_WARNING                 1
# define SSL3_AL_FATAL                   2

# define SSL3_AD_CLOSE_NOTIFY             0
# define SSL3_AD_UNEXPECTED_MESSAGE      10/* fatal */
# define SSL3_AD_BAD_RECORD_MAC          20/* fatal */
# define SSL3_AD_DECOMPRESSION_FAILURE   30/* fatal */
# define SSL3_AD_HANDSHAKE_FAILURE       40/* fatal */
# define SSL3_AD_NO_CERTIFICATE          41
# define SSL3_AD_BAD_CERTIFICATE         42
# define SSL3_AD_UNSUPPORTED_CERTIFICATE 43
# define SSL3_AD_CERTIFICATE_REVOKED     44
# define SSL3_AD_CERTIFICATE_EXPIRED     45
# define SSL3_AD_CERTIFICATE_UNKNOWN     46
# define SSL3_AD_ILLEGAL_PARAMETER       47/* fatal */

# define TLS1_HB_REQUEST         1
# define TLS1_HB_RESPONSE        2

# ifndef OPENSSL_NO_SSL_INTERN

typedef struct ssl3_record_st {
    /* type of record */
    /*
     * r
     */ int type;
    /* How many bytes available */
    /*
     * rw
     */ unsigned int length;
    /* read/write offset into 'buf' */
    /*
     * r
     */ unsigned int off;
    /* pointer to the record data */
    /*
     * rw
     */ unsigned char *data;
    /* where the decode bytes are */
    /*
     * rw
     */ unsigned char *input;
    /* only used with decompression - malloc()ed */
    /*
     * r
     */ unsigned char *comp;
    /* epoch number, needed by DTLS1 */
    /*
     * r
     */ unsigned long epoch;
    /* sequence number, needed by DTLS1 */
    /*
     * r
     */ unsigned char seq_num[8];
} SSL3_RECORD;

typedef struct ssl3_buffer_st {
    /* at least SSL3_RT_MAX_PACKET_SIZE bytes, see ssl3_setup_buffers() */
    unsigned char *buf;
    /* buffer size */
    size_t len;
    /* where to 'copy from' */
    int offset;
    /* how many bytes left */
    int left;
} SSL3_BUFFER;

# endif

# define SSL3_CT_RSA_SIGN                        1
# define SSL3_CT_DSS_SIGN                        2
# define SSL3_CT_RSA_FIXED_DH                    3
# define SSL3_CT_DSS_FIXED_DH                    4
# define SSL3_CT_RSA_EPHEMERAL_DH                5
# define SSL3_CT_DSS_EPHEMERAL_DH                6
# define SSL3_CT_FORTEZZA_DMS                    20
/*
 * SSL3_CT_NUMBER is used to size arrays and it must be large enough to
 * contain all of the cert types defined either for SSLv3 and TLSv1.
 */
# define SSL3_CT_NUMBER                  9

# define SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS       0x0001
# define SSL3_FLAGS_DELAY_CLIENT_FINISHED        0x0002
# define SSL3_FLAGS_POP_BUFFER                   0x0004
# define TLS1_FLAGS_TLS_PADDING_BUG              0x0008
# define TLS1_FLAGS_SKIP_CERT_VERIFY             0x0010
# define TLS1_FLAGS_KEEP_HANDSHAKE               0x0020
/*
 * Set when the handshake is ready to process peer's ChangeCipherSpec message.
 * Cleared after the message has been processed.
 */
# define SSL3_FLAGS_CCS_OK                       0x0080

/* SSL3_FLAGS_SGC_RESTART_DONE is no longer used */
# define SSL3_FLAGS_SGC_RESTART_DONE             0x0040

# ifndef OPENSSL_NO_SSL_INTERN

typedef struct ssl3_state_st {
    long flags;
    int delay_buf_pop_ret;
    unsigned char read_sequence[8];
    int read_mac_secret_size;
    unsigned char read_mac_secret[EVP_MAX_MD_SIZE];
    unsigned char write_sequence[8];
    int write_mac_secret_size;
    unsigned char write_mac_secret[EVP_MAX_MD_SIZE];
    unsigned char server_random[SSL3_RANDOM_SIZE];
    unsigned char client_random[SSL3_RANDOM_SIZE];
    /* flags for countermeasure against known-IV weakness */
    int need_empty_fragments;
    int empty_fragment_done;
    /* The value of 'extra' when the buffers were initialized */
    int init_extra;
    SSL3_BUFFER rbuf;           /* read IO goes into here */
    SSL3_BUFFER wbuf;           /* write IO goes into here */
    SSL3_RECORD rrec;           /* each decoded record goes in here */
    SSL3_RECORD wrec;           /* goes out from here */
    /*
     * storage for Alert/Handshake protocol data received but not yet
     * processed by ssl3_read_bytes:
     */
    unsigned char alert_fragment[2];
    unsigned int alert_fragment_len;
    unsigned char handshake_fragment[4];
    unsigned int handshake_fragment_len;
    /* partial write - check the numbers match */
    unsigned int wnum;          /* number of bytes sent so far */
    int wpend_tot;              /* number bytes written */
    int wpend_type;
    int wpend_ret;              /* number of bytes submitted */
    const unsigned char *wpend_buf;
    /* used during startup, digest all incoming/outgoing packets */
    BIO *handshake_buffer;
    /*
     * When set of handshake digests is determined, buffer is hashed and
     * freed and MD_CTX-es for all required digests are stored in this array
     */
    EVP_MD_CTX **handshake_dgst;
    /*
     * Set whenever an expected ChangeCipherSpec message is processed.
     * Unset when the peer's Finished message is received.
     * Unexpected ChangeCipherSpec messages trigger a fatal alert.
     */
    int change_cipher_spec;
    int warn_alert;
    int fatal_alert;
    /*
     * we allow one fatal and one warning alert to be outstanding, send close
     * alert via the warning alert
     */
    int alert_dispatch;
    unsigned char send_alert[2];
    /*
     * This flag is set when we should renegotiate ASAP, basically when there
     * is no more data in the read or write buffers
     */
    int renegotiate;
    int total_renegotiations;
    int num_renegotiations;
    int in_read_app_data;
    /*
     * Opaque PRF input as used for the current handshake. These fields are
     * used only if TLSEXT_TYPE_opaque_prf_input is defined (otherwise, they
     * are merely present to improve binary compatibility)
     */
    void *client_opaque_prf_input;
    size_t client_opaque_prf_input_len;
    void *server_opaque_prf_input;
    size_t server_opaque_prf_input_len;
    struct {
        /* actually only needs to be 16+20 */
        unsigned char cert_verify_md[EVP_MAX_MD_SIZE * 2];
        /* actually only need to be 16+20 for SSLv3 and 12 for TLS */
        unsigned char finish_md[EVP_MAX_MD_SIZE * 2];
        int finish_md_len;
        unsigned char peer_finish_md[EVP_MAX_MD_SIZE * 2];
        int peer_finish_md_len;
        unsigned long message_size;
        int message_type;
        /* used to hold the new cipher we are going to use */
        const SSL_CIPHER *new_cipher;
#  ifndef OPENSSL_NO_DH
        DH *dh;
#  endif
#  ifndef OPENSSL_NO_ECDH
        EC_KEY *ecdh;           /* holds short lived ECDH key */
#  endif
        /* used when SSL_ST_FLUSH_DATA is entered */
        int next_state;
        int reuse_message;
        /* used for certificate requests */
        int cert_req;
        int ctype_num;
        char ctype[SSL3_CT_NUMBER];
        STACK_OF(X509_NAME) *ca_names;
        int use_rsa_tmp;
        int key_block_length;
        unsigned char *key_block;
        const EVP_CIPHER *new_sym_enc;
        const EVP_MD *new_hash;
        int new_mac_pkey_type;
        int new_mac_secret_size;
#  ifndef OPENSSL_NO_COMP
        const SSL_COMP *new_compression;
#  else
        char *new_compression;
#  endif
        int cert_request;
    } tmp;

    /* Connection binding to prevent renegotiation attacks */
    unsigned char previous_client_finished[EVP_MAX_MD_SIZE];
    unsigned char previous_client_finished_len;
    unsigned char previous_server_finished[EVP_MAX_MD_SIZE];
    unsigned char previous_server_finished_len;
    int send_connection_binding; /* TODOEKR */

#  ifndef OPENSSL_NO_NEXTPROTONEG
    /*
     * Set if we saw the Next Protocol Negotiation extension from our peer.
     */
    int next_proto_neg_seen;
#  endif

#  ifndef OPENSSL_NO_TLSEXT
#   ifndef OPENSSL_NO_EC
    /*
     * This is set to true if we believe that this is a version of Safari
     * running on OS X 10.6 or newer. We wish to know this because Safari on
     * 10.8 .. 10.8.3 has broken ECDHE-ECDSA support.
     */
    char is_probably_safari;
#   endif                       /* !OPENSSL_NO_EC */

    /*
     * ALPN information (we are in the process of transitioning from NPN to
     * ALPN.)
     */

    /*
     * In a server these point to the selected ALPN protocol after the
     * ClientHello has been processed. In a client these contain the protocol
     * that the server selected once the ServerHello has been processed.
     */
    unsigned char *alpn_selected;
    unsigned alpn_selected_len;
#  endif                        /* OPENSSL_NO_TLSEXT */
} SSL3_STATE;

# endif

/* SSLv3 */
/*
 * client
 */
/* extra state */
# define SSL3_ST_CW_FLUSH                (0x100|SSL_ST_CONNECT)
# ifndef OPENSSL_NO_SCTP
#  define DTLS1_SCTP_ST_CW_WRITE_SOCK                     (0x310|SSL_ST_CONNECT)
#  define DTLS1_SCTP_ST_CR_READ_SOCK                      (0x320|SSL_ST_CONNECT)
# endif
/* write to server */
# define SSL3_ST_CW_CLNT_HELLO_A         (0x110|SSL_ST_CONNECT)
# define SSL3_ST_CW_CLNT_HELLO_B         (0x111|SSL_ST_CONNECT)
/* read from server */
# define SSL3_ST_CR_SRVR_HELLO_A         (0x120|SSL_ST_CONNECT)
# define SSL3_ST_CR_SRVR_HELLO_B         (0x121|SSL_ST_CONNECT)
# define DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A (0x126|SSL_ST_CONNECT)
# define DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B (0x127|SSL_ST_CONNECT)
# define SSL3_ST_CR_CERT_A               (0x130|SSL_ST_CONNECT)
# define SSL3_ST_CR_CERT_B               (0x131|SSL_ST_CONNECT)
# define SSL3_ST_CR_KEY_EXCH_A           (0x140|SSL_ST_CONNECT)
# define SSL3_ST_CR_KEY_EXCH_B           (0x141|SSL_ST_CONNECT)
# define SSL3_ST_CR_CERT_REQ_A           (0x150|SSL_ST_CONNECT)
# define SSL3_ST_CR_CERT_REQ_B           (0x151|SSL_ST_CONNECT)
# define SSL3_ST_CR_SRVR_DONE_A          (0x160|SSL_ST_CONNECT)
# define SSL3_ST_CR_SRVR_DONE_B          (0x161|SSL_ST_CONNECT)
/* write to server */
# define SSL3_ST_CW_CERT_A               (0x170|SSL_ST_CONNECT)
# define SSL3_ST_CW_CERT_B               (0x171|SSL_ST_CONNECT)
# define SSL3_ST_CW_CERT_C               (0x172|SSL_ST_CONNECT)
# define SSL3_ST_CW_CERT_D               (0x173|SSL_ST_CONNECT)
# define SSL3_ST_CW_KEY_EXCH_A           (0x180|SSL_ST_CONNECT)
# define SSL3_ST_CW_KEY_EXCH_B           (0x181|SSL_ST_CONNECT)
# define SSL3_ST_CW_CERT_VRFY_A          (0x190|SSL_ST_CONNECT)
# define SSL3_ST_CW_CERT_VRFY_B          (0x191|SSL_ST_CONNECT)
# define SSL3_ST_CW_CHANGE_A             (0x1A0|SSL_ST_CONNECT)
# define SSL3_ST_CW_CHANGE_B             (0x1A1|SSL_ST_CONNECT)
# ifndef OPENSSL_NO_NEXTPROTONEG
#  define SSL3_ST_CW_NEXT_PROTO_A         (0x200|SSL_ST_CONNECT)
#  define SSL3_ST_CW_NEXT_PROTO_B         (0x201|SSL_ST_CONNECT)
# endif
# define SSL3_ST_CW_FINISHED_A           (0x1B0|SSL_ST_CONNECT)
# define SSL3_ST_CW_FINISHED_B           (0x1B1|SSL_ST_CONNECT)
/* read from server */
# define SSL3_ST_CR_CHANGE_A             (0x1C0|SSL_ST_CONNECT)
# define SSL3_ST_CR_CHANGE_B             (0x1C1|SSL_ST_CONNECT)
# define SSL3_ST_CR_FINISHED_A           (0x1D0|SSL_ST_CONNECT)
# define SSL3_ST_CR_FINISHED_B           (0x1D1|SSL_ST_CONNECT)
# define SSL3_ST_CR_SESSION_TICKET_A     (0x1E0|SSL_ST_CONNECT)
# define SSL3_ST_CR_SESSION_TICKET_B     (0x1E1|SSL_ST_CONNECT)
# define SSL3_ST_CR_CERT_STATUS_A        (0x1F0|SSL_ST_CONNECT)
# define SSL3_ST_CR_CERT_STATUS_B        (0x1F1|SSL_ST_CONNECT)

/* server */
/* extra state */
# define SSL3_ST_SW_FLUSH                (0x100|SSL_ST_ACCEPT)
# ifndef OPENSSL_NO_SCTP
#  define DTLS1_SCTP_ST_SW_WRITE_SOCK                     (0x310|SSL_ST_ACCEPT)
#  define DTLS1_SCTP_ST_SR_READ_SOCK                      (0x320|SSL_ST_ACCEPT)
# endif
/* read from client */
/* Do not change the number values, they do matter */
# define SSL3_ST_SR_CLNT_HELLO_A         (0x110|SSL_ST_ACCEPT)
# define SSL3_ST_SR_CLNT_HELLO_B         (0x111|SSL_ST_ACCEPT)
# define SSL3_ST_SR_CLNT_HELLO_C         (0x112|SSL_ST_ACCEPT)
# define SSL3_ST_SR_CLNT_HELLO_D         (0x115|SSL_ST_ACCEPT)
/* write to client */
# define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A (0x113|SSL_ST_ACCEPT)
# define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B (0x114|SSL_ST_ACCEPT)
# define SSL3_ST_SW_HELLO_REQ_A          (0x120|SSL_ST_ACCEPT)
# define SSL3_ST_SW_HELLO_REQ_B          (0x121|SSL_ST_ACCEPT)
# define SSL3_ST_SW_HELLO_REQ_C          (0x122|SSL_ST_ACCEPT)
# define SSL3_ST_SW_SRVR_HELLO_A         (0x130|SSL_ST_ACCEPT)
# define SSL3_ST_SW_SRVR_HELLO_B         (0x131|SSL_ST_ACCEPT)
# define SSL3_ST_SW_CERT_A               (0x140|SSL_ST_ACCEPT)
# define SSL3_ST_SW_CERT_B               (0x141|SSL_ST_ACCEPT)
# define SSL3_ST_SW_KEY_EXCH_A           (0x150|SSL_ST_ACCEPT)
# define SSL3_ST_SW_KEY_EXCH_B           (0x151|SSL_ST_ACCEPT)
# define SSL3_ST_SW_CERT_REQ_A           (0x160|SSL_ST_ACCEPT)
# define SSL3_ST_SW_CERT_REQ_B           (0x161|SSL_ST_ACCEPT)
# define SSL3_ST_SW_SRVR_DONE_A          (0x170|SSL_ST_ACCEPT)
# define SSL3_ST_SW_SRVR_DONE_B          (0x171|SSL_ST_ACCEPT)
/* read from client */
# define SSL3_ST_SR_CERT_A               (0x180|SSL_ST_ACCEPT)
# define SSL3_ST_SR_CERT_B               (0x181|SSL_ST_ACCEPT)
# define SSL3_ST_SR_KEY_EXCH_A           (0x190|SSL_ST_ACCEPT)
# define SSL3_ST_SR_KEY_EXCH_B           (0x191|SSL_ST_ACCEPT)
# define SSL3_ST_SR_CERT_VRFY_A          (0x1A0|SSL_ST_ACCEPT)
# define SSL3_ST_SR_CERT_VRFY_B          (0x1A1|SSL_ST_ACCEPT)
# define SSL3_ST_SR_CHANGE_A             (0x1B0|SSL_ST_ACCEPT)
# define SSL3_ST_SR_CHANGE_B             (0x1B1|SSL_ST_ACCEPT)
# ifndef OPENSSL_NO_NEXTPROTONEG
#  define SSL3_ST_SR_NEXT_PROTO_A         (0x210|SSL_ST_ACCEPT)
#  define SSL3_ST_SR_NEXT_PROTO_B         (0x211|SSL_ST_ACCEPT)
# endif
# define SSL3_ST_SR_FINISHED_A           (0x1C0|SSL_ST_ACCEPT)
# define SSL3_ST_SR_FINISHED_B           (0x1C1|SSL_ST_ACCEPT)
/* write to client */
# define SSL3_ST_SW_CHANGE_A             (0x1D0|SSL_ST_ACCEPT)
# define SSL3_ST_SW_CHANGE_B             (0x1D1|SSL_ST_ACCEPT)
# define SSL3_ST_SW_FINISHED_A           (0x1E0|SSL_ST_ACCEPT)
# define SSL3_ST_SW_FINISHED_B           (0x1E1|SSL_ST_ACCEPT)
# define SSL3_ST_SW_SESSION_TICKET_A     (0x1F0|SSL_ST_ACCEPT)
# define SSL3_ST_SW_SESSION_TICKET_B     (0x1F1|SSL_ST_ACCEPT)
# define SSL3_ST_SW_CERT_STATUS_A        (0x200|SSL_ST_ACCEPT)
# define SSL3_ST_SW_CERT_STATUS_B        (0x201|SSL_ST_ACCEPT)

# define SSL3_MT_HELLO_REQUEST                   0
# define SSL3_MT_CLIENT_HELLO                    1
# define SSL3_MT_SERVER_HELLO                    2
# define SSL3_MT_NEWSESSION_TICKET               4
# define SSL3_MT_CERTIFICATE                     11
# define SSL3_MT_SERVER_KEY_EXCHANGE             12
# define SSL3_MT_CERTIFICATE_REQUEST             13
# define SSL3_MT_SERVER_DONE                     14
# define SSL3_MT_CERTIFICATE_VERIFY              15
# define SSL3_MT_CLIENT_KEY_EXCHANGE             16
# define SSL3_MT_FINISHED                        20
# define SSL3_MT_CERTIFICATE_STATUS              22
# ifndef OPENSSL_NO_NEXTPROTONEG
#  define SSL3_MT_NEXT_PROTO                      67
# endif
# define DTLS1_MT_HELLO_VERIFY_REQUEST    3

# define SSL3_MT_CCS                             1

/* These are used when changing over to a new cipher */
# define SSL3_CC_READ            0x01
# define SSL3_CC_WRITE           0x02
# define SSL3_CC_CLIENT          0x10
# define SSL3_CC_SERVER          0x20
# define SSL3_CHANGE_CIPHER_CLIENT_WRITE (SSL3_CC_CLIENT|SSL3_CC_WRITE)
# define SSL3_CHANGE_CIPHER_SERVER_READ  (SSL3_CC_SERVER|SSL3_CC_READ)
# define SSL3_CHANGE_CIPHER_CLIENT_READ  (SSL3_CC_CLIENT|SSL3_CC_READ)
# define SSL3_CHANGE_CIPHER_SERVER_WRITE (SSL3_CC_SERVER|SSL3_CC_WRITE)

#ifdef  __cplusplus
}
#endif
#endif
openssl/pem.h000064400000062523151733316550007202 0ustar00/* crypto/pem/pem.h */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#ifndef HEADER_PEM_H
# define HEADER_PEM_H

# include <openssl/e_os2.h>
# ifndef OPENSSL_NO_BIO
#  include <openssl/bio.h>
# endif
# ifndef OPENSSL_NO_STACK
#  include <openssl/stack.h>
# endif
# include <openssl/evp.h>
# include <openssl/x509.h>
# include <openssl/pem2.h>

#ifdef  __cplusplus
extern "C" {
#endif

# define PEM_BUFSIZE             1024

# define PEM_OBJ_UNDEF           0
# define PEM_OBJ_X509            1
# define PEM_OBJ_X509_REQ        2
# define PEM_OBJ_CRL             3
# define PEM_OBJ_SSL_SESSION     4
# define PEM_OBJ_PRIV_KEY        10
# define PEM_OBJ_PRIV_RSA        11
# define PEM_OBJ_PRIV_DSA        12
# define PEM_OBJ_PRIV_DH         13
# define PEM_OBJ_PUB_RSA         14
# define PEM_OBJ_PUB_DSA         15
# define PEM_OBJ_PUB_DH          16
# define PEM_OBJ_DHPARAMS        17
# define PEM_OBJ_DSAPARAMS       18
# define PEM_OBJ_PRIV_RSA_PUBLIC 19
# define PEM_OBJ_PRIV_ECDSA      20
# define PEM_OBJ_PUB_ECDSA       21
# define PEM_OBJ_ECPARAMETERS    22

# define PEM_ERROR               30
# define PEM_DEK_DES_CBC         40
# define PEM_DEK_IDEA_CBC        45
# define PEM_DEK_DES_EDE         50
# define PEM_DEK_DES_ECB         60
# define PEM_DEK_RSA             70
# define PEM_DEK_RSA_MD2         80
# define PEM_DEK_RSA_MD5         90

# define PEM_MD_MD2              NID_md2
# define PEM_MD_MD5              NID_md5
# define PEM_MD_SHA              NID_sha
# define PEM_MD_MD2_RSA          NID_md2WithRSAEncryption
# define PEM_MD_MD5_RSA          NID_md5WithRSAEncryption
# define PEM_MD_SHA_RSA          NID_sha1WithRSAEncryption

# define PEM_STRING_X509_OLD     "X509 CERTIFICATE"
# define PEM_STRING_X509         "CERTIFICATE"
# define PEM_STRING_X509_PAIR    "CERTIFICATE PAIR"
# define PEM_STRING_X509_TRUSTED "TRUSTED CERTIFICATE"
# define PEM_STRING_X509_REQ_OLD "NEW CERTIFICATE REQUEST"
# define PEM_STRING_X509_REQ     "CERTIFICATE REQUEST"
# define PEM_STRING_X509_CRL     "X509 CRL"
# define PEM_STRING_EVP_PKEY     "ANY PRIVATE KEY"
# define PEM_STRING_PUBLIC       "PUBLIC KEY"
# define PEM_STRING_RSA          "RSA PRIVATE KEY"
# define PEM_STRING_RSA_PUBLIC   "RSA PUBLIC KEY"
# define PEM_STRING_DSA          "DSA PRIVATE KEY"
# define PEM_STRING_DSA_PUBLIC   "DSA PUBLIC KEY"
# define PEM_STRING_PKCS7        "PKCS7"
# define PEM_STRING_PKCS7_SIGNED "PKCS #7 SIGNED DATA"
# define PEM_STRING_PKCS8        "ENCRYPTED PRIVATE KEY"
# define PEM_STRING_PKCS8INF     "PRIVATE KEY"
# define PEM_STRING_DHPARAMS     "DH PARAMETERS"
# define PEM_STRING_DHXPARAMS    "X9.42 DH PARAMETERS"
# define PEM_STRING_SSL_SESSION  "SSL SESSION PARAMETERS"
# define PEM_STRING_DSAPARAMS    "DSA PARAMETERS"
# define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY"
# define PEM_STRING_ECPARAMETERS "EC PARAMETERS"
# define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY"
# define PEM_STRING_PARAMETERS   "PARAMETERS"
# define PEM_STRING_CMS          "CMS"

  /*
   * Note that this structure is initialised by PEM_SealInit and cleaned up
   * by PEM_SealFinal (at least for now)
   */
typedef struct PEM_Encode_Seal_st {
    EVP_ENCODE_CTX encode;
    EVP_MD_CTX md;
    EVP_CIPHER_CTX cipher;
} PEM_ENCODE_SEAL_CTX;

/* enc_type is one off */
# define PEM_TYPE_ENCRYPTED      10
# define PEM_TYPE_MIC_ONLY       20
# define PEM_TYPE_MIC_CLEAR      30
# define PEM_TYPE_CLEAR          40

typedef struct pem_recip_st {
    char *name;
    X509_NAME *dn;
    int cipher;
    int key_enc;
    /*      char iv[8]; unused and wrong size */
} PEM_USER;

typedef struct pem_ctx_st {
    int type;                   /* what type of object */
    struct {
        int version;
        int mode;
    } proc_type;

    char *domain;

    struct {
        int cipher;
        /*-
        unused, and wrong size
        unsigned char iv[8]; */
    } DEK_info;

    PEM_USER *originator;

    int num_recipient;
    PEM_USER **recipient;
/*-
    XXX(ben): don#t think this is used!
        STACK *x509_chain;      / * certificate chain */
    EVP_MD *md;                 /* signature type */

    int md_enc;                 /* is the md encrypted or not? */
    int md_len;                 /* length of md_data */
    char *md_data;              /* message digest, could be pkey encrypted */

    EVP_CIPHER *dec;            /* date encryption cipher */
    int key_len;                /* key length */
    unsigned char *key;         /* key */
  /*-
    unused, and wrong size
    unsigned char iv[8]; */

    int data_enc;               /* is the data encrypted */
    int data_len;
    unsigned char *data;
} PEM_CTX;

/*
 * These macros make the PEM_read/PEM_write functions easier to maintain and
 * write. Now they are all implemented with either: IMPLEMENT_PEM_rw(...) or
 * IMPLEMENT_PEM_rw_cb(...)
 */

# ifdef OPENSSL_NO_FP_API

#  define IMPLEMENT_PEM_read_fp(name, type, str, asn1) /**/
#  define IMPLEMENT_PEM_write_fp(name, type, str, asn1) /**/
#  define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) /**/
#  define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) /**/
#  define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) /**/
# else

#  define IMPLEMENT_PEM_read_fp(name, type, str, asn1) \
type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u)\
{ \
return PEM_ASN1_read((d2i_of_void *)d2i_##asn1, str,fp,(void **)x,cb,u); \
}

#  define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \
int PEM_write_##name(FILE *fp, type *x) \
{ \
return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,NULL,NULL,0,NULL,NULL); \
}

#  define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) \
int PEM_write_##name(FILE *fp, const type *x) \
{ \
return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,(void *)x,NULL,NULL,0,NULL,NULL); \
}

#  define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) \
int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
             unsigned char *kstr, int klen, pem_password_cb *cb, \
                  void *u) \
        { \
        return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \
        }

#  define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) \
int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
             unsigned char *kstr, int klen, pem_password_cb *cb, \
                  void *u) \
        { \
        return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \
        }

# endif

# define IMPLEMENT_PEM_read_bio(name, type, str, asn1) \
type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u)\
{ \
return PEM_ASN1_read_bio((d2i_of_void *)d2i_##asn1, str,bp,(void **)x,cb,u); \
}

# define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \
int PEM_write_bio_##name(BIO *bp, type *x) \
{ \
return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,NULL,NULL,0,NULL,NULL); \
}

# define IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \
int PEM_write_bio_##name(BIO *bp, const type *x) \
{ \
return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,NULL,NULL,0,NULL,NULL); \
}

# define IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \
int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
             unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \
        { \
        return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,enc,kstr,klen,cb,u); \
        }

# define IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \
int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
             unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \
        { \
        return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,enc,kstr,klen,cb,u); \
        }

# define IMPLEMENT_PEM_write(name, type, str, asn1) \
        IMPLEMENT_PEM_write_bio(name, type, str, asn1) \
        IMPLEMENT_PEM_write_fp(name, type, str, asn1)

# define IMPLEMENT_PEM_write_const(name, type, str, asn1) \
        IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \
        IMPLEMENT_PEM_write_fp_const(name, type, str, asn1)

# define IMPLEMENT_PEM_write_cb(name, type, str, asn1) \
        IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \
        IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1)

# define IMPLEMENT_PEM_write_cb_const(name, type, str, asn1) \
        IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \
        IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1)

# define IMPLEMENT_PEM_read(name, type, str, asn1) \
        IMPLEMENT_PEM_read_bio(name, type, str, asn1) \
        IMPLEMENT_PEM_read_fp(name, type, str, asn1)

# define IMPLEMENT_PEM_rw(name, type, str, asn1) \
        IMPLEMENT_PEM_read(name, type, str, asn1) \
        IMPLEMENT_PEM_write(name, type, str, asn1)

# define IMPLEMENT_PEM_rw_const(name, type, str, asn1) \
        IMPLEMENT_PEM_read(name, type, str, asn1) \
        IMPLEMENT_PEM_write_const(name, type, str, asn1)

# define IMPLEMENT_PEM_rw_cb(name, type, str, asn1) \
        IMPLEMENT_PEM_read(name, type, str, asn1) \
        IMPLEMENT_PEM_write_cb(name, type, str, asn1)

/* These are the same except they are for the declarations */

# if defined(OPENSSL_NO_FP_API)

#  define DECLARE_PEM_read_fp(name, type) /**/
#  define DECLARE_PEM_write_fp(name, type) /**/
#  define DECLARE_PEM_write_cb_fp(name, type) /**/
# else

#  define DECLARE_PEM_read_fp(name, type) \
        type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u);

#  define DECLARE_PEM_write_fp(name, type) \
        int PEM_write_##name(FILE *fp, type *x);

#  define DECLARE_PEM_write_fp_const(name, type) \
        int PEM_write_##name(FILE *fp, const type *x);

#  define DECLARE_PEM_write_cb_fp(name, type) \
        int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
             unsigned char *kstr, int klen, pem_password_cb *cb, void *u);

# endif

# ifndef OPENSSL_NO_BIO
#  define DECLARE_PEM_read_bio(name, type) \
        type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u);

#  define DECLARE_PEM_write_bio(name, type) \
        int PEM_write_bio_##name(BIO *bp, type *x);

#  define DECLARE_PEM_write_bio_const(name, type) \
        int PEM_write_bio_##name(BIO *bp, const type *x);

#  define DECLARE_PEM_write_cb_bio(name, type) \
        int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
             unsigned char *kstr, int klen, pem_password_cb *cb, void *u);

# else

#  define DECLARE_PEM_read_bio(name, type) /**/
#  define DECLARE_PEM_write_bio(name, type) /**/
#  define DECLARE_PEM_write_bio_const(name, type) /**/
#  define DECLARE_PEM_write_cb_bio(name, type) /**/
# endif
# define DECLARE_PEM_write(name, type) \
        DECLARE_PEM_write_bio(name, type) \
        DECLARE_PEM_write_fp(name, type)
# define DECLARE_PEM_write_const(name, type) \
        DECLARE_PEM_write_bio_const(name, type) \
        DECLARE_PEM_write_fp_const(name, type)
# define DECLARE_PEM_write_cb(name, type) \
        DECLARE_PEM_write_cb_bio(name, type) \
        DECLARE_PEM_write_cb_fp(name, type)
# define DECLARE_PEM_read(name, type) \
        DECLARE_PEM_read_bio(name, type) \
        DECLARE_PEM_read_fp(name, type)
# define DECLARE_PEM_rw(name, type) \
        DECLARE_PEM_read(name, type) \
        DECLARE_PEM_write(name, type)
# define DECLARE_PEM_rw_const(name, type) \
        DECLARE_PEM_read(name, type) \
        DECLARE_PEM_write_const(name, type)
# define DECLARE_PEM_rw_cb(name, type) \
        DECLARE_PEM_read(name, type) \
        DECLARE_PEM_write_cb(name, type)
# if 1
/* "userdata": new with OpenSSL 0.9.4 */
typedef int pem_password_cb (char *buf, int size, int rwflag, void *userdata);
# else
/* OpenSSL 0.9.3, 0.9.3a */
typedef int pem_password_cb (char *buf, int size, int rwflag);
# endif

int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher);
int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *len,
                  pem_password_cb *callback, void *u);

# ifndef OPENSSL_NO_BIO
int PEM_read_bio(BIO *bp, char **name, char **header,
                 unsigned char **data, long *len);
int PEM_write_bio(BIO *bp, const char *name, const char *hdr,
                  const unsigned char *data, long len);
int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm,
                       const char *name, BIO *bp, pem_password_cb *cb,
                       void *u);
void *PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x,
                        pem_password_cb *cb, void *u);
int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, void *x,
                       const EVP_CIPHER *enc, unsigned char *kstr, int klen,
                       pem_password_cb *cb, void *u);

STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk,
                                            pem_password_cb *cb, void *u);
int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc,
                            unsigned char *kstr, int klen,
                            pem_password_cb *cd, void *u);
# endif

int PEM_read(FILE *fp, char **name, char **header,
             unsigned char **data, long *len);
int PEM_write(FILE *fp, const char *name, const char *hdr,
              const unsigned char *data, long len);
void *PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x,
                    pem_password_cb *cb, void *u);
int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp,
                   void *x, const EVP_CIPHER *enc, unsigned char *kstr,
                   int klen, pem_password_cb *callback, void *u);
STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk,
                                        pem_password_cb *cb, void *u);

int PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type,
                 EVP_MD *md_type, unsigned char **ek, int *ekl,
                 unsigned char *iv, EVP_PKEY **pubk, int npubk);
void PEM_SealUpdate(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *out, int *outl,
                    unsigned char *in, int inl);
int PEM_SealFinal(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *sig, int *sigl,
                  unsigned char *out, int *outl, EVP_PKEY *priv);

void PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type);
void PEM_SignUpdate(EVP_MD_CTX *ctx, unsigned char *d, unsigned int cnt);
int PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
                  unsigned int *siglen, EVP_PKEY *pkey);

/* The default pem_password_cb that's used internally */
int PEM_def_callback(char *buf, int num, int rwflag, void *userdata);
void PEM_proc_type(char *buf, int type);
void PEM_dek_info(char *buf, const char *type, int len, char *str);

# include <openssl/symhacks.h>

DECLARE_PEM_rw(X509, X509)
DECLARE_PEM_rw(X509_AUX, X509)
DECLARE_PEM_rw(X509_CERT_PAIR, X509_CERT_PAIR)
DECLARE_PEM_rw(X509_REQ, X509_REQ)
DECLARE_PEM_write(X509_REQ_NEW, X509_REQ)
DECLARE_PEM_rw(X509_CRL, X509_CRL)
DECLARE_PEM_rw(PKCS7, PKCS7)
DECLARE_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE)
DECLARE_PEM_rw(PKCS8, X509_SIG)
DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO)
# ifndef OPENSSL_NO_RSA
DECLARE_PEM_rw_cb(RSAPrivateKey, RSA)
DECLARE_PEM_rw_const(RSAPublicKey, RSA)
DECLARE_PEM_rw(RSA_PUBKEY, RSA)
# endif
# ifndef OPENSSL_NO_DSA
DECLARE_PEM_rw_cb(DSAPrivateKey, DSA)
DECLARE_PEM_rw(DSA_PUBKEY, DSA)
DECLARE_PEM_rw_const(DSAparams, DSA)
# endif
# ifndef OPENSSL_NO_EC
DECLARE_PEM_rw_const(ECPKParameters, EC_GROUP)
DECLARE_PEM_rw_cb(ECPrivateKey, EC_KEY)
DECLARE_PEM_rw(EC_PUBKEY, EC_KEY)
# endif
# ifndef OPENSSL_NO_DH
DECLARE_PEM_rw_const(DHparams, DH)
DECLARE_PEM_write_const(DHxparams, DH)
# endif
DECLARE_PEM_rw_cb(PrivateKey, EVP_PKEY)
DECLARE_PEM_rw(PUBKEY, EVP_PKEY)

int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid,
                                      char *kstr, int klen,
                                      pem_password_cb *cb, void *u);
int PEM_write_bio_PKCS8PrivateKey(BIO *, EVP_PKEY *, const EVP_CIPHER *,
                                  char *, int, pem_password_cb *, void *);
int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
                            char *kstr, int klen,
                            pem_password_cb *cb, void *u);
int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid,
                                char *kstr, int klen,
                                pem_password_cb *cb, void *u);
EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb,
                                  void *u);

int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
                           char *kstr, int klen,
                           pem_password_cb *cb, void *u);
int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid,
                               char *kstr, int klen,
                               pem_password_cb *cb, void *u);
int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid,
                                  char *kstr, int klen,
                                  pem_password_cb *cb, void *u);

EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb,
                                 void *u);

int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
                              char *kstr, int klen, pem_password_cb *cd,
                              void *u);

EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x);
int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x);

EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length);
EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length);
EVP_PKEY *b2i_PrivateKey_bio(BIO *in);
EVP_PKEY *b2i_PublicKey_bio(BIO *in);
int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk);
int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk);
# ifndef OPENSSL_NO_RC4
EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u);
int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel,
                pem_password_cb *cb, void *u);
# endif

/* BEGIN ERROR CODES */
/*
 * The following lines are auto generated by the script mkerr.pl. Any changes
 * made after this point may be overwritten when the script is next run.
 */

void ERR_load_PEM_strings(void);

/* Error codes for the PEM functions. */

/* Function codes. */
# define PEM_F_B2I_DSS                                    127
# define PEM_F_B2I_PVK_BIO                                128
# define PEM_F_B2I_RSA                                    129
# define PEM_F_CHECK_BITLEN_DSA                           130
# define PEM_F_CHECK_BITLEN_RSA                           131
# define PEM_F_D2I_PKCS8PRIVATEKEY_BIO                    120
# define PEM_F_D2I_PKCS8PRIVATEKEY_FP                     121
# define PEM_F_DO_B2I                                     132
# define PEM_F_DO_B2I_BIO                                 133
# define PEM_F_DO_BLOB_HEADER                             134
# define PEM_F_DO_PK8PKEY                                 126
# define PEM_F_DO_PK8PKEY_FP                              125
# define PEM_F_DO_PVK_BODY                                135
# define PEM_F_DO_PVK_HEADER                              136
# define PEM_F_I2B_PVK                                    137
# define PEM_F_I2B_PVK_BIO                                138
# define PEM_F_LOAD_IV                                    101
# define PEM_F_PEM_ASN1_READ                              102
# define PEM_F_PEM_ASN1_READ_BIO                          103
# define PEM_F_PEM_ASN1_WRITE                             104
# define PEM_F_PEM_ASN1_WRITE_BIO                         105
# define PEM_F_PEM_DEF_CALLBACK                           100
# define PEM_F_PEM_DO_HEADER                              106
# define PEM_F_PEM_F_PEM_WRITE_PKCS8PRIVATEKEY            118
# define PEM_F_PEM_GET_EVP_CIPHER_INFO                    107
# define PEM_F_PEM_PK8PKEY                                119
# define PEM_F_PEM_READ                                   108
# define PEM_F_PEM_READ_BIO                               109
# define PEM_F_PEM_READ_BIO_DHPARAMS                      141
# define PEM_F_PEM_READ_BIO_PARAMETERS                    140
# define PEM_F_PEM_READ_BIO_PRIVATEKEY                    123
# define PEM_F_PEM_READ_DHPARAMS                          142
# define PEM_F_PEM_READ_PRIVATEKEY                        124
# define PEM_F_PEM_SEALFINAL                              110
# define PEM_F_PEM_SEALINIT                               111
# define PEM_F_PEM_SIGNFINAL                              112
# define PEM_F_PEM_WRITE                                  113
# define PEM_F_PEM_WRITE_BIO                              114
# define PEM_F_PEM_WRITE_PRIVATEKEY                       139
# define PEM_F_PEM_X509_INFO_READ                         115
# define PEM_F_PEM_X509_INFO_READ_BIO                     116
# define PEM_F_PEM_X509_INFO_WRITE_BIO                    117

/* Reason codes. */
# define PEM_R_BAD_BASE64_DECODE                          100
# define PEM_R_BAD_DECRYPT                                101
# define PEM_R_BAD_END_LINE                               102
# define PEM_R_BAD_IV_CHARS                               103
# define PEM_R_BAD_MAGIC_NUMBER                           116
# define PEM_R_BAD_PASSWORD_READ                          104
# define PEM_R_BAD_VERSION_NUMBER                         117
# define PEM_R_BIO_WRITE_FAILURE                          118
# define PEM_R_CIPHER_IS_NULL                             127
# define PEM_R_ERROR_CONVERTING_PRIVATE_KEY               115
# define PEM_R_EXPECTING_PRIVATE_KEY_BLOB                 119
# define PEM_R_EXPECTING_PUBLIC_KEY_BLOB                  120
# define PEM_R_HEADER_TOO_LONG                            128
# define PEM_R_INCONSISTENT_HEADER                        121
# define PEM_R_KEYBLOB_HEADER_PARSE_ERROR                 122
# define PEM_R_KEYBLOB_TOO_SHORT                          123
# define PEM_R_NOT_DEK_INFO                               105
# define PEM_R_NOT_ENCRYPTED                              106
# define PEM_R_NOT_PROC_TYPE                              107
# define PEM_R_NO_START_LINE                              108
# define PEM_R_PROBLEMS_GETTING_PASSWORD                  109
# define PEM_R_PUBLIC_KEY_NO_RSA                          110
# define PEM_R_PVK_DATA_TOO_SHORT                         124
# define PEM_R_PVK_TOO_SHORT                              125
# define PEM_R_READ_KEY                                   111
# define PEM_R_SHORT_HEADER                               112
# define PEM_R_UNSUPPORTED_CIPHER                         113
# define PEM_R_UNSUPPORTED_ENCRYPTION                     114
# define PEM_R_UNSUPPORTED_KEY_COMPONENTS                 126

# ifdef  __cplusplus
}
# endif
#endif
openssl/cast.h000064400000011063151733316560007345 0ustar00/* crypto/cast/cast.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#ifndef HEADER_CAST_H
# define HEADER_CAST_H

#ifdef  __cplusplus
extern "C" {
#endif

# include <openssl/opensslconf.h>

# ifdef OPENSSL_NO_CAST
#  error CAST is disabled.
# endif

# define CAST_ENCRYPT    1
# define CAST_DECRYPT    0

# define CAST_LONG unsigned int

# define CAST_BLOCK      8
# define CAST_KEY_LENGTH 16

typedef struct cast_key_st {
    CAST_LONG data[32];
    int short_key;              /* Use reduced rounds for short key */
} CAST_KEY;

# ifdef OPENSSL_FIPS
void private_CAST_set_key(CAST_KEY *key, int len, const unsigned char *data);
# endif
void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data);
void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out,
                      const CAST_KEY *key, int enc);
void CAST_encrypt(CAST_LONG *data, const CAST_KEY *key);
void CAST_decrypt(CAST_LONG *data, const CAST_KEY *key);
void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out,
                      long length, const CAST_KEY *ks, unsigned char *iv,
                      int enc);
void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out,
                        long length, const CAST_KEY *schedule,
                        unsigned char *ivec, int *num, int enc);
void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out,
                        long length, const CAST_KEY *schedule,
                        unsigned char *ivec, int *num);

#ifdef  __cplusplus
}
#endif

#endif
openssl/stack.h000064400000010664151733316560007526 0ustar00/* crypto/stack/stack.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#ifndef HEADER_STACK_H
# define HEADER_STACK_H

#ifdef  __cplusplus
extern "C" {
#endif

typedef struct stack_st {
    int num;
    char **data;
    int sorted;
    int num_alloc;
    int (*comp) (const void *, const void *);
} _STACK;                       /* Use STACK_OF(...) instead */

# define M_sk_num(sk)            ((sk) ? (sk)->num:-1)
# define M_sk_value(sk,n)        ((sk) ? (sk)->data[n] : NULL)

int sk_num(const _STACK *);
void *sk_value(const _STACK *, int);

void *sk_set(_STACK *, int, void *);

_STACK *sk_new(int (*cmp) (const void *, const void *));
_STACK *sk_new_null(void);
void sk_free(_STACK *);
void sk_pop_free(_STACK *st, void (*func) (void *));
_STACK *sk_deep_copy(_STACK *, void *(*)(void *), void (*)(void *));
int sk_insert(_STACK *sk, void *data, int where);
void *sk_delete(_STACK *st, int loc);
void *sk_delete_ptr(_STACK *st, void *p);
int sk_find(_STACK *st, void *data);
int sk_find_ex(_STACK *st, void *data);
int sk_push(_STACK *st, void *data);
int sk_unshift(_STACK *st, void *data);
void *sk_shift(_STACK *st);
void *sk_pop(_STACK *st);
void sk_zero(_STACK *st);
int (*sk_set_cmp_func(_STACK *sk, int (*c) (const void *, const void *)))
 (const void *, const void *);
_STACK *sk_dup(_STACK *st);
void sk_sort(_STACK *st);
int sk_is_sorted(const _STACK *st);

#ifdef  __cplusplus
}
#endif

#endif
openssl/idea.h000064400000011107151733316560007314 0ustar00/* crypto/idea/idea.h */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#ifndef HEADER_IDEA_H
# define HEADER_IDEA_H

# include <openssl/opensslconf.h>/* IDEA_INT, OPENSSL_NO_IDEA */

# ifdef OPENSSL_NO_IDEA
#  error IDEA is disabled.
# endif

# define IDEA_ENCRYPT    1
# define IDEA_DECRYPT    0

# define IDEA_BLOCK      8
# define IDEA_KEY_LENGTH 16

#ifdef  __cplusplus
extern "C" {
#endif

typedef struct idea_key_st {
    IDEA_INT data[9][6];
} IDEA_KEY_SCHEDULE;

const char *idea_options(void);
void idea_ecb_encrypt(const unsigned char *in, unsigned char *out,
                      IDEA_KEY_SCHEDULE *ks);
# ifdef OPENSSL_FIPS
void private_idea_set_encrypt_key(const unsigned char *key,
                                  IDEA_KEY_SCHEDULE *ks);
# endif
void idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks);
void idea_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk);
void idea_cbc_encrypt(const unsigned char *in, unsigned char *out,
                      long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv,
                      int enc);
void idea_cfb64_encrypt(const unsigned char *in, unsigned char *out,
                        long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv,
                        int *num, int enc);
void idea_ofb64_encrypt(const unsigned char *in, unsigned char *out,
                        long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv,
                        int *num);
void idea_encrypt(unsigned long *in, IDEA_KEY_SCHEDULE *ks);
#ifdef  __cplusplus
}
#endif

#endif
openssl/buffer.h000064400000011642151733316560007667 0ustar00/* crypto/buffer/buffer.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#ifndef HEADER_BUFFER_H
# define HEADER_BUFFER_H

# include <openssl/ossl_typ.h>

#ifdef  __cplusplus
extern "C" {
#endif

# include <stddef.h>

# if !defined(NO_SYS_TYPES_H)
#  include <sys/types.h>
# endif

/* Already declared in ossl_typ.h */
/* typedef struct buf_mem_st BUF_MEM; */

struct buf_mem_st {
    size_t length;              /* current number of bytes */
    char *data;
    size_t max;                 /* size of buffer */
};

BUF_MEM *BUF_MEM_new(void);
void BUF_MEM_free(BUF_MEM *a);
int BUF_MEM_grow(BUF_MEM *str, size_t len);
int BUF_MEM_grow_clean(BUF_MEM *str, size_t len);
size_t BUF_strnlen(const char *str, size_t maxlen);
char *BUF_strdup(const char *str);

/*
 * Like strndup, but in addition, explicitly guarantees to never read past the
 * first |siz| bytes of |str|.
 */
char *BUF_strndup(const char *str, size_t siz);

void *BUF_memdup(const void *data, size_t siz);
void BUF_reverse(unsigned char *out, const unsigned char *in, size_t siz);

/* safe string functions */
size_t BUF_strlcpy(char *dst, const char *src, size_t siz);
size_t BUF_strlcat(char *dst, const char *src, size_t siz);

/* BEGIN ERROR CODES */
/*
 * The following lines are auto generated by the script mkerr.pl. Any changes
 * made after this point may be overwritten when the script is next run.
 */
void ERR_load_BUF_strings(void);

/* Error codes for the BUF functions. */

/* Function codes. */
# define BUF_F_BUF_MEMDUP                                 103
# define BUF_F_BUF_MEM_GROW                               100
# define BUF_F_BUF_MEM_GROW_CLEAN                         105
# define BUF_F_BUF_MEM_NEW                                101
# define BUF_F_BUF_STRDUP                                 102
# define BUF_F_BUF_STRNDUP                                104

/* Reason codes. */

#ifdef  __cplusplus
}
#endif
#endif
openssl/evp.h000064400000217542151733316560007217 0ustar00/* crypto/evp/evp.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#ifndef HEADER_ENVELOPE_H
# define HEADER_ENVELOPE_H

# ifdef OPENSSL_ALGORITHM_DEFINES
#  include <openssl/opensslconf.h>
# else
#  define OPENSSL_ALGORITHM_DEFINES
#  include <openssl/opensslconf.h>
#  undef OPENSSL_ALGORITHM_DEFINES
# endif

# include <openssl/ossl_typ.h>

# include <openssl/symhacks.h>

# ifndef OPENSSL_NO_BIO
#  include <openssl/bio.h>
# endif

/*-
#define EVP_RC2_KEY_SIZE                16
#define EVP_RC4_KEY_SIZE                16
#define EVP_BLOWFISH_KEY_SIZE           16
#define EVP_CAST5_KEY_SIZE              16
#define EVP_RC5_32_12_16_KEY_SIZE       16
*/
# define EVP_MAX_MD_SIZE                 64/* longest known is SHA512 */
# define EVP_MAX_KEY_LENGTH              64
# define EVP_MAX_IV_LENGTH               16
# define EVP_MAX_BLOCK_LENGTH            32

# define PKCS5_SALT_LEN                  8
/* Default PKCS#5 iteration count */
# define PKCS5_DEFAULT_ITER              2048

# include <openssl/objects.h>

# define EVP_PK_RSA      0x0001
# define EVP_PK_DSA      0x0002
# define EVP_PK_DH       0x0004
# define EVP_PK_EC       0x0008
# define EVP_PKT_SIGN    0x0010
# define EVP_PKT_ENC     0x0020
# define EVP_PKT_EXCH    0x0040
# define EVP_PKS_RSA     0x0100
# define EVP_PKS_DSA     0x0200
# define EVP_PKS_EC      0x0400

# define EVP_PKEY_NONE   NID_undef
# define EVP_PKEY_RSA    NID_rsaEncryption
# define EVP_PKEY_RSA2   NID_rsa
# define EVP_PKEY_DSA    NID_dsa
# define EVP_PKEY_DSA1   NID_dsa_2
# define EVP_PKEY_DSA2   NID_dsaWithSHA
# define EVP_PKEY_DSA3   NID_dsaWithSHA1
# define EVP_PKEY_DSA4   NID_dsaWithSHA1_2
# define EVP_PKEY_DH     NID_dhKeyAgreement
# define EVP_PKEY_DHX    NID_dhpublicnumber
# define EVP_PKEY_EC     NID_X9_62_id_ecPublicKey
# define EVP_PKEY_HMAC   NID_hmac
# define EVP_PKEY_CMAC   NID_cmac

#ifdef  __cplusplus
extern "C" {
#endif

# ifdef OPENSSL_FIPS
#  include <openssl/fips.h>
# endif

/*
 * Type needs to be a bit field Sub-type needs to be for variations on the
 * method, as in, can it do arbitrary encryption....
 */
struct evp_pkey_st {
    int type;
    int save_type;
    int references;
    const EVP_PKEY_ASN1_METHOD *ameth;
    ENGINE *engine;
    union {
        char *ptr;
# ifndef OPENSSL_NO_RSA
        struct rsa_st *rsa;     /* RSA */
# endif
# ifndef OPENSSL_NO_DSA
        struct dsa_st *dsa;     /* DSA */
# endif
# ifndef OPENSSL_NO_DH
        struct dh_st *dh;       /* DH */
# endif
# ifndef OPENSSL_NO_EC
        struct ec_key_st *ec;   /* ECC */
# endif
    } pkey;
    int save_parameters;
    STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
} /* EVP_PKEY */ ;

# define EVP_PKEY_MO_SIGN        0x0001
# define EVP_PKEY_MO_VERIFY      0x0002
# define EVP_PKEY_MO_ENCRYPT     0x0004
# define EVP_PKEY_MO_DECRYPT     0x0008

# ifndef EVP_MD
struct env_md_st {
    int type;
    int pkey_type;
    int md_size;
    unsigned long flags;
    int (*init) (EVP_MD_CTX *ctx);
    int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count);
    int (*final) (EVP_MD_CTX *ctx, unsigned char *md);
    int (*copy) (EVP_MD_CTX *to, const EVP_MD_CTX *from);
    int (*cleanup) (EVP_MD_CTX *ctx);
    /* FIXME: prototype these some day */
    int (*sign) (int type, const unsigned char *m, unsigned int m_length,
                 unsigned char *sigret, unsigned int *siglen, void *key);
    int (*verify) (int type, const unsigned char *m, unsigned int m_length,
                   const unsigned char *sigbuf, unsigned int siglen,
                   void *key);
    int required_pkey_type[5];  /* EVP_PKEY_xxx */
    int block_size;
    int ctx_size;               /* how big does the ctx->md_data need to be */
    /* control function */
    int (*md_ctrl) (EVP_MD_CTX *ctx, int cmd, int p1, void *p2);
} /* EVP_MD */ ;

typedef int evp_sign_method(int type, const unsigned char *m,
                            unsigned int m_length, unsigned char *sigret,
                            unsigned int *siglen, void *key);
typedef int evp_verify_method(int type, const unsigned char *m,
                              unsigned int m_length,
                              const unsigned char *sigbuf,
                              unsigned int siglen, void *key);

/* digest can only handle a single block */
#  define EVP_MD_FLAG_ONESHOT     0x0001

/*
 * digest is a "clone" digest used
 * which is a copy of an existing
 * one for a specific public key type.
 * EVP_dss1() etc
 */
#  define EVP_MD_FLAG_PKEY_DIGEST 0x0002

/* Digest uses EVP_PKEY_METHOD for signing instead of MD specific signing */

#  define EVP_MD_FLAG_PKEY_METHOD_SIGNATURE       0x0004

/* DigestAlgorithmIdentifier flags... */

#  define EVP_MD_FLAG_DIGALGID_MASK               0x0018

/* NULL or absent parameter accepted. Use NULL */

#  define EVP_MD_FLAG_DIGALGID_NULL               0x0000

/* NULL or absent parameter accepted. Use NULL for PKCS#1 otherwise absent */

#  define EVP_MD_FLAG_DIGALGID_ABSENT             0x0008

/* Custom handling via ctrl */

#  define EVP_MD_FLAG_DIGALGID_CUSTOM             0x0018

/* Note if suitable for use in FIPS mode */
#  define EVP_MD_FLAG_FIPS        0x0400

/* Digest ctrls */

#  define EVP_MD_CTRL_DIGALGID                    0x1
#  define EVP_MD_CTRL_MICALG                      0x2

/* Minimum Algorithm specific ctrl value */

#  define EVP_MD_CTRL_ALG_CTRL                    0x1000

#  define EVP_PKEY_NULL_method    NULL,NULL,{0,0,0,0}

#  ifndef OPENSSL_NO_DSA
#   define EVP_PKEY_DSA_method     (evp_sign_method *)DSA_sign, \
                                (evp_verify_method *)DSA_verify, \
                                {EVP_PKEY_DSA,EVP_PKEY_DSA2,EVP_PKEY_DSA3, \
                                        EVP_PKEY_DSA4,0}
#  else
#   define EVP_PKEY_DSA_method     EVP_PKEY_NULL_method
#  endif

#  ifndef OPENSSL_NO_ECDSA
#   define EVP_PKEY_ECDSA_method   (evp_sign_method *)ECDSA_sign, \
                                (evp_verify_method *)ECDSA_verify, \
                                 {EVP_PKEY_EC,0,0,0}
#  else
#   define EVP_PKEY_ECDSA_method   EVP_PKEY_NULL_method
#  endif

#  ifndef OPENSSL_NO_RSA
#   define EVP_PKEY_RSA_method     (evp_sign_method *)RSA_sign, \
                                (evp_verify_method *)RSA_verify, \
                                {EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0}
#   define EVP_PKEY_RSA_ASN1_OCTET_STRING_method \
                                (evp_sign_method *)RSA_sign_ASN1_OCTET_STRING, \
                                (evp_verify_method *)RSA_verify_ASN1_OCTET_STRING, \
                                {EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0}
#  else
#   define EVP_PKEY_RSA_method     EVP_PKEY_NULL_method
#   define EVP_PKEY_RSA_ASN1_OCTET_STRING_method EVP_PKEY_NULL_method
#  endif

# endif                         /* !EVP_MD */

struct env_md_ctx_st {
    const EVP_MD *digest;
    ENGINE *engine;             /* functional reference if 'digest' is
                                 * ENGINE-provided */
    unsigned long flags;
    void *md_data;
    /* Public key context for sign/verify */
    EVP_PKEY_CTX *pctx;
    /* Update function: usually copied from EVP_MD */
    int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count);
} /* EVP_MD_CTX */ ;

/* values for EVP_MD_CTX flags */

# define EVP_MD_CTX_FLAG_ONESHOT         0x0001/* digest update will be
                                                * called once only */
# define EVP_MD_CTX_FLAG_CLEANED         0x0002/* context has already been
                                                * cleaned */
# define EVP_MD_CTX_FLAG_REUSE           0x0004/* Don't free up ctx->md_data
                                                * in EVP_MD_CTX_cleanup */
# define EVP_MD_CTX_FLAG_NON_FIPS_ALLOW  0x0008/* Allow use of non FIPS
                                                * digest in FIPS mode */

/*
 * The following PAD options are also currently ignored in 1.0.0, digest
 * parameters are handled through EVP_DigestSign*() and EVP_DigestVerify*()
 * instead.
 */
# define EVP_MD_CTX_FLAG_PAD_MASK        0xF0/* RSA mode to use */
# define EVP_MD_CTX_FLAG_PAD_PKCS1       0x00/* PKCS#1 v1.5 mode */
# define EVP_MD_CTX_FLAG_PAD_X931        0x10/* X9.31 mode */
# define EVP_MD_CTX_FLAG_PAD_PSS         0x20/* PSS mode */
# define M_EVP_MD_CTX_FLAG_PSS_SALT(ctx) \
                ((ctx->flags>>16) &0xFFFF) /* seed length */
# define EVP_MD_CTX_FLAG_PSS_MDLEN       0xFFFF/* salt len same as digest */
# define EVP_MD_CTX_FLAG_PSS_MREC        0xFFFE/* salt max or auto recovered */

# define EVP_MD_CTX_FLAG_NO_INIT         0x0100/* Don't initialize md_data */

struct evp_cipher_st {
    int nid;
    int block_size;
    /* Default value for variable length ciphers */
    int key_len;
    int iv_len;
    /* Various flags */
    unsigned long flags;
    /* init key */
    int (*init) (EVP_CIPHER_CTX *ctx, const unsigned char *key,
                 const unsigned char *iv, int enc);
    /* encrypt/decrypt data */
    int (*do_cipher) (EVP_CIPHER_CTX *ctx, unsigned char *out,
                      const unsigned char *in, size_t inl);
    /* cleanup ctx */
    int (*cleanup) (EVP_CIPHER_CTX *);
    /* how big ctx->cipher_data needs to be */
    int ctx_size;
    /* Populate a ASN1_TYPE with parameters */
    int (*set_asn1_parameters) (EVP_CIPHER_CTX *, ASN1_TYPE *);
    /* Get parameters from a ASN1_TYPE */
    int (*get_asn1_parameters) (EVP_CIPHER_CTX *, ASN1_TYPE *);
    /* Miscellaneous operations */
    int (*ctrl) (EVP_CIPHER_CTX *, int type, int arg, void *ptr);
    /* Application data */
    void *app_data;
} /* EVP_CIPHER */ ;

/* Values for cipher flags */

/* Modes for ciphers */

# define         EVP_CIPH_STREAM_CIPHER          0x0
# define         EVP_CIPH_ECB_MODE               0x1
# define         EVP_CIPH_CBC_MODE               0x2
# define         EVP_CIPH_CFB_MODE               0x3
# define         EVP_CIPH_OFB_MODE               0x4
# define         EVP_CIPH_CTR_MODE               0x5
# define         EVP_CIPH_GCM_MODE               0x6
# define         EVP_CIPH_CCM_MODE               0x7
# define         EVP_CIPH_XTS_MODE               0x10001
# define         EVP_CIPH_WRAP_MODE              0x10002
# define         EVP_CIPH_MODE                   0xF0007
/* Set if variable length cipher */
# define         EVP_CIPH_VARIABLE_LENGTH        0x8
/* Set if the iv handling should be done by the cipher itself */
# define         EVP_CIPH_CUSTOM_IV              0x10
/* Set if the cipher's init() function should be called if key is NULL */
# define         EVP_CIPH_ALWAYS_CALL_INIT       0x20
/* Call ctrl() to init cipher parameters */
# define         EVP_CIPH_CTRL_INIT              0x40
/* Don't use standard key length function */
# define         EVP_CIPH_CUSTOM_KEY_LENGTH      0x80
/* Don't use standard block padding */
# define         EVP_CIPH_NO_PADDING             0x100
/* cipher handles random key generation */
# define         EVP_CIPH_RAND_KEY               0x200
/* cipher has its own additional copying logic */
# define         EVP_CIPH_CUSTOM_COPY            0x4000
/* Allow use default ASN1 get/set iv */
# define         EVP_CIPH_FLAG_DEFAULT_ASN1      0x1000
/* Buffer length in bits not bytes: CFB1 mode only */
# define         EVP_CIPH_FLAG_LENGTH_BITS       0x2000
/* Note if suitable for use in FIPS mode */
# define         EVP_CIPH_FLAG_FIPS              0x400
/* Allow non FIPS cipher in FIPS mode */
# define         EVP_CIPH_FLAG_NON_FIPS_ALLOW    0x800
/*
 * Cipher handles any and all padding logic as well as finalisation.
 */
# define         EVP_CIPH_FLAG_CUSTOM_CIPHER     0x100000
# define         EVP_CIPH_FLAG_AEAD_CIPHER       0x200000
# define         EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0x400000

/*
 * Cipher context flag to indicate we can handle wrap mode: if allowed in
 * older applications it could overflow buffers.
 */

# define         EVP_CIPHER_CTX_FLAG_WRAP_ALLOW  0x1

/* ctrl() values */

# define         EVP_CTRL_INIT                   0x0
# define         EVP_CTRL_SET_KEY_LENGTH         0x1
# define         EVP_CTRL_GET_RC2_KEY_BITS       0x2
# define         EVP_CTRL_SET_RC2_KEY_BITS       0x3
# define         EVP_CTRL_GET_RC5_ROUNDS         0x4
# define         EVP_CTRL_SET_RC5_ROUNDS         0x5
# define         EVP_CTRL_RAND_KEY               0x6
# define         EVP_CTRL_PBE_PRF_NID            0x7
# define         EVP_CTRL_COPY                   0x8
# define         EVP_CTRL_GCM_SET_IVLEN          0x9
# define         EVP_CTRL_GCM_GET_TAG            0x10
# define         EVP_CTRL_GCM_SET_TAG            0x11
# define         EVP_CTRL_GCM_SET_IV_FIXED       0x12
# define         EVP_CTRL_GCM_IV_GEN             0x13
# define         EVP_CTRL_CCM_SET_IVLEN          EVP_CTRL_GCM_SET_IVLEN
# define         EVP_CTRL_CCM_GET_TAG            EVP_CTRL_GCM_GET_TAG
# define         EVP_CTRL_CCM_SET_TAG            EVP_CTRL_GCM_SET_TAG
# define         EVP_CTRL_CCM_SET_L              0x14
# define         EVP_CTRL_CCM_SET_MSGLEN         0x15
/*
 * AEAD cipher deduces payload length and returns number of bytes required to
 * store MAC and eventual padding. Subsequent call to EVP_Cipher even
 * appends/verifies MAC.
 */
# define         EVP_CTRL_AEAD_TLS1_AAD          0x16
/* Used by composite AEAD ciphers, no-op in GCM, CCM... */
# define         EVP_CTRL_AEAD_SET_MAC_KEY       0x17
/* Set the GCM invocation field, decrypt only */
# define         EVP_CTRL_GCM_SET_IV_INV         0x18

# define         EVP_CTRL_TLS1_1_MULTIBLOCK_AAD  0x19
# define         EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT      0x1a
# define         EVP_CTRL_TLS1_1_MULTIBLOCK_DECRYPT      0x1b
# define         EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE  0x1c

/* RFC 5246 defines additional data to be 13 bytes in length */
# define         EVP_AEAD_TLS1_AAD_LEN           13

typedef struct {
    unsigned char *out;
    const unsigned char *inp;
    size_t len;
    unsigned int interleave;
} EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM;

/* GCM TLS constants */
/* Length of fixed part of IV derived from PRF */
# define EVP_GCM_TLS_FIXED_IV_LEN                        4
/* Length of explicit part of IV part of TLS records */
# define EVP_GCM_TLS_EXPLICIT_IV_LEN                     8
/* Length of tag for TLS */
# define EVP_GCM_TLS_TAG_LEN                             16

typedef struct evp_cipher_info_st {
    const EVP_CIPHER *cipher;
    unsigned char iv[EVP_MAX_IV_LENGTH];
} EVP_CIPHER_INFO;

struct evp_cipher_ctx_st {
    const EVP_CIPHER *cipher;
    ENGINE *engine;             /* functional reference if 'cipher' is
                                 * ENGINE-provided */
    int encrypt;                /* encrypt or decrypt */
    int buf_len;                /* number we have left */
    unsigned char oiv[EVP_MAX_IV_LENGTH]; /* original iv */
    unsigned char iv[EVP_MAX_IV_LENGTH]; /* working iv */
    unsigned char buf[EVP_MAX_BLOCK_LENGTH]; /* saved partial block */
    int num;                    /* used by cfb/ofb/ctr mode */
    void *app_data;             /* application stuff */
    int key_len;                /* May change for variable length cipher */
    unsigned long flags;        /* Various flags */
    void *cipher_data;          /* per EVP data */
    int final_used;
    int block_mask;
    unsigned char final[EVP_MAX_BLOCK_LENGTH]; /* possible final block */
} /* EVP_CIPHER_CTX */ ;

typedef struct evp_Encode_Ctx_st {
    /* number saved in a partial encode/decode */
    int num;
    /*
     * The length is either the output line length (in input bytes) or the
     * shortest input line length that is ok.  Once decoding begins, the
     * length is adjusted up each time a longer line is decoded
     */
    int length;
    /* data to encode */
    unsigned char enc_data[80];
    /* number read on current line */
    int line_num;
    int expect_nl;
} EVP_ENCODE_CTX;

/* Password based encryption function */
typedef int (EVP_PBE_KEYGEN) (EVP_CIPHER_CTX *ctx, const char *pass,
                              int passlen, ASN1_TYPE *param,
                              const EVP_CIPHER *cipher, const EVP_MD *md,
                              int en_de);

# ifndef OPENSSL_NO_RSA
#  define EVP_PKEY_assign_RSA(pkey,rsa) EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\
                                        (char *)(rsa))
# endif

# ifndef OPENSSL_NO_DSA
#  define EVP_PKEY_assign_DSA(pkey,dsa) EVP_PKEY_assign((pkey),EVP_PKEY_DSA,\
                                        (char *)(dsa))
# endif

# ifndef OPENSSL_NO_DH
#  define EVP_PKEY_assign_DH(pkey,dh) EVP_PKEY_assign((pkey),EVP_PKEY_DH,\
                                        (char *)(dh))
# endif

# ifndef OPENSSL_NO_EC
#  define EVP_PKEY_assign_EC_KEY(pkey,eckey) EVP_PKEY_assign((pkey),EVP_PKEY_EC,\
                                        (char *)(eckey))
# endif

/* Add some extra combinations */
# define EVP_get_digestbynid(a) EVP_get_digestbyname(OBJ_nid2sn(a))
# define EVP_get_digestbyobj(a) EVP_get_digestbynid(OBJ_obj2nid(a))
# define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a))
# define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a))

int EVP_MD_type(const EVP_MD *md);
# define EVP_MD_nid(e)                   EVP_MD_type(e)
# define EVP_MD_name(e)                  OBJ_nid2sn(EVP_MD_nid(e))
int EVP_MD_pkey_type(const EVP_MD *md);
int EVP_MD_size(const EVP_MD *md);
int EVP_MD_block_size(const EVP_MD *md);
unsigned long EVP_MD_flags(const EVP_MD *md);

const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx);
# define EVP_MD_CTX_size(e)              EVP_MD_size(EVP_MD_CTX_md(e))
# define EVP_MD_CTX_block_size(e)        EVP_MD_block_size(EVP_MD_CTX_md(e))
# define EVP_MD_CTX_type(e)              EVP_MD_type(EVP_MD_CTX_md(e))

int EVP_CIPHER_nid(const EVP_CIPHER *cipher);
# define EVP_CIPHER_name(e)              OBJ_nid2sn(EVP_CIPHER_nid(e))
int EVP_CIPHER_block_size(const EVP_CIPHER *cipher);
int EVP_CIPHER_key_length(const EVP_CIPHER *cipher);
int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher);
unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher);
# define EVP_CIPHER_mode(e)              (EVP_CIPHER_flags(e) & EVP_CIPH_MODE)

const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx);
int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx);
int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx);
int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx);
int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx);
int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in);
void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx);
void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data);
# define EVP_CIPHER_CTX_type(c)         EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c))
unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx);
# define EVP_CIPHER_CTX_mode(e)          (EVP_CIPHER_CTX_flags(e) & EVP_CIPH_MODE)

# define EVP_ENCODE_LENGTH(l)    (((l+2)/3*4)+(l/48+1)*2+80)
# define EVP_DECODE_LENGTH(l)    ((l+3)/4*3+80)

# define EVP_SignInit_ex(a,b,c)          EVP_DigestInit_ex(a,b,c)
# define EVP_SignInit(a,b)               EVP_DigestInit(a,b)
# define EVP_SignUpdate(a,b,c)           EVP_DigestUpdate(a,b,c)
# define EVP_VerifyInit_ex(a,b,c)        EVP_DigestInit_ex(a,b,c)
# define EVP_VerifyInit(a,b)             EVP_DigestInit(a,b)
# define EVP_VerifyUpdate(a,b,c)         EVP_DigestUpdate(a,b,c)
# define EVP_OpenUpdate(a,b,c,d,e)       EVP_DecryptUpdate(a,b,c,d,e)
# define EVP_SealUpdate(a,b,c,d,e)       EVP_EncryptUpdate(a,b,c,d,e)
# define EVP_DigestSignUpdate(a,b,c)     EVP_DigestUpdate(a,b,c)
# define EVP_DigestVerifyUpdate(a,b,c)   EVP_DigestUpdate(a,b,c)

# ifdef CONST_STRICT
void BIO_set_md(BIO *, const EVP_MD *md);
# else
#  define BIO_set_md(b,md)               BIO_ctrl(b,BIO_C_SET_MD,0,(char *)md)
# endif
# define BIO_get_md(b,mdp)               BIO_ctrl(b,BIO_C_GET_MD,0,(char *)mdp)
# define BIO_get_md_ctx(b,mdcp)     BIO_ctrl(b,BIO_C_GET_MD_CTX,0,(char *)mdcp)
# define BIO_set_md_ctx(b,mdcp)     BIO_ctrl(b,BIO_C_SET_MD_CTX,0,(char *)mdcp)
# define BIO_get_cipher_status(b)        BIO_ctrl(b,BIO_C_GET_CIPHER_STATUS,0,NULL)
# define BIO_get_cipher_ctx(b,c_pp)      BIO_ctrl(b,BIO_C_GET_CIPHER_CTX,0,(char *)c_pp)

int EVP_Cipher(EVP_CIPHER_CTX *c,
               unsigned char *out, const unsigned char *in, unsigned int inl);

# define EVP_add_cipher_alias(n,alias) \
        OBJ_NAME_add((alias),OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS,(n))
# define EVP_add_digest_alias(n,alias) \
        OBJ_NAME_add((alias),OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,(n))
# define EVP_delete_cipher_alias(alias) \
        OBJ_NAME_remove(alias,OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS);
# define EVP_delete_digest_alias(alias) \
        OBJ_NAME_remove(alias,OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS);

void EVP_MD_CTX_init(EVP_MD_CTX *ctx);
int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx);
EVP_MD_CTX *EVP_MD_CTX_create(void);
void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx);
int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in);
void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags);
void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags);
int EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags);
int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl);
int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt);
int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s);
int EVP_Digest(const void *data, size_t count,
               unsigned char *md, unsigned int *size, const EVP_MD *type,
               ENGINE *impl);

int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in);
int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type);
int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s);

int EVP_read_pw_string(char *buf, int length, const char *prompt, int verify);
int EVP_read_pw_string_min(char *buf, int minlen, int maxlen,
                           const char *prompt, int verify);
void EVP_set_pw_prompt(const char *prompt);
char *EVP_get_pw_prompt(void);

int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md,
                   const unsigned char *salt, const unsigned char *data,
                   int datal, int count, unsigned char *key,
                   unsigned char *iv);

void EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags);
void EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags);
int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags);

int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
                    const unsigned char *key, const unsigned char *iv);
int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
                       ENGINE *impl, const unsigned char *key,
                       const unsigned char *iv);
int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
                      const unsigned char *in, int inl);
int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);
int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);

int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
                    const unsigned char *key, const unsigned char *iv);
int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
                       ENGINE *impl, const unsigned char *key,
                       const unsigned char *iv);
int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
                      const unsigned char *in, int inl);
int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);

int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
                   const unsigned char *key, const unsigned char *iv,
                   int enc);
int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
                      ENGINE *impl, const unsigned char *key,
                      const unsigned char *iv, int enc);
int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
                     const unsigned char *in, int inl);
int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);

int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s,
                  EVP_PKEY *pkey);

int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
                    unsigned int siglen, EVP_PKEY *pkey);

int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
                       const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey);
int EVP_DigestSignFinal(EVP_MD_CTX *ctx,
                        unsigned char *sigret, size_t *siglen);

int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
                         const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey);
int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx,
                          const unsigned char *sig, size_t siglen);

int EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
                 const unsigned char *ek, int ekl, const unsigned char *iv,
                 EVP_PKEY *priv);
int EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);

int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
                 unsigned char **ek, int *ekl, unsigned char *iv,
                 EVP_PKEY **pubk, int npubk);
int EVP_SealFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);

void EVP_EncodeInit(EVP_ENCODE_CTX *ctx);
void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
                      const unsigned char *in, int inl);
void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl);
int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int n);

void EVP_DecodeInit(EVP_ENCODE_CTX *ctx);
int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
                     const unsigned char *in, int inl);
int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned
                    char *out, int *outl);
int EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n);

void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a);
int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a);
EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void);
void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *a);
int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen);
int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad);
int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr);
int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key);

# ifndef OPENSSL_NO_BIO
BIO_METHOD *BIO_f_md(void);
BIO_METHOD *BIO_f_base64(void);
BIO_METHOD *BIO_f_cipher(void);
BIO_METHOD *BIO_f_reliable(void);
void BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k,
                    const unsigned char *i, int enc);
# endif

const EVP_MD *EVP_md_null(void);
# ifndef OPENSSL_NO_MD2
const EVP_MD *EVP_md2(void);
# endif
# ifndef OPENSSL_NO_MD4
const EVP_MD *EVP_md4(void);
# endif
# ifndef OPENSSL_NO_MD5
const EVP_MD *EVP_md5(void);
# endif
# ifndef OPENSSL_NO_SHA
const EVP_MD *EVP_sha(void);
const EVP_MD *EVP_sha1(void);
const EVP_MD *EVP_dss(void);
const EVP_MD *EVP_dss1(void);
const EVP_MD *EVP_ecdsa(void);
# endif
# ifndef OPENSSL_NO_SHA256
const EVP_MD *EVP_sha224(void);
const EVP_MD *EVP_sha256(void);
# endif
# ifndef OPENSSL_NO_SHA512
const EVP_MD *EVP_sha384(void);
const EVP_MD *EVP_sha512(void);
# endif
# ifndef OPENSSL_NO_MDC2
const EVP_MD *EVP_mdc2(void);
# endif
# ifndef OPENSSL_NO_RIPEMD
const EVP_MD *EVP_ripemd160(void);
# endif
# ifndef OPENSSL_NO_WHIRLPOOL
const EVP_MD *EVP_whirlpool(void);
# endif
const EVP_CIPHER *EVP_enc_null(void); /* does nothing :-) */
# ifndef OPENSSL_NO_DES
const EVP_CIPHER *EVP_des_ecb(void);
const EVP_CIPHER *EVP_des_ede(void);
const EVP_CIPHER *EVP_des_ede3(void);
const EVP_CIPHER *EVP_des_ede_ecb(void);
const EVP_CIPHER *EVP_des_ede3_ecb(void);
const EVP_CIPHER *EVP_des_cfb64(void);
#  define EVP_des_cfb EVP_des_cfb64
const EVP_CIPHER *EVP_des_cfb1(void);
const EVP_CIPHER *EVP_des_cfb8(void);
const EVP_CIPHER *EVP_des_ede_cfb64(void);
#  define EVP_des_ede_cfb EVP_des_ede_cfb64
#  if 0
const EVP_CIPHER *EVP_des_ede_cfb1(void);
const EVP_CIPHER *EVP_des_ede_cfb8(void);
#  endif
const EVP_CIPHER *EVP_des_ede3_cfb64(void);
#  define EVP_des_ede3_cfb EVP_des_ede3_cfb64
const EVP_CIPHER *EVP_des_ede3_cfb1(void);
const EVP_CIPHER *EVP_des_ede3_cfb8(void);
const EVP_CIPHER *EVP_des_ofb(void);
const EVP_CIPHER *EVP_des_ede_ofb(void);
const EVP_CIPHER *EVP_des_ede3_ofb(void);
const EVP_CIPHER *EVP_des_cbc(void);
const EVP_CIPHER *EVP_des_ede_cbc(void);
const EVP_CIPHER *EVP_des_ede3_cbc(void);
const EVP_CIPHER *EVP_desx_cbc(void);
const EVP_CIPHER *EVP_des_ede3_wrap(void);
/*
 * This should now be supported through the dev_crypto ENGINE. But also, why
 * are rc4 and md5 declarations made here inside a "NO_DES" precompiler
 * branch?
 */
#  if 0
#   ifdef OPENSSL_OPENBSD_DEV_CRYPTO
const EVP_CIPHER *EVP_dev_crypto_des_ede3_cbc(void);
const EVP_CIPHER *EVP_dev_crypto_rc4(void);
const EVP_MD *EVP_dev_crypto_md5(void);
#   endif
#  endif
# endif
# ifndef OPENSSL_NO_RC4
const EVP_CIPHER *EVP_rc4(void);
const EVP_CIPHER *EVP_rc4_40(void);
#  ifndef OPENSSL_NO_MD5
const EVP_CIPHER *EVP_rc4_hmac_md5(void);
#  endif
# endif
# ifndef OPENSSL_NO_IDEA
const EVP_CIPHER *EVP_idea_ecb(void);
const EVP_CIPHER *EVP_idea_cfb64(void);
#  define EVP_idea_cfb EVP_idea_cfb64
const EVP_CIPHER *EVP_idea_ofb(void);
const EVP_CIPHER *EVP_idea_cbc(void);
# endif
# ifndef OPENSSL_NO_RC2
const EVP_CIPHER *EVP_rc2_ecb(void);
const EVP_CIPHER *EVP_rc2_cbc(void);
const EVP_CIPHER *EVP_rc2_40_cbc(void);
const EVP_CIPHER *EVP_rc2_64_cbc(void);
const EVP_CIPHER *EVP_rc2_cfb64(void);
#  define EVP_rc2_cfb EVP_rc2_cfb64
const EVP_CIPHER *EVP_rc2_ofb(void);
# endif
# ifndef OPENSSL_NO_BF
const EVP_CIPHER *EVP_bf_ecb(void);
const EVP_CIPHER *EVP_bf_cbc(void);
const EVP_CIPHER *EVP_bf_cfb64(void);
#  define EVP_bf_cfb EVP_bf_cfb64
const EVP_CIPHER *EVP_bf_ofb(void);
# endif
# ifndef OPENSSL_NO_CAST
const EVP_CIPHER *EVP_cast5_ecb(void);
const EVP_CIPHER *EVP_cast5_cbc(void);
const EVP_CIPHER *EVP_cast5_cfb64(void);
#  define EVP_cast5_cfb EVP_cast5_cfb64
const EVP_CIPHER *EVP_cast5_ofb(void);
# endif
# ifndef OPENSSL_NO_RC5
const EVP_CIPHER *EVP_rc5_32_12_16_cbc(void);
const EVP_CIPHER *EVP_rc5_32_12_16_ecb(void);
const EVP_CIPHER *EVP_rc5_32_12_16_cfb64(void);
#  define EVP_rc5_32_12_16_cfb EVP_rc5_32_12_16_cfb64
const EVP_CIPHER *EVP_rc5_32_12_16_ofb(void);
# endif
# ifndef OPENSSL_NO_AES
const EVP_CIPHER *EVP_aes_128_ecb(void);
const EVP_CIPHER *EVP_aes_128_cbc(void);
const EVP_CIPHER *EVP_aes_128_cfb1(void);
const EVP_CIPHER *EVP_aes_128_cfb8(void);
const EVP_CIPHER *EVP_aes_128_cfb128(void);
#  define EVP_aes_128_cfb EVP_aes_128_cfb128
const EVP_CIPHER *EVP_aes_128_ofb(void);
const EVP_CIPHER *EVP_aes_128_ctr(void);
const EVP_CIPHER *EVP_aes_128_ccm(void);
const EVP_CIPHER *EVP_aes_128_gcm(void);
const EVP_CIPHER *EVP_aes_128_xts(void);
const EVP_CIPHER *EVP_aes_128_wrap(void);
const EVP_CIPHER *EVP_aes_128_wrap_pad(void);
const EVP_CIPHER *EVP_aes_192_ecb(void);
const EVP_CIPHER *EVP_aes_192_cbc(void);
const EVP_CIPHER *EVP_aes_192_cfb1(void);
const EVP_CIPHER *EVP_aes_192_cfb8(void);
const EVP_CIPHER *EVP_aes_192_cfb128(void);
#  define EVP_aes_192_cfb EVP_aes_192_cfb128
const EVP_CIPHER *EVP_aes_192_ofb(void);
const EVP_CIPHER *EVP_aes_192_ctr(void);
const EVP_CIPHER *EVP_aes_192_ccm(void);
const EVP_CIPHER *EVP_aes_192_gcm(void);
const EVP_CIPHER *EVP_aes_192_wrap(void);
const EVP_CIPHER *EVP_aes_192_wrap_pad(void);
const EVP_CIPHER *EVP_aes_256_ecb(void);
const EVP_CIPHER *EVP_aes_256_cbc(void);
const EVP_CIPHER *EVP_aes_256_cfb1(void);
const EVP_CIPHER *EVP_aes_256_cfb8(void);
const EVP_CIPHER *EVP_aes_256_cfb128(void);
#  define EVP_aes_256_cfb EVP_aes_256_cfb128
const EVP_CIPHER *EVP_aes_256_ofb(void);
const EVP_CIPHER *EVP_aes_256_ctr(void);
const EVP_CIPHER *EVP_aes_256_ccm(void);
const EVP_CIPHER *EVP_aes_256_gcm(void);
const EVP_CIPHER *EVP_aes_256_xts(void);
const EVP_CIPHER *EVP_aes_256_wrap(void);
const EVP_CIPHER *EVP_aes_256_wrap_pad(void);
#  if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void);
const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void);
#  endif
#  ifndef OPENSSL_NO_SHA256
const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha256(void);
const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha256(void);
#  endif
# endif
# ifndef OPENSSL_NO_CAMELLIA
const EVP_CIPHER *EVP_camellia_128_ecb(void);
const EVP_CIPHER *EVP_camellia_128_cbc(void);
const EVP_CIPHER *EVP_camellia_128_cfb1(void);
const EVP_CIPHER *EVP_camellia_128_cfb8(void);
const EVP_CIPHER *EVP_camellia_128_cfb128(void);
#  define EVP_camellia_128_cfb EVP_camellia_128_cfb128
const EVP_CIPHER *EVP_camellia_128_ofb(void);
const EVP_CIPHER *EVP_camellia_192_ecb(void);
const EVP_CIPHER *EVP_camellia_192_cbc(void);
const EVP_CIPHER *EVP_camellia_192_cfb1(void);
const EVP_CIPHER *EVP_camellia_192_cfb8(void);
const EVP_CIPHER *EVP_camellia_192_cfb128(void);
#  define EVP_camellia_192_cfb EVP_camellia_192_cfb128
const EVP_CIPHER *EVP_camellia_192_ofb(void);
const EVP_CIPHER *EVP_camellia_256_ecb(void);
const EVP_CIPHER *EVP_camellia_256_cbc(void);
const EVP_CIPHER *EVP_camellia_256_cfb1(void);
const EVP_CIPHER *EVP_camellia_256_cfb8(void);
const EVP_CIPHER *EVP_camellia_256_cfb128(void);
#  define EVP_camellia_256_cfb EVP_camellia_256_cfb128
const EVP_CIPHER *EVP_camellia_256_ofb(void);
# endif

# ifndef OPENSSL_NO_SEED
const EVP_CIPHER *EVP_seed_ecb(void);
const EVP_CIPHER *EVP_seed_cbc(void);
const EVP_CIPHER *EVP_seed_cfb128(void);
#  define EVP_seed_cfb EVP_seed_cfb128
const EVP_CIPHER *EVP_seed_ofb(void);
# endif

void OPENSSL_add_all_algorithms_noconf(void);
void OPENSSL_add_all_algorithms_conf(void);

# ifdef OPENSSL_LOAD_CONF
#  define OpenSSL_add_all_algorithms() \
                OPENSSL_add_all_algorithms_conf()
# else
#  define OpenSSL_add_all_algorithms() \
                OPENSSL_add_all_algorithms_noconf()
# endif

void OpenSSL_add_all_ciphers(void);
void OpenSSL_add_all_digests(void);
# define SSLeay_add_all_algorithms() OpenSSL_add_all_algorithms()
# define SSLeay_add_all_ciphers() OpenSSL_add_all_ciphers()
# define SSLeay_add_all_digests() OpenSSL_add_all_digests()

int EVP_add_cipher(const EVP_CIPHER *cipher);
int EVP_add_digest(const EVP_MD *digest);

const EVP_CIPHER *EVP_get_cipherbyname(const char *name);
const EVP_MD *EVP_get_digestbyname(const char *name);
void EVP_cleanup(void);

void EVP_CIPHER_do_all(void (*fn) (const EVP_CIPHER *ciph,
                                   const char *from, const char *to, void *x),
                       void *arg);
void EVP_CIPHER_do_all_sorted(void (*fn)
                               (const EVP_CIPHER *ciph, const char *from,
                                const char *to, void *x), void *arg);

void EVP_MD_do_all(void (*fn) (const EVP_MD *ciph,
                               const char *from, const char *to, void *x),
                   void *arg);
void EVP_MD_do_all_sorted(void (*fn)
                           (const EVP_MD *ciph, const char *from,
                            const char *to, void *x), void *arg);

int EVP_PKEY_decrypt_old(unsigned char *dec_key,
                         const unsigned char *enc_key, int enc_key_len,
                         EVP_PKEY *private_key);
int EVP_PKEY_encrypt_old(unsigned char *enc_key,
                         const unsigned char *key, int key_len,
                         EVP_PKEY *pub_key);
int EVP_PKEY_type(int type);
int EVP_PKEY_id(const EVP_PKEY *pkey);
int EVP_PKEY_base_id(const EVP_PKEY *pkey);
int EVP_PKEY_bits(EVP_PKEY *pkey);
int EVP_PKEY_size(EVP_PKEY *pkey);
int EVP_PKEY_set_type(EVP_PKEY *pkey, int type);
int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len);
int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key);
void *EVP_PKEY_get0(EVP_PKEY *pkey);

# ifndef OPENSSL_NO_RSA
struct rsa_st;
int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, struct rsa_st *key);
struct rsa_st *EVP_PKEY_get1_RSA(EVP_PKEY *pkey);
# endif
# ifndef OPENSSL_NO_DSA
struct dsa_st;
int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, struct dsa_st *key);
struct dsa_st *EVP_PKEY_get1_DSA(EVP_PKEY *pkey);
# endif
# ifndef OPENSSL_NO_DH
struct dh_st;
int EVP_PKEY_set1_DH(EVP_PKEY *pkey, struct dh_st *key);
struct dh_st *EVP_PKEY_get1_DH(EVP_PKEY *pkey);
# endif
# ifndef OPENSSL_NO_EC
struct ec_key_st;
int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, struct ec_key_st *key);
struct ec_key_st *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey);
# endif

EVP_PKEY *EVP_PKEY_new(void);
void EVP_PKEY_free(EVP_PKEY *pkey);

EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp,
                        long length);
int i2d_PublicKey(EVP_PKEY *a, unsigned char **pp);

EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
                         long length);
EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp,
                             long length);
int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp);

int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from);
int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey);
int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode);
int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b);

int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b);

int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
                          int indent, ASN1_PCTX *pctx);
int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
                           int indent, ASN1_PCTX *pctx);
int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
                          int indent, ASN1_PCTX *pctx);

int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid);

int EVP_CIPHER_type(const EVP_CIPHER *ctx);

/* calls methods */
int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type);

/* These are used by EVP_CIPHER methods */
int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type);

/* PKCS5 password based encryption */
int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
                       ASN1_TYPE *param, const EVP_CIPHER *cipher,
                       const EVP_MD *md, int en_de);
int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
                           const unsigned char *salt, int saltlen, int iter,
                           int keylen, unsigned char *out);
int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
                      const unsigned char *salt, int saltlen, int iter,
                      const EVP_MD *digest, int keylen, unsigned char *out);
int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
                          ASN1_TYPE *param, const EVP_CIPHER *cipher,
                          const EVP_MD *md, int en_de);

void PKCS5_PBE_add(void);

int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
                       ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de);

/* PBE type */

/* Can appear as the outermost AlgorithmIdentifier */
# define EVP_PBE_TYPE_OUTER      0x0
/* Is an PRF type OID */
# define EVP_PBE_TYPE_PRF        0x1

int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid,
                         int md_nid, EVP_PBE_KEYGEN *keygen);
int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
                    EVP_PBE_KEYGEN *keygen);
int EVP_PBE_find(int type, int pbe_nid, int *pcnid, int *pmnid,
                 EVP_PBE_KEYGEN **pkeygen);
void EVP_PBE_cleanup(void);

# define ASN1_PKEY_ALIAS         0x1
# define ASN1_PKEY_DYNAMIC       0x2
# define ASN1_PKEY_SIGPARAM_NULL 0x4

# define ASN1_PKEY_CTRL_PKCS7_SIGN       0x1
# define ASN1_PKEY_CTRL_PKCS7_ENCRYPT    0x2
# define ASN1_PKEY_CTRL_DEFAULT_MD_NID   0x3
# define ASN1_PKEY_CTRL_CMS_SIGN         0x5
# define ASN1_PKEY_CTRL_CMS_ENVELOPE     0x7
# define ASN1_PKEY_CTRL_CMS_RI_TYPE      0x8

int EVP_PKEY_asn1_get_count(void);
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx);
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type);
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
                                                   const char *str, int len);
int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth);
int EVP_PKEY_asn1_add_alias(int to, int from);
int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *pkey_base_id,
                            int *ppkey_flags, const char **pinfo,
                            const char **ppem_str,
                            const EVP_PKEY_ASN1_METHOD *ameth);

const EVP_PKEY_ASN1_METHOD *EVP_PKEY_get0_asn1(EVP_PKEY *pkey);
EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags,
                                        const char *pem_str,
                                        const char *info);
void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst,
                        const EVP_PKEY_ASN1_METHOD *src);
void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth);
void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth,
                              int (*pub_decode) (EVP_PKEY *pk,
                                                 X509_PUBKEY *pub),
                              int (*pub_encode) (X509_PUBKEY *pub,
                                                 const EVP_PKEY *pk),
                              int (*pub_cmp) (const EVP_PKEY *a,
                                              const EVP_PKEY *b),
                              int (*pub_print) (BIO *out,
                                                const EVP_PKEY *pkey,
                                                int indent, ASN1_PCTX *pctx),
                              int (*pkey_size) (const EVP_PKEY *pk),
                              int (*pkey_bits) (const EVP_PKEY *pk));
void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth,
                               int (*priv_decode) (EVP_PKEY *pk,
                                                   PKCS8_PRIV_KEY_INFO
                                                   *p8inf),
                               int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8,
                                                   const EVP_PKEY *pk),
                               int (*priv_print) (BIO *out,
                                                  const EVP_PKEY *pkey,
                                                  int indent,
                                                  ASN1_PCTX *pctx));
void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth,
                             int (*param_decode) (EVP_PKEY *pkey,
                                                  const unsigned char **pder,
                                                  int derlen),
                             int (*param_encode) (const EVP_PKEY *pkey,
                                                  unsigned char **pder),
                             int (*param_missing) (const EVP_PKEY *pk),
                             int (*param_copy) (EVP_PKEY *to,
                                                const EVP_PKEY *from),
                             int (*param_cmp) (const EVP_PKEY *a,
                                               const EVP_PKEY *b),
                             int (*param_print) (BIO *out,
                                                 const EVP_PKEY *pkey,
                                                 int indent,
                                                 ASN1_PCTX *pctx));

void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth,
                            void (*pkey_free) (EVP_PKEY *pkey));
void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
                            int (*pkey_ctrl) (EVP_PKEY *pkey, int op,
                                              long arg1, void *arg2));
void EVP_PKEY_asn1_set_item(EVP_PKEY_ASN1_METHOD *ameth,
                            int (*item_verify) (EVP_MD_CTX *ctx,
                                                const ASN1_ITEM *it,
                                                void *asn,
                                                X509_ALGOR *a,
                                                ASN1_BIT_STRING *sig,
                                                EVP_PKEY *pkey),
                            int (*item_sign) (EVP_MD_CTX *ctx,
                                              const ASN1_ITEM *it,
                                              void *asn,
                                              X509_ALGOR *alg1,
                                              X509_ALGOR *alg2,
                                              ASN1_BIT_STRING *sig));

# define EVP_PKEY_OP_UNDEFINED           0
# define EVP_PKEY_OP_PARAMGEN            (1<<1)
# define EVP_PKEY_OP_KEYGEN              (1<<2)
# define EVP_PKEY_OP_SIGN                (1<<3)
# define EVP_PKEY_OP_VERIFY              (1<<4)
# define EVP_PKEY_OP_VERIFYRECOVER       (1<<5)
# define EVP_PKEY_OP_SIGNCTX             (1<<6)
# define EVP_PKEY_OP_VERIFYCTX           (1<<7)
# define EVP_PKEY_OP_ENCRYPT             (1<<8)
# define EVP_PKEY_OP_DECRYPT             (1<<9)
# define EVP_PKEY_OP_DERIVE              (1<<10)

# define EVP_PKEY_OP_TYPE_SIG    \
        (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYRECOVER \
                | EVP_PKEY_OP_SIGNCTX | EVP_PKEY_OP_VERIFYCTX)

# define EVP_PKEY_OP_TYPE_CRYPT \
        (EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT)

# define EVP_PKEY_OP_TYPE_NOGEN \
        (EVP_PKEY_OP_SIG | EVP_PKEY_OP_CRYPT | EVP_PKEY_OP_DERIVE)

# define EVP_PKEY_OP_TYPE_GEN \
                (EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN)

# define  EVP_PKEY_CTX_set_signature_md(ctx, md) \
                EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG,  \
                                        EVP_PKEY_CTRL_MD, 0, (void *)md)

# define  EVP_PKEY_CTX_get_signature_md(ctx, pmd)        \
                EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG,  \
                                        EVP_PKEY_CTRL_GET_MD, 0, (void *)pmd)

# define EVP_PKEY_CTRL_MD                1
# define EVP_PKEY_CTRL_PEER_KEY          2

# define EVP_PKEY_CTRL_PKCS7_ENCRYPT     3
# define EVP_PKEY_CTRL_PKCS7_DECRYPT     4

# define EVP_PKEY_CTRL_PKCS7_SIGN        5

# define EVP_PKEY_CTRL_SET_MAC_KEY       6

# define EVP_PKEY_CTRL_DIGESTINIT        7

/* Used by GOST key encryption in TLS */
# define EVP_PKEY_CTRL_SET_IV            8

# define EVP_PKEY_CTRL_CMS_ENCRYPT       9
# define EVP_PKEY_CTRL_CMS_DECRYPT       10
# define EVP_PKEY_CTRL_CMS_SIGN          11

# define EVP_PKEY_CTRL_CIPHER            12

# define EVP_PKEY_CTRL_GET_MD            13

# define EVP_PKEY_ALG_CTRL               0x1000

# define EVP_PKEY_FLAG_AUTOARGLEN        2
/*
 * Method handles all operations: don't assume any digest related defaults.
 */
# define EVP_PKEY_FLAG_SIGCTX_CUSTOM     4

const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type);
EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags);
void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags,
                             const EVP_PKEY_METHOD *meth);
void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src);
void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth);
int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth);

EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e);
EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx);
void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);

int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
                      int cmd, int p1, void *p2);
int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
                          const char *value);

int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx);
void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen);

EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e,
                               const unsigned char *key, int keylen);

void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data);
void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx);
EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx);

EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx);

void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data);
void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx);

int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx);
int EVP_PKEY_sign(EVP_PKEY_CTX *ctx,
                  unsigned char *sig, size_t *siglen,
                  const unsigned char *tbs, size_t tbslen);
int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx);
int EVP_PKEY_verify(EVP_PKEY_CTX *ctx,
                    const unsigned char *sig, size_t siglen,
                    const unsigned char *tbs, size_t tbslen);
int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx);
int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx,
                            unsigned char *rout, size_t *routlen,
                            const unsigned char *sig, size_t siglen);
int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx);
int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
                     unsigned char *out, size_t *outlen,
                     const unsigned char *in, size_t inlen);
int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx);
int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
                     unsigned char *out, size_t *outlen,
                     const unsigned char *in, size_t inlen);

int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx);
int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer);
int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);

typedef int EVP_PKEY_gen_cb (EVP_PKEY_CTX *ctx);

int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx);
int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx);
int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);

void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb);
EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx);

int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx);

void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth,
                            int (*init) (EVP_PKEY_CTX *ctx));

void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth,
                            int (*copy) (EVP_PKEY_CTX *dst,
                                         EVP_PKEY_CTX *src));

void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth,
                               void (*cleanup) (EVP_PKEY_CTX *ctx));

void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth,
                                int (*paramgen_init) (EVP_PKEY_CTX *ctx),
                                int (*paramgen) (EVP_PKEY_CTX *ctx,
                                                 EVP_PKEY *pkey));

void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth,
                              int (*keygen_init) (EVP_PKEY_CTX *ctx),
                              int (*keygen) (EVP_PKEY_CTX *ctx,
                                             EVP_PKEY *pkey));

void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth,
                            int (*sign_init) (EVP_PKEY_CTX *ctx),
                            int (*sign) (EVP_PKEY_CTX *ctx,
                                         unsigned char *sig, size_t *siglen,
                                         const unsigned char *tbs,
                                         size_t tbslen));

void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth,
                              int (*verify_init) (EVP_PKEY_CTX *ctx),
                              int (*verify) (EVP_PKEY_CTX *ctx,
                                             const unsigned char *sig,
                                             size_t siglen,
                                             const unsigned char *tbs,
                                             size_t tbslen));

void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth,
                                      int (*verify_recover_init) (EVP_PKEY_CTX
                                                                  *ctx),
                                      int (*verify_recover) (EVP_PKEY_CTX
                                                             *ctx,
                                                             unsigned char
                                                             *sig,
                                                             size_t *siglen,
                                                             const unsigned
                                                             char *tbs,
                                                             size_t tbslen));

void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth,
                               int (*signctx_init) (EVP_PKEY_CTX *ctx,
                                                    EVP_MD_CTX *mctx),
                               int (*signctx) (EVP_PKEY_CTX *ctx,
                                               unsigned char *sig,
                                               size_t *siglen,
                                               EVP_MD_CTX *mctx));

void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth,
                                 int (*verifyctx_init) (EVP_PKEY_CTX *ctx,
                                                        EVP_MD_CTX *mctx),
                                 int (*verifyctx) (EVP_PKEY_CTX *ctx,
                                                   const unsigned char *sig,
                                                   int siglen,
                                                   EVP_MD_CTX *mctx));

void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth,
                               int (*encrypt_init) (EVP_PKEY_CTX *ctx),
                               int (*encryptfn) (EVP_PKEY_CTX *ctx,
                                                 unsigned char *out,
                                                 size_t *outlen,
                                                 const unsigned char *in,
                                                 size_t inlen));

void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth,
                               int (*decrypt_init) (EVP_PKEY_CTX *ctx),
                               int (*decrypt) (EVP_PKEY_CTX *ctx,
                                               unsigned char *out,
                                               size_t *outlen,
                                               const unsigned char *in,
                                               size_t inlen));

void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth,
                              int (*derive_init) (EVP_PKEY_CTX *ctx),
                              int (*derive) (EVP_PKEY_CTX *ctx,
                                             unsigned char *key,
                                             size_t *keylen));

void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
                            int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1,
                                         void *p2),
                            int (*ctrl_str) (EVP_PKEY_CTX *ctx,
                                             const char *type,
                                             const char *value));

void EVP_PKEY_meth_get_init(EVP_PKEY_METHOD *pmeth,
                            int (**pinit) (EVP_PKEY_CTX *ctx));

void EVP_PKEY_meth_get_copy(EVP_PKEY_METHOD *pmeth,
                            int (**pcopy) (EVP_PKEY_CTX *dst,
                                           EVP_PKEY_CTX *src));

void EVP_PKEY_meth_get_cleanup(EVP_PKEY_METHOD *pmeth,
                               void (**pcleanup) (EVP_PKEY_CTX *ctx));

void EVP_PKEY_meth_get_paramgen(EVP_PKEY_METHOD *pmeth,
                                int (**pparamgen_init) (EVP_PKEY_CTX *ctx),
                                int (**pparamgen) (EVP_PKEY_CTX *ctx,
                                                   EVP_PKEY *pkey));

void EVP_PKEY_meth_get_keygen(EVP_PKEY_METHOD *pmeth,
                              int (**pkeygen_init) (EVP_PKEY_CTX *ctx),
                              int (**pkeygen) (EVP_PKEY_CTX *ctx,
                                               EVP_PKEY *pkey));

void EVP_PKEY_meth_get_sign(EVP_PKEY_METHOD *pmeth,
                            int (**psign_init) (EVP_PKEY_CTX *ctx),
                            int (**psign) (EVP_PKEY_CTX *ctx,
                                           unsigned char *sig, size_t *siglen,
                                           const unsigned char *tbs,
                                           size_t tbslen));

void EVP_PKEY_meth_get_verify(EVP_PKEY_METHOD *pmeth,
                              int (**pverify_init) (EVP_PKEY_CTX *ctx),
                              int (**pverify) (EVP_PKEY_CTX *ctx,
                                               const unsigned char *sig,
                                               size_t siglen,
                                               const unsigned char *tbs,
                                               size_t tbslen));

void EVP_PKEY_meth_get_verify_recover(EVP_PKEY_METHOD *pmeth,
                                      int (**pverify_recover_init) (EVP_PKEY_CTX
                                                                    *ctx),
                                      int (**pverify_recover) (EVP_PKEY_CTX
                                                               *ctx,
                                                               unsigned char
                                                               *sig,
                                                               size_t *siglen,
                                                               const unsigned
                                                               char *tbs,
                                                               size_t tbslen));

void EVP_PKEY_meth_get_signctx(EVP_PKEY_METHOD *pmeth,
                               int (**psignctx_init) (EVP_PKEY_CTX *ctx,
                                                      EVP_MD_CTX *mctx),
                               int (**psignctx) (EVP_PKEY_CTX *ctx,
                                                 unsigned char *sig,
                                                 size_t *siglen,
                                                 EVP_MD_CTX *mctx));

void EVP_PKEY_meth_get_verifyctx(EVP_PKEY_METHOD *pmeth,
                                 int (**pverifyctx_init) (EVP_PKEY_CTX *ctx,
                                                          EVP_MD_CTX *mctx),
                                 int (**pverifyctx) (EVP_PKEY_CTX *ctx,
                                                     const unsigned char *sig,
                                                     int siglen,
                                                     EVP_MD_CTX *mctx));

void EVP_PKEY_meth_get_encrypt(EVP_PKEY_METHOD *pmeth,
                               int (**pencrypt_init) (EVP_PKEY_CTX *ctx),
                               int (**pencryptfn) (EVP_PKEY_CTX *ctx,
                                                   unsigned char *out,
                                                   size_t *outlen,
                                                   const unsigned char *in,
                                                   size_t inlen));

void EVP_PKEY_meth_get_decrypt(EVP_PKEY_METHOD *pmeth,
                               int (**pdecrypt_init) (EVP_PKEY_CTX *ctx),
                               int (**pdecrypt) (EVP_PKEY_CTX *ctx,
                                                 unsigned char *out,
                                                 size_t *outlen,
                                                 const unsigned char *in,
                                                 size_t inlen));

void EVP_PKEY_meth_get_derive(EVP_PKEY_METHOD *pmeth,
                              int (**pderive_init) (EVP_PKEY_CTX *ctx),
                              int (**pderive) (EVP_PKEY_CTX *ctx,
                                               unsigned char *key,
                                               size_t *keylen));

void EVP_PKEY_meth_get_ctrl(EVP_PKEY_METHOD *pmeth,
                            int (**pctrl) (EVP_PKEY_CTX *ctx, int type, int p1,
                                           void *p2),
                            int (**pctrl_str) (EVP_PKEY_CTX *ctx,
                                               const char *type,
                                               const char *value));

void EVP_add_alg_module(void);

/* BEGIN ERROR CODES */
/*
 * The following lines are auto generated by the script mkerr.pl. Any changes
 * made after this point may be overwritten when the script is next run.
 */

void ERR_load_EVP_strings(void);

/* Error codes for the EVP functions. */

/* Function codes. */
# define EVP_F_AESNI_INIT_KEY                             165
# define EVP_F_AESNI_XTS_CIPHER                           176
# define EVP_F_AES_INIT_KEY                               133
# define EVP_F_AES_T4_INIT_KEY                            178
# define EVP_F_AES_XTS                                    172
# define EVP_F_AES_XTS_CIPHER                             175
# define EVP_F_ALG_MODULE_INIT                            177
# define EVP_F_CAMELLIA_INIT_KEY                          159
# define EVP_F_CMAC_INIT                                  173
# define EVP_F_CMLL_T4_INIT_KEY                           179
# define EVP_F_D2I_PKEY                                   100
# define EVP_F_DO_SIGVER_INIT                             161
# define EVP_F_DSAPKEY2PKCS8                              134
# define EVP_F_DSA_PKEY2PKCS8                             135
# define EVP_F_ECDSA_PKEY2PKCS8                           129
# define EVP_F_ECKEY_PKEY2PKCS8                           132
# define EVP_F_EVP_CIPHERINIT_EX                          123
# define EVP_F_EVP_CIPHER_CTX_COPY                        163
# define EVP_F_EVP_CIPHER_CTX_CTRL                        124
# define EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH              122
# define EVP_F_EVP_DECRYPTFINAL_EX                        101
# define EVP_F_EVP_DECRYPTUPDATE                          181
# define EVP_F_EVP_DIGESTINIT_EX                          128
# define EVP_F_EVP_ENCRYPTFINAL_EX                        127
# define EVP_F_EVP_ENCRYPTUPDATE                          180
# define EVP_F_EVP_MD_CTX_COPY_EX                         110
# define EVP_F_EVP_MD_SIZE                                162
# define EVP_F_EVP_OPENINIT                               102
# define EVP_F_EVP_PBE_ALG_ADD                            115
# define EVP_F_EVP_PBE_ALG_ADD_TYPE                       160
# define EVP_F_EVP_PBE_CIPHERINIT                         116
# define EVP_F_EVP_PKCS82PKEY                             111
# define EVP_F_EVP_PKCS82PKEY_BROKEN                      136
# define EVP_F_EVP_PKEY2PKCS8_BROKEN                      113
# define EVP_F_EVP_PKEY_COPY_PARAMETERS                   103
# define EVP_F_EVP_PKEY_CTX_CTRL                          137
# define EVP_F_EVP_PKEY_CTX_CTRL_STR                      150
# define EVP_F_EVP_PKEY_CTX_DUP                           156
# define EVP_F_EVP_PKEY_DECRYPT                           104
# define EVP_F_EVP_PKEY_DECRYPT_INIT                      138
# define EVP_F_EVP_PKEY_DECRYPT_OLD                       151
# define EVP_F_EVP_PKEY_DERIVE                            153
# define EVP_F_EVP_PKEY_DERIVE_INIT                       154
# define EVP_F_EVP_PKEY_DERIVE_SET_PEER                   155
# define EVP_F_EVP_PKEY_ENCRYPT                           105
# define EVP_F_EVP_PKEY_ENCRYPT_INIT                      139
# define EVP_F_EVP_PKEY_ENCRYPT_OLD                       152
# define EVP_F_EVP_PKEY_GET1_DH                           119
# define EVP_F_EVP_PKEY_GET1_DSA                          120
# define EVP_F_EVP_PKEY_GET1_ECDSA                        130
# define EVP_F_EVP_PKEY_GET1_EC_KEY                       131
# define EVP_F_EVP_PKEY_GET1_RSA                          121
# define EVP_F_EVP_PKEY_KEYGEN                            146
# define EVP_F_EVP_PKEY_KEYGEN_INIT                       147
# define EVP_F_EVP_PKEY_NEW                               106
# define EVP_F_EVP_PKEY_PARAMGEN                          148
# define EVP_F_EVP_PKEY_PARAMGEN_INIT                     149
# define EVP_F_EVP_PKEY_SIGN                              140
# define EVP_F_EVP_PKEY_SIGN_INIT                         141
# define EVP_F_EVP_PKEY_VERIFY                            142
# define EVP_F_EVP_PKEY_VERIFY_INIT                       143
# define EVP_F_EVP_PKEY_VERIFY_RECOVER                    144
# define EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT               145
# define EVP_F_EVP_RIJNDAEL                               126
# define EVP_F_EVP_SIGNFINAL                              107
# define EVP_F_EVP_VERIFYFINAL                            108
# define EVP_F_FIPS_CIPHERINIT                            166
# define EVP_F_FIPS_CIPHER_CTX_COPY                       170
# define EVP_F_FIPS_CIPHER_CTX_CTRL                       167
# define EVP_F_FIPS_CIPHER_CTX_SET_KEY_LENGTH             171
# define EVP_F_FIPS_DIGESTINIT                            168
# define EVP_F_FIPS_MD_CTX_COPY                           169
# define EVP_F_HMAC_INIT_EX                               174
# define EVP_F_INT_CTX_NEW                                157
# define EVP_F_PKCS5_PBE_KEYIVGEN                         117
# define EVP_F_PKCS5_V2_PBE_KEYIVGEN                      118
# define EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN                   164
# define EVP_F_PKCS8_SET_BROKEN                           112
# define EVP_F_PKEY_SET_TYPE                              158
# define EVP_F_RC2_MAGIC_TO_METH                          109
# define EVP_F_RC5_CTRL                                   125

/* Reason codes. */
# define EVP_R_AES_IV_SETUP_FAILED                        162
# define EVP_R_AES_KEY_SETUP_FAILED                       143
# define EVP_R_ASN1_LIB                                   140
# define EVP_R_BAD_BLOCK_LENGTH                           136
# define EVP_R_BAD_DECRYPT                                100
# define EVP_R_BAD_KEY_LENGTH                             137
# define EVP_R_BN_DECODE_ERROR                            112
# define EVP_R_BN_PUBKEY_ERROR                            113
# define EVP_R_BUFFER_TOO_SMALL                           155
# define EVP_R_CAMELLIA_KEY_SETUP_FAILED                  157
# define EVP_R_CIPHER_PARAMETER_ERROR                     122
# define EVP_R_COMMAND_NOT_SUPPORTED                      147
# define EVP_R_CTRL_NOT_IMPLEMENTED                       132
# define EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED             133
# define EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH          138
# define EVP_R_DECODE_ERROR                               114
# define EVP_R_DIFFERENT_KEY_TYPES                        101
# define EVP_R_DIFFERENT_PARAMETERS                       153
# define EVP_R_DISABLED_FOR_FIPS                          163
# define EVP_R_ENCODE_ERROR                               115
# define EVP_R_ERROR_LOADING_SECTION                      165
# define EVP_R_ERROR_SETTING_FIPS_MODE                    166
# define EVP_R_EVP_PBE_CIPHERINIT_ERROR                   119
# define EVP_R_EXPECTING_AN_RSA_KEY                       127
# define EVP_R_EXPECTING_A_DH_KEY                         128
# define EVP_R_EXPECTING_A_DSA_KEY                        129
# define EVP_R_EXPECTING_A_ECDSA_KEY                      141
# define EVP_R_EXPECTING_A_EC_KEY                         142
# define EVP_R_FIPS_MODE_NOT_SUPPORTED                    167
# define EVP_R_INITIALIZATION_ERROR                       134
# define EVP_R_INPUT_NOT_INITIALIZED                      111
# define EVP_R_INVALID_DIGEST                             152
# define EVP_R_INVALID_FIPS_MODE                          168
# define EVP_R_INVALID_KEY                                171
# define EVP_R_INVALID_KEY_LENGTH                         130
# define EVP_R_INVALID_OPERATION                          148
# define EVP_R_IV_TOO_LARGE                               102
# define EVP_R_KEYGEN_FAILURE                             120
# define EVP_R_MESSAGE_DIGEST_IS_NULL                     159
# define EVP_R_METHOD_NOT_SUPPORTED                       144
# define EVP_R_MISSING_PARAMETERS                         103
# define EVP_R_NO_CIPHER_SET                              131
# define EVP_R_NO_DEFAULT_DIGEST                          158
# define EVP_R_NO_DIGEST_SET                              139
# define EVP_R_NO_DSA_PARAMETERS                          116
# define EVP_R_NO_KEY_SET                                 154
# define EVP_R_NO_OPERATION_SET                           149
# define EVP_R_NO_SIGN_FUNCTION_CONFIGURED                104
# define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED              105
# define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE   150
# define EVP_R_OPERATON_NOT_INITIALIZED                   151
# define EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE                  117
# define EVP_R_PRIVATE_KEY_DECODE_ERROR                   145
# define EVP_R_PRIVATE_KEY_ENCODE_ERROR                   146
# define EVP_R_PUBLIC_KEY_NOT_RSA                         106
# define EVP_R_TOO_LARGE                                  164
# define EVP_R_UNKNOWN_CIPHER                             160
# define EVP_R_UNKNOWN_DIGEST                             161
# define EVP_R_UNKNOWN_OPTION                             169
# define EVP_R_UNKNOWN_PBE_ALGORITHM                      121
# define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS                135
# define EVP_R_UNSUPPORTED_ALGORITHM                      156
# define EVP_R_UNSUPPORTED_CIPHER                         107
# define EVP_R_UNSUPPORTED_KEYLENGTH                      123
# define EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION        124
# define EVP_R_UNSUPPORTED_KEY_SIZE                       108
# define EVP_R_UNSUPPORTED_PRF                            125
# define EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM          118
# define EVP_R_UNSUPPORTED_SALT_TYPE                      126
# define EVP_R_WRAP_MODE_NOT_ALLOWED                      170
# define EVP_R_WRONG_FINAL_BLOCK_LENGTH                   109
# define EVP_R_WRONG_PUBLIC_KEY_TYPE                      110

# ifdef  __cplusplus
}
# endif
#endif
openssl/ebcdic.h000064400000001150151733316560007620 0ustar00/* crypto/ebcdic.h */

#ifndef HEADER_EBCDIC_H
# define HEADER_EBCDIC_H

# include <sys/types.h>

#ifdef  __cplusplus
extern "C" {
#endif

/* Avoid name clashes with other applications */
# define os_toascii   _openssl_os_toascii
# define os_toebcdic  _openssl_os_toebcdic
# define ebcdic2ascii _openssl_ebcdic2ascii
# define ascii2ebcdic _openssl_ascii2ebcdic

extern const unsigned char os_toascii[256];
extern const unsigned char os_toebcdic[256];
void *ebcdic2ascii(void *dest, const void *srce, size_t count);
void *ascii2ebcdic(void *dest, const void *srce, size_t count);

#ifdef  __cplusplus
}
#endif
#endif
openssl/ts.h000064400000103400151733316560007036 0ustar00/* crypto/ts/ts.h */
/*
 * Written by Zoltan Glozik (zglozik@opentsa.org) for the OpenSSL project
 * 2002, 2003, 2004.
 */
/* ====================================================================
 * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#ifndef HEADER_TS_H
# define HEADER_TS_H

# include <openssl/opensslconf.h>
# include <openssl/symhacks.h>
# ifndef OPENSSL_NO_BUFFER
#  include <openssl/buffer.h>
# endif
# ifndef OPENSSL_NO_EVP
#  include <openssl/evp.h>
# endif
# ifndef OPENSSL_NO_BIO
#  include <openssl/bio.h>
# endif
# include <openssl/stack.h>
# include <openssl/asn1.h>
# include <openssl/safestack.h>

# ifndef OPENSSL_NO_RSA
#  include <openssl/rsa.h>
# endif

# ifndef OPENSSL_NO_DSA
#  include <openssl/dsa.h>
# endif

# ifndef OPENSSL_NO_DH
#  include <openssl/dh.h>
# endif

#ifdef  __cplusplus
extern "C" {
#endif

# ifdef WIN32
/* Under Win32 this is defined in wincrypt.h */
#  undef X509_NAME
# endif

# include <openssl/x509.h>
# include <openssl/x509v3.h>

/*-
MessageImprint ::= SEQUENCE  {
     hashAlgorithm                AlgorithmIdentifier,
     hashedMessage                OCTET STRING  }
*/

typedef struct TS_msg_imprint_st {
    X509_ALGOR *hash_algo;
    ASN1_OCTET_STRING *hashed_msg;
} TS_MSG_IMPRINT;

/*-
TimeStampReq ::= SEQUENCE  {
   version                  INTEGER  { v1(1) },
   messageImprint           MessageImprint,
     --a hash algorithm OID and the hash value of the data to be
     --time-stamped
   reqPolicy                TSAPolicyId                OPTIONAL,
   nonce                    INTEGER                    OPTIONAL,
   certReq                  BOOLEAN                    DEFAULT FALSE,
   extensions               [0] IMPLICIT Extensions    OPTIONAL  }
*/

typedef struct TS_req_st {
    ASN1_INTEGER *version;
    TS_MSG_IMPRINT *msg_imprint;
    ASN1_OBJECT *policy_id;     /* OPTIONAL */
    ASN1_INTEGER *nonce;        /* OPTIONAL */
    ASN1_BOOLEAN cert_req;      /* DEFAULT FALSE */
    STACK_OF(X509_EXTENSION) *extensions; /* [0] OPTIONAL */
} TS_REQ;

/*-
Accuracy ::= SEQUENCE {
                seconds        INTEGER           OPTIONAL,
                millis     [0] INTEGER  (1..999) OPTIONAL,
                micros     [1] INTEGER  (1..999) OPTIONAL  }
*/

typedef struct TS_accuracy_st {
    ASN1_INTEGER *seconds;
    ASN1_INTEGER *millis;
    ASN1_INTEGER *micros;
} TS_ACCURACY;

/*-
TSTInfo ::= SEQUENCE  {
    version                      INTEGER  { v1(1) },
    policy                       TSAPolicyId,
    messageImprint               MessageImprint,
      -- MUST have the same value as the similar field in
      -- TimeStampReq
    serialNumber                 INTEGER,
     -- Time-Stamping users MUST be ready to accommodate integers
     -- up to 160 bits.
    genTime                      GeneralizedTime,
    accuracy                     Accuracy                 OPTIONAL,
    ordering                     BOOLEAN             DEFAULT FALSE,
    nonce                        INTEGER                  OPTIONAL,
      -- MUST be present if the similar field was present
      -- in TimeStampReq.  In that case it MUST have the same value.
    tsa                          [0] GeneralName          OPTIONAL,
    extensions                   [1] IMPLICIT Extensions  OPTIONAL   }
*/

typedef struct TS_tst_info_st {
    ASN1_INTEGER *version;
    ASN1_OBJECT *policy_id;
    TS_MSG_IMPRINT *msg_imprint;
    ASN1_INTEGER *serial;
    ASN1_GENERALIZEDTIME *time;
    TS_ACCURACY *accuracy;
    ASN1_BOOLEAN ordering;
    ASN1_INTEGER *nonce;
    GENERAL_NAME *tsa;
    STACK_OF(X509_EXTENSION) *extensions;
} TS_TST_INFO;

/*-
PKIStatusInfo ::= SEQUENCE {
    status        PKIStatus,
    statusString  PKIFreeText     OPTIONAL,
    failInfo      PKIFailureInfo  OPTIONAL  }

From RFC 1510 - section 3.1.1:
PKIFreeText ::= SEQUENCE SIZE (1..MAX) OF UTF8String
        -- text encoded as UTF-8 String (note:  each UTF8String SHOULD
        -- include an RFC 1766 language tag to indicate the language
        -- of the contained text)
*/

/* Possible values for status. See ts_resp_print.c && ts_resp_verify.c. */

# define TS_STATUS_GRANTED                       0
# define TS_STATUS_GRANTED_WITH_MODS             1
# define TS_STATUS_REJECTION                     2
# define TS_STATUS_WAITING                       3
# define TS_STATUS_REVOCATION_WARNING            4
# define TS_STATUS_REVOCATION_NOTIFICATION       5

/*
 * Possible values for failure_info. See ts_resp_print.c && ts_resp_verify.c
 */

# define TS_INFO_BAD_ALG                 0
# define TS_INFO_BAD_REQUEST             2
# define TS_INFO_BAD_DATA_FORMAT         5
# define TS_INFO_TIME_NOT_AVAILABLE      14
# define TS_INFO_UNACCEPTED_POLICY       15
# define TS_INFO_UNACCEPTED_EXTENSION    16
# define TS_INFO_ADD_INFO_NOT_AVAILABLE  17
# define TS_INFO_SYSTEM_FAILURE          25

typedef struct TS_status_info_st {
    ASN1_INTEGER *status;
    STACK_OF(ASN1_UTF8STRING) *text;
    ASN1_BIT_STRING *failure_info;
} TS_STATUS_INFO;

DECLARE_STACK_OF(ASN1_UTF8STRING)
DECLARE_ASN1_SET_OF(ASN1_UTF8STRING)

/*-
TimeStampResp ::= SEQUENCE  {
     status                  PKIStatusInfo,
     timeStampToken          TimeStampToken     OPTIONAL }
*/

typedef struct TS_resp_st {
    TS_STATUS_INFO *status_info;
    PKCS7 *token;
    TS_TST_INFO *tst_info;
} TS_RESP;

/* The structure below would belong to the ESS component. */

/*-
IssuerSerial ::= SEQUENCE {
        issuer                   GeneralNames,
        serialNumber             CertificateSerialNumber
        }
*/

typedef struct ESS_issuer_serial {
    STACK_OF(GENERAL_NAME) *issuer;
    ASN1_INTEGER *serial;
} ESS_ISSUER_SERIAL;

/*-
ESSCertID ::=  SEQUENCE {
        certHash                 Hash,
        issuerSerial             IssuerSerial OPTIONAL
}
*/

typedef struct ESS_cert_id {
    ASN1_OCTET_STRING *hash;    /* Always SHA-1 digest. */
    ESS_ISSUER_SERIAL *issuer_serial;
} ESS_CERT_ID;

DECLARE_STACK_OF(ESS_CERT_ID)
DECLARE_ASN1_SET_OF(ESS_CERT_ID)

/*-
SigningCertificate ::=  SEQUENCE {
       certs        SEQUENCE OF ESSCertID,
       policies     SEQUENCE OF PolicyInformation OPTIONAL
}
*/

typedef struct ESS_signing_cert {
    STACK_OF(ESS_CERT_ID) *cert_ids;
    STACK_OF(POLICYINFO) *policy_info;
} ESS_SIGNING_CERT;

TS_REQ *TS_REQ_new(void);
void TS_REQ_free(TS_REQ *a);
int i2d_TS_REQ(const TS_REQ *a, unsigned char **pp);
TS_REQ *d2i_TS_REQ(TS_REQ **a, const unsigned char **pp, long length);

TS_REQ *TS_REQ_dup(TS_REQ *a);

TS_REQ *d2i_TS_REQ_fp(FILE *fp, TS_REQ **a);
int i2d_TS_REQ_fp(FILE *fp, TS_REQ *a);
TS_REQ *d2i_TS_REQ_bio(BIO *fp, TS_REQ **a);
int i2d_TS_REQ_bio(BIO *fp, TS_REQ *a);

TS_MSG_IMPRINT *TS_MSG_IMPRINT_new(void);
void TS_MSG_IMPRINT_free(TS_MSG_IMPRINT *a);
int i2d_TS_MSG_IMPRINT(const TS_MSG_IMPRINT *a, unsigned char **pp);
TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT(TS_MSG_IMPRINT **a,
                                   const unsigned char **pp, long length);

TS_MSG_IMPRINT *TS_MSG_IMPRINT_dup(TS_MSG_IMPRINT *a);

TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a);
int i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a);
TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_bio(BIO *fp, TS_MSG_IMPRINT **a);
int i2d_TS_MSG_IMPRINT_bio(BIO *fp, TS_MSG_IMPRINT *a);

TS_RESP *TS_RESP_new(void);
void TS_RESP_free(TS_RESP *a);
int i2d_TS_RESP(const TS_RESP *a, unsigned char **pp);
TS_RESP *d2i_TS_RESP(TS_RESP **a, const unsigned char **pp, long length);
TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token);
TS_RESP *TS_RESP_dup(TS_RESP *a);

TS_RESP *d2i_TS_RESP_fp(FILE *fp, TS_RESP **a);
int i2d_TS_RESP_fp(FILE *fp, TS_RESP *a);
TS_RESP *d2i_TS_RESP_bio(BIO *fp, TS_RESP **a);
int i2d_TS_RESP_bio(BIO *fp, TS_RESP *a);

TS_STATUS_INFO *TS_STATUS_INFO_new(void);
void TS_STATUS_INFO_free(TS_STATUS_INFO *a);
int i2d_TS_STATUS_INFO(const TS_STATUS_INFO *a, unsigned char **pp);
TS_STATUS_INFO *d2i_TS_STATUS_INFO(TS_STATUS_INFO **a,
                                   const unsigned char **pp, long length);
TS_STATUS_INFO *TS_STATUS_INFO_dup(TS_STATUS_INFO *a);

TS_TST_INFO *TS_TST_INFO_new(void);
void TS_TST_INFO_free(TS_TST_INFO *a);
int i2d_TS_TST_INFO(const TS_TST_INFO *a, unsigned char **pp);
TS_TST_INFO *d2i_TS_TST_INFO(TS_TST_INFO **a, const unsigned char **pp,
                             long length);
TS_TST_INFO *TS_TST_INFO_dup(TS_TST_INFO *a);

TS_TST_INFO *d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a);
int i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a);
TS_TST_INFO *d2i_TS_TST_INFO_bio(BIO *fp, TS_TST_INFO **a);
int i2d_TS_TST_INFO_bio(BIO *fp, TS_TST_INFO *a);

TS_ACCURACY *TS_ACCURACY_new(void);
void TS_ACCURACY_free(TS_ACCURACY *a);
int i2d_TS_ACCURACY(const TS_ACCURACY *a, unsigned char **pp);
TS_ACCURACY *d2i_TS_ACCURACY(TS_ACCURACY **a, const unsigned char **pp,
                             long length);
TS_ACCURACY *TS_ACCURACY_dup(TS_ACCURACY *a);

ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_new(void);
void ESS_ISSUER_SERIAL_free(ESS_ISSUER_SERIAL *a);
int i2d_ESS_ISSUER_SERIAL(const ESS_ISSUER_SERIAL *a, unsigned char **pp);
ESS_ISSUER_SERIAL *d2i_ESS_ISSUER_SERIAL(ESS_ISSUER_SERIAL **a,
                                         const unsigned char **pp,
                                         long length);
ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_dup(ESS_ISSUER_SERIAL *a);

ESS_CERT_ID *ESS_CERT_ID_new(void);
void ESS_CERT_ID_free(ESS_CERT_ID *a);
int i2d_ESS_CERT_ID(const ESS_CERT_ID *a, unsigned char **pp);
ESS_CERT_ID *d2i_ESS_CERT_ID(ESS_CERT_ID **a, const unsigned char **pp,
                             long length);
ESS_CERT_ID *ESS_CERT_ID_dup(ESS_CERT_ID *a);

ESS_SIGNING_CERT *ESS_SIGNING_CERT_new(void);
void ESS_SIGNING_CERT_free(ESS_SIGNING_CERT *a);
int i2d_ESS_SIGNING_CERT(const ESS_SIGNING_CERT *a, unsigned char **pp);
ESS_SIGNING_CERT *d2i_ESS_SIGNING_CERT(ESS_SIGNING_CERT **a,
                                       const unsigned char **pp, long length);
ESS_SIGNING_CERT *ESS_SIGNING_CERT_dup(ESS_SIGNING_CERT *a);

void ERR_load_TS_strings(void);

int TS_REQ_set_version(TS_REQ *a, long version);
long TS_REQ_get_version(const TS_REQ *a);

int TS_REQ_set_msg_imprint(TS_REQ *a, TS_MSG_IMPRINT *msg_imprint);
TS_MSG_IMPRINT *TS_REQ_get_msg_imprint(TS_REQ *a);

int TS_MSG_IMPRINT_set_algo(TS_MSG_IMPRINT *a, X509_ALGOR *alg);
X509_ALGOR *TS_MSG_IMPRINT_get_algo(TS_MSG_IMPRINT *a);

int TS_MSG_IMPRINT_set_msg(TS_MSG_IMPRINT *a, unsigned char *d, int len);
ASN1_OCTET_STRING *TS_MSG_IMPRINT_get_msg(TS_MSG_IMPRINT *a);

int TS_REQ_set_policy_id(TS_REQ *a, ASN1_OBJECT *policy);
ASN1_OBJECT *TS_REQ_get_policy_id(TS_REQ *a);

int TS_REQ_set_nonce(TS_REQ *a, const ASN1_INTEGER *nonce);
const ASN1_INTEGER *TS_REQ_get_nonce(const TS_REQ *a);

int TS_REQ_set_cert_req(TS_REQ *a, int cert_req);
int TS_REQ_get_cert_req(const TS_REQ *a);

STACK_OF(X509_EXTENSION) *TS_REQ_get_exts(TS_REQ *a);
void TS_REQ_ext_free(TS_REQ *a);
int TS_REQ_get_ext_count(TS_REQ *a);
int TS_REQ_get_ext_by_NID(TS_REQ *a, int nid, int lastpos);
int TS_REQ_get_ext_by_OBJ(TS_REQ *a, ASN1_OBJECT *obj, int lastpos);
int TS_REQ_get_ext_by_critical(TS_REQ *a, int crit, int lastpos);
X509_EXTENSION *TS_REQ_get_ext(TS_REQ *a, int loc);
X509_EXTENSION *TS_REQ_delete_ext(TS_REQ *a, int loc);
int TS_REQ_add_ext(TS_REQ *a, X509_EXTENSION *ex, int loc);
void *TS_REQ_get_ext_d2i(TS_REQ *a, int nid, int *crit, int *idx);

/* Function declarations for TS_REQ defined in ts/ts_req_print.c */

int TS_REQ_print_bio(BIO *bio, TS_REQ *a);

/* Function declarations for TS_RESP defined in ts/ts_resp_utils.c */

int TS_RESP_set_status_info(TS_RESP *a, TS_STATUS_INFO *info);
TS_STATUS_INFO *TS_RESP_get_status_info(TS_RESP *a);

/* Caller loses ownership of PKCS7 and TS_TST_INFO objects. */
void TS_RESP_set_tst_info(TS_RESP *a, PKCS7 *p7, TS_TST_INFO *tst_info);
PKCS7 *TS_RESP_get_token(TS_RESP *a);
TS_TST_INFO *TS_RESP_get_tst_info(TS_RESP *a);

int TS_TST_INFO_set_version(TS_TST_INFO *a, long version);
long TS_TST_INFO_get_version(const TS_TST_INFO *a);

int TS_TST_INFO_set_policy_id(TS_TST_INFO *a, ASN1_OBJECT *policy_id);
ASN1_OBJECT *TS_TST_INFO_get_policy_id(TS_TST_INFO *a);

int TS_TST_INFO_set_msg_imprint(TS_TST_INFO *a, TS_MSG_IMPRINT *msg_imprint);
TS_MSG_IMPRINT *TS_TST_INFO_get_msg_imprint(TS_TST_INFO *a);

int TS_TST_INFO_set_serial(TS_TST_INFO *a, const ASN1_INTEGER *serial);
const ASN1_INTEGER *TS_TST_INFO_get_serial(const TS_TST_INFO *a);

int TS_TST_INFO_set_time(TS_TST_INFO *a, const ASN1_GENERALIZEDTIME *gtime);
const ASN1_GENERALIZEDTIME *TS_TST_INFO_get_time(const TS_TST_INFO *a);

int TS_TST_INFO_set_accuracy(TS_TST_INFO *a, TS_ACCURACY *accuracy);
TS_ACCURACY *TS_TST_INFO_get_accuracy(TS_TST_INFO *a);

int TS_ACCURACY_set_seconds(TS_ACCURACY *a, const ASN1_INTEGER *seconds);
const ASN1_INTEGER *TS_ACCURACY_get_seconds(const TS_ACCURACY *a);

int TS_ACCURACY_set_millis(TS_ACCURACY *a, const ASN1_INTEGER *millis);
const ASN1_INTEGER *TS_ACCURACY_get_millis(const TS_ACCURACY *a);

int TS_ACCURACY_set_micros(TS_ACCURACY *a, const ASN1_INTEGER *micros);
const ASN1_INTEGER *TS_ACCURACY_get_micros(const TS_ACCURACY *a);

int TS_TST_INFO_set_ordering(TS_TST_INFO *a, int ordering);
int TS_TST_INFO_get_ordering(const TS_TST_INFO *a);

int TS_TST_INFO_set_nonce(TS_TST_INFO *a, const ASN1_INTEGER *nonce);
const ASN1_INTEGER *TS_TST_INFO_get_nonce(const TS_TST_INFO *a);

int TS_TST_INFO_set_tsa(TS_TST_INFO *a, GENERAL_NAME *tsa);
GENERAL_NAME *TS_TST_INFO_get_tsa(TS_TST_INFO *a);

STACK_OF(X509_EXTENSION) *TS_TST_INFO_get_exts(TS_TST_INFO *a);
void TS_TST_INFO_ext_free(TS_TST_INFO *a);
int TS_TST_INFO_get_ext_count(TS_TST_INFO *a);
int TS_TST_INFO_get_ext_by_NID(TS_TST_INFO *a, int nid, int lastpos);
int TS_TST_INFO_get_ext_by_OBJ(TS_TST_INFO *a, ASN1_OBJECT *obj, int lastpos);
int TS_TST_INFO_get_ext_by_critical(TS_TST_INFO *a, int crit, int lastpos);
X509_EXTENSION *TS_TST_INFO_get_ext(TS_TST_INFO *a, int loc);
X509_EXTENSION *TS_TST_INFO_delete_ext(TS_TST_INFO *a, int loc);
int TS_TST_INFO_add_ext(TS_TST_INFO *a, X509_EXTENSION *ex, int loc);
void *TS_TST_INFO_get_ext_d2i(TS_TST_INFO *a, int nid, int *crit, int *idx);

/*
 * Declarations related to response generation, defined in ts/ts_resp_sign.c.
 */

/* Optional flags for response generation. */

/* Don't include the TSA name in response. */
# define TS_TSA_NAME             0x01

/* Set ordering to true in response. */
# define TS_ORDERING             0x02

/*
 * Include the signer certificate and the other specified certificates in
 * the ESS signing certificate attribute beside the PKCS7 signed data.
 * Only the signer certificates is included by default.
 */
# define TS_ESS_CERT_ID_CHAIN    0x04

/* Forward declaration. */
struct TS_resp_ctx;

/* This must return a unique number less than 160 bits long. */
typedef ASN1_INTEGER *(*TS_serial_cb) (struct TS_resp_ctx *, void *);

/*
 * This must return the seconds and microseconds since Jan 1, 1970 in the sec
 * and usec variables allocated by the caller. Return non-zero for success
 * and zero for failure.
 */
typedef int (*TS_time_cb) (struct TS_resp_ctx *, void *, long *sec,
                           long *usec);

/*
 * This must process the given extension. It can modify the TS_TST_INFO
 * object of the context. Return values: !0 (processed), 0 (error, it must
 * set the status info/failure info of the response).
 */
typedef int (*TS_extension_cb) (struct TS_resp_ctx *, X509_EXTENSION *,
                                void *);

typedef struct TS_resp_ctx {
    X509 *signer_cert;
    EVP_PKEY *signer_key;
    STACK_OF(X509) *certs;      /* Certs to include in signed data. */
    STACK_OF(ASN1_OBJECT) *policies; /* Acceptable policies. */
    ASN1_OBJECT *default_policy; /* It may appear in policies, too. */
    STACK_OF(EVP_MD) *mds;      /* Acceptable message digests. */
    ASN1_INTEGER *seconds;      /* accuracy, 0 means not specified. */
    ASN1_INTEGER *millis;       /* accuracy, 0 means not specified. */
    ASN1_INTEGER *micros;       /* accuracy, 0 means not specified. */
    unsigned clock_precision_digits; /* fraction of seconds in time stamp
                                      * token. */
    unsigned flags;             /* Optional info, see values above. */
    /* Callback functions. */
    TS_serial_cb serial_cb;
    void *serial_cb_data;       /* User data for serial_cb. */
    TS_time_cb time_cb;
    void *time_cb_data;         /* User data for time_cb. */
    TS_extension_cb extension_cb;
    void *extension_cb_data;    /* User data for extension_cb. */
    /* These members are used only while creating the response. */
    TS_REQ *request;
    TS_RESP *response;
    TS_TST_INFO *tst_info;
} TS_RESP_CTX;

DECLARE_STACK_OF(EVP_MD)
DECLARE_ASN1_SET_OF(EVP_MD)

/* Creates a response context that can be used for generating responses. */
TS_RESP_CTX *TS_RESP_CTX_new(void);
void TS_RESP_CTX_free(TS_RESP_CTX *ctx);

/* This parameter must be set. */
int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer);

/* This parameter must be set. */
int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key);

/* This parameter must be set. */
int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *def_policy);

/* No additional certs are included in the response by default. */
int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs);

/*
 * Adds a new acceptable policy, only the default policy is accepted by
 * default.
 */
int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *policy);

/*
 * Adds a new acceptable message digest. Note that no message digests are
 * accepted by default. The md argument is shared with the caller.
 */
int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md);

/* Accuracy is not included by default. */
int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx,
                             int secs, int millis, int micros);

/*
 * Clock precision digits, i.e. the number of decimal digits: '0' means sec,
 * '3' msec, '6' usec, and so on. Default is 0.
 */
int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx,
                                           unsigned clock_precision_digits);
/* At most we accept usec precision. */
# define TS_MAX_CLOCK_PRECISION_DIGITS   6

/* Maximum status message length */
# define TS_MAX_STATUS_LENGTH   (1024 * 1024)

/* No flags are set by default. */
void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags);

/* Default callback always returns a constant. */
void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data);

/* Default callback uses the gettimeofday() and gmtime() system calls. */
void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data);

/*
 * Default callback rejects all extensions. The extension callback is called
 * when the TS_TST_INFO object is already set up and not signed yet.
 */
/* FIXME: extension handling is not tested yet. */
void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx,
                                  TS_extension_cb cb, void *data);

/* The following methods can be used in the callbacks. */
int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx,
                                int status, const char *text);

/* Sets the status info only if it is still TS_STATUS_GRANTED. */
int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx,
                                     int status, const char *text);

int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure);

/* The get methods below can be used in the extension callback. */
TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx);

TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx);

/*
 * Creates the signed TS_TST_INFO and puts it in TS_RESP.
 * In case of errors it sets the status info properly.
 * Returns NULL only in case of memory allocation/fatal error.
 */
TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio);

/*
 * Declarations related to response verification,
 * they are defined in ts/ts_resp_verify.c.
 */

int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs,
                             X509_STORE *store, X509 **signer_out);

/* Context structure for the generic verify method. */

/* Verify the signer's certificate and the signature of the response. */
# define TS_VFY_SIGNATURE        (1u << 0)
/* Verify the version number of the response. */
# define TS_VFY_VERSION          (1u << 1)
/* Verify if the policy supplied by the user matches the policy of the TSA. */
# define TS_VFY_POLICY           (1u << 2)
/*
 * Verify the message imprint provided by the user. This flag should not be
 * specified with TS_VFY_DATA.
 */
# define TS_VFY_IMPRINT          (1u << 3)
/*
 * Verify the message imprint computed by the verify method from the user
 * provided data and the MD algorithm of the response. This flag should not
 * be specified with TS_VFY_IMPRINT.
 */
# define TS_VFY_DATA             (1u << 4)
/* Verify the nonce value. */
# define TS_VFY_NONCE            (1u << 5)
/* Verify if the TSA name field matches the signer certificate. */
# define TS_VFY_SIGNER           (1u << 6)
/* Verify if the TSA name field equals to the user provided name. */
# define TS_VFY_TSA_NAME         (1u << 7)

/* You can use the following convenience constants. */
# define TS_VFY_ALL_IMPRINT      (TS_VFY_SIGNATURE       \
                                 | TS_VFY_VERSION       \
                                 | TS_VFY_POLICY        \
                                 | TS_VFY_IMPRINT       \
                                 | TS_VFY_NONCE         \
                                 | TS_VFY_SIGNER        \
                                 | TS_VFY_TSA_NAME)
# define TS_VFY_ALL_DATA         (TS_VFY_SIGNATURE       \
                                 | TS_VFY_VERSION       \
                                 | TS_VFY_POLICY        \
                                 | TS_VFY_DATA          \
                                 | TS_VFY_NONCE         \
                                 | TS_VFY_SIGNER        \
                                 | TS_VFY_TSA_NAME)

typedef struct TS_verify_ctx {
    /* Set this to the union of TS_VFY_... flags you want to carry out. */
    unsigned flags;
    /* Must be set only with TS_VFY_SIGNATURE. certs is optional. */
    X509_STORE *store;
    STACK_OF(X509) *certs;
    /* Must be set only with TS_VFY_POLICY. */
    ASN1_OBJECT *policy;
    /*
     * Must be set only with TS_VFY_IMPRINT. If md_alg is NULL, the
     * algorithm from the response is used.
     */
    X509_ALGOR *md_alg;
    unsigned char *imprint;
    unsigned imprint_len;
    /* Must be set only with TS_VFY_DATA. */
    BIO *data;
    /* Must be set only with TS_VFY_TSA_NAME. */
    ASN1_INTEGER *nonce;
    /* Must be set only with TS_VFY_TSA_NAME. */
    GENERAL_NAME *tsa_name;
} TS_VERIFY_CTX;

int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response);
int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token);

/*
 * Declarations related to response verification context,
 * they are defined in ts/ts_verify_ctx.c.
 */

/* Set all fields to zero. */
TS_VERIFY_CTX *TS_VERIFY_CTX_new(void);
void TS_VERIFY_CTX_init(TS_VERIFY_CTX *ctx);
void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx);
void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx);

/*-
 * If ctx is NULL, it allocates and returns a new object, otherwise
 * it returns ctx. It initialises all the members as follows:
 * flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE)
 * certs = NULL
 * store = NULL
 * policy = policy from the request or NULL if absent (in this case
 *      TS_VFY_POLICY is cleared from flags as well)
 * md_alg = MD algorithm from request
 * imprint, imprint_len = imprint from request
 * data = NULL
 * nonce, nonce_len = nonce from the request or NULL if absent (in this case
 *      TS_VFY_NONCE is cleared from flags as well)
 * tsa_name = NULL
 * Important: after calling this method TS_VFY_SIGNATURE should be added!
 */
TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx);

/* Function declarations for TS_RESP defined in ts/ts_resp_print.c */

int TS_RESP_print_bio(BIO *bio, TS_RESP *a);
int TS_STATUS_INFO_print_bio(BIO *bio, TS_STATUS_INFO *a);
int TS_TST_INFO_print_bio(BIO *bio, TS_TST_INFO *a);

/* Common utility functions defined in ts/ts_lib.c */

int TS_ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num);
int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj);
int TS_ext_print_bio(BIO *bio, const STACK_OF(X509_EXTENSION) *extensions);
int TS_X509_ALGOR_print_bio(BIO *bio, const X509_ALGOR *alg);
int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *msg);

/*
 * Function declarations for handling configuration options, defined in
 * ts/ts_conf.c
 */

X509 *TS_CONF_load_cert(const char *file);
STACK_OF(X509) *TS_CONF_load_certs(const char *file);
EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass);
const char *TS_CONF_get_tsa_section(CONF *conf, const char *section);
int TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb,
                       TS_RESP_CTX *ctx);
int TS_CONF_set_crypto_device(CONF *conf, const char *section,
                              const char *device);
int TS_CONF_set_default_engine(const char *name);
int TS_CONF_set_signer_cert(CONF *conf, const char *section,
                            const char *cert, TS_RESP_CTX *ctx);
int TS_CONF_set_certs(CONF *conf, const char *section, const char *certs,
                      TS_RESP_CTX *ctx);
int TS_CONF_set_signer_key(CONF *conf, const char *section,
                           const char *key, const char *pass,
                           TS_RESP_CTX *ctx);
int TS_CONF_set_def_policy(CONF *conf, const char *section,
                           const char *policy, TS_RESP_CTX *ctx);
int TS_CONF_set_policies(CONF *conf, const char *section, TS_RESP_CTX *ctx);
int TS_CONF_set_digests(CONF *conf, const char *section, TS_RESP_CTX *ctx);
int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx);
int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section,
                                       TS_RESP_CTX *ctx);
int TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx);
int TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx);
int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section,
                                  TS_RESP_CTX *ctx);

/* -------------------------------------------------- */
/* BEGIN ERROR CODES */
/*
 * The following lines are auto generated by the script mkerr.pl. Any changes
 * made after this point may be overwritten when the script is next run.
 */
void ERR_load_TS_strings(void);

/* Error codes for the TS functions. */

/* Function codes. */
# define TS_F_D2I_TS_RESP                                 147
# define TS_F_DEF_SERIAL_CB                               110
# define TS_F_DEF_TIME_CB                                 111
# define TS_F_ESS_ADD_SIGNING_CERT                        112
# define TS_F_ESS_CERT_ID_NEW_INIT                        113
# define TS_F_ESS_SIGNING_CERT_NEW_INIT                   114
# define TS_F_INT_TS_RESP_VERIFY_TOKEN                    149
# define TS_F_PKCS7_TO_TS_TST_INFO                        148
# define TS_F_TS_ACCURACY_SET_MICROS                      115
# define TS_F_TS_ACCURACY_SET_MILLIS                      116
# define TS_F_TS_ACCURACY_SET_SECONDS                     117
# define TS_F_TS_CHECK_IMPRINTS                           100
# define TS_F_TS_CHECK_NONCES                             101
# define TS_F_TS_CHECK_POLICY                             102
# define TS_F_TS_CHECK_SIGNING_CERTS                      103
# define TS_F_TS_CHECK_STATUS_INFO                        104
# define TS_F_TS_COMPUTE_IMPRINT                          145
# define TS_F_TS_CONF_SET_DEFAULT_ENGINE                  146
# define TS_F_TS_GET_STATUS_TEXT                          105
# define TS_F_TS_MSG_IMPRINT_SET_ALGO                     118
# define TS_F_TS_REQ_SET_MSG_IMPRINT                      119
# define TS_F_TS_REQ_SET_NONCE                            120
# define TS_F_TS_REQ_SET_POLICY_ID                        121
# define TS_F_TS_RESP_CREATE_RESPONSE                     122
# define TS_F_TS_RESP_CREATE_TST_INFO                     123
# define TS_F_TS_RESP_CTX_ADD_FAILURE_INFO                124
# define TS_F_TS_RESP_CTX_ADD_MD                          125
# define TS_F_TS_RESP_CTX_ADD_POLICY                      126
# define TS_F_TS_RESP_CTX_NEW                             127
# define TS_F_TS_RESP_CTX_SET_ACCURACY                    128
# define TS_F_TS_RESP_CTX_SET_CERTS                       129
# define TS_F_TS_RESP_CTX_SET_DEF_POLICY                  130
# define TS_F_TS_RESP_CTX_SET_SIGNER_CERT                 131
# define TS_F_TS_RESP_CTX_SET_STATUS_INFO                 132
# define TS_F_TS_RESP_GET_POLICY                          133
# define TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION          134
# define TS_F_TS_RESP_SET_STATUS_INFO                     135
# define TS_F_TS_RESP_SET_TST_INFO                        150
# define TS_F_TS_RESP_SIGN                                136
# define TS_F_TS_RESP_VERIFY_SIGNATURE                    106
# define TS_F_TS_RESP_VERIFY_TOKEN                        107
# define TS_F_TS_TST_INFO_SET_ACCURACY                    137
# define TS_F_TS_TST_INFO_SET_MSG_IMPRINT                 138
# define TS_F_TS_TST_INFO_SET_NONCE                       139
# define TS_F_TS_TST_INFO_SET_POLICY_ID                   140
# define TS_F_TS_TST_INFO_SET_SERIAL                      141
# define TS_F_TS_TST_INFO_SET_TIME                        142
# define TS_F_TS_TST_INFO_SET_TSA                         143
# define TS_F_TS_VERIFY                                   108
# define TS_F_TS_VERIFY_CERT                              109
# define TS_F_TS_VERIFY_CTX_NEW                           144

/* Reason codes. */
# define TS_R_BAD_PKCS7_TYPE                              132
# define TS_R_BAD_TYPE                                    133
# define TS_R_CERTIFICATE_VERIFY_ERROR                    100
# define TS_R_COULD_NOT_SET_ENGINE                        127
# define TS_R_COULD_NOT_SET_TIME                          115
# define TS_R_D2I_TS_RESP_INT_FAILED                      128
# define TS_R_DETACHED_CONTENT                            134
# define TS_R_ESS_ADD_SIGNING_CERT_ERROR                  116
# define TS_R_ESS_SIGNING_CERTIFICATE_ERROR               101
# define TS_R_INVALID_NULL_POINTER                        102
# define TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE          117
# define TS_R_MESSAGE_IMPRINT_MISMATCH                    103
# define TS_R_NONCE_MISMATCH                              104
# define TS_R_NONCE_NOT_RETURNED                          105
# define TS_R_NO_CONTENT                                  106
# define TS_R_NO_TIME_STAMP_TOKEN                         107
# define TS_R_PKCS7_ADD_SIGNATURE_ERROR                   118
# define TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR                 119
# define TS_R_PKCS7_TO_TS_TST_INFO_FAILED                 129
# define TS_R_POLICY_MISMATCH                             108
# define TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE      120
# define TS_R_RESPONSE_SETUP_ERROR                        121
# define TS_R_SIGNATURE_FAILURE                           109
# define TS_R_THERE_MUST_BE_ONE_SIGNER                    110
# define TS_R_TIME_SYSCALL_ERROR                          122
# define TS_R_TOKEN_NOT_PRESENT                           130
# define TS_R_TOKEN_PRESENT                               131
# define TS_R_TSA_NAME_MISMATCH                           111
# define TS_R_TSA_UNTRUSTED                               112
# define TS_R_TST_INFO_SETUP_ERROR                        123
# define TS_R_TS_DATASIGN                                 124
# define TS_R_UNACCEPTABLE_POLICY                         125
# define TS_R_UNSUPPORTED_MD_ALGORITHM                    126
# define TS_R_UNSUPPORTED_VERSION                         113
# define TS_R_WRONG_CONTENT_TYPE                          114

#ifdef  __cplusplus
}
#endif
#endif
openssl/asn1t.h000064400000103253151733316560007444 0ustar00/* asn1t.h */
/*
 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
 * 2000.
 */
/* ====================================================================
 * Copyright (c) 2000-2005 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */
#ifndef HEADER_ASN1T_H
# define HEADER_ASN1T_H

# include <stddef.h>
# include <openssl/e_os2.h>
# include <openssl/asn1.h>

# ifdef OPENSSL_BUILD_SHLIBCRYPTO
#  undef OPENSSL_EXTERN
#  define OPENSSL_EXTERN OPENSSL_EXPORT
# endif

/* ASN1 template defines, structures and functions */

#ifdef  __cplusplus
extern "C" {
#endif

# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION

/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */
#  define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr))

/* Macros for start and end of ASN1_ITEM definition */

#  define ASN1_ITEM_start(itname) \
        OPENSSL_GLOBAL const ASN1_ITEM itname##_it = {

#  define ASN1_ITEM_end(itname) \
                };

# else

/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */
#  define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr()))

/* Macros for start and end of ASN1_ITEM definition */

#  define ASN1_ITEM_start(itname) \
        const ASN1_ITEM * itname##_it(void) \
        { \
                static const ASN1_ITEM local_it = {

#  define ASN1_ITEM_end(itname) \
                }; \
        return &local_it; \
        }

# endif

/* Macros to aid ASN1 template writing */

# define ASN1_ITEM_TEMPLATE(tname) \
        static const ASN1_TEMPLATE tname##_item_tt

# define ASN1_ITEM_TEMPLATE_END(tname) \
        ;\
        ASN1_ITEM_start(tname) \
                ASN1_ITYPE_PRIMITIVE,\
                -1,\
                &tname##_item_tt,\
                0,\
                NULL,\
                0,\
                #tname \
        ASN1_ITEM_end(tname)

/* This is a ASN1 type which just embeds a template */

/*-
 * This pair helps declare a SEQUENCE. We can do:
 *
 *      ASN1_SEQUENCE(stname) = {
 *              ... SEQUENCE components ...
 *      } ASN1_SEQUENCE_END(stname)
 *
 *      This will produce an ASN1_ITEM called stname_it
 *      for a structure called stname.
 *
 *      If you want the same structure but a different
 *      name then use:
 *
 *      ASN1_SEQUENCE(itname) = {
 *              ... SEQUENCE components ...
 *      } ASN1_SEQUENCE_END_name(stname, itname)
 *
 *      This will create an item called itname_it using
 *      a structure called stname.
 */

# define ASN1_SEQUENCE(tname) \
        static const ASN1_TEMPLATE tname##_seq_tt[]

# define ASN1_SEQUENCE_END(stname) ASN1_SEQUENCE_END_name(stname, stname)

# define ASN1_SEQUENCE_END_name(stname, tname) \
        ;\
        ASN1_ITEM_start(tname) \
                ASN1_ITYPE_SEQUENCE,\
                V_ASN1_SEQUENCE,\
                tname##_seq_tt,\
                sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
                NULL,\
                sizeof(stname),\
                #stname \
        ASN1_ITEM_end(tname)

# define ASN1_NDEF_SEQUENCE(tname) \
        ASN1_SEQUENCE(tname)

# define ASN1_NDEF_SEQUENCE_cb(tname, cb) \
        ASN1_SEQUENCE_cb(tname, cb)

# define ASN1_SEQUENCE_cb(tname, cb) \
        static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
        ASN1_SEQUENCE(tname)

# define ASN1_BROKEN_SEQUENCE(tname) \
        static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0, 0}; \
        ASN1_SEQUENCE(tname)

# define ASN1_SEQUENCE_ref(tname, cb, lck) \
        static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), lck, cb, 0}; \
        ASN1_SEQUENCE(tname)

# define ASN1_SEQUENCE_enc(tname, enc, cb) \
        static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc)}; \
        ASN1_SEQUENCE(tname)

# define ASN1_NDEF_SEQUENCE_END(tname) \
        ;\
        ASN1_ITEM_start(tname) \
                ASN1_ITYPE_NDEF_SEQUENCE,\
                V_ASN1_SEQUENCE,\
                tname##_seq_tt,\
                sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
                NULL,\
                sizeof(tname),\
                #tname \
        ASN1_ITEM_end(tname)

# define ASN1_BROKEN_SEQUENCE_END(stname) ASN1_SEQUENCE_END_ref(stname, stname)

# define ASN1_SEQUENCE_END_enc(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)

# define ASN1_SEQUENCE_END_cb(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)

# define ASN1_SEQUENCE_END_ref(stname, tname) \
        ;\
        ASN1_ITEM_start(tname) \
                ASN1_ITYPE_SEQUENCE,\
                V_ASN1_SEQUENCE,\
                tname##_seq_tt,\
                sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
                &tname##_aux,\
                sizeof(stname),\
                #stname \
        ASN1_ITEM_end(tname)

# define ASN1_NDEF_SEQUENCE_END_cb(stname, tname) \
        ;\
        ASN1_ITEM_start(tname) \
                ASN1_ITYPE_NDEF_SEQUENCE,\
                V_ASN1_SEQUENCE,\
                tname##_seq_tt,\
                sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
                &tname##_aux,\
                sizeof(stname),\
                #stname \
        ASN1_ITEM_end(tname)

/*-
 * This pair helps declare a CHOICE type. We can do:
 *
 *      ASN1_CHOICE(chname) = {
 *              ... CHOICE options ...
 *      ASN1_CHOICE_END(chname)
 *
 *      This will produce an ASN1_ITEM called chname_it
 *      for a structure called chname. The structure
 *      definition must look like this:
 *      typedef struct {
 *              int type;
 *              union {
 *                      ASN1_SOMETHING *opt1;
 *                      ASN1_SOMEOTHER *opt2;
 *              } value;
 *      } chname;
 *
 *      the name of the selector must be 'type'.
 *      to use an alternative selector name use the
 *      ASN1_CHOICE_END_selector() version.
 */

# define ASN1_CHOICE(tname) \
        static const ASN1_TEMPLATE tname##_ch_tt[]

# define ASN1_CHOICE_cb(tname, cb) \
        static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
        ASN1_CHOICE(tname)

# define ASN1_CHOICE_END(stname) ASN1_CHOICE_END_name(stname, stname)

# define ASN1_CHOICE_END_name(stname, tname) ASN1_CHOICE_END_selector(stname, tname, type)

# define ASN1_CHOICE_END_selector(stname, tname, selname) \
        ;\
        ASN1_ITEM_start(tname) \
                ASN1_ITYPE_CHOICE,\
                offsetof(stname,selname) ,\
                tname##_ch_tt,\
                sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\
                NULL,\
                sizeof(stname),\
                #stname \
        ASN1_ITEM_end(tname)

# define ASN1_CHOICE_END_cb(stname, tname, selname) \
        ;\
        ASN1_ITEM_start(tname) \
                ASN1_ITYPE_CHOICE,\
                offsetof(stname,selname) ,\
                tname##_ch_tt,\
                sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\
                &tname##_aux,\
                sizeof(stname),\
                #stname \
        ASN1_ITEM_end(tname)

/* This helps with the template wrapper form of ASN1_ITEM */

# define ASN1_EX_TEMPLATE_TYPE(flags, tag, name, type) { \
        (flags), (tag), 0,\
        #name, ASN1_ITEM_ref(type) }

/* These help with SEQUENCE or CHOICE components */

/* used to declare other types */

# define ASN1_EX_TYPE(flags, tag, stname, field, type) { \
        (flags), (tag), offsetof(stname, field),\
        #field, ASN1_ITEM_ref(type) }

/* used when the structure is combined with the parent */

# define ASN1_EX_COMBINE(flags, tag, type) { \
        (flags)|ASN1_TFLG_COMBINE, (tag), 0, NULL, ASN1_ITEM_ref(type) }

/* implicit and explicit helper macros */

# define ASN1_IMP_EX(stname, field, type, tag, ex) \
                ASN1_EX_TYPE(ASN1_TFLG_IMPLICIT | ex, tag, stname, field, type)

# define ASN1_EXP_EX(stname, field, type, tag, ex) \
                ASN1_EX_TYPE(ASN1_TFLG_EXPLICIT | ex, tag, stname, field, type)

/* Any defined by macros: the field used is in the table itself */

# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
#  define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) }
#  define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) }
# else
#  define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, tblname##_adb }
#  define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, tblname##_adb }
# endif
/* Plain simple type */
# define ASN1_SIMPLE(stname, field, type) ASN1_EX_TYPE(0,0, stname, field, type)

/* OPTIONAL simple type */
# define ASN1_OPT(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL, 0, stname, field, type)

/* IMPLICIT tagged simple type */
# define ASN1_IMP(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, 0)

/* IMPLICIT tagged OPTIONAL simple type */
# define ASN1_IMP_OPT(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL)

/* Same as above but EXPLICIT */

# define ASN1_EXP(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, 0)
# define ASN1_EXP_OPT(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL)

/* SEQUENCE OF type */
# define ASN1_SEQUENCE_OF(stname, field, type) \
                ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, stname, field, type)

/* OPTIONAL SEQUENCE OF */
# define ASN1_SEQUENCE_OF_OPT(stname, field, type) \
                ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type)

/* Same as above but for SET OF */

# define ASN1_SET_OF(stname, field, type) \
                ASN1_EX_TYPE(ASN1_TFLG_SET_OF, 0, stname, field, type)

# define ASN1_SET_OF_OPT(stname, field, type) \
                ASN1_EX_TYPE(ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type)

/* Finally compound types of SEQUENCE, SET, IMPLICIT, EXPLICIT and OPTIONAL */

# define ASN1_IMP_SET_OF(stname, field, type, tag) \
                        ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF)

# define ASN1_EXP_SET_OF(stname, field, type, tag) \
                        ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF)

# define ASN1_IMP_SET_OF_OPT(stname, field, type, tag) \
                        ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL)

# define ASN1_EXP_SET_OF_OPT(stname, field, type, tag) \
                        ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL)

# define ASN1_IMP_SEQUENCE_OF(stname, field, type, tag) \
                        ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF)

# define ASN1_IMP_SEQUENCE_OF_OPT(stname, field, type, tag) \
                        ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)

# define ASN1_EXP_SEQUENCE_OF(stname, field, type, tag) \
                        ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF)

# define ASN1_EXP_SEQUENCE_OF_OPT(stname, field, type, tag) \
                        ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)

/* EXPLICIT using indefinite length constructed form */
# define ASN1_NDEF_EXP(stname, field, type, tag) \
                        ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_NDEF)

/* EXPLICIT OPTIONAL using indefinite length constructed form */
# define ASN1_NDEF_EXP_OPT(stname, field, type, tag) \
                        ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_NDEF)

/* Macros for the ASN1_ADB structure */

# define ASN1_ADB(name) \
        static const ASN1_ADB_TABLE name##_adbtbl[]

# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION

#  define ASN1_ADB_END(name, flags, field, app_table, def, none) \
        ;\
        static const ASN1_ADB name##_adb = {\
                flags,\
                offsetof(name, field),\
                app_table,\
                name##_adbtbl,\
                sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\
                def,\
                none\
        }

# else

#  define ASN1_ADB_END(name, flags, field, app_table, def, none) \
        ;\
        static const ASN1_ITEM *name##_adb(void) \
        { \
        static const ASN1_ADB internal_adb = \
                {\
                flags,\
                offsetof(name, field),\
                app_table,\
                name##_adbtbl,\
                sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\
                def,\
                none\
                }; \
                return (const ASN1_ITEM *) &internal_adb; \
        } \
        void dummy_function(void)

# endif

# define ADB_ENTRY(val, template) {val, template}

# define ASN1_ADB_TEMPLATE(name) \
        static const ASN1_TEMPLATE name##_tt

/*
 * This is the ASN1 template structure that defines a wrapper round the
 * actual type. It determines the actual position of the field in the value
 * structure, various flags such as OPTIONAL and the field name.
 */

struct ASN1_TEMPLATE_st {
    unsigned long flags;        /* Various flags */
    long tag;                   /* tag, not used if no tagging */
    unsigned long offset;       /* Offset of this field in structure */
# ifndef NO_ASN1_FIELD_NAMES
    const char *field_name;     /* Field name */
# endif
    ASN1_ITEM_EXP *item;        /* Relevant ASN1_ITEM or ASN1_ADB */
};

/* Macro to extract ASN1_ITEM and ASN1_ADB pointer from ASN1_TEMPLATE */

# define ASN1_TEMPLATE_item(t) (t->item_ptr)
# define ASN1_TEMPLATE_adb(t) (t->item_ptr)

typedef struct ASN1_ADB_TABLE_st ASN1_ADB_TABLE;
typedef struct ASN1_ADB_st ASN1_ADB;

struct ASN1_ADB_st {
    unsigned long flags;        /* Various flags */
    unsigned long offset;       /* Offset of selector field */
    STACK_OF(ASN1_ADB_TABLE) **app_items; /* Application defined items */
    const ASN1_ADB_TABLE *tbl;  /* Table of possible types */
    long tblcount;              /* Number of entries in tbl */
    const ASN1_TEMPLATE *default_tt; /* Type to use if no match */
    const ASN1_TEMPLATE *null_tt; /* Type to use if selector is NULL */
};

struct ASN1_ADB_TABLE_st {
    long value;                 /* NID for an object or value for an int */
    const ASN1_TEMPLATE tt;     /* item for this value */
};

/* template flags */

/* Field is optional */
# define ASN1_TFLG_OPTIONAL      (0x1)

/* Field is a SET OF */
# define ASN1_TFLG_SET_OF        (0x1 << 1)

/* Field is a SEQUENCE OF */
# define ASN1_TFLG_SEQUENCE_OF   (0x2 << 1)

/*
 * Special case: this refers to a SET OF that will be sorted into DER order
 * when encoded *and* the corresponding STACK will be modified to match the
 * new order.
 */
# define ASN1_TFLG_SET_ORDER     (0x3 << 1)

/* Mask for SET OF or SEQUENCE OF */
# define ASN1_TFLG_SK_MASK       (0x3 << 1)

/*
 * These flags mean the tag should be taken from the tag field. If EXPLICIT
 * then the underlying type is used for the inner tag.
 */

/* IMPLICIT tagging */
# define ASN1_TFLG_IMPTAG        (0x1 << 3)

/* EXPLICIT tagging, inner tag from underlying type */
# define ASN1_TFLG_EXPTAG        (0x2 << 3)

# define ASN1_TFLG_TAG_MASK      (0x3 << 3)

/* context specific IMPLICIT */
# define ASN1_TFLG_IMPLICIT      ASN1_TFLG_IMPTAG|ASN1_TFLG_CONTEXT

/* context specific EXPLICIT */
# define ASN1_TFLG_EXPLICIT      ASN1_TFLG_EXPTAG|ASN1_TFLG_CONTEXT

/*
 * If tagging is in force these determine the type of tag to use. Otherwise
 * the tag is determined by the underlying type. These values reflect the
 * actual octet format.
 */

/* Universal tag */
# define ASN1_TFLG_UNIVERSAL     (0x0<<6)
/* Application tag */
# define ASN1_TFLG_APPLICATION   (0x1<<6)
/* Context specific tag */
# define ASN1_TFLG_CONTEXT       (0x2<<6)
/* Private tag */
# define ASN1_TFLG_PRIVATE       (0x3<<6)

# define ASN1_TFLG_TAG_CLASS     (0x3<<6)

/*
 * These are for ANY DEFINED BY type. In this case the 'item' field points to
 * an ASN1_ADB structure which contains a table of values to decode the
 * relevant type
 */

# define ASN1_TFLG_ADB_MASK      (0x3<<8)

# define ASN1_TFLG_ADB_OID       (0x1<<8)

# define ASN1_TFLG_ADB_INT       (0x1<<9)

/*
 * This flag means a parent structure is passed instead of the field: this is
 * useful is a SEQUENCE is being combined with a CHOICE for example. Since
 * this means the structure and item name will differ we need to use the
 * ASN1_CHOICE_END_name() macro for example.
 */

# define ASN1_TFLG_COMBINE       (0x1<<10)

/*
 * This flag when present in a SEQUENCE OF, SET OF or EXPLICIT causes
 * indefinite length constructed encoding to be used if required.
 */

# define ASN1_TFLG_NDEF          (0x1<<11)

/* This is the actual ASN1 item itself */

struct ASN1_ITEM_st {
    char itype;                 /* The item type, primitive, SEQUENCE, CHOICE
                                 * or extern */
    long utype;                 /* underlying type */
    const ASN1_TEMPLATE *templates; /* If SEQUENCE or CHOICE this contains
                                     * the contents */
    long tcount;                /* Number of templates if SEQUENCE or CHOICE */
    const void *funcs;          /* functions that handle this type */
    long size;                  /* Structure size (usually) */
# ifndef NO_ASN1_FIELD_NAMES
    const char *sname;          /* Structure name */
# endif
};

/*-
 * These are values for the itype field and
 * determine how the type is interpreted.
 *
 * For PRIMITIVE types the underlying type
 * determines the behaviour if items is NULL.
 *
 * Otherwise templates must contain a single
 * template and the type is treated in the
 * same way as the type specified in the template.
 *
 * For SEQUENCE types the templates field points
 * to the members, the size field is the
 * structure size.
 *
 * For CHOICE types the templates field points
 * to each possible member (typically a union)
 * and the 'size' field is the offset of the
 * selector.
 *
 * The 'funcs' field is used for application
 * specific functions.
 *
 * For COMPAT types the funcs field gives a
 * set of functions that handle this type, this
 * supports the old d2i, i2d convention.
 *
 * The EXTERN type uses a new style d2i/i2d.
 * The new style should be used where possible
 * because it avoids things like the d2i IMPLICIT
 * hack.
 *
 * MSTRING is a multiple string type, it is used
 * for a CHOICE of character strings where the
 * actual strings all occupy an ASN1_STRING
 * structure. In this case the 'utype' field
 * has a special meaning, it is used as a mask
 * of acceptable types using the B_ASN1 constants.
 *
 * NDEF_SEQUENCE is the same as SEQUENCE except
 * that it will use indefinite length constructed
 * encoding if requested.
 *
 */

# define ASN1_ITYPE_PRIMITIVE            0x0

# define ASN1_ITYPE_SEQUENCE             0x1

# define ASN1_ITYPE_CHOICE               0x2

# define ASN1_ITYPE_COMPAT               0x3

# define ASN1_ITYPE_EXTERN               0x4

# define ASN1_ITYPE_MSTRING              0x5

# define ASN1_ITYPE_NDEF_SEQUENCE        0x6

/*
 * Cache for ASN1 tag and length, so we don't keep re-reading it for things
 * like CHOICE
 */

struct ASN1_TLC_st {
    char valid;                 /* Values below are valid */
    int ret;                    /* return value */
    long plen;                  /* length */
    int ptag;                   /* class value */
    int pclass;                 /* class value */
    int hdrlen;                 /* header length */
};

/* Typedefs for ASN1 function pointers */

typedef ASN1_VALUE *ASN1_new_func(void);
typedef void ASN1_free_func(ASN1_VALUE *a);
typedef ASN1_VALUE *ASN1_d2i_func(ASN1_VALUE **a, const unsigned char **in,
                                  long length);
typedef int ASN1_i2d_func(ASN1_VALUE *a, unsigned char **in);

typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
                        const ASN1_ITEM *it, int tag, int aclass, char opt,
                        ASN1_TLC *ctx);

typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
                        const ASN1_ITEM *it, int tag, int aclass);
typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it);

typedef int ASN1_ex_print_func(BIO *out, ASN1_VALUE **pval,
                               int indent, const char *fname,
                               const ASN1_PCTX *pctx);

typedef int ASN1_primitive_i2c(ASN1_VALUE **pval, unsigned char *cont,
                               int *putype, const ASN1_ITEM *it);
typedef int ASN1_primitive_c2i(ASN1_VALUE **pval, const unsigned char *cont,
                               int len, int utype, char *free_cont,
                               const ASN1_ITEM *it);
typedef int ASN1_primitive_print(BIO *out, ASN1_VALUE **pval,
                                 const ASN1_ITEM *it, int indent,
                                 const ASN1_PCTX *pctx);

typedef struct ASN1_COMPAT_FUNCS_st {
    ASN1_new_func *asn1_new;
    ASN1_free_func *asn1_free;
    ASN1_d2i_func *asn1_d2i;
    ASN1_i2d_func *asn1_i2d;
} ASN1_COMPAT_FUNCS;

typedef struct ASN1_EXTERN_FUNCS_st {
    void *app_data;
    ASN1_ex_new_func *asn1_ex_new;
    ASN1_ex_free_func *asn1_ex_free;
    ASN1_ex_free_func *asn1_ex_clear;
    ASN1_ex_d2i *asn1_ex_d2i;
    ASN1_ex_i2d *asn1_ex_i2d;
    ASN1_ex_print_func *asn1_ex_print;
} ASN1_EXTERN_FUNCS;

typedef struct ASN1_PRIMITIVE_FUNCS_st {
    void *app_data;
    unsigned long flags;
    ASN1_ex_new_func *prim_new;
    ASN1_ex_free_func *prim_free;
    ASN1_ex_free_func *prim_clear;
    ASN1_primitive_c2i *prim_c2i;
    ASN1_primitive_i2c *prim_i2c;
    ASN1_primitive_print *prim_print;
} ASN1_PRIMITIVE_FUNCS;

/*
 * This is the ASN1_AUX structure: it handles various miscellaneous
 * requirements. For example the use of reference counts and an informational
 * callback. The "informational callback" is called at various points during
 * the ASN1 encoding and decoding. It can be used to provide minor
 * customisation of the structures used. This is most useful where the
 * supplied routines *almost* do the right thing but need some extra help at
 * a few points. If the callback returns zero then it is assumed a fatal
 * error has occurred and the main operation should be abandoned. If major
 * changes in the default behaviour are required then an external type is
 * more appropriate.
 */

typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it,
                        void *exarg);

typedef struct ASN1_AUX_st {
    void *app_data;
    int flags;
    int ref_offset;             /* Offset of reference value */
    int ref_lock;               /* Lock type to use */
    ASN1_aux_cb *asn1_cb;
    int enc_offset;             /* Offset of ASN1_ENCODING structure */
} ASN1_AUX;

/* For print related callbacks exarg points to this structure */
typedef struct ASN1_PRINT_ARG_st {
    BIO *out;
    int indent;
    const ASN1_PCTX *pctx;
} ASN1_PRINT_ARG;

/* For streaming related callbacks exarg points to this structure */
typedef struct ASN1_STREAM_ARG_st {
    /* BIO to stream through */
    BIO *out;
    /* BIO with filters appended */
    BIO *ndef_bio;
    /* Streaming I/O boundary */
    unsigned char **boundary;
} ASN1_STREAM_ARG;

/* Flags in ASN1_AUX */

/* Use a reference count */
# define ASN1_AFLG_REFCOUNT      1
/* Save the encoding of structure (useful for signatures) */
# define ASN1_AFLG_ENCODING      2
/* The Sequence length is invalid */
# define ASN1_AFLG_BROKEN        4

/* operation values for asn1_cb */

# define ASN1_OP_NEW_PRE         0
# define ASN1_OP_NEW_POST        1
# define ASN1_OP_FREE_PRE        2
# define ASN1_OP_FREE_POST       3
# define ASN1_OP_D2I_PRE         4
# define ASN1_OP_D2I_POST        5
# define ASN1_OP_I2D_PRE         6
# define ASN1_OP_I2D_POST        7
# define ASN1_OP_PRINT_PRE       8
# define ASN1_OP_PRINT_POST      9
# define ASN1_OP_STREAM_PRE      10
# define ASN1_OP_STREAM_POST     11
# define ASN1_OP_DETACHED_PRE    12
# define ASN1_OP_DETACHED_POST   13

/* Macro to implement a primitive type */
# define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0)
# define IMPLEMENT_ASN1_TYPE_ex(itname, vname, ex) \
                                ASN1_ITEM_start(itname) \
                                        ASN1_ITYPE_PRIMITIVE, V_##vname, NULL, 0, NULL, ex, #itname \
                                ASN1_ITEM_end(itname)

/* Macro to implement a multi string type */
# define IMPLEMENT_ASN1_MSTRING(itname, mask) \
                                ASN1_ITEM_start(itname) \
                                        ASN1_ITYPE_MSTRING, mask, NULL, 0, NULL, sizeof(ASN1_STRING), #itname \
                                ASN1_ITEM_end(itname)

/* Macro to implement an ASN1_ITEM in terms of old style funcs */

# define IMPLEMENT_COMPAT_ASN1(sname) IMPLEMENT_COMPAT_ASN1_type(sname, V_ASN1_SEQUENCE)

# define IMPLEMENT_COMPAT_ASN1_type(sname, tag) \
        static const ASN1_COMPAT_FUNCS sname##_ff = { \
                (ASN1_new_func *)sname##_new, \
                (ASN1_free_func *)sname##_free, \
                (ASN1_d2i_func *)d2i_##sname, \
                (ASN1_i2d_func *)i2d_##sname, \
        }; \
        ASN1_ITEM_start(sname) \
                ASN1_ITYPE_COMPAT, \
                tag, \
                NULL, \
                0, \
                &sname##_ff, \
                0, \
                #sname \
        ASN1_ITEM_end(sname)

# define IMPLEMENT_EXTERN_ASN1(sname, tag, fptrs) \
        ASN1_ITEM_start(sname) \
                ASN1_ITYPE_EXTERN, \
                tag, \
                NULL, \
                0, \
                &fptrs, \
                0, \
                #sname \
        ASN1_ITEM_end(sname)

/* Macro to implement standard functions in terms of ASN1_ITEM structures */

# define IMPLEMENT_ASN1_FUNCTIONS(stname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, stname, stname)

# define IMPLEMENT_ASN1_FUNCTIONS_name(stname, itname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, itname)

# define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \
                        IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname)

# define IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(stname) \
                IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(static, stname, stname, stname)

# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS(stname) \
                IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, stname, stname)

# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(pre, stname, itname, fname) \
        pre stname *fname##_new(void) \
        { \
                return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \
        } \
        pre void fname##_free(stname *a) \
        { \
                ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \
        }

# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) \
        stname *fname##_new(void) \
        { \
                return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \
        } \
        void fname##_free(stname *a) \
        { \
                ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \
        }

# define IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, fname) \
        IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \
        IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname)

# define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \
        stname *d2i_##fname(stname **a, const unsigned char **in, long len) \
        { \
                return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\
        } \
        int i2d_##fname(stname *a, unsigned char **out) \
        { \
                return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\
        }

# define IMPLEMENT_ASN1_NDEF_FUNCTION(stname) \
        int i2d_##stname##_NDEF(stname *a, unsigned char **out) \
        { \
                return ASN1_item_ndef_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(stname));\
        }

/*
 * This includes evil casts to remove const: they will go away when full ASN1
 * constification is done.
 */
# define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \
        stname *d2i_##fname(stname **a, const unsigned char **in, long len) \
        { \
                return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\
        } \
        int i2d_##fname(const stname *a, unsigned char **out) \
        { \
                return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\
        }

# define IMPLEMENT_ASN1_DUP_FUNCTION(stname) \
        stname * stname##_dup(stname *x) \
        { \
        return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \
        }

# define IMPLEMENT_ASN1_PRINT_FUNCTION(stname) \
        IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, stname, stname)

# define IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, itname, fname) \
        int fname##_print_ctx(BIO *out, stname *x, int indent, \
                                                const ASN1_PCTX *pctx) \
        { \
                return ASN1_item_print(out, (ASN1_VALUE *)x, indent, \
                        ASN1_ITEM_rptr(itname), pctx); \
        }

# define IMPLEMENT_ASN1_FUNCTIONS_const(name) \
                IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name)

# define IMPLEMENT_ASN1_FUNCTIONS_const_fname(stname, itname, fname) \
        IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \
        IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname)

/* external definitions for primitive types */

DECLARE_ASN1_ITEM(ASN1_BOOLEAN)
DECLARE_ASN1_ITEM(ASN1_TBOOLEAN)
DECLARE_ASN1_ITEM(ASN1_FBOOLEAN)
DECLARE_ASN1_ITEM(ASN1_SEQUENCE)
DECLARE_ASN1_ITEM(CBIGNUM)
DECLARE_ASN1_ITEM(BIGNUM)
DECLARE_ASN1_ITEM(LONG)
DECLARE_ASN1_ITEM(ZLONG)

DECLARE_STACK_OF(ASN1_VALUE)

/* Functions used internally by the ASN1 code */

int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it);

void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
int ASN1_template_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
                      const ASN1_TEMPLATE *tt);
int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
                     const ASN1_ITEM *it, int tag, int aclass, char opt,
                     ASN1_TLC *ctx);

int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
                     const ASN1_ITEM *it, int tag, int aclass);
int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out,
                      const ASN1_TEMPLATE *tt);
void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it);

int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
                const ASN1_ITEM *it);
int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
                int utype, char *free_cont, const ASN1_ITEM *it);

int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it);
int asn1_set_choice_selector(ASN1_VALUE **pval, int value,
                             const ASN1_ITEM *it);

ASN1_VALUE **asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);

const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt,
                                 int nullerr);

int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it);

void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it);
void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval,
                     const ASN1_ITEM *it);
int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen,
                  const ASN1_ITEM *it);

#ifdef  __cplusplus
}
#endif
#endif
openssl/cmac.h000064400000006271151733316560007323 0ustar00/* crypto/cmac/cmac.h */
/*
 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
 * project.
 */
/* ====================================================================
 * Copyright (c) 2010 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 */

#ifndef HEADER_CMAC_H
# define HEADER_CMAC_H

#ifdef __cplusplus
extern "C" {
#endif

# include <openssl/evp.h>

/* Opaque */
typedef struct CMAC_CTX_st CMAC_CTX;

CMAC_CTX *CMAC_CTX_new(void);
void CMAC_CTX_cleanup(CMAC_CTX *ctx);
void CMAC_CTX_free(CMAC_CTX *ctx);
EVP_CIPHER_CTX *CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx);
int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in);

int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
              const EVP_CIPHER *cipher, ENGINE *impl);
int CMAC_Update(CMAC_CTX *ctx, const void *data, size_t dlen);
int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen);
int CMAC_resume(CMAC_CTX *ctx);

#ifdef  __cplusplus
}
#endif
#endif
openssl/md5.h000064400000011261151733316560007100 0ustar00/* crypto/md5/md5.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#ifndef HEADER_MD5_H
# define HEADER_MD5_H

# include <openssl/e_os2.h>
# include <stddef.h>

#ifdef  __cplusplus
extern "C" {
#endif

# ifdef OPENSSL_NO_MD5
#  error MD5 is disabled.
# endif

/*
 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 * ! MD5_LONG has to be at least 32 bits wide. If it's wider, then !
 * ! MD5_LONG_LOG2 has to be defined along.                        !
 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 */

# if defined(__LP32__)
#  define MD5_LONG unsigned long
# elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
#  define MD5_LONG unsigned long
#  define MD5_LONG_LOG2 3
/*
 * _CRAY note. I could declare short, but I have no idea what impact
 * does it have on performance on none-T3E machines. I could declare
 * int, but at least on C90 sizeof(int) can be chosen at compile time.
 * So I've chosen long...
 *                                      <appro@fy.chalmers.se>
 */
# else
#  define MD5_LONG unsigned int
# endif

# define MD5_CBLOCK      64
# define MD5_LBLOCK      (MD5_CBLOCK/4)
# define MD5_DIGEST_LENGTH 16

typedef struct MD5state_st {
    MD5_LONG A, B, C, D;
    MD5_LONG Nl, Nh;
    MD5_LONG data[MD5_LBLOCK];
    unsigned int num;
} MD5_CTX;

# ifdef OPENSSL_FIPS
int private_MD5_Init(MD5_CTX *c);
# endif
int MD5_Init(MD5_CTX *c);
int MD5_Update(MD5_CTX *c, const void *data, size_t len);
int MD5_Final(unsigned char *md, MD5_CTX *c);
unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md);
void MD5_Transform(MD5_CTX *c, const unsigned char *b);
#ifdef  __cplusplus
}
#endif

#endif
openssl/asn1_mac.h000064400000057563151733316560010114 0ustar00/* crypto/asn1/asn1_mac.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#ifndef HEADER_ASN1_MAC_H
# define HEADER_ASN1_MAC_H

# include <openssl/asn1.h>

#ifdef  __cplusplus
extern "C" {
#endif

# ifndef ASN1_MAC_ERR_LIB
#  define ASN1_MAC_ERR_LIB        ERR_LIB_ASN1
# endif

# define ASN1_MAC_H_err(f,r,line) \
        ERR_PUT_error(ASN1_MAC_ERR_LIB,(f),(r),__FILE__,(line))

# define M_ASN1_D2I_vars(a,type,func) \
        ASN1_const_CTX c; \
        type ret=NULL; \
        \
        c.pp=(const unsigned char **)pp; \
        c.q= *(const unsigned char **)pp; \
        c.error=ERR_R_NESTED_ASN1_ERROR; \
        if ((a == NULL) || ((*a) == NULL)) \
                { if ((ret=(type)func()) == NULL) \
                        { c.line=__LINE__; goto err; } } \
        else    ret=(*a);

# define M_ASN1_D2I_Init() \
        c.p= *(const unsigned char **)pp; \
        c.max=(length == 0)?0:(c.p+length);

# define M_ASN1_D2I_Finish_2(a) \
        if (!asn1_const_Finish(&c)) \
                { c.line=__LINE__; goto err; } \
        *(const unsigned char **)pp=c.p; \
        if (a != NULL) (*a)=ret; \
        return(ret);

# define M_ASN1_D2I_Finish(a,func,e) \
        M_ASN1_D2I_Finish_2(a); \
err:\
        ASN1_MAC_H_err((e),c.error,c.line); \
        asn1_add_error(*(const unsigned char **)pp,(int)(c.q- *pp)); \
        if ((ret != NULL) && ((a == NULL) || (*a != ret))) func(ret); \
        return(NULL)

# define M_ASN1_D2I_start_sequence() \
        if (!asn1_GetSequence(&c,&length)) \
                { c.line=__LINE__; goto err; }
/* Begin reading ASN1 without a surrounding sequence */
# define M_ASN1_D2I_begin() \
        c.slen = length;

/* End reading ASN1 with no check on length */
# define M_ASN1_D2I_Finish_nolen(a, func, e) \
        *pp=c.p; \
        if (a != NULL) (*a)=ret; \
        return(ret); \
err:\
        ASN1_MAC_H_err((e),c.error,c.line); \
        asn1_add_error(*pp,(int)(c.q- *pp)); \
        if ((ret != NULL) && ((a == NULL) || (*a != ret))) func(ret); \
        return(NULL)

# define M_ASN1_D2I_end_sequence() \
        (((c.inf&1) == 0)?(c.slen <= 0): \
                (c.eos=ASN1_const_check_infinite_end(&c.p,c.slen)))

/* Don't use this with d2i_ASN1_BOOLEAN() */
# define M_ASN1_D2I_get(b, func) \
        c.q=c.p; \
        if (func(&(b),&c.p,c.slen) == NULL) \
                {c.line=__LINE__; goto err; } \
        c.slen-=(c.p-c.q);

/* Don't use this with d2i_ASN1_BOOLEAN() */
# define M_ASN1_D2I_get_x(type,b,func) \
        c.q=c.p; \
        if (((D2I_OF(type))func)(&(b),&c.p,c.slen) == NULL) \
                {c.line=__LINE__; goto err; } \
        c.slen-=(c.p-c.q);

/* use this instead () */
# define M_ASN1_D2I_get_int(b,func) \
        c.q=c.p; \
        if (func(&(b),&c.p,c.slen) < 0) \
                {c.line=__LINE__; goto err; } \
        c.slen-=(c.p-c.q);

# define M_ASN1_D2I_get_opt(b,func,type) \
        if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) \
                == (V_ASN1_UNIVERSAL|(type)))) \
                { \
                M_ASN1_D2I_get(b,func); \
                }

# define M_ASN1_D2I_get_int_opt(b,func,type) \
        if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) \
                == (V_ASN1_UNIVERSAL|(type)))) \
                { \
                M_ASN1_D2I_get_int(b,func); \
                }

# define M_ASN1_D2I_get_imp(b,func, type) \
        M_ASN1_next=(_tmp& V_ASN1_CONSTRUCTED)|type; \
        c.q=c.p; \
        if (func(&(b),&c.p,c.slen) == NULL) \
                {c.line=__LINE__; M_ASN1_next_prev = _tmp; goto err; } \
        c.slen-=(c.p-c.q);\
        M_ASN1_next_prev=_tmp;

# define M_ASN1_D2I_get_IMP_opt(b,func,tag,type) \
        if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) == \
                (V_ASN1_CONTEXT_SPECIFIC|(tag)))) \
                { \
                unsigned char _tmp = M_ASN1_next; \
                M_ASN1_D2I_get_imp(b,func, type);\
                }

# define M_ASN1_D2I_get_set(r,func,free_func) \
                M_ASN1_D2I_get_imp_set(r,func,free_func, \
                        V_ASN1_SET,V_ASN1_UNIVERSAL);

# define M_ASN1_D2I_get_set_type(type,r,func,free_func) \
                M_ASN1_D2I_get_imp_set_type(type,r,func,free_func, \
                        V_ASN1_SET,V_ASN1_UNIVERSAL);

# define M_ASN1_D2I_get_set_opt(r,func,free_func) \
        if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
                V_ASN1_CONSTRUCTED|V_ASN1_SET)))\
                { M_ASN1_D2I_get_set(r,func,free_func); }

# define M_ASN1_D2I_get_set_opt_type(type,r,func,free_func) \
        if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
                V_ASN1_CONSTRUCTED|V_ASN1_SET)))\
                { M_ASN1_D2I_get_set_type(type,r,func,free_func); }

# define M_ASN1_I2D_len_SET_opt(a,f) \
        if ((a != NULL) && (sk_num(a) != 0)) \
                M_ASN1_I2D_len_SET(a,f);

# define M_ASN1_I2D_put_SET_opt(a,f) \
        if ((a != NULL) && (sk_num(a) != 0)) \
                M_ASN1_I2D_put_SET(a,f);

# define M_ASN1_I2D_put_SEQUENCE_opt(a,f) \
        if ((a != NULL) && (sk_num(a) != 0)) \
                M_ASN1_I2D_put_SEQUENCE(a,f);

# define M_ASN1_I2D_put_SEQUENCE_opt_type(type,a,f) \
        if ((a != NULL) && (sk_##type##_num(a) != 0)) \
                M_ASN1_I2D_put_SEQUENCE_type(type,a,f);

# define M_ASN1_D2I_get_IMP_set_opt(b,func,free_func,tag) \
        if ((c.slen != 0) && \
                (M_ASN1_next == \
                (V_ASN1_CONTEXT_SPECIFIC|V_ASN1_CONSTRUCTED|(tag))))\
                { \
                M_ASN1_D2I_get_imp_set(b,func,free_func,\
                        tag,V_ASN1_CONTEXT_SPECIFIC); \
                }

# define M_ASN1_D2I_get_IMP_set_opt_type(type,b,func,free_func,tag) \
        if ((c.slen != 0) && \
                (M_ASN1_next == \
                (V_ASN1_CONTEXT_SPECIFIC|V_ASN1_CONSTRUCTED|(tag))))\
                { \
                M_ASN1_D2I_get_imp_set_type(type,b,func,free_func,\
                        tag,V_ASN1_CONTEXT_SPECIFIC); \
                }

# define M_ASN1_D2I_get_seq(r,func,free_func) \
                M_ASN1_D2I_get_imp_set(r,func,free_func,\
                        V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);

# define M_ASN1_D2I_get_seq_type(type,r,func,free_func) \
                M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,\
                                            V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL)

# define M_ASN1_D2I_get_seq_opt(r,func,free_func) \
        if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
                V_ASN1_CONSTRUCTED|V_ASN1_SEQUENCE)))\
                { M_ASN1_D2I_get_seq(r,func,free_func); }

# define M_ASN1_D2I_get_seq_opt_type(type,r,func,free_func) \
        if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
                V_ASN1_CONSTRUCTED|V_ASN1_SEQUENCE)))\
                { M_ASN1_D2I_get_seq_type(type,r,func,free_func); }

# define M_ASN1_D2I_get_IMP_set(r,func,free_func,x) \
                M_ASN1_D2I_get_imp_set(r,func,free_func,\
                        x,V_ASN1_CONTEXT_SPECIFIC);

# define M_ASN1_D2I_get_IMP_set_type(type,r,func,free_func,x) \
                M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,\
                        x,V_ASN1_CONTEXT_SPECIFIC);

# define M_ASN1_D2I_get_imp_set(r,func,free_func,a,b) \
        c.q=c.p; \
        if (d2i_ASN1_SET(&(r),&c.p,c.slen,(char *(*)())func,\
                (void (*)())free_func,a,b) == NULL) \
                { c.line=__LINE__; goto err; } \
        c.slen-=(c.p-c.q);

# define M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,a,b) \
        c.q=c.p; \
        if (d2i_ASN1_SET_OF_##type(&(r),&c.p,c.slen,func,\
                                   free_func,a,b) == NULL) \
                { c.line=__LINE__; goto err; } \
        c.slen-=(c.p-c.q);

# define M_ASN1_D2I_get_set_strings(r,func,a,b) \
        c.q=c.p; \
        if (d2i_ASN1_STRING_SET(&(r),&c.p,c.slen,a,b) == NULL) \
                { c.line=__LINE__; goto err; } \
        c.slen-=(c.p-c.q);

# define M_ASN1_D2I_get_EXP_opt(r,func,tag) \
        if ((c.slen != 0L) && (M_ASN1_next == \
                (V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \
                { \
                int Tinf,Ttag,Tclass; \
                long Tlen; \
                \
                c.q=c.p; \
                Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \
                if (Tinf & 0x80) \
                        { c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \
                        c.line=__LINE__; goto err; } \
                if (Tinf == (V_ASN1_CONSTRUCTED+1)) \
                                        Tlen = c.slen - (c.p - c.q) - 2; \
                if (func(&(r),&c.p,Tlen) == NULL) \
                        { c.line=__LINE__; goto err; } \
                if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \
                        Tlen = c.slen - (c.p - c.q); \
                        if(!ASN1_const_check_infinite_end(&c.p, Tlen)) \
                                { c.error=ERR_R_MISSING_ASN1_EOS; \
                                c.line=__LINE__; goto err; } \
                }\
                c.slen-=(c.p-c.q); \
                }

# define M_ASN1_D2I_get_EXP_set_opt(r,func,free_func,tag,b) \
        if ((c.slen != 0) && (M_ASN1_next == \
                (V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \
                { \
                int Tinf,Ttag,Tclass; \
                long Tlen; \
                \
                c.q=c.p; \
                Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \
                if (Tinf & 0x80) \
                        { c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \
                        c.line=__LINE__; goto err; } \
                if (Tinf == (V_ASN1_CONSTRUCTED+1)) \
                                        Tlen = c.slen - (c.p - c.q) - 2; \
                if (d2i_ASN1_SET(&(r),&c.p,Tlen,(char *(*)())func, \
                        (void (*)())free_func, \
                        b,V_ASN1_UNIVERSAL) == NULL) \
                        { c.line=__LINE__; goto err; } \
                if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \
                        Tlen = c.slen - (c.p - c.q); \
                        if(!ASN1_check_infinite_end(&c.p, Tlen)) \
                                { c.error=ERR_R_MISSING_ASN1_EOS; \
                                c.line=__LINE__; goto err; } \
                }\
                c.slen-=(c.p-c.q); \
                }

# define M_ASN1_D2I_get_EXP_set_opt_type(type,r,func,free_func,tag,b) \
        if ((c.slen != 0) && (M_ASN1_next == \
                (V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \
                { \
                int Tinf,Ttag,Tclass; \
                long Tlen; \
                \
                c.q=c.p; \
                Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \
                if (Tinf & 0x80) \
                        { c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \
                        c.line=__LINE__; goto err; } \
                if (Tinf == (V_ASN1_CONSTRUCTED+1)) \
                                        Tlen = c.slen - (c.p - c.q) - 2; \
                if (d2i_ASN1_SET_OF_##type(&(r),&c.p,Tlen,func, \
                        free_func,b,V_ASN1_UNIVERSAL) == NULL) \
                        { c.line=__LINE__; goto err; } \
                if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \
                        Tlen = c.slen - (c.p - c.q); \
                        if(!ASN1_check_infinite_end(&c.p, Tlen)) \
                                { c.error=ERR_R_MISSING_ASN1_EOS; \
                                c.line=__LINE__; goto err; } \
                }\
                c.slen-=(c.p-c.q); \
                }

/* New macros */
# define M_ASN1_New_Malloc(ret,type) \
        if ((ret=(type *)OPENSSL_malloc(sizeof(type))) == NULL) \
                { c.line=__LINE__; goto err2; }

# define M_ASN1_New(arg,func) \
        if (((arg)=func()) == NULL) return(NULL)

# define M_ASN1_New_Error(a) \
/*-     err:    ASN1_MAC_H_err((a),ERR_R_NESTED_ASN1_ERROR,c.line); \
                return(NULL);*/ \
        err2:   ASN1_MAC_H_err((a),ERR_R_MALLOC_FAILURE,c.line); \
                return(NULL)

/*
 * BIG UGLY WARNING! This is so damn ugly I wanna puke.  Unfortunately, some
 * macros that use ASN1_const_CTX still insist on writing in the input
 * stream.  ARGH! ARGH! ARGH! Let's get rid of this macro package. Please? --
 * Richard Levitte
 */
# define M_ASN1_next             (*((unsigned char *)(c.p)))
# define M_ASN1_next_prev        (*((unsigned char *)(c.q)))

/*************************************************/

# define M_ASN1_I2D_vars(a)      int r=0,ret=0; \
                                unsigned char *p; \
                                if (a == NULL) return(0)

/* Length Macros */
# define M_ASN1_I2D_len(a,f)     ret+=f(a,NULL)
# define M_ASN1_I2D_len_IMP_opt(a,f)     if (a != NULL) M_ASN1_I2D_len(a,f)

# define M_ASN1_I2D_len_SET(a,f) \
                ret+=i2d_ASN1_SET(a,NULL,f,V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET);

# define M_ASN1_I2D_len_SET_type(type,a,f) \
                ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,V_ASN1_SET, \
                                            V_ASN1_UNIVERSAL,IS_SET);

# define M_ASN1_I2D_len_SEQUENCE(a,f) \
                ret+=i2d_ASN1_SET(a,NULL,f,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL, \
                                  IS_SEQUENCE);

# define M_ASN1_I2D_len_SEQUENCE_type(type,a,f) \
                ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,V_ASN1_SEQUENCE, \
                                            V_ASN1_UNIVERSAL,IS_SEQUENCE)

# define M_ASN1_I2D_len_SEQUENCE_opt(a,f) \
                if ((a != NULL) && (sk_num(a) != 0)) \
                        M_ASN1_I2D_len_SEQUENCE(a,f);

# define M_ASN1_I2D_len_SEQUENCE_opt_type(type,a,f) \
                if ((a != NULL) && (sk_##type##_num(a) != 0)) \
                        M_ASN1_I2D_len_SEQUENCE_type(type,a,f);

# define M_ASN1_I2D_len_IMP_SET(a,f,x) \
                ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC,IS_SET);

# define M_ASN1_I2D_len_IMP_SET_type(type,a,f,x) \
                ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \
                                            V_ASN1_CONTEXT_SPECIFIC,IS_SET);

# define M_ASN1_I2D_len_IMP_SET_opt(a,f,x) \
                if ((a != NULL) && (sk_num(a) != 0)) \
                        ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \
                                          IS_SET);

# define M_ASN1_I2D_len_IMP_SET_opt_type(type,a,f,x) \
                if ((a != NULL) && (sk_##type##_num(a) != 0)) \
                        ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \
                                               V_ASN1_CONTEXT_SPECIFIC,IS_SET);

# define M_ASN1_I2D_len_IMP_SEQUENCE(a,f,x) \
                ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \
                                  IS_SEQUENCE);

# define M_ASN1_I2D_len_IMP_SEQUENCE_opt(a,f,x) \
                if ((a != NULL) && (sk_num(a) != 0)) \
                        ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \
                                          IS_SEQUENCE);

# define M_ASN1_I2D_len_IMP_SEQUENCE_opt_type(type,a,f,x) \
                if ((a != NULL) && (sk_##type##_num(a) != 0)) \
                        ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \
                                                    V_ASN1_CONTEXT_SPECIFIC, \
                                                    IS_SEQUENCE);

# define M_ASN1_I2D_len_EXP_opt(a,f,mtag,v) \
                if (a != NULL)\
                        { \
                        v=f(a,NULL); \
                        ret+=ASN1_object_size(1,v,mtag); \
                        }

# define M_ASN1_I2D_len_EXP_SET_opt(a,f,mtag,tag,v) \
                if ((a != NULL) && (sk_num(a) != 0))\
                        { \
                        v=i2d_ASN1_SET(a,NULL,f,tag,V_ASN1_UNIVERSAL,IS_SET); \
                        ret+=ASN1_object_size(1,v,mtag); \
                        }

# define M_ASN1_I2D_len_EXP_SEQUENCE_opt(a,f,mtag,tag,v) \
                if ((a != NULL) && (sk_num(a) != 0))\
                        { \
                        v=i2d_ASN1_SET(a,NULL,f,tag,V_ASN1_UNIVERSAL, \
                                       IS_SEQUENCE); \
                        ret+=ASN1_object_size(1,v,mtag); \
                        }

# define M_ASN1_I2D_len_EXP_SEQUENCE_opt_type(type,a,f,mtag,tag,v) \
                if ((a != NULL) && (sk_##type##_num(a) != 0))\
                        { \
                        v=i2d_ASN1_SET_OF_##type(a,NULL,f,tag, \
                                                 V_ASN1_UNIVERSAL, \
                                                 IS_SEQUENCE); \
                        ret+=ASN1_object_size(1,v,mtag); \
                        }

/* Put Macros */
# define M_ASN1_I2D_put(a,f)     f(a,&p)

# define M_ASN1_I2D_put_IMP_opt(a,f,t)   \
                if (a != NULL) \
                        { \
                        unsigned char *q=p; \
                        f(a,&p); \
                        *q=(V_ASN1_CONTEXT_SPECIFIC|t|(*q&V_ASN1_CONSTRUCTED));\
                        }

# define M_ASN1_I2D_put_SET(a,f) i2d_ASN1_SET(a,&p,f,V_ASN1_SET,\
                        V_ASN1_UNIVERSAL,IS_SET)
# define M_ASN1_I2D_put_SET_type(type,a,f) \
     i2d_ASN1_SET_OF_##type(a,&p,f,V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET)
# define M_ASN1_I2D_put_IMP_SET(a,f,x) i2d_ASN1_SET(a,&p,f,x,\
                        V_ASN1_CONTEXT_SPECIFIC,IS_SET)
# define M_ASN1_I2D_put_IMP_SET_type(type,a,f,x) \
     i2d_ASN1_SET_OF_##type(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC,IS_SET)
# define M_ASN1_I2D_put_IMP_SEQUENCE(a,f,x) i2d_ASN1_SET(a,&p,f,x,\
                        V_ASN1_CONTEXT_SPECIFIC,IS_SEQUENCE)

# define M_ASN1_I2D_put_SEQUENCE(a,f) i2d_ASN1_SET(a,&p,f,V_ASN1_SEQUENCE,\
                                             V_ASN1_UNIVERSAL,IS_SEQUENCE)

# define M_ASN1_I2D_put_SEQUENCE_type(type,a,f) \
     i2d_ASN1_SET_OF_##type(a,&p,f,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL, \
                            IS_SEQUENCE)

# define M_ASN1_I2D_put_SEQUENCE_opt(a,f) \
                if ((a != NULL) && (sk_num(a) != 0)) \
                        M_ASN1_I2D_put_SEQUENCE(a,f);

# define M_ASN1_I2D_put_IMP_SET_opt(a,f,x) \
                if ((a != NULL) && (sk_num(a) != 0)) \
                        { i2d_ASN1_SET(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC, \
                                       IS_SET); }

# define M_ASN1_I2D_put_IMP_SET_opt_type(type,a,f,x) \
                if ((a != NULL) && (sk_##type##_num(a) != 0)) \
                        { i2d_ASN1_SET_OF_##type(a,&p,f,x, \
                                                 V_ASN1_CONTEXT_SPECIFIC, \
                                                 IS_SET); }

# define M_ASN1_I2D_put_IMP_SEQUENCE_opt(a,f,x) \
                if ((a != NULL) && (sk_num(a) != 0)) \
                        { i2d_ASN1_SET(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC, \
                                       IS_SEQUENCE); }

# define M_ASN1_I2D_put_IMP_SEQUENCE_opt_type(type,a,f,x) \
                if ((a != NULL) && (sk_##type##_num(a) != 0)) \
                        { i2d_ASN1_SET_OF_##type(a,&p,f,x, \
                                                 V_ASN1_CONTEXT_SPECIFIC, \
                                                 IS_SEQUENCE); }

# define M_ASN1_I2D_put_EXP_opt(a,f,tag,v) \
                if (a != NULL) \
                        { \
                        ASN1_put_object(&p,1,v,tag,V_ASN1_CONTEXT_SPECIFIC); \
                        f(a,&p); \
                        }

# define M_ASN1_I2D_put_EXP_SET_opt(a,f,mtag,tag,v) \
                if ((a != NULL) && (sk_num(a) != 0)) \
                        { \
                        ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \
                        i2d_ASN1_SET(a,&p,f,tag,V_ASN1_UNIVERSAL,IS_SET); \
                        }

# define M_ASN1_I2D_put_EXP_SEQUENCE_opt(a,f,mtag,tag,v) \
                if ((a != NULL) && (sk_num(a) != 0)) \
                        { \
                        ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \
                        i2d_ASN1_SET(a,&p,f,tag,V_ASN1_UNIVERSAL,IS_SEQUENCE); \
                        }

# define M_ASN1_I2D_put_EXP_SEQUENCE_opt_type(type,a,f,mtag,tag,v) \
                if ((a != NULL) && (sk_##type##_num(a) != 0)) \
                        { \
                        ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \
                        i2d_ASN1_SET_OF_##type(a,&p,f,tag,V_ASN1_UNIVERSAL, \
                                               IS_SEQUENCE); \
                        }

# define M_ASN1_I2D_seq_total() \
                r=ASN1_object_size(1,ret,V_ASN1_SEQUENCE); \
                if (pp == NULL) return(r); \
                p= *pp; \
                ASN1_put_object(&p,1,ret,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL)

# define M_ASN1_I2D_INF_seq_start(tag,ctx) \
                *(p++)=(V_ASN1_CONSTRUCTED|(tag)|(ctx)); \
                *(p++)=0x80

# define M_ASN1_I2D_INF_seq_end() *(p++)=0x00; *(p++)=0x00

# define M_ASN1_I2D_finish()     *pp=p; \
                                return(r);

int asn1_GetSequence(ASN1_const_CTX *c, long *length);
void asn1_add_error(const unsigned char *address, int offset);
#ifdef  __cplusplus
}
#endif

#endif
openssl/ssl23.h000064400000007315151733316560007366 0ustar00/* ssl/ssl23.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#ifndef HEADER_SSL23_H
# define HEADER_SSL23_H

#ifdef  __cplusplus
extern "C" {
#endif

/*
 * client
 */
/* write to server */
# define SSL23_ST_CW_CLNT_HELLO_A        (0x210|SSL_ST_CONNECT)
# define SSL23_ST_CW_CLNT_HELLO_B        (0x211|SSL_ST_CONNECT)
/* read from server */
# define SSL23_ST_CR_SRVR_HELLO_A        (0x220|SSL_ST_CONNECT)
# define SSL23_ST_CR_SRVR_HELLO_B        (0x221|SSL_ST_CONNECT)

/* server */
/* read from client */
# define SSL23_ST_SR_CLNT_HELLO_A        (0x210|SSL_ST_ACCEPT)
# define SSL23_ST_SR_CLNT_HELLO_B        (0x211|SSL_ST_ACCEPT)

#ifdef  __cplusplus
}
#endif
#endif
openssl/obj_mac.h000064400000527051151733316570010017 0ustar00/* crypto/objects/obj_mac.h */

/*
 * THIS FILE IS GENERATED FROM objects.txt by objects.pl via the following
 * command: perl objects.pl objects.txt obj_mac.num obj_mac.h
 */

/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#define SN_undef                        "UNDEF"
#define LN_undef                        "undefined"
#define NID_undef                       0
#define OBJ_undef                       0L

#define SN_itu_t                "ITU-T"
#define LN_itu_t                "itu-t"
#define NID_itu_t               645
#define OBJ_itu_t               0L

#define NID_ccitt               404
#define OBJ_ccitt               OBJ_itu_t

#define SN_iso          "ISO"
#define LN_iso          "iso"
#define NID_iso         181
#define OBJ_iso         1L

#define SN_joint_iso_itu_t              "JOINT-ISO-ITU-T"
#define LN_joint_iso_itu_t              "joint-iso-itu-t"
#define NID_joint_iso_itu_t             646
#define OBJ_joint_iso_itu_t             2L

#define NID_joint_iso_ccitt             393
#define OBJ_joint_iso_ccitt             OBJ_joint_iso_itu_t

#define SN_member_body          "member-body"
#define LN_member_body          "ISO Member Body"
#define NID_member_body         182
#define OBJ_member_body         OBJ_iso,2L

#define SN_identified_organization              "identified-organization"
#define NID_identified_organization             676
#define OBJ_identified_organization             OBJ_iso,3L

#define SN_hmac_md5             "HMAC-MD5"
#define LN_hmac_md5             "hmac-md5"
#define NID_hmac_md5            780
#define OBJ_hmac_md5            OBJ_identified_organization,6L,1L,5L,5L,8L,1L,1L

#define SN_hmac_sha1            "HMAC-SHA1"
#define LN_hmac_sha1            "hmac-sha1"
#define NID_hmac_sha1           781
#define OBJ_hmac_sha1           OBJ_identified_organization,6L,1L,5L,5L,8L,1L,2L

#define SN_certicom_arc         "certicom-arc"
#define NID_certicom_arc                677
#define OBJ_certicom_arc                OBJ_identified_organization,132L

#define SN_international_organizations          "international-organizations"
#define LN_international_organizations          "International Organizations"
#define NID_international_organizations         647
#define OBJ_international_organizations         OBJ_joint_iso_itu_t,23L

#define SN_wap          "wap"
#define NID_wap         678
#define OBJ_wap         OBJ_international_organizations,43L

#define SN_wap_wsg              "wap-wsg"
#define NID_wap_wsg             679
#define OBJ_wap_wsg             OBJ_wap,1L

#define SN_selected_attribute_types             "selected-attribute-types"
#define LN_selected_attribute_types             "Selected Attribute Types"
#define NID_selected_attribute_types            394
#define OBJ_selected_attribute_types            OBJ_joint_iso_itu_t,5L,1L,5L

#define SN_clearance            "clearance"
#define NID_clearance           395
#define OBJ_clearance           OBJ_selected_attribute_types,55L

#define SN_ISO_US               "ISO-US"
#define LN_ISO_US               "ISO US Member Body"
#define NID_ISO_US              183
#define OBJ_ISO_US              OBJ_member_body,840L

#define SN_X9_57                "X9-57"
#define LN_X9_57                "X9.57"
#define NID_X9_57               184
#define OBJ_X9_57               OBJ_ISO_US,10040L

#define SN_X9cm         "X9cm"
#define LN_X9cm         "X9.57 CM ?"
#define NID_X9cm                185
#define OBJ_X9cm                OBJ_X9_57,4L

#define SN_dsa          "DSA"
#define LN_dsa          "dsaEncryption"
#define NID_dsa         116
#define OBJ_dsa         OBJ_X9cm,1L

#define SN_dsaWithSHA1          "DSA-SHA1"
#define LN_dsaWithSHA1          "dsaWithSHA1"
#define NID_dsaWithSHA1         113
#define OBJ_dsaWithSHA1         OBJ_X9cm,3L

#define SN_ansi_X9_62           "ansi-X9-62"
#define LN_ansi_X9_62           "ANSI X9.62"
#define NID_ansi_X9_62          405
#define OBJ_ansi_X9_62          OBJ_ISO_US,10045L

#define OBJ_X9_62_id_fieldType          OBJ_ansi_X9_62,1L

#define SN_X9_62_prime_field            "prime-field"
#define NID_X9_62_prime_field           406
#define OBJ_X9_62_prime_field           OBJ_X9_62_id_fieldType,1L

#define SN_X9_62_characteristic_two_field               "characteristic-two-field"
#define NID_X9_62_characteristic_two_field              407
#define OBJ_X9_62_characteristic_two_field              OBJ_X9_62_id_fieldType,2L

#define SN_X9_62_id_characteristic_two_basis            "id-characteristic-two-basis"
#define NID_X9_62_id_characteristic_two_basis           680
#define OBJ_X9_62_id_characteristic_two_basis           OBJ_X9_62_characteristic_two_field,3L

#define SN_X9_62_onBasis                "onBasis"
#define NID_X9_62_onBasis               681
#define OBJ_X9_62_onBasis               OBJ_X9_62_id_characteristic_two_basis,1L

#define SN_X9_62_tpBasis                "tpBasis"
#define NID_X9_62_tpBasis               682
#define OBJ_X9_62_tpBasis               OBJ_X9_62_id_characteristic_two_basis,2L

#define SN_X9_62_ppBasis                "ppBasis"
#define NID_X9_62_ppBasis               683
#define OBJ_X9_62_ppBasis               OBJ_X9_62_id_characteristic_two_basis,3L

#define OBJ_X9_62_id_publicKeyType              OBJ_ansi_X9_62,2L

#define SN_X9_62_id_ecPublicKey         "id-ecPublicKey"
#define NID_X9_62_id_ecPublicKey                408
#define OBJ_X9_62_id_ecPublicKey                OBJ_X9_62_id_publicKeyType,1L

#define OBJ_X9_62_ellipticCurve         OBJ_ansi_X9_62,3L

#define OBJ_X9_62_c_TwoCurve            OBJ_X9_62_ellipticCurve,0L

#define SN_X9_62_c2pnb163v1             "c2pnb163v1"
#define NID_X9_62_c2pnb163v1            684
#define OBJ_X9_62_c2pnb163v1            OBJ_X9_62_c_TwoCurve,1L

#define SN_X9_62_c2pnb163v2             "c2pnb163v2"
#define NID_X9_62_c2pnb163v2            685
#define OBJ_X9_62_c2pnb163v2            OBJ_X9_62_c_TwoCurve,2L

#define SN_X9_62_c2pnb163v3             "c2pnb163v3"
#define NID_X9_62_c2pnb163v3            686
#define OBJ_X9_62_c2pnb163v3            OBJ_X9_62_c_TwoCurve,3L

#define SN_X9_62_c2pnb176v1             "c2pnb176v1"
#define NID_X9_62_c2pnb176v1            687
#define OBJ_X9_62_c2pnb176v1            OBJ_X9_62_c_TwoCurve,4L

#define SN_X9_62_c2tnb191v1             "c2tnb191v1"
#define NID_X9_62_c2tnb191v1            688
#define OBJ_X9_62_c2tnb191v1            OBJ_X9_62_c_TwoCurve,5L

#define SN_X9_62_c2tnb191v2             "c2tnb191v2"
#define NID_X9_62_c2tnb191v2            689
#define OBJ_X9_62_c2tnb191v2            OBJ_X9_62_c_TwoCurve,6L

#define SN_X9_62_c2tnb191v3             "c2tnb191v3"
#define NID_X9_62_c2tnb191v3            690
#define OBJ_X9_62_c2tnb191v3            OBJ_X9_62_c_TwoCurve,7L

#define SN_X9_62_c2onb191v4             "c2onb191v4"
#define NID_X9_62_c2onb191v4            691
#define OBJ_X9_62_c2onb191v4            OBJ_X9_62_c_TwoCurve,8L

#define SN_X9_62_c2onb191v5             "c2onb191v5"
#define NID_X9_62_c2onb191v5            692
#define OBJ_X9_62_c2onb191v5            OBJ_X9_62_c_TwoCurve,9L

#define SN_X9_62_c2pnb208w1             "c2pnb208w1"
#define NID_X9_62_c2pnb208w1            693
#define OBJ_X9_62_c2pnb208w1            OBJ_X9_62_c_TwoCurve,10L

#define SN_X9_62_c2tnb239v1             "c2tnb239v1"
#define NID_X9_62_c2tnb239v1            694
#define OBJ_X9_62_c2tnb239v1            OBJ_X9_62_c_TwoCurve,11L

#define SN_X9_62_c2tnb239v2             "c2tnb239v2"
#define NID_X9_62_c2tnb239v2            695
#define OBJ_X9_62_c2tnb239v2            OBJ_X9_62_c_TwoCurve,12L

#define SN_X9_62_c2tnb239v3             "c2tnb239v3"
#define NID_X9_62_c2tnb239v3            696
#define OBJ_X9_62_c2tnb239v3            OBJ_X9_62_c_TwoCurve,13L

#define SN_X9_62_c2onb239v4             "c2onb239v4"
#define NID_X9_62_c2onb239v4            697
#define OBJ_X9_62_c2onb239v4            OBJ_X9_62_c_TwoCurve,14L

#define SN_X9_62_c2onb239v5             "c2onb239v5"
#define NID_X9_62_c2onb239v5            698
#define OBJ_X9_62_c2onb239v5            OBJ_X9_62_c_TwoCurve,15L

#define SN_X9_62_c2pnb272w1             "c2pnb272w1"
#define NID_X9_62_c2pnb272w1            699
#define OBJ_X9_62_c2pnb272w1            OBJ_X9_62_c_TwoCurve,16L

#define SN_X9_62_c2pnb304w1             "c2pnb304w1"
#define NID_X9_62_c2pnb304w1            700
#define OBJ_X9_62_c2pnb304w1            OBJ_X9_62_c_TwoCurve,17L

#define SN_X9_62_c2tnb359v1             "c2tnb359v1"
#define NID_X9_62_c2tnb359v1            701
#define OBJ_X9_62_c2tnb359v1            OBJ_X9_62_c_TwoCurve,18L

#define SN_X9_62_c2pnb368w1             "c2pnb368w1"
#define NID_X9_62_c2pnb368w1            702
#define OBJ_X9_62_c2pnb368w1            OBJ_X9_62_c_TwoCurve,19L

#define SN_X9_62_c2tnb431r1             "c2tnb431r1"
#define NID_X9_62_c2tnb431r1            703
#define OBJ_X9_62_c2tnb431r1            OBJ_X9_62_c_TwoCurve,20L

#define OBJ_X9_62_primeCurve            OBJ_X9_62_ellipticCurve,1L

#define SN_X9_62_prime192v1             "prime192v1"
#define NID_X9_62_prime192v1            409
#define OBJ_X9_62_prime192v1            OBJ_X9_62_primeCurve,1L

#define SN_X9_62_prime192v2             "prime192v2"
#define NID_X9_62_prime192v2            410
#define OBJ_X9_62_prime192v2            OBJ_X9_62_primeCurve,2L

#define SN_X9_62_prime192v3             "prime192v3"
#define NID_X9_62_prime192v3            411
#define OBJ_X9_62_prime192v3            OBJ_X9_62_primeCurve,3L

#define SN_X9_62_prime239v1             "prime239v1"
#define NID_X9_62_prime239v1            412
#define OBJ_X9_62_prime239v1            OBJ_X9_62_primeCurve,4L

#define SN_X9_62_prime239v2             "prime239v2"
#define NID_X9_62_prime239v2            413
#define OBJ_X9_62_prime239v2            OBJ_X9_62_primeCurve,5L

#define SN_X9_62_prime239v3             "prime239v3"
#define NID_X9_62_prime239v3            414
#define OBJ_X9_62_prime239v3            OBJ_X9_62_primeCurve,6L

#define SN_X9_62_prime256v1             "prime256v1"
#define NID_X9_62_prime256v1            415
#define OBJ_X9_62_prime256v1            OBJ_X9_62_primeCurve,7L

#define OBJ_X9_62_id_ecSigType          OBJ_ansi_X9_62,4L

#define SN_ecdsa_with_SHA1              "ecdsa-with-SHA1"
#define NID_ecdsa_with_SHA1             416
#define OBJ_ecdsa_with_SHA1             OBJ_X9_62_id_ecSigType,1L

#define SN_ecdsa_with_Recommended               "ecdsa-with-Recommended"
#define NID_ecdsa_with_Recommended              791
#define OBJ_ecdsa_with_Recommended              OBJ_X9_62_id_ecSigType,2L

#define SN_ecdsa_with_Specified         "ecdsa-with-Specified"
#define NID_ecdsa_with_Specified                792
#define OBJ_ecdsa_with_Specified                OBJ_X9_62_id_ecSigType,3L

#define SN_ecdsa_with_SHA224            "ecdsa-with-SHA224"
#define NID_ecdsa_with_SHA224           793
#define OBJ_ecdsa_with_SHA224           OBJ_ecdsa_with_Specified,1L

#define SN_ecdsa_with_SHA256            "ecdsa-with-SHA256"
#define NID_ecdsa_with_SHA256           794
#define OBJ_ecdsa_with_SHA256           OBJ_ecdsa_with_Specified,2L

#define SN_ecdsa_with_SHA384            "ecdsa-with-SHA384"
#define NID_ecdsa_with_SHA384           795
#define OBJ_ecdsa_with_SHA384           OBJ_ecdsa_with_Specified,3L

#define SN_ecdsa_with_SHA512            "ecdsa-with-SHA512"
#define NID_ecdsa_with_SHA512           796
#define OBJ_ecdsa_with_SHA512           OBJ_ecdsa_with_Specified,4L

#define OBJ_secg_ellipticCurve          OBJ_certicom_arc,0L

#define SN_secp112r1            "secp112r1"
#define NID_secp112r1           704
#define OBJ_secp112r1           OBJ_secg_ellipticCurve,6L

#define SN_secp112r2            "secp112r2"
#define NID_secp112r2           705
#define OBJ_secp112r2           OBJ_secg_ellipticCurve,7L

#define SN_secp128r1            "secp128r1"
#define NID_secp128r1           706
#define OBJ_secp128r1           OBJ_secg_ellipticCurve,28L

#define SN_secp128r2            "secp128r2"
#define NID_secp128r2           707
#define OBJ_secp128r2           OBJ_secg_ellipticCurve,29L

#define SN_secp160k1            "secp160k1"
#define NID_secp160k1           708
#define OBJ_secp160k1           OBJ_secg_ellipticCurve,9L

#define SN_secp160r1            "secp160r1"
#define NID_secp160r1           709
#define OBJ_secp160r1           OBJ_secg_ellipticCurve,8L

#define SN_secp160r2            "secp160r2"
#define NID_secp160r2           710
#define OBJ_secp160r2           OBJ_secg_ellipticCurve,30L

#define SN_secp192k1            "secp192k1"
#define NID_secp192k1           711
#define OBJ_secp192k1           OBJ_secg_ellipticCurve,31L

#define SN_secp224k1            "secp224k1"
#define NID_secp224k1           712
#define OBJ_secp224k1           OBJ_secg_ellipticCurve,32L

#define SN_secp224r1            "secp224r1"
#define NID_secp224r1           713
#define OBJ_secp224r1           OBJ_secg_ellipticCurve,33L

#define SN_secp256k1            "secp256k1"
#define NID_secp256k1           714
#define OBJ_secp256k1           OBJ_secg_ellipticCurve,10L

#define SN_secp384r1            "secp384r1"
#define NID_secp384r1           715
#define OBJ_secp384r1           OBJ_secg_ellipticCurve,34L

#define SN_secp521r1            "secp521r1"
#define NID_secp521r1           716
#define OBJ_secp521r1           OBJ_secg_ellipticCurve,35L

#define SN_sect113r1            "sect113r1"
#define NID_sect113r1           717
#define OBJ_sect113r1           OBJ_secg_ellipticCurve,4L

#define SN_sect113r2            "sect113r2"
#define NID_sect113r2           718
#define OBJ_sect113r2           OBJ_secg_ellipticCurve,5L

#define SN_sect131r1            "sect131r1"
#define NID_sect131r1           719
#define OBJ_sect131r1           OBJ_secg_ellipticCurve,22L

#define SN_sect131r2            "sect131r2"
#define NID_sect131r2           720
#define OBJ_sect131r2           OBJ_secg_ellipticCurve,23L

#define SN_sect163k1            "sect163k1"
#define NID_sect163k1           721
#define OBJ_sect163k1           OBJ_secg_ellipticCurve,1L

#define SN_sect163r1            "sect163r1"
#define NID_sect163r1           722
#define OBJ_sect163r1           OBJ_secg_ellipticCurve,2L

#define SN_sect163r2            "sect163r2"
#define NID_sect163r2           723
#define OBJ_sect163r2           OBJ_secg_ellipticCurve,15L

#define SN_sect193r1            "sect193r1"
#define NID_sect193r1           724
#define OBJ_sect193r1           OBJ_secg_ellipticCurve,24L

#define SN_sect193r2            "sect193r2"
#define NID_sect193r2           725
#define OBJ_sect193r2           OBJ_secg_ellipticCurve,25L

#define SN_sect233k1            "sect233k1"
#define NID_sect233k1           726
#define OBJ_sect233k1           OBJ_secg_ellipticCurve,26L

#define SN_sect233r1            "sect233r1"
#define NID_sect233r1           727
#define OBJ_sect233r1           OBJ_secg_ellipticCurve,27L

#define SN_sect239k1            "sect239k1"
#define NID_sect239k1           728
#define OBJ_sect239k1           OBJ_secg_ellipticCurve,3L

#define SN_sect283k1            "sect283k1"
#define NID_sect283k1           729
#define OBJ_sect283k1           OBJ_secg_ellipticCurve,16L

#define SN_sect283r1            "sect283r1"
#define NID_sect283r1           730
#define OBJ_sect283r1           OBJ_secg_ellipticCurve,17L

#define SN_sect409k1            "sect409k1"
#define NID_sect409k1           731
#define OBJ_sect409k1           OBJ_secg_ellipticCurve,36L

#define SN_sect409r1            "sect409r1"
#define NID_sect409r1           732
#define OBJ_sect409r1           OBJ_secg_ellipticCurve,37L

#define SN_sect571k1            "sect571k1"
#define NID_sect571k1           733
#define OBJ_sect571k1           OBJ_secg_ellipticCurve,38L

#define SN_sect571r1            "sect571r1"
#define NID_sect571r1           734
#define OBJ_sect571r1           OBJ_secg_ellipticCurve,39L

#define OBJ_wap_wsg_idm_ecid            OBJ_wap_wsg,4L

#define SN_wap_wsg_idm_ecid_wtls1               "wap-wsg-idm-ecid-wtls1"
#define NID_wap_wsg_idm_ecid_wtls1              735
#define OBJ_wap_wsg_idm_ecid_wtls1              OBJ_wap_wsg_idm_ecid,1L

#define SN_wap_wsg_idm_ecid_wtls3               "wap-wsg-idm-ecid-wtls3"
#define NID_wap_wsg_idm_ecid_wtls3              736
#define OBJ_wap_wsg_idm_ecid_wtls3              OBJ_wap_wsg_idm_ecid,3L

#define SN_wap_wsg_idm_ecid_wtls4               "wap-wsg-idm-ecid-wtls4"
#define NID_wap_wsg_idm_ecid_wtls4              737
#define OBJ_wap_wsg_idm_ecid_wtls4              OBJ_wap_wsg_idm_ecid,4L

#define SN_wap_wsg_idm_ecid_wtls5               "wap-wsg-idm-ecid-wtls5"
#define NID_wap_wsg_idm_ecid_wtls5              738
#define OBJ_wap_wsg_idm_ecid_wtls5              OBJ_wap_wsg_idm_ecid,5L

#define SN_wap_wsg_idm_ecid_wtls6               "wap-wsg-idm-ecid-wtls6"
#define NID_wap_wsg_idm_ecid_wtls6              739
#define OBJ_wap_wsg_idm_ecid_wtls6              OBJ_wap_wsg_idm_ecid,6L

#define SN_wap_wsg_idm_ecid_wtls7               "wap-wsg-idm-ecid-wtls7"
#define NID_wap_wsg_idm_ecid_wtls7              740
#define OBJ_wap_wsg_idm_ecid_wtls7              OBJ_wap_wsg_idm_ecid,7L

#define SN_wap_wsg_idm_ecid_wtls8               "wap-wsg-idm-ecid-wtls8"
#define NID_wap_wsg_idm_ecid_wtls8              741
#define OBJ_wap_wsg_idm_ecid_wtls8              OBJ_wap_wsg_idm_ecid,8L

#define SN_wap_wsg_idm_ecid_wtls9               "wap-wsg-idm-ecid-wtls9"
#define NID_wap_wsg_idm_ecid_wtls9              742
#define OBJ_wap_wsg_idm_ecid_wtls9              OBJ_wap_wsg_idm_ecid,9L

#define SN_wap_wsg_idm_ecid_wtls10              "wap-wsg-idm-ecid-wtls10"
#define NID_wap_wsg_idm_ecid_wtls10             743
#define OBJ_wap_wsg_idm_ecid_wtls10             OBJ_wap_wsg_idm_ecid,10L

#define SN_wap_wsg_idm_ecid_wtls11              "wap-wsg-idm-ecid-wtls11"
#define NID_wap_wsg_idm_ecid_wtls11             744
#define OBJ_wap_wsg_idm_ecid_wtls11             OBJ_wap_wsg_idm_ecid,11L

#define SN_wap_wsg_idm_ecid_wtls12              "wap-wsg-idm-ecid-wtls12"
#define NID_wap_wsg_idm_ecid_wtls12             745
#define OBJ_wap_wsg_idm_ecid_wtls12             OBJ_wap_wsg_idm_ecid,12L

#define SN_cast5_cbc            "CAST5-CBC"
#define LN_cast5_cbc            "cast5-cbc"
#define NID_cast5_cbc           108
#define OBJ_cast5_cbc           OBJ_ISO_US,113533L,7L,66L,10L

#define SN_cast5_ecb            "CAST5-ECB"
#define LN_cast5_ecb            "cast5-ecb"
#define NID_cast5_ecb           109

#define SN_cast5_cfb64          "CAST5-CFB"
#define LN_cast5_cfb64          "cast5-cfb"
#define NID_cast5_cfb64         110

#define SN_cast5_ofb64          "CAST5-OFB"
#define LN_cast5_ofb64          "cast5-ofb"
#define NID_cast5_ofb64         111

#define LN_pbeWithMD5AndCast5_CBC               "pbeWithMD5AndCast5CBC"
#define NID_pbeWithMD5AndCast5_CBC              112
#define OBJ_pbeWithMD5AndCast5_CBC              OBJ_ISO_US,113533L,7L,66L,12L

#define SN_id_PasswordBasedMAC          "id-PasswordBasedMAC"
#define LN_id_PasswordBasedMAC          "password based MAC"
#define NID_id_PasswordBasedMAC         782
#define OBJ_id_PasswordBasedMAC         OBJ_ISO_US,113533L,7L,66L,13L

#define SN_id_DHBasedMac                "id-DHBasedMac"
#define LN_id_DHBasedMac                "Diffie-Hellman based MAC"
#define NID_id_DHBasedMac               783
#define OBJ_id_DHBasedMac               OBJ_ISO_US,113533L,7L,66L,30L

#define SN_rsadsi               "rsadsi"
#define LN_rsadsi               "RSA Data Security, Inc."
#define NID_rsadsi              1
#define OBJ_rsadsi              OBJ_ISO_US,113549L

#define SN_pkcs         "pkcs"
#define LN_pkcs         "RSA Data Security, Inc. PKCS"
#define NID_pkcs                2
#define OBJ_pkcs                OBJ_rsadsi,1L

#define SN_pkcs1                "pkcs1"
#define NID_pkcs1               186
#define OBJ_pkcs1               OBJ_pkcs,1L

#define LN_rsaEncryption                "rsaEncryption"
#define NID_rsaEncryption               6
#define OBJ_rsaEncryption               OBJ_pkcs1,1L

#define SN_md2WithRSAEncryption         "RSA-MD2"
#define LN_md2WithRSAEncryption         "md2WithRSAEncryption"
#define NID_md2WithRSAEncryption                7
#define OBJ_md2WithRSAEncryption                OBJ_pkcs1,2L

#define SN_md4WithRSAEncryption         "RSA-MD4"
#define LN_md4WithRSAEncryption         "md4WithRSAEncryption"
#define NID_md4WithRSAEncryption                396
#define OBJ_md4WithRSAEncryption                OBJ_pkcs1,3L

#define SN_md5WithRSAEncryption         "RSA-MD5"
#define LN_md5WithRSAEncryption         "md5WithRSAEncryption"
#define NID_md5WithRSAEncryption                8
#define OBJ_md5WithRSAEncryption                OBJ_pkcs1,4L

#define SN_sha1WithRSAEncryption                "RSA-SHA1"
#define LN_sha1WithRSAEncryption                "sha1WithRSAEncryption"
#define NID_sha1WithRSAEncryption               65
#define OBJ_sha1WithRSAEncryption               OBJ_pkcs1,5L

#define SN_rsaesOaep            "RSAES-OAEP"
#define LN_rsaesOaep            "rsaesOaep"
#define NID_rsaesOaep           919
#define OBJ_rsaesOaep           OBJ_pkcs1,7L

#define SN_mgf1         "MGF1"
#define LN_mgf1         "mgf1"
#define NID_mgf1                911
#define OBJ_mgf1                OBJ_pkcs1,8L

#define SN_pSpecified           "PSPECIFIED"
#define LN_pSpecified           "pSpecified"
#define NID_pSpecified          935
#define OBJ_pSpecified          OBJ_pkcs1,9L

#define SN_rsassaPss            "RSASSA-PSS"
#define LN_rsassaPss            "rsassaPss"
#define NID_rsassaPss           912
#define OBJ_rsassaPss           OBJ_pkcs1,10L

#define SN_sha256WithRSAEncryption              "RSA-SHA256"
#define LN_sha256WithRSAEncryption              "sha256WithRSAEncryption"
#define NID_sha256WithRSAEncryption             668
#define OBJ_sha256WithRSAEncryption             OBJ_pkcs1,11L

#define SN_sha384WithRSAEncryption              "RSA-SHA384"
#define LN_sha384WithRSAEncryption              "sha384WithRSAEncryption"
#define NID_sha384WithRSAEncryption             669
#define OBJ_sha384WithRSAEncryption             OBJ_pkcs1,12L

#define SN_sha512WithRSAEncryption              "RSA-SHA512"
#define LN_sha512WithRSAEncryption              "sha512WithRSAEncryption"
#define NID_sha512WithRSAEncryption             670
#define OBJ_sha512WithRSAEncryption             OBJ_pkcs1,13L

#define SN_sha224WithRSAEncryption              "RSA-SHA224"
#define LN_sha224WithRSAEncryption              "sha224WithRSAEncryption"
#define NID_sha224WithRSAEncryption             671
#define OBJ_sha224WithRSAEncryption             OBJ_pkcs1,14L

#define SN_pkcs3                "pkcs3"
#define NID_pkcs3               27
#define OBJ_pkcs3               OBJ_pkcs,3L

#define LN_dhKeyAgreement               "dhKeyAgreement"
#define NID_dhKeyAgreement              28
#define OBJ_dhKeyAgreement              OBJ_pkcs3,1L

#define SN_pkcs5                "pkcs5"
#define NID_pkcs5               187
#define OBJ_pkcs5               OBJ_pkcs,5L

#define SN_pbeWithMD2AndDES_CBC         "PBE-MD2-DES"
#define LN_pbeWithMD2AndDES_CBC         "pbeWithMD2AndDES-CBC"
#define NID_pbeWithMD2AndDES_CBC                9
#define OBJ_pbeWithMD2AndDES_CBC                OBJ_pkcs5,1L

#define SN_pbeWithMD5AndDES_CBC         "PBE-MD5-DES"
#define LN_pbeWithMD5AndDES_CBC         "pbeWithMD5AndDES-CBC"
#define NID_pbeWithMD5AndDES_CBC                10
#define OBJ_pbeWithMD5AndDES_CBC                OBJ_pkcs5,3L

#define SN_pbeWithMD2AndRC2_CBC         "PBE-MD2-RC2-64"
#define LN_pbeWithMD2AndRC2_CBC         "pbeWithMD2AndRC2-CBC"
#define NID_pbeWithMD2AndRC2_CBC                168
#define OBJ_pbeWithMD2AndRC2_CBC                OBJ_pkcs5,4L

#define SN_pbeWithMD5AndRC2_CBC         "PBE-MD5-RC2-64"
#define LN_pbeWithMD5AndRC2_CBC         "pbeWithMD5AndRC2-CBC"
#define NID_pbeWithMD5AndRC2_CBC                169
#define OBJ_pbeWithMD5AndRC2_CBC                OBJ_pkcs5,6L

#define SN_pbeWithSHA1AndDES_CBC                "PBE-SHA1-DES"
#define LN_pbeWithSHA1AndDES_CBC                "pbeWithSHA1AndDES-CBC"
#define NID_pbeWithSHA1AndDES_CBC               170
#define OBJ_pbeWithSHA1AndDES_CBC               OBJ_pkcs5,10L

#define SN_pbeWithSHA1AndRC2_CBC                "PBE-SHA1-RC2-64"
#define LN_pbeWithSHA1AndRC2_CBC                "pbeWithSHA1AndRC2-CBC"
#define NID_pbeWithSHA1AndRC2_CBC               68
#define OBJ_pbeWithSHA1AndRC2_CBC               OBJ_pkcs5,11L

#define LN_id_pbkdf2            "PBKDF2"
#define NID_id_pbkdf2           69
#define OBJ_id_pbkdf2           OBJ_pkcs5,12L

#define LN_pbes2                "PBES2"
#define NID_pbes2               161
#define OBJ_pbes2               OBJ_pkcs5,13L

#define LN_pbmac1               "PBMAC1"
#define NID_pbmac1              162
#define OBJ_pbmac1              OBJ_pkcs5,14L

#define SN_pkcs7                "pkcs7"
#define NID_pkcs7               20
#define OBJ_pkcs7               OBJ_pkcs,7L

#define LN_pkcs7_data           "pkcs7-data"
#define NID_pkcs7_data          21
#define OBJ_pkcs7_data          OBJ_pkcs7,1L

#define LN_pkcs7_signed         "pkcs7-signedData"
#define NID_pkcs7_signed                22
#define OBJ_pkcs7_signed                OBJ_pkcs7,2L

#define LN_pkcs7_enveloped              "pkcs7-envelopedData"
#define NID_pkcs7_enveloped             23
#define OBJ_pkcs7_enveloped             OBJ_pkcs7,3L

#define LN_pkcs7_signedAndEnveloped             "pkcs7-signedAndEnvelopedData"
#define NID_pkcs7_signedAndEnveloped            24
#define OBJ_pkcs7_signedAndEnveloped            OBJ_pkcs7,4L

#define LN_pkcs7_digest         "pkcs7-digestData"
#define NID_pkcs7_digest                25
#define OBJ_pkcs7_digest                OBJ_pkcs7,5L

#define LN_pkcs7_encrypted              "pkcs7-encryptedData"
#define NID_pkcs7_encrypted             26
#define OBJ_pkcs7_encrypted             OBJ_pkcs7,6L

#define SN_pkcs9                "pkcs9"
#define NID_pkcs9               47
#define OBJ_pkcs9               OBJ_pkcs,9L

#define LN_pkcs9_emailAddress           "emailAddress"
#define NID_pkcs9_emailAddress          48
#define OBJ_pkcs9_emailAddress          OBJ_pkcs9,1L

#define LN_pkcs9_unstructuredName               "unstructuredName"
#define NID_pkcs9_unstructuredName              49
#define OBJ_pkcs9_unstructuredName              OBJ_pkcs9,2L

#define LN_pkcs9_contentType            "contentType"
#define NID_pkcs9_contentType           50
#define OBJ_pkcs9_contentType           OBJ_pkcs9,3L

#define LN_pkcs9_messageDigest          "messageDigest"
#define NID_pkcs9_messageDigest         51
#define OBJ_pkcs9_messageDigest         OBJ_pkcs9,4L

#define LN_pkcs9_signingTime            "signingTime"
#define NID_pkcs9_signingTime           52
#define OBJ_pkcs9_signingTime           OBJ_pkcs9,5L

#define LN_pkcs9_countersignature               "countersignature"
#define NID_pkcs9_countersignature              53
#define OBJ_pkcs9_countersignature              OBJ_pkcs9,6L

#define LN_pkcs9_challengePassword              "challengePassword"
#define NID_pkcs9_challengePassword             54
#define OBJ_pkcs9_challengePassword             OBJ_pkcs9,7L

#define LN_pkcs9_unstructuredAddress            "unstructuredAddress"
#define NID_pkcs9_unstructuredAddress           55
#define OBJ_pkcs9_unstructuredAddress           OBJ_pkcs9,8L

#define LN_pkcs9_extCertAttributes              "extendedCertificateAttributes"
#define NID_pkcs9_extCertAttributes             56
#define OBJ_pkcs9_extCertAttributes             OBJ_pkcs9,9L

#define SN_ext_req              "extReq"
#define LN_ext_req              "Extension Request"
#define NID_ext_req             172
#define OBJ_ext_req             OBJ_pkcs9,14L

#define SN_SMIMECapabilities            "SMIME-CAPS"
#define LN_SMIMECapabilities            "S/MIME Capabilities"
#define NID_SMIMECapabilities           167
#define OBJ_SMIMECapabilities           OBJ_pkcs9,15L

#define SN_SMIME                "SMIME"
#define LN_SMIME                "S/MIME"
#define NID_SMIME               188
#define OBJ_SMIME               OBJ_pkcs9,16L

#define SN_id_smime_mod         "id-smime-mod"
#define NID_id_smime_mod                189
#define OBJ_id_smime_mod                OBJ_SMIME,0L

#define SN_id_smime_ct          "id-smime-ct"
#define NID_id_smime_ct         190
#define OBJ_id_smime_ct         OBJ_SMIME,1L

#define SN_id_smime_aa          "id-smime-aa"
#define NID_id_smime_aa         191
#define OBJ_id_smime_aa         OBJ_SMIME,2L

#define SN_id_smime_alg         "id-smime-alg"
#define NID_id_smime_alg                192
#define OBJ_id_smime_alg                OBJ_SMIME,3L

#define SN_id_smime_cd          "id-smime-cd"
#define NID_id_smime_cd         193
#define OBJ_id_smime_cd         OBJ_SMIME,4L

#define SN_id_smime_spq         "id-smime-spq"
#define NID_id_smime_spq                194
#define OBJ_id_smime_spq                OBJ_SMIME,5L

#define SN_id_smime_cti         "id-smime-cti"
#define NID_id_smime_cti                195
#define OBJ_id_smime_cti                OBJ_SMIME,6L

#define SN_id_smime_mod_cms             "id-smime-mod-cms"
#define NID_id_smime_mod_cms            196
#define OBJ_id_smime_mod_cms            OBJ_id_smime_mod,1L

#define SN_id_smime_mod_ess             "id-smime-mod-ess"
#define NID_id_smime_mod_ess            197
#define OBJ_id_smime_mod_ess            OBJ_id_smime_mod,2L

#define SN_id_smime_mod_oid             "id-smime-mod-oid"
#define NID_id_smime_mod_oid            198
#define OBJ_id_smime_mod_oid            OBJ_id_smime_mod,3L

#define SN_id_smime_mod_msg_v3          "id-smime-mod-msg-v3"
#define NID_id_smime_mod_msg_v3         199
#define OBJ_id_smime_mod_msg_v3         OBJ_id_smime_mod,4L

#define SN_id_smime_mod_ets_eSignature_88               "id-smime-mod-ets-eSignature-88"
#define NID_id_smime_mod_ets_eSignature_88              200
#define OBJ_id_smime_mod_ets_eSignature_88              OBJ_id_smime_mod,5L

#define SN_id_smime_mod_ets_eSignature_97               "id-smime-mod-ets-eSignature-97"
#define NID_id_smime_mod_ets_eSignature_97              201
#define OBJ_id_smime_mod_ets_eSignature_97              OBJ_id_smime_mod,6L

#define SN_id_smime_mod_ets_eSigPolicy_88               "id-smime-mod-ets-eSigPolicy-88"
#define NID_id_smime_mod_ets_eSigPolicy_88              202
#define OBJ_id_smime_mod_ets_eSigPolicy_88              OBJ_id_smime_mod,7L

#define SN_id_smime_mod_ets_eSigPolicy_97               "id-smime-mod-ets-eSigPolicy-97"
#define NID_id_smime_mod_ets_eSigPolicy_97              203
#define OBJ_id_smime_mod_ets_eSigPolicy_97              OBJ_id_smime_mod,8L

#define SN_id_smime_ct_receipt          "id-smime-ct-receipt"
#define NID_id_smime_ct_receipt         204
#define OBJ_id_smime_ct_receipt         OBJ_id_smime_ct,1L

#define SN_id_smime_ct_authData         "id-smime-ct-authData"
#define NID_id_smime_ct_authData                205
#define OBJ_id_smime_ct_authData                OBJ_id_smime_ct,2L

#define SN_id_smime_ct_publishCert              "id-smime-ct-publishCert"
#define NID_id_smime_ct_publishCert             206
#define OBJ_id_smime_ct_publishCert             OBJ_id_smime_ct,3L

#define SN_id_smime_ct_TSTInfo          "id-smime-ct-TSTInfo"
#define NID_id_smime_ct_TSTInfo         207
#define OBJ_id_smime_ct_TSTInfo         OBJ_id_smime_ct,4L

#define SN_id_smime_ct_TDTInfo          "id-smime-ct-TDTInfo"
#define NID_id_smime_ct_TDTInfo         208
#define OBJ_id_smime_ct_TDTInfo         OBJ_id_smime_ct,5L

#define SN_id_smime_ct_contentInfo              "id-smime-ct-contentInfo"
#define NID_id_smime_ct_contentInfo             209
#define OBJ_id_smime_ct_contentInfo             OBJ_id_smime_ct,6L

#define SN_id_smime_ct_DVCSRequestData          "id-smime-ct-DVCSRequestData"
#define NID_id_smime_ct_DVCSRequestData         210
#define OBJ_id_smime_ct_DVCSRequestData         OBJ_id_smime_ct,7L

#define SN_id_smime_ct_DVCSResponseData         "id-smime-ct-DVCSResponseData"
#define NID_id_smime_ct_DVCSResponseData                211
#define OBJ_id_smime_ct_DVCSResponseData                OBJ_id_smime_ct,8L

#define SN_id_smime_ct_compressedData           "id-smime-ct-compressedData"
#define NID_id_smime_ct_compressedData          786
#define OBJ_id_smime_ct_compressedData          OBJ_id_smime_ct,9L

#define SN_id_ct_asciiTextWithCRLF              "id-ct-asciiTextWithCRLF"
#define NID_id_ct_asciiTextWithCRLF             787
#define OBJ_id_ct_asciiTextWithCRLF             OBJ_id_smime_ct,27L

#define SN_id_smime_aa_receiptRequest           "id-smime-aa-receiptRequest"
#define NID_id_smime_aa_receiptRequest          212
#define OBJ_id_smime_aa_receiptRequest          OBJ_id_smime_aa,1L

#define SN_id_smime_aa_securityLabel            "id-smime-aa-securityLabel"
#define NID_id_smime_aa_securityLabel           213
#define OBJ_id_smime_aa_securityLabel           OBJ_id_smime_aa,2L

#define SN_id_smime_aa_mlExpandHistory          "id-smime-aa-mlExpandHistory"
#define NID_id_smime_aa_mlExpandHistory         214
#define OBJ_id_smime_aa_mlExpandHistory         OBJ_id_smime_aa,3L

#define SN_id_smime_aa_contentHint              "id-smime-aa-contentHint"
#define NID_id_smime_aa_contentHint             215
#define OBJ_id_smime_aa_contentHint             OBJ_id_smime_aa,4L

#define SN_id_smime_aa_msgSigDigest             "id-smime-aa-msgSigDigest"
#define NID_id_smime_aa_msgSigDigest            216
#define OBJ_id_smime_aa_msgSigDigest            OBJ_id_smime_aa,5L

#define SN_id_smime_aa_encapContentType         "id-smime-aa-encapContentType"
#define NID_id_smime_aa_encapContentType                217
#define OBJ_id_smime_aa_encapContentType                OBJ_id_smime_aa,6L

#define SN_id_smime_aa_contentIdentifier                "id-smime-aa-contentIdentifier"
#define NID_id_smime_aa_contentIdentifier               218
#define OBJ_id_smime_aa_contentIdentifier               OBJ_id_smime_aa,7L

#define SN_id_smime_aa_macValue         "id-smime-aa-macValue"
#define NID_id_smime_aa_macValue                219
#define OBJ_id_smime_aa_macValue                OBJ_id_smime_aa,8L

#define SN_id_smime_aa_equivalentLabels         "id-smime-aa-equivalentLabels"
#define NID_id_smime_aa_equivalentLabels                220
#define OBJ_id_smime_aa_equivalentLabels                OBJ_id_smime_aa,9L

#define SN_id_smime_aa_contentReference         "id-smime-aa-contentReference"
#define NID_id_smime_aa_contentReference                221
#define OBJ_id_smime_aa_contentReference                OBJ_id_smime_aa,10L

#define SN_id_smime_aa_encrypKeyPref            "id-smime-aa-encrypKeyPref"
#define NID_id_smime_aa_encrypKeyPref           222
#define OBJ_id_smime_aa_encrypKeyPref           OBJ_id_smime_aa,11L

#define SN_id_smime_aa_signingCertificate               "id-smime-aa-signingCertificate"
#define NID_id_smime_aa_signingCertificate              223
#define OBJ_id_smime_aa_signingCertificate              OBJ_id_smime_aa,12L

#define SN_id_smime_aa_smimeEncryptCerts                "id-smime-aa-smimeEncryptCerts"
#define NID_id_smime_aa_smimeEncryptCerts               224
#define OBJ_id_smime_aa_smimeEncryptCerts               OBJ_id_smime_aa,13L

#define SN_id_smime_aa_timeStampToken           "id-smime-aa-timeStampToken"
#define NID_id_smime_aa_timeStampToken          225
#define OBJ_id_smime_aa_timeStampToken          OBJ_id_smime_aa,14L

#define SN_id_smime_aa_ets_sigPolicyId          "id-smime-aa-ets-sigPolicyId"
#define NID_id_smime_aa_ets_sigPolicyId         226
#define OBJ_id_smime_aa_ets_sigPolicyId         OBJ_id_smime_aa,15L

#define SN_id_smime_aa_ets_commitmentType               "id-smime-aa-ets-commitmentType"
#define NID_id_smime_aa_ets_commitmentType              227
#define OBJ_id_smime_aa_ets_commitmentType              OBJ_id_smime_aa,16L

#define SN_id_smime_aa_ets_signerLocation               "id-smime-aa-ets-signerLocation"
#define NID_id_smime_aa_ets_signerLocation              228
#define OBJ_id_smime_aa_ets_signerLocation              OBJ_id_smime_aa,17L

#define SN_id_smime_aa_ets_signerAttr           "id-smime-aa-ets-signerAttr"
#define NID_id_smime_aa_ets_signerAttr          229
#define OBJ_id_smime_aa_ets_signerAttr          OBJ_id_smime_aa,18L

#define SN_id_smime_aa_ets_otherSigCert         "id-smime-aa-ets-otherSigCert"
#define NID_id_smime_aa_ets_otherSigCert                230
#define OBJ_id_smime_aa_ets_otherSigCert                OBJ_id_smime_aa,19L

#define SN_id_smime_aa_ets_contentTimestamp             "id-smime-aa-ets-contentTimestamp"
#define NID_id_smime_aa_ets_contentTimestamp            231
#define OBJ_id_smime_aa_ets_contentTimestamp            OBJ_id_smime_aa,20L

#define SN_id_smime_aa_ets_CertificateRefs              "id-smime-aa-ets-CertificateRefs"
#define NID_id_smime_aa_ets_CertificateRefs             232
#define OBJ_id_smime_aa_ets_CertificateRefs             OBJ_id_smime_aa,21L

#define SN_id_smime_aa_ets_RevocationRefs               "id-smime-aa-ets-RevocationRefs"
#define NID_id_smime_aa_ets_RevocationRefs              233
#define OBJ_id_smime_aa_ets_RevocationRefs              OBJ_id_smime_aa,22L

#define SN_id_smime_aa_ets_certValues           "id-smime-aa-ets-certValues"
#define NID_id_smime_aa_ets_certValues          234
#define OBJ_id_smime_aa_ets_certValues          OBJ_id_smime_aa,23L

#define SN_id_smime_aa_ets_revocationValues             "id-smime-aa-ets-revocationValues"
#define NID_id_smime_aa_ets_revocationValues            235
#define OBJ_id_smime_aa_ets_revocationValues            OBJ_id_smime_aa,24L

#define SN_id_smime_aa_ets_escTimeStamp         "id-smime-aa-ets-escTimeStamp"
#define NID_id_smime_aa_ets_escTimeStamp                236
#define OBJ_id_smime_aa_ets_escTimeStamp                OBJ_id_smime_aa,25L

#define SN_id_smime_aa_ets_certCRLTimestamp             "id-smime-aa-ets-certCRLTimestamp"
#define NID_id_smime_aa_ets_certCRLTimestamp            237
#define OBJ_id_smime_aa_ets_certCRLTimestamp            OBJ_id_smime_aa,26L

#define SN_id_smime_aa_ets_archiveTimeStamp             "id-smime-aa-ets-archiveTimeStamp"
#define NID_id_smime_aa_ets_archiveTimeStamp            238
#define OBJ_id_smime_aa_ets_archiveTimeStamp            OBJ_id_smime_aa,27L

#define SN_id_smime_aa_signatureType            "id-smime-aa-signatureType"
#define NID_id_smime_aa_signatureType           239
#define OBJ_id_smime_aa_signatureType           OBJ_id_smime_aa,28L

#define SN_id_smime_aa_dvcs_dvc         "id-smime-aa-dvcs-dvc"
#define NID_id_smime_aa_dvcs_dvc                240
#define OBJ_id_smime_aa_dvcs_dvc                OBJ_id_smime_aa,29L

#define SN_id_smime_alg_ESDHwith3DES            "id-smime-alg-ESDHwith3DES"
#define NID_id_smime_alg_ESDHwith3DES           241
#define OBJ_id_smime_alg_ESDHwith3DES           OBJ_id_smime_alg,1L

#define SN_id_smime_alg_ESDHwithRC2             "id-smime-alg-ESDHwithRC2"
#define NID_id_smime_alg_ESDHwithRC2            242
#define OBJ_id_smime_alg_ESDHwithRC2            OBJ_id_smime_alg,2L

#define SN_id_smime_alg_3DESwrap                "id-smime-alg-3DESwrap"
#define NID_id_smime_alg_3DESwrap               243
#define OBJ_id_smime_alg_3DESwrap               OBJ_id_smime_alg,3L

#define SN_id_smime_alg_RC2wrap         "id-smime-alg-RC2wrap"
#define NID_id_smime_alg_RC2wrap                244
#define OBJ_id_smime_alg_RC2wrap                OBJ_id_smime_alg,4L

#define SN_id_smime_alg_ESDH            "id-smime-alg-ESDH"
#define NID_id_smime_alg_ESDH           245
#define OBJ_id_smime_alg_ESDH           OBJ_id_smime_alg,5L

#define SN_id_smime_alg_CMS3DESwrap             "id-smime-alg-CMS3DESwrap"
#define NID_id_smime_alg_CMS3DESwrap            246
#define OBJ_id_smime_alg_CMS3DESwrap            OBJ_id_smime_alg,6L

#define SN_id_smime_alg_CMSRC2wrap              "id-smime-alg-CMSRC2wrap"
#define NID_id_smime_alg_CMSRC2wrap             247
#define OBJ_id_smime_alg_CMSRC2wrap             OBJ_id_smime_alg,7L

#define SN_id_alg_PWRI_KEK              "id-alg-PWRI-KEK"
#define NID_id_alg_PWRI_KEK             893
#define OBJ_id_alg_PWRI_KEK             OBJ_id_smime_alg,9L

#define SN_id_smime_cd_ldap             "id-smime-cd-ldap"
#define NID_id_smime_cd_ldap            248
#define OBJ_id_smime_cd_ldap            OBJ_id_smime_cd,1L

#define SN_id_smime_spq_ets_sqt_uri             "id-smime-spq-ets-sqt-uri"
#define NID_id_smime_spq_ets_sqt_uri            249
#define OBJ_id_smime_spq_ets_sqt_uri            OBJ_id_smime_spq,1L

#define SN_id_smime_spq_ets_sqt_unotice         "id-smime-spq-ets-sqt-unotice"
#define NID_id_smime_spq_ets_sqt_unotice                250
#define OBJ_id_smime_spq_ets_sqt_unotice                OBJ_id_smime_spq,2L

#define SN_id_smime_cti_ets_proofOfOrigin               "id-smime-cti-ets-proofOfOrigin"
#define NID_id_smime_cti_ets_proofOfOrigin              251
#define OBJ_id_smime_cti_ets_proofOfOrigin              OBJ_id_smime_cti,1L

#define SN_id_smime_cti_ets_proofOfReceipt              "id-smime-cti-ets-proofOfReceipt"
#define NID_id_smime_cti_ets_proofOfReceipt             252
#define OBJ_id_smime_cti_ets_proofOfReceipt             OBJ_id_smime_cti,2L

#define SN_id_smime_cti_ets_proofOfDelivery             "id-smime-cti-ets-proofOfDelivery"
#define NID_id_smime_cti_ets_proofOfDelivery            253
#define OBJ_id_smime_cti_ets_proofOfDelivery            OBJ_id_smime_cti,3L

#define SN_id_smime_cti_ets_proofOfSender               "id-smime-cti-ets-proofOfSender"
#define NID_id_smime_cti_ets_proofOfSender              254
#define OBJ_id_smime_cti_ets_proofOfSender              OBJ_id_smime_cti,4L

#define SN_id_smime_cti_ets_proofOfApproval             "id-smime-cti-ets-proofOfApproval"
#define NID_id_smime_cti_ets_proofOfApproval            255
#define OBJ_id_smime_cti_ets_proofOfApproval            OBJ_id_smime_cti,5L

#define SN_id_smime_cti_ets_proofOfCreation             "id-smime-cti-ets-proofOfCreation"
#define NID_id_smime_cti_ets_proofOfCreation            256
#define OBJ_id_smime_cti_ets_proofOfCreation            OBJ_id_smime_cti,6L

#define LN_friendlyName         "friendlyName"
#define NID_friendlyName                156
#define OBJ_friendlyName                OBJ_pkcs9,20L

#define LN_localKeyID           "localKeyID"
#define NID_localKeyID          157
#define OBJ_localKeyID          OBJ_pkcs9,21L

#define SN_ms_csp_name          "CSPName"
#define LN_ms_csp_name          "Microsoft CSP Name"
#define NID_ms_csp_name         417
#define OBJ_ms_csp_name         1L,3L,6L,1L,4L,1L,311L,17L,1L

#define SN_LocalKeySet          "LocalKeySet"
#define LN_LocalKeySet          "Microsoft Local Key set"
#define NID_LocalKeySet         856
#define OBJ_LocalKeySet         1L,3L,6L,1L,4L,1L,311L,17L,2L

#define OBJ_certTypes           OBJ_pkcs9,22L

#define LN_x509Certificate              "x509Certificate"
#define NID_x509Certificate             158
#define OBJ_x509Certificate             OBJ_certTypes,1L

#define LN_sdsiCertificate              "sdsiCertificate"
#define NID_sdsiCertificate             159
#define OBJ_sdsiCertificate             OBJ_certTypes,2L

#define OBJ_crlTypes            OBJ_pkcs9,23L

#define LN_x509Crl              "x509Crl"
#define NID_x509Crl             160
#define OBJ_x509Crl             OBJ_crlTypes,1L

#define OBJ_pkcs12              OBJ_pkcs,12L

#define OBJ_pkcs12_pbeids               OBJ_pkcs12,1L

#define SN_pbe_WithSHA1And128BitRC4             "PBE-SHA1-RC4-128"
#define LN_pbe_WithSHA1And128BitRC4             "pbeWithSHA1And128BitRC4"
#define NID_pbe_WithSHA1And128BitRC4            144
#define OBJ_pbe_WithSHA1And128BitRC4            OBJ_pkcs12_pbeids,1L

#define SN_pbe_WithSHA1And40BitRC4              "PBE-SHA1-RC4-40"
#define LN_pbe_WithSHA1And40BitRC4              "pbeWithSHA1And40BitRC4"
#define NID_pbe_WithSHA1And40BitRC4             145
#define OBJ_pbe_WithSHA1And40BitRC4             OBJ_pkcs12_pbeids,2L

#define SN_pbe_WithSHA1And3_Key_TripleDES_CBC           "PBE-SHA1-3DES"
#define LN_pbe_WithSHA1And3_Key_TripleDES_CBC           "pbeWithSHA1And3-KeyTripleDES-CBC"
#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC          146
#define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC          OBJ_pkcs12_pbeids,3L

#define SN_pbe_WithSHA1And2_Key_TripleDES_CBC           "PBE-SHA1-2DES"
#define LN_pbe_WithSHA1And2_Key_TripleDES_CBC           "pbeWithSHA1And2-KeyTripleDES-CBC"
#define NID_pbe_WithSHA1And2_Key_TripleDES_CBC          147
#define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC          OBJ_pkcs12_pbeids,4L

#define SN_pbe_WithSHA1And128BitRC2_CBC         "PBE-SHA1-RC2-128"
#define LN_pbe_WithSHA1And128BitRC2_CBC         "pbeWithSHA1And128BitRC2-CBC"
#define NID_pbe_WithSHA1And128BitRC2_CBC                148
#define OBJ_pbe_WithSHA1And128BitRC2_CBC                OBJ_pkcs12_pbeids,5L

#define SN_pbe_WithSHA1And40BitRC2_CBC          "PBE-SHA1-RC2-40"
#define LN_pbe_WithSHA1And40BitRC2_CBC          "pbeWithSHA1And40BitRC2-CBC"
#define NID_pbe_WithSHA1And40BitRC2_CBC         149
#define OBJ_pbe_WithSHA1And40BitRC2_CBC         OBJ_pkcs12_pbeids,6L

#define OBJ_pkcs12_Version1             OBJ_pkcs12,10L

#define OBJ_pkcs12_BagIds               OBJ_pkcs12_Version1,1L

#define LN_keyBag               "keyBag"
#define NID_keyBag              150
#define OBJ_keyBag              OBJ_pkcs12_BagIds,1L

#define LN_pkcs8ShroudedKeyBag          "pkcs8ShroudedKeyBag"
#define NID_pkcs8ShroudedKeyBag         151
#define OBJ_pkcs8ShroudedKeyBag         OBJ_pkcs12_BagIds,2L

#define LN_certBag              "certBag"
#define NID_certBag             152
#define OBJ_certBag             OBJ_pkcs12_BagIds,3L

#define LN_crlBag               "crlBag"
#define NID_crlBag              153
#define OBJ_crlBag              OBJ_pkcs12_BagIds,4L

#define LN_secretBag            "secretBag"
#define NID_secretBag           154
#define OBJ_secretBag           OBJ_pkcs12_BagIds,5L

#define LN_safeContentsBag              "safeContentsBag"
#define NID_safeContentsBag             155
#define OBJ_safeContentsBag             OBJ_pkcs12_BagIds,6L

#define SN_md2          "MD2"
#define LN_md2          "md2"
#define NID_md2         3
#define OBJ_md2         OBJ_rsadsi,2L,2L

#define SN_md4          "MD4"
#define LN_md4          "md4"
#define NID_md4         257
#define OBJ_md4         OBJ_rsadsi,2L,4L

#define SN_md5          "MD5"
#define LN_md5          "md5"
#define NID_md5         4
#define OBJ_md5         OBJ_rsadsi,2L,5L

#define SN_md5_sha1             "MD5-SHA1"
#define LN_md5_sha1             "md5-sha1"
#define NID_md5_sha1            114

#define LN_hmacWithMD5          "hmacWithMD5"
#define NID_hmacWithMD5         797
#define OBJ_hmacWithMD5         OBJ_rsadsi,2L,6L

#define LN_hmacWithSHA1         "hmacWithSHA1"
#define NID_hmacWithSHA1                163
#define OBJ_hmacWithSHA1                OBJ_rsadsi,2L,7L

#define LN_hmacWithSHA224               "hmacWithSHA224"
#define NID_hmacWithSHA224              798
#define OBJ_hmacWithSHA224              OBJ_rsadsi,2L,8L

#define LN_hmacWithSHA256               "hmacWithSHA256"
#define NID_hmacWithSHA256              799
#define OBJ_hmacWithSHA256              OBJ_rsadsi,2L,9L

#define LN_hmacWithSHA384               "hmacWithSHA384"
#define NID_hmacWithSHA384              800
#define OBJ_hmacWithSHA384              OBJ_rsadsi,2L,10L

#define LN_hmacWithSHA512               "hmacWithSHA512"
#define NID_hmacWithSHA512              801
#define OBJ_hmacWithSHA512              OBJ_rsadsi,2L,11L

#define SN_rc2_cbc              "RC2-CBC"
#define LN_rc2_cbc              "rc2-cbc"
#define NID_rc2_cbc             37
#define OBJ_rc2_cbc             OBJ_rsadsi,3L,2L

#define SN_rc2_ecb              "RC2-ECB"
#define LN_rc2_ecb              "rc2-ecb"
#define NID_rc2_ecb             38

#define SN_rc2_cfb64            "RC2-CFB"
#define LN_rc2_cfb64            "rc2-cfb"
#define NID_rc2_cfb64           39

#define SN_rc2_ofb64            "RC2-OFB"
#define LN_rc2_ofb64            "rc2-ofb"
#define NID_rc2_ofb64           40

#define SN_rc2_40_cbc           "RC2-40-CBC"
#define LN_rc2_40_cbc           "rc2-40-cbc"
#define NID_rc2_40_cbc          98

#define SN_rc2_64_cbc           "RC2-64-CBC"
#define LN_rc2_64_cbc           "rc2-64-cbc"
#define NID_rc2_64_cbc          166

#define SN_rc4          "RC4"
#define LN_rc4          "rc4"
#define NID_rc4         5
#define OBJ_rc4         OBJ_rsadsi,3L,4L

#define SN_rc4_40               "RC4-40"
#define LN_rc4_40               "rc4-40"
#define NID_rc4_40              97

#define SN_des_ede3_cbc         "DES-EDE3-CBC"
#define LN_des_ede3_cbc         "des-ede3-cbc"
#define NID_des_ede3_cbc                44
#define OBJ_des_ede3_cbc                OBJ_rsadsi,3L,7L

#define SN_rc5_cbc              "RC5-CBC"
#define LN_rc5_cbc              "rc5-cbc"
#define NID_rc5_cbc             120
#define OBJ_rc5_cbc             OBJ_rsadsi,3L,8L

#define SN_rc5_ecb              "RC5-ECB"
#define LN_rc5_ecb              "rc5-ecb"
#define NID_rc5_ecb             121

#define SN_rc5_cfb64            "RC5-CFB"
#define LN_rc5_cfb64            "rc5-cfb"
#define NID_rc5_cfb64           122

#define SN_rc5_ofb64            "RC5-OFB"
#define LN_rc5_ofb64            "rc5-ofb"
#define NID_rc5_ofb64           123

#define SN_ms_ext_req           "msExtReq"
#define LN_ms_ext_req           "Microsoft Extension Request"
#define NID_ms_ext_req          171
#define OBJ_ms_ext_req          1L,3L,6L,1L,4L,1L,311L,2L,1L,14L

#define SN_ms_code_ind          "msCodeInd"
#define LN_ms_code_ind          "Microsoft Individual Code Signing"
#define NID_ms_code_ind         134
#define OBJ_ms_code_ind         1L,3L,6L,1L,4L,1L,311L,2L,1L,21L

#define SN_ms_code_com          "msCodeCom"
#define LN_ms_code_com          "Microsoft Commercial Code Signing"
#define NID_ms_code_com         135
#define OBJ_ms_code_com         1L,3L,6L,1L,4L,1L,311L,2L,1L,22L

#define SN_ms_ctl_sign          "msCTLSign"
#define LN_ms_ctl_sign          "Microsoft Trust List Signing"
#define NID_ms_ctl_sign         136
#define OBJ_ms_ctl_sign         1L,3L,6L,1L,4L,1L,311L,10L,3L,1L

#define SN_ms_sgc               "msSGC"
#define LN_ms_sgc               "Microsoft Server Gated Crypto"
#define NID_ms_sgc              137
#define OBJ_ms_sgc              1L,3L,6L,1L,4L,1L,311L,10L,3L,3L

#define SN_ms_efs               "msEFS"
#define LN_ms_efs               "Microsoft Encrypted File System"
#define NID_ms_efs              138
#define OBJ_ms_efs              1L,3L,6L,1L,4L,1L,311L,10L,3L,4L

#define SN_ms_smartcard_login           "msSmartcardLogin"
#define LN_ms_smartcard_login           "Microsoft Smartcardlogin"
#define NID_ms_smartcard_login          648
#define OBJ_ms_smartcard_login          1L,3L,6L,1L,4L,1L,311L,20L,2L,2L

#define SN_ms_upn               "msUPN"
#define LN_ms_upn               "Microsoft Universal Principal Name"
#define NID_ms_upn              649
#define OBJ_ms_upn              1L,3L,6L,1L,4L,1L,311L,20L,2L,3L

#define SN_idea_cbc             "IDEA-CBC"
#define LN_idea_cbc             "idea-cbc"
#define NID_idea_cbc            34
#define OBJ_idea_cbc            1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L

#define SN_idea_ecb             "IDEA-ECB"
#define LN_idea_ecb             "idea-ecb"
#define NID_idea_ecb            36

#define SN_idea_cfb64           "IDEA-CFB"
#define LN_idea_cfb64           "idea-cfb"
#define NID_idea_cfb64          35

#define SN_idea_ofb64           "IDEA-OFB"
#define LN_idea_ofb64           "idea-ofb"
#define NID_idea_ofb64          46

#define SN_bf_cbc               "BF-CBC"
#define LN_bf_cbc               "bf-cbc"
#define NID_bf_cbc              91
#define OBJ_bf_cbc              1L,3L,6L,1L,4L,1L,3029L,1L,2L

#define SN_bf_ecb               "BF-ECB"
#define LN_bf_ecb               "bf-ecb"
#define NID_bf_ecb              92

#define SN_bf_cfb64             "BF-CFB"
#define LN_bf_cfb64             "bf-cfb"
#define NID_bf_cfb64            93

#define SN_bf_ofb64             "BF-OFB"
#define LN_bf_ofb64             "bf-ofb"
#define NID_bf_ofb64            94

#define SN_id_pkix              "PKIX"
#define NID_id_pkix             127
#define OBJ_id_pkix             1L,3L,6L,1L,5L,5L,7L

#define SN_id_pkix_mod          "id-pkix-mod"
#define NID_id_pkix_mod         258
#define OBJ_id_pkix_mod         OBJ_id_pkix,0L

#define SN_id_pe                "id-pe"
#define NID_id_pe               175
#define OBJ_id_pe               OBJ_id_pkix,1L

#define SN_id_qt                "id-qt"
#define NID_id_qt               259
#define OBJ_id_qt               OBJ_id_pkix,2L

#define SN_id_kp                "id-kp"
#define NID_id_kp               128
#define OBJ_id_kp               OBJ_id_pkix,3L

#define SN_id_it                "id-it"
#define NID_id_it               260
#define OBJ_id_it               OBJ_id_pkix,4L

#define SN_id_pkip              "id-pkip"
#define NID_id_pkip             261
#define OBJ_id_pkip             OBJ_id_pkix,5L

#define SN_id_alg               "id-alg"
#define NID_id_alg              262
#define OBJ_id_alg              OBJ_id_pkix,6L

#define SN_id_cmc               "id-cmc"
#define NID_id_cmc              263
#define OBJ_id_cmc              OBJ_id_pkix,7L

#define SN_id_on                "id-on"
#define NID_id_on               264
#define OBJ_id_on               OBJ_id_pkix,8L

#define SN_id_pda               "id-pda"
#define NID_id_pda              265
#define OBJ_id_pda              OBJ_id_pkix,9L

#define SN_id_aca               "id-aca"
#define NID_id_aca              266
#define OBJ_id_aca              OBJ_id_pkix,10L

#define SN_id_qcs               "id-qcs"
#define NID_id_qcs              267
#define OBJ_id_qcs              OBJ_id_pkix,11L

#define SN_id_cct               "id-cct"
#define NID_id_cct              268
#define OBJ_id_cct              OBJ_id_pkix,12L

#define SN_id_ppl               "id-ppl"
#define NID_id_ppl              662
#define OBJ_id_ppl              OBJ_id_pkix,21L

#define SN_id_ad                "id-ad"
#define NID_id_ad               176
#define OBJ_id_ad               OBJ_id_pkix,48L

#define SN_id_pkix1_explicit_88         "id-pkix1-explicit-88"
#define NID_id_pkix1_explicit_88                269
#define OBJ_id_pkix1_explicit_88                OBJ_id_pkix_mod,1L

#define SN_id_pkix1_implicit_88         "id-pkix1-implicit-88"
#define NID_id_pkix1_implicit_88                270
#define OBJ_id_pkix1_implicit_88                OBJ_id_pkix_mod,2L

#define SN_id_pkix1_explicit_93         "id-pkix1-explicit-93"
#define NID_id_pkix1_explicit_93                271
#define OBJ_id_pkix1_explicit_93                OBJ_id_pkix_mod,3L

#define SN_id_pkix1_implicit_93         "id-pkix1-implicit-93"
#define NID_id_pkix1_implicit_93                272
#define OBJ_id_pkix1_implicit_93                OBJ_id_pkix_mod,4L

#define SN_id_mod_crmf          "id-mod-crmf"
#define NID_id_mod_crmf         273
#define OBJ_id_mod_crmf         OBJ_id_pkix_mod,5L

#define SN_id_mod_cmc           "id-mod-cmc"
#define NID_id_mod_cmc          274
#define OBJ_id_mod_cmc          OBJ_id_pkix_mod,6L

#define SN_id_mod_kea_profile_88                "id-mod-kea-profile-88"
#define NID_id_mod_kea_profile_88               275
#define OBJ_id_mod_kea_profile_88               OBJ_id_pkix_mod,7L

#define SN_id_mod_kea_profile_93                "id-mod-kea-profile-93"
#define NID_id_mod_kea_profile_93               276
#define OBJ_id_mod_kea_profile_93               OBJ_id_pkix_mod,8L

#define SN_id_mod_cmp           "id-mod-cmp"
#define NID_id_mod_cmp          277
#define OBJ_id_mod_cmp          OBJ_id_pkix_mod,9L

#define SN_id_mod_qualified_cert_88             "id-mod-qualified-cert-88"
#define NID_id_mod_qualified_cert_88            278
#define OBJ_id_mod_qualified_cert_88            OBJ_id_pkix_mod,10L

#define SN_id_mod_qualified_cert_93             "id-mod-qualified-cert-93"
#define NID_id_mod_qualified_cert_93            279
#define OBJ_id_mod_qualified_cert_93            OBJ_id_pkix_mod,11L

#define SN_id_mod_attribute_cert                "id-mod-attribute-cert"
#define NID_id_mod_attribute_cert               280
#define OBJ_id_mod_attribute_cert               OBJ_id_pkix_mod,12L

#define SN_id_mod_timestamp_protocol            "id-mod-timestamp-protocol"
#define NID_id_mod_timestamp_protocol           281
#define OBJ_id_mod_timestamp_protocol           OBJ_id_pkix_mod,13L

#define SN_id_mod_ocsp          "id-mod-ocsp"
#define NID_id_mod_ocsp         282
#define OBJ_id_mod_ocsp         OBJ_id_pkix_mod,14L

#define SN_id_mod_dvcs          "id-mod-dvcs"
#define NID_id_mod_dvcs         283
#define OBJ_id_mod_dvcs         OBJ_id_pkix_mod,15L

#define SN_id_mod_cmp2000               "id-mod-cmp2000"
#define NID_id_mod_cmp2000              284
#define OBJ_id_mod_cmp2000              OBJ_id_pkix_mod,16L

#define SN_info_access          "authorityInfoAccess"
#define LN_info_access          "Authority Information Access"
#define NID_info_access         177
#define OBJ_info_access         OBJ_id_pe,1L

#define SN_biometricInfo                "biometricInfo"
#define LN_biometricInfo                "Biometric Info"
#define NID_biometricInfo               285
#define OBJ_biometricInfo               OBJ_id_pe,2L

#define SN_qcStatements         "qcStatements"
#define NID_qcStatements                286
#define OBJ_qcStatements                OBJ_id_pe,3L

#define SN_ac_auditEntity               "ac-auditEntity"
#define NID_ac_auditEntity              287
#define OBJ_ac_auditEntity              OBJ_id_pe,4L

#define SN_ac_targeting         "ac-targeting"
#define NID_ac_targeting                288
#define OBJ_ac_targeting                OBJ_id_pe,5L

#define SN_aaControls           "aaControls"
#define NID_aaControls          289
#define OBJ_aaControls          OBJ_id_pe,6L

#define SN_sbgp_ipAddrBlock             "sbgp-ipAddrBlock"
#define NID_sbgp_ipAddrBlock            290
#define OBJ_sbgp_ipAddrBlock            OBJ_id_pe,7L

#define SN_sbgp_autonomousSysNum                "sbgp-autonomousSysNum"
#define NID_sbgp_autonomousSysNum               291
#define OBJ_sbgp_autonomousSysNum               OBJ_id_pe,8L

#define SN_sbgp_routerIdentifier                "sbgp-routerIdentifier"
#define NID_sbgp_routerIdentifier               292
#define OBJ_sbgp_routerIdentifier               OBJ_id_pe,9L

#define SN_ac_proxying          "ac-proxying"
#define NID_ac_proxying         397
#define OBJ_ac_proxying         OBJ_id_pe,10L

#define SN_sinfo_access         "subjectInfoAccess"
#define LN_sinfo_access         "Subject Information Access"
#define NID_sinfo_access                398
#define OBJ_sinfo_access                OBJ_id_pe,11L

#define SN_proxyCertInfo                "proxyCertInfo"
#define LN_proxyCertInfo                "Proxy Certificate Information"
#define NID_proxyCertInfo               663
#define OBJ_proxyCertInfo               OBJ_id_pe,14L

#define SN_id_qt_cps            "id-qt-cps"
#define LN_id_qt_cps            "Policy Qualifier CPS"
#define NID_id_qt_cps           164
#define OBJ_id_qt_cps           OBJ_id_qt,1L

#define SN_id_qt_unotice                "id-qt-unotice"
#define LN_id_qt_unotice                "Policy Qualifier User Notice"
#define NID_id_qt_unotice               165
#define OBJ_id_qt_unotice               OBJ_id_qt,2L

#define SN_textNotice           "textNotice"
#define NID_textNotice          293
#define OBJ_textNotice          OBJ_id_qt,3L

#define SN_server_auth          "serverAuth"
#define LN_server_auth          "TLS Web Server Authentication"
#define NID_server_auth         129
#define OBJ_server_auth         OBJ_id_kp,1L

#define SN_client_auth          "clientAuth"
#define LN_client_auth          "TLS Web Client Authentication"
#define NID_client_auth         130
#define OBJ_client_auth         OBJ_id_kp,2L

#define SN_code_sign            "codeSigning"
#define LN_code_sign            "Code Signing"
#define NID_code_sign           131
#define OBJ_code_sign           OBJ_id_kp,3L

#define SN_email_protect                "emailProtection"
#define LN_email_protect                "E-mail Protection"
#define NID_email_protect               132
#define OBJ_email_protect               OBJ_id_kp,4L

#define SN_ipsecEndSystem               "ipsecEndSystem"
#define LN_ipsecEndSystem               "IPSec End System"
#define NID_ipsecEndSystem              294
#define OBJ_ipsecEndSystem              OBJ_id_kp,5L

#define SN_ipsecTunnel          "ipsecTunnel"
#define LN_ipsecTunnel          "IPSec Tunnel"
#define NID_ipsecTunnel         295
#define OBJ_ipsecTunnel         OBJ_id_kp,6L

#define SN_ipsecUser            "ipsecUser"
#define LN_ipsecUser            "IPSec User"
#define NID_ipsecUser           296
#define OBJ_ipsecUser           OBJ_id_kp,7L

#define SN_time_stamp           "timeStamping"
#define LN_time_stamp           "Time Stamping"
#define NID_time_stamp          133
#define OBJ_time_stamp          OBJ_id_kp,8L

#define SN_OCSP_sign            "OCSPSigning"
#define LN_OCSP_sign            "OCSP Signing"
#define NID_OCSP_sign           180
#define OBJ_OCSP_sign           OBJ_id_kp,9L

#define SN_dvcs         "DVCS"
#define LN_dvcs         "dvcs"
#define NID_dvcs                297
#define OBJ_dvcs                OBJ_id_kp,10L

#define SN_id_it_caProtEncCert          "id-it-caProtEncCert"
#define NID_id_it_caProtEncCert         298
#define OBJ_id_it_caProtEncCert         OBJ_id_it,1L

#define SN_id_it_signKeyPairTypes               "id-it-signKeyPairTypes"
#define NID_id_it_signKeyPairTypes              299
#define OBJ_id_it_signKeyPairTypes              OBJ_id_it,2L

#define SN_id_it_encKeyPairTypes                "id-it-encKeyPairTypes"
#define NID_id_it_encKeyPairTypes               300
#define OBJ_id_it_encKeyPairTypes               OBJ_id_it,3L

#define SN_id_it_preferredSymmAlg               "id-it-preferredSymmAlg"
#define NID_id_it_preferredSymmAlg              301
#define OBJ_id_it_preferredSymmAlg              OBJ_id_it,4L

#define SN_id_it_caKeyUpdateInfo                "id-it-caKeyUpdateInfo"
#define NID_id_it_caKeyUpdateInfo               302
#define OBJ_id_it_caKeyUpdateInfo               OBJ_id_it,5L

#define SN_id_it_currentCRL             "id-it-currentCRL"
#define NID_id_it_currentCRL            303
#define OBJ_id_it_currentCRL            OBJ_id_it,6L

#define SN_id_it_unsupportedOIDs                "id-it-unsupportedOIDs"
#define NID_id_it_unsupportedOIDs               304
#define OBJ_id_it_unsupportedOIDs               OBJ_id_it,7L

#define SN_id_it_subscriptionRequest            "id-it-subscriptionRequest"
#define NID_id_it_subscriptionRequest           305
#define OBJ_id_it_subscriptionRequest           OBJ_id_it,8L

#define SN_id_it_subscriptionResponse           "id-it-subscriptionResponse"
#define NID_id_it_subscriptionResponse          306
#define OBJ_id_it_subscriptionResponse          OBJ_id_it,9L

#define SN_id_it_keyPairParamReq                "id-it-keyPairParamReq"
#define NID_id_it_keyPairParamReq               307
#define OBJ_id_it_keyPairParamReq               OBJ_id_it,10L

#define SN_id_it_keyPairParamRep                "id-it-keyPairParamRep"
#define NID_id_it_keyPairParamRep               308
#define OBJ_id_it_keyPairParamRep               OBJ_id_it,11L

#define SN_id_it_revPassphrase          "id-it-revPassphrase"
#define NID_id_it_revPassphrase         309
#define OBJ_id_it_revPassphrase         OBJ_id_it,12L

#define SN_id_it_implicitConfirm                "id-it-implicitConfirm"
#define NID_id_it_implicitConfirm               310
#define OBJ_id_it_implicitConfirm               OBJ_id_it,13L

#define SN_id_it_confirmWaitTime                "id-it-confirmWaitTime"
#define NID_id_it_confirmWaitTime               311
#define OBJ_id_it_confirmWaitTime               OBJ_id_it,14L

#define SN_id_it_origPKIMessage         "id-it-origPKIMessage"
#define NID_id_it_origPKIMessage                312
#define OBJ_id_it_origPKIMessage                OBJ_id_it,15L

#define SN_id_it_suppLangTags           "id-it-suppLangTags"
#define NID_id_it_suppLangTags          784
#define OBJ_id_it_suppLangTags          OBJ_id_it,16L

#define SN_id_regCtrl           "id-regCtrl"
#define NID_id_regCtrl          313
#define OBJ_id_regCtrl          OBJ_id_pkip,1L

#define SN_id_regInfo           "id-regInfo"
#define NID_id_regInfo          314
#define OBJ_id_regInfo          OBJ_id_pkip,2L

#define SN_id_regCtrl_regToken          "id-regCtrl-regToken"
#define NID_id_regCtrl_regToken         315
#define OBJ_id_regCtrl_regToken         OBJ_id_regCtrl,1L

#define SN_id_regCtrl_authenticator             "id-regCtrl-authenticator"
#define NID_id_regCtrl_authenticator            316
#define OBJ_id_regCtrl_authenticator            OBJ_id_regCtrl,2L

#define SN_id_regCtrl_pkiPublicationInfo                "id-regCtrl-pkiPublicationInfo"
#define NID_id_regCtrl_pkiPublicationInfo               317
#define OBJ_id_regCtrl_pkiPublicationInfo               OBJ_id_regCtrl,3L

#define SN_id_regCtrl_pkiArchiveOptions         "id-regCtrl-pkiArchiveOptions"
#define NID_id_regCtrl_pkiArchiveOptions                318
#define OBJ_id_regCtrl_pkiArchiveOptions                OBJ_id_regCtrl,4L

#define SN_id_regCtrl_oldCertID         "id-regCtrl-oldCertID"
#define NID_id_regCtrl_oldCertID                319
#define OBJ_id_regCtrl_oldCertID                OBJ_id_regCtrl,5L

#define SN_id_regCtrl_protocolEncrKey           "id-regCtrl-protocolEncrKey"
#define NID_id_regCtrl_protocolEncrKey          320
#define OBJ_id_regCtrl_protocolEncrKey          OBJ_id_regCtrl,6L

#define SN_id_regInfo_utf8Pairs         "id-regInfo-utf8Pairs"
#define NID_id_regInfo_utf8Pairs                321
#define OBJ_id_regInfo_utf8Pairs                OBJ_id_regInfo,1L

#define SN_id_regInfo_certReq           "id-regInfo-certReq"
#define NID_id_regInfo_certReq          322
#define OBJ_id_regInfo_certReq          OBJ_id_regInfo,2L

#define SN_id_alg_des40         "id-alg-des40"
#define NID_id_alg_des40                323
#define OBJ_id_alg_des40                OBJ_id_alg,1L

#define SN_id_alg_noSignature           "id-alg-noSignature"
#define NID_id_alg_noSignature          324
#define OBJ_id_alg_noSignature          OBJ_id_alg,2L

#define SN_id_alg_dh_sig_hmac_sha1              "id-alg-dh-sig-hmac-sha1"
#define NID_id_alg_dh_sig_hmac_sha1             325
#define OBJ_id_alg_dh_sig_hmac_sha1             OBJ_id_alg,3L

#define SN_id_alg_dh_pop                "id-alg-dh-pop"
#define NID_id_alg_dh_pop               326
#define OBJ_id_alg_dh_pop               OBJ_id_alg,4L

#define SN_id_cmc_statusInfo            "id-cmc-statusInfo"
#define NID_id_cmc_statusInfo           327
#define OBJ_id_cmc_statusInfo           OBJ_id_cmc,1L

#define SN_id_cmc_identification                "id-cmc-identification"
#define NID_id_cmc_identification               328
#define OBJ_id_cmc_identification               OBJ_id_cmc,2L

#define SN_id_cmc_identityProof         "id-cmc-identityProof"
#define NID_id_cmc_identityProof                329
#define OBJ_id_cmc_identityProof                OBJ_id_cmc,3L

#define SN_id_cmc_dataReturn            "id-cmc-dataReturn"
#define NID_id_cmc_dataReturn           330
#define OBJ_id_cmc_dataReturn           OBJ_id_cmc,4L

#define SN_id_cmc_transactionId         "id-cmc-transactionId"
#define NID_id_cmc_transactionId                331
#define OBJ_id_cmc_transactionId                OBJ_id_cmc,5L

#define SN_id_cmc_senderNonce           "id-cmc-senderNonce"
#define NID_id_cmc_senderNonce          332
#define OBJ_id_cmc_senderNonce          OBJ_id_cmc,6L

#define SN_id_cmc_recipientNonce                "id-cmc-recipientNonce"
#define NID_id_cmc_recipientNonce               333
#define OBJ_id_cmc_recipientNonce               OBJ_id_cmc,7L

#define SN_id_cmc_addExtensions         "id-cmc-addExtensions"
#define NID_id_cmc_addExtensions                334
#define OBJ_id_cmc_addExtensions                OBJ_id_cmc,8L

#define SN_id_cmc_encryptedPOP          "id-cmc-encryptedPOP"
#define NID_id_cmc_encryptedPOP         335
#define OBJ_id_cmc_encryptedPOP         OBJ_id_cmc,9L

#define SN_id_cmc_decryptedPOP          "id-cmc-decryptedPOP"
#define NID_id_cmc_decryptedPOP         336
#define OBJ_id_cmc_decryptedPOP         OBJ_id_cmc,10L

#define SN_id_cmc_lraPOPWitness         "id-cmc-lraPOPWitness"
#define NID_id_cmc_lraPOPWitness                337
#define OBJ_id_cmc_lraPOPWitness                OBJ_id_cmc,11L

#define SN_id_cmc_getCert               "id-cmc-getCert"
#define NID_id_cmc_getCert              338
#define OBJ_id_cmc_getCert              OBJ_id_cmc,15L

#define SN_id_cmc_getCRL                "id-cmc-getCRL"
#define NID_id_cmc_getCRL               339
#define OBJ_id_cmc_getCRL               OBJ_id_cmc,16L

#define SN_id_cmc_revokeRequest         "id-cmc-revokeRequest"
#define NID_id_cmc_revokeRequest                340
#define OBJ_id_cmc_revokeRequest                OBJ_id_cmc,17L

#define SN_id_cmc_regInfo               "id-cmc-regInfo"
#define NID_id_cmc_regInfo              341
#define OBJ_id_cmc_regInfo              OBJ_id_cmc,18L

#define SN_id_cmc_responseInfo          "id-cmc-responseInfo"
#define NID_id_cmc_responseInfo         342
#define OBJ_id_cmc_responseInfo         OBJ_id_cmc,19L

#define SN_id_cmc_queryPending          "id-cmc-queryPending"
#define NID_id_cmc_queryPending         343
#define OBJ_id_cmc_queryPending         OBJ_id_cmc,21L

#define SN_id_cmc_popLinkRandom         "id-cmc-popLinkRandom"
#define NID_id_cmc_popLinkRandom                344
#define OBJ_id_cmc_popLinkRandom                OBJ_id_cmc,22L

#define SN_id_cmc_popLinkWitness                "id-cmc-popLinkWitness"
#define NID_id_cmc_popLinkWitness               345
#define OBJ_id_cmc_popLinkWitness               OBJ_id_cmc,23L

#define SN_id_cmc_confirmCertAcceptance         "id-cmc-confirmCertAcceptance"
#define NID_id_cmc_confirmCertAcceptance                346
#define OBJ_id_cmc_confirmCertAcceptance                OBJ_id_cmc,24L

#define SN_id_on_personalData           "id-on-personalData"
#define NID_id_on_personalData          347
#define OBJ_id_on_personalData          OBJ_id_on,1L

#define SN_id_on_permanentIdentifier            "id-on-permanentIdentifier"
#define LN_id_on_permanentIdentifier            "Permanent Identifier"
#define NID_id_on_permanentIdentifier           858
#define OBJ_id_on_permanentIdentifier           OBJ_id_on,3L

#define SN_id_pda_dateOfBirth           "id-pda-dateOfBirth"
#define NID_id_pda_dateOfBirth          348
#define OBJ_id_pda_dateOfBirth          OBJ_id_pda,1L

#define SN_id_pda_placeOfBirth          "id-pda-placeOfBirth"
#define NID_id_pda_placeOfBirth         349
#define OBJ_id_pda_placeOfBirth         OBJ_id_pda,2L

#define SN_id_pda_gender                "id-pda-gender"
#define NID_id_pda_gender               351
#define OBJ_id_pda_gender               OBJ_id_pda,3L

#define SN_id_pda_countryOfCitizenship          "id-pda-countryOfCitizenship"
#define NID_id_pda_countryOfCitizenship         352
#define OBJ_id_pda_countryOfCitizenship         OBJ_id_pda,4L

#define SN_id_pda_countryOfResidence            "id-pda-countryOfResidence"
#define NID_id_pda_countryOfResidence           353
#define OBJ_id_pda_countryOfResidence           OBJ_id_pda,5L

#define SN_id_aca_authenticationInfo            "id-aca-authenticationInfo"
#define NID_id_aca_authenticationInfo           354
#define OBJ_id_aca_authenticationInfo           OBJ_id_aca,1L

#define SN_id_aca_accessIdentity                "id-aca-accessIdentity"
#define NID_id_aca_accessIdentity               355
#define OBJ_id_aca_accessIdentity               OBJ_id_aca,2L

#define SN_id_aca_chargingIdentity              "id-aca-chargingIdentity"
#define NID_id_aca_chargingIdentity             356
#define OBJ_id_aca_chargingIdentity             OBJ_id_aca,3L

#define SN_id_aca_group         "id-aca-group"
#define NID_id_aca_group                357
#define OBJ_id_aca_group                OBJ_id_aca,4L

#define SN_id_aca_role          "id-aca-role"
#define NID_id_aca_role         358
#define OBJ_id_aca_role         OBJ_id_aca,5L

#define SN_id_aca_encAttrs              "id-aca-encAttrs"
#define NID_id_aca_encAttrs             399
#define OBJ_id_aca_encAttrs             OBJ_id_aca,6L

#define SN_id_qcs_pkixQCSyntax_v1               "id-qcs-pkixQCSyntax-v1"
#define NID_id_qcs_pkixQCSyntax_v1              359
#define OBJ_id_qcs_pkixQCSyntax_v1              OBJ_id_qcs,1L

#define SN_id_cct_crs           "id-cct-crs"
#define NID_id_cct_crs          360
#define OBJ_id_cct_crs          OBJ_id_cct,1L

#define SN_id_cct_PKIData               "id-cct-PKIData"
#define NID_id_cct_PKIData              361
#define OBJ_id_cct_PKIData              OBJ_id_cct,2L

#define SN_id_cct_PKIResponse           "id-cct-PKIResponse"
#define NID_id_cct_PKIResponse          362
#define OBJ_id_cct_PKIResponse          OBJ_id_cct,3L

#define SN_id_ppl_anyLanguage           "id-ppl-anyLanguage"
#define LN_id_ppl_anyLanguage           "Any language"
#define NID_id_ppl_anyLanguage          664
#define OBJ_id_ppl_anyLanguage          OBJ_id_ppl,0L

#define SN_id_ppl_inheritAll            "id-ppl-inheritAll"
#define LN_id_ppl_inheritAll            "Inherit all"
#define NID_id_ppl_inheritAll           665
#define OBJ_id_ppl_inheritAll           OBJ_id_ppl,1L

#define SN_Independent          "id-ppl-independent"
#define LN_Independent          "Independent"
#define NID_Independent         667
#define OBJ_Independent         OBJ_id_ppl,2L

#define SN_ad_OCSP              "OCSP"
#define LN_ad_OCSP              "OCSP"
#define NID_ad_OCSP             178
#define OBJ_ad_OCSP             OBJ_id_ad,1L

#define SN_ad_ca_issuers                "caIssuers"
#define LN_ad_ca_issuers                "CA Issuers"
#define NID_ad_ca_issuers               179
#define OBJ_ad_ca_issuers               OBJ_id_ad,2L

#define SN_ad_timeStamping              "ad_timestamping"
#define LN_ad_timeStamping              "AD Time Stamping"
#define NID_ad_timeStamping             363
#define OBJ_ad_timeStamping             OBJ_id_ad,3L

#define SN_ad_dvcs              "AD_DVCS"
#define LN_ad_dvcs              "ad dvcs"
#define NID_ad_dvcs             364
#define OBJ_ad_dvcs             OBJ_id_ad,4L

#define SN_caRepository         "caRepository"
#define LN_caRepository         "CA Repository"
#define NID_caRepository                785
#define OBJ_caRepository                OBJ_id_ad,5L

#define OBJ_id_pkix_OCSP                OBJ_ad_OCSP

#define SN_id_pkix_OCSP_basic           "basicOCSPResponse"
#define LN_id_pkix_OCSP_basic           "Basic OCSP Response"
#define NID_id_pkix_OCSP_basic          365
#define OBJ_id_pkix_OCSP_basic          OBJ_id_pkix_OCSP,1L

#define SN_id_pkix_OCSP_Nonce           "Nonce"
#define LN_id_pkix_OCSP_Nonce           "OCSP Nonce"
#define NID_id_pkix_OCSP_Nonce          366
#define OBJ_id_pkix_OCSP_Nonce          OBJ_id_pkix_OCSP,2L

#define SN_id_pkix_OCSP_CrlID           "CrlID"
#define LN_id_pkix_OCSP_CrlID           "OCSP CRL ID"
#define NID_id_pkix_OCSP_CrlID          367
#define OBJ_id_pkix_OCSP_CrlID          OBJ_id_pkix_OCSP,3L

#define SN_id_pkix_OCSP_acceptableResponses             "acceptableResponses"
#define LN_id_pkix_OCSP_acceptableResponses             "Acceptable OCSP Responses"
#define NID_id_pkix_OCSP_acceptableResponses            368
#define OBJ_id_pkix_OCSP_acceptableResponses            OBJ_id_pkix_OCSP,4L

#define SN_id_pkix_OCSP_noCheck         "noCheck"
#define LN_id_pkix_OCSP_noCheck         "OCSP No Check"
#define NID_id_pkix_OCSP_noCheck                369
#define OBJ_id_pkix_OCSP_noCheck                OBJ_id_pkix_OCSP,5L

#define SN_id_pkix_OCSP_archiveCutoff           "archiveCutoff"
#define LN_id_pkix_OCSP_archiveCutoff           "OCSP Archive Cutoff"
#define NID_id_pkix_OCSP_archiveCutoff          370
#define OBJ_id_pkix_OCSP_archiveCutoff          OBJ_id_pkix_OCSP,6L

#define SN_id_pkix_OCSP_serviceLocator          "serviceLocator"
#define LN_id_pkix_OCSP_serviceLocator          "OCSP Service Locator"
#define NID_id_pkix_OCSP_serviceLocator         371
#define OBJ_id_pkix_OCSP_serviceLocator         OBJ_id_pkix_OCSP,7L

#define SN_id_pkix_OCSP_extendedStatus          "extendedStatus"
#define LN_id_pkix_OCSP_extendedStatus          "Extended OCSP Status"
#define NID_id_pkix_OCSP_extendedStatus         372
#define OBJ_id_pkix_OCSP_extendedStatus         OBJ_id_pkix_OCSP,8L

#define SN_id_pkix_OCSP_valid           "valid"
#define NID_id_pkix_OCSP_valid          373
#define OBJ_id_pkix_OCSP_valid          OBJ_id_pkix_OCSP,9L

#define SN_id_pkix_OCSP_path            "path"
#define NID_id_pkix_OCSP_path           374
#define OBJ_id_pkix_OCSP_path           OBJ_id_pkix_OCSP,10L

#define SN_id_pkix_OCSP_trustRoot               "trustRoot"
#define LN_id_pkix_OCSP_trustRoot               "Trust Root"
#define NID_id_pkix_OCSP_trustRoot              375
#define OBJ_id_pkix_OCSP_trustRoot              OBJ_id_pkix_OCSP,11L

#define SN_algorithm            "algorithm"
#define LN_algorithm            "algorithm"
#define NID_algorithm           376
#define OBJ_algorithm           1L,3L,14L,3L,2L

#define SN_md5WithRSA           "RSA-NP-MD5"
#define LN_md5WithRSA           "md5WithRSA"
#define NID_md5WithRSA          104
#define OBJ_md5WithRSA          OBJ_algorithm,3L

#define SN_des_ecb              "DES-ECB"
#define LN_des_ecb              "des-ecb"
#define NID_des_ecb             29
#define OBJ_des_ecb             OBJ_algorithm,6L

#define SN_des_cbc              "DES-CBC"
#define LN_des_cbc              "des-cbc"
#define NID_des_cbc             31
#define OBJ_des_cbc             OBJ_algorithm,7L

#define SN_des_ofb64            "DES-OFB"
#define LN_des_ofb64            "des-ofb"
#define NID_des_ofb64           45
#define OBJ_des_ofb64           OBJ_algorithm,8L

#define SN_des_cfb64            "DES-CFB"
#define LN_des_cfb64            "des-cfb"
#define NID_des_cfb64           30
#define OBJ_des_cfb64           OBJ_algorithm,9L

#define SN_rsaSignature         "rsaSignature"
#define NID_rsaSignature                377
#define OBJ_rsaSignature                OBJ_algorithm,11L

#define SN_dsa_2                "DSA-old"
#define LN_dsa_2                "dsaEncryption-old"
#define NID_dsa_2               67
#define OBJ_dsa_2               OBJ_algorithm,12L

#define SN_dsaWithSHA           "DSA-SHA"
#define LN_dsaWithSHA           "dsaWithSHA"
#define NID_dsaWithSHA          66
#define OBJ_dsaWithSHA          OBJ_algorithm,13L

#define SN_shaWithRSAEncryption         "RSA-SHA"
#define LN_shaWithRSAEncryption         "shaWithRSAEncryption"
#define NID_shaWithRSAEncryption                42
#define OBJ_shaWithRSAEncryption                OBJ_algorithm,15L

#define SN_des_ede_ecb          "DES-EDE"
#define LN_des_ede_ecb          "des-ede"
#define NID_des_ede_ecb         32
#define OBJ_des_ede_ecb         OBJ_algorithm,17L

#define SN_des_ede3_ecb         "DES-EDE3"
#define LN_des_ede3_ecb         "des-ede3"
#define NID_des_ede3_ecb                33

#define SN_des_ede_cbc          "DES-EDE-CBC"
#define LN_des_ede_cbc          "des-ede-cbc"
#define NID_des_ede_cbc         43

#define SN_des_ede_cfb64                "DES-EDE-CFB"
#define LN_des_ede_cfb64                "des-ede-cfb"
#define NID_des_ede_cfb64               60

#define SN_des_ede3_cfb64               "DES-EDE3-CFB"
#define LN_des_ede3_cfb64               "des-ede3-cfb"
#define NID_des_ede3_cfb64              61

#define SN_des_ede_ofb64                "DES-EDE-OFB"
#define LN_des_ede_ofb64                "des-ede-ofb"
#define NID_des_ede_ofb64               62

#define SN_des_ede3_ofb64               "DES-EDE3-OFB"
#define LN_des_ede3_ofb64               "des-ede3-ofb"
#define NID_des_ede3_ofb64              63

#define SN_desx_cbc             "DESX-CBC"
#define LN_desx_cbc             "desx-cbc"
#define NID_desx_cbc            80

#define SN_sha          "SHA"
#define LN_sha          "sha"
#define NID_sha         41
#define OBJ_sha         OBJ_algorithm,18L

#define SN_sha1         "SHA1"
#define LN_sha1         "sha1"
#define NID_sha1                64
#define OBJ_sha1                OBJ_algorithm,26L

#define SN_dsaWithSHA1_2                "DSA-SHA1-old"
#define LN_dsaWithSHA1_2                "dsaWithSHA1-old"
#define NID_dsaWithSHA1_2               70
#define OBJ_dsaWithSHA1_2               OBJ_algorithm,27L

#define SN_sha1WithRSA          "RSA-SHA1-2"
#define LN_sha1WithRSA          "sha1WithRSA"
#define NID_sha1WithRSA         115
#define OBJ_sha1WithRSA         OBJ_algorithm,29L

#define SN_ripemd160            "RIPEMD160"
#define LN_ripemd160            "ripemd160"
#define NID_ripemd160           117
#define OBJ_ripemd160           1L,3L,36L,3L,2L,1L

#define SN_ripemd160WithRSA             "RSA-RIPEMD160"
#define LN_ripemd160WithRSA             "ripemd160WithRSA"
#define NID_ripemd160WithRSA            119
#define OBJ_ripemd160WithRSA            1L,3L,36L,3L,3L,1L,2L

#define SN_sxnet                "SXNetID"
#define LN_sxnet                "Strong Extranet ID"
#define NID_sxnet               143
#define OBJ_sxnet               1L,3L,101L,1L,4L,1L

#define SN_X500         "X500"
#define LN_X500         "directory services (X.500)"
#define NID_X500                11
#define OBJ_X500                2L,5L

#define SN_X509         "X509"
#define NID_X509                12
#define OBJ_X509                OBJ_X500,4L

#define SN_commonName           "CN"
#define LN_commonName           "commonName"
#define NID_commonName          13
#define OBJ_commonName          OBJ_X509,3L

#define SN_surname              "SN"
#define LN_surname              "surname"
#define NID_surname             100
#define OBJ_surname             OBJ_X509,4L

#define LN_serialNumber         "serialNumber"
#define NID_serialNumber                105
#define OBJ_serialNumber                OBJ_X509,5L

#define SN_countryName          "C"
#define LN_countryName          "countryName"
#define NID_countryName         14
#define OBJ_countryName         OBJ_X509,6L

#define SN_localityName         "L"
#define LN_localityName         "localityName"
#define NID_localityName                15
#define OBJ_localityName                OBJ_X509,7L

#define SN_stateOrProvinceName          "ST"
#define LN_stateOrProvinceName          "stateOrProvinceName"
#define NID_stateOrProvinceName         16
#define OBJ_stateOrProvinceName         OBJ_X509,8L

#define SN_streetAddress                "street"
#define LN_streetAddress                "streetAddress"
#define NID_streetAddress               660
#define OBJ_streetAddress               OBJ_X509,9L

#define SN_organizationName             "O"
#define LN_organizationName             "organizationName"
#define NID_organizationName            17
#define OBJ_organizationName            OBJ_X509,10L

#define SN_organizationalUnitName               "OU"
#define LN_organizationalUnitName               "organizationalUnitName"
#define NID_organizationalUnitName              18
#define OBJ_organizationalUnitName              OBJ_X509,11L

#define SN_title                "title"
#define LN_title                "title"
#define NID_title               106
#define OBJ_title               OBJ_X509,12L

#define LN_description          "description"
#define NID_description         107
#define OBJ_description         OBJ_X509,13L

#define LN_searchGuide          "searchGuide"
#define NID_searchGuide         859
#define OBJ_searchGuide         OBJ_X509,14L

#define LN_businessCategory             "businessCategory"
#define NID_businessCategory            860
#define OBJ_businessCategory            OBJ_X509,15L

#define LN_postalAddress                "postalAddress"
#define NID_postalAddress               861
#define OBJ_postalAddress               OBJ_X509,16L

#define LN_postalCode           "postalCode"
#define NID_postalCode          661
#define OBJ_postalCode          OBJ_X509,17L

#define LN_postOfficeBox                "postOfficeBox"
#define NID_postOfficeBox               862
#define OBJ_postOfficeBox               OBJ_X509,18L

#define LN_physicalDeliveryOfficeName           "physicalDeliveryOfficeName"
#define NID_physicalDeliveryOfficeName          863
#define OBJ_physicalDeliveryOfficeName          OBJ_X509,19L

#define LN_telephoneNumber              "telephoneNumber"
#define NID_telephoneNumber             864
#define OBJ_telephoneNumber             OBJ_X509,20L

#define LN_telexNumber          "telexNumber"
#define NID_telexNumber         865
#define OBJ_telexNumber         OBJ_X509,21L

#define LN_teletexTerminalIdentifier            "teletexTerminalIdentifier"
#define NID_teletexTerminalIdentifier           866
#define OBJ_teletexTerminalIdentifier           OBJ_X509,22L

#define LN_facsimileTelephoneNumber             "facsimileTelephoneNumber"
#define NID_facsimileTelephoneNumber            867
#define OBJ_facsimileTelephoneNumber            OBJ_X509,23L

#define LN_x121Address          "x121Address"
#define NID_x121Address         868
#define OBJ_x121Address         OBJ_X509,24L

#define LN_internationaliSDNNumber              "internationaliSDNNumber"
#define NID_internationaliSDNNumber             869
#define OBJ_internationaliSDNNumber             OBJ_X509,25L

#define LN_registeredAddress            "registeredAddress"
#define NID_registeredAddress           870
#define OBJ_registeredAddress           OBJ_X509,26L

#define LN_destinationIndicator         "destinationIndicator"
#define NID_destinationIndicator                871
#define OBJ_destinationIndicator                OBJ_X509,27L

#define LN_preferredDeliveryMethod              "preferredDeliveryMethod"
#define NID_preferredDeliveryMethod             872
#define OBJ_preferredDeliveryMethod             OBJ_X509,28L

#define LN_presentationAddress          "presentationAddress"
#define NID_presentationAddress         873
#define OBJ_presentationAddress         OBJ_X509,29L

#define LN_supportedApplicationContext          "supportedApplicationContext"
#define NID_supportedApplicationContext         874
#define OBJ_supportedApplicationContext         OBJ_X509,30L

#define SN_member               "member"
#define NID_member              875
#define OBJ_member              OBJ_X509,31L

#define SN_owner                "owner"
#define NID_owner               876
#define OBJ_owner               OBJ_X509,32L

#define LN_roleOccupant         "roleOccupant"
#define NID_roleOccupant                877
#define OBJ_roleOccupant                OBJ_X509,33L

#define SN_seeAlso              "seeAlso"
#define NID_seeAlso             878
#define OBJ_seeAlso             OBJ_X509,34L

#define LN_userPassword         "userPassword"
#define NID_userPassword                879
#define OBJ_userPassword                OBJ_X509,35L

#define LN_userCertificate              "userCertificate"
#define NID_userCertificate             880
#define OBJ_userCertificate             OBJ_X509,36L

#define LN_cACertificate                "cACertificate"
#define NID_cACertificate               881
#define OBJ_cACertificate               OBJ_X509,37L

#define LN_authorityRevocationList              "authorityRevocationList"
#define NID_authorityRevocationList             882
#define OBJ_authorityRevocationList             OBJ_X509,38L

#define LN_certificateRevocationList            "certificateRevocationList"
#define NID_certificateRevocationList           883
#define OBJ_certificateRevocationList           OBJ_X509,39L

#define LN_crossCertificatePair         "crossCertificatePair"
#define NID_crossCertificatePair                884
#define OBJ_crossCertificatePair                OBJ_X509,40L

#define SN_name         "name"
#define LN_name         "name"
#define NID_name                173
#define OBJ_name                OBJ_X509,41L

#define SN_givenName            "GN"
#define LN_givenName            "givenName"
#define NID_givenName           99
#define OBJ_givenName           OBJ_X509,42L

#define SN_initials             "initials"
#define LN_initials             "initials"
#define NID_initials            101
#define OBJ_initials            OBJ_X509,43L

#define LN_generationQualifier          "generationQualifier"
#define NID_generationQualifier         509
#define OBJ_generationQualifier         OBJ_X509,44L

#define LN_x500UniqueIdentifier         "x500UniqueIdentifier"
#define NID_x500UniqueIdentifier                503
#define OBJ_x500UniqueIdentifier                OBJ_X509,45L

#define SN_dnQualifier          "dnQualifier"
#define LN_dnQualifier          "dnQualifier"
#define NID_dnQualifier         174
#define OBJ_dnQualifier         OBJ_X509,46L

#define LN_enhancedSearchGuide          "enhancedSearchGuide"
#define NID_enhancedSearchGuide         885
#define OBJ_enhancedSearchGuide         OBJ_X509,47L

#define LN_protocolInformation          "protocolInformation"
#define NID_protocolInformation         886
#define OBJ_protocolInformation         OBJ_X509,48L

#define LN_distinguishedName            "distinguishedName"
#define NID_distinguishedName           887
#define OBJ_distinguishedName           OBJ_X509,49L

#define LN_uniqueMember         "uniqueMember"
#define NID_uniqueMember                888
#define OBJ_uniqueMember                OBJ_X509,50L

#define LN_houseIdentifier              "houseIdentifier"
#define NID_houseIdentifier             889
#define OBJ_houseIdentifier             OBJ_X509,51L

#define LN_supportedAlgorithms          "supportedAlgorithms"
#define NID_supportedAlgorithms         890
#define OBJ_supportedAlgorithms         OBJ_X509,52L

#define LN_deltaRevocationList          "deltaRevocationList"
#define NID_deltaRevocationList         891
#define OBJ_deltaRevocationList         OBJ_X509,53L

#define SN_dmdName              "dmdName"
#define NID_dmdName             892
#define OBJ_dmdName             OBJ_X509,54L

#define LN_pseudonym            "pseudonym"
#define NID_pseudonym           510
#define OBJ_pseudonym           OBJ_X509,65L

#define SN_role         "role"
#define LN_role         "role"
#define NID_role                400
#define OBJ_role                OBJ_X509,72L

#define SN_X500algorithms               "X500algorithms"
#define LN_X500algorithms               "directory services - algorithms"
#define NID_X500algorithms              378
#define OBJ_X500algorithms              OBJ_X500,8L

#define SN_rsa          "RSA"
#define LN_rsa          "rsa"
#define NID_rsa         19
#define OBJ_rsa         OBJ_X500algorithms,1L,1L

#define SN_mdc2WithRSA          "RSA-MDC2"
#define LN_mdc2WithRSA          "mdc2WithRSA"
#define NID_mdc2WithRSA         96
#define OBJ_mdc2WithRSA         OBJ_X500algorithms,3L,100L

#define SN_mdc2         "MDC2"
#define LN_mdc2         "mdc2"
#define NID_mdc2                95
#define OBJ_mdc2                OBJ_X500algorithms,3L,101L

#define SN_id_ce                "id-ce"
#define NID_id_ce               81
#define OBJ_id_ce               OBJ_X500,29L

#define SN_subject_directory_attributes         "subjectDirectoryAttributes"
#define LN_subject_directory_attributes         "X509v3 Subject Directory Attributes"
#define NID_subject_directory_attributes                769
#define OBJ_subject_directory_attributes                OBJ_id_ce,9L

#define SN_subject_key_identifier               "subjectKeyIdentifier"
#define LN_subject_key_identifier               "X509v3 Subject Key Identifier"
#define NID_subject_key_identifier              82
#define OBJ_subject_key_identifier              OBJ_id_ce,14L

#define SN_key_usage            "keyUsage"
#define LN_key_usage            "X509v3 Key Usage"
#define NID_key_usage           83
#define OBJ_key_usage           OBJ_id_ce,15L

#define SN_private_key_usage_period             "privateKeyUsagePeriod"
#define LN_private_key_usage_period             "X509v3 Private Key Usage Period"
#define NID_private_key_usage_period            84
#define OBJ_private_key_usage_period            OBJ_id_ce,16L

#define SN_subject_alt_name             "subjectAltName"
#define LN_subject_alt_name             "X509v3 Subject Alternative Name"
#define NID_subject_alt_name            85
#define OBJ_subject_alt_name            OBJ_id_ce,17L

#define SN_issuer_alt_name              "issuerAltName"
#define LN_issuer_alt_name              "X509v3 Issuer Alternative Name"
#define NID_issuer_alt_name             86
#define OBJ_issuer_alt_name             OBJ_id_ce,18L

#define SN_basic_constraints            "basicConstraints"
#define LN_basic_constraints            "X509v3 Basic Constraints"
#define NID_basic_constraints           87
#define OBJ_basic_constraints           OBJ_id_ce,19L

#define SN_crl_number           "crlNumber"
#define LN_crl_number           "X509v3 CRL Number"
#define NID_crl_number          88
#define OBJ_crl_number          OBJ_id_ce,20L

#define SN_crl_reason           "CRLReason"
#define LN_crl_reason           "X509v3 CRL Reason Code"
#define NID_crl_reason          141
#define OBJ_crl_reason          OBJ_id_ce,21L

#define SN_invalidity_date              "invalidityDate"
#define LN_invalidity_date              "Invalidity Date"
#define NID_invalidity_date             142
#define OBJ_invalidity_date             OBJ_id_ce,24L

#define SN_delta_crl            "deltaCRL"
#define LN_delta_crl            "X509v3 Delta CRL Indicator"
#define NID_delta_crl           140
#define OBJ_delta_crl           OBJ_id_ce,27L

#define SN_issuing_distribution_point           "issuingDistributionPoint"
#define LN_issuing_distribution_point           "X509v3 Issuing Distrubution Point"
#define NID_issuing_distribution_point          770
#define OBJ_issuing_distribution_point          OBJ_id_ce,28L

#define SN_certificate_issuer           "certificateIssuer"
#define LN_certificate_issuer           "X509v3 Certificate Issuer"
#define NID_certificate_issuer          771
#define OBJ_certificate_issuer          OBJ_id_ce,29L

#define SN_name_constraints             "nameConstraints"
#define LN_name_constraints             "X509v3 Name Constraints"
#define NID_name_constraints            666
#define OBJ_name_constraints            OBJ_id_ce,30L

#define SN_crl_distribution_points              "crlDistributionPoints"
#define LN_crl_distribution_points              "X509v3 CRL Distribution Points"
#define NID_crl_distribution_points             103
#define OBJ_crl_distribution_points             OBJ_id_ce,31L

#define SN_certificate_policies         "certificatePolicies"
#define LN_certificate_policies         "X509v3 Certificate Policies"
#define NID_certificate_policies                89
#define OBJ_certificate_policies                OBJ_id_ce,32L

#define SN_any_policy           "anyPolicy"
#define LN_any_policy           "X509v3 Any Policy"
#define NID_any_policy          746
#define OBJ_any_policy          OBJ_certificate_policies,0L

#define SN_policy_mappings              "policyMappings"
#define LN_policy_mappings              "X509v3 Policy Mappings"
#define NID_policy_mappings             747
#define OBJ_policy_mappings             OBJ_id_ce,33L

#define SN_authority_key_identifier             "authorityKeyIdentifier"
#define LN_authority_key_identifier             "X509v3 Authority Key Identifier"
#define NID_authority_key_identifier            90
#define OBJ_authority_key_identifier            OBJ_id_ce,35L

#define SN_policy_constraints           "policyConstraints"
#define LN_policy_constraints           "X509v3 Policy Constraints"
#define NID_policy_constraints          401
#define OBJ_policy_constraints          OBJ_id_ce,36L

#define SN_ext_key_usage                "extendedKeyUsage"
#define LN_ext_key_usage                "X509v3 Extended Key Usage"
#define NID_ext_key_usage               126
#define OBJ_ext_key_usage               OBJ_id_ce,37L

#define SN_freshest_crl         "freshestCRL"
#define LN_freshest_crl         "X509v3 Freshest CRL"
#define NID_freshest_crl                857
#define OBJ_freshest_crl                OBJ_id_ce,46L

#define SN_inhibit_any_policy           "inhibitAnyPolicy"
#define LN_inhibit_any_policy           "X509v3 Inhibit Any Policy"
#define NID_inhibit_any_policy          748
#define OBJ_inhibit_any_policy          OBJ_id_ce,54L

#define SN_target_information           "targetInformation"
#define LN_target_information           "X509v3 AC Targeting"
#define NID_target_information          402
#define OBJ_target_information          OBJ_id_ce,55L

#define SN_no_rev_avail         "noRevAvail"
#define LN_no_rev_avail         "X509v3 No Revocation Available"
#define NID_no_rev_avail                403
#define OBJ_no_rev_avail                OBJ_id_ce,56L

#define SN_anyExtendedKeyUsage          "anyExtendedKeyUsage"
#define LN_anyExtendedKeyUsage          "Any Extended Key Usage"
#define NID_anyExtendedKeyUsage         910
#define OBJ_anyExtendedKeyUsage         OBJ_ext_key_usage,0L

#define SN_netscape             "Netscape"
#define LN_netscape             "Netscape Communications Corp."
#define NID_netscape            57
#define OBJ_netscape            2L,16L,840L,1L,113730L

#define SN_netscape_cert_extension              "nsCertExt"
#define LN_netscape_cert_extension              "Netscape Certificate Extension"
#define NID_netscape_cert_extension             58
#define OBJ_netscape_cert_extension             OBJ_netscape,1L

#define SN_netscape_data_type           "nsDataType"
#define LN_netscape_data_type           "Netscape Data Type"
#define NID_netscape_data_type          59
#define OBJ_netscape_data_type          OBJ_netscape,2L

#define SN_netscape_cert_type           "nsCertType"
#define LN_netscape_cert_type           "Netscape Cert Type"
#define NID_netscape_cert_type          71
#define OBJ_netscape_cert_type          OBJ_netscape_cert_extension,1L

#define SN_netscape_base_url            "nsBaseUrl"
#define LN_netscape_base_url            "Netscape Base Url"
#define NID_netscape_base_url           72
#define OBJ_netscape_base_url           OBJ_netscape_cert_extension,2L

#define SN_netscape_revocation_url              "nsRevocationUrl"
#define LN_netscape_revocation_url              "Netscape Revocation Url"
#define NID_netscape_revocation_url             73
#define OBJ_netscape_revocation_url             OBJ_netscape_cert_extension,3L

#define SN_netscape_ca_revocation_url           "nsCaRevocationUrl"
#define LN_netscape_ca_revocation_url           "Netscape CA Revocation Url"
#define NID_netscape_ca_revocation_url          74
#define OBJ_netscape_ca_revocation_url          OBJ_netscape_cert_extension,4L

#define SN_netscape_renewal_url         "nsRenewalUrl"
#define LN_netscape_renewal_url         "Netscape Renewal Url"
#define NID_netscape_renewal_url                75
#define OBJ_netscape_renewal_url                OBJ_netscape_cert_extension,7L

#define SN_netscape_ca_policy_url               "nsCaPolicyUrl"
#define LN_netscape_ca_policy_url               "Netscape CA Policy Url"
#define NID_netscape_ca_policy_url              76
#define OBJ_netscape_ca_policy_url              OBJ_netscape_cert_extension,8L

#define SN_netscape_ssl_server_name             "nsSslServerName"
#define LN_netscape_ssl_server_name             "Netscape SSL Server Name"
#define NID_netscape_ssl_server_name            77
#define OBJ_netscape_ssl_server_name            OBJ_netscape_cert_extension,12L

#define SN_netscape_comment             "nsComment"
#define LN_netscape_comment             "Netscape Comment"
#define NID_netscape_comment            78
#define OBJ_netscape_comment            OBJ_netscape_cert_extension,13L

#define SN_netscape_cert_sequence               "nsCertSequence"
#define LN_netscape_cert_sequence               "Netscape Certificate Sequence"
#define NID_netscape_cert_sequence              79
#define OBJ_netscape_cert_sequence              OBJ_netscape_data_type,5L

#define SN_ns_sgc               "nsSGC"
#define LN_ns_sgc               "Netscape Server Gated Crypto"
#define NID_ns_sgc              139
#define OBJ_ns_sgc              OBJ_netscape,4L,1L

#define SN_org          "ORG"
#define LN_org          "org"
#define NID_org         379
#define OBJ_org         OBJ_iso,3L

#define SN_dod          "DOD"
#define LN_dod          "dod"
#define NID_dod         380
#define OBJ_dod         OBJ_org,6L

#define SN_iana         "IANA"
#define LN_iana         "iana"
#define NID_iana                381
#define OBJ_iana                OBJ_dod,1L

#define OBJ_internet            OBJ_iana

#define SN_Directory            "directory"
#define LN_Directory            "Directory"
#define NID_Directory           382
#define OBJ_Directory           OBJ_internet,1L

#define SN_Management           "mgmt"
#define LN_Management           "Management"
#define NID_Management          383
#define OBJ_Management          OBJ_internet,2L

#define SN_Experimental         "experimental"
#define LN_Experimental         "Experimental"
#define NID_Experimental                384
#define OBJ_Experimental                OBJ_internet,3L

#define SN_Private              "private"
#define LN_Private              "Private"
#define NID_Private             385
#define OBJ_Private             OBJ_internet,4L

#define SN_Security             "security"
#define LN_Security             "Security"
#define NID_Security            386
#define OBJ_Security            OBJ_internet,5L

#define SN_SNMPv2               "snmpv2"
#define LN_SNMPv2               "SNMPv2"
#define NID_SNMPv2              387
#define OBJ_SNMPv2              OBJ_internet,6L

#define LN_Mail         "Mail"
#define NID_Mail                388
#define OBJ_Mail                OBJ_internet,7L

#define SN_Enterprises          "enterprises"
#define LN_Enterprises          "Enterprises"
#define NID_Enterprises         389
#define OBJ_Enterprises         OBJ_Private,1L

#define SN_dcObject             "dcobject"
#define LN_dcObject             "dcObject"
#define NID_dcObject            390
#define OBJ_dcObject            OBJ_Enterprises,1466L,344L

#define SN_mime_mhs             "mime-mhs"
#define LN_mime_mhs             "MIME MHS"
#define NID_mime_mhs            504
#define OBJ_mime_mhs            OBJ_Mail,1L

#define SN_mime_mhs_headings            "mime-mhs-headings"
#define LN_mime_mhs_headings            "mime-mhs-headings"
#define NID_mime_mhs_headings           505
#define OBJ_mime_mhs_headings           OBJ_mime_mhs,1L

#define SN_mime_mhs_bodies              "mime-mhs-bodies"
#define LN_mime_mhs_bodies              "mime-mhs-bodies"
#define NID_mime_mhs_bodies             506
#define OBJ_mime_mhs_bodies             OBJ_mime_mhs,2L

#define SN_id_hex_partial_message               "id-hex-partial-message"
#define LN_id_hex_partial_message               "id-hex-partial-message"
#define NID_id_hex_partial_message              507
#define OBJ_id_hex_partial_message              OBJ_mime_mhs_headings,1L

#define SN_id_hex_multipart_message             "id-hex-multipart-message"
#define LN_id_hex_multipart_message             "id-hex-multipart-message"
#define NID_id_hex_multipart_message            508
#define OBJ_id_hex_multipart_message            OBJ_mime_mhs_headings,2L

#define SN_rle_compression              "RLE"
#define LN_rle_compression              "run length compression"
#define NID_rle_compression             124
#define OBJ_rle_compression             1L,1L,1L,1L,666L,1L

#define SN_zlib_compression             "ZLIB"
#define LN_zlib_compression             "zlib compression"
#define NID_zlib_compression            125
#define OBJ_zlib_compression            OBJ_id_smime_alg,8L

#define OBJ_csor                2L,16L,840L,1L,101L,3L

#define OBJ_nistAlgorithms              OBJ_csor,4L

#define OBJ_aes         OBJ_nistAlgorithms,1L

#define SN_aes_128_ecb          "AES-128-ECB"
#define LN_aes_128_ecb          "aes-128-ecb"
#define NID_aes_128_ecb         418
#define OBJ_aes_128_ecb         OBJ_aes,1L

#define SN_aes_128_cbc          "AES-128-CBC"
#define LN_aes_128_cbc          "aes-128-cbc"
#define NID_aes_128_cbc         419
#define OBJ_aes_128_cbc         OBJ_aes,2L

#define SN_aes_128_ofb128               "AES-128-OFB"
#define LN_aes_128_ofb128               "aes-128-ofb"
#define NID_aes_128_ofb128              420
#define OBJ_aes_128_ofb128              OBJ_aes,3L

#define SN_aes_128_cfb128               "AES-128-CFB"
#define LN_aes_128_cfb128               "aes-128-cfb"
#define NID_aes_128_cfb128              421
#define OBJ_aes_128_cfb128              OBJ_aes,4L

#define SN_id_aes128_wrap               "id-aes128-wrap"
#define NID_id_aes128_wrap              788
#define OBJ_id_aes128_wrap              OBJ_aes,5L

#define SN_aes_128_gcm          "id-aes128-GCM"
#define LN_aes_128_gcm          "aes-128-gcm"
#define NID_aes_128_gcm         895
#define OBJ_aes_128_gcm         OBJ_aes,6L

#define SN_aes_128_ccm          "id-aes128-CCM"
#define LN_aes_128_ccm          "aes-128-ccm"
#define NID_aes_128_ccm         896
#define OBJ_aes_128_ccm         OBJ_aes,7L

#define SN_id_aes128_wrap_pad           "id-aes128-wrap-pad"
#define NID_id_aes128_wrap_pad          897
#define OBJ_id_aes128_wrap_pad          OBJ_aes,8L

#define SN_aes_192_ecb          "AES-192-ECB"
#define LN_aes_192_ecb          "aes-192-ecb"
#define NID_aes_192_ecb         422
#define OBJ_aes_192_ecb         OBJ_aes,21L

#define SN_aes_192_cbc          "AES-192-CBC"
#define LN_aes_192_cbc          "aes-192-cbc"
#define NID_aes_192_cbc         423
#define OBJ_aes_192_cbc         OBJ_aes,22L

#define SN_aes_192_ofb128               "AES-192-OFB"
#define LN_aes_192_ofb128               "aes-192-ofb"
#define NID_aes_192_ofb128              424
#define OBJ_aes_192_ofb128              OBJ_aes,23L

#define SN_aes_192_cfb128               "AES-192-CFB"
#define LN_aes_192_cfb128               "aes-192-cfb"
#define NID_aes_192_cfb128              425
#define OBJ_aes_192_cfb128              OBJ_aes,24L

#define SN_id_aes192_wrap               "id-aes192-wrap"
#define NID_id_aes192_wrap              789
#define OBJ_id_aes192_wrap              OBJ_aes,25L

#define SN_aes_192_gcm          "id-aes192-GCM"
#define LN_aes_192_gcm          "aes-192-gcm"
#define NID_aes_192_gcm         898
#define OBJ_aes_192_gcm         OBJ_aes,26L

#define SN_aes_192_ccm          "id-aes192-CCM"
#define LN_aes_192_ccm          "aes-192-ccm"
#define NID_aes_192_ccm         899
#define OBJ_aes_192_ccm         OBJ_aes,27L

#define SN_id_aes192_wrap_pad           "id-aes192-wrap-pad"
#define NID_id_aes192_wrap_pad          900
#define OBJ_id_aes192_wrap_pad          OBJ_aes,28L

#define SN_aes_256_ecb          "AES-256-ECB"
#define LN_aes_256_ecb          "aes-256-ecb"
#define NID_aes_256_ecb         426
#define OBJ_aes_256_ecb         OBJ_aes,41L

#define SN_aes_256_cbc          "AES-256-CBC"
#define LN_aes_256_cbc          "aes-256-cbc"
#define NID_aes_256_cbc         427
#define OBJ_aes_256_cbc         OBJ_aes,42L

#define SN_aes_256_ofb128               "AES-256-OFB"
#define LN_aes_256_ofb128               "aes-256-ofb"
#define NID_aes_256_ofb128              428
#define OBJ_aes_256_ofb128              OBJ_aes,43L

#define SN_aes_256_cfb128               "AES-256-CFB"
#define LN_aes_256_cfb128               "aes-256-cfb"
#define NID_aes_256_cfb128              429
#define OBJ_aes_256_cfb128              OBJ_aes,44L

#define SN_id_aes256_wrap               "id-aes256-wrap"
#define NID_id_aes256_wrap              790
#define OBJ_id_aes256_wrap              OBJ_aes,45L

#define SN_aes_256_gcm          "id-aes256-GCM"
#define LN_aes_256_gcm          "aes-256-gcm"
#define NID_aes_256_gcm         901
#define OBJ_aes_256_gcm         OBJ_aes,46L

#define SN_aes_256_ccm          "id-aes256-CCM"
#define LN_aes_256_ccm          "aes-256-ccm"
#define NID_aes_256_ccm         902
#define OBJ_aes_256_ccm         OBJ_aes,47L

#define SN_id_aes256_wrap_pad           "id-aes256-wrap-pad"
#define NID_id_aes256_wrap_pad          903
#define OBJ_id_aes256_wrap_pad          OBJ_aes,48L

#define SN_aes_128_cfb1         "AES-128-CFB1"
#define LN_aes_128_cfb1         "aes-128-cfb1"
#define NID_aes_128_cfb1                650

#define SN_aes_192_cfb1         "AES-192-CFB1"
#define LN_aes_192_cfb1         "aes-192-cfb1"
#define NID_aes_192_cfb1                651

#define SN_aes_256_cfb1         "AES-256-CFB1"
#define LN_aes_256_cfb1         "aes-256-cfb1"
#define NID_aes_256_cfb1                652

#define SN_aes_128_cfb8         "AES-128-CFB8"
#define LN_aes_128_cfb8         "aes-128-cfb8"
#define NID_aes_128_cfb8                653

#define SN_aes_192_cfb8         "AES-192-CFB8"
#define LN_aes_192_cfb8         "aes-192-cfb8"
#define NID_aes_192_cfb8                654

#define SN_aes_256_cfb8         "AES-256-CFB8"
#define LN_aes_256_cfb8         "aes-256-cfb8"
#define NID_aes_256_cfb8                655

#define SN_aes_128_ctr          "AES-128-CTR"
#define LN_aes_128_ctr          "aes-128-ctr"
#define NID_aes_128_ctr         904

#define SN_aes_192_ctr          "AES-192-CTR"
#define LN_aes_192_ctr          "aes-192-ctr"
#define NID_aes_192_ctr         905

#define SN_aes_256_ctr          "AES-256-CTR"
#define LN_aes_256_ctr          "aes-256-ctr"
#define NID_aes_256_ctr         906

#define SN_aes_128_xts          "AES-128-XTS"
#define LN_aes_128_xts          "aes-128-xts"
#define NID_aes_128_xts         913

#define SN_aes_256_xts          "AES-256-XTS"
#define LN_aes_256_xts          "aes-256-xts"
#define NID_aes_256_xts         914

#define SN_des_cfb1             "DES-CFB1"
#define LN_des_cfb1             "des-cfb1"
#define NID_des_cfb1            656

#define SN_des_cfb8             "DES-CFB8"
#define LN_des_cfb8             "des-cfb8"
#define NID_des_cfb8            657

#define SN_des_ede3_cfb1                "DES-EDE3-CFB1"
#define LN_des_ede3_cfb1                "des-ede3-cfb1"
#define NID_des_ede3_cfb1               658

#define SN_des_ede3_cfb8                "DES-EDE3-CFB8"
#define LN_des_ede3_cfb8                "des-ede3-cfb8"
#define NID_des_ede3_cfb8               659

#define OBJ_nist_hashalgs               OBJ_nistAlgorithms,2L

#define SN_sha256               "SHA256"
#define LN_sha256               "sha256"
#define NID_sha256              672
#define OBJ_sha256              OBJ_nist_hashalgs,1L

#define SN_sha384               "SHA384"
#define LN_sha384               "sha384"
#define NID_sha384              673
#define OBJ_sha384              OBJ_nist_hashalgs,2L

#define SN_sha512               "SHA512"
#define LN_sha512               "sha512"
#define NID_sha512              674
#define OBJ_sha512              OBJ_nist_hashalgs,3L

#define SN_sha224               "SHA224"
#define LN_sha224               "sha224"
#define NID_sha224              675
#define OBJ_sha224              OBJ_nist_hashalgs,4L

#define OBJ_dsa_with_sha2               OBJ_nistAlgorithms,3L

#define SN_dsa_with_SHA224              "dsa_with_SHA224"
#define NID_dsa_with_SHA224             802
#define OBJ_dsa_with_SHA224             OBJ_dsa_with_sha2,1L

#define SN_dsa_with_SHA256              "dsa_with_SHA256"
#define NID_dsa_with_SHA256             803
#define OBJ_dsa_with_SHA256             OBJ_dsa_with_sha2,2L

#define SN_hold_instruction_code                "holdInstructionCode"
#define LN_hold_instruction_code                "Hold Instruction Code"
#define NID_hold_instruction_code               430
#define OBJ_hold_instruction_code               OBJ_id_ce,23L

#define OBJ_holdInstruction             OBJ_X9_57,2L

#define SN_hold_instruction_none                "holdInstructionNone"
#define LN_hold_instruction_none                "Hold Instruction None"
#define NID_hold_instruction_none               431
#define OBJ_hold_instruction_none               OBJ_holdInstruction,1L

#define SN_hold_instruction_call_issuer         "holdInstructionCallIssuer"
#define LN_hold_instruction_call_issuer         "Hold Instruction Call Issuer"
#define NID_hold_instruction_call_issuer                432
#define OBJ_hold_instruction_call_issuer                OBJ_holdInstruction,2L

#define SN_hold_instruction_reject              "holdInstructionReject"
#define LN_hold_instruction_reject              "Hold Instruction Reject"
#define NID_hold_instruction_reject             433
#define OBJ_hold_instruction_reject             OBJ_holdInstruction,3L

#define SN_data         "data"
#define NID_data                434
#define OBJ_data                OBJ_itu_t,9L

#define SN_pss          "pss"
#define NID_pss         435
#define OBJ_pss         OBJ_data,2342L

#define SN_ucl          "ucl"
#define NID_ucl         436
#define OBJ_ucl         OBJ_pss,19200300L

#define SN_pilot                "pilot"
#define NID_pilot               437
#define OBJ_pilot               OBJ_ucl,100L

#define LN_pilotAttributeType           "pilotAttributeType"
#define NID_pilotAttributeType          438
#define OBJ_pilotAttributeType          OBJ_pilot,1L

#define LN_pilotAttributeSyntax         "pilotAttributeSyntax"
#define NID_pilotAttributeSyntax                439
#define OBJ_pilotAttributeSyntax                OBJ_pilot,3L

#define LN_pilotObjectClass             "pilotObjectClass"
#define NID_pilotObjectClass            440
#define OBJ_pilotObjectClass            OBJ_pilot,4L

#define LN_pilotGroups          "pilotGroups"
#define NID_pilotGroups         441
#define OBJ_pilotGroups         OBJ_pilot,10L

#define LN_iA5StringSyntax              "iA5StringSyntax"
#define NID_iA5StringSyntax             442
#define OBJ_iA5StringSyntax             OBJ_pilotAttributeSyntax,4L

#define LN_caseIgnoreIA5StringSyntax            "caseIgnoreIA5StringSyntax"
#define NID_caseIgnoreIA5StringSyntax           443
#define OBJ_caseIgnoreIA5StringSyntax           OBJ_pilotAttributeSyntax,5L

#define LN_pilotObject          "pilotObject"
#define NID_pilotObject         444
#define OBJ_pilotObject         OBJ_pilotObjectClass,3L

#define LN_pilotPerson          "pilotPerson"
#define NID_pilotPerson         445
#define OBJ_pilotPerson         OBJ_pilotObjectClass,4L

#define SN_account              "account"
#define NID_account             446
#define OBJ_account             OBJ_pilotObjectClass,5L

#define SN_document             "document"
#define NID_document            447
#define OBJ_document            OBJ_pilotObjectClass,6L

#define SN_room         "room"
#define NID_room                448
#define OBJ_room                OBJ_pilotObjectClass,7L

#define LN_documentSeries               "documentSeries"
#define NID_documentSeries              449
#define OBJ_documentSeries              OBJ_pilotObjectClass,9L

#define SN_Domain               "domain"
#define LN_Domain               "Domain"
#define NID_Domain              392
#define OBJ_Domain              OBJ_pilotObjectClass,13L

#define LN_rFC822localPart              "rFC822localPart"
#define NID_rFC822localPart             450
#define OBJ_rFC822localPart             OBJ_pilotObjectClass,14L

#define LN_dNSDomain            "dNSDomain"
#define NID_dNSDomain           451
#define OBJ_dNSDomain           OBJ_pilotObjectClass,15L

#define LN_domainRelatedObject          "domainRelatedObject"
#define NID_domainRelatedObject         452
#define OBJ_domainRelatedObject         OBJ_pilotObjectClass,17L

#define LN_friendlyCountry              "friendlyCountry"
#define NID_friendlyCountry             453
#define OBJ_friendlyCountry             OBJ_pilotObjectClass,18L

#define LN_simpleSecurityObject         "simpleSecurityObject"
#define NID_simpleSecurityObject                454
#define OBJ_simpleSecurityObject                OBJ_pilotObjectClass,19L

#define LN_pilotOrganization            "pilotOrganization"
#define NID_pilotOrganization           455
#define OBJ_pilotOrganization           OBJ_pilotObjectClass,20L

#define LN_pilotDSA             "pilotDSA"
#define NID_pilotDSA            456
#define OBJ_pilotDSA            OBJ_pilotObjectClass,21L

#define LN_qualityLabelledData          "qualityLabelledData"
#define NID_qualityLabelledData         457
#define OBJ_qualityLabelledData         OBJ_pilotObjectClass,22L

#define SN_userId               "UID"
#define LN_userId               "userId"
#define NID_userId              458
#define OBJ_userId              OBJ_pilotAttributeType,1L

#define LN_textEncodedORAddress         "textEncodedORAddress"
#define NID_textEncodedORAddress                459
#define OBJ_textEncodedORAddress                OBJ_pilotAttributeType,2L

#define SN_rfc822Mailbox                "mail"
#define LN_rfc822Mailbox                "rfc822Mailbox"
#define NID_rfc822Mailbox               460
#define OBJ_rfc822Mailbox               OBJ_pilotAttributeType,3L

#define SN_info         "info"
#define NID_info                461
#define OBJ_info                OBJ_pilotAttributeType,4L

#define LN_favouriteDrink               "favouriteDrink"
#define NID_favouriteDrink              462
#define OBJ_favouriteDrink              OBJ_pilotAttributeType,5L

#define LN_roomNumber           "roomNumber"
#define NID_roomNumber          463
#define OBJ_roomNumber          OBJ_pilotAttributeType,6L

#define SN_photo                "photo"
#define NID_photo               464
#define OBJ_photo               OBJ_pilotAttributeType,7L

#define LN_userClass            "userClass"
#define NID_userClass           465
#define OBJ_userClass           OBJ_pilotAttributeType,8L

#define SN_host         "host"
#define NID_host                466
#define OBJ_host                OBJ_pilotAttributeType,9L

#define SN_manager              "manager"
#define NID_manager             467
#define OBJ_manager             OBJ_pilotAttributeType,10L

#define LN_documentIdentifier           "documentIdentifier"
#define NID_documentIdentifier          468
#define OBJ_documentIdentifier          OBJ_pilotAttributeType,11L

#define LN_documentTitle                "documentTitle"
#define NID_documentTitle               469
#define OBJ_documentTitle               OBJ_pilotAttributeType,12L

#define LN_documentVersion              "documentVersion"
#define NID_documentVersion             470
#define OBJ_documentVersion             OBJ_pilotAttributeType,13L

#define LN_documentAuthor               "documentAuthor"
#define NID_documentAuthor              471
#define OBJ_documentAuthor              OBJ_pilotAttributeType,14L

#define LN_documentLocation             "documentLocation"
#define NID_documentLocation            472
#define OBJ_documentLocation            OBJ_pilotAttributeType,15L

#define LN_homeTelephoneNumber          "homeTelephoneNumber"
#define NID_homeTelephoneNumber         473
#define OBJ_homeTelephoneNumber         OBJ_pilotAttributeType,20L

#define SN_secretary            "secretary"
#define NID_secretary           474
#define OBJ_secretary           OBJ_pilotAttributeType,21L

#define LN_otherMailbox         "otherMailbox"
#define NID_otherMailbox                475
#define OBJ_otherMailbox                OBJ_pilotAttributeType,22L

#define LN_lastModifiedTime             "lastModifiedTime"
#define NID_lastModifiedTime            476
#define OBJ_lastModifiedTime            OBJ_pilotAttributeType,23L

#define LN_lastModifiedBy               "lastModifiedBy"
#define NID_lastModifiedBy              477
#define OBJ_lastModifiedBy              OBJ_pilotAttributeType,24L

#define SN_domainComponent              "DC"
#define LN_domainComponent              "domainComponent"
#define NID_domainComponent             391
#define OBJ_domainComponent             OBJ_pilotAttributeType,25L

#define LN_aRecord              "aRecord"
#define NID_aRecord             478
#define OBJ_aRecord             OBJ_pilotAttributeType,26L

#define LN_pilotAttributeType27         "pilotAttributeType27"
#define NID_pilotAttributeType27                479
#define OBJ_pilotAttributeType27                OBJ_pilotAttributeType,27L

#define LN_mXRecord             "mXRecord"
#define NID_mXRecord            480
#define OBJ_mXRecord            OBJ_pilotAttributeType,28L

#define LN_nSRecord             "nSRecord"
#define NID_nSRecord            481
#define OBJ_nSRecord            OBJ_pilotAttributeType,29L

#define LN_sOARecord            "sOARecord"
#define NID_sOARecord           482
#define OBJ_sOARecord           OBJ_pilotAttributeType,30L

#define LN_cNAMERecord          "cNAMERecord"
#define NID_cNAMERecord         483
#define OBJ_cNAMERecord         OBJ_pilotAttributeType,31L

#define LN_associatedDomain             "associatedDomain"
#define NID_associatedDomain            484
#define OBJ_associatedDomain            OBJ_pilotAttributeType,37L

#define LN_associatedName               "associatedName"
#define NID_associatedName              485
#define OBJ_associatedName              OBJ_pilotAttributeType,38L

#define LN_homePostalAddress            "homePostalAddress"
#define NID_homePostalAddress           486
#define OBJ_homePostalAddress           OBJ_pilotAttributeType,39L

#define LN_personalTitle                "personalTitle"
#define NID_personalTitle               487
#define OBJ_personalTitle               OBJ_pilotAttributeType,40L

#define LN_mobileTelephoneNumber                "mobileTelephoneNumber"
#define NID_mobileTelephoneNumber               488
#define OBJ_mobileTelephoneNumber               OBJ_pilotAttributeType,41L

#define LN_pagerTelephoneNumber         "pagerTelephoneNumber"
#define NID_pagerTelephoneNumber                489
#define OBJ_pagerTelephoneNumber                OBJ_pilotAttributeType,42L

#define LN_friendlyCountryName          "friendlyCountryName"
#define NID_friendlyCountryName         490
#define OBJ_friendlyCountryName         OBJ_pilotAttributeType,43L

#define LN_organizationalStatus         "organizationalStatus"
#define NID_organizationalStatus                491
#define OBJ_organizationalStatus                OBJ_pilotAttributeType,45L

#define LN_janetMailbox         "janetMailbox"
#define NID_janetMailbox                492
#define OBJ_janetMailbox                OBJ_pilotAttributeType,46L

#define LN_mailPreferenceOption         "mailPreferenceOption"
#define NID_mailPreferenceOption                493
#define OBJ_mailPreferenceOption                OBJ_pilotAttributeType,47L

#define LN_buildingName         "buildingName"
#define NID_buildingName                494
#define OBJ_buildingName                OBJ_pilotAttributeType,48L

#define LN_dSAQuality           "dSAQuality"
#define NID_dSAQuality          495
#define OBJ_dSAQuality          OBJ_pilotAttributeType,49L

#define LN_singleLevelQuality           "singleLevelQuality"
#define NID_singleLevelQuality          496
#define OBJ_singleLevelQuality          OBJ_pilotAttributeType,50L

#define LN_subtreeMinimumQuality                "subtreeMinimumQuality"
#define NID_subtreeMinimumQuality               497
#define OBJ_subtreeMinimumQuality               OBJ_pilotAttributeType,51L

#define LN_subtreeMaximumQuality                "subtreeMaximumQuality"
#define NID_subtreeMaximumQuality               498
#define OBJ_subtreeMaximumQuality               OBJ_pilotAttributeType,52L

#define LN_personalSignature            "personalSignature"
#define NID_personalSignature           499
#define OBJ_personalSignature           OBJ_pilotAttributeType,53L

#define LN_dITRedirect          "dITRedirect"
#define NID_dITRedirect         500
#define OBJ_dITRedirect         OBJ_pilotAttributeType,54L

#define SN_audio                "audio"
#define NID_audio               501
#define OBJ_audio               OBJ_pilotAttributeType,55L

#define LN_documentPublisher            "documentPublisher"
#define NID_documentPublisher           502
#define OBJ_documentPublisher           OBJ_pilotAttributeType,56L

#define SN_id_set               "id-set"
#define LN_id_set               "Secure Electronic Transactions"
#define NID_id_set              512
#define OBJ_id_set              OBJ_international_organizations,42L

#define SN_set_ctype            "set-ctype"
#define LN_set_ctype            "content types"
#define NID_set_ctype           513
#define OBJ_set_ctype           OBJ_id_set,0L

#define SN_set_msgExt           "set-msgExt"
#define LN_set_msgExt           "message extensions"
#define NID_set_msgExt          514
#define OBJ_set_msgExt          OBJ_id_set,1L

#define SN_set_attr             "set-attr"
#define NID_set_attr            515
#define OBJ_set_attr            OBJ_id_set,3L

#define SN_set_policy           "set-policy"
#define NID_set_policy          516
#define OBJ_set_policy          OBJ_id_set,5L

#define SN_set_certExt          "set-certExt"
#define LN_set_certExt          "certificate extensions"
#define NID_set_certExt         517
#define OBJ_set_certExt         OBJ_id_set,7L

#define SN_set_brand            "set-brand"
#define NID_set_brand           518
#define OBJ_set_brand           OBJ_id_set,8L

#define SN_setct_PANData                "setct-PANData"
#define NID_setct_PANData               519
#define OBJ_setct_PANData               OBJ_set_ctype,0L

#define SN_setct_PANToken               "setct-PANToken"
#define NID_setct_PANToken              520
#define OBJ_setct_PANToken              OBJ_set_ctype,1L

#define SN_setct_PANOnly                "setct-PANOnly"
#define NID_setct_PANOnly               521
#define OBJ_setct_PANOnly               OBJ_set_ctype,2L

#define SN_setct_OIData         "setct-OIData"
#define NID_setct_OIData                522
#define OBJ_setct_OIData                OBJ_set_ctype,3L

#define SN_setct_PI             "setct-PI"
#define NID_setct_PI            523
#define OBJ_setct_PI            OBJ_set_ctype,4L

#define SN_setct_PIData         "setct-PIData"
#define NID_setct_PIData                524
#define OBJ_setct_PIData                OBJ_set_ctype,5L

#define SN_setct_PIDataUnsigned         "setct-PIDataUnsigned"
#define NID_setct_PIDataUnsigned                525
#define OBJ_setct_PIDataUnsigned                OBJ_set_ctype,6L

#define SN_setct_HODInput               "setct-HODInput"
#define NID_setct_HODInput              526
#define OBJ_setct_HODInput              OBJ_set_ctype,7L

#define SN_setct_AuthResBaggage         "setct-AuthResBaggage"
#define NID_setct_AuthResBaggage                527
#define OBJ_setct_AuthResBaggage                OBJ_set_ctype,8L

#define SN_setct_AuthRevReqBaggage              "setct-AuthRevReqBaggage"
#define NID_setct_AuthRevReqBaggage             528
#define OBJ_setct_AuthRevReqBaggage             OBJ_set_ctype,9L

#define SN_setct_AuthRevResBaggage              "setct-AuthRevResBaggage"
#define NID_setct_AuthRevResBaggage             529
#define OBJ_setct_AuthRevResBaggage             OBJ_set_ctype,10L

#define SN_setct_CapTokenSeq            "setct-CapTokenSeq"
#define NID_setct_CapTokenSeq           530
#define OBJ_setct_CapTokenSeq           OBJ_set_ctype,11L

#define SN_setct_PInitResData           "setct-PInitResData"
#define NID_setct_PInitResData          531
#define OBJ_setct_PInitResData          OBJ_set_ctype,12L

#define SN_setct_PI_TBS         "setct-PI-TBS"
#define NID_setct_PI_TBS                532
#define OBJ_setct_PI_TBS                OBJ_set_ctype,13L

#define SN_setct_PResData               "setct-PResData"
#define NID_setct_PResData              533
#define OBJ_setct_PResData              OBJ_set_ctype,14L

#define SN_setct_AuthReqTBS             "setct-AuthReqTBS"
#define NID_setct_AuthReqTBS            534
#define OBJ_setct_AuthReqTBS            OBJ_set_ctype,16L

#define SN_setct_AuthResTBS             "setct-AuthResTBS"
#define NID_setct_AuthResTBS            535
#define OBJ_setct_AuthResTBS            OBJ_set_ctype,17L

#define SN_setct_AuthResTBSX            "setct-AuthResTBSX"
#define NID_setct_AuthResTBSX           536
#define OBJ_setct_AuthResTBSX           OBJ_set_ctype,18L

#define SN_setct_AuthTokenTBS           "setct-AuthTokenTBS"
#define NID_setct_AuthTokenTBS          537
#define OBJ_setct_AuthTokenTBS          OBJ_set_ctype,19L

#define SN_setct_CapTokenData           "setct-CapTokenData"
#define NID_setct_CapTokenData          538
#define OBJ_setct_CapTokenData          OBJ_set_ctype,20L

#define SN_setct_CapTokenTBS            "setct-CapTokenTBS"
#define NID_setct_CapTokenTBS           539
#define OBJ_setct_CapTokenTBS           OBJ_set_ctype,21L

#define SN_setct_AcqCardCodeMsg         "setct-AcqCardCodeMsg"
#define NID_setct_AcqCardCodeMsg                540
#define OBJ_setct_AcqCardCodeMsg                OBJ_set_ctype,22L

#define SN_setct_AuthRevReqTBS          "setct-AuthRevReqTBS"
#define NID_setct_AuthRevReqTBS         541
#define OBJ_setct_AuthRevReqTBS         OBJ_set_ctype,23L

#define SN_setct_AuthRevResData         "setct-AuthRevResData"
#define NID_setct_AuthRevResData                542
#define OBJ_setct_AuthRevResData                OBJ_set_ctype,24L

#define SN_setct_AuthRevResTBS          "setct-AuthRevResTBS"
#define NID_setct_AuthRevResTBS         543
#define OBJ_setct_AuthRevResTBS         OBJ_set_ctype,25L

#define SN_setct_CapReqTBS              "setct-CapReqTBS"
#define NID_setct_CapReqTBS             544
#define OBJ_setct_CapReqTBS             OBJ_set_ctype,26L

#define SN_setct_CapReqTBSX             "setct-CapReqTBSX"
#define NID_setct_CapReqTBSX            545
#define OBJ_setct_CapReqTBSX            OBJ_set_ctype,27L

#define SN_setct_CapResData             "setct-CapResData"
#define NID_setct_CapResData            546
#define OBJ_setct_CapResData            OBJ_set_ctype,28L

#define SN_setct_CapRevReqTBS           "setct-CapRevReqTBS"
#define NID_setct_CapRevReqTBS          547
#define OBJ_setct_CapRevReqTBS          OBJ_set_ctype,29L

#define SN_setct_CapRevReqTBSX          "setct-CapRevReqTBSX"
#define NID_setct_CapRevReqTBSX         548
#define OBJ_setct_CapRevReqTBSX         OBJ_set_ctype,30L

#define SN_setct_CapRevResData          "setct-CapRevResData"
#define NID_setct_CapRevResData         549
#define OBJ_setct_CapRevResData         OBJ_set_ctype,31L

#define SN_setct_CredReqTBS             "setct-CredReqTBS"
#define NID_setct_CredReqTBS            550
#define OBJ_setct_CredReqTBS            OBJ_set_ctype,32L

#define SN_setct_CredReqTBSX            "setct-CredReqTBSX"
#define NID_setct_CredReqTBSX           551
#define OBJ_setct_CredReqTBSX           OBJ_set_ctype,33L

#define SN_setct_CredResData            "setct-CredResData"
#define NID_setct_CredResData           552
#define OBJ_setct_CredResData           OBJ_set_ctype,34L

#define SN_setct_CredRevReqTBS          "setct-CredRevReqTBS"
#define NID_setct_CredRevReqTBS         553
#define OBJ_setct_CredRevReqTBS         OBJ_set_ctype,35L

#define SN_setct_CredRevReqTBSX         "setct-CredRevReqTBSX"
#define NID_setct_CredRevReqTBSX                554
#define OBJ_setct_CredRevReqTBSX                OBJ_set_ctype,36L

#define SN_setct_CredRevResData         "setct-CredRevResData"
#define NID_setct_CredRevResData                555
#define OBJ_setct_CredRevResData                OBJ_set_ctype,37L

#define SN_setct_PCertReqData           "setct-PCertReqData"
#define NID_setct_PCertReqData          556
#define OBJ_setct_PCertReqData          OBJ_set_ctype,38L

#define SN_setct_PCertResTBS            "setct-PCertResTBS"
#define NID_setct_PCertResTBS           557
#define OBJ_setct_PCertResTBS           OBJ_set_ctype,39L

#define SN_setct_BatchAdminReqData              "setct-BatchAdminReqData"
#define NID_setct_BatchAdminReqData             558
#define OBJ_setct_BatchAdminReqData             OBJ_set_ctype,40L

#define SN_setct_BatchAdminResData              "setct-BatchAdminResData"
#define NID_setct_BatchAdminResData             559
#define OBJ_setct_BatchAdminResData             OBJ_set_ctype,41L

#define SN_setct_CardCInitResTBS                "setct-CardCInitResTBS"
#define NID_setct_CardCInitResTBS               560
#define OBJ_setct_CardCInitResTBS               OBJ_set_ctype,42L

#define SN_setct_MeAqCInitResTBS                "setct-MeAqCInitResTBS"
#define NID_setct_MeAqCInitResTBS               561
#define OBJ_setct_MeAqCInitResTBS               OBJ_set_ctype,43L

#define SN_setct_RegFormResTBS          "setct-RegFormResTBS"
#define NID_setct_RegFormResTBS         562
#define OBJ_setct_RegFormResTBS         OBJ_set_ctype,44L

#define SN_setct_CertReqData            "setct-CertReqData"
#define NID_setct_CertReqData           563
#define OBJ_setct_CertReqData           OBJ_set_ctype,45L

#define SN_setct_CertReqTBS             "setct-CertReqTBS"
#define NID_setct_CertReqTBS            564
#define OBJ_setct_CertReqTBS            OBJ_set_ctype,46L

#define SN_setct_CertResData            "setct-CertResData"
#define NID_setct_CertResData           565
#define OBJ_setct_CertResData           OBJ_set_ctype,47L

#define SN_setct_CertInqReqTBS          "setct-CertInqReqTBS"
#define NID_setct_CertInqReqTBS         566
#define OBJ_setct_CertInqReqTBS         OBJ_set_ctype,48L

#define SN_setct_ErrorTBS               "setct-ErrorTBS"
#define NID_setct_ErrorTBS              567
#define OBJ_setct_ErrorTBS              OBJ_set_ctype,49L

#define SN_setct_PIDualSignedTBE                "setct-PIDualSignedTBE"
#define NID_setct_PIDualSignedTBE               568
#define OBJ_setct_PIDualSignedTBE               OBJ_set_ctype,50L

#define SN_setct_PIUnsignedTBE          "setct-PIUnsignedTBE"
#define NID_setct_PIUnsignedTBE         569
#define OBJ_setct_PIUnsignedTBE         OBJ_set_ctype,51L

#define SN_setct_AuthReqTBE             "setct-AuthReqTBE"
#define NID_setct_AuthReqTBE            570
#define OBJ_setct_AuthReqTBE            OBJ_set_ctype,52L

#define SN_setct_AuthResTBE             "setct-AuthResTBE"
#define NID_setct_AuthResTBE            571
#define OBJ_setct_AuthResTBE            OBJ_set_ctype,53L

#define SN_setct_AuthResTBEX            "setct-AuthResTBEX"
#define NID_setct_AuthResTBEX           572
#define OBJ_setct_AuthResTBEX           OBJ_set_ctype,54L

#define SN_setct_AuthTokenTBE           "setct-AuthTokenTBE"
#define NID_setct_AuthTokenTBE          573
#define OBJ_setct_AuthTokenTBE          OBJ_set_ctype,55L

#define SN_setct_CapTokenTBE            "setct-CapTokenTBE"
#define NID_setct_CapTokenTBE           574
#define OBJ_setct_CapTokenTBE           OBJ_set_ctype,56L

#define SN_setct_CapTokenTBEX           "setct-CapTokenTBEX"
#define NID_setct_CapTokenTBEX          575
#define OBJ_setct_CapTokenTBEX          OBJ_set_ctype,57L

#define SN_setct_AcqCardCodeMsgTBE              "setct-AcqCardCodeMsgTBE"
#define NID_setct_AcqCardCodeMsgTBE             576
#define OBJ_setct_AcqCardCodeMsgTBE             OBJ_set_ctype,58L

#define SN_setct_AuthRevReqTBE          "setct-AuthRevReqTBE"
#define NID_setct_AuthRevReqTBE         577
#define OBJ_setct_AuthRevReqTBE         OBJ_set_ctype,59L

#define SN_setct_AuthRevResTBE          "setct-AuthRevResTBE"
#define NID_setct_AuthRevResTBE         578
#define OBJ_setct_AuthRevResTBE         OBJ_set_ctype,60L

#define SN_setct_AuthRevResTBEB         "setct-AuthRevResTBEB"
#define NID_setct_AuthRevResTBEB                579
#define OBJ_setct_AuthRevResTBEB                OBJ_set_ctype,61L

#define SN_setct_CapReqTBE              "setct-CapReqTBE"
#define NID_setct_CapReqTBE             580
#define OBJ_setct_CapReqTBE             OBJ_set_ctype,62L

#define SN_setct_CapReqTBEX             "setct-CapReqTBEX"
#define NID_setct_CapReqTBEX            581
#define OBJ_setct_CapReqTBEX            OBJ_set_ctype,63L

#define SN_setct_CapResTBE              "setct-CapResTBE"
#define NID_setct_CapResTBE             582
#define OBJ_setct_CapResTBE             OBJ_set_ctype,64L

#define SN_setct_CapRevReqTBE           "setct-CapRevReqTBE"
#define NID_setct_CapRevReqTBE          583
#define OBJ_setct_CapRevReqTBE          OBJ_set_ctype,65L

#define SN_setct_CapRevReqTBEX          "setct-CapRevReqTBEX"
#define NID_setct_CapRevReqTBEX         584
#define OBJ_setct_CapRevReqTBEX         OBJ_set_ctype,66L

#define SN_setct_CapRevResTBE           "setct-CapRevResTBE"
#define NID_setct_CapRevResTBE          585
#define OBJ_setct_CapRevResTBE          OBJ_set_ctype,67L

#define SN_setct_CredReqTBE             "setct-CredReqTBE"
#define NID_setct_CredReqTBE            586
#define OBJ_setct_CredReqTBE            OBJ_set_ctype,68L

#define SN_setct_CredReqTBEX            "setct-CredReqTBEX"
#define NID_setct_CredReqTBEX           587
#define OBJ_setct_CredReqTBEX           OBJ_set_ctype,69L

#define SN_setct_CredResTBE             "setct-CredResTBE"
#define NID_setct_CredResTBE            588
#define OBJ_setct_CredResTBE            OBJ_set_ctype,70L

#define SN_setct_CredRevReqTBE          "setct-CredRevReqTBE"
#define NID_setct_CredRevReqTBE         589
#define OBJ_setct_CredRevReqTBE         OBJ_set_ctype,71L

#define SN_setct_CredRevReqTBEX         "setct-CredRevReqTBEX"
#define NID_setct_CredRevReqTBEX                590
#define OBJ_setct_CredRevReqTBEX                OBJ_set_ctype,72L

#define SN_setct_CredRevResTBE          "setct-CredRevResTBE"
#define NID_setct_CredRevResTBE         591
#define OBJ_setct_CredRevResTBE         OBJ_set_ctype,73L

#define SN_setct_BatchAdminReqTBE               "setct-BatchAdminReqTBE"
#define NID_setct_BatchAdminReqTBE              592
#define OBJ_setct_BatchAdminReqTBE              OBJ_set_ctype,74L

#define SN_setct_BatchAdminResTBE               "setct-BatchAdminResTBE"
#define NID_setct_BatchAdminResTBE              593
#define OBJ_setct_BatchAdminResTBE              OBJ_set_ctype,75L

#define SN_setct_RegFormReqTBE          "setct-RegFormReqTBE"
#define NID_setct_RegFormReqTBE         594
#define OBJ_setct_RegFormReqTBE         OBJ_set_ctype,76L

#define SN_setct_CertReqTBE             "setct-CertReqTBE"
#define NID_setct_CertReqTBE            595
#define OBJ_setct_CertReqTBE            OBJ_set_ctype,77L

#define SN_setct_CertReqTBEX            "setct-CertReqTBEX"
#define NID_setct_CertReqTBEX           596
#define OBJ_setct_CertReqTBEX           OBJ_set_ctype,78L

#define SN_setct_CertResTBE             "setct-CertResTBE"
#define NID_setct_CertResTBE            597
#define OBJ_setct_CertResTBE            OBJ_set_ctype,79L

#define SN_setct_CRLNotificationTBS             "setct-CRLNotificationTBS"
#define NID_setct_CRLNotificationTBS            598
#define OBJ_setct_CRLNotificationTBS            OBJ_set_ctype,80L

#define SN_setct_CRLNotificationResTBS          "setct-CRLNotificationResTBS"
#define NID_setct_CRLNotificationResTBS         599
#define OBJ_setct_CRLNotificationResTBS         OBJ_set_ctype,81L

#define SN_setct_BCIDistributionTBS             "setct-BCIDistributionTBS"
#define NID_setct_BCIDistributionTBS            600
#define OBJ_setct_BCIDistributionTBS            OBJ_set_ctype,82L

#define SN_setext_genCrypt              "setext-genCrypt"
#define LN_setext_genCrypt              "generic cryptogram"
#define NID_setext_genCrypt             601
#define OBJ_setext_genCrypt             OBJ_set_msgExt,1L

#define SN_setext_miAuth                "setext-miAuth"
#define LN_setext_miAuth                "merchant initiated auth"
#define NID_setext_miAuth               602
#define OBJ_setext_miAuth               OBJ_set_msgExt,3L

#define SN_setext_pinSecure             "setext-pinSecure"
#define NID_setext_pinSecure            603
#define OBJ_setext_pinSecure            OBJ_set_msgExt,4L

#define SN_setext_pinAny                "setext-pinAny"
#define NID_setext_pinAny               604
#define OBJ_setext_pinAny               OBJ_set_msgExt,5L

#define SN_setext_track2                "setext-track2"
#define NID_setext_track2               605
#define OBJ_setext_track2               OBJ_set_msgExt,7L

#define SN_setext_cv            "setext-cv"
#define LN_setext_cv            "additional verification"
#define NID_setext_cv           606
#define OBJ_setext_cv           OBJ_set_msgExt,8L

#define SN_set_policy_root              "set-policy-root"
#define NID_set_policy_root             607
#define OBJ_set_policy_root             OBJ_set_policy,0L

#define SN_setCext_hashedRoot           "setCext-hashedRoot"
#define NID_setCext_hashedRoot          608
#define OBJ_setCext_hashedRoot          OBJ_set_certExt,0L

#define SN_setCext_certType             "setCext-certType"
#define NID_setCext_certType            609
#define OBJ_setCext_certType            OBJ_set_certExt,1L

#define SN_setCext_merchData            "setCext-merchData"
#define NID_setCext_merchData           610
#define OBJ_setCext_merchData           OBJ_set_certExt,2L

#define SN_setCext_cCertRequired                "setCext-cCertRequired"
#define NID_setCext_cCertRequired               611
#define OBJ_setCext_cCertRequired               OBJ_set_certExt,3L

#define SN_setCext_tunneling            "setCext-tunneling"
#define NID_setCext_tunneling           612
#define OBJ_setCext_tunneling           OBJ_set_certExt,4L

#define SN_setCext_setExt               "setCext-setExt"
#define NID_setCext_setExt              613
#define OBJ_setCext_setExt              OBJ_set_certExt,5L

#define SN_setCext_setQualf             "setCext-setQualf"
#define NID_setCext_setQualf            614
#define OBJ_setCext_setQualf            OBJ_set_certExt,6L

#define SN_setCext_PGWYcapabilities             "setCext-PGWYcapabilities"
#define NID_setCext_PGWYcapabilities            615
#define OBJ_setCext_PGWYcapabilities            OBJ_set_certExt,7L

#define SN_setCext_TokenIdentifier              "setCext-TokenIdentifier"
#define NID_setCext_TokenIdentifier             616
#define OBJ_setCext_TokenIdentifier             OBJ_set_certExt,8L

#define SN_setCext_Track2Data           "setCext-Track2Data"
#define NID_setCext_Track2Data          617
#define OBJ_setCext_Track2Data          OBJ_set_certExt,9L

#define SN_setCext_TokenType            "setCext-TokenType"
#define NID_setCext_TokenType           618
#define OBJ_setCext_TokenType           OBJ_set_certExt,10L

#define SN_setCext_IssuerCapabilities           "setCext-IssuerCapabilities"
#define NID_setCext_IssuerCapabilities          619
#define OBJ_setCext_IssuerCapabilities          OBJ_set_certExt,11L

#define SN_setAttr_Cert         "setAttr-Cert"
#define NID_setAttr_Cert                620
#define OBJ_setAttr_Cert                OBJ_set_attr,0L

#define SN_setAttr_PGWYcap              "setAttr-PGWYcap"
#define LN_setAttr_PGWYcap              "payment gateway capabilities"
#define NID_setAttr_PGWYcap             621
#define OBJ_setAttr_PGWYcap             OBJ_set_attr,1L

#define SN_setAttr_TokenType            "setAttr-TokenType"
#define NID_setAttr_TokenType           622
#define OBJ_setAttr_TokenType           OBJ_set_attr,2L

#define SN_setAttr_IssCap               "setAttr-IssCap"
#define LN_setAttr_IssCap               "issuer capabilities"
#define NID_setAttr_IssCap              623
#define OBJ_setAttr_IssCap              OBJ_set_attr,3L

#define SN_set_rootKeyThumb             "set-rootKeyThumb"
#define NID_set_rootKeyThumb            624
#define OBJ_set_rootKeyThumb            OBJ_setAttr_Cert,0L

#define SN_set_addPolicy                "set-addPolicy"
#define NID_set_addPolicy               625
#define OBJ_set_addPolicy               OBJ_setAttr_Cert,1L

#define SN_setAttr_Token_EMV            "setAttr-Token-EMV"
#define NID_setAttr_Token_EMV           626
#define OBJ_setAttr_Token_EMV           OBJ_setAttr_TokenType,1L

#define SN_setAttr_Token_B0Prime                "setAttr-Token-B0Prime"
#define NID_setAttr_Token_B0Prime               627
#define OBJ_setAttr_Token_B0Prime               OBJ_setAttr_TokenType,2L

#define SN_setAttr_IssCap_CVM           "setAttr-IssCap-CVM"
#define NID_setAttr_IssCap_CVM          628
#define OBJ_setAttr_IssCap_CVM          OBJ_setAttr_IssCap,3L

#define SN_setAttr_IssCap_T2            "setAttr-IssCap-T2"
#define NID_setAttr_IssCap_T2           629
#define OBJ_setAttr_IssCap_T2           OBJ_setAttr_IssCap,4L

#define SN_setAttr_IssCap_Sig           "setAttr-IssCap-Sig"
#define NID_setAttr_IssCap_Sig          630
#define OBJ_setAttr_IssCap_Sig          OBJ_setAttr_IssCap,5L

#define SN_setAttr_GenCryptgrm          "setAttr-GenCryptgrm"
#define LN_setAttr_GenCryptgrm          "generate cryptogram"
#define NID_setAttr_GenCryptgrm         631
#define OBJ_setAttr_GenCryptgrm         OBJ_setAttr_IssCap_CVM,1L

#define SN_setAttr_T2Enc                "setAttr-T2Enc"
#define LN_setAttr_T2Enc                "encrypted track 2"
#define NID_setAttr_T2Enc               632
#define OBJ_setAttr_T2Enc               OBJ_setAttr_IssCap_T2,1L

#define SN_setAttr_T2cleartxt           "setAttr-T2cleartxt"
#define LN_setAttr_T2cleartxt           "cleartext track 2"
#define NID_setAttr_T2cleartxt          633
#define OBJ_setAttr_T2cleartxt          OBJ_setAttr_IssCap_T2,2L

#define SN_setAttr_TokICCsig            "setAttr-TokICCsig"
#define LN_setAttr_TokICCsig            "ICC or token signature"
#define NID_setAttr_TokICCsig           634
#define OBJ_setAttr_TokICCsig           OBJ_setAttr_IssCap_Sig,1L

#define SN_setAttr_SecDevSig            "setAttr-SecDevSig"
#define LN_setAttr_SecDevSig            "secure device signature"
#define NID_setAttr_SecDevSig           635
#define OBJ_setAttr_SecDevSig           OBJ_setAttr_IssCap_Sig,2L

#define SN_set_brand_IATA_ATA           "set-brand-IATA-ATA"
#define NID_set_brand_IATA_ATA          636
#define OBJ_set_brand_IATA_ATA          OBJ_set_brand,1L

#define SN_set_brand_Diners             "set-brand-Diners"
#define NID_set_brand_Diners            637
#define OBJ_set_brand_Diners            OBJ_set_brand,30L

#define SN_set_brand_AmericanExpress            "set-brand-AmericanExpress"
#define NID_set_brand_AmericanExpress           638
#define OBJ_set_brand_AmericanExpress           OBJ_set_brand,34L

#define SN_set_brand_JCB                "set-brand-JCB"
#define NID_set_brand_JCB               639
#define OBJ_set_brand_JCB               OBJ_set_brand,35L

#define SN_set_brand_Visa               "set-brand-Visa"
#define NID_set_brand_Visa              640
#define OBJ_set_brand_Visa              OBJ_set_brand,4L

#define SN_set_brand_MasterCard         "set-brand-MasterCard"
#define NID_set_brand_MasterCard                641
#define OBJ_set_brand_MasterCard                OBJ_set_brand,5L

#define SN_set_brand_Novus              "set-brand-Novus"
#define NID_set_brand_Novus             642
#define OBJ_set_brand_Novus             OBJ_set_brand,6011L

#define SN_des_cdmf             "DES-CDMF"
#define LN_des_cdmf             "des-cdmf"
#define NID_des_cdmf            643
#define OBJ_des_cdmf            OBJ_rsadsi,3L,10L

#define SN_rsaOAEPEncryptionSET         "rsaOAEPEncryptionSET"
#define NID_rsaOAEPEncryptionSET                644
#define OBJ_rsaOAEPEncryptionSET                OBJ_rsadsi,1L,1L,6L

#define SN_ipsec3               "Oakley-EC2N-3"
#define LN_ipsec3               "ipsec3"
#define NID_ipsec3              749

#define SN_ipsec4               "Oakley-EC2N-4"
#define LN_ipsec4               "ipsec4"
#define NID_ipsec4              750

#define SN_whirlpool            "whirlpool"
#define NID_whirlpool           804
#define OBJ_whirlpool           OBJ_iso,0L,10118L,3L,0L,55L

#define SN_cryptopro            "cryptopro"
#define NID_cryptopro           805
#define OBJ_cryptopro           OBJ_member_body,643L,2L,2L

#define SN_cryptocom            "cryptocom"
#define NID_cryptocom           806
#define OBJ_cryptocom           OBJ_member_body,643L,2L,9L

#define SN_id_GostR3411_94_with_GostR3410_2001          "id-GostR3411-94-with-GostR3410-2001"
#define LN_id_GostR3411_94_with_GostR3410_2001          "GOST R 34.11-94 with GOST R 34.10-2001"
#define NID_id_GostR3411_94_with_GostR3410_2001         807
#define OBJ_id_GostR3411_94_with_GostR3410_2001         OBJ_cryptopro,3L

#define SN_id_GostR3411_94_with_GostR3410_94            "id-GostR3411-94-with-GostR3410-94"
#define LN_id_GostR3411_94_with_GostR3410_94            "GOST R 34.11-94 with GOST R 34.10-94"
#define NID_id_GostR3411_94_with_GostR3410_94           808
#define OBJ_id_GostR3411_94_with_GostR3410_94           OBJ_cryptopro,4L

#define SN_id_GostR3411_94              "md_gost94"
#define LN_id_GostR3411_94              "GOST R 34.11-94"
#define NID_id_GostR3411_94             809
#define OBJ_id_GostR3411_94             OBJ_cryptopro,9L

#define SN_id_HMACGostR3411_94          "id-HMACGostR3411-94"
#define LN_id_HMACGostR3411_94          "HMAC GOST 34.11-94"
#define NID_id_HMACGostR3411_94         810
#define OBJ_id_HMACGostR3411_94         OBJ_cryptopro,10L

#define SN_id_GostR3410_2001            "gost2001"
#define LN_id_GostR3410_2001            "GOST R 34.10-2001"
#define NID_id_GostR3410_2001           811
#define OBJ_id_GostR3410_2001           OBJ_cryptopro,19L

#define SN_id_GostR3410_94              "gost94"
#define LN_id_GostR3410_94              "GOST R 34.10-94"
#define NID_id_GostR3410_94             812
#define OBJ_id_GostR3410_94             OBJ_cryptopro,20L

#define SN_id_Gost28147_89              "gost89"
#define LN_id_Gost28147_89              "GOST 28147-89"
#define NID_id_Gost28147_89             813
#define OBJ_id_Gost28147_89             OBJ_cryptopro,21L

#define SN_gost89_cnt           "gost89-cnt"
#define NID_gost89_cnt          814

#define SN_id_Gost28147_89_MAC          "gost-mac"
#define LN_id_Gost28147_89_MAC          "GOST 28147-89 MAC"
#define NID_id_Gost28147_89_MAC         815
#define OBJ_id_Gost28147_89_MAC         OBJ_cryptopro,22L

#define SN_id_GostR3411_94_prf          "prf-gostr3411-94"
#define LN_id_GostR3411_94_prf          "GOST R 34.11-94 PRF"
#define NID_id_GostR3411_94_prf         816
#define OBJ_id_GostR3411_94_prf         OBJ_cryptopro,23L

#define SN_id_GostR3410_2001DH          "id-GostR3410-2001DH"
#define LN_id_GostR3410_2001DH          "GOST R 34.10-2001 DH"
#define NID_id_GostR3410_2001DH         817
#define OBJ_id_GostR3410_2001DH         OBJ_cryptopro,98L

#define SN_id_GostR3410_94DH            "id-GostR3410-94DH"
#define LN_id_GostR3410_94DH            "GOST R 34.10-94 DH"
#define NID_id_GostR3410_94DH           818
#define OBJ_id_GostR3410_94DH           OBJ_cryptopro,99L

#define SN_id_Gost28147_89_CryptoPro_KeyMeshing         "id-Gost28147-89-CryptoPro-KeyMeshing"
#define NID_id_Gost28147_89_CryptoPro_KeyMeshing                819
#define OBJ_id_Gost28147_89_CryptoPro_KeyMeshing                OBJ_cryptopro,14L,1L

#define SN_id_Gost28147_89_None_KeyMeshing              "id-Gost28147-89-None-KeyMeshing"
#define NID_id_Gost28147_89_None_KeyMeshing             820
#define OBJ_id_Gost28147_89_None_KeyMeshing             OBJ_cryptopro,14L,0L

#define SN_id_GostR3411_94_TestParamSet         "id-GostR3411-94-TestParamSet"
#define NID_id_GostR3411_94_TestParamSet                821
#define OBJ_id_GostR3411_94_TestParamSet                OBJ_cryptopro,30L,0L

#define SN_id_GostR3411_94_CryptoProParamSet            "id-GostR3411-94-CryptoProParamSet"
#define NID_id_GostR3411_94_CryptoProParamSet           822
#define OBJ_id_GostR3411_94_CryptoProParamSet           OBJ_cryptopro,30L,1L

#define SN_id_Gost28147_89_TestParamSet         "id-Gost28147-89-TestParamSet"
#define NID_id_Gost28147_89_TestParamSet                823
#define OBJ_id_Gost28147_89_TestParamSet                OBJ_cryptopro,31L,0L

#define SN_id_Gost28147_89_CryptoPro_A_ParamSet         "id-Gost28147-89-CryptoPro-A-ParamSet"
#define NID_id_Gost28147_89_CryptoPro_A_ParamSet                824
#define OBJ_id_Gost28147_89_CryptoPro_A_ParamSet                OBJ_cryptopro,31L,1L

#define SN_id_Gost28147_89_CryptoPro_B_ParamSet         "id-Gost28147-89-CryptoPro-B-ParamSet"
#define NID_id_Gost28147_89_CryptoPro_B_ParamSet                825
#define OBJ_id_Gost28147_89_CryptoPro_B_ParamSet                OBJ_cryptopro,31L,2L

#define SN_id_Gost28147_89_CryptoPro_C_ParamSet         "id-Gost28147-89-CryptoPro-C-ParamSet"
#define NID_id_Gost28147_89_CryptoPro_C_ParamSet                826
#define OBJ_id_Gost28147_89_CryptoPro_C_ParamSet                OBJ_cryptopro,31L,3L

#define SN_id_Gost28147_89_CryptoPro_D_ParamSet         "id-Gost28147-89-CryptoPro-D-ParamSet"
#define NID_id_Gost28147_89_CryptoPro_D_ParamSet                827
#define OBJ_id_Gost28147_89_CryptoPro_D_ParamSet                OBJ_cryptopro,31L,4L

#define SN_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet         "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet"
#define NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet                828
#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet                OBJ_cryptopro,31L,5L

#define SN_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet         "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet"
#define NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet                829
#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet                OBJ_cryptopro,31L,6L

#define SN_id_Gost28147_89_CryptoPro_RIC_1_ParamSet             "id-Gost28147-89-CryptoPro-RIC-1-ParamSet"
#define NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet            830
#define OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet            OBJ_cryptopro,31L,7L

#define SN_id_GostR3410_94_TestParamSet         "id-GostR3410-94-TestParamSet"
#define NID_id_GostR3410_94_TestParamSet                831
#define OBJ_id_GostR3410_94_TestParamSet                OBJ_cryptopro,32L,0L

#define SN_id_GostR3410_94_CryptoPro_A_ParamSet         "id-GostR3410-94-CryptoPro-A-ParamSet"
#define NID_id_GostR3410_94_CryptoPro_A_ParamSet                832
#define OBJ_id_GostR3410_94_CryptoPro_A_ParamSet                OBJ_cryptopro,32L,2L

#define SN_id_GostR3410_94_CryptoPro_B_ParamSet         "id-GostR3410-94-CryptoPro-B-ParamSet"
#define NID_id_GostR3410_94_CryptoPro_B_ParamSet                833
#define OBJ_id_GostR3410_94_CryptoPro_B_ParamSet                OBJ_cryptopro,32L,3L

#define SN_id_GostR3410_94_CryptoPro_C_ParamSet         "id-GostR3410-94-CryptoPro-C-ParamSet"
#define NID_id_GostR3410_94_CryptoPro_C_ParamSet                834
#define OBJ_id_GostR3410_94_CryptoPro_C_ParamSet                OBJ_cryptopro,32L,4L

#define SN_id_GostR3410_94_CryptoPro_D_ParamSet         "id-GostR3410-94-CryptoPro-D-ParamSet"
#define NID_id_GostR3410_94_CryptoPro_D_ParamSet                835
#define OBJ_id_GostR3410_94_CryptoPro_D_ParamSet                OBJ_cryptopro,32L,5L

#define SN_id_GostR3410_94_CryptoPro_XchA_ParamSet              "id-GostR3410-94-CryptoPro-XchA-ParamSet"
#define NID_id_GostR3410_94_CryptoPro_XchA_ParamSet             836
#define OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet             OBJ_cryptopro,33L,1L

#define SN_id_GostR3410_94_CryptoPro_XchB_ParamSet              "id-GostR3410-94-CryptoPro-XchB-ParamSet"
#define NID_id_GostR3410_94_CryptoPro_XchB_ParamSet             837
#define OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet             OBJ_cryptopro,33L,2L

#define SN_id_GostR3410_94_CryptoPro_XchC_ParamSet              "id-GostR3410-94-CryptoPro-XchC-ParamSet"
#define NID_id_GostR3410_94_CryptoPro_XchC_ParamSet             838
#define OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet             OBJ_cryptopro,33L,3L

#define SN_id_GostR3410_2001_TestParamSet               "id-GostR3410-2001-TestParamSet"
#define NID_id_GostR3410_2001_TestParamSet              839
#define OBJ_id_GostR3410_2001_TestParamSet              OBJ_cryptopro,35L,0L

#define SN_id_GostR3410_2001_CryptoPro_A_ParamSet               "id-GostR3410-2001-CryptoPro-A-ParamSet"
#define NID_id_GostR3410_2001_CryptoPro_A_ParamSet              840
#define OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet              OBJ_cryptopro,35L,1L

#define SN_id_GostR3410_2001_CryptoPro_B_ParamSet               "id-GostR3410-2001-CryptoPro-B-ParamSet"
#define NID_id_GostR3410_2001_CryptoPro_B_ParamSet              841
#define OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet              OBJ_cryptopro,35L,2L

#define SN_id_GostR3410_2001_CryptoPro_C_ParamSet               "id-GostR3410-2001-CryptoPro-C-ParamSet"
#define NID_id_GostR3410_2001_CryptoPro_C_ParamSet              842
#define OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet              OBJ_cryptopro,35L,3L

#define SN_id_GostR3410_2001_CryptoPro_XchA_ParamSet            "id-GostR3410-2001-CryptoPro-XchA-ParamSet"
#define NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet           843
#define OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet           OBJ_cryptopro,36L,0L

#define SN_id_GostR3410_2001_CryptoPro_XchB_ParamSet            "id-GostR3410-2001-CryptoPro-XchB-ParamSet"
#define NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet           844
#define OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet           OBJ_cryptopro,36L,1L

#define SN_id_GostR3410_94_a            "id-GostR3410-94-a"
#define NID_id_GostR3410_94_a           845
#define OBJ_id_GostR3410_94_a           OBJ_id_GostR3410_94,1L

#define SN_id_GostR3410_94_aBis         "id-GostR3410-94-aBis"
#define NID_id_GostR3410_94_aBis                846
#define OBJ_id_GostR3410_94_aBis                OBJ_id_GostR3410_94,2L

#define SN_id_GostR3410_94_b            "id-GostR3410-94-b"
#define NID_id_GostR3410_94_b           847
#define OBJ_id_GostR3410_94_b           OBJ_id_GostR3410_94,3L

#define SN_id_GostR3410_94_bBis         "id-GostR3410-94-bBis"
#define NID_id_GostR3410_94_bBis                848
#define OBJ_id_GostR3410_94_bBis                OBJ_id_GostR3410_94,4L

#define SN_id_Gost28147_89_cc           "id-Gost28147-89-cc"
#define LN_id_Gost28147_89_cc           "GOST 28147-89 Cryptocom ParamSet"
#define NID_id_Gost28147_89_cc          849
#define OBJ_id_Gost28147_89_cc          OBJ_cryptocom,1L,6L,1L

#define SN_id_GostR3410_94_cc           "gost94cc"
#define LN_id_GostR3410_94_cc           "GOST 34.10-94 Cryptocom"
#define NID_id_GostR3410_94_cc          850
#define OBJ_id_GostR3410_94_cc          OBJ_cryptocom,1L,5L,3L

#define SN_id_GostR3410_2001_cc         "gost2001cc"
#define LN_id_GostR3410_2001_cc         "GOST 34.10-2001 Cryptocom"
#define NID_id_GostR3410_2001_cc                851
#define OBJ_id_GostR3410_2001_cc                OBJ_cryptocom,1L,5L,4L

#define SN_id_GostR3411_94_with_GostR3410_94_cc         "id-GostR3411-94-with-GostR3410-94-cc"
#define LN_id_GostR3411_94_with_GostR3410_94_cc         "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom"
#define NID_id_GostR3411_94_with_GostR3410_94_cc                852
#define OBJ_id_GostR3411_94_with_GostR3410_94_cc                OBJ_cryptocom,1L,3L,3L

#define SN_id_GostR3411_94_with_GostR3410_2001_cc               "id-GostR3411-94-with-GostR3410-2001-cc"
#define LN_id_GostR3411_94_with_GostR3410_2001_cc               "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom"
#define NID_id_GostR3411_94_with_GostR3410_2001_cc              853
#define OBJ_id_GostR3411_94_with_GostR3410_2001_cc              OBJ_cryptocom,1L,3L,4L

#define SN_id_GostR3410_2001_ParamSet_cc                "id-GostR3410-2001-ParamSet-cc"
#define LN_id_GostR3410_2001_ParamSet_cc                "GOST R 3410-2001 Parameter Set Cryptocom"
#define NID_id_GostR3410_2001_ParamSet_cc               854
#define OBJ_id_GostR3410_2001_ParamSet_cc               OBJ_cryptocom,1L,8L,1L

#define SN_camellia_128_cbc             "CAMELLIA-128-CBC"
#define LN_camellia_128_cbc             "camellia-128-cbc"
#define NID_camellia_128_cbc            751
#define OBJ_camellia_128_cbc            1L,2L,392L,200011L,61L,1L,1L,1L,2L

#define SN_camellia_192_cbc             "CAMELLIA-192-CBC"
#define LN_camellia_192_cbc             "camellia-192-cbc"
#define NID_camellia_192_cbc            752
#define OBJ_camellia_192_cbc            1L,2L,392L,200011L,61L,1L,1L,1L,3L

#define SN_camellia_256_cbc             "CAMELLIA-256-CBC"
#define LN_camellia_256_cbc             "camellia-256-cbc"
#define NID_camellia_256_cbc            753
#define OBJ_camellia_256_cbc            1L,2L,392L,200011L,61L,1L,1L,1L,4L

#define SN_id_camellia128_wrap          "id-camellia128-wrap"
#define NID_id_camellia128_wrap         907
#define OBJ_id_camellia128_wrap         1L,2L,392L,200011L,61L,1L,1L,3L,2L

#define SN_id_camellia192_wrap          "id-camellia192-wrap"
#define NID_id_camellia192_wrap         908
#define OBJ_id_camellia192_wrap         1L,2L,392L,200011L,61L,1L,1L,3L,3L

#define SN_id_camellia256_wrap          "id-camellia256-wrap"
#define NID_id_camellia256_wrap         909
#define OBJ_id_camellia256_wrap         1L,2L,392L,200011L,61L,1L,1L,3L,4L

#define OBJ_ntt_ds              0L,3L,4401L,5L

#define OBJ_camellia            OBJ_ntt_ds,3L,1L,9L

#define SN_camellia_128_ecb             "CAMELLIA-128-ECB"
#define LN_camellia_128_ecb             "camellia-128-ecb"
#define NID_camellia_128_ecb            754
#define OBJ_camellia_128_ecb            OBJ_camellia,1L

#define SN_camellia_128_ofb128          "CAMELLIA-128-OFB"
#define LN_camellia_128_ofb128          "camellia-128-ofb"
#define NID_camellia_128_ofb128         766
#define OBJ_camellia_128_ofb128         OBJ_camellia,3L

#define SN_camellia_128_cfb128          "CAMELLIA-128-CFB"
#define LN_camellia_128_cfb128          "camellia-128-cfb"
#define NID_camellia_128_cfb128         757
#define OBJ_camellia_128_cfb128         OBJ_camellia,4L

#define SN_camellia_192_ecb             "CAMELLIA-192-ECB"
#define LN_camellia_192_ecb             "camellia-192-ecb"
#define NID_camellia_192_ecb            755
#define OBJ_camellia_192_ecb            OBJ_camellia,21L

#define SN_camellia_192_ofb128          "CAMELLIA-192-OFB"
#define LN_camellia_192_ofb128          "camellia-192-ofb"
#define NID_camellia_192_ofb128         767
#define OBJ_camellia_192_ofb128         OBJ_camellia,23L

#define SN_camellia_192_cfb128          "CAMELLIA-192-CFB"
#define LN_camellia_192_cfb128          "camellia-192-cfb"
#define NID_camellia_192_cfb128         758
#define OBJ_camellia_192_cfb128         OBJ_camellia,24L

#define SN_camellia_256_ecb             "CAMELLIA-256-ECB"
#define LN_camellia_256_ecb             "camellia-256-ecb"
#define NID_camellia_256_ecb            756
#define OBJ_camellia_256_ecb            OBJ_camellia,41L

#define SN_camellia_256_ofb128          "CAMELLIA-256-OFB"
#define LN_camellia_256_ofb128          "camellia-256-ofb"
#define NID_camellia_256_ofb128         768
#define OBJ_camellia_256_ofb128         OBJ_camellia,43L

#define SN_camellia_256_cfb128          "CAMELLIA-256-CFB"
#define LN_camellia_256_cfb128          "camellia-256-cfb"
#define NID_camellia_256_cfb128         759
#define OBJ_camellia_256_cfb128         OBJ_camellia,44L

#define SN_camellia_128_cfb1            "CAMELLIA-128-CFB1"
#define LN_camellia_128_cfb1            "camellia-128-cfb1"
#define NID_camellia_128_cfb1           760

#define SN_camellia_192_cfb1            "CAMELLIA-192-CFB1"
#define LN_camellia_192_cfb1            "camellia-192-cfb1"
#define NID_camellia_192_cfb1           761

#define SN_camellia_256_cfb1            "CAMELLIA-256-CFB1"
#define LN_camellia_256_cfb1            "camellia-256-cfb1"
#define NID_camellia_256_cfb1           762

#define SN_camellia_128_cfb8            "CAMELLIA-128-CFB8"
#define LN_camellia_128_cfb8            "camellia-128-cfb8"
#define NID_camellia_128_cfb8           763

#define SN_camellia_192_cfb8            "CAMELLIA-192-CFB8"
#define LN_camellia_192_cfb8            "camellia-192-cfb8"
#define NID_camellia_192_cfb8           764

#define SN_camellia_256_cfb8            "CAMELLIA-256-CFB8"
#define LN_camellia_256_cfb8            "camellia-256-cfb8"
#define NID_camellia_256_cfb8           765

#define SN_kisa         "KISA"
#define LN_kisa         "kisa"
#define NID_kisa                773
#define OBJ_kisa                OBJ_member_body,410L,200004L

#define SN_seed_ecb             "SEED-ECB"
#define LN_seed_ecb             "seed-ecb"
#define NID_seed_ecb            776
#define OBJ_seed_ecb            OBJ_kisa,1L,3L

#define SN_seed_cbc             "SEED-CBC"
#define LN_seed_cbc             "seed-cbc"
#define NID_seed_cbc            777
#define OBJ_seed_cbc            OBJ_kisa,1L,4L

#define SN_seed_cfb128          "SEED-CFB"
#define LN_seed_cfb128          "seed-cfb"
#define NID_seed_cfb128         779
#define OBJ_seed_cfb128         OBJ_kisa,1L,5L

#define SN_seed_ofb128          "SEED-OFB"
#define LN_seed_ofb128          "seed-ofb"
#define NID_seed_ofb128         778
#define OBJ_seed_ofb128         OBJ_kisa,1L,6L

#define SN_hmac         "HMAC"
#define LN_hmac         "hmac"
#define NID_hmac                855

#define SN_cmac         "CMAC"
#define LN_cmac         "cmac"
#define NID_cmac                894

#define SN_rc4_hmac_md5         "RC4-HMAC-MD5"
#define LN_rc4_hmac_md5         "rc4-hmac-md5"
#define NID_rc4_hmac_md5                915

#define SN_aes_128_cbc_hmac_sha1                "AES-128-CBC-HMAC-SHA1"
#define LN_aes_128_cbc_hmac_sha1                "aes-128-cbc-hmac-sha1"
#define NID_aes_128_cbc_hmac_sha1               916

#define SN_aes_192_cbc_hmac_sha1                "AES-192-CBC-HMAC-SHA1"
#define LN_aes_192_cbc_hmac_sha1                "aes-192-cbc-hmac-sha1"
#define NID_aes_192_cbc_hmac_sha1               917

#define SN_aes_256_cbc_hmac_sha1                "AES-256-CBC-HMAC-SHA1"
#define LN_aes_256_cbc_hmac_sha1                "aes-256-cbc-hmac-sha1"
#define NID_aes_256_cbc_hmac_sha1               918

#define SN_aes_128_cbc_hmac_sha256              "AES-128-CBC-HMAC-SHA256"
#define LN_aes_128_cbc_hmac_sha256              "aes-128-cbc-hmac-sha256"
#define NID_aes_128_cbc_hmac_sha256             948

#define SN_aes_192_cbc_hmac_sha256              "AES-192-CBC-HMAC-SHA256"
#define LN_aes_192_cbc_hmac_sha256              "aes-192-cbc-hmac-sha256"
#define NID_aes_192_cbc_hmac_sha256             949

#define SN_aes_256_cbc_hmac_sha256              "AES-256-CBC-HMAC-SHA256"
#define LN_aes_256_cbc_hmac_sha256              "aes-256-cbc-hmac-sha256"
#define NID_aes_256_cbc_hmac_sha256             950

#define SN_dhpublicnumber               "dhpublicnumber"
#define LN_dhpublicnumber               "X9.42 DH"
#define NID_dhpublicnumber              920
#define OBJ_dhpublicnumber              OBJ_ISO_US,10046L,2L,1L

#define SN_brainpoolP160r1              "brainpoolP160r1"
#define NID_brainpoolP160r1             921
#define OBJ_brainpoolP160r1             1L,3L,36L,3L,3L,2L,8L,1L,1L,1L

#define SN_brainpoolP160t1              "brainpoolP160t1"
#define NID_brainpoolP160t1             922
#define OBJ_brainpoolP160t1             1L,3L,36L,3L,3L,2L,8L,1L,1L,2L

#define SN_brainpoolP192r1              "brainpoolP192r1"
#define NID_brainpoolP192r1             923
#define OBJ_brainpoolP192r1             1L,3L,36L,3L,3L,2L,8L,1L,1L,3L

#define SN_brainpoolP192t1              "brainpoolP192t1"
#define NID_brainpoolP192t1             924
#define OBJ_brainpoolP192t1             1L,3L,36L,3L,3L,2L,8L,1L,1L,4L

#define SN_brainpoolP224r1              "brainpoolP224r1"
#define NID_brainpoolP224r1             925
#define OBJ_brainpoolP224r1             1L,3L,36L,3L,3L,2L,8L,1L,1L,5L

#define SN_brainpoolP224t1              "brainpoolP224t1"
#define NID_brainpoolP224t1             926
#define OBJ_brainpoolP224t1             1L,3L,36L,3L,3L,2L,8L,1L,1L,6L

#define SN_brainpoolP256r1              "brainpoolP256r1"
#define NID_brainpoolP256r1             927
#define OBJ_brainpoolP256r1             1L,3L,36L,3L,3L,2L,8L,1L,1L,7L

#define SN_brainpoolP256t1              "brainpoolP256t1"
#define NID_brainpoolP256t1             928
#define OBJ_brainpoolP256t1             1L,3L,36L,3L,3L,2L,8L,1L,1L,8L

#define SN_brainpoolP320r1              "brainpoolP320r1"
#define NID_brainpoolP320r1             929
#define OBJ_brainpoolP320r1             1L,3L,36L,3L,3L,2L,8L,1L,1L,9L

#define SN_brainpoolP320t1              "brainpoolP320t1"
#define NID_brainpoolP320t1             930
#define OBJ_brainpoolP320t1             1L,3L,36L,3L,3L,2L,8L,1L,1L,10L

#define SN_brainpoolP384r1              "brainpoolP384r1"
#define NID_brainpoolP384r1             931
#define OBJ_brainpoolP384r1             1L,3L,36L,3L,3L,2L,8L,1L,1L,11L

#define SN_brainpoolP384t1              "brainpoolP384t1"
#define NID_brainpoolP384t1             932
#define OBJ_brainpoolP384t1             1L,3L,36L,3L,3L,2L,8L,1L,1L,12L

#define SN_brainpoolP512r1              "brainpoolP512r1"
#define NID_brainpoolP512r1             933
#define OBJ_brainpoolP512r1             1L,3L,36L,3L,3L,2L,8L,1L,1L,13L

#define SN_brainpoolP512t1              "brainpoolP512t1"
#define NID_brainpoolP512t1             934
#define OBJ_brainpoolP512t1             1L,3L,36L,3L,3L,2L,8L,1L,1L,14L

#define OBJ_x9_63_scheme                1L,3L,133L,16L,840L,63L,0L

#define OBJ_secg_scheme         OBJ_certicom_arc,1L

#define SN_dhSinglePass_stdDH_sha1kdf_scheme            "dhSinglePass-stdDH-sha1kdf-scheme"
#define NID_dhSinglePass_stdDH_sha1kdf_scheme           936
#define OBJ_dhSinglePass_stdDH_sha1kdf_scheme           OBJ_x9_63_scheme,2L

#define SN_dhSinglePass_stdDH_sha224kdf_scheme          "dhSinglePass-stdDH-sha224kdf-scheme"
#define NID_dhSinglePass_stdDH_sha224kdf_scheme         937
#define OBJ_dhSinglePass_stdDH_sha224kdf_scheme         OBJ_secg_scheme,11L,0L

#define SN_dhSinglePass_stdDH_sha256kdf_scheme          "dhSinglePass-stdDH-sha256kdf-scheme"
#define NID_dhSinglePass_stdDH_sha256kdf_scheme         938
#define OBJ_dhSinglePass_stdDH_sha256kdf_scheme         OBJ_secg_scheme,11L,1L

#define SN_dhSinglePass_stdDH_sha384kdf_scheme          "dhSinglePass-stdDH-sha384kdf-scheme"
#define NID_dhSinglePass_stdDH_sha384kdf_scheme         939
#define OBJ_dhSinglePass_stdDH_sha384kdf_scheme         OBJ_secg_scheme,11L,2L

#define SN_dhSinglePass_stdDH_sha512kdf_scheme          "dhSinglePass-stdDH-sha512kdf-scheme"
#define NID_dhSinglePass_stdDH_sha512kdf_scheme         940
#define OBJ_dhSinglePass_stdDH_sha512kdf_scheme         OBJ_secg_scheme,11L,3L

#define SN_dhSinglePass_cofactorDH_sha1kdf_scheme               "dhSinglePass-cofactorDH-sha1kdf-scheme"
#define NID_dhSinglePass_cofactorDH_sha1kdf_scheme              941
#define OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme              OBJ_x9_63_scheme,3L

#define SN_dhSinglePass_cofactorDH_sha224kdf_scheme             "dhSinglePass-cofactorDH-sha224kdf-scheme"
#define NID_dhSinglePass_cofactorDH_sha224kdf_scheme            942
#define OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme            OBJ_secg_scheme,14L,0L

#define SN_dhSinglePass_cofactorDH_sha256kdf_scheme             "dhSinglePass-cofactorDH-sha256kdf-scheme"
#define NID_dhSinglePass_cofactorDH_sha256kdf_scheme            943
#define OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme            OBJ_secg_scheme,14L,1L

#define SN_dhSinglePass_cofactorDH_sha384kdf_scheme             "dhSinglePass-cofactorDH-sha384kdf-scheme"
#define NID_dhSinglePass_cofactorDH_sha384kdf_scheme            944
#define OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme            OBJ_secg_scheme,14L,2L

#define SN_dhSinglePass_cofactorDH_sha512kdf_scheme             "dhSinglePass-cofactorDH-sha512kdf-scheme"
#define NID_dhSinglePass_cofactorDH_sha512kdf_scheme            945
#define OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme            OBJ_secg_scheme,14L,3L

#define SN_dh_std_kdf           "dh-std-kdf"
#define NID_dh_std_kdf          946

#define SN_dh_cofactor_kdf              "dh-cofactor-kdf"
#define NID_dh_cofactor_kdf             947

#define SN_ct_precert_scts              "ct_precert_scts"
#define LN_ct_precert_scts              "CT Precertificate SCTs"
#define NID_ct_precert_scts             951
#define OBJ_ct_precert_scts             1L,3L,6L,1L,4L,1L,11129L,2L,4L,2L

#define SN_ct_precert_poison            "ct_precert_poison"
#define LN_ct_precert_poison            "CT Precertificate Poison"
#define NID_ct_precert_poison           952
#define OBJ_ct_precert_poison           1L,3L,6L,1L,4L,1L,11129L,2L,4L,3L

#define SN_ct_precert_signer            "ct_precert_signer"
#define LN_ct_precert_signer            "CT Precertificate Signer"
#define NID_ct_precert_signer           953
#define OBJ_ct_precert_signer           1L,3L,6L,1L,4L,1L,11129L,2L,4L,4L

#define SN_ct_cert_scts         "ct_cert_scts"
#define LN_ct_cert_scts         "CT Certificate SCTs"
#define NID_ct_cert_scts                954
#define OBJ_ct_cert_scts                1L,3L,6L,1L,4L,1L,11129L,2L,4L,5L

#define SN_jurisdictionLocalityName             "jurisdictionL"
#define LN_jurisdictionLocalityName             "jurisdictionLocalityName"
#define NID_jurisdictionLocalityName            955
#define OBJ_jurisdictionLocalityName            1L,3L,6L,1L,4L,1L,311L,60L,2L,1L,1L

#define SN_jurisdictionStateOrProvinceName              "jurisdictionST"
#define LN_jurisdictionStateOrProvinceName              "jurisdictionStateOrProvinceName"
#define NID_jurisdictionStateOrProvinceName             956
#define OBJ_jurisdictionStateOrProvinceName             1L,3L,6L,1L,4L,1L,311L,60L,2L,1L,2L

#define SN_jurisdictionCountryName              "jurisdictionC"
#define LN_jurisdictionCountryName              "jurisdictionCountryName"
#define NID_jurisdictionCountryName             957
#define OBJ_jurisdictionCountryName             1L,3L,6L,1L,4L,1L,311L,60L,2L,1L,3L
openssl/blowfish.h000064400000012347151733316570010237 0ustar00/* crypto/bf/blowfish.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#ifndef HEADER_BLOWFISH_H
# define HEADER_BLOWFISH_H

# include <openssl/e_os2.h>

#ifdef  __cplusplus
extern "C" {
#endif

# ifdef OPENSSL_NO_BF
#  error BF is disabled.
# endif

# define BF_ENCRYPT      1
# define BF_DECRYPT      0

/*-
 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 * ! BF_LONG has to be at least 32 bits wide. If it's wider, then !
 * ! BF_LONG_LOG2 has to be defined along.                        !
 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 */

# if defined(__LP32__)
#  define BF_LONG unsigned long
# elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
#  define BF_LONG unsigned long
#  define BF_LONG_LOG2 3
/*
 * _CRAY note. I could declare short, but I have no idea what impact
 * does it have on performance on none-T3E machines. I could declare
 * int, but at least on C90 sizeof(int) can be chosen at compile time.
 * So I've chosen long...
 *                                      <appro@fy.chalmers.se>
 */
# else
#  define BF_LONG unsigned int
# endif

# define BF_ROUNDS       16
# define BF_BLOCK        8

typedef struct bf_key_st {
    BF_LONG P[BF_ROUNDS + 2];
    BF_LONG S[4 * 256];
} BF_KEY;

# ifdef OPENSSL_FIPS
void private_BF_set_key(BF_KEY *key, int len, const unsigned char *data);
# endif
void BF_set_key(BF_KEY *key, int len, const unsigned char *data);

void BF_encrypt(BF_LONG *data, const BF_KEY *key);
void BF_decrypt(BF_LONG *data, const BF_KEY *key);

void BF_ecb_encrypt(const unsigned char *in, unsigned char *out,
                    const BF_KEY *key, int enc);
void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
                    const BF_KEY *schedule, unsigned char *ivec, int enc);
void BF_cfb64_encrypt(const unsigned char *in, unsigned char *out,
                      long length, const BF_KEY *schedule,
                      unsigned char *ivec, int *num, int enc);
void BF_ofb64_encrypt(const unsigned char *in, unsigned char *out,
                      long length, const BF_KEY *schedule,
                      unsigned char *ivec, int *num);
const char *BF_options(void);

#ifdef  __cplusplus
}
#endif

#endif
openssl/camellia.h000064400000012675151733316570010175 0ustar00/* crypto/camellia/camellia.h */
/* ====================================================================
 * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 */

#ifndef HEADER_CAMELLIA_H
# define HEADER_CAMELLIA_H

# include <openssl/opensslconf.h>

# ifdef OPENSSL_NO_CAMELLIA
#  error CAMELLIA is disabled.
# endif

# include <stddef.h>

# define CAMELLIA_ENCRYPT        1
# define CAMELLIA_DECRYPT        0

/*
 * Because array size can't be a const in C, the following two are macros.
 * Both sizes are in bytes.
 */

#ifdef  __cplusplus
extern "C" {
#endif

/* This should be a hidden type, but EVP requires that the size be known */

# define CAMELLIA_BLOCK_SIZE 16
# define CAMELLIA_TABLE_BYTE_LEN 272
# define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4)

typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; /* to match
                                                               * with WORD */

struct camellia_key_st {
    union {
        double d;               /* ensures 64-bit align */
        KEY_TABLE_TYPE rd_key;
    } u;
    int grand_rounds;
};
typedef struct camellia_key_st CAMELLIA_KEY;

# ifdef OPENSSL_FIPS
int private_Camellia_set_key(const unsigned char *userKey, const int bits,
                             CAMELLIA_KEY *key);
# endif
int Camellia_set_key(const unsigned char *userKey, const int bits,
                     CAMELLIA_KEY *key);

void Camellia_encrypt(const unsigned char *in, unsigned char *out,
                      const CAMELLIA_KEY *key);
void Camellia_decrypt(const unsigned char *in, unsigned char *out,
                      const CAMELLIA_KEY *key);

void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out,
                          const CAMELLIA_KEY *key, const int enc);
void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out,
                          size_t length, const CAMELLIA_KEY *key,
                          unsigned char *ivec, const int enc);
void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out,
                             size_t length, const CAMELLIA_KEY *key,
                             unsigned char *ivec, int *num, const int enc);
void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out,
                           size_t length, const CAMELLIA_KEY *key,
                           unsigned char *ivec, int *num, const int enc);
void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out,
                           size_t length, const CAMELLIA_KEY *key,
                           unsigned char *ivec, int *num, const int enc);
void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out,
                             size_t length, const CAMELLIA_KEY *key,
                             unsigned char *ivec, int *num);
void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out,
                             size_t length, const CAMELLIA_KEY *key,
                             unsigned char ivec[CAMELLIA_BLOCK_SIZE],
                             unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE],
                             unsigned int *num);

#ifdef  __cplusplus
}
#endif

#endif                          /* !HEADER_Camellia_H */
openssl/tls1.h000064400000114763151733316570007312 0ustar00/* ssl/tls1.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */
/* ====================================================================
 * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */
/* ====================================================================
 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
 *
 * Portions of the attached software ("Contribution") are developed by
 * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
 *
 * The Contribution is licensed pursuant to the OpenSSL open source
 * license provided above.
 *
 * ECC cipher suite support in OpenSSL originally written by
 * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories.
 *
 */
/* ====================================================================
 * Copyright 2005 Nokia. All rights reserved.
 *
 * The portions of the attached software ("Contribution") is developed by
 * Nokia Corporation and is licensed pursuant to the OpenSSL open source
 * license.
 *
 * The Contribution, originally written by Mika Kousa and Pasi Eronen of
 * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
 * support (see RFC 4279) to OpenSSL.
 *
 * No patent licenses or other rights except those expressly stated in
 * the OpenSSL open source license shall be deemed granted or received
 * expressly, by implication, estoppel, or otherwise.
 *
 * No assurances are provided by Nokia that the Contribution does not
 * infringe the patent or other intellectual property rights of any third
 * party or that the license provides you with all the necessary rights
 * to make use of the Contribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
 * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
 * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
 * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
 * OTHERWISE.
 */

#ifndef HEADER_TLS1_H
# define HEADER_TLS1_H

# include <openssl/buffer.h>

#ifdef  __cplusplus
extern "C" {
#endif

# define TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES    0

# define TLS1_VERSION                    0x0301
# define TLS1_1_VERSION                  0x0302
# define TLS1_2_VERSION                  0x0303
# define TLS_MAX_VERSION                 TLS1_2_VERSION

# define TLS1_VERSION_MAJOR              0x03
# define TLS1_VERSION_MINOR              0x01

# define TLS1_1_VERSION_MAJOR            0x03
# define TLS1_1_VERSION_MINOR            0x02

# define TLS1_2_VERSION_MAJOR            0x03
# define TLS1_2_VERSION_MINOR            0x03

# define TLS1_get_version(s) \
                ((s->version >> 8) == TLS1_VERSION_MAJOR ? s->version : 0)

# define TLS1_get_client_version(s) \
                ((s->client_version >> 8) == TLS1_VERSION_MAJOR ? s->client_version : 0)

# define TLS1_AD_DECRYPTION_FAILED       21
# define TLS1_AD_RECORD_OVERFLOW         22
# define TLS1_AD_UNKNOWN_CA              48/* fatal */
# define TLS1_AD_ACCESS_DENIED           49/* fatal */
# define TLS1_AD_DECODE_ERROR            50/* fatal */
# define TLS1_AD_DECRYPT_ERROR           51
# define TLS1_AD_EXPORT_RESTRICTION      60/* fatal */
# define TLS1_AD_PROTOCOL_VERSION        70/* fatal */
# define TLS1_AD_INSUFFICIENT_SECURITY   71/* fatal */
# define TLS1_AD_INTERNAL_ERROR          80/* fatal */
# define TLS1_AD_INAPPROPRIATE_FALLBACK  86/* fatal */
# define TLS1_AD_USER_CANCELLED          90
# define TLS1_AD_NO_RENEGOTIATION        100
/* codes 110-114 are from RFC3546 */
# define TLS1_AD_UNSUPPORTED_EXTENSION   110
# define TLS1_AD_CERTIFICATE_UNOBTAINABLE 111
# define TLS1_AD_UNRECOGNIZED_NAME       112
# define TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 113
# define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114
# define TLS1_AD_UNKNOWN_PSK_IDENTITY    115/* fatal */

/* ExtensionType values from RFC3546 / RFC4366 / RFC6066 */
# define TLSEXT_TYPE_server_name                 0
# define TLSEXT_TYPE_max_fragment_length         1
# define TLSEXT_TYPE_client_certificate_url      2
# define TLSEXT_TYPE_trusted_ca_keys             3
# define TLSEXT_TYPE_truncated_hmac              4
# define TLSEXT_TYPE_status_request              5
/* ExtensionType values from RFC4681 */
# define TLSEXT_TYPE_user_mapping                6
/* ExtensionType values from RFC5878 */
# define TLSEXT_TYPE_client_authz                7
# define TLSEXT_TYPE_server_authz                8
/* ExtensionType values from RFC6091 */
# define TLSEXT_TYPE_cert_type           9

/* ExtensionType values from RFC4492 */
# define TLSEXT_TYPE_elliptic_curves             10
# define TLSEXT_TYPE_ec_point_formats            11

/* ExtensionType value from RFC5054 */
# define TLSEXT_TYPE_srp                         12

/* ExtensionType values from RFC5246 */
# define TLSEXT_TYPE_signature_algorithms        13

/* ExtensionType value from RFC5764 */
# define TLSEXT_TYPE_use_srtp    14

/* ExtensionType value from RFC5620 */
# define TLSEXT_TYPE_heartbeat   15

/* ExtensionType value from RFC7301 */
# define TLSEXT_TYPE_application_layer_protocol_negotiation 16

/*
 * ExtensionType value for TLS padding extension.
 * http://tools.ietf.org/html/draft-agl-tls-padding
 */
# define TLSEXT_TYPE_padding     21

/* ExtensionType value from RFC4507 */
# define TLSEXT_TYPE_session_ticket              35

/* ExtensionType value from draft-rescorla-tls-opaque-prf-input-00.txt */
# if 0
/*
 * will have to be provided externally for now ,
 * i.e. build with -DTLSEXT_TYPE_opaque_prf_input=38183
 * using whatever extension number you'd like to try
 */
#  define TLSEXT_TYPE_opaque_prf_input           ??
# endif

/* Temporary extension type */
# define TLSEXT_TYPE_renegotiate                 0xff01

# ifndef OPENSSL_NO_NEXTPROTONEG
/* This is not an IANA defined extension number */
#  define TLSEXT_TYPE_next_proto_neg              13172
# endif

/* NameType value from RFC3546 */
# define TLSEXT_NAMETYPE_host_name 0
/* status request value from RFC3546 */
# define TLSEXT_STATUSTYPE_ocsp 1

/* ECPointFormat values from RFC4492 */
# define TLSEXT_ECPOINTFORMAT_first                      0
# define TLSEXT_ECPOINTFORMAT_uncompressed               0
# define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime  1
# define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2  2
# define TLSEXT_ECPOINTFORMAT_last                       2

/* Signature and hash algorithms from RFC5246 */
# define TLSEXT_signature_anonymous                      0
# define TLSEXT_signature_rsa                            1
# define TLSEXT_signature_dsa                            2
# define TLSEXT_signature_ecdsa                          3

/* Total number of different signature algorithms */
# define TLSEXT_signature_num                            4

# define TLSEXT_hash_none                                0
# define TLSEXT_hash_md5                                 1
# define TLSEXT_hash_sha1                                2
# define TLSEXT_hash_sha224                              3
# define TLSEXT_hash_sha256                              4
# define TLSEXT_hash_sha384                              5
# define TLSEXT_hash_sha512                              6

/* Total number of different digest algorithms */

# define TLSEXT_hash_num                                 7

/* Flag set for unrecognised algorithms */
# define TLSEXT_nid_unknown                              0x1000000

/* ECC curves */

# define TLSEXT_curve_P_256                              23
# define TLSEXT_curve_P_384                              24

# ifndef OPENSSL_NO_TLSEXT

#  define TLSEXT_MAXLEN_host_name 255

const char *SSL_get_servername(const SSL *s, const int type);
int SSL_get_servername_type(const SSL *s);
/*
 * SSL_export_keying_material exports a value derived from the master secret,
 * as specified in RFC 5705. It writes |olen| bytes to |out| given a label and
 * optional context. (Since a zero length context is allowed, the |use_context|
 * flag controls whether a context is included.) It returns 1 on success and
 * zero otherwise.
 */
int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
                               const char *label, size_t llen,
                               const unsigned char *context, size_t contextlen,
                               int use_context);

int SSL_get_sigalgs(SSL *s, int idx,
                    int *psign, int *phash, int *psignandhash,
                    unsigned char *rsig, unsigned char *rhash);

int SSL_get_shared_sigalgs(SSL *s, int idx,
                           int *psign, int *phash, int *psignandhash,
                           unsigned char *rsig, unsigned char *rhash);

int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain);

#  define SSL_set_tlsext_host_name(s,name) \
SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name,(char *)name)

#  define SSL_set_tlsext_debug_callback(ssl, cb) \
SSL_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_CB,(void (*)(void))cb)

#  define SSL_set_tlsext_debug_arg(ssl, arg) \
SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_ARG,0, (void *)arg)

#  define SSL_set_tlsext_status_type(ssl, type) \
SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE,type, NULL)

#  define SSL_get_tlsext_status_exts(ssl, arg) \
SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS,0, (void *)arg)

#  define SSL_set_tlsext_status_exts(ssl, arg) \
SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS,0, (void *)arg)

#  define SSL_get_tlsext_status_ids(ssl, arg) \
SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS,0, (void *)arg)

#  define SSL_set_tlsext_status_ids(ssl, arg) \
SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS,0, (void *)arg)

#  define SSL_get_tlsext_status_ocsp_resp(ssl, arg) \
SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP,0, (void *)arg)

#  define SSL_set_tlsext_status_ocsp_resp(ssl, arg, arglen) \
SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP,arglen, (void *)arg)

#  define SSL_CTX_set_tlsext_servername_callback(ctx, cb) \
SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_CB,(void (*)(void))cb)

#  define SSL_TLSEXT_ERR_OK 0
#  define SSL_TLSEXT_ERR_ALERT_WARNING 1
#  define SSL_TLSEXT_ERR_ALERT_FATAL 2
#  define SSL_TLSEXT_ERR_NOACK 3

#  define SSL_CTX_set_tlsext_servername_arg(ctx, arg) \
SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG,0, (void *)arg)

#  define SSL_CTX_get_tlsext_ticket_keys(ctx, keys, keylen) \
        SSL_CTX_ctrl((ctx),SSL_CTRL_GET_TLSEXT_TICKET_KEYS,(keylen),(keys))
#  define SSL_CTX_set_tlsext_ticket_keys(ctx, keys, keylen) \
        SSL_CTX_ctrl((ctx),SSL_CTRL_SET_TLSEXT_TICKET_KEYS,(keylen),(keys))

#  define SSL_CTX_set_tlsext_status_cb(ssl, cb) \
SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB,(void (*)(void))cb)

#  define SSL_CTX_set_tlsext_status_arg(ssl, arg) \
SSL_CTX_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG,0, (void *)arg)

#  define SSL_set_tlsext_opaque_prf_input(s, src, len) \
SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT, len, src)
#  define SSL_CTX_set_tlsext_opaque_prf_input_callback(ctx, cb) \
SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB, (void (*)(void))cb)
#  define SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(ctx, arg) \
SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG, 0, arg)

#  define SSL_CTX_set_tlsext_ticket_key_cb(ssl, cb) \
SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)

#  ifndef OPENSSL_NO_HEARTBEATS
#   define SSL_TLSEXT_HB_ENABLED                           0x01
#   define SSL_TLSEXT_HB_DONT_SEND_REQUESTS        0x02
#   define SSL_TLSEXT_HB_DONT_RECV_REQUESTS        0x04

#   define SSL_get_tlsext_heartbeat_pending(ssl) \
        SSL_ctrl((ssl),SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING,0,NULL)
#   define SSL_set_tlsext_heartbeat_no_requests(ssl, arg) \
        SSL_ctrl((ssl),SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS,arg,NULL)
#  endif
# endif

/* PSK ciphersuites from 4279 */
# define TLS1_CK_PSK_WITH_RC4_128_SHA                    0x0300008A
# define TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA               0x0300008B
# define TLS1_CK_PSK_WITH_AES_128_CBC_SHA                0x0300008C
# define TLS1_CK_PSK_WITH_AES_256_CBC_SHA                0x0300008D

/*
 * Additional TLS ciphersuites from expired Internet Draft
 * draft-ietf-tls-56-bit-ciphersuites-01.txt (available if
 * TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES is defined, see s3_lib.c).  We
 * actually treat them like SSL 3.0 ciphers, which we probably shouldn't.
 * Note that the first two are actually not in the IDs.
 */
# define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5          0x03000060/* not in
                                                                    * ID */
# define TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5      0x03000061/* not in
                                                                    * ID */
# define TLS1_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA         0x03000062
# define TLS1_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA     0x03000063
# define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_SHA          0x03000064
# define TLS1_CK_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA      0x03000065
# define TLS1_CK_DHE_DSS_WITH_RC4_128_SHA                0x03000066

/* AES ciphersuites from RFC3268 */
# define TLS1_CK_RSA_WITH_AES_128_SHA                    0x0300002F
# define TLS1_CK_DH_DSS_WITH_AES_128_SHA                 0x03000030
# define TLS1_CK_DH_RSA_WITH_AES_128_SHA                 0x03000031
# define TLS1_CK_DHE_DSS_WITH_AES_128_SHA                0x03000032
# define TLS1_CK_DHE_RSA_WITH_AES_128_SHA                0x03000033
# define TLS1_CK_ADH_WITH_AES_128_SHA                    0x03000034

# define TLS1_CK_RSA_WITH_AES_256_SHA                    0x03000035
# define TLS1_CK_DH_DSS_WITH_AES_256_SHA                 0x03000036
# define TLS1_CK_DH_RSA_WITH_AES_256_SHA                 0x03000037
# define TLS1_CK_DHE_DSS_WITH_AES_256_SHA                0x03000038
# define TLS1_CK_DHE_RSA_WITH_AES_256_SHA                0x03000039
# define TLS1_CK_ADH_WITH_AES_256_SHA                    0x0300003A

/* TLS v1.2 ciphersuites */
# define TLS1_CK_RSA_WITH_NULL_SHA256                    0x0300003B
# define TLS1_CK_RSA_WITH_AES_128_SHA256                 0x0300003C
# define TLS1_CK_RSA_WITH_AES_256_SHA256                 0x0300003D
# define TLS1_CK_DH_DSS_WITH_AES_128_SHA256              0x0300003E
# define TLS1_CK_DH_RSA_WITH_AES_128_SHA256              0x0300003F
# define TLS1_CK_DHE_DSS_WITH_AES_128_SHA256             0x03000040

/* Camellia ciphersuites from RFC4132 */
# define TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA           0x03000041
# define TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA        0x03000042
# define TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA        0x03000043
# define TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA       0x03000044
# define TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA       0x03000045
# define TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA           0x03000046

/* TLS v1.2 ciphersuites */
# define TLS1_CK_DHE_RSA_WITH_AES_128_SHA256             0x03000067
# define TLS1_CK_DH_DSS_WITH_AES_256_SHA256              0x03000068
# define TLS1_CK_DH_RSA_WITH_AES_256_SHA256              0x03000069
# define TLS1_CK_DHE_DSS_WITH_AES_256_SHA256             0x0300006A
# define TLS1_CK_DHE_RSA_WITH_AES_256_SHA256             0x0300006B
# define TLS1_CK_ADH_WITH_AES_128_SHA256                 0x0300006C
# define TLS1_CK_ADH_WITH_AES_256_SHA256                 0x0300006D

/* Camellia ciphersuites from RFC4132 */
# define TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA           0x03000084
# define TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA        0x03000085
# define TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA        0x03000086
# define TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA       0x03000087
# define TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA       0x03000088
# define TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA           0x03000089

/* SEED ciphersuites from RFC4162 */
# define TLS1_CK_RSA_WITH_SEED_SHA                       0x03000096
# define TLS1_CK_DH_DSS_WITH_SEED_SHA                    0x03000097
# define TLS1_CK_DH_RSA_WITH_SEED_SHA                    0x03000098
# define TLS1_CK_DHE_DSS_WITH_SEED_SHA                   0x03000099
# define TLS1_CK_DHE_RSA_WITH_SEED_SHA                   0x0300009A
# define TLS1_CK_ADH_WITH_SEED_SHA                       0x0300009B

/* TLS v1.2 GCM ciphersuites from RFC5288 */
# define TLS1_CK_RSA_WITH_AES_128_GCM_SHA256             0x0300009C
# define TLS1_CK_RSA_WITH_AES_256_GCM_SHA384             0x0300009D
# define TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256         0x0300009E
# define TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384         0x0300009F
# define TLS1_CK_DH_RSA_WITH_AES_128_GCM_SHA256          0x030000A0
# define TLS1_CK_DH_RSA_WITH_AES_256_GCM_SHA384          0x030000A1
# define TLS1_CK_DHE_DSS_WITH_AES_128_GCM_SHA256         0x030000A2
# define TLS1_CK_DHE_DSS_WITH_AES_256_GCM_SHA384         0x030000A3
# define TLS1_CK_DH_DSS_WITH_AES_128_GCM_SHA256          0x030000A4
# define TLS1_CK_DH_DSS_WITH_AES_256_GCM_SHA384          0x030000A5
# define TLS1_CK_ADH_WITH_AES_128_GCM_SHA256             0x030000A6
# define TLS1_CK_ADH_WITH_AES_256_GCM_SHA384             0x030000A7

/*
 * ECC ciphersuites from draft-ietf-tls-ecc-12.txt with changes soon to be in
 * draft 13
 */
# define TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA                0x0300C001
# define TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA             0x0300C002
# define TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA        0x0300C003
# define TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA         0x0300C004
# define TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA         0x0300C005

# define TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA               0x0300C006
# define TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA            0x0300C007
# define TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA       0x0300C008
# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA        0x0300C009
# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA        0x0300C00A

# define TLS1_CK_ECDH_RSA_WITH_NULL_SHA                  0x0300C00B
# define TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA               0x0300C00C
# define TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA          0x0300C00D
# define TLS1_CK_ECDH_RSA_WITH_AES_128_CBC_SHA           0x0300C00E
# define TLS1_CK_ECDH_RSA_WITH_AES_256_CBC_SHA           0x0300C00F

# define TLS1_CK_ECDHE_RSA_WITH_NULL_SHA                 0x0300C010
# define TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA              0x0300C011
# define TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA         0x0300C012
# define TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA          0x0300C013
# define TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA          0x0300C014

# define TLS1_CK_ECDH_anon_WITH_NULL_SHA                 0x0300C015
# define TLS1_CK_ECDH_anon_WITH_RC4_128_SHA              0x0300C016
# define TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA         0x0300C017
# define TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA          0x0300C018
# define TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA          0x0300C019

/* SRP ciphersuites from RFC 5054 */
# define TLS1_CK_SRP_SHA_WITH_3DES_EDE_CBC_SHA           0x0300C01A
# define TLS1_CK_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA       0x0300C01B
# define TLS1_CK_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA       0x0300C01C
# define TLS1_CK_SRP_SHA_WITH_AES_128_CBC_SHA            0x0300C01D
# define TLS1_CK_SRP_SHA_RSA_WITH_AES_128_CBC_SHA        0x0300C01E
# define TLS1_CK_SRP_SHA_DSS_WITH_AES_128_CBC_SHA        0x0300C01F
# define TLS1_CK_SRP_SHA_WITH_AES_256_CBC_SHA            0x0300C020
# define TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA        0x0300C021
# define TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA        0x0300C022

/* ECDH HMAC based ciphersuites from RFC5289 */

# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256         0x0300C023
# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384         0x0300C024
# define TLS1_CK_ECDH_ECDSA_WITH_AES_128_SHA256          0x0300C025
# define TLS1_CK_ECDH_ECDSA_WITH_AES_256_SHA384          0x0300C026
# define TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256           0x0300C027
# define TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384           0x0300C028
# define TLS1_CK_ECDH_RSA_WITH_AES_128_SHA256            0x0300C029
# define TLS1_CK_ECDH_RSA_WITH_AES_256_SHA384            0x0300C02A

/* ECDH GCM based ciphersuites from RFC5289 */
# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256     0x0300C02B
# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384     0x0300C02C
# define TLS1_CK_ECDH_ECDSA_WITH_AES_128_GCM_SHA256      0x0300C02D
# define TLS1_CK_ECDH_ECDSA_WITH_AES_256_GCM_SHA384      0x0300C02E
# define TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256       0x0300C02F
# define TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384       0x0300C030
# define TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256        0x0300C031
# define TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384        0x0300C032

/*
 * XXX * Backward compatibility alert: + * Older versions of OpenSSL gave
 * some DHE ciphers names with "EDH" + * instead of "DHE".  Going forward, we
 * should be using DHE + * everywhere, though we may indefinitely maintain
 * aliases for users + * or configurations that used "EDH" +
 */
# define TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_MD5         "EXP1024-RC4-MD5"
# define TLS1_TXT_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5     "EXP1024-RC2-CBC-MD5"
# define TLS1_TXT_RSA_EXPORT1024_WITH_DES_CBC_SHA        "EXP1024-DES-CBC-SHA"
# define TLS1_TXT_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA    "EXP1024-DHE-DSS-DES-CBC-SHA"
# define TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_SHA         "EXP1024-RC4-SHA"
# define TLS1_TXT_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA     "EXP1024-DHE-DSS-RC4-SHA"
# define TLS1_TXT_DHE_DSS_WITH_RC4_128_SHA               "DHE-DSS-RC4-SHA"

/* AES ciphersuites from RFC3268 */
# define TLS1_TXT_RSA_WITH_AES_128_SHA                   "AES128-SHA"
# define TLS1_TXT_DH_DSS_WITH_AES_128_SHA                "DH-DSS-AES128-SHA"
# define TLS1_TXT_DH_RSA_WITH_AES_128_SHA                "DH-RSA-AES128-SHA"
# define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA               "DHE-DSS-AES128-SHA"
# define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA               "DHE-RSA-AES128-SHA"
# define TLS1_TXT_ADH_WITH_AES_128_SHA                   "ADH-AES128-SHA"

# define TLS1_TXT_RSA_WITH_AES_256_SHA                   "AES256-SHA"
# define TLS1_TXT_DH_DSS_WITH_AES_256_SHA                "DH-DSS-AES256-SHA"
# define TLS1_TXT_DH_RSA_WITH_AES_256_SHA                "DH-RSA-AES256-SHA"
# define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA               "DHE-DSS-AES256-SHA"
# define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA               "DHE-RSA-AES256-SHA"
# define TLS1_TXT_ADH_WITH_AES_256_SHA                   "ADH-AES256-SHA"

/* ECC ciphersuites from RFC4492 */
# define TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA               "ECDH-ECDSA-NULL-SHA"
# define TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA            "ECDH-ECDSA-RC4-SHA"
# define TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA       "ECDH-ECDSA-DES-CBC3-SHA"
# define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA        "ECDH-ECDSA-AES128-SHA"
# define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA        "ECDH-ECDSA-AES256-SHA"

# define TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA              "ECDHE-ECDSA-NULL-SHA"
# define TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA           "ECDHE-ECDSA-RC4-SHA"
# define TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA      "ECDHE-ECDSA-DES-CBC3-SHA"
# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA       "ECDHE-ECDSA-AES128-SHA"
# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA       "ECDHE-ECDSA-AES256-SHA"

# define TLS1_TXT_ECDH_RSA_WITH_NULL_SHA                 "ECDH-RSA-NULL-SHA"
# define TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA              "ECDH-RSA-RC4-SHA"
# define TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA         "ECDH-RSA-DES-CBC3-SHA"
# define TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA          "ECDH-RSA-AES128-SHA"
# define TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA          "ECDH-RSA-AES256-SHA"

# define TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA                "ECDHE-RSA-NULL-SHA"
# define TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA             "ECDHE-RSA-RC4-SHA"
# define TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA        "ECDHE-RSA-DES-CBC3-SHA"
# define TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA         "ECDHE-RSA-AES128-SHA"
# define TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA         "ECDHE-RSA-AES256-SHA"

# define TLS1_TXT_ECDH_anon_WITH_NULL_SHA                "AECDH-NULL-SHA"
# define TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA             "AECDH-RC4-SHA"
# define TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA        "AECDH-DES-CBC3-SHA"
# define TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA         "AECDH-AES128-SHA"
# define TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA         "AECDH-AES256-SHA"

/* PSK ciphersuites from RFC 4279 */
# define TLS1_TXT_PSK_WITH_RC4_128_SHA                   "PSK-RC4-SHA"
# define TLS1_TXT_PSK_WITH_3DES_EDE_CBC_SHA              "PSK-3DES-EDE-CBC-SHA"
# define TLS1_TXT_PSK_WITH_AES_128_CBC_SHA               "PSK-AES128-CBC-SHA"
# define TLS1_TXT_PSK_WITH_AES_256_CBC_SHA               "PSK-AES256-CBC-SHA"

/* SRP ciphersuite from RFC 5054 */
# define TLS1_TXT_SRP_SHA_WITH_3DES_EDE_CBC_SHA          "SRP-3DES-EDE-CBC-SHA"
# define TLS1_TXT_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA      "SRP-RSA-3DES-EDE-CBC-SHA"
# define TLS1_TXT_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA      "SRP-DSS-3DES-EDE-CBC-SHA"
# define TLS1_TXT_SRP_SHA_WITH_AES_128_CBC_SHA           "SRP-AES-128-CBC-SHA"
# define TLS1_TXT_SRP_SHA_RSA_WITH_AES_128_CBC_SHA       "SRP-RSA-AES-128-CBC-SHA"
# define TLS1_TXT_SRP_SHA_DSS_WITH_AES_128_CBC_SHA       "SRP-DSS-AES-128-CBC-SHA"
# define TLS1_TXT_SRP_SHA_WITH_AES_256_CBC_SHA           "SRP-AES-256-CBC-SHA"
# define TLS1_TXT_SRP_SHA_RSA_WITH_AES_256_CBC_SHA       "SRP-RSA-AES-256-CBC-SHA"
# define TLS1_TXT_SRP_SHA_DSS_WITH_AES_256_CBC_SHA       "SRP-DSS-AES-256-CBC-SHA"

/* Camellia ciphersuites from RFC4132 */
# define TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA          "CAMELLIA128-SHA"
# define TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA       "DH-DSS-CAMELLIA128-SHA"
# define TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA       "DH-RSA-CAMELLIA128-SHA"
# define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA      "DHE-DSS-CAMELLIA128-SHA"
# define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA      "DHE-RSA-CAMELLIA128-SHA"
# define TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA          "ADH-CAMELLIA128-SHA"

# define TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA          "CAMELLIA256-SHA"
# define TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA       "DH-DSS-CAMELLIA256-SHA"
# define TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA       "DH-RSA-CAMELLIA256-SHA"
# define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA      "DHE-DSS-CAMELLIA256-SHA"
# define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA      "DHE-RSA-CAMELLIA256-SHA"
# define TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA          "ADH-CAMELLIA256-SHA"

/* SEED ciphersuites from RFC4162 */
# define TLS1_TXT_RSA_WITH_SEED_SHA                      "SEED-SHA"
# define TLS1_TXT_DH_DSS_WITH_SEED_SHA                   "DH-DSS-SEED-SHA"
# define TLS1_TXT_DH_RSA_WITH_SEED_SHA                   "DH-RSA-SEED-SHA"
# define TLS1_TXT_DHE_DSS_WITH_SEED_SHA                  "DHE-DSS-SEED-SHA"
# define TLS1_TXT_DHE_RSA_WITH_SEED_SHA                  "DHE-RSA-SEED-SHA"
# define TLS1_TXT_ADH_WITH_SEED_SHA                      "ADH-SEED-SHA"

/* TLS v1.2 ciphersuites */
# define TLS1_TXT_RSA_WITH_NULL_SHA256                   "NULL-SHA256"
# define TLS1_TXT_RSA_WITH_AES_128_SHA256                "AES128-SHA256"
# define TLS1_TXT_RSA_WITH_AES_256_SHA256                "AES256-SHA256"
# define TLS1_TXT_DH_DSS_WITH_AES_128_SHA256             "DH-DSS-AES128-SHA256"
# define TLS1_TXT_DH_RSA_WITH_AES_128_SHA256             "DH-RSA-AES128-SHA256"
# define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA256            "DHE-DSS-AES128-SHA256"
# define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256            "DHE-RSA-AES128-SHA256"
# define TLS1_TXT_DH_DSS_WITH_AES_256_SHA256             "DH-DSS-AES256-SHA256"
# define TLS1_TXT_DH_RSA_WITH_AES_256_SHA256             "DH-RSA-AES256-SHA256"
# define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA256            "DHE-DSS-AES256-SHA256"
# define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256            "DHE-RSA-AES256-SHA256"
# define TLS1_TXT_ADH_WITH_AES_128_SHA256                "ADH-AES128-SHA256"
# define TLS1_TXT_ADH_WITH_AES_256_SHA256                "ADH-AES256-SHA256"

/* TLS v1.2 GCM ciphersuites from RFC5288 */
# define TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256            "AES128-GCM-SHA256"
# define TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384            "AES256-GCM-SHA384"
# define TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256        "DHE-RSA-AES128-GCM-SHA256"
# define TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384        "DHE-RSA-AES256-GCM-SHA384"
# define TLS1_TXT_DH_RSA_WITH_AES_128_GCM_SHA256         "DH-RSA-AES128-GCM-SHA256"
# define TLS1_TXT_DH_RSA_WITH_AES_256_GCM_SHA384         "DH-RSA-AES256-GCM-SHA384"
# define TLS1_TXT_DHE_DSS_WITH_AES_128_GCM_SHA256        "DHE-DSS-AES128-GCM-SHA256"
# define TLS1_TXT_DHE_DSS_WITH_AES_256_GCM_SHA384        "DHE-DSS-AES256-GCM-SHA384"
# define TLS1_TXT_DH_DSS_WITH_AES_128_GCM_SHA256         "DH-DSS-AES128-GCM-SHA256"
# define TLS1_TXT_DH_DSS_WITH_AES_256_GCM_SHA384         "DH-DSS-AES256-GCM-SHA384"
# define TLS1_TXT_ADH_WITH_AES_128_GCM_SHA256            "ADH-AES128-GCM-SHA256"
# define TLS1_TXT_ADH_WITH_AES_256_GCM_SHA384            "ADH-AES256-GCM-SHA384"

/* ECDH HMAC based ciphersuites from RFC5289 */

# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256    "ECDHE-ECDSA-AES128-SHA256"
# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384    "ECDHE-ECDSA-AES256-SHA384"
# define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_SHA256     "ECDH-ECDSA-AES128-SHA256"
# define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_SHA384     "ECDH-ECDSA-AES256-SHA384"
# define TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256      "ECDHE-RSA-AES128-SHA256"
# define TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384      "ECDHE-RSA-AES256-SHA384"
# define TLS1_TXT_ECDH_RSA_WITH_AES_128_SHA256       "ECDH-RSA-AES128-SHA256"
# define TLS1_TXT_ECDH_RSA_WITH_AES_256_SHA384       "ECDH-RSA-AES256-SHA384"

/* ECDH GCM based ciphersuites from RFC5289 */
# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256    "ECDHE-ECDSA-AES128-GCM-SHA256"
# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384    "ECDHE-ECDSA-AES256-GCM-SHA384"
# define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_GCM_SHA256     "ECDH-ECDSA-AES128-GCM-SHA256"
# define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_GCM_SHA384     "ECDH-ECDSA-AES256-GCM-SHA384"
# define TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256      "ECDHE-RSA-AES128-GCM-SHA256"
# define TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384      "ECDHE-RSA-AES256-GCM-SHA384"
# define TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256       "ECDH-RSA-AES128-GCM-SHA256"
# define TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384       "ECDH-RSA-AES256-GCM-SHA384"

# define TLS_CT_RSA_SIGN                 1
# define TLS_CT_DSS_SIGN                 2
# define TLS_CT_RSA_FIXED_DH             3
# define TLS_CT_DSS_FIXED_DH             4
# define TLS_CT_ECDSA_SIGN               64
# define TLS_CT_RSA_FIXED_ECDH           65
# define TLS_CT_ECDSA_FIXED_ECDH         66
# define TLS_CT_GOST94_SIGN              21
# define TLS_CT_GOST01_SIGN              22
/*
 * when correcting this number, correct also SSL3_CT_NUMBER in ssl3.h (see
 * comment there)
 */
# define TLS_CT_NUMBER                   9

# define TLS1_FINISH_MAC_LENGTH          12

# define TLS_MD_MAX_CONST_SIZE                   20
# define TLS_MD_CLIENT_FINISH_CONST              "client finished"
# define TLS_MD_CLIENT_FINISH_CONST_SIZE         15
# define TLS_MD_SERVER_FINISH_CONST              "server finished"
# define TLS_MD_SERVER_FINISH_CONST_SIZE         15
# define TLS_MD_SERVER_WRITE_KEY_CONST           "server write key"
# define TLS_MD_SERVER_WRITE_KEY_CONST_SIZE      16
# define TLS_MD_KEY_EXPANSION_CONST              "key expansion"
# define TLS_MD_KEY_EXPANSION_CONST_SIZE         13
# define TLS_MD_CLIENT_WRITE_KEY_CONST           "client write key"
# define TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE      16
# define TLS_MD_SERVER_WRITE_KEY_CONST           "server write key"
# define TLS_MD_SERVER_WRITE_KEY_CONST_SIZE      16
# define TLS_MD_IV_BLOCK_CONST                   "IV block"
# define TLS_MD_IV_BLOCK_CONST_SIZE              8
# define TLS_MD_MASTER_SECRET_CONST              "master secret"
# define TLS_MD_MASTER_SECRET_CONST_SIZE         13

# ifdef CHARSET_EBCDIC
#  undef TLS_MD_CLIENT_FINISH_CONST
/*
 * client finished
 */
#  define TLS_MD_CLIENT_FINISH_CONST    "\x63\x6c\x69\x65\x6e\x74\x20\x66\x69\x6e\x69\x73\x68\x65\x64"

#  undef TLS_MD_SERVER_FINISH_CONST
/*
 * server finished
 */
#  define TLS_MD_SERVER_FINISH_CONST    "\x73\x65\x72\x76\x65\x72\x20\x66\x69\x6e\x69\x73\x68\x65\x64"

#  undef TLS_MD_SERVER_WRITE_KEY_CONST
/*
 * server write key
 */
#  define TLS_MD_SERVER_WRITE_KEY_CONST "\x73\x65\x72\x76\x65\x72\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79"

#  undef TLS_MD_KEY_EXPANSION_CONST
/*
 * key expansion
 */
#  define TLS_MD_KEY_EXPANSION_CONST    "\x6b\x65\x79\x20\x65\x78\x70\x61\x6e\x73\x69\x6f\x6e"

#  undef TLS_MD_CLIENT_WRITE_KEY_CONST
/*
 * client write key
 */
#  define TLS_MD_CLIENT_WRITE_KEY_CONST "\x63\x6c\x69\x65\x6e\x74\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79"

#  undef TLS_MD_SERVER_WRITE_KEY_CONST
/*
 * server write key
 */
#  define TLS_MD_SERVER_WRITE_KEY_CONST "\x73\x65\x72\x76\x65\x72\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79"

#  undef TLS_MD_IV_BLOCK_CONST
/*
 * IV block
 */
#  define TLS_MD_IV_BLOCK_CONST         "\x49\x56\x20\x62\x6c\x6f\x63\x6b"

#  undef TLS_MD_MASTER_SECRET_CONST
/*
 * master secret
 */
#  define TLS_MD_MASTER_SECRET_CONST    "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74"
# endif

/* TLS Session Ticket extension struct */
struct tls_session_ticket_ext_st {
    unsigned short length;
    void *data;
};

#ifdef  __cplusplus
}
#endif
#endif
openssl/x509.h000064400000150103151733316570007120 0ustar00/* crypto/x509/x509.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */
/* ====================================================================
 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
 * ECDH support in OpenSSL originally developed by
 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
 */

#ifndef HEADER_X509_H
# define HEADER_X509_H

# include <openssl/e_os2.h>
# include <openssl/symhacks.h>
# ifndef OPENSSL_NO_BUFFER
#  include <openssl/buffer.h>
# endif
# ifndef OPENSSL_NO_EVP
#  include <openssl/evp.h>
# endif
# ifndef OPENSSL_NO_BIO
#  include <openssl/bio.h>
# endif
# include <openssl/stack.h>
# include <openssl/asn1.h>
# include <openssl/safestack.h>

# ifndef OPENSSL_NO_EC
#  include <openssl/ec.h>
# endif

# ifndef OPENSSL_NO_ECDSA
#  include <openssl/ecdsa.h>
# endif

# ifndef OPENSSL_NO_ECDH
#  include <openssl/ecdh.h>
# endif

# ifndef OPENSSL_NO_DEPRECATED
#  ifndef OPENSSL_NO_RSA
#   include <openssl/rsa.h>
#  endif
#  ifndef OPENSSL_NO_DSA
#   include <openssl/dsa.h>
#  endif
#  ifndef OPENSSL_NO_DH
#   include <openssl/dh.h>
#  endif
# endif

# ifndef OPENSSL_NO_SHA
#  include <openssl/sha.h>
# endif
# include <openssl/ossl_typ.h>

#ifdef  __cplusplus
extern "C" {
#endif

# ifdef OPENSSL_SYS_WIN32
/* Under Win32 these are defined in wincrypt.h */
#  undef X509_NAME
#  undef X509_CERT_PAIR
#  undef X509_EXTENSIONS
# endif

# define X509_FILETYPE_PEM       1
# define X509_FILETYPE_ASN1      2
# define X509_FILETYPE_DEFAULT   3

# define X509v3_KU_DIGITAL_SIGNATURE     0x0080
# define X509v3_KU_NON_REPUDIATION       0x0040
# define X509v3_KU_KEY_ENCIPHERMENT      0x0020
# define X509v3_KU_DATA_ENCIPHERMENT     0x0010
# define X509v3_KU_KEY_AGREEMENT         0x0008
# define X509v3_KU_KEY_CERT_SIGN         0x0004
# define X509v3_KU_CRL_SIGN              0x0002
# define X509v3_KU_ENCIPHER_ONLY         0x0001
# define X509v3_KU_DECIPHER_ONLY         0x8000
# define X509v3_KU_UNDEF                 0xffff

typedef struct X509_objects_st {
    int nid;
    int (*a2i) (void);
    int (*i2a) (void);
} X509_OBJECTS;

struct X509_algor_st {
    ASN1_OBJECT *algorithm;
    ASN1_TYPE *parameter;
} /* X509_ALGOR */ ;

DECLARE_ASN1_SET_OF(X509_ALGOR)

typedef STACK_OF(X509_ALGOR) X509_ALGORS;

typedef struct X509_val_st {
    ASN1_TIME *notBefore;
    ASN1_TIME *notAfter;
} X509_VAL;

struct X509_pubkey_st {
    X509_ALGOR *algor;
    ASN1_BIT_STRING *public_key;
    EVP_PKEY *pkey;
};

typedef struct X509_sig_st {
    X509_ALGOR *algor;
    ASN1_OCTET_STRING *digest;
} X509_SIG;

typedef struct X509_name_entry_st {
    ASN1_OBJECT *object;
    ASN1_STRING *value;
    int set;
    int size;                   /* temp variable */
} X509_NAME_ENTRY;

DECLARE_STACK_OF(X509_NAME_ENTRY)
DECLARE_ASN1_SET_OF(X509_NAME_ENTRY)

/* we always keep X509_NAMEs in 2 forms. */
struct X509_name_st {
    STACK_OF(X509_NAME_ENTRY) *entries;
    int modified;               /* true if 'bytes' needs to be built */
# ifndef OPENSSL_NO_BUFFER
    BUF_MEM *bytes;
# else
    char *bytes;
# endif
/*      unsigned long hash; Keep the hash around for lookups */
    unsigned char *canon_enc;
    int canon_enclen;
} /* X509_NAME */ ;

DECLARE_STACK_OF(X509_NAME)

# define X509_EX_V_NETSCAPE_HACK         0x8000
# define X509_EX_V_INIT                  0x0001
typedef struct X509_extension_st {
    ASN1_OBJECT *object;
    ASN1_BOOLEAN critical;
    ASN1_OCTET_STRING *value;
} X509_EXTENSION;

typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS;

DECLARE_STACK_OF(X509_EXTENSION)
DECLARE_ASN1_SET_OF(X509_EXTENSION)

/* a sequence of these are used */
typedef struct x509_attributes_st {
    ASN1_OBJECT *object;
    int single;                 /* 0 for a set, 1 for a single item (which is
                                 * wrong) */
    union {
        char *ptr;
        /*
         * 0
         */ STACK_OF(ASN1_TYPE) *set;
        /*
         * 1
         */ ASN1_TYPE *single;
    } value;
} X509_ATTRIBUTE;

DECLARE_STACK_OF(X509_ATTRIBUTE)
DECLARE_ASN1_SET_OF(X509_ATTRIBUTE)

typedef struct X509_req_info_st {
    ASN1_ENCODING enc;
    ASN1_INTEGER *version;
    X509_NAME *subject;
    X509_PUBKEY *pubkey;
    /*  d=2 hl=2 l=  0 cons: cont: 00 */
    STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
} X509_REQ_INFO;

typedef struct X509_req_st {
    X509_REQ_INFO *req_info;
    X509_ALGOR *sig_alg;
    ASN1_BIT_STRING *signature;
    int references;
} X509_REQ;

typedef struct x509_cinf_st {
    ASN1_INTEGER *version;      /* [ 0 ] default of v1 */
    ASN1_INTEGER *serialNumber;
    X509_ALGOR *signature;
    X509_NAME *issuer;
    X509_VAL *validity;
    X509_NAME *subject;
    X509_PUBKEY *key;
    ASN1_BIT_STRING *issuerUID; /* [ 1 ] optional in v2 */
    ASN1_BIT_STRING *subjectUID; /* [ 2 ] optional in v2 */
    STACK_OF(X509_EXTENSION) *extensions; /* [ 3 ] optional in v3 */
    ASN1_ENCODING enc;
} X509_CINF;

/*
 * This stuff is certificate "auxiliary info" it contains details which are
 * useful in certificate stores and databases. When used this is tagged onto
 * the end of the certificate itself
 */

typedef struct x509_cert_aux_st {
    STACK_OF(ASN1_OBJECT) *trust; /* trusted uses */
    STACK_OF(ASN1_OBJECT) *reject; /* rejected uses */
    ASN1_UTF8STRING *alias;     /* "friendly name" */
    ASN1_OCTET_STRING *keyid;   /* key id of private key */
    STACK_OF(X509_ALGOR) *other; /* other unspecified info */
} X509_CERT_AUX;

struct x509_st {
    X509_CINF *cert_info;
    X509_ALGOR *sig_alg;
    ASN1_BIT_STRING *signature;
    int valid;
    int references;
    char *name;
    CRYPTO_EX_DATA ex_data;
    /* These contain copies of various extension values */
    long ex_pathlen;
    long ex_pcpathlen;
    unsigned long ex_flags;
    unsigned long ex_kusage;
    unsigned long ex_xkusage;
    unsigned long ex_nscert;
    ASN1_OCTET_STRING *skid;
    AUTHORITY_KEYID *akid;
    X509_POLICY_CACHE *policy_cache;
    STACK_OF(DIST_POINT) *crldp;
    STACK_OF(GENERAL_NAME) *altname;
    NAME_CONSTRAINTS *nc;
# ifndef OPENSSL_NO_RFC3779
    STACK_OF(IPAddressFamily) *rfc3779_addr;
    struct ASIdentifiers_st *rfc3779_asid;
# endif
# ifndef OPENSSL_NO_SHA
    unsigned char sha1_hash[SHA_DIGEST_LENGTH];
# endif
    X509_CERT_AUX *aux;
} /* X509 */ ;

DECLARE_STACK_OF(X509)
DECLARE_ASN1_SET_OF(X509)

/* This is used for a table of trust checking functions */

typedef struct x509_trust_st {
    int trust;
    int flags;
    int (*check_trust) (struct x509_trust_st *, X509 *, int);
    char *name;
    int arg1;
    void *arg2;
} X509_TRUST;

DECLARE_STACK_OF(X509_TRUST)

typedef struct x509_cert_pair_st {
    X509 *forward;
    X509 *reverse;
} X509_CERT_PAIR;

/* standard trust ids */

# define X509_TRUST_DEFAULT      -1/* Only valid in purpose settings */

# define X509_TRUST_COMPAT       1
# define X509_TRUST_SSL_CLIENT   2
# define X509_TRUST_SSL_SERVER   3
# define X509_TRUST_EMAIL        4
# define X509_TRUST_OBJECT_SIGN  5
# define X509_TRUST_OCSP_SIGN    6
# define X509_TRUST_OCSP_REQUEST 7
# define X509_TRUST_TSA          8

/* Keep these up to date! */
# define X509_TRUST_MIN          1
# define X509_TRUST_MAX          8

/* trust_flags values */
# define X509_TRUST_DYNAMIC      1
# define X509_TRUST_DYNAMIC_NAME 2

/* check_trust return codes */

# define X509_TRUST_TRUSTED      1
# define X509_TRUST_REJECTED     2
# define X509_TRUST_UNTRUSTED    3

/* Flags for X509_print_ex() */

# define X509_FLAG_COMPAT                0
# define X509_FLAG_NO_HEADER             1L
# define X509_FLAG_NO_VERSION            (1L << 1)
# define X509_FLAG_NO_SERIAL             (1L << 2)
# define X509_FLAG_NO_SIGNAME            (1L << 3)
# define X509_FLAG_NO_ISSUER             (1L << 4)
# define X509_FLAG_NO_VALIDITY           (1L << 5)
# define X509_FLAG_NO_SUBJECT            (1L << 6)
# define X509_FLAG_NO_PUBKEY             (1L << 7)
# define X509_FLAG_NO_EXTENSIONS         (1L << 8)
# define X509_FLAG_NO_SIGDUMP            (1L << 9)
# define X509_FLAG_NO_AUX                (1L << 10)
# define X509_FLAG_NO_ATTRIBUTES         (1L << 11)
# define X509_FLAG_NO_IDS                (1L << 12)

/* Flags specific to X509_NAME_print_ex() */

/* The field separator information */

# define XN_FLAG_SEP_MASK        (0xf << 16)

# define XN_FLAG_COMPAT          0/* Traditional SSLeay: use old
                                   * X509_NAME_print */
# define XN_FLAG_SEP_COMMA_PLUS  (1 << 16)/* RFC2253 ,+ */
# define XN_FLAG_SEP_CPLUS_SPC   (2 << 16)/* ,+ spaced: more readable */
# define XN_FLAG_SEP_SPLUS_SPC   (3 << 16)/* ;+ spaced */
# define XN_FLAG_SEP_MULTILINE   (4 << 16)/* One line per field */

# define XN_FLAG_DN_REV          (1 << 20)/* Reverse DN order */

/* How the field name is shown */

# define XN_FLAG_FN_MASK         (0x3 << 21)

# define XN_FLAG_FN_SN           0/* Object short name */
# define XN_FLAG_FN_LN           (1 << 21)/* Object long name */
# define XN_FLAG_FN_OID          (2 << 21)/* Always use OIDs */
# define XN_FLAG_FN_NONE         (3 << 21)/* No field names */

# define XN_FLAG_SPC_EQ          (1 << 23)/* Put spaces round '=' */

/*
 * This determines if we dump fields we don't recognise: RFC2253 requires
 * this.
 */

# define XN_FLAG_DUMP_UNKNOWN_FIELDS (1 << 24)

# define XN_FLAG_FN_ALIGN        (1 << 25)/* Align field names to 20
                                           * characters */

/* Complete set of RFC2253 flags */

# define XN_FLAG_RFC2253 (ASN1_STRFLGS_RFC2253 | \
                        XN_FLAG_SEP_COMMA_PLUS | \
                        XN_FLAG_DN_REV | \
                        XN_FLAG_FN_SN | \
                        XN_FLAG_DUMP_UNKNOWN_FIELDS)

/* readable oneline form */

# define XN_FLAG_ONELINE (ASN1_STRFLGS_RFC2253 | \
                        ASN1_STRFLGS_ESC_QUOTE | \
                        XN_FLAG_SEP_CPLUS_SPC | \
                        XN_FLAG_SPC_EQ | \
                        XN_FLAG_FN_SN)

/* readable multiline form */

# define XN_FLAG_MULTILINE (ASN1_STRFLGS_ESC_CTRL | \
                        ASN1_STRFLGS_ESC_MSB | \
                        XN_FLAG_SEP_MULTILINE | \
                        XN_FLAG_SPC_EQ | \
                        XN_FLAG_FN_LN | \
                        XN_FLAG_FN_ALIGN)

struct x509_revoked_st {
    ASN1_INTEGER *serialNumber;
    ASN1_TIME *revocationDate;
    STACK_OF(X509_EXTENSION) /* optional */ *extensions;
    /* Set up if indirect CRL */
    STACK_OF(GENERAL_NAME) *issuer;
    /* Revocation reason */
    int reason;
    int sequence;               /* load sequence */
};

DECLARE_STACK_OF(X509_REVOKED)
DECLARE_ASN1_SET_OF(X509_REVOKED)

typedef struct X509_crl_info_st {
    ASN1_INTEGER *version;
    X509_ALGOR *sig_alg;
    X509_NAME *issuer;
    ASN1_TIME *lastUpdate;
    ASN1_TIME *nextUpdate;
    STACK_OF(X509_REVOKED) *revoked;
    STACK_OF(X509_EXTENSION) /* [0] */ *extensions;
    ASN1_ENCODING enc;
} X509_CRL_INFO;

struct X509_crl_st {
    /* actual signature */
    X509_CRL_INFO *crl;
    X509_ALGOR *sig_alg;
    ASN1_BIT_STRING *signature;
    int references;
    int flags;
    /* Copies of various extensions */
    AUTHORITY_KEYID *akid;
    ISSUING_DIST_POINT *idp;
    /* Convenient breakdown of IDP */
    int idp_flags;
    int idp_reasons;
    /* CRL and base CRL numbers for delta processing */
    ASN1_INTEGER *crl_number;
    ASN1_INTEGER *base_crl_number;
# ifndef OPENSSL_NO_SHA
    unsigned char sha1_hash[SHA_DIGEST_LENGTH];
# endif
    STACK_OF(GENERAL_NAMES) *issuers;
    const X509_CRL_METHOD *meth;
    void *meth_data;
} /* X509_CRL */ ;

DECLARE_STACK_OF(X509_CRL)
DECLARE_ASN1_SET_OF(X509_CRL)

typedef struct private_key_st {
    int version;
    /* The PKCS#8 data types */
    X509_ALGOR *enc_algor;
    ASN1_OCTET_STRING *enc_pkey; /* encrypted pub key */
    /* When decrypted, the following will not be NULL */
    EVP_PKEY *dec_pkey;
    /* used to encrypt and decrypt */
    int key_length;
    char *key_data;
    int key_free;               /* true if we should auto free key_data */
    /* expanded version of 'enc_algor' */
    EVP_CIPHER_INFO cipher;
    int references;
} X509_PKEY;

# ifndef OPENSSL_NO_EVP
typedef struct X509_info_st {
    X509 *x509;
    X509_CRL *crl;
    X509_PKEY *x_pkey;
    EVP_CIPHER_INFO enc_cipher;
    int enc_len;
    char *enc_data;
    int references;
} X509_INFO;

DECLARE_STACK_OF(X509_INFO)
# endif

/*
 * The next 2 structures and their 8 routines were sent to me by Pat Richard
 * <patr@x509.com> and are used to manipulate Netscapes spki structures -
 * useful if you are writing a CA web page
 */
typedef struct Netscape_spkac_st {
    X509_PUBKEY *pubkey;
    ASN1_IA5STRING *challenge;  /* challenge sent in atlas >= PR2 */
} NETSCAPE_SPKAC;

typedef struct Netscape_spki_st {
    NETSCAPE_SPKAC *spkac;      /* signed public key and challenge */
    X509_ALGOR *sig_algor;
    ASN1_BIT_STRING *signature;
} NETSCAPE_SPKI;

/* Netscape certificate sequence structure */
typedef struct Netscape_certificate_sequence {
    ASN1_OBJECT *type;
    STACK_OF(X509) *certs;
} NETSCAPE_CERT_SEQUENCE;

/*- Unused (and iv length is wrong)
typedef struct CBCParameter_st
        {
        unsigned char iv[8];
        } CBC_PARAM;
*/

/* Password based encryption structure */

typedef struct PBEPARAM_st {
    ASN1_OCTET_STRING *salt;
    ASN1_INTEGER *iter;
} PBEPARAM;

/* Password based encryption V2 structures */

typedef struct PBE2PARAM_st {
    X509_ALGOR *keyfunc;
    X509_ALGOR *encryption;
} PBE2PARAM;

typedef struct PBKDF2PARAM_st {
/* Usually OCTET STRING but could be anything */
    ASN1_TYPE *salt;
    ASN1_INTEGER *iter;
    ASN1_INTEGER *keylength;
    X509_ALGOR *prf;
} PBKDF2PARAM;

/* PKCS#8 private key info structure */

struct pkcs8_priv_key_info_st {
    /* Flag for various broken formats */
    int broken;
# define PKCS8_OK                0
# define PKCS8_NO_OCTET          1
# define PKCS8_EMBEDDED_PARAM    2
# define PKCS8_NS_DB             3
# define PKCS8_NEG_PRIVKEY       4
    ASN1_INTEGER *version;
    X509_ALGOR *pkeyalg;
    /* Should be OCTET STRING but some are broken */
    ASN1_TYPE *pkey;
    STACK_OF(X509_ATTRIBUTE) *attributes;
};

#ifdef  __cplusplus
}
#endif

# include <openssl/x509_vfy.h>
# include <openssl/pkcs7.h>

#ifdef  __cplusplus
extern "C" {
#endif

# define X509_EXT_PACK_UNKNOWN   1
# define X509_EXT_PACK_STRING    2

# define         X509_get_version(x) ASN1_INTEGER_get((x)->cert_info->version)
/* #define      X509_get_serialNumber(x) ((x)->cert_info->serialNumber) */
# define         X509_get_notBefore(x) ((x)->cert_info->validity->notBefore)
# define         X509_get_notAfter(x) ((x)->cert_info->validity->notAfter)
# define         X509_extract_key(x)     X509_get_pubkey(x)/*****/
# define         X509_REQ_get_version(x) ASN1_INTEGER_get((x)->req_info->version)
# define         X509_REQ_get_subject_name(x) ((x)->req_info->subject)
# define         X509_REQ_extract_key(a) X509_REQ_get_pubkey(a)
# define         X509_name_cmp(a,b)      X509_NAME_cmp((a),(b))
# define         X509_get_signature_type(x) EVP_PKEY_type(OBJ_obj2nid((x)->sig_alg->algorithm))

# define         X509_CRL_get_version(x) ASN1_INTEGER_get((x)->crl->version)
# define         X509_CRL_get_lastUpdate(x) ((x)->crl->lastUpdate)
# define         X509_CRL_get_nextUpdate(x) ((x)->crl->nextUpdate)
# define         X509_CRL_get_issuer(x) ((x)->crl->issuer)
# define         X509_CRL_get_REVOKED(x) ((x)->crl->revoked)

void X509_CRL_set_default_method(const X509_CRL_METHOD *meth);
X509_CRL_METHOD *X509_CRL_METHOD_new(int (*crl_init) (X509_CRL *crl),
                                     int (*crl_free) (X509_CRL *crl),
                                     int (*crl_lookup) (X509_CRL *crl,
                                                        X509_REVOKED **ret,
                                                        ASN1_INTEGER *ser,
                                                        X509_NAME *issuer),
                                     int (*crl_verify) (X509_CRL *crl,
                                                        EVP_PKEY *pk));
void X509_CRL_METHOD_free(X509_CRL_METHOD *m);

void X509_CRL_set_meth_data(X509_CRL *crl, void *dat);
void *X509_CRL_get_meth_data(X509_CRL *crl);

/*
 * This one is only used so that a binary form can output, as in
 * i2d_X509_NAME(X509_get_X509_PUBKEY(x),&buf)
 */
# define         X509_get_X509_PUBKEY(x) ((x)->cert_info->key)

const char *X509_verify_cert_error_string(long n);

# ifndef OPENSSL_NO_EVP
int X509_verify(X509 *a, EVP_PKEY *r);

int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r);
int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r);
int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r);

NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, int len);
char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *x);
EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x);
int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey);

int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki);

int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent);
int X509_signature_print(BIO *bp, X509_ALGOR *alg, ASN1_STRING *sig);

int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx);
int X509_http_nbio(OCSP_REQ_CTX *rctx, X509 **pcert);
int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md);
int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx);
int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md);
int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx);
int X509_CRL_http_nbio(OCSP_REQ_CTX *rctx, X509_CRL **pcrl);
int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md);

int X509_pubkey_digest(const X509 *data, const EVP_MD *type,
                       unsigned char *md, unsigned int *len);
int X509_digest(const X509 *data, const EVP_MD *type,
                unsigned char *md, unsigned int *len);
int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type,
                    unsigned char *md, unsigned int *len);
int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type,
                    unsigned char *md, unsigned int *len);
int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type,
                     unsigned char *md, unsigned int *len);
# endif

# ifndef OPENSSL_NO_FP_API
X509 *d2i_X509_fp(FILE *fp, X509 **x509);
int i2d_X509_fp(FILE *fp, X509 *x509);
X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl);
int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl);
X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req);
int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req);
#  ifndef OPENSSL_NO_RSA
RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa);
int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa);
RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa);
int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa);
RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa);
int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa);
#  endif
#  ifndef OPENSSL_NO_DSA
DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa);
int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa);
DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa);
int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa);
#  endif
#  ifndef OPENSSL_NO_EC
EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey);
int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey);
EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey);
int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey);
#  endif
X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8);
int i2d_PKCS8_fp(FILE *fp, X509_SIG *p8);
PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,
                                                PKCS8_PRIV_KEY_INFO **p8inf);
int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf);
int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key);
int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey);
EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a);
int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey);
EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a);
# endif

# ifndef OPENSSL_NO_BIO
X509 *d2i_X509_bio(BIO *bp, X509 **x509);
int i2d_X509_bio(BIO *bp, X509 *x509);
X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl);
int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl);
X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req);
int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req);
#  ifndef OPENSSL_NO_RSA
RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa);
int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa);
RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa);
int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa);
RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa);
int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa);
#  endif
#  ifndef OPENSSL_NO_DSA
DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa);
int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa);
DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa);
int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa);
#  endif
#  ifndef OPENSSL_NO_EC
EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey);
int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *eckey);
EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey);
int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey);
#  endif
X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8);
int i2d_PKCS8_bio(BIO *bp, X509_SIG *p8);
PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,
                                                 PKCS8_PRIV_KEY_INFO **p8inf);
int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf);
int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key);
int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey);
EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a);
int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey);
EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a);
# endif

X509 *X509_dup(X509 *x509);
X509_ATTRIBUTE *X509_ATTRIBUTE_dup(X509_ATTRIBUTE *xa);
X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex);
X509_CRL *X509_CRL_dup(X509_CRL *crl);
X509_REVOKED *X509_REVOKED_dup(X509_REVOKED *rev);
X509_REQ *X509_REQ_dup(X509_REQ *req);
X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn);
int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype,
                    void *pval);
void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
                     X509_ALGOR *algor);
void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md);
int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b);

X509_NAME *X509_NAME_dup(X509_NAME *xn);
X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne);

int X509_cmp_time(const ASN1_TIME *s, time_t *t);
int X509_cmp_current_time(const ASN1_TIME *s);
ASN1_TIME *X509_time_adj(ASN1_TIME *s, long adj, time_t *t);
ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s,
                            int offset_day, long offset_sec, time_t *t);
ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj);

const char *X509_get_default_cert_area(void);
const char *X509_get_default_cert_dir(void);
const char *X509_get_default_cert_file(void);
const char *X509_get_default_cert_dir_env(void);
const char *X509_get_default_cert_file_env(void);
const char *X509_get_default_private_dir(void);

X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey);

DECLARE_ASN1_FUNCTIONS(X509_ALGOR)
DECLARE_ASN1_ENCODE_FUNCTIONS(X509_ALGORS, X509_ALGORS, X509_ALGORS)
DECLARE_ASN1_FUNCTIONS(X509_VAL)

DECLARE_ASN1_FUNCTIONS(X509_PUBKEY)

int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey);
EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key);
int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain);
int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp);
EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length);
# ifndef OPENSSL_NO_RSA
int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp);
RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length);
# endif
# ifndef OPENSSL_NO_DSA
int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp);
DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length);
# endif
# ifndef OPENSSL_NO_EC
int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp);
EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length);
# endif

DECLARE_ASN1_FUNCTIONS(X509_SIG)
DECLARE_ASN1_FUNCTIONS(X509_REQ_INFO)
DECLARE_ASN1_FUNCTIONS(X509_REQ)

DECLARE_ASN1_FUNCTIONS(X509_ATTRIBUTE)
X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value);

DECLARE_ASN1_FUNCTIONS(X509_EXTENSION)
DECLARE_ASN1_ENCODE_FUNCTIONS(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS)

DECLARE_ASN1_FUNCTIONS(X509_NAME_ENTRY)

DECLARE_ASN1_FUNCTIONS(X509_NAME)

int X509_NAME_set(X509_NAME **xn, X509_NAME *name);

DECLARE_ASN1_FUNCTIONS(X509_CINF)

DECLARE_ASN1_FUNCTIONS(X509)
DECLARE_ASN1_FUNCTIONS(X509_CERT_AUX)

DECLARE_ASN1_FUNCTIONS(X509_CERT_PAIR)

int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
                          CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
int X509_set_ex_data(X509 *r, int idx, void *arg);
void *X509_get_ex_data(X509 *r, int idx);
int i2d_X509_AUX(X509 *a, unsigned char **pp);
X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length);

int i2d_re_X509_tbs(X509 *x, unsigned char **pp);

void X509_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg,
                         const X509 *x);
int X509_get_signature_nid(const X509 *x);

int X509_alias_set1(X509 *x, unsigned char *name, int len);
int X509_keyid_set1(X509 *x, unsigned char *id, int len);
unsigned char *X509_alias_get0(X509 *x, int *len);
unsigned char *X509_keyid_get0(X509 *x, int *len);
int (*X509_TRUST_set_default(int (*trust) (int, X509 *, int))) (int, X509 *,
                                                                int);
int X509_TRUST_set(int *t, int trust);
int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj);
int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj);
void X509_trust_clear(X509 *x);
void X509_reject_clear(X509 *x);

DECLARE_ASN1_FUNCTIONS(X509_REVOKED)
DECLARE_ASN1_FUNCTIONS(X509_CRL_INFO)
DECLARE_ASN1_FUNCTIONS(X509_CRL)

int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev);
int X509_CRL_get0_by_serial(X509_CRL *crl,
                            X509_REVOKED **ret, ASN1_INTEGER *serial);
int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x);

X509_PKEY *X509_PKEY_new(void);
void X509_PKEY_free(X509_PKEY *a);
int i2d_X509_PKEY(X509_PKEY *a, unsigned char **pp);
X509_PKEY *d2i_X509_PKEY(X509_PKEY **a, const unsigned char **pp,
                         long length);

DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKI)
DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKAC)
DECLARE_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE)

# ifndef OPENSSL_NO_EVP
X509_INFO *X509_INFO_new(void);
void X509_INFO_free(X509_INFO *a);
char *X509_NAME_oneline(X509_NAME *a, char *buf, int size);

int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *algor1,
                ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey);

int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data,
                unsigned char *md, unsigned int *len);

int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1,
              X509_ALGOR *algor2, ASN1_BIT_STRING *signature,
              char *data, EVP_PKEY *pkey, const EVP_MD *type);

int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *data,
                     unsigned char *md, unsigned int *len);

int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1,
                     ASN1_BIT_STRING *signature, void *data, EVP_PKEY *pkey);

int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1,
                   X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *data,
                   EVP_PKEY *pkey, const EVP_MD *type);
int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1,
                       X509_ALGOR *algor2, ASN1_BIT_STRING *signature,
                       void *asn, EVP_MD_CTX *ctx);
# endif

int X509_set_version(X509 *x, long version);
int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial);
ASN1_INTEGER *X509_get_serialNumber(X509 *x);
int X509_set_issuer_name(X509 *x, X509_NAME *name);
X509_NAME *X509_get_issuer_name(X509 *a);
int X509_set_subject_name(X509 *x, X509_NAME *name);
X509_NAME *X509_get_subject_name(X509 *a);
int X509_set_notBefore(X509 *x, const ASN1_TIME *tm);
int X509_set_notAfter(X509 *x, const ASN1_TIME *tm);
int X509_set_pubkey(X509 *x, EVP_PKEY *pkey);
EVP_PKEY *X509_get_pubkey(X509 *x);
ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x);
int X509_certificate_type(X509 *x, EVP_PKEY *pubkey /* optional */ );

int X509_REQ_set_version(X509_REQ *x, long version);
int X509_REQ_set_subject_name(X509_REQ *req, X509_NAME *name);
int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey);
EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req);
int X509_REQ_extension_nid(int nid);
int *X509_REQ_get_extension_nids(void);
void X509_REQ_set_extension_nids(int *nids);
STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req);
int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
                                int nid);
int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts);
int X509_REQ_get_attr_count(const X509_REQ *req);
int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos);
int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj,
                             int lastpos);
X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc);
X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc);
int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr);
int X509_REQ_add1_attr_by_OBJ(X509_REQ *req,
                              const ASN1_OBJECT *obj, int type,
                              const unsigned char *bytes, int len);
int X509_REQ_add1_attr_by_NID(X509_REQ *req,
                              int nid, int type,
                              const unsigned char *bytes, int len);
int X509_REQ_add1_attr_by_txt(X509_REQ *req,
                              const char *attrname, int type,
                              const unsigned char *bytes, int len);

int X509_CRL_set_version(X509_CRL *x, long version);
int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name);
int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm);
int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm);
int X509_CRL_sort(X509_CRL *crl);

int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial);
int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm);

X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer,
                        EVP_PKEY *skey, const EVP_MD *md, unsigned int flags);

int X509_REQ_check_private_key(X509_REQ *x509, EVP_PKEY *pkey);

int X509_check_private_key(X509 *x509, EVP_PKEY *pkey);
int X509_chain_check_suiteb(int *perror_depth,
                            X509 *x, STACK_OF(X509) *chain,
                            unsigned long flags);
int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags);
STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain);

int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b);
unsigned long X509_issuer_and_serial_hash(X509 *a);

int X509_issuer_name_cmp(const X509 *a, const X509 *b);
unsigned long X509_issuer_name_hash(X509 *a);

int X509_subject_name_cmp(const X509 *a, const X509 *b);
unsigned long X509_subject_name_hash(X509 *x);

# ifndef OPENSSL_NO_MD5
unsigned long X509_issuer_name_hash_old(X509 *a);
unsigned long X509_subject_name_hash_old(X509 *x);
# endif

int X509_cmp(const X509 *a, const X509 *b);
int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b);
unsigned long X509_NAME_hash(X509_NAME *x);
unsigned long X509_NAME_hash_old(X509_NAME *x);

int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b);
int X509_CRL_match(const X509_CRL *a, const X509_CRL *b);
# ifndef OPENSSL_NO_FP_API
int X509_print_ex_fp(FILE *bp, X509 *x, unsigned long nmflag,
                     unsigned long cflag);
int X509_print_fp(FILE *bp, X509 *x);
int X509_CRL_print_fp(FILE *bp, X509_CRL *x);
int X509_REQ_print_fp(FILE *bp, X509_REQ *req);
int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent,
                          unsigned long flags);
# endif

# ifndef OPENSSL_NO_BIO
int X509_NAME_print(BIO *bp, X509_NAME *name, int obase);
int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent,
                       unsigned long flags);
int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflag,
                  unsigned long cflag);
int X509_print(BIO *bp, X509 *x);
int X509_ocspid_print(BIO *bp, X509 *x);
int X509_CERT_AUX_print(BIO *bp, X509_CERT_AUX *x, int indent);
int X509_CRL_print(BIO *bp, X509_CRL *x);
int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag,
                      unsigned long cflag);
int X509_REQ_print(BIO *bp, X509_REQ *req);
# endif

int X509_NAME_entry_count(X509_NAME *name);
int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len);
int X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj,
                              char *buf, int len);

/*
 * NOTE: you should be passsing -1, not 0 as lastpos.  The functions that use
 * lastpos, search after that position on.
 */
int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos);
int X509_NAME_get_index_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj,
                               int lastpos);
X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc);
X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc);
int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne,
                        int loc, int set);
int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type,
                               unsigned char *bytes, int len, int loc,
                               int set);
int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type,
                               unsigned char *bytes, int len, int loc,
                               int set);
X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
                                               const char *field, int type,
                                               const unsigned char *bytes,
                                               int len);
X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
                                               int type, unsigned char *bytes,
                                               int len);
int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type,
                               const unsigned char *bytes, int len, int loc,
                               int set);
X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
                                               ASN1_OBJECT *obj, int type,
                                               const unsigned char *bytes,
                                               int len);
int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, ASN1_OBJECT *obj);
int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
                             const unsigned char *bytes, int len);
ASN1_OBJECT *X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne);
ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne);

int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x);
int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x,
                          int nid, int lastpos);
int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x,
                          ASN1_OBJECT *obj, int lastpos);
int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x,
                               int crit, int lastpos);
X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc);
X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc);
STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
                                         X509_EXTENSION *ex, int loc);

int X509_get_ext_count(X509 *x);
int X509_get_ext_by_NID(X509 *x, int nid, int lastpos);
int X509_get_ext_by_OBJ(X509 *x, ASN1_OBJECT *obj, int lastpos);
int X509_get_ext_by_critical(X509 *x, int crit, int lastpos);
X509_EXTENSION *X509_get_ext(X509 *x, int loc);
X509_EXTENSION *X509_delete_ext(X509 *x, int loc);
int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
void *X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx);
int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit,
                      unsigned long flags);

int X509_CRL_get_ext_count(X509_CRL *x);
int X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos);
int X509_CRL_get_ext_by_OBJ(X509_CRL *x, ASN1_OBJECT *obj, int lastpos);
int X509_CRL_get_ext_by_critical(X509_CRL *x, int crit, int lastpos);
X509_EXTENSION *X509_CRL_get_ext(X509_CRL *x, int loc);
X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc);
int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc);
void *X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx);
int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit,
                          unsigned long flags);

int X509_REVOKED_get_ext_count(X509_REVOKED *x);
int X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos);
int X509_REVOKED_get_ext_by_OBJ(X509_REVOKED *x, ASN1_OBJECT *obj,
                                int lastpos);
int X509_REVOKED_get_ext_by_critical(X509_REVOKED *x, int crit, int lastpos);
X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *x, int loc);
X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc);
int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc);
void *X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx);
int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit,
                              unsigned long flags);

X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex,
                                             int nid, int crit,
                                             ASN1_OCTET_STRING *data);
X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex,
                                             ASN1_OBJECT *obj, int crit,
                                             ASN1_OCTET_STRING *data);
int X509_EXTENSION_set_object(X509_EXTENSION *ex, ASN1_OBJECT *obj);
int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit);
int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data);
ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex);
ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne);
int X509_EXTENSION_get_critical(X509_EXTENSION *ex);

int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x);
int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid,
                           int lastpos);
int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk,
                           ASN1_OBJECT *obj, int lastpos);
X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc);
X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc);
STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
                                           X509_ATTRIBUTE *attr);
STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE)
                                                  **x, const ASN1_OBJECT *obj,
                                                  int type,
                                                  const unsigned char *bytes,
                                                  int len);
STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE)
                                                  **x, int nid, int type,
                                                  const unsigned char *bytes,
                                                  int len);
STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE)
                                                  **x, const char *attrname,
                                                  int type,
                                                  const unsigned char *bytes,
                                                  int len);
void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x, ASN1_OBJECT *obj,
                              int lastpos, int type);
X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid,
                                             int atrtype, const void *data,
                                             int len);
X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr,
                                             const ASN1_OBJECT *obj,
                                             int atrtype, const void *data,
                                             int len);
X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr,
                                             const char *atrname, int type,
                                             const unsigned char *bytes,
                                             int len);
int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj);
int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype,
                             const void *data, int len);
void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, int atrtype,
                               void *data);
int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr);
ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr);
ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx);

int EVP_PKEY_get_attr_count(const EVP_PKEY *key);
int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid, int lastpos);
int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, ASN1_OBJECT *obj,
                             int lastpos);
X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc);
X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc);
int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr);
int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key,
                              const ASN1_OBJECT *obj, int type,
                              const unsigned char *bytes, int len);
int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key,
                              int nid, int type,
                              const unsigned char *bytes, int len);
int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key,
                              const char *attrname, int type,
                              const unsigned char *bytes, int len);

int X509_verify_cert(X509_STORE_CTX *ctx);

/* lookup a cert from a X509 STACK */
X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name,
                                     ASN1_INTEGER *serial);
X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name);

DECLARE_ASN1_FUNCTIONS(PBEPARAM)
DECLARE_ASN1_FUNCTIONS(PBE2PARAM)
DECLARE_ASN1_FUNCTIONS(PBKDF2PARAM)

int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
                         const unsigned char *salt, int saltlen);

X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
                          const unsigned char *salt, int saltlen);
X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
                           unsigned char *salt, int saltlen);
X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
                              unsigned char *salt, int saltlen,
                              unsigned char *aiv, int prf_nid);

X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
                             int prf_nid, int keylen);

/* PKCS#8 utilities */

DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO)

EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8);
PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey);
PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken);
PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken);

int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj,
                    int version, int ptype, void *pval,
                    unsigned char *penc, int penclen);
int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg,
                    const unsigned char **pk, int *ppklen,
                    X509_ALGOR **pa, PKCS8_PRIV_KEY_INFO *p8);

int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj,
                           int ptype, void *pval,
                           unsigned char *penc, int penclen);
int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
                           const unsigned char **pk, int *ppklen,
                           X509_ALGOR **pa, X509_PUBKEY *pub);

int X509_check_trust(X509 *x, int id, int flags);
int X509_TRUST_get_count(void);
X509_TRUST *X509_TRUST_get0(int idx);
int X509_TRUST_get_by_id(int id);
int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int),
                   char *name, int arg1, void *arg2);
void X509_TRUST_cleanup(void);
int X509_TRUST_get_flags(X509_TRUST *xp);
char *X509_TRUST_get0_name(X509_TRUST *xp);
int X509_TRUST_get_trust(X509_TRUST *xp);

/* BEGIN ERROR CODES */
/*
 * The following lines are auto generated by the script mkerr.pl. Any changes
 * made after this point may be overwritten when the script is next run.
 */

void ERR_load_X509_strings(void);

/* Error codes for the X509 functions. */

/* Function codes. */
# define X509_F_ADD_CERT_DIR                              100
# define X509_F_BY_FILE_CTRL                              101
# define X509_F_CHECK_NAME_CONSTRAINTS                    106
# define X509_F_CHECK_POLICY                              145
# define X509_F_DIR_CTRL                                  102
# define X509_F_GET_CERT_BY_SUBJECT                       103
# define X509_F_NETSCAPE_SPKI_B64_DECODE                  129
# define X509_F_NETSCAPE_SPKI_B64_ENCODE                  130
# define X509_F_X509AT_ADD1_ATTR                          135
# define X509_F_X509V3_ADD_EXT                            104
# define X509_F_X509_ATTRIBUTE_CREATE_BY_NID              136
# define X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ              137
# define X509_F_X509_ATTRIBUTE_CREATE_BY_TXT              140
# define X509_F_X509_ATTRIBUTE_GET0_DATA                  139
# define X509_F_X509_ATTRIBUTE_SET1_DATA                  138
# define X509_F_X509_CHECK_PRIVATE_KEY                    128
# define X509_F_X509_CRL_DIFF                             105
# define X509_F_X509_CRL_PRINT_FP                         147
# define X509_F_X509_EXTENSION_CREATE_BY_NID              108
# define X509_F_X509_EXTENSION_CREATE_BY_OBJ              109
# define X509_F_X509_GET_PUBKEY_PARAMETERS                110
# define X509_F_X509_LOAD_CERT_CRL_FILE                   132
# define X509_F_X509_LOAD_CERT_FILE                       111
# define X509_F_X509_LOAD_CRL_FILE                        112
# define X509_F_X509_NAME_ADD_ENTRY                       113
# define X509_F_X509_NAME_ENTRY_CREATE_BY_NID             114
# define X509_F_X509_NAME_ENTRY_CREATE_BY_TXT             131
# define X509_F_X509_NAME_ENTRY_SET_OBJECT                115
# define X509_F_X509_NAME_ONELINE                         116
# define X509_F_X509_NAME_PRINT                           117
# define X509_F_X509_PRINT_EX_FP                          118
# define X509_F_X509_PUBKEY_GET                           119
# define X509_F_X509_PUBKEY_SET                           120
# define X509_F_X509_REQ_CHECK_PRIVATE_KEY                144
# define X509_F_X509_REQ_PRINT_EX                         121
# define X509_F_X509_REQ_PRINT_FP                         122
# define X509_F_X509_REQ_TO_X509                          123
# define X509_F_X509_STORE_ADD_CERT                       124
# define X509_F_X509_STORE_ADD_CRL                        125
# define X509_F_X509_STORE_CTX_GET1_ISSUER                146
# define X509_F_X509_STORE_CTX_INIT                       143
# define X509_F_X509_STORE_CTX_NEW                        142
# define X509_F_X509_STORE_CTX_PURPOSE_INHERIT            134
# define X509_F_X509_TO_X509_REQ                          126
# define X509_F_X509_TRUST_ADD                            133
# define X509_F_X509_TRUST_SET                            141
# define X509_F_X509_VERIFY_CERT                          127

/* Reason codes. */
# define X509_R_AKID_MISMATCH                             110
# define X509_R_BAD_X509_FILETYPE                         100
# define X509_R_BASE64_DECODE_ERROR                       118
# define X509_R_CANT_CHECK_DH_KEY                         114
# define X509_R_CERT_ALREADY_IN_HASH_TABLE                101
# define X509_R_CRL_ALREADY_DELTA                         127
# define X509_R_CRL_VERIFY_FAILURE                        131
# define X509_R_ERR_ASN1_LIB                              102
# define X509_R_IDP_MISMATCH                              128
# define X509_R_INVALID_DIRECTORY                         113
# define X509_R_INVALID_FIELD_NAME                        119
# define X509_R_INVALID_TRUST                             123
# define X509_R_ISSUER_MISMATCH                           129
# define X509_R_KEY_TYPE_MISMATCH                         115
# define X509_R_KEY_VALUES_MISMATCH                       116
# define X509_R_LOADING_CERT_DIR                          103
# define X509_R_LOADING_DEFAULTS                          104
# define X509_R_METHOD_NOT_SUPPORTED                      124
# define X509_R_NAME_TOO_LONG                             134
# define X509_R_NEWER_CRL_NOT_NEWER                       132
# define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY              105
# define X509_R_NO_CRL_NUMBER                             130
# define X509_R_PUBLIC_KEY_DECODE_ERROR                   125
# define X509_R_PUBLIC_KEY_ENCODE_ERROR                   126
# define X509_R_SHOULD_RETRY                              106
# define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN        107
# define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY            108
# define X509_R_UNKNOWN_KEY_TYPE                          117
# define X509_R_UNKNOWN_NID                               109
# define X509_R_UNKNOWN_PURPOSE_ID                        121
# define X509_R_UNKNOWN_TRUST_ID                          120
# define X509_R_UNSUPPORTED_ALGORITHM                     111
# define X509_R_WRONG_LOOKUP_TYPE                         112
# define X509_R_WRONG_TYPE                                122

# ifdef  __cplusplus
}
# endif
#endif
openssl/ec.h000064400000155403151733316570007012 0ustar00/* crypto/ec/ec.h */
/*
 * Originally written by Bodo Moeller for the OpenSSL project.
 */
/**
 * \file crypto/ec/ec.h Include file for the OpenSSL EC functions
 * \author Originally written by Bodo Moeller for the OpenSSL project
 */
/* ====================================================================
 * Copyright (c) 1998-2019 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */
/* ====================================================================
 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
 *
 * Portions of the attached software ("Contribution") are developed by
 * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
 *
 * The Contribution is licensed pursuant to the OpenSSL open source
 * license provided above.
 *
 * The elliptic curve binary polynomial software is originally written by
 * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
 *
 */

#ifndef HEADER_EC_H
# define HEADER_EC_H

# include <openssl/opensslconf.h>

# ifdef OPENSSL_NO_EC
#  error EC is disabled.
# endif

# include <openssl/asn1.h>
# include <openssl/symhacks.h>
# ifndef OPENSSL_NO_DEPRECATED
#  include <openssl/bn.h>
# endif

# ifdef  __cplusplus
extern "C" {
# elif defined(__SUNPRO_C)
#  if __SUNPRO_C >= 0x520
#   pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
#  endif
# endif

# ifndef OPENSSL_ECC_MAX_FIELD_BITS
#  define OPENSSL_ECC_MAX_FIELD_BITS 661
# endif

/** Enum for the point conversion form as defined in X9.62 (ECDSA)
 *  for the encoding of a elliptic curve point (x,y) */
typedef enum {
        /** the point is encoded as z||x, where the octet z specifies
         *  which solution of the quadratic equation y is  */
    POINT_CONVERSION_COMPRESSED = 2,
        /** the point is encoded as z||x||y, where z is the octet 0x04  */
    POINT_CONVERSION_UNCOMPRESSED = 4,
        /** the point is encoded as z||x||y, where the octet z specifies
         *  which solution of the quadratic equation y is  */
    POINT_CONVERSION_HYBRID = 6
} point_conversion_form_t;

typedef struct ec_method_st EC_METHOD;

typedef struct ec_group_st
    /*-
     EC_METHOD *meth;
     -- field definition
     -- curve coefficients
     -- optional generator with associated information (order, cofactor)
     -- optional extra data (precomputed table for fast computation of multiples of generator)
     -- ASN1 stuff
    */
    EC_GROUP;

typedef struct ec_point_st EC_POINT;

/********************************************************************/
/*               EC_METHODs for curves over GF(p)                   */
/********************************************************************/

/** Returns the basic GFp ec methods which provides the basis for the
 *  optimized methods.
 *  \return  EC_METHOD object
 */
const EC_METHOD *EC_GFp_simple_method(void);

/** Returns GFp methods using montgomery multiplication.
 *  \return  EC_METHOD object
 */
const EC_METHOD *EC_GFp_mont_method(void);

/** Returns GFp methods using optimized methods for NIST recommended curves
 *  \return  EC_METHOD object
 */
const EC_METHOD *EC_GFp_nist_method(void);

# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
/** Returns 64-bit optimized methods for nistp256
 *  \return  EC_METHOD object
 */
const EC_METHOD *EC_GFp_nistp256_method(void);

/** Returns 64-bit optimized methods for nistp521
 *  \return  EC_METHOD object
 */
const EC_METHOD *EC_GFp_nistp521_method(void);
# endif

# ifndef OPENSSL_NO_EC2M
/********************************************************************/
/*           EC_METHOD for curves over GF(2^m)                      */
/********************************************************************/

/** Returns the basic GF2m ec method
 *  \return  EC_METHOD object
 */
const EC_METHOD *EC_GF2m_simple_method(void);

# endif

/********************************************************************/
/*                   EC_GROUP functions                             */
/********************************************************************/

/** Creates a new EC_GROUP object
 *  \param   meth  EC_METHOD to use
 *  \return  newly created EC_GROUP object or NULL in case of an error.
 */
EC_GROUP *EC_GROUP_new(const EC_METHOD *meth);

/** Frees a EC_GROUP object
 *  \param  group  EC_GROUP object to be freed.
 */
void EC_GROUP_free(EC_GROUP *group);

/** Clears and frees a EC_GROUP object
 *  \param  group  EC_GROUP object to be cleared and freed.
 */
void EC_GROUP_clear_free(EC_GROUP *group);

/** Copies EC_GROUP objects. Note: both EC_GROUPs must use the same EC_METHOD.
 *  \param  dst  destination EC_GROUP object
 *  \param  src  source EC_GROUP object
 *  \return 1 on success and 0 if an error occurred.
 */
int EC_GROUP_copy(EC_GROUP *dst, const EC_GROUP *src);

/** Creates a new EC_GROUP object and copies the copies the content
 *  form src to the newly created EC_KEY object
 *  \param  src  source EC_GROUP object
 *  \return newly created EC_GROUP object or NULL in case of an error.
 */
EC_GROUP *EC_GROUP_dup(const EC_GROUP *src);

/** Returns the EC_METHOD of the EC_GROUP object.
 *  \param  group  EC_GROUP object
 *  \return EC_METHOD used in this EC_GROUP object.
 */
const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group);

/** Returns the field type of the EC_METHOD.
 *  \param  meth  EC_METHOD object
 *  \return NID of the underlying field type OID.
 */
int EC_METHOD_get_field_type(const EC_METHOD *meth);

/** Sets the generator and it's order/cofactor of a EC_GROUP object.
 *  \param  group      EC_GROUP object
 *  \param  generator  EC_POINT object with the generator.
 *  \param  order      the order of the group generated by the generator.
 *  \param  cofactor   the index of the sub-group generated by the generator
 *                     in the group of all points on the elliptic curve.
 *  \return 1 on success and 0 if an error occured
 */
int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
                           const BIGNUM *order, const BIGNUM *cofactor);

/** Returns the generator of a EC_GROUP object.
 *  \param  group  EC_GROUP object
 *  \return the currently used generator (possibly NULL).
 */
const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group);

/** Returns the montgomery data for order(Generator)
 *  \param  group  EC_GROUP object
 *  \return the currently used generator (possibly NULL).
*/
BN_MONT_CTX *EC_GROUP_get_mont_data(const EC_GROUP *group);

/** Gets the order of a EC_GROUP
 *  \param  group  EC_GROUP object
 *  \param  order  BIGNUM to which the order is copied
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occured
 */
int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx);

/** Gets the cofactor of a EC_GROUP
 *  \param  group     EC_GROUP object
 *  \param  cofactor  BIGNUM to which the cofactor is copied
 *  \param  ctx       BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occured
 */
int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
                          BN_CTX *ctx);

/** Sets the name of a EC_GROUP object
 *  \param  group  EC_GROUP object
 *  \param  nid    NID of the curve name OID
 */
void EC_GROUP_set_curve_name(EC_GROUP *group, int nid);

/** Returns the curve name of a EC_GROUP object
 *  \param  group  EC_GROUP object
 *  \return NID of the curve name OID or 0 if not set.
 */
int EC_GROUP_get_curve_name(const EC_GROUP *group);

void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag);
int EC_GROUP_get_asn1_flag(const EC_GROUP *group);

void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
                                        point_conversion_form_t form);
point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *);

unsigned char *EC_GROUP_get0_seed(const EC_GROUP *x);
size_t EC_GROUP_get_seed_len(const EC_GROUP *);
size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len);

/** Sets the parameter of a ec over GFp defined by y^2 = x^3 + a*x + b
 *  \param  group  EC_GROUP object
 *  \param  p      BIGNUM with the prime number
 *  \param  a      BIGNUM with parameter a of the equation
 *  \param  b      BIGNUM with parameter b of the equation
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occured
 */
int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
                           const BIGNUM *b, BN_CTX *ctx);

/** Gets the parameter of the ec over GFp defined by y^2 = x^3 + a*x + b
 *  \param  group  EC_GROUP object
 *  \param  p      BIGNUM for the prime number
 *  \param  a      BIGNUM for parameter a of the equation
 *  \param  b      BIGNUM for parameter b of the equation
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occured
 */
int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
                           BIGNUM *b, BN_CTX *ctx);

# ifndef OPENSSL_NO_EC2M
/** Sets the parameter of a ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b
 *  \param  group  EC_GROUP object
 *  \param  p      BIGNUM with the polynomial defining the underlying field
 *  \param  a      BIGNUM with parameter a of the equation
 *  \param  b      BIGNUM with parameter b of the equation
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occured
 */
int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
                            const BIGNUM *b, BN_CTX *ctx);

/** Gets the parameter of the ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b
 *  \param  group  EC_GROUP object
 *  \param  p      BIGNUM for the polynomial defining the underlying field
 *  \param  a      BIGNUM for parameter a of the equation
 *  \param  b      BIGNUM for parameter b of the equation
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occured
 */
int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
                            BIGNUM *b, BN_CTX *ctx);
# endif
/** Returns the number of bits needed to represent a field element
 *  \param  group  EC_GROUP object
 *  \return number of bits needed to represent a field element
 */
int EC_GROUP_get_degree(const EC_GROUP *group);

/** Checks whether the parameter in the EC_GROUP define a valid ec group
 *  \param  group  EC_GROUP object
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 if group is a valid ec group and 0 otherwise
 */
int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx);

/** Checks whether the discriminant of the elliptic curve is zero or not
 *  \param  group  EC_GROUP object
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 if the discriminant is not zero and 0 otherwise
 */
int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx);

/** Compares two EC_GROUP objects
 *  \param  a    first EC_GROUP object
 *  \param  b    second EC_GROUP object
 *  \param  ctx  BN_CTX object (optional)
 *  \return 0 if both groups are equal and 1 otherwise
 */
int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx);

/*
 * EC_GROUP_new_GF*() calls EC_GROUP_new() and EC_GROUP_set_GF*() after
 * choosing an appropriate EC_METHOD
 */

/** Creates a new EC_GROUP object with the specified parameters defined
 *  over GFp (defined by the equation y^2 = x^3 + a*x + b)
 *  \param  p    BIGNUM with the prime number
 *  \param  a    BIGNUM with the parameter a of the equation
 *  \param  b    BIGNUM with the parameter b of the equation
 *  \param  ctx  BN_CTX object (optional)
 *  \return newly created EC_GROUP object with the specified parameters
 */
EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
                                 const BIGNUM *b, BN_CTX *ctx);
# ifndef OPENSSL_NO_EC2M
/** Creates a new EC_GROUP object with the specified parameters defined
 *  over GF2m (defined by the equation y^2 + x*y = x^3 + a*x^2 + b)
 *  \param  p    BIGNUM with the polynomial defining the underlying field
 *  \param  a    BIGNUM with the parameter a of the equation
 *  \param  b    BIGNUM with the parameter b of the equation
 *  \param  ctx  BN_CTX object (optional)
 *  \return newly created EC_GROUP object with the specified parameters
 */
EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a,
                                  const BIGNUM *b, BN_CTX *ctx);
# endif
/** Creates a EC_GROUP object with a curve specified by a NID
 *  \param  nid  NID of the OID of the curve name
 *  \return newly created EC_GROUP object with specified curve or NULL
 *          if an error occurred
 */
EC_GROUP *EC_GROUP_new_by_curve_name(int nid);

/********************************************************************/
/*               handling of internal curves                        */
/********************************************************************/

typedef struct {
    int nid;
    const char *comment;
} EC_builtin_curve;

/*
 * EC_builtin_curves(EC_builtin_curve *r, size_t size) returns number of all
 * available curves or zero if a error occurred. In case r ist not zero
 * nitems EC_builtin_curve structures are filled with the data of the first
 * nitems internal groups
 */
size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems);

const char *EC_curve_nid2nist(int nid);
int EC_curve_nist2nid(const char *name);

/********************************************************************/
/*                    EC_POINT functions                            */
/********************************************************************/

/** Creates a new EC_POINT object for the specified EC_GROUP
 *  \param  group  EC_GROUP the underlying EC_GROUP object
 *  \return newly created EC_POINT object or NULL if an error occurred
 */
EC_POINT *EC_POINT_new(const EC_GROUP *group);

/** Frees a EC_POINT object
 *  \param  point  EC_POINT object to be freed
 */
void EC_POINT_free(EC_POINT *point);

/** Clears and frees a EC_POINT object
 *  \param  point  EC_POINT object to be cleared and freed
 */
void EC_POINT_clear_free(EC_POINT *point);

/** Copies EC_POINT object
 *  \param  dst  destination EC_POINT object
 *  \param  src  source EC_POINT object
 *  \return 1 on success and 0 if an error occured
 */
int EC_POINT_copy(EC_POINT *dst, const EC_POINT *src);

/** Creates a new EC_POINT object and copies the content of the supplied
 *  EC_POINT
 *  \param  src    source EC_POINT object
 *  \param  group  underlying the EC_GROUP object
 *  \return newly created EC_POINT object or NULL if an error occurred
 */
EC_POINT *EC_POINT_dup(const EC_POINT *src, const EC_GROUP *group);

/** Returns the EC_METHOD used in EC_POINT object
 *  \param  point  EC_POINT object
 *  \return the EC_METHOD used
 */
const EC_METHOD *EC_POINT_method_of(const EC_POINT *point);

/** Sets a point to infinity (neutral element)
 *  \param  group  underlying EC_GROUP object
 *  \param  point  EC_POINT to set to infinity
 *  \return 1 on success and 0 if an error occured
 */
int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point);

/** Sets the jacobian projective coordinates of a EC_POINT over GFp
 *  \param  group  underlying EC_GROUP object
 *  \param  p      EC_POINT object
 *  \param  x      BIGNUM with the x-coordinate
 *  \param  y      BIGNUM with the y-coordinate
 *  \param  z      BIGNUM with the z-coordinate
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occured
 */
int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group,
                                             EC_POINT *p, const BIGNUM *x,
                                             const BIGNUM *y, const BIGNUM *z,
                                             BN_CTX *ctx);

/** Gets the jacobian projective coordinates of a EC_POINT over GFp
 *  \param  group  underlying EC_GROUP object
 *  \param  p      EC_POINT object
 *  \param  x      BIGNUM for the x-coordinate
 *  \param  y      BIGNUM for the y-coordinate
 *  \param  z      BIGNUM for the z-coordinate
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occured
 */
int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
                                             const EC_POINT *p, BIGNUM *x,
                                             BIGNUM *y, BIGNUM *z,
                                             BN_CTX *ctx);

/** Sets the affine coordinates of a EC_POINT over GFp
 *  \param  group  underlying EC_GROUP object
 *  \param  p      EC_POINT object
 *  \param  x      BIGNUM with the x-coordinate
 *  \param  y      BIGNUM with the y-coordinate
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occured
 */
int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
                                        const BIGNUM *x, const BIGNUM *y,
                                        BN_CTX *ctx);

/** Gets the affine coordinates of a EC_POINT over GFp
 *  \param  group  underlying EC_GROUP object
 *  \param  p      EC_POINT object
 *  \param  x      BIGNUM for the x-coordinate
 *  \param  y      BIGNUM for the y-coordinate
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occured
 */
int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
                                        const EC_POINT *p, BIGNUM *x,
                                        BIGNUM *y, BN_CTX *ctx);

/** Sets the x9.62 compressed coordinates of a EC_POINT over GFp
 *  \param  group  underlying EC_GROUP object
 *  \param  p      EC_POINT object
 *  \param  x      BIGNUM with x-coordinate
 *  \param  y_bit  integer with the y-Bit (either 0 or 1)
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occured
 */
int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group,
                                            EC_POINT *p, const BIGNUM *x,
                                            int y_bit, BN_CTX *ctx);
# ifndef OPENSSL_NO_EC2M
/** Sets the affine coordinates of a EC_POINT over GF2m
 *  \param  group  underlying EC_GROUP object
 *  \param  p      EC_POINT object
 *  \param  x      BIGNUM with the x-coordinate
 *  \param  y      BIGNUM with the y-coordinate
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occured
 */
int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p,
                                         const BIGNUM *x, const BIGNUM *y,
                                         BN_CTX *ctx);

/** Gets the affine coordinates of a EC_POINT over GF2m
 *  \param  group  underlying EC_GROUP object
 *  \param  p      EC_POINT object
 *  \param  x      BIGNUM for the x-coordinate
 *  \param  y      BIGNUM for the y-coordinate
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occured
 */
int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group,
                                         const EC_POINT *p, BIGNUM *x,
                                         BIGNUM *y, BN_CTX *ctx);

/** Sets the x9.62 compressed coordinates of a EC_POINT over GF2m
 *  \param  group  underlying EC_GROUP object
 *  \param  p      EC_POINT object
 *  \param  x      BIGNUM with x-coordinate
 *  \param  y_bit  integer with the y-Bit (either 0 or 1)
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occured
 */
int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group,
                                             EC_POINT *p, const BIGNUM *x,
                                             int y_bit, BN_CTX *ctx);
# endif
/** Encodes a EC_POINT object to a octet string
 *  \param  group  underlying EC_GROUP object
 *  \param  p      EC_POINT object
 *  \param  form   point conversion form
 *  \param  buf    memory buffer for the result. If NULL the function returns
 *                 required buffer size.
 *  \param  len    length of the memory buffer
 *  \param  ctx    BN_CTX object (optional)
 *  \return the length of the encoded octet string or 0 if an error occurred
 */
size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *p,
                          point_conversion_form_t form,
                          unsigned char *buf, size_t len, BN_CTX *ctx);

/** Decodes a EC_POINT from a octet string
 *  \param  group  underlying EC_GROUP object
 *  \param  p      EC_POINT object
 *  \param  buf    memory buffer with the encoded ec point
 *  \param  len    length of the encoded ec point
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occured
 */
int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *p,
                       const unsigned char *buf, size_t len, BN_CTX *ctx);

/* other interfaces to point2oct/oct2point: */
BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *,
                          point_conversion_form_t form, BIGNUM *, BN_CTX *);
EC_POINT *EC_POINT_bn2point(const EC_GROUP *, const BIGNUM *,
                            EC_POINT *, BN_CTX *);
char *EC_POINT_point2hex(const EC_GROUP *, const EC_POINT *,
                         point_conversion_form_t form, BN_CTX *);
EC_POINT *EC_POINT_hex2point(const EC_GROUP *, const char *,
                             EC_POINT *, BN_CTX *);

/********************************************************************/
/*         functions for doing EC_POINT arithmetic                  */
/********************************************************************/

/** Computes the sum of two EC_POINT
 *  \param  group  underlying EC_GROUP object
 *  \param  r      EC_POINT object for the result (r = a + b)
 *  \param  a      EC_POINT object with the first summand
 *  \param  b      EC_POINT object with the second summand
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occured
 */
int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
                 const EC_POINT *b, BN_CTX *ctx);

/** Computes the double of a EC_POINT
 *  \param  group  underlying EC_GROUP object
 *  \param  r      EC_POINT object for the result (r = 2 * a)
 *  \param  a      EC_POINT object
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occured
 */
int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
                 BN_CTX *ctx);

/** Computes the inverse of a EC_POINT
 *  \param  group  underlying EC_GROUP object
 *  \param  a      EC_POINT object to be inverted (it's used for the result as well)
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occured
 */
int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx);

/** Checks whether the point is the neutral element of the group
 *  \param  group  the underlying EC_GROUP object
 *  \param  p      EC_POINT object
 *  \return 1 if the point is the neutral element and 0 otherwise
 */
int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *p);

/** Checks whether the point is on the curve
 *  \param  group  underlying EC_GROUP object
 *  \param  point  EC_POINT object to check
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 if point if on the curve and 0 otherwise
 */
int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
                         BN_CTX *ctx);

/** Compares two EC_POINTs
 *  \param  group  underlying EC_GROUP object
 *  \param  a      first EC_POINT object
 *  \param  b      second EC_POINT object
 *  \param  ctx    BN_CTX object (optional)
 *  \return 0 if both points are equal and a value != 0 otherwise
 */
int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
                 BN_CTX *ctx);

int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx);
int EC_POINTs_make_affine(const EC_GROUP *group, size_t num,
                          EC_POINT *points[], BN_CTX *ctx);

/** Computes r = generator * n sum_{i=0}^{num-1} p[i] * m[i]
 *  \param  group  underlying EC_GROUP object
 *  \param  r      EC_POINT object for the result
 *  \param  n      BIGNUM with the multiplier for the group generator (optional)
 *  \param  num    number futher summands
 *  \param  p      array of size num of EC_POINT objects
 *  \param  m      array of size num of BIGNUM objects
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occured
 */
int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n,
                  size_t num, const EC_POINT *p[], const BIGNUM *m[],
                  BN_CTX *ctx);

/** Computes r = generator * n + q * m
 *  \param  group  underlying EC_GROUP object
 *  \param  r      EC_POINT object for the result
 *  \param  n      BIGNUM with the multiplier for the group generator (optional)
 *  \param  q      EC_POINT object with the first factor of the second summand
 *  \param  m      BIGNUM with the second factor of the second summand
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occured
 */
int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n,
                 const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx);

/** Stores multiples of generator for faster point multiplication
 *  \param  group  EC_GROUP object
 *  \param  ctx    BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occured
 */
int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx);

/** Reports whether a precomputation has been done
 *  \param  group  EC_GROUP object
 *  \return 1 if a pre-computation has been done and 0 otherwise
 */
int EC_GROUP_have_precompute_mult(const EC_GROUP *group);

/********************************************************************/
/*                       ASN1 stuff                                 */
/********************************************************************/

/*
 * EC_GROUP_get_basis_type() returns the NID of the basis type used to
 * represent the field elements
 */
int EC_GROUP_get_basis_type(const EC_GROUP *);
# ifndef OPENSSL_NO_EC2M
int EC_GROUP_get_trinomial_basis(const EC_GROUP *, unsigned int *k);
int EC_GROUP_get_pentanomial_basis(const EC_GROUP *, unsigned int *k1,
                                   unsigned int *k2, unsigned int *k3);
# endif

# define OPENSSL_EC_NAMED_CURVE  0x001

typedef struct ecpk_parameters_st ECPKPARAMETERS;

EC_GROUP *d2i_ECPKParameters(EC_GROUP **, const unsigned char **in, long len);
int i2d_ECPKParameters(const EC_GROUP *, unsigned char **out);

# define d2i_ECPKParameters_bio(bp,x) ASN1_d2i_bio_of(EC_GROUP,NULL,d2i_ECPKParameters,bp,x)
# define i2d_ECPKParameters_bio(bp,x) ASN1_i2d_bio_of_const(EC_GROUP,i2d_ECPKParameters,bp,x)
# define d2i_ECPKParameters_fp(fp,x) (EC_GROUP *)ASN1_d2i_fp(NULL, \
                (char *(*)())d2i_ECPKParameters,(fp),(unsigned char **)(x))
# define i2d_ECPKParameters_fp(fp,x) ASN1_i2d_fp(i2d_ECPKParameters,(fp), \
                (unsigned char *)(x))

# ifndef OPENSSL_NO_BIO
int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off);
# endif
# ifndef OPENSSL_NO_FP_API
int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off);
# endif

/********************************************************************/
/*                      EC_KEY functions                            */
/********************************************************************/

typedef struct ec_key_st EC_KEY;

/* some values for the encoding_flag */
# define EC_PKEY_NO_PARAMETERS   0x001
# define EC_PKEY_NO_PUBKEY       0x002

/* some values for the flags field */
# define EC_FLAG_NON_FIPS_ALLOW  0x1
# define EC_FLAG_FIPS_CHECKED    0x2

/** Creates a new EC_KEY object.
 *  \return EC_KEY object or NULL if an error occurred.
 */
EC_KEY *EC_KEY_new(void);

int EC_KEY_get_flags(const EC_KEY *key);

void EC_KEY_set_flags(EC_KEY *key, int flags);

void EC_KEY_clear_flags(EC_KEY *key, int flags);

/** Creates a new EC_KEY object using a named curve as underlying
 *  EC_GROUP object.
 *  \param  nid  NID of the named curve.
 *  \return EC_KEY object or NULL if an error occurred.
 */
EC_KEY *EC_KEY_new_by_curve_name(int nid);

/** Frees a EC_KEY object.
 *  \param  key  EC_KEY object to be freed.
 */
void EC_KEY_free(EC_KEY *key);

/** Copies a EC_KEY object.
 *  \param  dst  destination EC_KEY object
 *  \param  src  src EC_KEY object
 *  \return dst or NULL if an error occurred.
 */
EC_KEY *EC_KEY_copy(EC_KEY *dst, const EC_KEY *src);

/** Creates a new EC_KEY object and copies the content from src to it.
 *  \param  src  the source EC_KEY object
 *  \return newly created EC_KEY object or NULL if an error occurred.
 */
EC_KEY *EC_KEY_dup(const EC_KEY *src);

/** Increases the internal reference count of a EC_KEY object.
 *  \param  key  EC_KEY object
 *  \return 1 on success and 0 if an error occurred.
 */
int EC_KEY_up_ref(EC_KEY *key);

/** Returns the EC_GROUP object of a EC_KEY object
 *  \param  key  EC_KEY object
 *  \return the EC_GROUP object (possibly NULL).
 */
const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key);

/** Sets the EC_GROUP of a EC_KEY object.
 *  \param  key    EC_KEY object
 *  \param  group  EC_GROUP to use in the EC_KEY object (note: the EC_KEY
 *                 object will use an own copy of the EC_GROUP).
 *  \return 1 on success and 0 if an error occurred.
 */
int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group);

/** Returns the private key of a EC_KEY object.
 *  \param  key  EC_KEY object
 *  \return a BIGNUM with the private key (possibly NULL).
 */
const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key);

/** Sets the private key of a EC_KEY object.
 *  \param  key  EC_KEY object
 *  \param  prv  BIGNUM with the private key (note: the EC_KEY object
 *               will use an own copy of the BIGNUM).
 *  \return 1 on success and 0 if an error occurred.
 */
int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *prv);

/** Returns the public key of a EC_KEY object.
 *  \param  key  the EC_KEY object
 *  \return a EC_POINT object with the public key (possibly NULL)
 */
const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key);

/** Sets the public key of a EC_KEY object.
 *  \param  key  EC_KEY object
 *  \param  pub  EC_POINT object with the public key (note: the EC_KEY object
 *               will use an own copy of the EC_POINT object).
 *  \return 1 on success and 0 if an error occurred.
 */
int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub);

unsigned EC_KEY_get_enc_flags(const EC_KEY *key);
void EC_KEY_set_enc_flags(EC_KEY *eckey, unsigned int flags);
point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key);
void EC_KEY_set_conv_form(EC_KEY *eckey, point_conversion_form_t cform);
/* functions to set/get method specific data  */
void *EC_KEY_get_key_method_data(EC_KEY *key,
                                 void *(*dup_func) (void *),
                                 void (*free_func) (void *),
                                 void (*clear_free_func) (void *));
/** Sets the key method data of an EC_KEY object, if none has yet been set.
 *  \param  key              EC_KEY object
 *  \param  data             opaque data to install.
 *  \param  dup_func         a function that duplicates |data|.
 *  \param  free_func        a function that frees |data|.
 *  \param  clear_free_func  a function that wipes and frees |data|.
 *  \return the previously set data pointer, or NULL if |data| was inserted.
 */
void *EC_KEY_insert_key_method_data(EC_KEY *key, void *data,
                                    void *(*dup_func) (void *),
                                    void (*free_func) (void *),
                                    void (*clear_free_func) (void *));
/* wrapper functions for the underlying EC_GROUP object */
void EC_KEY_set_asn1_flag(EC_KEY *eckey, int asn1_flag);

/** Creates a table of pre-computed multiples of the generator to
 *  accelerate further EC_KEY operations.
 *  \param  key  EC_KEY object
 *  \param  ctx  BN_CTX object (optional)
 *  \return 1 on success and 0 if an error occurred.
 */
int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx);

/** Creates a new ec private (and optional a new public) key.
 *  \param  key  EC_KEY object
 *  \return 1 on success and 0 if an error occurred.
 */
int EC_KEY_generate_key(EC_KEY *key);

/** Verifies that a private and/or public key is valid.
 *  \param  key  the EC_KEY object
 *  \return 1 on success and 0 otherwise.
 */
int EC_KEY_check_key(const EC_KEY *key);

/** Sets a public key from affine coordindates performing
 *  neccessary NIST PKV tests.
 *  \param  key  the EC_KEY object
 *  \param  x    public key x coordinate
 *  \param  y    public key y coordinate
 *  \return 1 on success and 0 otherwise.
 */
int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
                                             BIGNUM *y);

/********************************************************************/
/*        de- and encoding functions for SEC1 ECPrivateKey          */
/********************************************************************/

/** Decodes a private key from a memory buffer.
 *  \param  key  a pointer to a EC_KEY object which should be used (or NULL)
 *  \param  in   pointer to memory with the DER encoded private key
 *  \param  len  length of the DER encoded private key
 *  \return the decoded private key or NULL if an error occurred.
 */
EC_KEY *d2i_ECPrivateKey(EC_KEY **key, const unsigned char **in, long len);

/** Encodes a private key object and stores the result in a buffer.
 *  \param  key  the EC_KEY object to encode
 *  \param  out  the buffer for the result (if NULL the function returns number
 *               of bytes needed).
 *  \return 1 on success and 0 if an error occurred.
 */
int i2d_ECPrivateKey(EC_KEY *key, unsigned char **out);

/********************************************************************/
/*        de- and encoding functions for EC parameters              */
/********************************************************************/

/** Decodes ec parameter from a memory buffer.
 *  \param  key  a pointer to a EC_KEY object which should be used (or NULL)
 *  \param  in   pointer to memory with the DER encoded ec parameters
 *  \param  len  length of the DER encoded ec parameters
 *  \return a EC_KEY object with the decoded parameters or NULL if an error
 *          occurred.
 */
EC_KEY *d2i_ECParameters(EC_KEY **key, const unsigned char **in, long len);

/** Encodes ec parameter and stores the result in a buffer.
 *  \param  key  the EC_KEY object with ec paramters to encode
 *  \param  out  the buffer for the result (if NULL the function returns number
 *               of bytes needed).
 *  \return 1 on success and 0 if an error occurred.
 */
int i2d_ECParameters(EC_KEY *key, unsigned char **out);

/********************************************************************/
/*         de- and encoding functions for EC public key             */
/*         (octet string, not DER -- hence 'o2i' and 'i2o')         */
/********************************************************************/

/** Decodes a ec public key from a octet string.
 *  \param  key  a pointer to a EC_KEY object which should be used
 *  \param  in   memory buffer with the encoded public key
 *  \param  len  length of the encoded public key
 *  \return EC_KEY object with decoded public key or NULL if an error
 *          occurred.
 */
EC_KEY *o2i_ECPublicKey(EC_KEY **key, const unsigned char **in, long len);

/** Encodes a ec public key in an octet string.
 *  \param  key  the EC_KEY object with the public key
 *  \param  out  the buffer for the result (if NULL the function returns number
 *               of bytes needed).
 *  \return 1 on success and 0 if an error occurred
 */
int i2o_ECPublicKey(EC_KEY *key, unsigned char **out);

# ifndef OPENSSL_NO_BIO
/** Prints out the ec parameters on human readable form.
 *  \param  bp   BIO object to which the information is printed
 *  \param  key  EC_KEY object
 *  \return 1 on success and 0 if an error occurred
 */
int ECParameters_print(BIO *bp, const EC_KEY *key);

/** Prints out the contents of a EC_KEY object
 *  \param  bp   BIO object to which the information is printed
 *  \param  key  EC_KEY object
 *  \param  off  line offset
 *  \return 1 on success and 0 if an error occurred
 */
int EC_KEY_print(BIO *bp, const EC_KEY *key, int off);

# endif
# ifndef OPENSSL_NO_FP_API
/** Prints out the ec parameters on human readable form.
 *  \param  fp   file descriptor to which the information is printed
 *  \param  key  EC_KEY object
 *  \return 1 on success and 0 if an error occurred
 */
int ECParameters_print_fp(FILE *fp, const EC_KEY *key);

/** Prints out the contents of a EC_KEY object
 *  \param  fp   file descriptor to which the information is printed
 *  \param  key  EC_KEY object
 *  \param  off  line offset
 *  \return 1 on success and 0 if an error occurred
 */
int EC_KEY_print_fp(FILE *fp, const EC_KEY *key, int off);

# endif

# define ECParameters_dup(x) ASN1_dup_of(EC_KEY,i2d_ECParameters,d2i_ECParameters,x)

# ifndef __cplusplus
#  if defined(__SUNPRO_C)
#   if __SUNPRO_C >= 0x520
#    pragma error_messages (default,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
#   endif
#  endif
# endif

# define EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
                                EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN, \
                                EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, NULL)

# define EVP_PKEY_CTX_set_ec_param_enc(ctx, flag) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
                                EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN, \
                                EVP_PKEY_CTRL_EC_PARAM_ENC, flag, NULL)

# define EVP_PKEY_CTX_set_ecdh_cofactor_mode(ctx, flag) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
                                EVP_PKEY_OP_DERIVE, \
                                EVP_PKEY_CTRL_EC_ECDH_COFACTOR, flag, NULL)

# define EVP_PKEY_CTX_get_ecdh_cofactor_mode(ctx) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
                                EVP_PKEY_OP_DERIVE, \
                                EVP_PKEY_CTRL_EC_ECDH_COFACTOR, -2, NULL)

# define EVP_PKEY_CTX_set_ecdh_kdf_type(ctx, kdf) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
                                EVP_PKEY_OP_DERIVE, \
                                EVP_PKEY_CTRL_EC_KDF_TYPE, kdf, NULL)

# define EVP_PKEY_CTX_get_ecdh_kdf_type(ctx) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
                                EVP_PKEY_OP_DERIVE, \
                                EVP_PKEY_CTRL_EC_KDF_TYPE, -2, NULL)

# define EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, md) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
                                EVP_PKEY_OP_DERIVE, \
                                EVP_PKEY_CTRL_EC_KDF_MD, 0, (void *)md)

# define EVP_PKEY_CTX_get_ecdh_kdf_md(ctx, pmd) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
                                EVP_PKEY_OP_DERIVE, \
                                EVP_PKEY_CTRL_GET_EC_KDF_MD, 0, (void *)pmd)

# define EVP_PKEY_CTX_set_ecdh_kdf_outlen(ctx, len) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
                                EVP_PKEY_OP_DERIVE, \
                                EVP_PKEY_CTRL_EC_KDF_OUTLEN, len, NULL)

# define EVP_PKEY_CTX_get_ecdh_kdf_outlen(ctx, plen) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
                                EVP_PKEY_OP_DERIVE, \
                        EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN, 0, (void *)plen)

# define EVP_PKEY_CTX_set0_ecdh_kdf_ukm(ctx, p, plen) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
                                EVP_PKEY_OP_DERIVE, \
                                EVP_PKEY_CTRL_EC_KDF_UKM, plen, (void *)p)

# define EVP_PKEY_CTX_get0_ecdh_kdf_ukm(ctx, p) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
                                EVP_PKEY_OP_DERIVE, \
                                EVP_PKEY_CTRL_GET_EC_KDF_UKM, 0, (void *)p)

# define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID             (EVP_PKEY_ALG_CTRL + 1)
# define EVP_PKEY_CTRL_EC_PARAM_ENC                      (EVP_PKEY_ALG_CTRL + 2)
# define EVP_PKEY_CTRL_EC_ECDH_COFACTOR                  (EVP_PKEY_ALG_CTRL + 3)
# define EVP_PKEY_CTRL_EC_KDF_TYPE                       (EVP_PKEY_ALG_CTRL + 4)
# define EVP_PKEY_CTRL_EC_KDF_MD                         (EVP_PKEY_ALG_CTRL + 5)
# define EVP_PKEY_CTRL_GET_EC_KDF_MD                     (EVP_PKEY_ALG_CTRL + 6)
# define EVP_PKEY_CTRL_EC_KDF_OUTLEN                     (EVP_PKEY_ALG_CTRL + 7)
# define EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN                 (EVP_PKEY_ALG_CTRL + 8)
# define EVP_PKEY_CTRL_EC_KDF_UKM                        (EVP_PKEY_ALG_CTRL + 9)
# define EVP_PKEY_CTRL_GET_EC_KDF_UKM                    (EVP_PKEY_ALG_CTRL + 10)
/* KDF types */
# define EVP_PKEY_ECDH_KDF_NONE                          1
# define EVP_PKEY_ECDH_KDF_X9_62                         2

/* BEGIN ERROR CODES */
/*
 * The following lines are auto generated by the script mkerr.pl. Any changes
 * made after this point may be overwritten when the script is next run.
 */

void ERR_load_EC_strings(void);

/* Error codes for the EC functions. */

/* Function codes. */
# define EC_F_BN_TO_FELEM                                 224
# define EC_F_COMPUTE_WNAF                                143
# define EC_F_D2I_ECPARAMETERS                            144
# define EC_F_D2I_ECPKPARAMETERS                          145
# define EC_F_D2I_ECPRIVATEKEY                            146
# define EC_F_DO_EC_KEY_PRINT                             221
# define EC_F_ECDH_CMS_DECRYPT                            238
# define EC_F_ECDH_CMS_SET_SHARED_INFO                    239
# define EC_F_ECKEY_PARAM2TYPE                            223
# define EC_F_ECKEY_PARAM_DECODE                          212
# define EC_F_ECKEY_PRIV_DECODE                           213
# define EC_F_ECKEY_PRIV_ENCODE                           214
# define EC_F_ECKEY_PUB_DECODE                            215
# define EC_F_ECKEY_PUB_ENCODE                            216
# define EC_F_ECKEY_TYPE2PARAM                            220
# define EC_F_ECPARAMETERS_PRINT                          147
# define EC_F_ECPARAMETERS_PRINT_FP                       148
# define EC_F_ECPKPARAMETERS_PRINT                        149
# define EC_F_ECPKPARAMETERS_PRINT_FP                     150
# define EC_F_ECP_NISTZ256_GET_AFFINE                     240
# define EC_F_ECP_NISTZ256_MULT_PRECOMPUTE                243
# define EC_F_ECP_NISTZ256_POINTS_MUL                     241
# define EC_F_ECP_NISTZ256_PRE_COMP_NEW                   244
# define EC_F_ECP_NISTZ256_SET_WORDS                      245
# define EC_F_ECP_NISTZ256_WINDOWED_MUL                   242
# define EC_F_ECP_NIST_MOD_192                            203
# define EC_F_ECP_NIST_MOD_224                            204
# define EC_F_ECP_NIST_MOD_256                            205
# define EC_F_ECP_NIST_MOD_521                            206
# define EC_F_EC_ASN1_GROUP2CURVE                         153
# define EC_F_EC_ASN1_GROUP2FIELDID                       154
# define EC_F_EC_ASN1_GROUP2PARAMETERS                    155
# define EC_F_EC_ASN1_GROUP2PKPARAMETERS                  156
# define EC_F_EC_ASN1_PARAMETERS2GROUP                    157
# define EC_F_EC_ASN1_PKPARAMETERS2GROUP                  158
# define EC_F_EC_EX_DATA_SET_DATA                         211
# define EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY           208
# define EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT     159
# define EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE              195
# define EC_F_EC_GF2M_SIMPLE_OCT2POINT                    160
# define EC_F_EC_GF2M_SIMPLE_POINT2OCT                    161
# define EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES 162
# define EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES 163
# define EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES   164
# define EC_F_EC_GFP_MONT_FIELD_DECODE                    133
# define EC_F_EC_GFP_MONT_FIELD_ENCODE                    134
# define EC_F_EC_GFP_MONT_FIELD_MUL                       131
# define EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE                209
# define EC_F_EC_GFP_MONT_FIELD_SQR                       132
# define EC_F_EC_GFP_MONT_GROUP_SET_CURVE                 189
# define EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP             135
# define EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE             225
# define EC_F_EC_GFP_NISTP224_POINTS_MUL                  228
# define EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES 226
# define EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE             230
# define EC_F_EC_GFP_NISTP256_POINTS_MUL                  231
# define EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES 232
# define EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE             233
# define EC_F_EC_GFP_NISTP521_POINTS_MUL                  234
# define EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES 235
# define EC_F_EC_GFP_NIST_FIELD_MUL                       200
# define EC_F_EC_GFP_NIST_FIELD_SQR                       201
# define EC_F_EC_GFP_NIST_GROUP_SET_CURVE                 202
# define EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT      165
# define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE               166
# define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP           100
# define EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR           101
# define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE                   102
# define EC_F_EC_GFP_SIMPLE_OCT2POINT                     103
# define EC_F_EC_GFP_SIMPLE_POINT2OCT                     104
# define EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE            137
# define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES  167
# define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP 105
# define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES  168
# define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP 128
# define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES    169
# define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP 129
# define EC_F_EC_GROUP_CHECK                              170
# define EC_F_EC_GROUP_CHECK_DISCRIMINANT                 171
# define EC_F_EC_GROUP_COPY                               106
# define EC_F_EC_GROUP_GET0_GENERATOR                     139
# define EC_F_EC_GROUP_GET_COFACTOR                       140
# define EC_F_EC_GROUP_GET_CURVE_GF2M                     172
# define EC_F_EC_GROUP_GET_CURVE_GFP                      130
# define EC_F_EC_GROUP_GET_DEGREE                         173
# define EC_F_EC_GROUP_GET_ORDER                          141
# define EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS              193
# define EC_F_EC_GROUP_GET_TRINOMIAL_BASIS                194
# define EC_F_EC_GROUP_NEW                                108
# define EC_F_EC_GROUP_NEW_BY_CURVE_NAME                  174
# define EC_F_EC_GROUP_NEW_FROM_DATA                      175
# define EC_F_EC_GROUP_PRECOMPUTE_MULT                    142
# define EC_F_EC_GROUP_SET_CURVE_GF2M                     176
# define EC_F_EC_GROUP_SET_CURVE_GFP                      109
# define EC_F_EC_GROUP_SET_EXTRA_DATA                     110
# define EC_F_EC_GROUP_SET_GENERATOR                      111
# define EC_F_EC_KEY_CHECK_KEY                            177
# define EC_F_EC_KEY_COPY                                 178
# define EC_F_EC_KEY_GENERATE_KEY                         179
# define EC_F_EC_KEY_NEW                                  182
# define EC_F_EC_KEY_PRINT                                180
# define EC_F_EC_KEY_PRINT_FP                             181
# define EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES    229
# define EC_F_EC_POINTS_MAKE_AFFINE                       136
# define EC_F_EC_POINT_ADD                                112
# define EC_F_EC_POINT_CMP                                113
# define EC_F_EC_POINT_COPY                               114
# define EC_F_EC_POINT_DBL                                115
# define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M        183
# define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP         116
# define EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP    117
# define EC_F_EC_POINT_INVERT                             210
# define EC_F_EC_POINT_IS_AT_INFINITY                     118
# define EC_F_EC_POINT_IS_ON_CURVE                        119
# define EC_F_EC_POINT_MAKE_AFFINE                        120
# define EC_F_EC_POINT_MUL                                184
# define EC_F_EC_POINT_NEW                                121
# define EC_F_EC_POINT_OCT2POINT                          122
# define EC_F_EC_POINT_POINT2OCT                          123
# define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M        185
# define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP         124
# define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M    186
# define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP     125
# define EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP    126
# define EC_F_EC_POINT_SET_TO_INFINITY                    127
# define EC_F_EC_PRE_COMP_DUP                             207
# define EC_F_EC_PRE_COMP_NEW                             196
# define EC_F_EC_WNAF_MUL                                 187
# define EC_F_EC_WNAF_PRECOMPUTE_MULT                     188
# define EC_F_I2D_ECPARAMETERS                            190
# define EC_F_I2D_ECPKPARAMETERS                          191
# define EC_F_I2D_ECPRIVATEKEY                            192
# define EC_F_I2O_ECPUBLICKEY                             151
# define EC_F_NISTP224_PRE_COMP_NEW                       227
# define EC_F_NISTP256_PRE_COMP_NEW                       236
# define EC_F_NISTP521_PRE_COMP_NEW                       237
# define EC_F_O2I_ECPUBLICKEY                             152
# define EC_F_OLD_EC_PRIV_DECODE                          222
# define EC_F_PKEY_EC_CTRL                                197
# define EC_F_PKEY_EC_CTRL_STR                            198
# define EC_F_PKEY_EC_DERIVE                              217
# define EC_F_PKEY_EC_KEYGEN                              199
# define EC_F_PKEY_EC_PARAMGEN                            219
# define EC_F_PKEY_EC_SIGN                                218

/* Reason codes. */
# define EC_R_ASN1_ERROR                                  115
# define EC_R_ASN1_UNKNOWN_FIELD                          116
# define EC_R_BIGNUM_OUT_OF_RANGE                         144
# define EC_R_BUFFER_TOO_SMALL                            100
# define EC_R_COORDINATES_OUT_OF_RANGE                    146
# define EC_R_D2I_ECPKPARAMETERS_FAILURE                  117
# define EC_R_DECODE_ERROR                                142
# define EC_R_DISCRIMINANT_IS_ZERO                        118
# define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE                119
# define EC_R_FIELD_TOO_LARGE                             143
# define EC_R_GF2M_NOT_SUPPORTED                          147
# define EC_R_GROUP2PKPARAMETERS_FAILURE                  120
# define EC_R_I2D_ECPKPARAMETERS_FAILURE                  121
# define EC_R_INCOMPATIBLE_OBJECTS                        101
# define EC_R_INVALID_ARGUMENT                            112
# define EC_R_INVALID_COMPRESSED_POINT                    110
# define EC_R_INVALID_COMPRESSION_BIT                     109
# define EC_R_INVALID_CURVE                               141
# define EC_R_INVALID_DIGEST                              151
# define EC_R_INVALID_DIGEST_TYPE                         138
# define EC_R_INVALID_ENCODING                            102
# define EC_R_INVALID_FIELD                               103
# define EC_R_INVALID_FORM                                104
# define EC_R_INVALID_GROUP_ORDER                         122
# define EC_R_INVALID_PENTANOMIAL_BASIS                   132
# define EC_R_INVALID_PRIVATE_KEY                         123
# define EC_R_INVALID_TRINOMIAL_BASIS                     137
# define EC_R_KDF_PARAMETER_ERROR                         148
# define EC_R_KEYS_NOT_SET                                140
# define EC_R_MISSING_PARAMETERS                          124
# define EC_R_MISSING_PRIVATE_KEY                         125
# define EC_R_NOT_A_NIST_PRIME                            135
# define EC_R_NOT_A_SUPPORTED_NIST_PRIME                  136
# define EC_R_NOT_IMPLEMENTED                             126
# define EC_R_NOT_INITIALIZED                             111
# define EC_R_NO_FIELD_MOD                                133
# define EC_R_NO_PARAMETERS_SET                           139
# define EC_R_PASSED_NULL_PARAMETER                       134
# define EC_R_PEER_KEY_ERROR                              149
# define EC_R_PKPARAMETERS2GROUP_FAILURE                  127
# define EC_R_POINT_AT_INFINITY                           106
# define EC_R_POINT_IS_NOT_ON_CURVE                       107
# define EC_R_SHARED_INFO_ERROR                           150
# define EC_R_SLOT_FULL                                   108
# define EC_R_UNDEFINED_GENERATOR                         113
# define EC_R_UNDEFINED_ORDER                             128
# define EC_R_UNKNOWN_COFACTOR                            152
# define EC_R_UNKNOWN_GROUP                               129
# define EC_R_UNKNOWN_ORDER                               114
# define EC_R_UNSUPPORTED_FIELD                           131
# define EC_R_WRONG_CURVE_PARAMETERS                      145
# define EC_R_WRONG_ORDER                                 130

# ifdef  __cplusplus
}
# endif
#endif
openssl/x509v3.h000064400000116705151733316570007403 0ustar00/* x509v3.h */
/*
 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
 * 1999.
 */
/* ====================================================================
 * Copyright (c) 1999-2004 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */
#ifndef HEADER_X509V3_H
# define HEADER_X509V3_H

# include <openssl/bio.h>
# include <openssl/x509.h>
# include <openssl/conf.h>

#ifdef __cplusplus
extern "C" {
#endif

# ifdef OPENSSL_SYS_WIN32
/* Under Win32 these are defined in wincrypt.h */
#  undef X509_NAME
#  undef X509_CERT_PAIR
#  undef X509_EXTENSIONS
# endif

/* Forward reference */
struct v3_ext_method;
struct v3_ext_ctx;

/* Useful typedefs */

typedef void *(*X509V3_EXT_NEW)(void);
typedef void (*X509V3_EXT_FREE) (void *);
typedef void *(*X509V3_EXT_D2I)(void *, const unsigned char **, long);
typedef int (*X509V3_EXT_I2D) (void *, unsigned char **);
typedef STACK_OF(CONF_VALUE) *
    (*X509V3_EXT_I2V) (const struct v3_ext_method *method, void *ext,
                       STACK_OF(CONF_VALUE) *extlist);
typedef void *(*X509V3_EXT_V2I)(const struct v3_ext_method *method,
                                struct v3_ext_ctx *ctx,
                                STACK_OF(CONF_VALUE) *values);
typedef char *(*X509V3_EXT_I2S)(const struct v3_ext_method *method,
                                void *ext);
typedef void *(*X509V3_EXT_S2I)(const struct v3_ext_method *method,
                                struct v3_ext_ctx *ctx, const char *str);
typedef int (*X509V3_EXT_I2R) (const struct v3_ext_method *method, void *ext,
                               BIO *out, int indent);
typedef void *(*X509V3_EXT_R2I)(const struct v3_ext_method *method,
                                struct v3_ext_ctx *ctx, const char *str);

/* V3 extension structure */

struct v3_ext_method {
    int ext_nid;
    int ext_flags;
/* If this is set the following four fields are ignored */
    ASN1_ITEM_EXP *it;
/* Old style ASN1 calls */
    X509V3_EXT_NEW ext_new;
    X509V3_EXT_FREE ext_free;
    X509V3_EXT_D2I d2i;
    X509V3_EXT_I2D i2d;
/* The following pair is used for string extensions */
    X509V3_EXT_I2S i2s;
    X509V3_EXT_S2I s2i;
/* The following pair is used for multi-valued extensions */
    X509V3_EXT_I2V i2v;
    X509V3_EXT_V2I v2i;
/* The following are used for raw extensions */
    X509V3_EXT_I2R i2r;
    X509V3_EXT_R2I r2i;
    void *usr_data;             /* Any extension specific data */
};

typedef struct X509V3_CONF_METHOD_st {
    char *(*get_string) (void *db, char *section, char *value);
    STACK_OF(CONF_VALUE) *(*get_section) (void *db, char *section);
    void (*free_string) (void *db, char *string);
    void (*free_section) (void *db, STACK_OF(CONF_VALUE) *section);
} X509V3_CONF_METHOD;

/* Context specific info */
struct v3_ext_ctx {
# define CTX_TEST 0x1
    int flags;
    X509 *issuer_cert;
    X509 *subject_cert;
    X509_REQ *subject_req;
    X509_CRL *crl;
    X509V3_CONF_METHOD *db_meth;
    void *db;
/* Maybe more here */
};

typedef struct v3_ext_method X509V3_EXT_METHOD;

DECLARE_STACK_OF(X509V3_EXT_METHOD)

/* ext_flags values */
# define X509V3_EXT_DYNAMIC      0x1
# define X509V3_EXT_CTX_DEP      0x2
# define X509V3_EXT_MULTILINE    0x4

typedef BIT_STRING_BITNAME ENUMERATED_NAMES;

typedef struct BASIC_CONSTRAINTS_st {
    int ca;
    ASN1_INTEGER *pathlen;
} BASIC_CONSTRAINTS;

typedef struct PKEY_USAGE_PERIOD_st {
    ASN1_GENERALIZEDTIME *notBefore;
    ASN1_GENERALIZEDTIME *notAfter;
} PKEY_USAGE_PERIOD;

typedef struct otherName_st {
    ASN1_OBJECT *type_id;
    ASN1_TYPE *value;
} OTHERNAME;

typedef struct EDIPartyName_st {
    ASN1_STRING *nameAssigner;
    ASN1_STRING *partyName;
} EDIPARTYNAME;

typedef struct GENERAL_NAME_st {
# define GEN_OTHERNAME   0
# define GEN_EMAIL       1
# define GEN_DNS         2
# define GEN_X400        3
# define GEN_DIRNAME     4
# define GEN_EDIPARTY    5
# define GEN_URI         6
# define GEN_IPADD       7
# define GEN_RID         8
    int type;
    union {
        char *ptr;
        OTHERNAME *otherName;   /* otherName */
        ASN1_IA5STRING *rfc822Name;
        ASN1_IA5STRING *dNSName;
        ASN1_TYPE *x400Address;
        X509_NAME *directoryName;
        EDIPARTYNAME *ediPartyName;
        ASN1_IA5STRING *uniformResourceIdentifier;
        ASN1_OCTET_STRING *iPAddress;
        ASN1_OBJECT *registeredID;
        /* Old names */
        ASN1_OCTET_STRING *ip;  /* iPAddress */
        X509_NAME *dirn;        /* dirn */
        ASN1_IA5STRING *ia5;    /* rfc822Name, dNSName,
                                 * uniformResourceIdentifier */
        ASN1_OBJECT *rid;       /* registeredID */
        ASN1_TYPE *other;       /* x400Address */
    } d;
} GENERAL_NAME;

typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES;

typedef struct ACCESS_DESCRIPTION_st {
    ASN1_OBJECT *method;
    GENERAL_NAME *location;
} ACCESS_DESCRIPTION;

typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS;

typedef STACK_OF(ASN1_OBJECT) EXTENDED_KEY_USAGE;

DECLARE_STACK_OF(GENERAL_NAME)
DECLARE_ASN1_SET_OF(GENERAL_NAME)

DECLARE_STACK_OF(ACCESS_DESCRIPTION)
DECLARE_ASN1_SET_OF(ACCESS_DESCRIPTION)

typedef struct DIST_POINT_NAME_st {
    int type;
    union {
        GENERAL_NAMES *fullname;
        STACK_OF(X509_NAME_ENTRY) *relativename;
    } name;
/* If relativename then this contains the full distribution point name */
    X509_NAME *dpname;
} DIST_POINT_NAME;
/* All existing reasons */
# define CRLDP_ALL_REASONS       0x807f

# define CRL_REASON_NONE                         -1
# define CRL_REASON_UNSPECIFIED                  0
# define CRL_REASON_KEY_COMPROMISE               1
# define CRL_REASON_CA_COMPROMISE                2
# define CRL_REASON_AFFILIATION_CHANGED          3
# define CRL_REASON_SUPERSEDED                   4
# define CRL_REASON_CESSATION_OF_OPERATION       5
# define CRL_REASON_CERTIFICATE_HOLD             6
# define CRL_REASON_REMOVE_FROM_CRL              8
# define CRL_REASON_PRIVILEGE_WITHDRAWN          9
# define CRL_REASON_AA_COMPROMISE                10

struct DIST_POINT_st {
    DIST_POINT_NAME *distpoint;
    ASN1_BIT_STRING *reasons;
    GENERAL_NAMES *CRLissuer;
    int dp_reasons;
};

typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS;

DECLARE_STACK_OF(DIST_POINT)
DECLARE_ASN1_SET_OF(DIST_POINT)

struct AUTHORITY_KEYID_st {
    ASN1_OCTET_STRING *keyid;
    GENERAL_NAMES *issuer;
    ASN1_INTEGER *serial;
};

/* Strong extranet structures */

typedef struct SXNET_ID_st {
    ASN1_INTEGER *zone;
    ASN1_OCTET_STRING *user;
} SXNETID;

DECLARE_STACK_OF(SXNETID)
DECLARE_ASN1_SET_OF(SXNETID)

typedef struct SXNET_st {
    ASN1_INTEGER *version;
    STACK_OF(SXNETID) *ids;
} SXNET;

typedef struct NOTICEREF_st {
    ASN1_STRING *organization;
    STACK_OF(ASN1_INTEGER) *noticenos;
} NOTICEREF;

typedef struct USERNOTICE_st {
    NOTICEREF *noticeref;
    ASN1_STRING *exptext;
} USERNOTICE;

typedef struct POLICYQUALINFO_st {
    ASN1_OBJECT *pqualid;
    union {
        ASN1_IA5STRING *cpsuri;
        USERNOTICE *usernotice;
        ASN1_TYPE *other;
    } d;
} POLICYQUALINFO;

DECLARE_STACK_OF(POLICYQUALINFO)
DECLARE_ASN1_SET_OF(POLICYQUALINFO)

typedef struct POLICYINFO_st {
    ASN1_OBJECT *policyid;
    STACK_OF(POLICYQUALINFO) *qualifiers;
} POLICYINFO;

typedef STACK_OF(POLICYINFO) CERTIFICATEPOLICIES;

DECLARE_STACK_OF(POLICYINFO)
DECLARE_ASN1_SET_OF(POLICYINFO)

typedef struct POLICY_MAPPING_st {
    ASN1_OBJECT *issuerDomainPolicy;
    ASN1_OBJECT *subjectDomainPolicy;
} POLICY_MAPPING;

DECLARE_STACK_OF(POLICY_MAPPING)

typedef STACK_OF(POLICY_MAPPING) POLICY_MAPPINGS;

typedef struct GENERAL_SUBTREE_st {
    GENERAL_NAME *base;
    ASN1_INTEGER *minimum;
    ASN1_INTEGER *maximum;
} GENERAL_SUBTREE;

DECLARE_STACK_OF(GENERAL_SUBTREE)

struct NAME_CONSTRAINTS_st {
    STACK_OF(GENERAL_SUBTREE) *permittedSubtrees;
    STACK_OF(GENERAL_SUBTREE) *excludedSubtrees;
};

typedef struct POLICY_CONSTRAINTS_st {
    ASN1_INTEGER *requireExplicitPolicy;
    ASN1_INTEGER *inhibitPolicyMapping;
} POLICY_CONSTRAINTS;

/* Proxy certificate structures, see RFC 3820 */
typedef struct PROXY_POLICY_st {
    ASN1_OBJECT *policyLanguage;
    ASN1_OCTET_STRING *policy;
} PROXY_POLICY;

typedef struct PROXY_CERT_INFO_EXTENSION_st {
    ASN1_INTEGER *pcPathLengthConstraint;
    PROXY_POLICY *proxyPolicy;
} PROXY_CERT_INFO_EXTENSION;

DECLARE_ASN1_FUNCTIONS(PROXY_POLICY)
DECLARE_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION)

struct ISSUING_DIST_POINT_st {
    DIST_POINT_NAME *distpoint;
    int onlyuser;
    int onlyCA;
    ASN1_BIT_STRING *onlysomereasons;
    int indirectCRL;
    int onlyattr;
};

/* Values in idp_flags field */
/* IDP present */
# define IDP_PRESENT     0x1
/* IDP values inconsistent */
# define IDP_INVALID     0x2
/* onlyuser true */
# define IDP_ONLYUSER    0x4
/* onlyCA true */
# define IDP_ONLYCA      0x8
/* onlyattr true */
# define IDP_ONLYATTR    0x10
/* indirectCRL true */
# define IDP_INDIRECT    0x20
/* onlysomereasons present */
# define IDP_REASONS     0x40

# define X509V3_conf_err(val) ERR_add_error_data(6, "section:", val->section, \
",name:", val->name, ",value:", val->value);

# define X509V3_set_ctx_test(ctx) \
                        X509V3_set_ctx(ctx, NULL, NULL, NULL, NULL, CTX_TEST)
# define X509V3_set_ctx_nodb(ctx) (ctx)->db = NULL;

# define EXT_BITSTRING(nid, table) { nid, 0, ASN1_ITEM_ref(ASN1_BIT_STRING), \
                        0,0,0,0, \
                        0,0, \
                        (X509V3_EXT_I2V)i2v_ASN1_BIT_STRING, \
                        (X509V3_EXT_V2I)v2i_ASN1_BIT_STRING, \
                        NULL, NULL, \
                        table}

# define EXT_IA5STRING(nid) { nid, 0, ASN1_ITEM_ref(ASN1_IA5STRING), \
                        0,0,0,0, \
                        (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, \
                        (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, \
                        0,0,0,0, \
                        NULL}

# define EXT_END { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

/* X509_PURPOSE stuff */

# define EXFLAG_BCONS            0x1
# define EXFLAG_KUSAGE           0x2
# define EXFLAG_XKUSAGE          0x4
# define EXFLAG_NSCERT           0x8

# define EXFLAG_CA               0x10
/* Really self issued not necessarily self signed */
# define EXFLAG_SI               0x20
# define EXFLAG_V1               0x40
# define EXFLAG_INVALID          0x80
# define EXFLAG_SET              0x100
# define EXFLAG_CRITICAL         0x200
# define EXFLAG_PROXY            0x400

# define EXFLAG_INVALID_POLICY   0x800
# define EXFLAG_FRESHEST         0x1000
/* Self signed */
# define EXFLAG_SS               0x2000

# define KU_DIGITAL_SIGNATURE    0x0080
# define KU_NON_REPUDIATION      0x0040
# define KU_KEY_ENCIPHERMENT     0x0020
# define KU_DATA_ENCIPHERMENT    0x0010
# define KU_KEY_AGREEMENT        0x0008
# define KU_KEY_CERT_SIGN        0x0004
# define KU_CRL_SIGN             0x0002
# define KU_ENCIPHER_ONLY        0x0001
# define KU_DECIPHER_ONLY        0x8000

# define NS_SSL_CLIENT           0x80
# define NS_SSL_SERVER           0x40
# define NS_SMIME                0x20
# define NS_OBJSIGN              0x10
# define NS_SSL_CA               0x04
# define NS_SMIME_CA             0x02
# define NS_OBJSIGN_CA           0x01
# define NS_ANY_CA               (NS_SSL_CA|NS_SMIME_CA|NS_OBJSIGN_CA)

# define XKU_SSL_SERVER          0x1
# define XKU_SSL_CLIENT          0x2
# define XKU_SMIME               0x4
# define XKU_CODE_SIGN           0x8
# define XKU_SGC                 0x10
# define XKU_OCSP_SIGN           0x20
# define XKU_TIMESTAMP           0x40
# define XKU_DVCS                0x80
# define XKU_ANYEKU              0x100

# define X509_PURPOSE_DYNAMIC    0x1
# define X509_PURPOSE_DYNAMIC_NAME       0x2

typedef struct x509_purpose_st {
    int purpose;
    int trust;                  /* Default trust ID */
    int flags;
    int (*check_purpose) (const struct x509_purpose_st *, const X509 *, int);
    char *name;
    char *sname;
    void *usr_data;
} X509_PURPOSE;

# define X509_PURPOSE_SSL_CLIENT         1
# define X509_PURPOSE_SSL_SERVER         2
# define X509_PURPOSE_NS_SSL_SERVER      3
# define X509_PURPOSE_SMIME_SIGN         4
# define X509_PURPOSE_SMIME_ENCRYPT      5
# define X509_PURPOSE_CRL_SIGN           6
# define X509_PURPOSE_ANY                7
# define X509_PURPOSE_OCSP_HELPER        8
# define X509_PURPOSE_TIMESTAMP_SIGN     9

# define X509_PURPOSE_MIN                1
# define X509_PURPOSE_MAX                9

/* Flags for X509V3_EXT_print() */

# define X509V3_EXT_UNKNOWN_MASK         (0xfL << 16)
/* Return error for unknown extensions */
# define X509V3_EXT_DEFAULT              0
/* Print error for unknown extensions */
# define X509V3_EXT_ERROR_UNKNOWN        (1L << 16)
/* ASN1 parse unknown extensions */
# define X509V3_EXT_PARSE_UNKNOWN        (2L << 16)
/* BIO_dump unknown extensions */
# define X509V3_EXT_DUMP_UNKNOWN         (3L << 16)

/* Flags for X509V3_add1_i2d */

# define X509V3_ADD_OP_MASK              0xfL
# define X509V3_ADD_DEFAULT              0L
# define X509V3_ADD_APPEND               1L
# define X509V3_ADD_REPLACE              2L
# define X509V3_ADD_REPLACE_EXISTING     3L
# define X509V3_ADD_KEEP_EXISTING        4L
# define X509V3_ADD_DELETE               5L
# define X509V3_ADD_SILENT               0x10

DECLARE_STACK_OF(X509_PURPOSE)

DECLARE_ASN1_FUNCTIONS(BASIC_CONSTRAINTS)

DECLARE_ASN1_FUNCTIONS(SXNET)
DECLARE_ASN1_FUNCTIONS(SXNETID)

int SXNET_add_id_asc(SXNET **psx, char *zone, char *user, int userlen);
int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, char *user,
                       int userlen);
int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *izone, char *user,
                         int userlen);

ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, char *zone);
ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone);
ASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone);

DECLARE_ASN1_FUNCTIONS(AUTHORITY_KEYID)

DECLARE_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD)

DECLARE_ASN1_FUNCTIONS(GENERAL_NAME)
GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a);
int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b);

ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
                                     X509V3_CTX *ctx,
                                     STACK_OF(CONF_VALUE) *nval);
STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
                                          ASN1_BIT_STRING *bits,
                                          STACK_OF(CONF_VALUE) *extlist);

STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method,
                                       GENERAL_NAME *gen,
                                       STACK_OF(CONF_VALUE) *ret);
int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen);

DECLARE_ASN1_FUNCTIONS(GENERAL_NAMES)

STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method,
                                        GENERAL_NAMES *gen,
                                        STACK_OF(CONF_VALUE) *extlist);
GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method,
                                 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);

DECLARE_ASN1_FUNCTIONS(OTHERNAME)
DECLARE_ASN1_FUNCTIONS(EDIPARTYNAME)
int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b);
void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value);
void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype);
int GENERAL_NAME_set0_othername(GENERAL_NAME *gen,
                                ASN1_OBJECT *oid, ASN1_TYPE *value);
int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen,
                                ASN1_OBJECT **poid, ASN1_TYPE **pvalue);

char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method,
                            ASN1_OCTET_STRING *ia5);
ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method,
                                         X509V3_CTX *ctx, char *str);

DECLARE_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE)
int i2a_ACCESS_DESCRIPTION(BIO *bp, ACCESS_DESCRIPTION *a);

DECLARE_ASN1_FUNCTIONS(CERTIFICATEPOLICIES)
DECLARE_ASN1_FUNCTIONS(POLICYINFO)
DECLARE_ASN1_FUNCTIONS(POLICYQUALINFO)
DECLARE_ASN1_FUNCTIONS(USERNOTICE)
DECLARE_ASN1_FUNCTIONS(NOTICEREF)

DECLARE_ASN1_FUNCTIONS(CRL_DIST_POINTS)
DECLARE_ASN1_FUNCTIONS(DIST_POINT)
DECLARE_ASN1_FUNCTIONS(DIST_POINT_NAME)
DECLARE_ASN1_FUNCTIONS(ISSUING_DIST_POINT)

int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname);

int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc);

DECLARE_ASN1_FUNCTIONS(ACCESS_DESCRIPTION)
DECLARE_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS)

DECLARE_ASN1_ITEM(POLICY_MAPPING)
DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING)
DECLARE_ASN1_ITEM(POLICY_MAPPINGS)

DECLARE_ASN1_ITEM(GENERAL_SUBTREE)
DECLARE_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE)

DECLARE_ASN1_ITEM(NAME_CONSTRAINTS)
DECLARE_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS)

DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS)
DECLARE_ASN1_ITEM(POLICY_CONSTRAINTS)

GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
                               const X509V3_EXT_METHOD *method,
                               X509V3_CTX *ctx, int gen_type, char *value,
                               int is_nc);

# ifdef HEADER_CONF_H
GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method,
                               X509V3_CTX *ctx, CONF_VALUE *cnf);
GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
                                  const X509V3_EXT_METHOD *method,
                                  X509V3_CTX *ctx, CONF_VALUE *cnf,
                                  int is_nc);
void X509V3_conf_free(CONF_VALUE *val);

X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid,
                                     char *value);
X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name,
                                 char *value);
int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section,
                            STACK_OF(X509_EXTENSION) **sk);
int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
                         X509 *cert);
int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
                             X509_REQ *req);
int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
                             X509_CRL *crl);

X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf,
                                    X509V3_CTX *ctx, int ext_nid,
                                    char *value);
X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
                                char *name, char *value);
int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
                        char *section, X509 *cert);
int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
                            char *section, X509_REQ *req);
int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
                            char *section, X509_CRL *crl);

int X509V3_add_value_bool_nf(char *name, int asn1_bool,
                             STACK_OF(CONF_VALUE) **extlist);
int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool);
int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint);
void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf);
void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash);
# endif

char *X509V3_get_string(X509V3_CTX *ctx, char *name, char *section);
STACK_OF(CONF_VALUE) *X509V3_get_section(X509V3_CTX *ctx, char *section);
void X509V3_string_free(X509V3_CTX *ctx, char *str);
void X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section);
void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subject,
                    X509_REQ *req, X509_CRL *crl, int flags);

int X509V3_add_value(const char *name, const char *value,
                     STACK_OF(CONF_VALUE) **extlist);
int X509V3_add_value_uchar(const char *name, const unsigned char *value,
                           STACK_OF(CONF_VALUE) **extlist);
int X509V3_add_value_bool(const char *name, int asn1_bool,
                          STACK_OF(CONF_VALUE) **extlist);
int X509V3_add_value_int(const char *name, ASN1_INTEGER *aint,
                         STACK_OF(CONF_VALUE) **extlist);
char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *meth, ASN1_INTEGER *aint);
ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *meth, char *value);
char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *meth, ASN1_ENUMERATED *aint);
char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *meth,
                                ASN1_ENUMERATED *aint);
int X509V3_EXT_add(X509V3_EXT_METHOD *ext);
int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist);
int X509V3_EXT_add_alias(int nid_to, int nid_from);
void X509V3_EXT_cleanup(void);

const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext);
const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid);
int X509V3_add_standard_extensions(void);
STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line);
void *X509V3_EXT_d2i(X509_EXTENSION *ext);
void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit,
                     int *idx);
int X509V3_EXT_free(int nid, void *ext_data);

X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc);
int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value,
                    int crit, unsigned long flags);

char *hex_to_string(const unsigned char *buffer, long len);
unsigned char *string_to_hex(const char *str, long *len);
int name_cmp(const char *name, const char *cmp);

void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent,
                        int ml);
int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag,
                     int indent);
int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag, int indent);

int X509V3_extensions_print(BIO *out, char *title,
                            STACK_OF(X509_EXTENSION) *exts,
                            unsigned long flag, int indent);

int X509_check_ca(X509 *x);
int X509_check_purpose(X509 *x, int id, int ca);
int X509_supported_extension(X509_EXTENSION *ex);
int X509_PURPOSE_set(int *p, int purpose);
int X509_check_issued(X509 *issuer, X509 *subject);
int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid);
int X509_PURPOSE_get_count(void);
X509_PURPOSE *X509_PURPOSE_get0(int idx);
int X509_PURPOSE_get_by_sname(char *sname);
int X509_PURPOSE_get_by_id(int id);
int X509_PURPOSE_add(int id, int trust, int flags,
                     int (*ck) (const X509_PURPOSE *, const X509 *, int),
                     char *name, char *sname, void *arg);
char *X509_PURPOSE_get0_name(X509_PURPOSE *xp);
char *X509_PURPOSE_get0_sname(X509_PURPOSE *xp);
int X509_PURPOSE_get_trust(X509_PURPOSE *xp);
void X509_PURPOSE_cleanup(void);
int X509_PURPOSE_get_id(X509_PURPOSE *);

STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x);
STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x);
void X509_email_free(STACK_OF(OPENSSL_STRING) *sk);
STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x);
/* Flags for X509_check_* functions */

/*
 * Always check subject name for host match even if subject alt names present
 */
# define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT    0x1
/* Disable wildcard matching for dnsName fields and common name. */
# define X509_CHECK_FLAG_NO_WILDCARDS    0x2
/* Wildcards must not match a partial label. */
# define X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS 0x4
/* Allow (non-partial) wildcards to match multiple labels. */
# define X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS 0x8
/* Constraint verifier subdomain patterns to match a single labels. */
# define X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS 0x10
/*
 * Match reference identifiers starting with "." to any sub-domain.
 * This is a non-public flag, turned on implicitly when the subject
 * reference identity is a DNS name.
 */
# define _X509_CHECK_FLAG_DOT_SUBDOMAINS 0x8000

int X509_check_host(X509 *x, const char *chk, size_t chklen,
                    unsigned int flags, char **peername);
int X509_check_email(X509 *x, const char *chk, size_t chklen,
                     unsigned int flags);
int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen,
                  unsigned int flags);
int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags);

ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc);
ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc);
int a2i_ipadd(unsigned char *ipout, const char *ipasc);
int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE) *dn_sk,
                             unsigned long chtype);

void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent);
DECLARE_STACK_OF(X509_POLICY_NODE)

# ifndef OPENSSL_NO_RFC3779

typedef struct ASRange_st {
    ASN1_INTEGER *min, *max;
} ASRange;

#  define ASIdOrRange_id          0
#  define ASIdOrRange_range       1

typedef struct ASIdOrRange_st {
    int type;
    union {
        ASN1_INTEGER *id;
        ASRange *range;
    } u;
} ASIdOrRange;

typedef STACK_OF(ASIdOrRange) ASIdOrRanges;
DECLARE_STACK_OF(ASIdOrRange)

#  define ASIdentifierChoice_inherit              0
#  define ASIdentifierChoice_asIdsOrRanges        1

typedef struct ASIdentifierChoice_st {
    int type;
    union {
        ASN1_NULL *inherit;
        ASIdOrRanges *asIdsOrRanges;
    } u;
} ASIdentifierChoice;

typedef struct ASIdentifiers_st {
    ASIdentifierChoice *asnum, *rdi;
} ASIdentifiers;

DECLARE_ASN1_FUNCTIONS(ASRange)
DECLARE_ASN1_FUNCTIONS(ASIdOrRange)
DECLARE_ASN1_FUNCTIONS(ASIdentifierChoice)
DECLARE_ASN1_FUNCTIONS(ASIdentifiers)

typedef struct IPAddressRange_st {
    ASN1_BIT_STRING *min, *max;
} IPAddressRange;

#  define IPAddressOrRange_addressPrefix  0
#  define IPAddressOrRange_addressRange   1

typedef struct IPAddressOrRange_st {
    int type;
    union {
        ASN1_BIT_STRING *addressPrefix;
        IPAddressRange *addressRange;
    } u;
} IPAddressOrRange;

typedef STACK_OF(IPAddressOrRange) IPAddressOrRanges;
DECLARE_STACK_OF(IPAddressOrRange)

#  define IPAddressChoice_inherit                 0
#  define IPAddressChoice_addressesOrRanges       1

typedef struct IPAddressChoice_st {
    int type;
    union {
        ASN1_NULL *inherit;
        IPAddressOrRanges *addressesOrRanges;
    } u;
} IPAddressChoice;

typedef struct IPAddressFamily_st {
    ASN1_OCTET_STRING *addressFamily;
    IPAddressChoice *ipAddressChoice;
} IPAddressFamily;

typedef STACK_OF(IPAddressFamily) IPAddrBlocks;
DECLARE_STACK_OF(IPAddressFamily)

DECLARE_ASN1_FUNCTIONS(IPAddressRange)
DECLARE_ASN1_FUNCTIONS(IPAddressOrRange)
DECLARE_ASN1_FUNCTIONS(IPAddressChoice)
DECLARE_ASN1_FUNCTIONS(IPAddressFamily)

/*
 * API tag for elements of the ASIdentifer SEQUENCE.
 */
#  define V3_ASID_ASNUM   0
#  define V3_ASID_RDI     1

/*
 * AFI values, assigned by IANA.  It'd be nice to make the AFI
 * handling code totally generic, but there are too many little things
 * that would need to be defined for other address families for it to
 * be worth the trouble.
 */
#  define IANA_AFI_IPV4   1
#  define IANA_AFI_IPV6   2

/*
 * Utilities to construct and extract values from RFC3779 extensions,
 * since some of the encodings (particularly for IP address prefixes
 * and ranges) are a bit tedious to work with directly.
 */
int v3_asid_add_inherit(ASIdentifiers *asid, int which);
int v3_asid_add_id_or_range(ASIdentifiers *asid, int which,
                            ASN1_INTEGER *min, ASN1_INTEGER *max);
int v3_addr_add_inherit(IPAddrBlocks *addr,
                        const unsigned afi, const unsigned *safi);
int v3_addr_add_prefix(IPAddrBlocks *addr,
                       const unsigned afi, const unsigned *safi,
                       unsigned char *a, const int prefixlen);
int v3_addr_add_range(IPAddrBlocks *addr,
                      const unsigned afi, const unsigned *safi,
                      unsigned char *min, unsigned char *max);
unsigned v3_addr_get_afi(const IPAddressFamily *f);
int v3_addr_get_range(IPAddressOrRange *aor, const unsigned afi,
                      unsigned char *min, unsigned char *max,
                      const int length);

/*
 * Canonical forms.
 */
int v3_asid_is_canonical(ASIdentifiers *asid);
int v3_addr_is_canonical(IPAddrBlocks *addr);
int v3_asid_canonize(ASIdentifiers *asid);
int v3_addr_canonize(IPAddrBlocks *addr);

/*
 * Tests for inheritance and containment.
 */
int v3_asid_inherits(ASIdentifiers *asid);
int v3_addr_inherits(IPAddrBlocks *addr);
int v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b);
int v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b);

/*
 * Check whether RFC 3779 extensions nest properly in chains.
 */
int v3_asid_validate_path(X509_STORE_CTX *);
int v3_addr_validate_path(X509_STORE_CTX *);
int v3_asid_validate_resource_set(STACK_OF(X509) *chain,
                                  ASIdentifiers *ext, int allow_inheritance);
int v3_addr_validate_resource_set(STACK_OF(X509) *chain,
                                  IPAddrBlocks *ext, int allow_inheritance);

# endif                         /* OPENSSL_NO_RFC3779 */

/* BEGIN ERROR CODES */
/*
 * The following lines are auto generated by the script mkerr.pl. Any changes
 * made after this point may be overwritten when the script is next run.
 */
void ERR_load_X509V3_strings(void);

/* Error codes for the X509V3 functions. */

/* Function codes. */
# define X509V3_F_A2I_GENERAL_NAME                        164
# define X509V3_F_ASIDENTIFIERCHOICE_CANONIZE             161
# define X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL         162
# define X509V3_F_COPY_EMAIL                              122
# define X509V3_F_COPY_ISSUER                             123
# define X509V3_F_DO_DIRNAME                              144
# define X509V3_F_DO_EXT_CONF                             124
# define X509V3_F_DO_EXT_I2D                              135
# define X509V3_F_DO_EXT_NCONF                            151
# define X509V3_F_DO_I2V_NAME_CONSTRAINTS                 148
# define X509V3_F_GNAMES_FROM_SECTNAME                    156
# define X509V3_F_HEX_TO_STRING                           111
# define X509V3_F_I2S_ASN1_ENUMERATED                     121
# define X509V3_F_I2S_ASN1_IA5STRING                      149
# define X509V3_F_I2S_ASN1_INTEGER                        120
# define X509V3_F_I2V_AUTHORITY_INFO_ACCESS               138
# define X509V3_F_NOTICE_SECTION                          132
# define X509V3_F_NREF_NOS                                133
# define X509V3_F_POLICY_SECTION                          131
# define X509V3_F_PROCESS_PCI_VALUE                       150
# define X509V3_F_R2I_CERTPOL                             130
# define X509V3_F_R2I_PCI                                 155
# define X509V3_F_S2I_ASN1_IA5STRING                      100
# define X509V3_F_S2I_ASN1_INTEGER                        108
# define X509V3_F_S2I_ASN1_OCTET_STRING                   112
# define X509V3_F_S2I_ASN1_SKEY_ID                        114
# define X509V3_F_S2I_SKEY_ID                             115
# define X509V3_F_SET_DIST_POINT_NAME                     158
# define X509V3_F_STRING_TO_HEX                           113
# define X509V3_F_SXNET_ADD_ID_ASC                        125
# define X509V3_F_SXNET_ADD_ID_INTEGER                    126
# define X509V3_F_SXNET_ADD_ID_ULONG                      127
# define X509V3_F_SXNET_GET_ID_ASC                        128
# define X509V3_F_SXNET_GET_ID_ULONG                      129
# define X509V3_F_V2I_ASIDENTIFIERS                       163
# define X509V3_F_V2I_ASN1_BIT_STRING                     101
# define X509V3_F_V2I_AUTHORITY_INFO_ACCESS               139
# define X509V3_F_V2I_AUTHORITY_KEYID                     119
# define X509V3_F_V2I_BASIC_CONSTRAINTS                   102
# define X509V3_F_V2I_CRLD                                134
# define X509V3_F_V2I_EXTENDED_KEY_USAGE                  103
# define X509V3_F_V2I_GENERAL_NAMES                       118
# define X509V3_F_V2I_GENERAL_NAME_EX                     117
# define X509V3_F_V2I_IDP                                 157
# define X509V3_F_V2I_IPADDRBLOCKS                        159
# define X509V3_F_V2I_ISSUER_ALT                          153
# define X509V3_F_V2I_NAME_CONSTRAINTS                    147
# define X509V3_F_V2I_POLICY_CONSTRAINTS                  146
# define X509V3_F_V2I_POLICY_MAPPINGS                     145
# define X509V3_F_V2I_SUBJECT_ALT                         154
# define X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL          160
# define X509V3_F_V3_GENERIC_EXTENSION                    116
# define X509V3_F_X509V3_ADD1_I2D                         140
# define X509V3_F_X509V3_ADD_VALUE                        105
# define X509V3_F_X509V3_EXT_ADD                          104
# define X509V3_F_X509V3_EXT_ADD_ALIAS                    106
# define X509V3_F_X509V3_EXT_CONF                         107
# define X509V3_F_X509V3_EXT_FREE                         165
# define X509V3_F_X509V3_EXT_I2D                          136
# define X509V3_F_X509V3_EXT_NCONF                        152
# define X509V3_F_X509V3_GET_SECTION                      142
# define X509V3_F_X509V3_GET_STRING                       143
# define X509V3_F_X509V3_GET_VALUE_BOOL                   110
# define X509V3_F_X509V3_PARSE_LIST                       109
# define X509V3_F_X509_PURPOSE_ADD                        137
# define X509V3_F_X509_PURPOSE_SET                        141

/* Reason codes. */
# define X509V3_R_BAD_IP_ADDRESS                          118
# define X509V3_R_BAD_OBJECT                              119
# define X509V3_R_BN_DEC2BN_ERROR                         100
# define X509V3_R_BN_TO_ASN1_INTEGER_ERROR                101
# define X509V3_R_CANNOT_FIND_FREE_FUNCTION               168
# define X509V3_R_DIRNAME_ERROR                           149
# define X509V3_R_DISTPOINT_ALREADY_SET                   160
# define X509V3_R_DUPLICATE_ZONE_ID                       133
# define X509V3_R_ERROR_CONVERTING_ZONE                   131
# define X509V3_R_ERROR_CREATING_EXTENSION                144
# define X509V3_R_ERROR_IN_EXTENSION                      128
# define X509V3_R_EXPECTED_A_SECTION_NAME                 137
# define X509V3_R_EXTENSION_EXISTS                        145
# define X509V3_R_EXTENSION_NAME_ERROR                    115
# define X509V3_R_EXTENSION_NOT_FOUND                     102
# define X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED         103
# define X509V3_R_EXTENSION_VALUE_ERROR                   116
# define X509V3_R_ILLEGAL_EMPTY_EXTENSION                 151
# define X509V3_R_ILLEGAL_HEX_DIGIT                       113
# define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG             152
# define X509V3_R_INVALID_ASNUMBER                        162
# define X509V3_R_INVALID_ASRANGE                         163
# define X509V3_R_INVALID_BOOLEAN_STRING                  104
# define X509V3_R_INVALID_EXTENSION_STRING                105
# define X509V3_R_INVALID_INHERITANCE                     165
# define X509V3_R_INVALID_IPADDRESS                       166
# define X509V3_R_INVALID_MULTIPLE_RDNS                   161
# define X509V3_R_INVALID_NAME                            106
# define X509V3_R_INVALID_NULL_ARGUMENT                   107
# define X509V3_R_INVALID_NULL_NAME                       108
# define X509V3_R_INVALID_NULL_VALUE                      109
# define X509V3_R_INVALID_NUMBER                          140
# define X509V3_R_INVALID_NUMBERS                         141
# define X509V3_R_INVALID_OBJECT_IDENTIFIER               110
# define X509V3_R_INVALID_OPTION                          138
# define X509V3_R_INVALID_POLICY_IDENTIFIER               134
# define X509V3_R_INVALID_PROXY_POLICY_SETTING            153
# define X509V3_R_INVALID_PURPOSE                         146
# define X509V3_R_INVALID_SAFI                            164
# define X509V3_R_INVALID_SECTION                         135
# define X509V3_R_INVALID_SYNTAX                          143
# define X509V3_R_ISSUER_DECODE_ERROR                     126
# define X509V3_R_MISSING_VALUE                           124
# define X509V3_R_NEED_ORGANIZATION_AND_NUMBERS           142
# define X509V3_R_NO_CONFIG_DATABASE                      136
# define X509V3_R_NO_ISSUER_CERTIFICATE                   121
# define X509V3_R_NO_ISSUER_DETAILS                       127
# define X509V3_R_NO_POLICY_IDENTIFIER                    139
# define X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED   154
# define X509V3_R_NO_PUBLIC_KEY                           114
# define X509V3_R_NO_SUBJECT_DETAILS                      125
# define X509V3_R_ODD_NUMBER_OF_DIGITS                    112
# define X509V3_R_OPERATION_NOT_DEFINED                   148
# define X509V3_R_OTHERNAME_ERROR                         147
# define X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED         155
# define X509V3_R_POLICY_PATH_LENGTH                      156
# define X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED      157
# define X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED   158
# define X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY 159
# define X509V3_R_SECTION_NOT_FOUND                       150
# define X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS            122
# define X509V3_R_UNABLE_TO_GET_ISSUER_KEYID              123
# define X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT             111
# define X509V3_R_UNKNOWN_EXTENSION                       129
# define X509V3_R_UNKNOWN_EXTENSION_NAME                  130
# define X509V3_R_UNKNOWN_OPTION                          120
# define X509V3_R_UNSUPPORTED_OPTION                      117
# define X509V3_R_UNSUPPORTED_TYPE                        167
# define X509V3_R_USER_TOO_LONG                           132

#ifdef  __cplusplus
}
#endif
#endif
openssl/rc5.h000064400000011503151733316570007104 0ustar00/* crypto/rc5/rc5.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#ifndef HEADER_RC5_H
# define HEADER_RC5_H

# include <openssl/opensslconf.h>/* OPENSSL_NO_RC5 */

#ifdef  __cplusplus
extern "C" {
#endif

# ifdef OPENSSL_NO_RC5
#  error RC5 is disabled.
# endif

# define RC5_ENCRYPT     1
# define RC5_DECRYPT     0

/* 32 bit.  For Alpha, things may get weird */
# define RC5_32_INT unsigned long

# define RC5_32_BLOCK            8
# define RC5_32_KEY_LENGTH       16/* This is a default, max is 255 */

/*
 * This are the only values supported.  Tweak the code if you want more The
 * most supported modes will be RC5-32/12/16 RC5-32/16/8
 */
# define RC5_8_ROUNDS    8
# define RC5_12_ROUNDS   12
# define RC5_16_ROUNDS   16

typedef struct rc5_key_st {
    /* Number of rounds */
    int rounds;
    RC5_32_INT data[2 * (RC5_16_ROUNDS + 1)];
} RC5_32_KEY;

void RC5_32_set_key(RC5_32_KEY *key, int len, const unsigned char *data,
                    int rounds);
void RC5_32_ecb_encrypt(const unsigned char *in, unsigned char *out,
                        RC5_32_KEY *key, int enc);
void RC5_32_encrypt(unsigned long *data, RC5_32_KEY *key);
void RC5_32_decrypt(unsigned long *data, RC5_32_KEY *key);
void RC5_32_cbc_encrypt(const unsigned char *in, unsigned char *out,
                        long length, RC5_32_KEY *ks, unsigned char *iv,
                        int enc);
void RC5_32_cfb64_encrypt(const unsigned char *in, unsigned char *out,
                          long length, RC5_32_KEY *schedule,
                          unsigned char *ivec, int *num, int enc);
void RC5_32_ofb64_encrypt(const unsigned char *in, unsigned char *out,
                          long length, RC5_32_KEY *schedule,
                          unsigned char *ivec, int *num);

#ifdef  __cplusplus
}
#endif

#endif
openssl/ui_compat.h000064400000006646151733316570010407 0ustar00/* crypto/ui/ui.h */
/*
 * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project
 * 2001.
 */
/* ====================================================================
 * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#ifndef HEADER_UI_COMPAT_H
# define HEADER_UI_COMPAT_H

# include <openssl/opensslconf.h>
# include <openssl/ui.h>

#ifdef  __cplusplus
extern "C" {
#endif

/*
 * The following functions were previously part of the DES section, and are
 * provided here for backward compatibility reasons.
 */

# define des_read_pw_string(b,l,p,v) \
        _ossl_old_des_read_pw_string((b),(l),(p),(v))
# define des_read_pw(b,bf,s,p,v) \
        _ossl_old_des_read_pw((b),(bf),(s),(p),(v))

int _ossl_old_des_read_pw_string(char *buf, int length, const char *prompt,
                                 int verify);
int _ossl_old_des_read_pw(char *buf, char *buff, int size, const char *prompt,
                          int verify);

#ifdef  __cplusplus
}
#endif
#endif
openssl/seed.h000064400000013630151733316570007336 0ustar00/*
 * Copyright (c) 2007 KISA(Korea Information Security Agency). All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Neither the name of author nor the names of its contributors may
 *    be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 */
/* ====================================================================
 * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#ifndef HEADER_SEED_H
# define HEADER_SEED_H

# include <openssl/opensslconf.h>
# include <openssl/e_os2.h>
# include <openssl/crypto.h>

# ifdef OPENSSL_NO_SEED
#  error SEED is disabled.
# endif

/* look whether we need 'long' to get 32 bits */
# ifdef AES_LONG
#  ifndef SEED_LONG
#   define SEED_LONG 1
#  endif
# endif

# if !defined(NO_SYS_TYPES_H)
#  include <sys/types.h>
# endif

# define SEED_BLOCK_SIZE 16
# define SEED_KEY_LENGTH 16


#ifdef  __cplusplus
extern "C" {
#endif

typedef struct seed_key_st {
# ifdef SEED_LONG
    unsigned long data[32];
# else
    unsigned int data[32];
# endif
} SEED_KEY_SCHEDULE;

# ifdef OPENSSL_FIPS
void private_SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH],
                          SEED_KEY_SCHEDULE *ks);
# endif
void SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH],
                  SEED_KEY_SCHEDULE *ks);

void SEED_encrypt(const unsigned char s[SEED_BLOCK_SIZE],
                  unsigned char d[SEED_BLOCK_SIZE],
                  const SEED_KEY_SCHEDULE *ks);
void SEED_decrypt(const unsigned char s[SEED_BLOCK_SIZE],
                  unsigned char d[SEED_BLOCK_SIZE],
                  const SEED_KEY_SCHEDULE *ks);

void SEED_ecb_encrypt(const unsigned char *in, unsigned char *out,
                      const SEED_KEY_SCHEDULE *ks, int enc);
void SEED_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t len,
                      const SEED_KEY_SCHEDULE *ks,
                      unsigned char ivec[SEED_BLOCK_SIZE], int enc);
void SEED_cfb128_encrypt(const unsigned char *in, unsigned char *out,
                         size_t len, const SEED_KEY_SCHEDULE *ks,
                         unsigned char ivec[SEED_BLOCK_SIZE], int *num,
                         int enc);
void SEED_ofb128_encrypt(const unsigned char *in, unsigned char *out,
                         size_t len, const SEED_KEY_SCHEDULE *ks,
                         unsigned char ivec[SEED_BLOCK_SIZE], int *num);

#ifdef  __cplusplus
}
#endif

#endif                          /* HEADER_SEED_H */
openssl/conf.h000064400000026066151733316570007352 0ustar00/* crypto/conf/conf.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#ifndef  HEADER_CONF_H
# define HEADER_CONF_H

# include <openssl/bio.h>
# include <openssl/lhash.h>
# include <openssl/stack.h>
# include <openssl/safestack.h>
# include <openssl/e_os2.h>

# include <openssl/ossl_typ.h>

#ifdef  __cplusplus
extern "C" {
#endif

typedef struct {
    char *section;
    char *name;
    char *value;
} CONF_VALUE;

DECLARE_STACK_OF(CONF_VALUE)
DECLARE_LHASH_OF(CONF_VALUE);

struct conf_st;
struct conf_method_st;
typedef struct conf_method_st CONF_METHOD;

struct conf_method_st {
    const char *name;
    CONF *(*create) (CONF_METHOD *meth);
    int (*init) (CONF *conf);
    int (*destroy) (CONF *conf);
    int (*destroy_data) (CONF *conf);
    int (*load_bio) (CONF *conf, BIO *bp, long *eline);
    int (*dump) (const CONF *conf, BIO *bp);
    int (*is_number) (const CONF *conf, char c);
    int (*to_int) (const CONF *conf, char c);
    int (*load) (CONF *conf, const char *name, long *eline);
};

/* Module definitions */

typedef struct conf_imodule_st CONF_IMODULE;
typedef struct conf_module_st CONF_MODULE;

DECLARE_STACK_OF(CONF_MODULE)
DECLARE_STACK_OF(CONF_IMODULE)

/* DSO module function typedefs */
typedef int conf_init_func (CONF_IMODULE *md, const CONF *cnf);
typedef void conf_finish_func (CONF_IMODULE *md);

# define CONF_MFLAGS_IGNORE_ERRORS       0x1
# define CONF_MFLAGS_IGNORE_RETURN_CODES 0x2
# define CONF_MFLAGS_SILENT              0x4
# define CONF_MFLAGS_NO_DSO              0x8
# define CONF_MFLAGS_IGNORE_MISSING_FILE 0x10
# define CONF_MFLAGS_DEFAULT_SECTION     0x20

int CONF_set_default_method(CONF_METHOD *meth);
void CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash);
LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file,
                                long *eline);
# ifndef OPENSSL_NO_FP_API
LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp,
                                   long *eline);
# endif
LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp,
                                    long *eline);
STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf,
                                       const char *section);
char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf, const char *group,
                      const char *name);
long CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group,
                     const char *name);
void CONF_free(LHASH_OF(CONF_VALUE) *conf);
int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out);
int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out);

void OPENSSL_config(const char *config_name);
void OPENSSL_no_config(void);

/*
 * New conf code.  The semantics are different from the functions above. If
 * that wasn't the case, the above functions would have been replaced
 */

struct conf_st {
    CONF_METHOD *meth;
    void *meth_data;
    LHASH_OF(CONF_VALUE) *data;
};

CONF *NCONF_new(CONF_METHOD *meth);
CONF_METHOD *NCONF_default(void);
CONF_METHOD *NCONF_WIN32(void);
# if 0                          /* Just to give you an idea of what I have in
                                 * mind */
CONF_METHOD *NCONF_XML(void);
# endif
void NCONF_free(CONF *conf);
void NCONF_free_data(CONF *conf);

int NCONF_load(CONF *conf, const char *file, long *eline);
# ifndef OPENSSL_NO_FP_API
int NCONF_load_fp(CONF *conf, FILE *fp, long *eline);
# endif
int NCONF_load_bio(CONF *conf, BIO *bp, long *eline);
STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf,
                                        const char *section);
char *NCONF_get_string(const CONF *conf, const char *group, const char *name);
int NCONF_get_number_e(const CONF *conf, const char *group, const char *name,
                       long *result);
int NCONF_dump_fp(const CONF *conf, FILE *out);
int NCONF_dump_bio(const CONF *conf, BIO *out);

# if 0                          /* The following function has no error
                                 * checking, and should therefore be avoided */
long NCONF_get_number(CONF *conf, char *group, char *name);
# else
#  define NCONF_get_number(c,g,n,r) NCONF_get_number_e(c,g,n,r)
# endif

/* Module functions */

int CONF_modules_load(const CONF *cnf, const char *appname,
                      unsigned long flags);
int CONF_modules_load_file(const char *filename, const char *appname,
                           unsigned long flags);
void CONF_modules_unload(int all);
void CONF_modules_finish(void);
void CONF_modules_free(void);
int CONF_module_add(const char *name, conf_init_func *ifunc,
                    conf_finish_func *ffunc);

const char *CONF_imodule_get_name(const CONF_IMODULE *md);
const char *CONF_imodule_get_value(const CONF_IMODULE *md);
void *CONF_imodule_get_usr_data(const CONF_IMODULE *md);
void CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data);
CONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md);
unsigned long CONF_imodule_get_flags(const CONF_IMODULE *md);
void CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags);
void *CONF_module_get_usr_data(CONF_MODULE *pmod);
void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data);

char *CONF_get1_default_config_file(void);

int CONF_parse_list(const char *list, int sep, int nospc,
                    int (*list_cb) (const char *elem, int len, void *usr),
                    void *arg);

void OPENSSL_load_builtin_modules(void);

/* BEGIN ERROR CODES */
/*
 * The following lines are auto generated by the script mkerr.pl. Any changes
 * made after this point may be overwritten when the script is next run.
 */
void ERR_load_CONF_strings(void);

/* Error codes for the CONF functions. */

/* Function codes. */
# define CONF_F_CONF_DUMP_FP                              104
# define CONF_F_CONF_LOAD                                 100
# define CONF_F_CONF_LOAD_BIO                             102
# define CONF_F_CONF_LOAD_FP                              103
# define CONF_F_CONF_MODULES_LOAD                         116
# define CONF_F_CONF_PARSE_LIST                           119
# define CONF_F_DEF_LOAD                                  120
# define CONF_F_DEF_LOAD_BIO                              121
# define CONF_F_MODULE_INIT                               115
# define CONF_F_MODULE_LOAD_DSO                           117
# define CONF_F_MODULE_RUN                                118
# define CONF_F_NCONF_DUMP_BIO                            105
# define CONF_F_NCONF_DUMP_FP                             106
# define CONF_F_NCONF_GET_NUMBER                          107
# define CONF_F_NCONF_GET_NUMBER_E                        112
# define CONF_F_NCONF_GET_SECTION                         108
# define CONF_F_NCONF_GET_STRING                          109
# define CONF_F_NCONF_LOAD                                113
# define CONF_F_NCONF_LOAD_BIO                            110
# define CONF_F_NCONF_LOAD_FP                             114
# define CONF_F_NCONF_NEW                                 111
# define CONF_F_STR_COPY                                  101

/* Reason codes. */
# define CONF_R_ERROR_LOADING_DSO                         110
# define CONF_R_LIST_CANNOT_BE_NULL                       115
# define CONF_R_MISSING_CLOSE_SQUARE_BRACKET              100
# define CONF_R_MISSING_EQUAL_SIGN                        101
# define CONF_R_MISSING_FINISH_FUNCTION                   111
# define CONF_R_MISSING_INIT_FUNCTION                     112
# define CONF_R_MODULE_INITIALIZATION_ERROR               109
# define CONF_R_NO_CLOSE_BRACE                            102
# define CONF_R_NO_CONF                                   105
# define CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE           106
# define CONF_R_NO_SECTION                                107
# define CONF_R_NO_SUCH_FILE                              114
# define CONF_R_NO_VALUE                                  108
# define CONF_R_UNABLE_TO_CREATE_NEW_SECTION              103
# define CONF_R_UNKNOWN_MODULE_NAME                       113
# define CONF_R_VARIABLE_EXPANSION_TOO_LONG               116
# define CONF_R_VARIABLE_HAS_NO_VALUE                     104

#ifdef  __cplusplus
}
#endif
#endif
openssl/engine.h000064400000127622151733316570007672 0ustar00/* openssl/engine.h */
/*
 * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project
 * 2000.
 */
/* ====================================================================
 * Copyright (c) 1999-2004 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */
/* ====================================================================
 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
 * ECDH support in OpenSSL originally developed by
 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
 */

#ifndef HEADER_ENGINE_H
# define HEADER_ENGINE_H

# include <openssl/opensslconf.h>

# ifdef OPENSSL_NO_ENGINE
#  error ENGINE is disabled.
# endif

# ifndef OPENSSL_NO_DEPRECATED
#  include <openssl/bn.h>
#  ifndef OPENSSL_NO_RSA
#   include <openssl/rsa.h>
#  endif
#  ifndef OPENSSL_NO_DSA
#   include <openssl/dsa.h>
#  endif
#  ifndef OPENSSL_NO_DH
#   include <openssl/dh.h>
#  endif
#  ifndef OPENSSL_NO_ECDH
#   include <openssl/ecdh.h>
#  endif
#  ifndef OPENSSL_NO_ECDSA
#   include <openssl/ecdsa.h>
#  endif
#  include <openssl/rand.h>
#  include <openssl/ui.h>
#  include <openssl/err.h>
# endif

# include <openssl/ossl_typ.h>
# include <openssl/symhacks.h>

# include <openssl/x509.h>

#ifdef  __cplusplus
extern "C" {
#endif

/*
 * These flags are used to control combinations of algorithm (methods) by
 * bitwise "OR"ing.
 */
# define ENGINE_METHOD_RSA               (unsigned int)0x0001
# define ENGINE_METHOD_DSA               (unsigned int)0x0002
# define ENGINE_METHOD_DH                (unsigned int)0x0004
# define ENGINE_METHOD_RAND              (unsigned int)0x0008
# define ENGINE_METHOD_ECDH              (unsigned int)0x0010
# define ENGINE_METHOD_ECDSA             (unsigned int)0x0020
# define ENGINE_METHOD_CIPHERS           (unsigned int)0x0040
# define ENGINE_METHOD_DIGESTS           (unsigned int)0x0080
# define ENGINE_METHOD_STORE             (unsigned int)0x0100
# define ENGINE_METHOD_PKEY_METHS        (unsigned int)0x0200
# define ENGINE_METHOD_PKEY_ASN1_METHS   (unsigned int)0x0400
/* Obvious all-or-nothing cases. */
# define ENGINE_METHOD_ALL               (unsigned int)0xFFFF
# define ENGINE_METHOD_NONE              (unsigned int)0x0000

/*
 * This(ese) flag(s) controls behaviour of the ENGINE_TABLE mechanism used
 * internally to control registration of ENGINE implementations, and can be
 * set by ENGINE_set_table_flags(). The "NOINIT" flag prevents attempts to
 * initialise registered ENGINEs if they are not already initialised.
 */
# define ENGINE_TABLE_FLAG_NOINIT        (unsigned int)0x0001

/* ENGINE flags that can be set by ENGINE_set_flags(). */
/* Not used */
/* #define ENGINE_FLAGS_MALLOCED        0x0001 */

/*
 * This flag is for ENGINEs that wish to handle the various 'CMD'-related
 * control commands on their own. Without this flag, ENGINE_ctrl() handles
 * these control commands on behalf of the ENGINE using their "cmd_defns"
 * data.
 */
# define ENGINE_FLAGS_MANUAL_CMD_CTRL    (int)0x0002

/*
 * This flag is for ENGINEs who return new duplicate structures when found
 * via "ENGINE_by_id()". When an ENGINE must store state (eg. if
 * ENGINE_ctrl() commands are called in sequence as part of some stateful
 * process like key-generation setup and execution), it can set this flag -
 * then each attempt to obtain the ENGINE will result in it being copied into
 * a new structure. Normally, ENGINEs don't declare this flag so
 * ENGINE_by_id() just increments the existing ENGINE's structural reference
 * count.
 */
# define ENGINE_FLAGS_BY_ID_COPY         (int)0x0004

/*
 * This flag if for an ENGINE that does not want its methods registered as
 * part of ENGINE_register_all_complete() for example if the methods are not
 * usable as default methods.
 */

# define ENGINE_FLAGS_NO_REGISTER_ALL    (int)0x0008

/*
 * ENGINEs can support their own command types, and these flags are used in
 * ENGINE_CTRL_GET_CMD_FLAGS to indicate to the caller what kind of input
 * each command expects. Currently only numeric and string input is
 * supported. If a control command supports none of the _NUMERIC, _STRING, or
 * _NO_INPUT options, then it is regarded as an "internal" control command -
 * and not for use in config setting situations. As such, they're not
 * available to the ENGINE_ctrl_cmd_string() function, only raw ENGINE_ctrl()
 * access. Changes to this list of 'command types' should be reflected
 * carefully in ENGINE_cmd_is_executable() and ENGINE_ctrl_cmd_string().
 */

/* accepts a 'long' input value (3rd parameter to ENGINE_ctrl) */
# define ENGINE_CMD_FLAG_NUMERIC         (unsigned int)0x0001
/*
 * accepts string input (cast from 'void*' to 'const char *', 4th parameter
 * to ENGINE_ctrl)
 */
# define ENGINE_CMD_FLAG_STRING          (unsigned int)0x0002
/*
 * Indicates that the control command takes *no* input. Ie. the control
 * command is unparameterised.
 */
# define ENGINE_CMD_FLAG_NO_INPUT        (unsigned int)0x0004
/*
 * Indicates that the control command is internal. This control command won't
 * be shown in any output, and is only usable through the ENGINE_ctrl_cmd()
 * function.
 */
# define ENGINE_CMD_FLAG_INTERNAL        (unsigned int)0x0008

/*
 * NB: These 3 control commands are deprecated and should not be used.
 * ENGINEs relying on these commands should compile conditional support for
 * compatibility (eg. if these symbols are defined) but should also migrate
 * the same functionality to their own ENGINE-specific control functions that
 * can be "discovered" by calling applications. The fact these control
 * commands wouldn't be "executable" (ie. usable by text-based config)
 * doesn't change the fact that application code can find and use them
 * without requiring per-ENGINE hacking.
 */

/*
 * These flags are used to tell the ctrl function what should be done. All
 * command numbers are shared between all engines, even if some don't make
 * sense to some engines.  In such a case, they do nothing but return the
 * error ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED.
 */
# define ENGINE_CTRL_SET_LOGSTREAM               1
# define ENGINE_CTRL_SET_PASSWORD_CALLBACK       2
# define ENGINE_CTRL_HUP                         3/* Close and reinitialise
                                                   * any handles/connections
                                                   * etc. */
# define ENGINE_CTRL_SET_USER_INTERFACE          4/* Alternative to callback */
# define ENGINE_CTRL_SET_CALLBACK_DATA           5/* User-specific data, used
                                                   * when calling the password
                                                   * callback and the user
                                                   * interface */
# define ENGINE_CTRL_LOAD_CONFIGURATION          6/* Load a configuration,
                                                   * given a string that
                                                   * represents a file name
                                                   * or so */
# define ENGINE_CTRL_LOAD_SECTION                7/* Load data from a given
                                                   * section in the already
                                                   * loaded configuration */

/*
 * These control commands allow an application to deal with an arbitrary
 * engine in a dynamic way. Warn: Negative return values indicate errors FOR
 * THESE COMMANDS because zero is used to indicate 'end-of-list'. Other
 * commands, including ENGINE-specific command types, return zero for an
 * error. An ENGINE can choose to implement these ctrl functions, and can
 * internally manage things however it chooses - it does so by setting the
 * ENGINE_FLAGS_MANUAL_CMD_CTRL flag (using ENGINE_set_flags()). Otherwise
 * the ENGINE_ctrl() code handles this on the ENGINE's behalf using the
 * cmd_defns data (set using ENGINE_set_cmd_defns()). This means an ENGINE's
 * ctrl() handler need only implement its own commands - the above "meta"
 * commands will be taken care of.
 */

/*
 * Returns non-zero if the supplied ENGINE has a ctrl() handler. If "not",
 * then all the remaining control commands will return failure, so it is
 * worth checking this first if the caller is trying to "discover" the
 * engine's capabilities and doesn't want errors generated unnecessarily.
 */
# define ENGINE_CTRL_HAS_CTRL_FUNCTION           10
/*
 * Returns a positive command number for the first command supported by the
 * engine. Returns zero if no ctrl commands are supported.
 */
# define ENGINE_CTRL_GET_FIRST_CMD_TYPE          11
/*
 * The 'long' argument specifies a command implemented by the engine, and the
 * return value is the next command supported, or zero if there are no more.
 */
# define ENGINE_CTRL_GET_NEXT_CMD_TYPE           12
/*
 * The 'void*' argument is a command name (cast from 'const char *'), and the
 * return value is the command that corresponds to it.
 */
# define ENGINE_CTRL_GET_CMD_FROM_NAME           13
/*
 * The next two allow a command to be converted into its corresponding string
 * form. In each case, the 'long' argument supplies the command. In the
 * NAME_LEN case, the return value is the length of the command name (not
 * counting a trailing EOL). In the NAME case, the 'void*' argument must be a
 * string buffer large enough, and it will be populated with the name of the
 * command (WITH a trailing EOL).
 */
# define ENGINE_CTRL_GET_NAME_LEN_FROM_CMD       14
# define ENGINE_CTRL_GET_NAME_FROM_CMD           15
/* The next two are similar but give a "short description" of a command. */
# define ENGINE_CTRL_GET_DESC_LEN_FROM_CMD       16
# define ENGINE_CTRL_GET_DESC_FROM_CMD           17
/*
 * With this command, the return value is the OR'd combination of
 * ENGINE_CMD_FLAG_*** values that indicate what kind of input a given
 * engine-specific ctrl command expects.
 */
# define ENGINE_CTRL_GET_CMD_FLAGS               18

/*
 * ENGINE implementations should start the numbering of their own control
 * commands from this value. (ie. ENGINE_CMD_BASE, ENGINE_CMD_BASE + 1, etc).
 */
# define ENGINE_CMD_BASE                         200

/*
 * NB: These 2 nCipher "chil" control commands are deprecated, and their
 * functionality is now available through ENGINE-specific control commands
 * (exposed through the above-mentioned 'CMD'-handling). Code using these 2
 * commands should be migrated to the more general command handling before
 * these are removed.
 */

/* Flags specific to the nCipher "chil" engine */
# define ENGINE_CTRL_CHIL_SET_FORKCHECK          100
        /*
         * Depending on the value of the (long)i argument, this sets or
         * unsets the SimpleForkCheck flag in the CHIL API to enable or
         * disable checking and workarounds for applications that fork().
         */
# define ENGINE_CTRL_CHIL_NO_LOCKING             101
        /*
         * This prevents the initialisation function from providing mutex
         * callbacks to the nCipher library.
         */

/*
 * If an ENGINE supports its own specific control commands and wishes the
 * framework to handle the above 'ENGINE_CMD_***'-manipulation commands on
 * its behalf, it should supply a null-terminated array of ENGINE_CMD_DEFN
 * entries to ENGINE_set_cmd_defns(). It should also implement a ctrl()
 * handler that supports the stated commands (ie. the "cmd_num" entries as
 * described by the array). NB: The array must be ordered in increasing order
 * of cmd_num. "null-terminated" means that the last ENGINE_CMD_DEFN element
 * has cmd_num set to zero and/or cmd_name set to NULL.
 */
typedef struct ENGINE_CMD_DEFN_st {
    unsigned int cmd_num;       /* The command number */
    const char *cmd_name;       /* The command name itself */
    const char *cmd_desc;       /* A short description of the command */
    unsigned int cmd_flags;     /* The input the command expects */
} ENGINE_CMD_DEFN;

/* Generic function pointer */
typedef int (*ENGINE_GEN_FUNC_PTR) (void);
/* Generic function pointer taking no arguments */
typedef int (*ENGINE_GEN_INT_FUNC_PTR) (ENGINE *);
/* Specific control function pointer */
typedef int (*ENGINE_CTRL_FUNC_PTR) (ENGINE *, int, long, void *,
                                     void (*f) (void));
/* Generic load_key function pointer */
typedef EVP_PKEY *(*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *,
                                         UI_METHOD *ui_method,
                                         void *callback_data);
typedef int (*ENGINE_SSL_CLIENT_CERT_PTR) (ENGINE *, SSL *ssl,
                                           STACK_OF(X509_NAME) *ca_dn,
                                           X509 **pcert, EVP_PKEY **pkey,
                                           STACK_OF(X509) **pother,
                                           UI_METHOD *ui_method,
                                           void *callback_data);
/*-
 * These callback types are for an ENGINE's handler for cipher and digest logic.
 * These handlers have these prototypes;
 *   int foo(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid);
 *   int foo(ENGINE *e, const EVP_MD **digest, const int **nids, int nid);
 * Looking at how to implement these handlers in the case of cipher support, if
 * the framework wants the EVP_CIPHER for 'nid', it will call;
 *   foo(e, &p_evp_cipher, NULL, nid);    (return zero for failure)
 * If the framework wants a list of supported 'nid's, it will call;
 *   foo(e, NULL, &p_nids, 0); (returns number of 'nids' or -1 for error)
 */
/*
 * Returns to a pointer to the array of supported cipher 'nid's. If the
 * second parameter is non-NULL it is set to the size of the returned array.
 */
typedef int (*ENGINE_CIPHERS_PTR) (ENGINE *, const EVP_CIPHER **,
                                   const int **, int);
typedef int (*ENGINE_DIGESTS_PTR) (ENGINE *, const EVP_MD **, const int **,
                                   int);
typedef int (*ENGINE_PKEY_METHS_PTR) (ENGINE *, EVP_PKEY_METHOD **,
                                      const int **, int);
typedef int (*ENGINE_PKEY_ASN1_METHS_PTR) (ENGINE *, EVP_PKEY_ASN1_METHOD **,
                                           const int **, int);
/*
 * STRUCTURE functions ... all of these functions deal with pointers to
 * ENGINE structures where the pointers have a "structural reference". This
 * means that their reference is to allowed access to the structure but it
 * does not imply that the structure is functional. To simply increment or
 * decrement the structural reference count, use ENGINE_by_id and
 * ENGINE_free. NB: This is not required when iterating using ENGINE_get_next
 * as it will automatically decrement the structural reference count of the
 * "current" ENGINE and increment the structural reference count of the
 * ENGINE it returns (unless it is NULL).
 */

/* Get the first/last "ENGINE" type available. */
ENGINE *ENGINE_get_first(void);
ENGINE *ENGINE_get_last(void);
/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */
ENGINE *ENGINE_get_next(ENGINE *e);
ENGINE *ENGINE_get_prev(ENGINE *e);
/* Add another "ENGINE" type into the array. */
int ENGINE_add(ENGINE *e);
/* Remove an existing "ENGINE" type from the array. */
int ENGINE_remove(ENGINE *e);
/* Retrieve an engine from the list by its unique "id" value. */
ENGINE *ENGINE_by_id(const char *id);
/* Add all the built-in engines. */
void ENGINE_load_openssl(void);
void ENGINE_load_dynamic(void);
# ifndef OPENSSL_NO_STATIC_ENGINE
void ENGINE_load_4758cca(void);
void ENGINE_load_aep(void);
void ENGINE_load_atalla(void);
void ENGINE_load_chil(void);
void ENGINE_load_cswift(void);
void ENGINE_load_nuron(void);
void ENGINE_load_sureware(void);
void ENGINE_load_ubsec(void);
void ENGINE_load_padlock(void);
void ENGINE_load_capi(void);
#  ifndef OPENSSL_NO_GMP
void ENGINE_load_gmp(void);
#  endif
#  ifndef OPENSSL_NO_GOST
void ENGINE_load_gost(void);
#  endif
# endif
void ENGINE_load_cryptodev(void);
void ENGINE_load_rdrand(void);
void ENGINE_load_builtin_engines(void);

/*
 * Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation
 * "registry" handling.
 */
unsigned int ENGINE_get_table_flags(void);
void ENGINE_set_table_flags(unsigned int flags);

/*- Manage registration of ENGINEs per "table". For each type, there are 3
 * functions;
 *   ENGINE_register_***(e) - registers the implementation from 'e' (if it has one)
 *   ENGINE_unregister_***(e) - unregister the implementation from 'e'
 *   ENGINE_register_all_***() - call ENGINE_register_***() for each 'e' in the list
 * Cleanup is automatically registered from each table when required, so
 * ENGINE_cleanup() will reverse any "register" operations.
 */

int ENGINE_register_RSA(ENGINE *e);
void ENGINE_unregister_RSA(ENGINE *e);
void ENGINE_register_all_RSA(void);

int ENGINE_register_DSA(ENGINE *e);
void ENGINE_unregister_DSA(ENGINE *e);
void ENGINE_register_all_DSA(void);

int ENGINE_register_ECDH(ENGINE *e);
void ENGINE_unregister_ECDH(ENGINE *e);
void ENGINE_register_all_ECDH(void);

int ENGINE_register_ECDSA(ENGINE *e);
void ENGINE_unregister_ECDSA(ENGINE *e);
void ENGINE_register_all_ECDSA(void);

int ENGINE_register_DH(ENGINE *e);
void ENGINE_unregister_DH(ENGINE *e);
void ENGINE_register_all_DH(void);

int ENGINE_register_RAND(ENGINE *e);
void ENGINE_unregister_RAND(ENGINE *e);
void ENGINE_register_all_RAND(void);

int ENGINE_register_STORE(ENGINE *e);
void ENGINE_unregister_STORE(ENGINE *e);
void ENGINE_register_all_STORE(void);

int ENGINE_register_ciphers(ENGINE *e);
void ENGINE_unregister_ciphers(ENGINE *e);
void ENGINE_register_all_ciphers(void);

int ENGINE_register_digests(ENGINE *e);
void ENGINE_unregister_digests(ENGINE *e);
void ENGINE_register_all_digests(void);

int ENGINE_register_pkey_meths(ENGINE *e);
void ENGINE_unregister_pkey_meths(ENGINE *e);
void ENGINE_register_all_pkey_meths(void);

int ENGINE_register_pkey_asn1_meths(ENGINE *e);
void ENGINE_unregister_pkey_asn1_meths(ENGINE *e);
void ENGINE_register_all_pkey_asn1_meths(void);

/*
 * These functions register all support from the above categories. Note, use
 * of these functions can result in static linkage of code your application
 * may not need. If you only need a subset of functionality, consider using
 * more selective initialisation.
 */
int ENGINE_register_complete(ENGINE *e);
int ENGINE_register_all_complete(void);

/*
 * Send parametrised control commands to the engine. The possibilities to
 * send down an integer, a pointer to data or a function pointer are
 * provided. Any of the parameters may or may not be NULL, depending on the
 * command number. In actuality, this function only requires a structural
 * (rather than functional) reference to an engine, but many control commands
 * may require the engine be functional. The caller should be aware of trying
 * commands that require an operational ENGINE, and only use functional
 * references in such situations.
 */
int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void));

/*
 * This function tests if an ENGINE-specific command is usable as a
 * "setting". Eg. in an application's config file that gets processed through
 * ENGINE_ctrl_cmd_string(). If this returns zero, it is not available to
 * ENGINE_ctrl_cmd_string(), only ENGINE_ctrl().
 */
int ENGINE_cmd_is_executable(ENGINE *e, int cmd);

/*
 * This function works like ENGINE_ctrl() with the exception of taking a
 * command name instead of a command number, and can handle optional
 * commands. See the comment on ENGINE_ctrl_cmd_string() for an explanation
 * on how to use the cmd_name and cmd_optional.
 */
int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
                    long i, void *p, void (*f) (void), int cmd_optional);

/*
 * This function passes a command-name and argument to an ENGINE. The
 * cmd_name is converted to a command number and the control command is
 * called using 'arg' as an argument (unless the ENGINE doesn't support such
 * a command, in which case no control command is called). The command is
 * checked for input flags, and if necessary the argument will be converted
 * to a numeric value. If cmd_optional is non-zero, then if the ENGINE
 * doesn't support the given cmd_name the return value will be success
 * anyway. This function is intended for applications to use so that users
 * (or config files) can supply engine-specific config data to the ENGINE at
 * run-time to control behaviour of specific engines. As such, it shouldn't
 * be used for calling ENGINE_ctrl() functions that return data, deal with
 * binary data, or that are otherwise supposed to be used directly through
 * ENGINE_ctrl() in application code. Any "return" data from an ENGINE_ctrl()
 * operation in this function will be lost - the return value is interpreted
 * as failure if the return value is zero, success otherwise, and this
 * function returns a boolean value as a result. In other words, vendors of
 * 'ENGINE'-enabled devices should write ENGINE implementations with
 * parameterisations that work in this scheme, so that compliant ENGINE-based
 * applications can work consistently with the same configuration for the
 * same ENGINE-enabled devices, across applications.
 */
int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
                           int cmd_optional);

/*
 * These functions are useful for manufacturing new ENGINE structures. They
 * don't address reference counting at all - one uses them to populate an
 * ENGINE structure with personalised implementations of things prior to
 * using it directly or adding it to the builtin ENGINE list in OpenSSL.
 * These are also here so that the ENGINE structure doesn't have to be
 * exposed and break binary compatibility!
 */
ENGINE *ENGINE_new(void);
int ENGINE_free(ENGINE *e);
int ENGINE_up_ref(ENGINE *e);
int ENGINE_set_id(ENGINE *e, const char *id);
int ENGINE_set_name(ENGINE *e, const char *name);
int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth);
int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth);
int ENGINE_set_ECDH(ENGINE *e, const ECDH_METHOD *ecdh_meth);
int ENGINE_set_ECDSA(ENGINE *e, const ECDSA_METHOD *ecdsa_meth);
int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth);
int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth);
int ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *store_meth);
int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f);
int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f);
int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f);
int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f);
int ENGINE_set_load_privkey_function(ENGINE *e,
                                     ENGINE_LOAD_KEY_PTR loadpriv_f);
int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f);
int ENGINE_set_load_ssl_client_cert_function(ENGINE *e,
                                             ENGINE_SSL_CLIENT_CERT_PTR
                                             loadssl_f);
int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f);
int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f);
int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f);
int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f);
int ENGINE_set_flags(ENGINE *e, int flags);
int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns);
/* These functions allow control over any per-structure ENGINE data. */
int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
                            CRYPTO_EX_dup *dup_func,
                            CRYPTO_EX_free *free_func);
int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg);
void *ENGINE_get_ex_data(const ENGINE *e, int idx);

/*
 * This function cleans up anything that needs it. Eg. the ENGINE_add()
 * function automatically ensures the list cleanup function is registered to
 * be called from ENGINE_cleanup(). Similarly, all ENGINE_register_***
 * functions ensure ENGINE_cleanup() will clean up after them.
 */
void ENGINE_cleanup(void);

/*
 * These return values from within the ENGINE structure. These can be useful
 * with functional references as well as structural references - it depends
 * which you obtained. Using the result for functional purposes if you only
 * obtained a structural reference may be problematic!
 */
const char *ENGINE_get_id(const ENGINE *e);
const char *ENGINE_get_name(const ENGINE *e);
const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e);
const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e);
const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *e);
const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *e);
const DH_METHOD *ENGINE_get_DH(const ENGINE *e);
const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e);
const STORE_METHOD *ENGINE_get_STORE(const ENGINE *e);
ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e);
ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e);
ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e);
ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e);
ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e);
ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e);
ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE
                                                               *e);
ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e);
ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e);
ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e);
ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e);
const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid);
const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid);
const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid);
const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid);
const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e,
                                                          const char *str,
                                                          int len);
const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe,
                                                      const char *str,
                                                      int len);
const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e);
int ENGINE_get_flags(const ENGINE *e);

/*
 * FUNCTIONAL functions. These functions deal with ENGINE structures that
 * have (or will) be initialised for use. Broadly speaking, the structural
 * functions are useful for iterating the list of available engine types,
 * creating new engine types, and other "list" operations. These functions
 * actually deal with ENGINEs that are to be used. As such these functions
 * can fail (if applicable) when particular engines are unavailable - eg. if
 * a hardware accelerator is not attached or not functioning correctly. Each
 * ENGINE has 2 reference counts; structural and functional. Every time a
 * functional reference is obtained or released, a corresponding structural
 * reference is automatically obtained or released too.
 */

/*
 * Initialise a engine type for use (or up its reference count if it's
 * already in use). This will fail if the engine is not currently operational
 * and cannot initialise.
 */
int ENGINE_init(ENGINE *e);
/*
 * Free a functional reference to a engine type. This does not require a
 * corresponding call to ENGINE_free as it also releases a structural
 * reference.
 */
int ENGINE_finish(ENGINE *e);

/*
 * The following functions handle keys that are stored in some secondary
 * location, handled by the engine.  The storage may be on a card or
 * whatever.
 */
EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
                                  UI_METHOD *ui_method, void *callback_data);
EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
                                 UI_METHOD *ui_method, void *callback_data);
int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s,
                                STACK_OF(X509_NAME) *ca_dn, X509 **pcert,
                                EVP_PKEY **ppkey, STACK_OF(X509) **pother,
                                UI_METHOD *ui_method, void *callback_data);

/*
 * This returns a pointer for the current ENGINE structure that is (by
 * default) performing any RSA operations. The value returned is an
 * incremented reference, so it should be free'd (ENGINE_finish) before it is
 * discarded.
 */
ENGINE *ENGINE_get_default_RSA(void);
/* Same for the other "methods" */
ENGINE *ENGINE_get_default_DSA(void);
ENGINE *ENGINE_get_default_ECDH(void);
ENGINE *ENGINE_get_default_ECDSA(void);
ENGINE *ENGINE_get_default_DH(void);
ENGINE *ENGINE_get_default_RAND(void);
/*
 * These functions can be used to get a functional reference to perform
 * ciphering or digesting corresponding to "nid".
 */
ENGINE *ENGINE_get_cipher_engine(int nid);
ENGINE *ENGINE_get_digest_engine(int nid);
ENGINE *ENGINE_get_pkey_meth_engine(int nid);
ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid);

/*
 * This sets a new default ENGINE structure for performing RSA operations. If
 * the result is non-zero (success) then the ENGINE structure will have had
 * its reference count up'd so the caller should still free their own
 * reference 'e'.
 */
int ENGINE_set_default_RSA(ENGINE *e);
int ENGINE_set_default_string(ENGINE *e, const char *def_list);
/* Same for the other "methods" */
int ENGINE_set_default_DSA(ENGINE *e);
int ENGINE_set_default_ECDH(ENGINE *e);
int ENGINE_set_default_ECDSA(ENGINE *e);
int ENGINE_set_default_DH(ENGINE *e);
int ENGINE_set_default_RAND(ENGINE *e);
int ENGINE_set_default_ciphers(ENGINE *e);
int ENGINE_set_default_digests(ENGINE *e);
int ENGINE_set_default_pkey_meths(ENGINE *e);
int ENGINE_set_default_pkey_asn1_meths(ENGINE *e);

/*
 * The combination "set" - the flags are bitwise "OR"d from the
 * ENGINE_METHOD_*** defines above. As with the "ENGINE_register_complete()"
 * function, this function can result in unnecessary static linkage. If your
 * application requires only specific functionality, consider using more
 * selective functions.
 */
int ENGINE_set_default(ENGINE *e, unsigned int flags);

void ENGINE_add_conf_module(void);

/* Deprecated functions ... */
/* int ENGINE_clear_defaults(void); */

/**************************/
/* DYNAMIC ENGINE SUPPORT */
/**************************/

/* Binary/behaviour compatibility levels */
# define OSSL_DYNAMIC_VERSION            (unsigned long)0x00020000
/*
 * Binary versions older than this are too old for us (whether we're a loader
 * or a loadee)
 */
# define OSSL_DYNAMIC_OLDEST             (unsigned long)0x00020000

/*
 * When compiling an ENGINE entirely as an external shared library, loadable
 * by the "dynamic" ENGINE, these types are needed. The 'dynamic_fns'
 * structure type provides the calling application's (or library's) error
 * functionality and memory management function pointers to the loaded
 * library. These should be used/set in the loaded library code so that the
 * loading application's 'state' will be used/changed in all operations. The
 * 'static_state' pointer allows the loaded library to know if it shares the
 * same static data as the calling application (or library), and thus whether
 * these callbacks need to be set or not.
 */
typedef void *(*dyn_MEM_malloc_cb) (size_t);
typedef void *(*dyn_MEM_realloc_cb) (void *, size_t);
typedef void (*dyn_MEM_free_cb) (void *);
typedef struct st_dynamic_MEM_fns {
    dyn_MEM_malloc_cb malloc_cb;
    dyn_MEM_realloc_cb realloc_cb;
    dyn_MEM_free_cb free_cb;
} dynamic_MEM_fns;
/*
 * FIXME: Perhaps the memory and locking code (crypto.h) should declare and
 * use these types so we (and any other dependant code) can simplify a bit??
 */
typedef void (*dyn_lock_locking_cb) (int, int, const char *, int);
typedef int (*dyn_lock_add_lock_cb) (int *, int, int, const char *, int);
typedef struct CRYPTO_dynlock_value *(*dyn_dynlock_create_cb) (const char *,
                                                               int);
typedef void (*dyn_dynlock_lock_cb) (int, struct CRYPTO_dynlock_value *,
                                     const char *, int);
typedef void (*dyn_dynlock_destroy_cb) (struct CRYPTO_dynlock_value *,
                                        const char *, int);
typedef struct st_dynamic_LOCK_fns {
    dyn_lock_locking_cb lock_locking_cb;
    dyn_lock_add_lock_cb lock_add_lock_cb;
    dyn_dynlock_create_cb dynlock_create_cb;
    dyn_dynlock_lock_cb dynlock_lock_cb;
    dyn_dynlock_destroy_cb dynlock_destroy_cb;
} dynamic_LOCK_fns;
/* The top-level structure */
typedef struct st_dynamic_fns {
    void *static_state;
    const ERR_FNS *err_fns;
    const CRYPTO_EX_DATA_IMPL *ex_data_fns;
    dynamic_MEM_fns mem_fns;
    dynamic_LOCK_fns lock_fns;
} dynamic_fns;

/*
 * The version checking function should be of this prototype. NB: The
 * ossl_version value passed in is the OSSL_DYNAMIC_VERSION of the loading
 * code. If this function returns zero, it indicates a (potential) version
 * incompatibility and the loaded library doesn't believe it can proceed.
 * Otherwise, the returned value is the (latest) version supported by the
 * loading library. The loader may still decide that the loaded code's
 * version is unsatisfactory and could veto the load. The function is
 * expected to be implemented with the symbol name "v_check", and a default
 * implementation can be fully instantiated with
 * IMPLEMENT_DYNAMIC_CHECK_FN().
 */
typedef unsigned long (*dynamic_v_check_fn) (unsigned long ossl_version);
# define IMPLEMENT_DYNAMIC_CHECK_FN() \
        OPENSSL_EXPORT unsigned long v_check(unsigned long v); \
        OPENSSL_EXPORT unsigned long v_check(unsigned long v) { \
                if(v >= OSSL_DYNAMIC_OLDEST) return OSSL_DYNAMIC_VERSION; \
                return 0; }

/*
 * This function is passed the ENGINE structure to initialise with its own
 * function and command settings. It should not adjust the structural or
 * functional reference counts. If this function returns zero, (a) the load
 * will be aborted, (b) the previous ENGINE state will be memcpy'd back onto
 * the structure, and (c) the shared library will be unloaded. So
 * implementations should do their own internal cleanup in failure
 * circumstances otherwise they could leak. The 'id' parameter, if non-NULL,
 * represents the ENGINE id that the loader is looking for. If this is NULL,
 * the shared library can choose to return failure or to initialise a
 * 'default' ENGINE. If non-NULL, the shared library must initialise only an
 * ENGINE matching the passed 'id'. The function is expected to be
 * implemented with the symbol name "bind_engine". A standard implementation
 * can be instantiated with IMPLEMENT_DYNAMIC_BIND_FN(fn) where the parameter
 * 'fn' is a callback function that populates the ENGINE structure and
 * returns an int value (zero for failure). 'fn' should have prototype;
 * [static] int fn(ENGINE *e, const char *id);
 */
typedef int (*dynamic_bind_engine) (ENGINE *e, const char *id,
                                    const dynamic_fns *fns);
# define IMPLEMENT_DYNAMIC_BIND_FN(fn) \
        OPENSSL_EXPORT \
        int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns); \
        OPENSSL_EXPORT \
        int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { \
                if(ENGINE_get_static_state() == fns->static_state) goto skip_cbs; \
                if(!CRYPTO_set_mem_functions(fns->mem_fns.malloc_cb, \
                        fns->mem_fns.realloc_cb, fns->mem_fns.free_cb)) \
                        return 0; \
                CRYPTO_set_locking_callback(fns->lock_fns.lock_locking_cb); \
                CRYPTO_set_add_lock_callback(fns->lock_fns.lock_add_lock_cb); \
                CRYPTO_set_dynlock_create_callback(fns->lock_fns.dynlock_create_cb); \
                CRYPTO_set_dynlock_lock_callback(fns->lock_fns.dynlock_lock_cb); \
                CRYPTO_set_dynlock_destroy_callback(fns->lock_fns.dynlock_destroy_cb); \
                if(!CRYPTO_set_ex_data_implementation(fns->ex_data_fns)) \
                        return 0; \
                if(!ERR_set_implementation(fns->err_fns)) return 0; \
        skip_cbs: \
                if(!fn(e,id)) return 0; \
                return 1; }

/*
 * If the loading application (or library) and the loaded ENGINE library
 * share the same static data (eg. they're both dynamically linked to the
 * same libcrypto.so) we need a way to avoid trying to set system callbacks -
 * this would fail, and for the same reason that it's unnecessary to try. If
 * the loaded ENGINE has (or gets from through the loader) its own copy of
 * the libcrypto static data, we will need to set the callbacks. The easiest
 * way to detect this is to have a function that returns a pointer to some
 * static data and let the loading application and loaded ENGINE compare
 * their respective values.
 */
void *ENGINE_get_static_state(void);

# if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
void ENGINE_setup_bsd_cryptodev(void);
# endif

/* BEGIN ERROR CODES */
/*
 * The following lines are auto generated by the script mkerr.pl. Any changes
 * made after this point may be overwritten when the script is next run.
 */
void ERR_load_ENGINE_strings(void);

/* Error codes for the ENGINE functions. */

/* Function codes. */
# define ENGINE_F_DYNAMIC_CTRL                            180
# define ENGINE_F_DYNAMIC_GET_DATA_CTX                    181
# define ENGINE_F_DYNAMIC_LOAD                            182
# define ENGINE_F_DYNAMIC_SET_DATA_CTX                    183
# define ENGINE_F_ENGINE_ADD                              105
# define ENGINE_F_ENGINE_BY_ID                            106
# define ENGINE_F_ENGINE_CMD_IS_EXECUTABLE                170
# define ENGINE_F_ENGINE_CTRL                             142
# define ENGINE_F_ENGINE_CTRL_CMD                         178
# define ENGINE_F_ENGINE_CTRL_CMD_STRING                  171
# define ENGINE_F_ENGINE_FINISH                           107
# define ENGINE_F_ENGINE_FREE_UTIL                        108
# define ENGINE_F_ENGINE_GET_CIPHER                       185
# define ENGINE_F_ENGINE_GET_DEFAULT_TYPE                 177
# define ENGINE_F_ENGINE_GET_DIGEST                       186
# define ENGINE_F_ENGINE_GET_NEXT                         115
# define ENGINE_F_ENGINE_GET_PKEY_ASN1_METH               193
# define ENGINE_F_ENGINE_GET_PKEY_METH                    192
# define ENGINE_F_ENGINE_GET_PREV                         116
# define ENGINE_F_ENGINE_INIT                             119
# define ENGINE_F_ENGINE_LIST_ADD                         120
# define ENGINE_F_ENGINE_LIST_REMOVE                      121
# define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY                 150
# define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY                  151
# define ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT             194
# define ENGINE_F_ENGINE_NEW                              122
# define ENGINE_F_ENGINE_REMOVE                           123
# define ENGINE_F_ENGINE_SET_DEFAULT_STRING               189
# define ENGINE_F_ENGINE_SET_DEFAULT_TYPE                 126
# define ENGINE_F_ENGINE_SET_ID                           129
# define ENGINE_F_ENGINE_SET_NAME                         130
# define ENGINE_F_ENGINE_TABLE_REGISTER                   184
# define ENGINE_F_ENGINE_UNLOAD_KEY                       152
# define ENGINE_F_ENGINE_UNLOCKED_FINISH                  191
# define ENGINE_F_ENGINE_UP_REF                           190
# define ENGINE_F_INT_CTRL_HELPER                         172
# define ENGINE_F_INT_ENGINE_CONFIGURE                    188
# define ENGINE_F_INT_ENGINE_MODULE_INIT                  187
# define ENGINE_F_LOG_MESSAGE                             141

/* Reason codes. */
# define ENGINE_R_ALREADY_LOADED                          100
# define ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER                133
# define ENGINE_R_CMD_NOT_EXECUTABLE                      134
# define ENGINE_R_COMMAND_TAKES_INPUT                     135
# define ENGINE_R_COMMAND_TAKES_NO_INPUT                  136
# define ENGINE_R_CONFLICTING_ENGINE_ID                   103
# define ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED            119
# define ENGINE_R_DH_NOT_IMPLEMENTED                      139
# define ENGINE_R_DSA_NOT_IMPLEMENTED                     140
# define ENGINE_R_DSO_FAILURE                             104
# define ENGINE_R_DSO_NOT_FOUND                           132
# define ENGINE_R_ENGINES_SECTION_ERROR                   148
# define ENGINE_R_ENGINE_CONFIGURATION_ERROR              102
# define ENGINE_R_ENGINE_IS_NOT_IN_LIST                   105
# define ENGINE_R_ENGINE_SECTION_ERROR                    149
# define ENGINE_R_FAILED_LOADING_PRIVATE_KEY              128
# define ENGINE_R_FAILED_LOADING_PUBLIC_KEY               129
# define ENGINE_R_FINISH_FAILED                           106
# define ENGINE_R_GET_HANDLE_FAILED                       107
# define ENGINE_R_ID_OR_NAME_MISSING                      108
# define ENGINE_R_INIT_FAILED                             109
# define ENGINE_R_INTERNAL_LIST_ERROR                     110
# define ENGINE_R_INVALID_ARGUMENT                        143
# define ENGINE_R_INVALID_CMD_NAME                        137
# define ENGINE_R_INVALID_CMD_NUMBER                      138
# define ENGINE_R_INVALID_INIT_VALUE                      151
# define ENGINE_R_INVALID_STRING                          150
# define ENGINE_R_NOT_INITIALISED                         117
# define ENGINE_R_NOT_LOADED                              112
# define ENGINE_R_NO_CONTROL_FUNCTION                     120
# define ENGINE_R_NO_INDEX                                144
# define ENGINE_R_NO_LOAD_FUNCTION                        125
# define ENGINE_R_NO_REFERENCE                            130
# define ENGINE_R_NO_SUCH_ENGINE                          116
# define ENGINE_R_NO_UNLOAD_FUNCTION                      126
# define ENGINE_R_PROVIDE_PARAMETERS                      113
# define ENGINE_R_RSA_NOT_IMPLEMENTED                     141
# define ENGINE_R_UNIMPLEMENTED_CIPHER                    146
# define ENGINE_R_UNIMPLEMENTED_DIGEST                    147
# define ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD         101
# define ENGINE_R_VERSION_INCOMPATIBILITY                 145

#ifdef  __cplusplus
}
#endif
#endif
openssl/sha.h000064400000016630151733316570007174 0ustar00/* crypto/sha/sha.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#ifndef HEADER_SHA_H
# define HEADER_SHA_H

# include <openssl/e_os2.h>
# include <stddef.h>

#ifdef  __cplusplus
extern "C" {
#endif

# if defined(OPENSSL_NO_SHA) || (defined(OPENSSL_NO_SHA0) && defined(OPENSSL_NO_SHA1))
#  error SHA is disabled.
# endif

# if defined(OPENSSL_FIPS)
#  define FIPS_SHA_SIZE_T size_t
# endif

/*-
 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 * ! SHA_LONG has to be at least 32 bits wide. If it's wider, then !
 * ! SHA_LONG_LOG2 has to be defined along.                        !
 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 */

# if defined(__LP32__)
#  define SHA_LONG unsigned long
# elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
#  define SHA_LONG unsigned long
#  define SHA_LONG_LOG2 3
# else
#  define SHA_LONG unsigned int
# endif

# define SHA_LBLOCK      16
# define SHA_CBLOCK      (SHA_LBLOCK*4)/* SHA treats input data as a
                                        * contiguous array of 32 bit wide
                                        * big-endian values. */
# define SHA_LAST_BLOCK  (SHA_CBLOCK-8)
# define SHA_DIGEST_LENGTH 20

typedef struct SHAstate_st {
    SHA_LONG h0, h1, h2, h3, h4;
    SHA_LONG Nl, Nh;
    SHA_LONG data[SHA_LBLOCK];
    unsigned int num;
} SHA_CTX;

# ifndef OPENSSL_NO_SHA0
int SHA_Init(SHA_CTX *c);
int SHA_Update(SHA_CTX *c, const void *data, size_t len);
int SHA_Final(unsigned char *md, SHA_CTX *c);
unsigned char *SHA(const unsigned char *d, size_t n, unsigned char *md);
void SHA_Transform(SHA_CTX *c, const unsigned char *data);
# endif
# ifndef OPENSSL_NO_SHA1
int SHA1_Init(SHA_CTX *c);
int SHA1_Update(SHA_CTX *c, const void *data, size_t len);
int SHA1_Final(unsigned char *md, SHA_CTX *c);
unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md);
void SHA1_Transform(SHA_CTX *c, const unsigned char *data);
# endif

# define SHA256_CBLOCK   (SHA_LBLOCK*4)/* SHA-256 treats input data as a
                                        * contiguous array of 32 bit wide
                                        * big-endian values. */
# define SHA224_DIGEST_LENGTH    28
# define SHA256_DIGEST_LENGTH    32

typedef struct SHA256state_st {
    SHA_LONG h[8];
    SHA_LONG Nl, Nh;
    SHA_LONG data[SHA_LBLOCK];
    unsigned int num, md_len;
} SHA256_CTX;

# ifndef OPENSSL_NO_SHA256
int SHA224_Init(SHA256_CTX *c);
int SHA224_Update(SHA256_CTX *c, const void *data, size_t len);
int SHA224_Final(unsigned char *md, SHA256_CTX *c);
unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md);
int SHA256_Init(SHA256_CTX *c);
int SHA256_Update(SHA256_CTX *c, const void *data, size_t len);
int SHA256_Final(unsigned char *md, SHA256_CTX *c);
unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md);
void SHA256_Transform(SHA256_CTX *c, const unsigned char *data);
# endif

# define SHA384_DIGEST_LENGTH    48
# define SHA512_DIGEST_LENGTH    64

# ifndef OPENSSL_NO_SHA512
/*
 * Unlike 32-bit digest algorithms, SHA-512 *relies* on SHA_LONG64
 * being exactly 64-bit wide. See Implementation Notes in sha512.c
 * for further details.
 */
/*
 * SHA-512 treats input data as a
 * contiguous array of 64 bit
 * wide big-endian values.
 */
#  define SHA512_CBLOCK   (SHA_LBLOCK*8)
#  if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
#   define SHA_LONG64 unsigned __int64
#   define U64(C)     C##UI64
#  elif defined(__arch64__)
#   define SHA_LONG64 unsigned long
#   define U64(C)     C##UL
#  else
#   define SHA_LONG64 unsigned long long
#   define U64(C)     C##ULL
#  endif

typedef struct SHA512state_st {
    SHA_LONG64 h[8];
    SHA_LONG64 Nl, Nh;
    union {
        SHA_LONG64 d[SHA_LBLOCK];
        unsigned char p[SHA512_CBLOCK];
    } u;
    unsigned int num, md_len;
} SHA512_CTX;
# endif

# ifndef OPENSSL_NO_SHA512
int SHA384_Init(SHA512_CTX *c);
int SHA384_Update(SHA512_CTX *c, const void *data, size_t len);
int SHA384_Final(unsigned char *md, SHA512_CTX *c);
unsigned char *SHA384(const unsigned char *d, size_t n, unsigned char *md);
int SHA512_Init(SHA512_CTX *c);
int SHA512_Update(SHA512_CTX *c, const void *data, size_t len);
int SHA512_Final(unsigned char *md, SHA512_CTX *c);
unsigned char *SHA512(const unsigned char *d, size_t n, unsigned char *md);
void SHA512_Transform(SHA512_CTX *c, const unsigned char *data);
# endif

#ifdef  __cplusplus
}
#endif

#endif
openssl/krb5_asn.h000064400000017745151733316570010135 0ustar00/* krb5_asn.h */
/*
 * Written by Vern Staats <staatsvr@asc.hpc.mil> for the OpenSSL project, **
 * using ocsp/{*.h,*asn*.c} as a starting point
 */

/* ====================================================================
 * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#ifndef HEADER_KRB5_ASN_H
# define HEADER_KRB5_ASN_H

/*
 * #include <krb5.h>
 */
# include <openssl/safestack.h>

#ifdef  __cplusplus
extern "C" {
#endif

/*
 * ASN.1 from Kerberos RFC 1510
 */

/*-     EncryptedData ::=   SEQUENCE {
 *              etype[0]                      INTEGER, -- EncryptionType
 *              kvno[1]                       INTEGER OPTIONAL,
 *              cipher[2]                     OCTET STRING -- ciphertext
 *      }
 */
typedef struct krb5_encdata_st {
    ASN1_INTEGER *etype;
    ASN1_INTEGER *kvno;
    ASN1_OCTET_STRING *cipher;
} KRB5_ENCDATA;

DECLARE_STACK_OF(KRB5_ENCDATA)

/*-     PrincipalName ::=   SEQUENCE {
 *              name-type[0]                  INTEGER,
 *              name-string[1]                SEQUENCE OF GeneralString
 *      }
 */
typedef struct krb5_princname_st {
    ASN1_INTEGER *nametype;
    STACK_OF(ASN1_GENERALSTRING) *namestring;
} KRB5_PRINCNAME;

DECLARE_STACK_OF(KRB5_PRINCNAME)

/*-     Ticket ::=      [APPLICATION 1] SEQUENCE {
 *              tkt-vno[0]                    INTEGER,
 *              realm[1]                      Realm,
 *              sname[2]                      PrincipalName,
 *              enc-part[3]                   EncryptedData
 *      }
 */
typedef struct krb5_tktbody_st {
    ASN1_INTEGER *tktvno;
    ASN1_GENERALSTRING *realm;
    KRB5_PRINCNAME *sname;
    KRB5_ENCDATA *encdata;
} KRB5_TKTBODY;

typedef STACK_OF(KRB5_TKTBODY) KRB5_TICKET;
DECLARE_STACK_OF(KRB5_TKTBODY)

/*-     AP-REQ ::=      [APPLICATION 14] SEQUENCE {
 *              pvno[0]                       INTEGER,
 *              msg-type[1]                   INTEGER,
 *              ap-options[2]                 APOptions,
 *              ticket[3]                     Ticket,
 *              authenticator[4]              EncryptedData
 *      }
 *
 *      APOptions ::=   BIT STRING {
 *              reserved(0), use-session-key(1), mutual-required(2) }
 */
typedef struct krb5_ap_req_st {
    ASN1_INTEGER *pvno;
    ASN1_INTEGER *msgtype;
    ASN1_BIT_STRING *apoptions;
    KRB5_TICKET *ticket;
    KRB5_ENCDATA *authenticator;
} KRB5_APREQBODY;

typedef STACK_OF(KRB5_APREQBODY) KRB5_APREQ;
DECLARE_STACK_OF(KRB5_APREQBODY)

/*      Authenticator Stuff     */

/*-     Checksum ::=   SEQUENCE {
 *              cksumtype[0]                  INTEGER,
 *              checksum[1]                   OCTET STRING
 *      }
 */
typedef struct krb5_checksum_st {
    ASN1_INTEGER *ctype;
    ASN1_OCTET_STRING *checksum;
} KRB5_CHECKSUM;

DECLARE_STACK_OF(KRB5_CHECKSUM)

/*-     EncryptionKey ::=   SEQUENCE {
 *              keytype[0]                    INTEGER,
 *              keyvalue[1]                   OCTET STRING
 *      }
 */
typedef struct krb5_encryptionkey_st {
    ASN1_INTEGER *ktype;
    ASN1_OCTET_STRING *keyvalue;
} KRB5_ENCKEY;

DECLARE_STACK_OF(KRB5_ENCKEY)

/*-     AuthorizationData ::=   SEQUENCE OF SEQUENCE {
 *              ad-type[0]                    INTEGER,
 *              ad-data[1]                    OCTET STRING
 *      }
 */
typedef struct krb5_authorization_st {
    ASN1_INTEGER *adtype;
    ASN1_OCTET_STRING *addata;
} KRB5_AUTHDATA;

DECLARE_STACK_OF(KRB5_AUTHDATA)

/*-     -- Unencrypted authenticator
 *      Authenticator ::=    [APPLICATION 2] SEQUENCE    {
 *              authenticator-vno[0]          INTEGER,
 *              crealm[1]                     Realm,
 *              cname[2]                      PrincipalName,
 *              cksum[3]                      Checksum OPTIONAL,
 *              cusec[4]                      INTEGER,
 *              ctime[5]                      KerberosTime,
 *              subkey[6]                     EncryptionKey OPTIONAL,
 *              seq-number[7]                 INTEGER OPTIONAL,
 *              authorization-data[8]         AuthorizationData OPTIONAL
 *      }
 */
typedef struct krb5_authenticator_st {
    ASN1_INTEGER *avno;
    ASN1_GENERALSTRING *crealm;
    KRB5_PRINCNAME *cname;
    KRB5_CHECKSUM *cksum;
    ASN1_INTEGER *cusec;
    ASN1_GENERALIZEDTIME *ctime;
    KRB5_ENCKEY *subkey;
    ASN1_INTEGER *seqnum;
    KRB5_AUTHDATA *authorization;
} KRB5_AUTHENTBODY;

typedef STACK_OF(KRB5_AUTHENTBODY) KRB5_AUTHENT;
DECLARE_STACK_OF(KRB5_AUTHENTBODY)

/*-  DECLARE_ASN1_FUNCTIONS(type) = DECLARE_ASN1_FUNCTIONS_name(type, type) =
 *      type *name##_new(void);
 *      void name##_free(type *a);
 *      DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name) =
 *       DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) =
 *        type *d2i_##name(type **a, const unsigned char **in, long len);
 *        int i2d_##name(type *a, unsigned char **out);
 *        DECLARE_ASN1_ITEM(itname) = OPENSSL_EXTERN const ASN1_ITEM itname##_it
 */

DECLARE_ASN1_FUNCTIONS(KRB5_ENCDATA)
DECLARE_ASN1_FUNCTIONS(KRB5_PRINCNAME)
DECLARE_ASN1_FUNCTIONS(KRB5_TKTBODY)
DECLARE_ASN1_FUNCTIONS(KRB5_APREQBODY)
DECLARE_ASN1_FUNCTIONS(KRB5_TICKET)
DECLARE_ASN1_FUNCTIONS(KRB5_APREQ)

DECLARE_ASN1_FUNCTIONS(KRB5_CHECKSUM)
DECLARE_ASN1_FUNCTIONS(KRB5_ENCKEY)
DECLARE_ASN1_FUNCTIONS(KRB5_AUTHDATA)
DECLARE_ASN1_FUNCTIONS(KRB5_AUTHENTBODY)
DECLARE_ASN1_FUNCTIONS(KRB5_AUTHENT)

/* BEGIN ERROR CODES */
/*
 * The following lines are auto generated by the script mkerr.pl. Any changes
 * made after this point may be overwritten when the script is next run.
 */

#ifdef  __cplusplus
}
#endif
#endif
openssl/symhacks.h000064400000066251151733316570010247 0ustar00/* ====================================================================
 * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#ifndef HEADER_SYMHACKS_H
# define HEADER_SYMHACKS_H

# include <openssl/e_os2.h>

/*
 * Hacks to solve the problem with linkers incapable of handling very long
 * symbol names.  In the case of VMS, the limit is 31 characters on VMS for
 * VAX.
 */
/*
 * Note that this affects util/libeay.num and util/ssleay.num...  you may
 * change those manually, but that's not recommended, as those files are
 * controlled centrally and updated on Unix, and the central definition may
 * disagree with yours, which in turn may come with shareable library
 * incompatibilities.
 */
# ifdef OPENSSL_SYS_VMS

/* Hack a long name in crypto/ex_data.c */
#  undef CRYPTO_get_ex_data_implementation
#  define CRYPTO_get_ex_data_implementation       CRYPTO_get_ex_data_impl
#  undef CRYPTO_set_ex_data_implementation
#  define CRYPTO_set_ex_data_implementation       CRYPTO_set_ex_data_impl

/* Hack a long name in crypto/asn1/a_mbstr.c */
#  undef ASN1_STRING_set_default_mask_asc
#  define ASN1_STRING_set_default_mask_asc        ASN1_STRING_set_def_mask_asc

#  if 0                         /* No longer needed, since safestack macro
                                 * magic does the job */
/* Hack the names created with DECLARE_ASN1_SET_OF(PKCS7_SIGNER_INFO) */
#   undef i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO
#   define i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO       i2d_ASN1_SET_OF_PKCS7_SIGINF
#   undef d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO
#   define d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO       d2i_ASN1_SET_OF_PKCS7_SIGINF
#  endif

#  if 0                         /* No longer needed, since safestack macro
                                 * magic does the job */
/* Hack the names created with DECLARE_ASN1_SET_OF(PKCS7_RECIP_INFO) */
#   undef i2d_ASN1_SET_OF_PKCS7_RECIP_INFO
#   define i2d_ASN1_SET_OF_PKCS7_RECIP_INFO        i2d_ASN1_SET_OF_PKCS7_RECINF
#   undef d2i_ASN1_SET_OF_PKCS7_RECIP_INFO
#   define d2i_ASN1_SET_OF_PKCS7_RECIP_INFO        d2i_ASN1_SET_OF_PKCS7_RECINF
#  endif

#  if 0                         /* No longer needed, since safestack macro
                                 * magic does the job */
/* Hack the names created with DECLARE_ASN1_SET_OF(ACCESS_DESCRIPTION) */
#   undef i2d_ASN1_SET_OF_ACCESS_DESCRIPTION
#   define i2d_ASN1_SET_OF_ACCESS_DESCRIPTION      i2d_ASN1_SET_OF_ACC_DESC
#   undef d2i_ASN1_SET_OF_ACCESS_DESCRIPTION
#   define d2i_ASN1_SET_OF_ACCESS_DESCRIPTION      d2i_ASN1_SET_OF_ACC_DESC
#  endif

/* Hack the names created with DECLARE_PEM_rw(NETSCAPE_CERT_SEQUENCE) */
#  undef PEM_read_NETSCAPE_CERT_SEQUENCE
#  define PEM_read_NETSCAPE_CERT_SEQUENCE         PEM_read_NS_CERT_SEQ
#  undef PEM_write_NETSCAPE_CERT_SEQUENCE
#  define PEM_write_NETSCAPE_CERT_SEQUENCE        PEM_write_NS_CERT_SEQ
#  undef PEM_read_bio_NETSCAPE_CERT_SEQUENCE
#  define PEM_read_bio_NETSCAPE_CERT_SEQUENCE     PEM_read_bio_NS_CERT_SEQ
#  undef PEM_write_bio_NETSCAPE_CERT_SEQUENCE
#  define PEM_write_bio_NETSCAPE_CERT_SEQUENCE    PEM_write_bio_NS_CERT_SEQ
#  undef PEM_write_cb_bio_NETSCAPE_CERT_SEQUENCE
#  define PEM_write_cb_bio_NETSCAPE_CERT_SEQUENCE PEM_write_cb_bio_NS_CERT_SEQ

/* Hack the names created with DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO) */
#  undef PEM_read_PKCS8_PRIV_KEY_INFO
#  define PEM_read_PKCS8_PRIV_KEY_INFO            PEM_read_P8_PRIV_KEY_INFO
#  undef PEM_write_PKCS8_PRIV_KEY_INFO
#  define PEM_write_PKCS8_PRIV_KEY_INFO           PEM_write_P8_PRIV_KEY_INFO
#  undef PEM_read_bio_PKCS8_PRIV_KEY_INFO
#  define PEM_read_bio_PKCS8_PRIV_KEY_INFO        PEM_read_bio_P8_PRIV_KEY_INFO
#  undef PEM_write_bio_PKCS8_PRIV_KEY_INFO
#  define PEM_write_bio_PKCS8_PRIV_KEY_INFO       PEM_write_bio_P8_PRIV_KEY_INFO
#  undef PEM_write_cb_bio_PKCS8_PRIV_KEY_INFO
#  define PEM_write_cb_bio_PKCS8_PRIV_KEY_INFO    PEM_wrt_cb_bio_P8_PRIV_KEY_INFO

/* Hack other PEM names */
#  undef PEM_write_bio_PKCS8PrivateKey_nid
#  define PEM_write_bio_PKCS8PrivateKey_nid       PEM_write_bio_PKCS8PrivKey_nid

/* Hack some long X509 names */
#  undef X509_REVOKED_get_ext_by_critical
#  define X509_REVOKED_get_ext_by_critical        X509_REVOKED_get_ext_by_critic
#  undef X509_policy_tree_get0_user_policies
#  define X509_policy_tree_get0_user_policies     X509_pcy_tree_get0_usr_policies
#  undef X509_policy_node_get0_qualifiers
#  define X509_policy_node_get0_qualifiers        X509_pcy_node_get0_qualifiers
#  undef X509_STORE_CTX_get_explicit_policy
#  define X509_STORE_CTX_get_explicit_policy      X509_STORE_CTX_get_expl_policy
#  undef X509_STORE_CTX_get0_current_issuer
#  define X509_STORE_CTX_get0_current_issuer      X509_STORE_CTX_get0_cur_issuer

/* Hack some long CRYPTO names */
#  undef CRYPTO_set_dynlock_destroy_callback
#  define CRYPTO_set_dynlock_destroy_callback     CRYPTO_set_dynlock_destroy_cb
#  undef CRYPTO_set_dynlock_create_callback
#  define CRYPTO_set_dynlock_create_callback      CRYPTO_set_dynlock_create_cb
#  undef CRYPTO_set_dynlock_lock_callback
#  define CRYPTO_set_dynlock_lock_callback        CRYPTO_set_dynlock_lock_cb
#  undef CRYPTO_get_dynlock_lock_callback
#  define CRYPTO_get_dynlock_lock_callback        CRYPTO_get_dynlock_lock_cb
#  undef CRYPTO_get_dynlock_destroy_callback
#  define CRYPTO_get_dynlock_destroy_callback     CRYPTO_get_dynlock_destroy_cb
#  undef CRYPTO_get_dynlock_create_callback
#  define CRYPTO_get_dynlock_create_callback      CRYPTO_get_dynlock_create_cb
#  undef CRYPTO_set_locked_mem_ex_functions
#  define CRYPTO_set_locked_mem_ex_functions      CRYPTO_set_locked_mem_ex_funcs
#  undef CRYPTO_get_locked_mem_ex_functions
#  define CRYPTO_get_locked_mem_ex_functions      CRYPTO_get_locked_mem_ex_funcs

/* Hack some long SSL/TLS names */
#  undef SSL_CTX_set_default_verify_paths
#  define SSL_CTX_set_default_verify_paths        SSL_CTX_set_def_verify_paths
#  undef SSL_get_ex_data_X509_STORE_CTX_idx
#  define SSL_get_ex_data_X509_STORE_CTX_idx      SSL_get_ex_d_X509_STORE_CTX_idx
#  undef SSL_add_file_cert_subjects_to_stack
#  define SSL_add_file_cert_subjects_to_stack     SSL_add_file_cert_subjs_to_stk
#  undef SSL_add_dir_cert_subjects_to_stack
#  define SSL_add_dir_cert_subjects_to_stack      SSL_add_dir_cert_subjs_to_stk
#  undef SSL_CTX_use_certificate_chain_file
#  define SSL_CTX_use_certificate_chain_file      SSL_CTX_use_cert_chain_file
#  undef SSL_CTX_set_cert_verify_callback
#  define SSL_CTX_set_cert_verify_callback        SSL_CTX_set_cert_verify_cb
#  undef SSL_CTX_set_default_passwd_cb_userdata
#  define SSL_CTX_set_default_passwd_cb_userdata  SSL_CTX_set_def_passwd_cb_ud
#  undef SSL_COMP_get_compression_methods
#  define SSL_COMP_get_compression_methods        SSL_COMP_get_compress_methods
#  undef SSL_COMP_set0_compression_methods
#  define SSL_COMP_set0_compression_methods       SSL_COMP_set0_compress_methods
#  undef SSL_COMP_free_compression_methods
#  define SSL_COMP_free_compression_methods       SSL_COMP_free_compress_methods
#  undef ssl_add_clienthello_renegotiate_ext
#  define ssl_add_clienthello_renegotiate_ext     ssl_add_clienthello_reneg_ext
#  undef ssl_add_serverhello_renegotiate_ext
#  define ssl_add_serverhello_renegotiate_ext     ssl_add_serverhello_reneg_ext
#  undef ssl_parse_clienthello_renegotiate_ext
#  define ssl_parse_clienthello_renegotiate_ext   ssl_parse_clienthello_reneg_ext
#  undef ssl_parse_serverhello_renegotiate_ext
#  define ssl_parse_serverhello_renegotiate_ext   ssl_parse_serverhello_reneg_ext
#  undef SSL_srp_server_param_with_username
#  define SSL_srp_server_param_with_username      SSL_srp_server_param_with_un
#  undef SSL_CTX_set_srp_client_pwd_callback
#  define SSL_CTX_set_srp_client_pwd_callback     SSL_CTX_set_srp_client_pwd_cb
#  undef SSL_CTX_set_srp_verify_param_callback
#  define SSL_CTX_set_srp_verify_param_callback   SSL_CTX_set_srp_vfy_param_cb
#  undef SSL_CTX_set_srp_username_callback
#  define SSL_CTX_set_srp_username_callback       SSL_CTX_set_srp_un_cb
#  undef ssl_add_clienthello_use_srtp_ext
#  define ssl_add_clienthello_use_srtp_ext        ssl_add_clihello_use_srtp_ext
#  undef ssl_add_serverhello_use_srtp_ext
#  define ssl_add_serverhello_use_srtp_ext        ssl_add_serhello_use_srtp_ext
#  undef ssl_parse_clienthello_use_srtp_ext
#  define ssl_parse_clienthello_use_srtp_ext      ssl_parse_clihello_use_srtp_ext
#  undef ssl_parse_serverhello_use_srtp_ext
#  define ssl_parse_serverhello_use_srtp_ext      ssl_parse_serhello_use_srtp_ext
#  undef SSL_CTX_set_next_protos_advertised_cb
#  define SSL_CTX_set_next_protos_advertised_cb   SSL_CTX_set_next_protos_adv_cb
#  undef SSL_CTX_set_next_proto_select_cb
#  define SSL_CTX_set_next_proto_select_cb        SSL_CTX_set_next_proto_sel_cb

#  undef tls1_send_server_supplemental_data
#  define tls1_send_server_supplemental_data      tls1_send_server_suppl_data
#  undef tls1_send_client_supplemental_data
#  define tls1_send_client_supplemental_data      tls1_send_client_suppl_data
#  undef tls1_get_server_supplemental_data
#  define tls1_get_server_supplemental_data       tls1_get_server_suppl_data
#  undef tls1_get_client_supplemental_data
#  define tls1_get_client_supplemental_data       tls1_get_client_suppl_data

#  undef ssl3_cbc_record_digest_supported
#  define ssl3_cbc_record_digest_supported        ssl3_cbc_record_digest_support
#  undef ssl_check_clienthello_tlsext_late
#  define ssl_check_clienthello_tlsext_late       ssl_check_clihello_tlsext_late
#  undef ssl_check_clienthello_tlsext_early
#  define ssl_check_clienthello_tlsext_early      ssl_check_clihello_tlsext_early

/* Hack some RSA long names */
#  undef RSA_padding_check_PKCS1_OAEP_mgf1
#  define RSA_padding_check_PKCS1_OAEP_mgf1       RSA_pad_check_PKCS1_OAEP_mgf1

/* Hack some ENGINE long names */
#  undef ENGINE_get_default_BN_mod_exp_crt
#  define ENGINE_get_default_BN_mod_exp_crt       ENGINE_get_def_BN_mod_exp_crt
#  undef ENGINE_set_default_BN_mod_exp_crt
#  define ENGINE_set_default_BN_mod_exp_crt       ENGINE_set_def_BN_mod_exp_crt
#  undef ENGINE_set_load_privkey_function
#  define ENGINE_set_load_privkey_function        ENGINE_set_load_privkey_fn
#  undef ENGINE_get_load_privkey_function
#  define ENGINE_get_load_privkey_function        ENGINE_get_load_privkey_fn
#  undef ENGINE_unregister_pkey_asn1_meths
#  define ENGINE_unregister_pkey_asn1_meths       ENGINE_unreg_pkey_asn1_meths
#  undef ENGINE_register_all_pkey_asn1_meths
#  define ENGINE_register_all_pkey_asn1_meths     ENGINE_reg_all_pkey_asn1_meths
#  undef ENGINE_set_default_pkey_asn1_meths
#  define ENGINE_set_default_pkey_asn1_meths      ENGINE_set_def_pkey_asn1_meths
#  undef ENGINE_get_pkey_asn1_meth_engine
#  define ENGINE_get_pkey_asn1_meth_engine        ENGINE_get_pkey_asn1_meth_eng
#  undef ENGINE_set_load_ssl_client_cert_function
#  define ENGINE_set_load_ssl_client_cert_function \
                                                ENGINE_set_ld_ssl_clnt_cert_fn
#  undef ENGINE_get_ssl_client_cert_function
#  define ENGINE_get_ssl_client_cert_function     ENGINE_get_ssl_client_cert_fn

/* Hack some long OCSP names */
#  undef OCSP_REQUEST_get_ext_by_critical
#  define OCSP_REQUEST_get_ext_by_critical        OCSP_REQUEST_get_ext_by_crit
#  undef OCSP_BASICRESP_get_ext_by_critical
#  define OCSP_BASICRESP_get_ext_by_critical      OCSP_BASICRESP_get_ext_by_crit
#  undef OCSP_SINGLERESP_get_ext_by_critical
#  define OCSP_SINGLERESP_get_ext_by_critical     OCSP_SINGLERESP_get_ext_by_crit

/* Hack some long DES names */
#  undef _ossl_old_des_ede3_cfb64_encrypt
#  define _ossl_old_des_ede3_cfb64_encrypt        _ossl_odes_ede3_cfb64_encrypt
#  undef _ossl_old_des_ede3_ofb64_encrypt
#  define _ossl_old_des_ede3_ofb64_encrypt        _ossl_odes_ede3_ofb64_encrypt

/* Hack some long EVP names */
#  undef OPENSSL_add_all_algorithms_noconf
#  define OPENSSL_add_all_algorithms_noconf       OPENSSL_add_all_algo_noconf
#  undef OPENSSL_add_all_algorithms_conf
#  define OPENSSL_add_all_algorithms_conf         OPENSSL_add_all_algo_conf
#  undef EVP_PKEY_meth_set_verify_recover
#  define EVP_PKEY_meth_set_verify_recover        EVP_PKEY_meth_set_vrfy_recover
#  undef EVP_PKEY_meth_get_verify_recover
#  define EVP_PKEY_meth_get_verify_recover        EVP_PKEY_meth_get_vrfy_recover

/* Hack some long EC names */
#  undef EC_GROUP_set_point_conversion_form
#  define EC_GROUP_set_point_conversion_form      EC_GROUP_set_point_conv_form
#  undef EC_GROUP_get_point_conversion_form
#  define EC_GROUP_get_point_conversion_form      EC_GROUP_get_point_conv_form
#  undef EC_GROUP_clear_free_all_extra_data
#  define EC_GROUP_clear_free_all_extra_data      EC_GROUP_clr_free_all_xtra_data
#  undef EC_KEY_set_public_key_affine_coordinates
#  define EC_KEY_set_public_key_affine_coordinates \
                                                EC_KEY_set_pub_key_aff_coords
#  undef EC_POINT_set_Jprojective_coordinates_GFp
#  define EC_POINT_set_Jprojective_coordinates_GFp \
                                                EC_POINT_set_Jproj_coords_GFp
#  undef EC_POINT_get_Jprojective_coordinates_GFp
#  define EC_POINT_get_Jprojective_coordinates_GFp \
                                                EC_POINT_get_Jproj_coords_GFp
#  undef EC_POINT_set_affine_coordinates_GFp
#  define EC_POINT_set_affine_coordinates_GFp     EC_POINT_set_affine_coords_GFp
#  undef EC_POINT_get_affine_coordinates_GFp
#  define EC_POINT_get_affine_coordinates_GFp     EC_POINT_get_affine_coords_GFp
#  undef EC_POINT_set_compressed_coordinates_GFp
#  define EC_POINT_set_compressed_coordinates_GFp EC_POINT_set_compr_coords_GFp
#  undef EC_POINT_set_affine_coordinates_GF2m
#  define EC_POINT_set_affine_coordinates_GF2m    EC_POINT_set_affine_coords_GF2m
#  undef EC_POINT_get_affine_coordinates_GF2m
#  define EC_POINT_get_affine_coordinates_GF2m    EC_POINT_get_affine_coords_GF2m
#  undef EC_POINT_set_compressed_coordinates_GF2m
#  define EC_POINT_set_compressed_coordinates_GF2m \
                                                EC_POINT_set_compr_coords_GF2m
#  undef ec_GF2m_simple_group_clear_finish
#  define ec_GF2m_simple_group_clear_finish       ec_GF2m_simple_grp_clr_finish
#  undef ec_GF2m_simple_group_check_discriminant
#  define ec_GF2m_simple_group_check_discriminant ec_GF2m_simple_grp_chk_discrim
#  undef ec_GF2m_simple_point_clear_finish
#  define ec_GF2m_simple_point_clear_finish       ec_GF2m_simple_pt_clr_finish
#  undef ec_GF2m_simple_point_set_to_infinity
#  define ec_GF2m_simple_point_set_to_infinity    ec_GF2m_simple_pt_set_to_inf
#  undef ec_GF2m_simple_points_make_affine
#  define ec_GF2m_simple_points_make_affine       ec_GF2m_simple_pts_make_affine
#  undef ec_GF2m_simple_point_set_affine_coordinates
#  define ec_GF2m_simple_point_set_affine_coordinates \
                                                ec_GF2m_smp_pt_set_af_coords
#  undef ec_GF2m_simple_point_get_affine_coordinates
#  define ec_GF2m_simple_point_get_affine_coordinates \
                                                ec_GF2m_smp_pt_get_af_coords
#  undef ec_GF2m_simple_set_compressed_coordinates
#  define ec_GF2m_simple_set_compressed_coordinates \
                                                ec_GF2m_smp_set_compr_coords
#  undef ec_GFp_simple_group_set_curve_GFp
#  define ec_GFp_simple_group_set_curve_GFp       ec_GFp_simple_grp_set_curve_GFp
#  undef ec_GFp_simple_group_get_curve_GFp
#  define ec_GFp_simple_group_get_curve_GFp       ec_GFp_simple_grp_get_curve_GFp
#  undef ec_GFp_simple_group_clear_finish
#  define ec_GFp_simple_group_clear_finish        ec_GFp_simple_grp_clear_finish
#  undef ec_GFp_simple_group_set_generator
#  define ec_GFp_simple_group_set_generator       ec_GFp_simple_grp_set_generator
#  undef ec_GFp_simple_group_get0_generator
#  define ec_GFp_simple_group_get0_generator      ec_GFp_simple_grp_gt0_generator
#  undef ec_GFp_simple_group_get_cofactor
#  define ec_GFp_simple_group_get_cofactor        ec_GFp_simple_grp_get_cofactor
#  undef ec_GFp_simple_point_clear_finish
#  define ec_GFp_simple_point_clear_finish        ec_GFp_simple_pt_clear_finish
#  undef ec_GFp_simple_point_set_to_infinity
#  define ec_GFp_simple_point_set_to_infinity     ec_GFp_simple_pt_set_to_inf
#  undef ec_GFp_simple_points_make_affine
#  define ec_GFp_simple_points_make_affine        ec_GFp_simple_pts_make_affine
#  undef ec_GFp_simple_set_Jprojective_coordinates_GFp
#  define ec_GFp_simple_set_Jprojective_coordinates_GFp \
                                                ec_GFp_smp_set_Jproj_coords_GFp
#  undef ec_GFp_simple_get_Jprojective_coordinates_GFp
#  define ec_GFp_simple_get_Jprojective_coordinates_GFp \
                                                ec_GFp_smp_get_Jproj_coords_GFp
#  undef ec_GFp_simple_point_set_affine_coordinates_GFp
#  define ec_GFp_simple_point_set_affine_coordinates_GFp \
                                                ec_GFp_smp_pt_set_af_coords_GFp
#  undef ec_GFp_simple_point_get_affine_coordinates_GFp
#  define ec_GFp_simple_point_get_affine_coordinates_GFp \
                                                ec_GFp_smp_pt_get_af_coords_GFp
#  undef ec_GFp_simple_set_compressed_coordinates_GFp
#  define ec_GFp_simple_set_compressed_coordinates_GFp \
                                                ec_GFp_smp_set_compr_coords_GFp
#  undef ec_GFp_simple_point_set_affine_coordinates
#  define ec_GFp_simple_point_set_affine_coordinates \
                                                ec_GFp_smp_pt_set_af_coords
#  undef ec_GFp_simple_point_get_affine_coordinates
#  define ec_GFp_simple_point_get_affine_coordinates \
                                                ec_GFp_smp_pt_get_af_coords
#  undef ec_GFp_simple_set_compressed_coordinates
#  define ec_GFp_simple_set_compressed_coordinates \
                                                ec_GFp_smp_set_compr_coords
#  undef ec_GFp_simple_group_check_discriminant
#  define ec_GFp_simple_group_check_discriminant  ec_GFp_simple_grp_chk_discrim

/* Hack som long STORE names */
#  undef STORE_method_set_initialise_function
#  define STORE_method_set_initialise_function    STORE_meth_set_initialise_fn
#  undef STORE_method_set_cleanup_function
#  define STORE_method_set_cleanup_function       STORE_meth_set_cleanup_fn
#  undef STORE_method_set_generate_function
#  define STORE_method_set_generate_function      STORE_meth_set_generate_fn
#  undef STORE_method_set_modify_function
#  define STORE_method_set_modify_function        STORE_meth_set_modify_fn
#  undef STORE_method_set_revoke_function
#  define STORE_method_set_revoke_function        STORE_meth_set_revoke_fn
#  undef STORE_method_set_delete_function
#  define STORE_method_set_delete_function        STORE_meth_set_delete_fn
#  undef STORE_method_set_list_start_function
#  define STORE_method_set_list_start_function    STORE_meth_set_list_start_fn
#  undef STORE_method_set_list_next_function
#  define STORE_method_set_list_next_function     STORE_meth_set_list_next_fn
#  undef STORE_method_set_list_end_function
#  define STORE_method_set_list_end_function      STORE_meth_set_list_end_fn
#  undef STORE_method_set_update_store_function
#  define STORE_method_set_update_store_function  STORE_meth_set_update_store_fn
#  undef STORE_method_set_lock_store_function
#  define STORE_method_set_lock_store_function    STORE_meth_set_lock_store_fn
#  undef STORE_method_set_unlock_store_function
#  define STORE_method_set_unlock_store_function  STORE_meth_set_unlock_store_fn
#  undef STORE_method_get_initialise_function
#  define STORE_method_get_initialise_function    STORE_meth_get_initialise_fn
#  undef STORE_method_get_cleanup_function
#  define STORE_method_get_cleanup_function       STORE_meth_get_cleanup_fn
#  undef STORE_method_get_generate_function
#  define STORE_method_get_generate_function      STORE_meth_get_generate_fn
#  undef STORE_method_get_modify_function
#  define STORE_method_get_modify_function        STORE_meth_get_modify_fn
#  undef STORE_method_get_revoke_function
#  define STORE_method_get_revoke_function        STORE_meth_get_revoke_fn
#  undef STORE_method_get_delete_function
#  define STORE_method_get_delete_function        STORE_meth_get_delete_fn
#  undef STORE_method_get_list_start_function
#  define STORE_method_get_list_start_function    STORE_meth_get_list_start_fn
#  undef STORE_method_get_list_next_function
#  define STORE_method_get_list_next_function     STORE_meth_get_list_next_fn
#  undef STORE_method_get_list_end_function
#  define STORE_method_get_list_end_function      STORE_meth_get_list_end_fn
#  undef STORE_method_get_update_store_function
#  define STORE_method_get_update_store_function  STORE_meth_get_update_store_fn
#  undef STORE_method_get_lock_store_function
#  define STORE_method_get_lock_store_function    STORE_meth_get_lock_store_fn
#  undef STORE_method_get_unlock_store_function
#  define STORE_method_get_unlock_store_function  STORE_meth_get_unlock_store_fn

/* Hack some long TS names */
#  undef TS_RESP_CTX_set_status_info_cond
#  define TS_RESP_CTX_set_status_info_cond        TS_RESP_CTX_set_stat_info_cond
#  undef TS_RESP_CTX_set_clock_precision_digits
#  define TS_RESP_CTX_set_clock_precision_digits  TS_RESP_CTX_set_clk_prec_digits
#  undef TS_CONF_set_clock_precision_digits
#  define TS_CONF_set_clock_precision_digits      TS_CONF_set_clk_prec_digits

/* Hack some long CMS names */
#  undef CMS_RecipientInfo_ktri_get0_algs
#  define CMS_RecipientInfo_ktri_get0_algs        CMS_RecipInfo_ktri_get0_algs
#  undef CMS_RecipientInfo_ktri_get0_signer_id
#  define CMS_RecipientInfo_ktri_get0_signer_id   CMS_RecipInfo_ktri_get0_sigr_id
#  undef CMS_OtherRevocationInfoFormat_it
#  define CMS_OtherRevocationInfoFormat_it        CMS_OtherRevocInfoFormat_it
#  undef CMS_KeyAgreeRecipientIdentifier_it
#  define CMS_KeyAgreeRecipientIdentifier_it      CMS_KeyAgreeRecipIdentifier_it
#  undef CMS_OriginatorIdentifierOrKey_it
#  define CMS_OriginatorIdentifierOrKey_it        CMS_OriginatorIdOrKey_it
#  undef cms_SignerIdentifier_get0_signer_id
#  define cms_SignerIdentifier_get0_signer_id     cms_SignerId_get0_signer_id
#  undef CMS_RecipientInfo_kari_get0_orig_id
#  define CMS_RecipientInfo_kari_get0_orig_id     CMS_RecipInfo_kari_get0_orig_id
#  undef CMS_RecipientInfo_kari_get0_reks
#  define CMS_RecipientInfo_kari_get0_reks        CMS_RecipInfo_kari_get0_reks
#  undef CMS_RecipientEncryptedKey_cert_cmp
#  define CMS_RecipientEncryptedKey_cert_cmp      CMS_RecipEncryptedKey_cert_cmp
#  undef CMS_RecipientInfo_kari_set0_pkey
#  define CMS_RecipientInfo_kari_set0_pkey        CMS_RecipInfo_kari_set0_pkey
#  undef CMS_RecipientEncryptedKey_get0_id
#  define CMS_RecipientEncryptedKey_get0_id       CMS_RecipEncryptedKey_get0_id
#  undef CMS_RecipientInfo_kari_orig_id_cmp
#  define CMS_RecipientInfo_kari_orig_id_cmp      CMS_RecipInfo_kari_orig_id_cmp

/* Hack some long DTLS1 names */
#  undef dtls1_retransmit_buffered_messages
#  define dtls1_retransmit_buffered_messages      dtls1_retransmit_buffered_msgs

/* Hack some long SRP names */
#  undef SRP_generate_server_master_secret
#  define SRP_generate_server_master_secret       SRP_gen_server_master_secret
#  undef SRP_generate_client_master_secret
#  define SRP_generate_client_master_secret       SRP_gen_client_master_secret

/* Hack some long UI names */
#  undef UI_method_get_prompt_constructor
#  define UI_method_get_prompt_constructor        UI_method_get_prompt_constructr
#  undef UI_method_set_prompt_constructor
#  define UI_method_set_prompt_constructor        UI_method_set_prompt_constructr

# endif                         /* defined OPENSSL_SYS_VMS */

/* Case insensitive linking causes problems.... */
# if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2)
#  undef ERR_load_CRYPTO_strings
#  define ERR_load_CRYPTO_strings                 ERR_load_CRYPTOlib_strings
#  undef OCSP_crlID_new
#  define OCSP_crlID_new                          OCSP_crlID2_new

#  undef d2i_ECPARAMETERS
#  define d2i_ECPARAMETERS                        d2i_UC_ECPARAMETERS
#  undef i2d_ECPARAMETERS
#  define i2d_ECPARAMETERS                        i2d_UC_ECPARAMETERS
#  undef d2i_ECPKPARAMETERS
#  define d2i_ECPKPARAMETERS                      d2i_UC_ECPKPARAMETERS
#  undef i2d_ECPKPARAMETERS
#  define i2d_ECPKPARAMETERS                      i2d_UC_ECPKPARAMETERS

/*
 * These functions do not seem to exist! However, I'm paranoid... Original
 * command in x509v3.h: These functions are being redefined in another
 * directory, and clash when the linker is case-insensitive, so let's hide
 * them a little, by giving them an extra 'o' at the beginning of the name...
 */
#  undef X509v3_cleanup_extensions
#  define X509v3_cleanup_extensions               oX509v3_cleanup_extensions
#  undef X509v3_add_extension
#  define X509v3_add_extension                    oX509v3_add_extension
#  undef X509v3_add_netscape_extensions
#  define X509v3_add_netscape_extensions          oX509v3_add_netscape_extensions
#  undef X509v3_add_standard_extensions
#  define X509v3_add_standard_extensions          oX509v3_add_standard_extensions

/* This one clashes with CMS_data_create */
#  undef cms_Data_create
#  define cms_Data_create                         priv_cms_Data_create

# endif

#endif                          /* ! defined HEADER_VMS_IDHACKS_H */
openssl/pkcs7.h000064400000050452151733316570007450 0ustar00/* crypto/pkcs7/pkcs7.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#ifndef HEADER_PKCS7_H
# define HEADER_PKCS7_H

# include <openssl/asn1.h>
# include <openssl/bio.h>
# include <openssl/e_os2.h>

# include <openssl/symhacks.h>
# include <openssl/ossl_typ.h>

#ifdef  __cplusplus
extern "C" {
#endif

# ifdef OPENSSL_SYS_WIN32
/* Under Win32 thes are defined in wincrypt.h */
#  undef PKCS7_ISSUER_AND_SERIAL
#  undef PKCS7_SIGNER_INFO
# endif

/*-
Encryption_ID           DES-CBC
Digest_ID               MD5
Digest_Encryption_ID    rsaEncryption
Key_Encryption_ID       rsaEncryption
*/

typedef struct pkcs7_issuer_and_serial_st {
    X509_NAME *issuer;
    ASN1_INTEGER *serial;
} PKCS7_ISSUER_AND_SERIAL;

typedef struct pkcs7_signer_info_st {
    ASN1_INTEGER *version;      /* version 1 */
    PKCS7_ISSUER_AND_SERIAL *issuer_and_serial;
    X509_ALGOR *digest_alg;
    STACK_OF(X509_ATTRIBUTE) *auth_attr; /* [ 0 ] */
    X509_ALGOR *digest_enc_alg;
    ASN1_OCTET_STRING *enc_digest;
    STACK_OF(X509_ATTRIBUTE) *unauth_attr; /* [ 1 ] */
    /* The private key to sign with */
    EVP_PKEY *pkey;
} PKCS7_SIGNER_INFO;

DECLARE_STACK_OF(PKCS7_SIGNER_INFO)
DECLARE_ASN1_SET_OF(PKCS7_SIGNER_INFO)

typedef struct pkcs7_recip_info_st {
    ASN1_INTEGER *version;      /* version 0 */
    PKCS7_ISSUER_AND_SERIAL *issuer_and_serial;
    X509_ALGOR *key_enc_algor;
    ASN1_OCTET_STRING *enc_key;
    X509 *cert;                 /* get the pub-key from this */
} PKCS7_RECIP_INFO;

DECLARE_STACK_OF(PKCS7_RECIP_INFO)
DECLARE_ASN1_SET_OF(PKCS7_RECIP_INFO)

typedef struct pkcs7_signed_st {
    ASN1_INTEGER *version;      /* version 1 */
    STACK_OF(X509_ALGOR) *md_algs; /* md used */
    STACK_OF(X509) *cert;       /* [ 0 ] */
    STACK_OF(X509_CRL) *crl;    /* [ 1 ] */
    STACK_OF(PKCS7_SIGNER_INFO) *signer_info;
    struct pkcs7_st *contents;
} PKCS7_SIGNED;
/*
 * The above structure is very very similar to PKCS7_SIGN_ENVELOPE. How about
 * merging the two
 */

typedef struct pkcs7_enc_content_st {
    ASN1_OBJECT *content_type;
    X509_ALGOR *algorithm;
    ASN1_OCTET_STRING *enc_data; /* [ 0 ] */
    const EVP_CIPHER *cipher;
} PKCS7_ENC_CONTENT;

typedef struct pkcs7_enveloped_st {
    ASN1_INTEGER *version;      /* version 0 */
    STACK_OF(PKCS7_RECIP_INFO) *recipientinfo;
    PKCS7_ENC_CONTENT *enc_data;
} PKCS7_ENVELOPE;

typedef struct pkcs7_signedandenveloped_st {
    ASN1_INTEGER *version;      /* version 1 */
    STACK_OF(X509_ALGOR) *md_algs; /* md used */
    STACK_OF(X509) *cert;       /* [ 0 ] */
    STACK_OF(X509_CRL) *crl;    /* [ 1 ] */
    STACK_OF(PKCS7_SIGNER_INFO) *signer_info;
    PKCS7_ENC_CONTENT *enc_data;
    STACK_OF(PKCS7_RECIP_INFO) *recipientinfo;
} PKCS7_SIGN_ENVELOPE;

typedef struct pkcs7_digest_st {
    ASN1_INTEGER *version;      /* version 0 */
    X509_ALGOR *md;             /* md used */
    struct pkcs7_st *contents;
    ASN1_OCTET_STRING *digest;
} PKCS7_DIGEST;

typedef struct pkcs7_encrypted_st {
    ASN1_INTEGER *version;      /* version 0 */
    PKCS7_ENC_CONTENT *enc_data;
} PKCS7_ENCRYPT;

typedef struct pkcs7_st {
    /*
     * The following is non NULL if it contains ASN1 encoding of this
     * structure
     */
    unsigned char *asn1;
    long length;
# define PKCS7_S_HEADER  0
# define PKCS7_S_BODY    1
# define PKCS7_S_TAIL    2
    int state;                  /* used during processing */
    int detached;
    ASN1_OBJECT *type;
    /* content as defined by the type */
    /*
     * all encryption/message digests are applied to the 'contents', leaving
     * out the 'type' field.
     */
    union {
        char *ptr;
        /* NID_pkcs7_data */
        ASN1_OCTET_STRING *data;
        /* NID_pkcs7_signed */
        PKCS7_SIGNED *sign;
        /* NID_pkcs7_enveloped */
        PKCS7_ENVELOPE *enveloped;
        /* NID_pkcs7_signedAndEnveloped */
        PKCS7_SIGN_ENVELOPE *signed_and_enveloped;
        /* NID_pkcs7_digest */
        PKCS7_DIGEST *digest;
        /* NID_pkcs7_encrypted */
        PKCS7_ENCRYPT *encrypted;
        /* Anything else */
        ASN1_TYPE *other;
    } d;
} PKCS7;

DECLARE_STACK_OF(PKCS7)
DECLARE_ASN1_SET_OF(PKCS7)
DECLARE_PKCS12_STACK_OF(PKCS7)

# define PKCS7_OP_SET_DETACHED_SIGNATURE 1
# define PKCS7_OP_GET_DETACHED_SIGNATURE 2

# define PKCS7_get_signed_attributes(si) ((si)->auth_attr)
# define PKCS7_get_attributes(si)        ((si)->unauth_attr)

# define PKCS7_type_is_signed(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_signed)
# define PKCS7_type_is_encrypted(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted)
# define PKCS7_type_is_enveloped(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_enveloped)
# define PKCS7_type_is_signedAndEnveloped(a) \
                (OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped)
# define PKCS7_type_is_data(a)   (OBJ_obj2nid((a)->type) == NID_pkcs7_data)
# define PKCS7_type_is_digest(a)   (OBJ_obj2nid((a)->type) == NID_pkcs7_digest)

# define PKCS7_set_detached(p,v) \
                PKCS7_ctrl(p,PKCS7_OP_SET_DETACHED_SIGNATURE,v,NULL)
# define PKCS7_get_detached(p) \
                PKCS7_ctrl(p,PKCS7_OP_GET_DETACHED_SIGNATURE,0,NULL)

# define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7))

/* S/MIME related flags */

# define PKCS7_TEXT              0x1
# define PKCS7_NOCERTS           0x2
# define PKCS7_NOSIGS            0x4
# define PKCS7_NOCHAIN           0x8
# define PKCS7_NOINTERN          0x10
# define PKCS7_NOVERIFY          0x20
# define PKCS7_DETACHED          0x40
# define PKCS7_BINARY            0x80
# define PKCS7_NOATTR            0x100
# define PKCS7_NOSMIMECAP        0x200
# define PKCS7_NOOLDMIMETYPE     0x400
# define PKCS7_CRLFEOL           0x800
# define PKCS7_STREAM            0x1000
# define PKCS7_NOCRL             0x2000
# define PKCS7_PARTIAL           0x4000
# define PKCS7_REUSE_DIGEST      0x8000

/* Flags: for compatibility with older code */

# define SMIME_TEXT      PKCS7_TEXT
# define SMIME_NOCERTS   PKCS7_NOCERTS
# define SMIME_NOSIGS    PKCS7_NOSIGS
# define SMIME_NOCHAIN   PKCS7_NOCHAIN
# define SMIME_NOINTERN  PKCS7_NOINTERN
# define SMIME_NOVERIFY  PKCS7_NOVERIFY
# define SMIME_DETACHED  PKCS7_DETACHED
# define SMIME_BINARY    PKCS7_BINARY
# define SMIME_NOATTR    PKCS7_NOATTR

DECLARE_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL)

int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data,
                                   const EVP_MD *type, unsigned char *md,
                                   unsigned int *len);
# ifndef OPENSSL_NO_FP_API
PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7);
int i2d_PKCS7_fp(FILE *fp, PKCS7 *p7);
# endif
PKCS7 *PKCS7_dup(PKCS7 *p7);
PKCS7 *d2i_PKCS7_bio(BIO *bp, PKCS7 **p7);
int i2d_PKCS7_bio(BIO *bp, PKCS7 *p7);
int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags);
int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags);

DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO)
DECLARE_ASN1_FUNCTIONS(PKCS7_RECIP_INFO)
DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNED)
DECLARE_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT)
DECLARE_ASN1_FUNCTIONS(PKCS7_ENVELOPE)
DECLARE_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE)
DECLARE_ASN1_FUNCTIONS(PKCS7_DIGEST)
DECLARE_ASN1_FUNCTIONS(PKCS7_ENCRYPT)
DECLARE_ASN1_FUNCTIONS(PKCS7)

DECLARE_ASN1_ITEM(PKCS7_ATTR_SIGN)
DECLARE_ASN1_ITEM(PKCS7_ATTR_VERIFY)

DECLARE_ASN1_NDEF_FUNCTION(PKCS7)
DECLARE_ASN1_PRINT_FUNCTION(PKCS7)

long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg);

int PKCS7_set_type(PKCS7 *p7, int type);
int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other);
int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data);
int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
                          const EVP_MD *dgst);
int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si);
int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i);
int PKCS7_add_certificate(PKCS7 *p7, X509 *x509);
int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509);
int PKCS7_content_new(PKCS7 *p7, int nid);
int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx,
                     BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si);
int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
                          X509 *x509);

BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio);
int PKCS7_dataFinal(PKCS7 *p7, BIO *bio);
BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert);

PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509,
                                       EVP_PKEY *pkey, const EVP_MD *dgst);
X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si);
int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md);
STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7);

PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509);
void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk,
                                 X509_ALGOR **pdig, X509_ALGOR **psig);
void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc);
int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri);
int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509);
int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher);
int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7);

PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx);
ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk);
int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int type,
                               void *data);
int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
                        void *value);
ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid);
ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid);
int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si,
                                STACK_OF(X509_ATTRIBUTE) *sk);
int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si,
                         STACK_OF(X509_ATTRIBUTE) *sk);

PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
                  BIO *data, int flags);

PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7,
                                         X509 *signcert, EVP_PKEY *pkey,
                                         const EVP_MD *md, int flags);

int PKCS7_final(PKCS7 *p7, BIO *data, int flags);
int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
                 BIO *indata, BIO *out, int flags);
STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs,
                                   int flags);
PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
                     int flags);
int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data,
                  int flags);

int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si,
                              STACK_OF(X509_ALGOR) *cap);
STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si);
int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg);

int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid);
int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t);
int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si,
                             const unsigned char *md, int mdlen);

int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags);
PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont);

BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7);

/* BEGIN ERROR CODES */
/*
 * The following lines are auto generated by the script mkerr.pl. Any changes
 * made after this point may be overwritten when the script is next run.
 */
void ERR_load_PKCS7_strings(void);

/* Error codes for the PKCS7 functions. */

/* Function codes. */
# define PKCS7_F_B64_READ_PKCS7                           120
# define PKCS7_F_B64_WRITE_PKCS7                          121
# define PKCS7_F_DO_PKCS7_SIGNED_ATTRIB                   136
# define PKCS7_F_I2D_PKCS7_BIO_STREAM                     140
# define PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME           135
# define PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP                118
# define PKCS7_F_PKCS7_ADD_CERTIFICATE                    100
# define PKCS7_F_PKCS7_ADD_CRL                            101
# define PKCS7_F_PKCS7_ADD_RECIPIENT_INFO                 102
# define PKCS7_F_PKCS7_ADD_SIGNATURE                      131
# define PKCS7_F_PKCS7_ADD_SIGNER                         103
# define PKCS7_F_PKCS7_BIO_ADD_DIGEST                     125
# define PKCS7_F_PKCS7_COPY_EXISTING_DIGEST               138
# define PKCS7_F_PKCS7_CTRL                               104
# define PKCS7_F_PKCS7_DATADECODE                         112
# define PKCS7_F_PKCS7_DATAFINAL                          128
# define PKCS7_F_PKCS7_DATAINIT                           105
# define PKCS7_F_PKCS7_DATASIGN                           106
# define PKCS7_F_PKCS7_DATAVERIFY                         107
# define PKCS7_F_PKCS7_DECRYPT                            114
# define PKCS7_F_PKCS7_DECRYPT_RINFO                      133
# define PKCS7_F_PKCS7_ENCODE_RINFO                       132
# define PKCS7_F_PKCS7_ENCRYPT                            115
# define PKCS7_F_PKCS7_FINAL                              134
# define PKCS7_F_PKCS7_FIND_DIGEST                        127
# define PKCS7_F_PKCS7_GET0_SIGNERS                       124
# define PKCS7_F_PKCS7_RECIP_INFO_SET                     130
# define PKCS7_F_PKCS7_SET_CIPHER                         108
# define PKCS7_F_PKCS7_SET_CONTENT                        109
# define PKCS7_F_PKCS7_SET_DIGEST                         126
# define PKCS7_F_PKCS7_SET_TYPE                           110
# define PKCS7_F_PKCS7_SIGN                               116
# define PKCS7_F_PKCS7_SIGNATUREVERIFY                    113
# define PKCS7_F_PKCS7_SIGNER_INFO_SET                    129
# define PKCS7_F_PKCS7_SIGNER_INFO_SIGN                   139
# define PKCS7_F_PKCS7_SIGN_ADD_SIGNER                    137
# define PKCS7_F_PKCS7_SIMPLE_SMIMECAP                    119
# define PKCS7_F_PKCS7_VERIFY                             117
# define PKCS7_F_SMIME_READ_PKCS7                         122
# define PKCS7_F_SMIME_TEXT                               123

/* Reason codes. */
# define PKCS7_R_CERTIFICATE_VERIFY_ERROR                 117
# define PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER          144
# define PKCS7_R_CIPHER_NOT_INITIALIZED                   116
# define PKCS7_R_CONTENT_AND_DATA_PRESENT                 118
# define PKCS7_R_CTRL_ERROR                               152
# define PKCS7_R_DECODE_ERROR                             130
# define PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH            100
# define PKCS7_R_DECRYPT_ERROR                            119
# define PKCS7_R_DIGEST_FAILURE                           101
# define PKCS7_R_ENCRYPTION_CTRL_FAILURE                  149
# define PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 150
# define PKCS7_R_ERROR_ADDING_RECIPIENT                   120
# define PKCS7_R_ERROR_SETTING_CIPHER                     121
# define PKCS7_R_INVALID_MIME_TYPE                        131
# define PKCS7_R_INVALID_NULL_POINTER                     143
# define PKCS7_R_INVALID_SIGNED_DATA_TYPE                 155
# define PKCS7_R_MIME_NO_CONTENT_TYPE                     132
# define PKCS7_R_MIME_PARSE_ERROR                         133
# define PKCS7_R_MIME_SIG_PARSE_ERROR                     134
# define PKCS7_R_MISSING_CERIPEND_INFO                    103
# define PKCS7_R_NO_CONTENT                               122
# define PKCS7_R_NO_CONTENT_TYPE                          135
# define PKCS7_R_NO_DEFAULT_DIGEST                        151
# define PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND            154
# define PKCS7_R_NO_MULTIPART_BODY_FAILURE                136
# define PKCS7_R_NO_MULTIPART_BOUNDARY                    137
# define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE         115
# define PKCS7_R_NO_RECIPIENT_MATCHES_KEY                 146
# define PKCS7_R_NO_SIGNATURES_ON_DATA                    123
# define PKCS7_R_NO_SIGNERS                               142
# define PKCS7_R_NO_SIG_CONTENT_TYPE                      138
# define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE     104
# define PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR                124
# define PKCS7_R_PKCS7_ADD_SIGNER_ERROR                   153
# define PKCS7_R_PKCS7_DATAFINAL                          126
# define PKCS7_R_PKCS7_DATAFINAL_ERROR                    125
# define PKCS7_R_PKCS7_DATASIGN                           145
# define PKCS7_R_PKCS7_PARSE_ERROR                        139
# define PKCS7_R_PKCS7_SIG_PARSE_ERROR                    140
# define PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE   127
# define PKCS7_R_SIGNATURE_FAILURE                        105
# define PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND             128
# define PKCS7_R_SIGNING_CTRL_FAILURE                     147
# define PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE  148
# define PKCS7_R_SIG_INVALID_MIME_TYPE                    141
# define PKCS7_R_SMIME_TEXT_ERROR                         129
# define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE               106
# define PKCS7_R_UNABLE_TO_FIND_MEM_BIO                   107
# define PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST            108
# define PKCS7_R_UNKNOWN_DIGEST_TYPE                      109
# define PKCS7_R_UNKNOWN_OPERATION                        110
# define PKCS7_R_UNSUPPORTED_CIPHER_TYPE                  111
# define PKCS7_R_UNSUPPORTED_CONTENT_TYPE                 112
# define PKCS7_R_WRONG_CONTENT_TYPE                       113
# define PKCS7_R_WRONG_PKCS7_TYPE                         114

#ifdef  __cplusplus
}
#endif
#endif
openssl/ssl2.h000064400000027421151733316600007276 0ustar00/* ssl/ssl2.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#ifndef HEADER_SSL2_H
# define HEADER_SSL2_H

#ifdef  __cplusplus
extern "C" {
#endif

/* Protocol Version Codes */
# define SSL2_VERSION            0x0002
# define SSL2_VERSION_MAJOR      0x00
# define SSL2_VERSION_MINOR      0x02
/* #define SSL2_CLIENT_VERSION  0x0002 */
/* #define SSL2_SERVER_VERSION  0x0002 */

/* Protocol Message Codes */
# define SSL2_MT_ERROR                   0
# define SSL2_MT_CLIENT_HELLO            1
# define SSL2_MT_CLIENT_MASTER_KEY       2
# define SSL2_MT_CLIENT_FINISHED         3
# define SSL2_MT_SERVER_HELLO            4
# define SSL2_MT_SERVER_VERIFY           5
# define SSL2_MT_SERVER_FINISHED         6
# define SSL2_MT_REQUEST_CERTIFICATE     7
# define SSL2_MT_CLIENT_CERTIFICATE      8

/* Error Message Codes */
# define SSL2_PE_UNDEFINED_ERROR         0x0000
# define SSL2_PE_NO_CIPHER               0x0001
# define SSL2_PE_NO_CERTIFICATE          0x0002
# define SSL2_PE_BAD_CERTIFICATE         0x0004
# define SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE 0x0006

/* Cipher Kind Values */
# define SSL2_CK_NULL_WITH_MD5                   0x02000000/* v3 */
# define SSL2_CK_RC4_128_WITH_MD5                0x02010080
# define SSL2_CK_RC4_128_EXPORT40_WITH_MD5       0x02020080
# define SSL2_CK_RC2_128_CBC_WITH_MD5            0x02030080
# define SSL2_CK_RC2_128_CBC_EXPORT40_WITH_MD5   0x02040080
# define SSL2_CK_IDEA_128_CBC_WITH_MD5           0x02050080
# define SSL2_CK_DES_64_CBC_WITH_MD5             0x02060040
# define SSL2_CK_DES_64_CBC_WITH_SHA             0x02060140/* v3 */
# define SSL2_CK_DES_192_EDE3_CBC_WITH_MD5       0x020700c0
# define SSL2_CK_DES_192_EDE3_CBC_WITH_SHA       0x020701c0/* v3 */
# define SSL2_CK_RC4_64_WITH_MD5                 0x02080080/* MS hack */

# define SSL2_CK_DES_64_CFB64_WITH_MD5_1         0x02ff0800/* SSLeay */
# define SSL2_CK_NULL                            0x02ff0810/* SSLeay */

# define SSL2_TXT_DES_64_CFB64_WITH_MD5_1        "DES-CFB-M1"
# define SSL2_TXT_NULL_WITH_MD5                  "NULL-MD5"
# define SSL2_TXT_RC4_128_WITH_MD5               "RC4-MD5"
# define SSL2_TXT_RC4_128_EXPORT40_WITH_MD5      "EXP-RC4-MD5"
# define SSL2_TXT_RC2_128_CBC_WITH_MD5           "RC2-CBC-MD5"
# define SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5  "EXP-RC2-CBC-MD5"
# define SSL2_TXT_IDEA_128_CBC_WITH_MD5          "IDEA-CBC-MD5"
# define SSL2_TXT_DES_64_CBC_WITH_MD5            "DES-CBC-MD5"
# define SSL2_TXT_DES_64_CBC_WITH_SHA            "DES-CBC-SHA"
# define SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5      "DES-CBC3-MD5"
# define SSL2_TXT_DES_192_EDE3_CBC_WITH_SHA      "DES-CBC3-SHA"
# define SSL2_TXT_RC4_64_WITH_MD5                "RC4-64-MD5"

# define SSL2_TXT_NULL                           "NULL"

/* Flags for the SSL_CIPHER.algorithm2 field */
# define SSL2_CF_5_BYTE_ENC                      0x01
# define SSL2_CF_8_BYTE_ENC                      0x02

/* Certificate Type Codes */
# define SSL2_CT_X509_CERTIFICATE                0x01

/* Authentication Type Code */
# define SSL2_AT_MD5_WITH_RSA_ENCRYPTION         0x01

# define SSL2_MAX_SSL_SESSION_ID_LENGTH          32

/* Upper/Lower Bounds */
# define SSL2_MAX_MASTER_KEY_LENGTH_IN_BITS      256
# ifdef OPENSSL_SYS_MPE
#  define SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER    29998u
# else
#  define SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER    32767u
                                                       /* 2^15-1 */
# endif
# define SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER    16383/* 2^14-1 */

# define SSL2_CHALLENGE_LENGTH   16
/*
 * #define SSL2_CHALLENGE_LENGTH 32
 */
# define SSL2_MIN_CHALLENGE_LENGTH       16
# define SSL2_MAX_CHALLENGE_LENGTH       32
# define SSL2_CONNECTION_ID_LENGTH       16
# define SSL2_MAX_CONNECTION_ID_LENGTH   16
# define SSL2_SSL_SESSION_ID_LENGTH      16
# define SSL2_MAX_CERT_CHALLENGE_LENGTH  32
# define SSL2_MIN_CERT_CHALLENGE_LENGTH  16
# define SSL2_MAX_KEY_MATERIAL_LENGTH    24

# ifndef HEADER_SSL_LOCL_H
#  define  CERT           char
# endif

# ifndef OPENSSL_NO_SSL_INTERN

typedef struct ssl2_state_st {
    int three_byte_header;
    int clear_text;             /* clear text */
    int escape;                 /* not used in SSLv2 */
    int ssl2_rollback;          /* used if SSLv23 rolled back to SSLv2 */
    /*
     * non-blocking io info, used to make sure the same args were passwd
     */
    unsigned int wnum;          /* number of bytes sent so far */
    int wpend_tot;
    const unsigned char *wpend_buf;
    int wpend_off;              /* offset to data to write */
    int wpend_len;              /* number of bytes passwd to write */
    int wpend_ret;              /* number of bytes to return to caller */
    /* buffer raw data */
    int rbuf_left;
    int rbuf_offs;
    unsigned char *rbuf;
    unsigned char *wbuf;
    unsigned char *write_ptr;   /* used to point to the start due to 2/3 byte
                                 * header. */
    unsigned int padding;
    unsigned int rlength;       /* passed to ssl2_enc */
    int ract_data_length;       /* Set when things are encrypted. */
    unsigned int wlength;       /* passed to ssl2_enc */
    int wact_data_length;       /* Set when things are decrypted. */
    unsigned char *ract_data;
    unsigned char *wact_data;
    unsigned char *mac_data;
    unsigned char *read_key;
    unsigned char *write_key;
    /* Stuff specifically to do with this SSL session */
    unsigned int challenge_length;
    unsigned char challenge[SSL2_MAX_CHALLENGE_LENGTH];
    unsigned int conn_id_length;
    unsigned char conn_id[SSL2_MAX_CONNECTION_ID_LENGTH];
    unsigned int key_material_length;
    unsigned char key_material[SSL2_MAX_KEY_MATERIAL_LENGTH * 2];
    unsigned long read_sequence;
    unsigned long write_sequence;
    struct {
        unsigned int conn_id_length;
        unsigned int cert_type;
        unsigned int cert_length;
        unsigned int csl;
        unsigned int clear;
        unsigned int enc;
        unsigned char ccl[SSL2_MAX_CERT_CHALLENGE_LENGTH];
        unsigned int cipher_spec_length;
        unsigned int session_id_length;
        unsigned int clen;
        unsigned int rlen;
    } tmp;
} SSL2_STATE;

# endif

/* SSLv2 */
/* client */
# define SSL2_ST_SEND_CLIENT_HELLO_A             (0x10|SSL_ST_CONNECT)
# define SSL2_ST_SEND_CLIENT_HELLO_B             (0x11|SSL_ST_CONNECT)
# define SSL2_ST_GET_SERVER_HELLO_A              (0x20|SSL_ST_CONNECT)
# define SSL2_ST_GET_SERVER_HELLO_B              (0x21|SSL_ST_CONNECT)
# define SSL2_ST_SEND_CLIENT_MASTER_KEY_A        (0x30|SSL_ST_CONNECT)
# define SSL2_ST_SEND_CLIENT_MASTER_KEY_B        (0x31|SSL_ST_CONNECT)
# define SSL2_ST_SEND_CLIENT_FINISHED_A          (0x40|SSL_ST_CONNECT)
# define SSL2_ST_SEND_CLIENT_FINISHED_B          (0x41|SSL_ST_CONNECT)
# define SSL2_ST_SEND_CLIENT_CERTIFICATE_A       (0x50|SSL_ST_CONNECT)
# define SSL2_ST_SEND_CLIENT_CERTIFICATE_B       (0x51|SSL_ST_CONNECT)
# define SSL2_ST_SEND_CLIENT_CERTIFICATE_C       (0x52|SSL_ST_CONNECT)
# define SSL2_ST_SEND_CLIENT_CERTIFICATE_D       (0x53|SSL_ST_CONNECT)
# define SSL2_ST_GET_SERVER_VERIFY_A             (0x60|SSL_ST_CONNECT)
# define SSL2_ST_GET_SERVER_VERIFY_B             (0x61|SSL_ST_CONNECT)
# define SSL2_ST_GET_SERVER_FINISHED_A           (0x70|SSL_ST_CONNECT)
# define SSL2_ST_GET_SERVER_FINISHED_B           (0x71|SSL_ST_CONNECT)
# define SSL2_ST_CLIENT_START_ENCRYPTION         (0x80|SSL_ST_CONNECT)
# define SSL2_ST_X509_GET_CLIENT_CERTIFICATE     (0x90|SSL_ST_CONNECT)
/* server */
# define SSL2_ST_GET_CLIENT_HELLO_A              (0x10|SSL_ST_ACCEPT)
# define SSL2_ST_GET_CLIENT_HELLO_B              (0x11|SSL_ST_ACCEPT)
# define SSL2_ST_GET_CLIENT_HELLO_C              (0x12|SSL_ST_ACCEPT)
# define SSL2_ST_SEND_SERVER_HELLO_A             (0x20|SSL_ST_ACCEPT)
# define SSL2_ST_SEND_SERVER_HELLO_B             (0x21|SSL_ST_ACCEPT)
# define SSL2_ST_GET_CLIENT_MASTER_KEY_A         (0x30|SSL_ST_ACCEPT)
# define SSL2_ST_GET_CLIENT_MASTER_KEY_B         (0x31|SSL_ST_ACCEPT)
# define SSL2_ST_SEND_SERVER_VERIFY_A            (0x40|SSL_ST_ACCEPT)
# define SSL2_ST_SEND_SERVER_VERIFY_B            (0x41|SSL_ST_ACCEPT)
# define SSL2_ST_SEND_SERVER_VERIFY_C            (0x42|SSL_ST_ACCEPT)
# define SSL2_ST_GET_CLIENT_FINISHED_A           (0x50|SSL_ST_ACCEPT)
# define SSL2_ST_GET_CLIENT_FINISHED_B           (0x51|SSL_ST_ACCEPT)
# define SSL2_ST_SEND_SERVER_FINISHED_A          (0x60|SSL_ST_ACCEPT)
# define SSL2_ST_SEND_SERVER_FINISHED_B          (0x61|SSL_ST_ACCEPT)
# define SSL2_ST_SEND_REQUEST_CERTIFICATE_A      (0x70|SSL_ST_ACCEPT)
# define SSL2_ST_SEND_REQUEST_CERTIFICATE_B      (0x71|SSL_ST_ACCEPT)
# define SSL2_ST_SEND_REQUEST_CERTIFICATE_C      (0x72|SSL_ST_ACCEPT)
# define SSL2_ST_SEND_REQUEST_CERTIFICATE_D      (0x73|SSL_ST_ACCEPT)
# define SSL2_ST_SERVER_START_ENCRYPTION         (0x80|SSL_ST_ACCEPT)
# define SSL2_ST_X509_GET_SERVER_CERTIFICATE     (0x90|SSL_ST_ACCEPT)

#ifdef  __cplusplus
}
#endif
#endif
openssl/opensslv.h000064400000007546151733316600010272 0ustar00#ifndef HEADER_OPENSSLV_H
# define HEADER_OPENSSLV_H

#ifdef  __cplusplus
extern "C" {
#endif

/*-
 * Numeric release version identifier:
 * MNNFFPPS: major minor fix patch status
 * The status nibble has one of the values 0 for development, 1 to e for betas
 * 1 to 14, and f for release.  The patch level is exactly that.
 * For example:
 * 0.9.3-dev      0x00903000
 * 0.9.3-beta1    0x00903001
 * 0.9.3-beta2-dev 0x00903002
 * 0.9.3-beta2    0x00903002 (same as ...beta2-dev)
 * 0.9.3          0x0090300f
 * 0.9.3a         0x0090301f
 * 0.9.4          0x0090400f
 * 1.2.3z         0x102031af
 *
 * For continuity reasons (because 0.9.5 is already out, and is coded
 * 0x00905100), between 0.9.5 and 0.9.6 the coding of the patch level
 * part is slightly different, by setting the highest bit.  This means
 * that 0.9.5a looks like this: 0x0090581f.  At 0.9.6, we can start
 * with 0x0090600S...
 *
 * (Prior to 0.9.3-dev a different scheme was used: 0.9.2b is 0x0922.)
 * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
 *  major minor fix final patch/beta)
 */
# define OPENSSL_VERSION_NUMBER  0x1000215fL
# ifdef OPENSSL_FIPS
#  define OPENSSL_VERSION_TEXT    "OpenSSL 1.0.2u-fips  20 Dec 2019"
# else
#  define OPENSSL_VERSION_TEXT    "OpenSSL 1.0.2u  20 Dec 2019"
# endif
# define OPENSSL_VERSION_PTEXT   " part of " OPENSSL_VERSION_TEXT

/*-
 * The macros below are to be used for shared library (.so, .dll, ...)
 * versioning.  That kind of versioning works a bit differently between
 * operating systems.  The most usual scheme is to set a major and a minor
 * number, and have the runtime loader check that the major number is equal
 * to what it was at application link time, while the minor number has to
 * be greater or equal to what it was at application link time.  With this
 * scheme, the version number is usually part of the file name, like this:
 *
 *      libcrypto.so.0.9
 *
 * Some unixen also make a softlink with the major verson number only:
 *
 *      libcrypto.so.0
 *
 * On Tru64 and IRIX 6.x it works a little bit differently.  There, the
 * shared library version is stored in the file, and is actually a series
 * of versions, separated by colons.  The rightmost version present in the
 * library when linking an application is stored in the application to be
 * matched at run time.  When the application is run, a check is done to
 * see if the library version stored in the application matches any of the
 * versions in the version string of the library itself.
 * This version string can be constructed in any way, depending on what
 * kind of matching is desired.  However, to implement the same scheme as
 * the one used in the other unixen, all compatible versions, from lowest
 * to highest, should be part of the string.  Consecutive builds would
 * give the following versions strings:
 *
 *      3.0
 *      3.0:3.1
 *      3.0:3.1:3.2
 *      4.0
 *      4.0:4.1
 *
 * Notice how version 4 is completely incompatible with version, and
 * therefore give the breach you can see.
 *
 * There may be other schemes as well that I haven't yet discovered.
 *
 * So, here's the way it works here: first of all, the library version
 * number doesn't need at all to match the overall OpenSSL version.
 * However, it's nice and more understandable if it actually does.
 * The current library version is stored in the macro SHLIB_VERSION_NUMBER,
 * which is just a piece of text in the format "M.m.e" (Major, minor, edit).
 * For the sake of Tru64, IRIX, and any other OS that behaves in similar ways,
 * we need to keep a history of version numbers, which is done in the
 * macro SHLIB_VERSION_HISTORY.  The numbers are separated by colons and
 * should only keep the versions that are binary compatible with the current.
 */
# define SHLIB_VERSION_HISTORY ""
# define SHLIB_VERSION_NUMBER "1.0.2u"


#ifdef  __cplusplus
}
#endif
#endif                          /* HEADER_OPENSSLV_H */
openssl/des_old.h000064400000051756151733316600010034 0ustar00/* crypto/des/des_old.h */

/*-
 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
 *
 * The function names in here are deprecated and are only present to
 * provide an interface compatible with openssl 0.9.6 and older as
 * well as libdes.  OpenSSL now provides functions where "des_" has
 * been replaced with "DES_" in the names, to make it possible to
 * make incompatible changes that are needed for C type security and
 * other stuff.
 *
 * This include files has two compatibility modes:
 *
 *   - If OPENSSL_DES_LIBDES_COMPATIBILITY is defined, you get an API
 *     that is compatible with libdes and SSLeay.
 *   - If OPENSSL_DES_LIBDES_COMPATIBILITY isn't defined, you get an
 *     API that is compatible with OpenSSL 0.9.5x to 0.9.6x.
 *
 * Note that these modes break earlier snapshots of OpenSSL, where
 * libdes compatibility was the only available mode or (later on) the
 * prefered compatibility mode.  However, after much consideration
 * (and more or less violent discussions with external parties), it
 * was concluded that OpenSSL should be compatible with earlier versions
 * of itself before anything else.  Also, in all honesty, libdes is
 * an old beast that shouldn't really be used any more.
 *
 * Please consider starting to use the DES_ functions rather than the
 * des_ ones.  The des_ functions will disappear completely before
 * OpenSSL 1.0!
 *
 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
 */

/*
 * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project
 * 2001.
 */
/* ====================================================================
 * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#ifndef HEADER_DES_H
# define HEADER_DES_H

# include <openssl/e_os2.h>     /* OPENSSL_EXTERN, OPENSSL_NO_DES, DES_LONG */

# ifdef OPENSSL_NO_DES
#  error DES is disabled.
# endif

# ifndef HEADER_NEW_DES_H
#  error You must include des.h, not des_old.h directly.
# endif

# ifdef _KERBEROS_DES_H
#  error <openssl/des_old.h> replaces <kerberos/des.h>.
# endif

# include <openssl/symhacks.h>

# ifdef OPENSSL_BUILD_SHLIBCRYPTO
#  undef OPENSSL_EXTERN
#  define OPENSSL_EXTERN OPENSSL_EXPORT
# endif

#ifdef  __cplusplus
extern "C" {
#endif

# ifdef _
#  undef _
# endif

typedef unsigned char _ossl_old_des_cblock[8];
typedef struct _ossl_old_des_ks_struct {
    union {
        _ossl_old_des_cblock _;
        /*
         * make sure things are correct size on machines with 8 byte longs
         */
        DES_LONG pad[2];
    } ks;
} _ossl_old_des_key_schedule[16];

# ifndef OPENSSL_DES_LIBDES_COMPATIBILITY
#  define des_cblock DES_cblock
#  define const_des_cblock const_DES_cblock
#  define des_key_schedule DES_key_schedule
#  define des_ecb3_encrypt(i,o,k1,k2,k3,e)\
        DES_ecb3_encrypt((i),(o),&(k1),&(k2),&(k3),(e))
#  define des_ede3_cbc_encrypt(i,o,l,k1,k2,k3,iv,e)\
        DES_ede3_cbc_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv),(e))
#  define des_ede3_cbcm_encrypt(i,o,l,k1,k2,k3,iv1,iv2,e)\
        DES_ede3_cbcm_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv1),(iv2),(e))
#  define des_ede3_cfb64_encrypt(i,o,l,k1,k2,k3,iv,n,e)\
        DES_ede3_cfb64_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv),(n),(e))
#  define des_ede3_ofb64_encrypt(i,o,l,k1,k2,k3,iv,n)\
        DES_ede3_ofb64_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv),(n))
#  define des_options()\
        DES_options()
#  define des_cbc_cksum(i,o,l,k,iv)\
        DES_cbc_cksum((i),(o),(l),&(k),(iv))
#  define des_cbc_encrypt(i,o,l,k,iv,e)\
        DES_cbc_encrypt((i),(o),(l),&(k),(iv),(e))
#  define des_ncbc_encrypt(i,o,l,k,iv,e)\
        DES_ncbc_encrypt((i),(o),(l),&(k),(iv),(e))
#  define des_xcbc_encrypt(i,o,l,k,iv,inw,outw,e)\
        DES_xcbc_encrypt((i),(o),(l),&(k),(iv),(inw),(outw),(e))
#  define des_cfb_encrypt(i,o,n,l,k,iv,e)\
        DES_cfb_encrypt((i),(o),(n),(l),&(k),(iv),(e))
#  define des_ecb_encrypt(i,o,k,e)\
        DES_ecb_encrypt((i),(o),&(k),(e))
#  define des_encrypt1(d,k,e)\
        DES_encrypt1((d),&(k),(e))
#  define des_encrypt2(d,k,e)\
        DES_encrypt2((d),&(k),(e))
#  define des_encrypt3(d,k1,k2,k3)\
        DES_encrypt3((d),&(k1),&(k2),&(k3))
#  define des_decrypt3(d,k1,k2,k3)\
        DES_decrypt3((d),&(k1),&(k2),&(k3))
#  define des_xwhite_in2out(k,i,o)\
        DES_xwhite_in2out((k),(i),(o))
#  define des_enc_read(f,b,l,k,iv)\
        DES_enc_read((f),(b),(l),&(k),(iv))
#  define des_enc_write(f,b,l,k,iv)\
        DES_enc_write((f),(b),(l),&(k),(iv))
#  define des_fcrypt(b,s,r)\
        DES_fcrypt((b),(s),(r))
#  if 0
#   define des_crypt(b,s)\
        DES_crypt((b),(s))
#   if !defined(PERL5) && !defined(__FreeBSD__) && !defined(NeXT) && !defined(__OpenBSD__)
#    define crypt(b,s)\
        DES_crypt((b),(s))
#   endif
#  endif
#  define des_ofb_encrypt(i,o,n,l,k,iv)\
        DES_ofb_encrypt((i),(o),(n),(l),&(k),(iv))
#  define des_pcbc_encrypt(i,o,l,k,iv,e)\
        DES_pcbc_encrypt((i),(o),(l),&(k),(iv),(e))
#  define des_quad_cksum(i,o,l,c,s)\
        DES_quad_cksum((i),(o),(l),(c),(s))
#  define des_random_seed(k)\
        _ossl_096_des_random_seed((k))
#  define des_random_key(r)\
        DES_random_key((r))
#  define des_read_password(k,p,v) \
        DES_read_password((k),(p),(v))
#  define des_read_2passwords(k1,k2,p,v) \
        DES_read_2passwords((k1),(k2),(p),(v))
#  define des_set_odd_parity(k)\
        DES_set_odd_parity((k))
#  define des_check_key_parity(k)\
        DES_check_key_parity((k))
#  define des_is_weak_key(k)\
        DES_is_weak_key((k))
#  define des_set_key(k,ks)\
        DES_set_key((k),&(ks))
#  define des_key_sched(k,ks)\
        DES_key_sched((k),&(ks))
#  define des_set_key_checked(k,ks)\
        DES_set_key_checked((k),&(ks))
#  define des_set_key_unchecked(k,ks)\
        DES_set_key_unchecked((k),&(ks))
#  define des_string_to_key(s,k)\
        DES_string_to_key((s),(k))
#  define des_string_to_2keys(s,k1,k2)\
        DES_string_to_2keys((s),(k1),(k2))
#  define des_cfb64_encrypt(i,o,l,ks,iv,n,e)\
        DES_cfb64_encrypt((i),(o),(l),&(ks),(iv),(n),(e))
#  define des_ofb64_encrypt(i,o,l,ks,iv,n)\
        DES_ofb64_encrypt((i),(o),(l),&(ks),(iv),(n))

#  define des_ecb2_encrypt(i,o,k1,k2,e) \
        des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))

#  define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
        des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))

#  define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
        des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))

#  define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
        des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))

#  define des_check_key DES_check_key
#  define des_rw_mode DES_rw_mode
# else                          /* libdes compatibility */
/*
 * Map all symbol names to _ossl_old_des_* form, so we avoid all clashes with
 * libdes
 */
#  define des_cblock _ossl_old_des_cblock
#  define des_key_schedule _ossl_old_des_key_schedule
#  define des_ecb3_encrypt(i,o,k1,k2,k3,e)\
        _ossl_old_des_ecb3_encrypt((i),(o),(k1),(k2),(k3),(e))
#  define des_ede3_cbc_encrypt(i,o,l,k1,k2,k3,iv,e)\
        _ossl_old_des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k3),(iv),(e))
#  define des_ede3_cfb64_encrypt(i,o,l,k1,k2,k3,iv,n,e)\
        _ossl_old_des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k3),(iv),(n),(e))
#  define des_ede3_ofb64_encrypt(i,o,l,k1,k2,k3,iv,n)\
        _ossl_old_des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k3),(iv),(n))
#  define des_options()\
        _ossl_old_des_options()
#  define des_cbc_cksum(i,o,l,k,iv)\
        _ossl_old_des_cbc_cksum((i),(o),(l),(k),(iv))
#  define des_cbc_encrypt(i,o,l,k,iv,e)\
        _ossl_old_des_cbc_encrypt((i),(o),(l),(k),(iv),(e))
#  define des_ncbc_encrypt(i,o,l,k,iv,e)\
        _ossl_old_des_ncbc_encrypt((i),(o),(l),(k),(iv),(e))
#  define des_xcbc_encrypt(i,o,l,k,iv,inw,outw,e)\
        _ossl_old_des_xcbc_encrypt((i),(o),(l),(k),(iv),(inw),(outw),(e))
#  define des_cfb_encrypt(i,o,n,l,k,iv,e)\
        _ossl_old_des_cfb_encrypt((i),(o),(n),(l),(k),(iv),(e))
#  define des_ecb_encrypt(i,o,k,e)\
        _ossl_old_des_ecb_encrypt((i),(o),(k),(e))
#  define des_encrypt(d,k,e)\
        _ossl_old_des_encrypt((d),(k),(e))
#  define des_encrypt2(d,k,e)\
        _ossl_old_des_encrypt2((d),(k),(e))
#  define des_encrypt3(d,k1,k2,k3)\
        _ossl_old_des_encrypt3((d),(k1),(k2),(k3))
#  define des_decrypt3(d,k1,k2,k3)\
        _ossl_old_des_decrypt3((d),(k1),(k2),(k3))
#  define des_xwhite_in2out(k,i,o)\
        _ossl_old_des_xwhite_in2out((k),(i),(o))
#  define des_enc_read(f,b,l,k,iv)\
        _ossl_old_des_enc_read((f),(b),(l),(k),(iv))
#  define des_enc_write(f,b,l,k,iv)\
        _ossl_old_des_enc_write((f),(b),(l),(k),(iv))
#  define des_fcrypt(b,s,r)\
        _ossl_old_des_fcrypt((b),(s),(r))
#  define des_crypt(b,s)\
        _ossl_old_des_crypt((b),(s))
#  if 0
#   define crypt(b,s)\
        _ossl_old_crypt((b),(s))
#  endif
#  define des_ofb_encrypt(i,o,n,l,k,iv)\
        _ossl_old_des_ofb_encrypt((i),(o),(n),(l),(k),(iv))
#  define des_pcbc_encrypt(i,o,l,k,iv,e)\
        _ossl_old_des_pcbc_encrypt((i),(o),(l),(k),(iv),(e))
#  define des_quad_cksum(i,o,l,c,s)\
        _ossl_old_des_quad_cksum((i),(o),(l),(c),(s))
#  define des_random_seed(k)\
        _ossl_old_des_random_seed((k))
#  define des_random_key(r)\
        _ossl_old_des_random_key((r))
#  define des_read_password(k,p,v) \
        _ossl_old_des_read_password((k),(p),(v))
#  define des_read_2passwords(k1,k2,p,v) \
        _ossl_old_des_read_2passwords((k1),(k2),(p),(v))
#  define des_set_odd_parity(k)\
        _ossl_old_des_set_odd_parity((k))
#  define des_is_weak_key(k)\
        _ossl_old_des_is_weak_key((k))
#  define des_set_key(k,ks)\
        _ossl_old_des_set_key((k),(ks))
#  define des_key_sched(k,ks)\
        _ossl_old_des_key_sched((k),(ks))
#  define des_string_to_key(s,k)\
        _ossl_old_des_string_to_key((s),(k))
#  define des_string_to_2keys(s,k1,k2)\
        _ossl_old_des_string_to_2keys((s),(k1),(k2))
#  define des_cfb64_encrypt(i,o,l,ks,iv,n,e)\
        _ossl_old_des_cfb64_encrypt((i),(o),(l),(ks),(iv),(n),(e))
#  define des_ofb64_encrypt(i,o,l,ks,iv,n)\
        _ossl_old_des_ofb64_encrypt((i),(o),(l),(ks),(iv),(n))

#  define des_ecb2_encrypt(i,o,k1,k2,e) \
        des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))

#  define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
        des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))

#  define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
        des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))

#  define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
        des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))

#  define des_check_key DES_check_key
#  define des_rw_mode DES_rw_mode
# endif

const char *_ossl_old_des_options(void);
void _ossl_old_des_ecb3_encrypt(_ossl_old_des_cblock *input,
                                _ossl_old_des_cblock *output,
                                _ossl_old_des_key_schedule ks1,
                                _ossl_old_des_key_schedule ks2,
                                _ossl_old_des_key_schedule ks3, int enc);
DES_LONG _ossl_old_des_cbc_cksum(_ossl_old_des_cblock *input,
                                 _ossl_old_des_cblock *output, long length,
                                 _ossl_old_des_key_schedule schedule,
                                 _ossl_old_des_cblock *ivec);
void _ossl_old_des_cbc_encrypt(_ossl_old_des_cblock *input,
                               _ossl_old_des_cblock *output, long length,
                               _ossl_old_des_key_schedule schedule,
                               _ossl_old_des_cblock *ivec, int enc);
void _ossl_old_des_ncbc_encrypt(_ossl_old_des_cblock *input,
                                _ossl_old_des_cblock *output, long length,
                                _ossl_old_des_key_schedule schedule,
                                _ossl_old_des_cblock *ivec, int enc);
void _ossl_old_des_xcbc_encrypt(_ossl_old_des_cblock *input,
                                _ossl_old_des_cblock *output, long length,
                                _ossl_old_des_key_schedule schedule,
                                _ossl_old_des_cblock *ivec,
                                _ossl_old_des_cblock *inw,
                                _ossl_old_des_cblock *outw, int enc);
void _ossl_old_des_cfb_encrypt(unsigned char *in, unsigned char *out,
                               int numbits, long length,
                               _ossl_old_des_key_schedule schedule,
                               _ossl_old_des_cblock *ivec, int enc);
void _ossl_old_des_ecb_encrypt(_ossl_old_des_cblock *input,
                               _ossl_old_des_cblock *output,
                               _ossl_old_des_key_schedule ks, int enc);
void _ossl_old_des_encrypt(DES_LONG *data, _ossl_old_des_key_schedule ks,
                           int enc);
void _ossl_old_des_encrypt2(DES_LONG *data, _ossl_old_des_key_schedule ks,
                            int enc);
void _ossl_old_des_encrypt3(DES_LONG *data, _ossl_old_des_key_schedule ks1,
                            _ossl_old_des_key_schedule ks2,
                            _ossl_old_des_key_schedule ks3);
void _ossl_old_des_decrypt3(DES_LONG *data, _ossl_old_des_key_schedule ks1,
                            _ossl_old_des_key_schedule ks2,
                            _ossl_old_des_key_schedule ks3);
void _ossl_old_des_ede3_cbc_encrypt(_ossl_old_des_cblock *input,
                                    _ossl_old_des_cblock *output, long length,
                                    _ossl_old_des_key_schedule ks1,
                                    _ossl_old_des_key_schedule ks2,
                                    _ossl_old_des_key_schedule ks3,
                                    _ossl_old_des_cblock *ivec, int enc);
void _ossl_old_des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out,
                                      long length,
                                      _ossl_old_des_key_schedule ks1,
                                      _ossl_old_des_key_schedule ks2,
                                      _ossl_old_des_key_schedule ks3,
                                      _ossl_old_des_cblock *ivec, int *num,
                                      int enc);
void _ossl_old_des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out,
                                      long length,
                                      _ossl_old_des_key_schedule ks1,
                                      _ossl_old_des_key_schedule ks2,
                                      _ossl_old_des_key_schedule ks3,
                                      _ossl_old_des_cblock *ivec, int *num);
# if 0
void _ossl_old_des_xwhite_in2out(_ossl_old_des_cblock (*des_key),
                                 _ossl_old_des_cblock (*in_white),
                                 _ossl_old_des_cblock (*out_white));
# endif

int _ossl_old_des_enc_read(int fd, char *buf, int len,
                           _ossl_old_des_key_schedule sched,
                           _ossl_old_des_cblock *iv);
int _ossl_old_des_enc_write(int fd, char *buf, int len,
                            _ossl_old_des_key_schedule sched,
                            _ossl_old_des_cblock *iv);
char *_ossl_old_des_fcrypt(const char *buf, const char *salt, char *ret);
char *_ossl_old_des_crypt(const char *buf, const char *salt);
# if !defined(PERL5) && !defined(NeXT)
char *_ossl_old_crypt(const char *buf, const char *salt);
# endif
void _ossl_old_des_ofb_encrypt(unsigned char *in, unsigned char *out,
                               int numbits, long length,
                               _ossl_old_des_key_schedule schedule,
                               _ossl_old_des_cblock *ivec);
void _ossl_old_des_pcbc_encrypt(_ossl_old_des_cblock *input,
                                _ossl_old_des_cblock *output, long length,
                                _ossl_old_des_key_schedule schedule,
                                _ossl_old_des_cblock *ivec, int enc);
DES_LONG _ossl_old_des_quad_cksum(_ossl_old_des_cblock *input,
                                  _ossl_old_des_cblock *output, long length,
                                  int out_count, _ossl_old_des_cblock *seed);
void _ossl_old_des_random_seed(_ossl_old_des_cblock key);
void _ossl_old_des_random_key(_ossl_old_des_cblock ret);
int _ossl_old_des_read_password(_ossl_old_des_cblock *key, const char *prompt,
                                int verify);
int _ossl_old_des_read_2passwords(_ossl_old_des_cblock *key1,
                                  _ossl_old_des_cblock *key2,
                                  const char *prompt, int verify);
void _ossl_old_des_set_odd_parity(_ossl_old_des_cblock *key);
int _ossl_old_des_is_weak_key(_ossl_old_des_cblock *key);
int _ossl_old_des_set_key(_ossl_old_des_cblock *key,
                          _ossl_old_des_key_schedule schedule);
int _ossl_old_des_key_sched(_ossl_old_des_cblock *key,
                            _ossl_old_des_key_schedule schedule);
void _ossl_old_des_string_to_key(char *str, _ossl_old_des_cblock *key);
void _ossl_old_des_string_to_2keys(char *str, _ossl_old_des_cblock *key1,
                                   _ossl_old_des_cblock *key2);
void _ossl_old_des_cfb64_encrypt(unsigned char *in, unsigned char *out,
                                 long length,
                                 _ossl_old_des_key_schedule schedule,
                                 _ossl_old_des_cblock *ivec, int *num,
                                 int enc);
void _ossl_old_des_ofb64_encrypt(unsigned char *in, unsigned char *out,
                                 long length,
                                 _ossl_old_des_key_schedule schedule,
                                 _ossl_old_des_cblock *ivec, int *num);

void _ossl_096_des_random_seed(des_cblock *key);

/*
 * The following definitions provide compatibility with the MIT Kerberos
 * library. The _ossl_old_des_key_schedule structure is not binary
 * compatible.
 */

# define _KERBEROS_DES_H

# define KRBDES_ENCRYPT DES_ENCRYPT
# define KRBDES_DECRYPT DES_DECRYPT

# ifdef KERBEROS
#  define ENCRYPT DES_ENCRYPT
#  define DECRYPT DES_DECRYPT
# endif

# ifndef NCOMPAT
#  define C_Block des_cblock
#  define Key_schedule des_key_schedule
#  define KEY_SZ DES_KEY_SZ
#  define string_to_key des_string_to_key
#  define read_pw_string des_read_pw_string
#  define random_key des_random_key
#  define pcbc_encrypt des_pcbc_encrypt
#  define set_key des_set_key
#  define key_sched des_key_sched
#  define ecb_encrypt des_ecb_encrypt
#  define cbc_encrypt des_cbc_encrypt
#  define ncbc_encrypt des_ncbc_encrypt
#  define xcbc_encrypt des_xcbc_encrypt
#  define cbc_cksum des_cbc_cksum
#  define quad_cksum des_quad_cksum
#  define check_parity des_check_key_parity
# endif

# define des_fixup_key_parity DES_fixup_key_parity

#ifdef  __cplusplus
}
#endif

/* for DES_read_pw_string et al */
# include <openssl/ui_compat.h>

#endif
openssl/x509_vfy.h000064400000071066151733316600010010 0ustar00/* crypto/x509/x509_vfy.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#ifndef HEADER_X509_H
# include <openssl/x509.h>
/*
 * openssl/x509.h ends up #include-ing this file at about the only
 * appropriate moment.
 */
#endif

#ifndef HEADER_X509_VFY_H
# define HEADER_X509_VFY_H

# include <openssl/opensslconf.h>
# ifndef OPENSSL_NO_LHASH
#  include <openssl/lhash.h>
# endif
# include <openssl/bio.h>
# include <openssl/crypto.h>
# include <openssl/symhacks.h>

#ifdef  __cplusplus
extern "C" {
#endif

# if 0
/* Outer object */
typedef struct x509_hash_dir_st {
    int num_dirs;
    char **dirs;
    int *dirs_type;
    int num_dirs_alloced;
} X509_HASH_DIR_CTX;
# endif

typedef struct x509_file_st {
    int num_paths;              /* number of paths to files or directories */
    int num_alloced;
    char **paths;               /* the list of paths or directories */
    int *path_type;
} X509_CERT_FILE_CTX;

/*******************************/
/*-
SSL_CTX -> X509_STORE
                -> X509_LOOKUP
                        ->X509_LOOKUP_METHOD
                -> X509_LOOKUP
                        ->X509_LOOKUP_METHOD

SSL     -> X509_STORE_CTX
                ->X509_STORE

The X509_STORE holds the tables etc for verification stuff.
A X509_STORE_CTX is used while validating a single certificate.
The X509_STORE has X509_LOOKUPs for looking up certs.
The X509_STORE then calls a function to actually verify the
certificate chain.
*/

# define X509_LU_RETRY           -1
# define X509_LU_FAIL            0
# define X509_LU_X509            1
# define X509_LU_CRL             2
# define X509_LU_PKEY            3

typedef struct x509_object_st {
    /* one of the above types */
    int type;
    union {
        char *ptr;
        X509 *x509;
        X509_CRL *crl;
        EVP_PKEY *pkey;
    } data;
} X509_OBJECT;

typedef struct x509_lookup_st X509_LOOKUP;

DECLARE_STACK_OF(X509_LOOKUP)
DECLARE_STACK_OF(X509_OBJECT)

/* This is a static that defines the function interface */
typedef struct x509_lookup_method_st {
    const char *name;
    int (*new_item) (X509_LOOKUP *ctx);
    void (*free) (X509_LOOKUP *ctx);
    int (*init) (X509_LOOKUP *ctx);
    int (*shutdown) (X509_LOOKUP *ctx);
    int (*ctrl) (X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
                 char **ret);
    int (*get_by_subject) (X509_LOOKUP *ctx, int type, X509_NAME *name,
                           X509_OBJECT *ret);
    int (*get_by_issuer_serial) (X509_LOOKUP *ctx, int type, X509_NAME *name,
                                 ASN1_INTEGER *serial, X509_OBJECT *ret);
    int (*get_by_fingerprint) (X509_LOOKUP *ctx, int type,
                               unsigned char *bytes, int len,
                               X509_OBJECT *ret);
    int (*get_by_alias) (X509_LOOKUP *ctx, int type, char *str, int len,
                         X509_OBJECT *ret);
} X509_LOOKUP_METHOD;

typedef struct X509_VERIFY_PARAM_ID_st X509_VERIFY_PARAM_ID;

/*
 * This structure hold all parameters associated with a verify operation by
 * including an X509_VERIFY_PARAM structure in related structures the
 * parameters used can be customized
 */

typedef struct X509_VERIFY_PARAM_st {
    char *name;
    time_t check_time;          /* Time to use */
    unsigned long inh_flags;    /* Inheritance flags */
    unsigned long flags;        /* Various verify flags */
    int purpose;                /* purpose to check untrusted certificates */
    int trust;                  /* trust setting to check */
    int depth;                  /* Verify depth */
    STACK_OF(ASN1_OBJECT) *policies; /* Permissible policies */
    X509_VERIFY_PARAM_ID *id;   /* opaque ID data */
} X509_VERIFY_PARAM;

DECLARE_STACK_OF(X509_VERIFY_PARAM)

/*
 * This is used to hold everything.  It is used for all certificate
 * validation.  Once we have a certificate chain, the 'verify' function is
 * then called to actually check the cert chain.
 */
struct x509_store_st {
    /* The following is a cache of trusted certs */
    int cache;                  /* if true, stash any hits */
    STACK_OF(X509_OBJECT) *objs; /* Cache of all objects */
    /* These are external lookup methods */
    STACK_OF(X509_LOOKUP) *get_cert_methods;
    X509_VERIFY_PARAM *param;
    /* Callbacks for various operations */
    /* called to verify a certificate */
    int (*verify) (X509_STORE_CTX *ctx);
    /* error callback */
    int (*verify_cb) (int ok, X509_STORE_CTX *ctx);
    /* get issuers cert from ctx */
    int (*get_issuer) (X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
    /* check issued */
    int (*check_issued) (X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
    /* Check revocation status of chain */
    int (*check_revocation) (X509_STORE_CTX *ctx);
    /* retrieve CRL */
    int (*get_crl) (X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x);
    /* Check CRL validity */
    int (*check_crl) (X509_STORE_CTX *ctx, X509_CRL *crl);
    /* Check certificate against CRL */
    int (*cert_crl) (X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x);
    STACK_OF(X509) *(*lookup_certs) (X509_STORE_CTX *ctx, X509_NAME *nm);
    STACK_OF(X509_CRL) *(*lookup_crls) (X509_STORE_CTX *ctx, X509_NAME *nm);
    int (*cleanup) (X509_STORE_CTX *ctx);
    CRYPTO_EX_DATA ex_data;
    int references;
} /* X509_STORE */ ;

int X509_STORE_set_depth(X509_STORE *store, int depth);

# define X509_STORE_set_verify_cb_func(ctx,func) ((ctx)->verify_cb=(func))
# define X509_STORE_set_verify_func(ctx,func)    ((ctx)->verify=(func))

/* This is the functions plus an instance of the local variables. */
struct x509_lookup_st {
    int init;                   /* have we been started */
    int skip;                   /* don't use us. */
    X509_LOOKUP_METHOD *method; /* the functions */
    char *method_data;          /* method data */
    X509_STORE *store_ctx;      /* who owns us */
} /* X509_LOOKUP */ ;

/*
 * This is a used when verifying cert chains.  Since the gathering of the
 * cert chain can take some time (and have to be 'retried', this needs to be
 * kept and passed around.
 */
struct x509_store_ctx_st {      /* X509_STORE_CTX */
    X509_STORE *ctx;
    /* used when looking up certs */
    int current_method;
    /* The following are set by the caller */
    /* The cert to check */
    X509 *cert;
    /* chain of X509s - untrusted - passed in */
    STACK_OF(X509) *untrusted;
    /* set of CRLs passed in */
    STACK_OF(X509_CRL) *crls;
    X509_VERIFY_PARAM *param;
    /* Other info for use with get_issuer() */
    void *other_ctx;
    /* Callbacks for various operations */
    /* called to verify a certificate */
    int (*verify) (X509_STORE_CTX *ctx);
    /* error callback */
    int (*verify_cb) (int ok, X509_STORE_CTX *ctx);
    /* get issuers cert from ctx */
    int (*get_issuer) (X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
    /* check issued */
    int (*check_issued) (X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
    /* Check revocation status of chain */
    int (*check_revocation) (X509_STORE_CTX *ctx);
    /* retrieve CRL */
    int (*get_crl) (X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x);
    /* Check CRL validity */
    int (*check_crl) (X509_STORE_CTX *ctx, X509_CRL *crl);
    /* Check certificate against CRL */
    int (*cert_crl) (X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x);
    int (*check_policy) (X509_STORE_CTX *ctx);
    STACK_OF(X509) *(*lookup_certs) (X509_STORE_CTX *ctx, X509_NAME *nm);
    STACK_OF(X509_CRL) *(*lookup_crls) (X509_STORE_CTX *ctx, X509_NAME *nm);
    int (*cleanup) (X509_STORE_CTX *ctx);
    /* The following is built up */
    /* if 0, rebuild chain */
    int valid;
    /* index of last untrusted cert */
    int last_untrusted;
    /* chain of X509s - built up and trusted */
    STACK_OF(X509) *chain;
    /* Valid policy tree */
    X509_POLICY_TREE *tree;
    /* Require explicit policy value */
    int explicit_policy;
    /* When something goes wrong, this is why */
    int error_depth;
    int error;
    X509 *current_cert;
    /* cert currently being tested as valid issuer */
    X509 *current_issuer;
    /* current CRL */
    X509_CRL *current_crl;
    /* score of current CRL */
    int current_crl_score;
    /* Reason mask */
    unsigned int current_reasons;
    /* For CRL path validation: parent context */
    X509_STORE_CTX *parent;
    CRYPTO_EX_DATA ex_data;
} /* X509_STORE_CTX */ ;

void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);

# define X509_STORE_CTX_set_app_data(ctx,data) \
        X509_STORE_CTX_set_ex_data(ctx,0,data)
# define X509_STORE_CTX_get_app_data(ctx) \
        X509_STORE_CTX_get_ex_data(ctx,0)

# define X509_L_FILE_LOAD        1
# define X509_L_ADD_DIR          2

# define X509_LOOKUP_load_file(x,name,type) \
                X509_LOOKUP_ctrl((x),X509_L_FILE_LOAD,(name),(long)(type),NULL)

# define X509_LOOKUP_add_dir(x,name,type) \
                X509_LOOKUP_ctrl((x),X509_L_ADD_DIR,(name),(long)(type),NULL)

# define         X509_V_OK                                       0
# define         X509_V_ERR_UNSPECIFIED                          1

# define         X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT            2
# define         X509_V_ERR_UNABLE_TO_GET_CRL                    3
# define         X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE     4
# define         X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE      5
# define         X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY   6
# define         X509_V_ERR_CERT_SIGNATURE_FAILURE               7
# define         X509_V_ERR_CRL_SIGNATURE_FAILURE                8
# define         X509_V_ERR_CERT_NOT_YET_VALID                   9
# define         X509_V_ERR_CERT_HAS_EXPIRED                     10
# define         X509_V_ERR_CRL_NOT_YET_VALID                    11
# define         X509_V_ERR_CRL_HAS_EXPIRED                      12
# define         X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD       13
# define         X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD        14
# define         X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD       15
# define         X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD       16
# define         X509_V_ERR_OUT_OF_MEM                           17
# define         X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT          18
# define         X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN            19
# define         X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY    20
# define         X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE      21
# define         X509_V_ERR_CERT_CHAIN_TOO_LONG                  22
# define         X509_V_ERR_CERT_REVOKED                         23
# define         X509_V_ERR_INVALID_CA                           24
# define         X509_V_ERR_PATH_LENGTH_EXCEEDED                 25
# define         X509_V_ERR_INVALID_PURPOSE                      26
# define         X509_V_ERR_CERT_UNTRUSTED                       27
# define         X509_V_ERR_CERT_REJECTED                        28
/* These are 'informational' when looking for issuer cert */
# define         X509_V_ERR_SUBJECT_ISSUER_MISMATCH              29
# define         X509_V_ERR_AKID_SKID_MISMATCH                   30
# define         X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH          31
# define         X509_V_ERR_KEYUSAGE_NO_CERTSIGN                 32

# define         X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER             33
# define         X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION         34
# define         X509_V_ERR_KEYUSAGE_NO_CRL_SIGN                 35
# define         X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION     36
# define         X509_V_ERR_INVALID_NON_CA                       37
# define         X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED           38
# define         X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE        39
# define         X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED       40

# define         X509_V_ERR_INVALID_EXTENSION                    41
# define         X509_V_ERR_INVALID_POLICY_EXTENSION             42
# define         X509_V_ERR_NO_EXPLICIT_POLICY                   43
# define         X509_V_ERR_DIFFERENT_CRL_SCOPE                  44
# define         X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE        45

# define         X509_V_ERR_UNNESTED_RESOURCE                    46

# define         X509_V_ERR_PERMITTED_VIOLATION                  47
# define         X509_V_ERR_EXCLUDED_VIOLATION                   48
# define         X509_V_ERR_SUBTREE_MINMAX                       49
# define         X509_V_ERR_APPLICATION_VERIFICATION             50
# define         X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE          51
# define         X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX        52
# define         X509_V_ERR_UNSUPPORTED_NAME_SYNTAX              53
# define         X509_V_ERR_CRL_PATH_VALIDATION_ERROR            54

/* Suite B mode algorithm violation */
# define         X509_V_ERR_SUITE_B_INVALID_VERSION              56
# define         X509_V_ERR_SUITE_B_INVALID_ALGORITHM            57
# define         X509_V_ERR_SUITE_B_INVALID_CURVE                58
# define         X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM  59
# define         X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED              60
# define         X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 61

/* Host, email and IP check errors */
# define         X509_V_ERR_HOSTNAME_MISMATCH                    62
# define         X509_V_ERR_EMAIL_MISMATCH                       63
# define         X509_V_ERR_IP_ADDRESS_MISMATCH                  64

/* Caller error */
# define         X509_V_ERR_INVALID_CALL                         65
/* Issuer lookup error */
# define         X509_V_ERR_STORE_LOOKUP                         66

# define         X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION         67

/* Certificate verify flags */

/* Send issuer+subject checks to verify_cb */
# define X509_V_FLAG_CB_ISSUER_CHECK             0x1
/* Use check time instead of current time */
# define X509_V_FLAG_USE_CHECK_TIME              0x2
/* Lookup CRLs */
# define X509_V_FLAG_CRL_CHECK                   0x4
/* Lookup CRLs for whole chain */
# define X509_V_FLAG_CRL_CHECK_ALL               0x8
/* Ignore unhandled critical extensions */
# define X509_V_FLAG_IGNORE_CRITICAL             0x10
/* Disable workarounds for broken certificates */
# define X509_V_FLAG_X509_STRICT                 0x20
/* Enable proxy certificate validation */
# define X509_V_FLAG_ALLOW_PROXY_CERTS           0x40
/* Enable policy checking */
# define X509_V_FLAG_POLICY_CHECK                0x80
/* Policy variable require-explicit-policy */
# define X509_V_FLAG_EXPLICIT_POLICY             0x100
/* Policy variable inhibit-any-policy */
# define X509_V_FLAG_INHIBIT_ANY                 0x200
/* Policy variable inhibit-policy-mapping */
# define X509_V_FLAG_INHIBIT_MAP                 0x400
/* Notify callback that policy is OK */
# define X509_V_FLAG_NOTIFY_POLICY               0x800
/* Extended CRL features such as indirect CRLs, alternate CRL signing keys */
# define X509_V_FLAG_EXTENDED_CRL_SUPPORT        0x1000
/* Delta CRL support */
# define X509_V_FLAG_USE_DELTAS                  0x2000
/* Check selfsigned CA signature */
# define X509_V_FLAG_CHECK_SS_SIGNATURE          0x4000
/* Use trusted store first */
# define X509_V_FLAG_TRUSTED_FIRST               0x8000
/* Suite B 128 bit only mode: not normally used */
# define X509_V_FLAG_SUITEB_128_LOS_ONLY         0x10000
/* Suite B 192 bit only mode */
# define X509_V_FLAG_SUITEB_192_LOS              0x20000
/* Suite B 128 bit mode allowing 192 bit algorithms */
# define X509_V_FLAG_SUITEB_128_LOS              0x30000

/* Allow partial chains if at least one certificate is in trusted store */
# define X509_V_FLAG_PARTIAL_CHAIN               0x80000
/*
 * If the initial chain is not trusted, do not attempt to build an alternative
 * chain. Alternate chain checking was introduced in 1.0.2b. Setting this flag
 * will force the behaviour to match that of previous versions.
 */
# define X509_V_FLAG_NO_ALT_CHAINS               0x100000

# define X509_VP_FLAG_DEFAULT                    0x1
# define X509_VP_FLAG_OVERWRITE                  0x2
# define X509_VP_FLAG_RESET_FLAGS                0x4
# define X509_VP_FLAG_LOCKED                     0x8
# define X509_VP_FLAG_ONCE                       0x10

/* Internal use: mask of policy related options */
# define X509_V_FLAG_POLICY_MASK (X509_V_FLAG_POLICY_CHECK \
                                | X509_V_FLAG_EXPLICIT_POLICY \
                                | X509_V_FLAG_INHIBIT_ANY \
                                | X509_V_FLAG_INHIBIT_MAP)

int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
                               X509_NAME *name);
X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,
                                             int type, X509_NAME *name);
X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h,
                                        X509_OBJECT *x);
void X509_OBJECT_up_ref_count(X509_OBJECT *a);
void X509_OBJECT_free_contents(X509_OBJECT *a);
X509_STORE *X509_STORE_new(void);
void X509_STORE_free(X509_STORE *v);

STACK_OF(X509) *X509_STORE_get1_certs(X509_STORE_CTX *st, X509_NAME *nm);
STACK_OF(X509_CRL) *X509_STORE_get1_crls(X509_STORE_CTX *st, X509_NAME *nm);
int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags);
int X509_STORE_set_purpose(X509_STORE *ctx, int purpose);
int X509_STORE_set_trust(X509_STORE *ctx, int trust);
int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm);

void X509_STORE_set_verify_cb(X509_STORE *ctx,
                              int (*verify_cb) (int, X509_STORE_CTX *));

void X509_STORE_set_lookup_crls_cb(X509_STORE *ctx,
                                   STACK_OF(X509_CRL) *(*cb) (X509_STORE_CTX
                                                              *ctx,
                                                              X509_NAME *nm));

X509_STORE_CTX *X509_STORE_CTX_new(void);

int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x);

void X509_STORE_CTX_free(X509_STORE_CTX *ctx);
int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store,
                        X509 *x509, STACK_OF(X509) *chain);
void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk);
void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx);

X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx);

X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m);

X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void);
X509_LOOKUP_METHOD *X509_LOOKUP_file(void);

int X509_STORE_add_cert(X509_STORE *ctx, X509 *x);
int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x);

int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name,
                              X509_OBJECT *ret);

int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc,
                     long argl, char **ret);

# ifndef OPENSSL_NO_STDIO
int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type);
int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type);
int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type);
# endif

X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method);
void X509_LOOKUP_free(X509_LOOKUP *ctx);
int X509_LOOKUP_init(X509_LOOKUP *ctx);
int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name,
                           X509_OBJECT *ret);
int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name,
                                 ASN1_INTEGER *serial, X509_OBJECT *ret);
int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type,
                               unsigned char *bytes, int len,
                               X509_OBJECT *ret);
int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len,
                         X509_OBJECT *ret);
int X509_LOOKUP_shutdown(X509_LOOKUP *ctx);

# ifndef OPENSSL_NO_STDIO
int X509_STORE_load_locations(X509_STORE *ctx,
                              const char *file, const char *dir);
int X509_STORE_set_default_paths(X509_STORE *ctx);
# endif

int X509_STORE_CTX_get_ex_new_index(long argl, void *argp,
                                    CRYPTO_EX_new *new_func,
                                    CRYPTO_EX_dup *dup_func,
                                    CRYPTO_EX_free *free_func);
int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data);
void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx);
int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx);
void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int s);
int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx);
X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx);
X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx);
X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx);
X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx);
STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx);
STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx);
void X509_STORE_CTX_set_cert(X509_STORE_CTX *c, X509 *x);
void X509_STORE_CTX_set_chain(X509_STORE_CTX *c, STACK_OF(X509) *sk);
void X509_STORE_CTX_set0_crls(X509_STORE_CTX *c, STACK_OF(X509_CRL) *sk);
int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose);
int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust);
int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
                                   int purpose, int trust);
void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags);
void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags,
                             time_t t);
void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
                                  int (*verify_cb) (int, X509_STORE_CTX *));

X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx);
int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx);

X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx);
void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param);
int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name);

/* X509_VERIFY_PARAM functions */

X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void);
void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param);
int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *to,
                              const X509_VERIFY_PARAM *from);
int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to,
                           const X509_VERIFY_PARAM *from);
int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name);
int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param,
                                unsigned long flags);
int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param,
                                  unsigned long flags);
unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param);
int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose);
int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust);
void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth);
void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t);
int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param,
                                  ASN1_OBJECT *policy);
int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param,
                                    STACK_OF(ASN1_OBJECT) *policies);

int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param,
                                const char *name, size_t namelen);
int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param,
                                const char *name, size_t namelen);
void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param,
                                     unsigned int flags);
char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *);
int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param,
                                 const char *email, size_t emaillen);
int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param,
                              const unsigned char *ip, size_t iplen);
int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param,
                                  const char *ipasc);

int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param);
const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param);

int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param);
int X509_VERIFY_PARAM_get_count(void);
const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id);
const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name);
void X509_VERIFY_PARAM_table_cleanup(void);

int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
                      STACK_OF(X509) *certs,
                      STACK_OF(ASN1_OBJECT) *policy_oids, unsigned int flags);

void X509_policy_tree_free(X509_POLICY_TREE *tree);

int X509_policy_tree_level_count(const X509_POLICY_TREE *tree);
X509_POLICY_LEVEL *X509_policy_tree_get0_level(const X509_POLICY_TREE *tree,
                                               int i);

STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_policies(const
                                                           X509_POLICY_TREE
                                                           *tree);

STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_user_policies(const
                                                                X509_POLICY_TREE
                                                                *tree);

int X509_policy_level_node_count(X509_POLICY_LEVEL *level);

X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level,
                                              int i);

const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node);

STACK_OF(POLICYQUALINFO) *X509_policy_node_get0_qualifiers(const
                                                           X509_POLICY_NODE
                                                           *node);
const X509_POLICY_NODE *X509_policy_node_get0_parent(const X509_POLICY_NODE
                                                     *node);

#ifdef  __cplusplus
}
#endif
#endif
openssl/aes.h000064400000014002151733316600007152 0ustar00/* crypto/aes/aes.h */
/* ====================================================================
 * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 */

#ifndef HEADER_AES_H
# define HEADER_AES_H

# include <openssl/opensslconf.h>

# ifdef OPENSSL_NO_AES
#  error AES is disabled.
# endif

# include <stddef.h>

# define AES_ENCRYPT     1
# define AES_DECRYPT     0

/*
 * Because array size can't be a const in C, the following two are macros.
 * Both sizes are in bytes.
 */
# define AES_MAXNR 14
# define AES_BLOCK_SIZE 16

#ifdef  __cplusplus
extern "C" {
#endif

/* This should be a hidden type, but EVP requires that the size be known */
struct aes_key_st {
# ifdef AES_LONG
    unsigned long rd_key[4 * (AES_MAXNR + 1)];
# else
    unsigned int rd_key[4 * (AES_MAXNR + 1)];
# endif
    int rounds;
};
typedef struct aes_key_st AES_KEY;

const char *AES_options(void);

int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
                        AES_KEY *key);
int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
                        AES_KEY *key);

int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits,
                                AES_KEY *key);
int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits,
                                AES_KEY *key);

void AES_encrypt(const unsigned char *in, unsigned char *out,
                 const AES_KEY *key);
void AES_decrypt(const unsigned char *in, unsigned char *out,
                 const AES_KEY *key);

void AES_ecb_encrypt(const unsigned char *in, unsigned char *out,
                     const AES_KEY *key, const int enc);
void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
                     size_t length, const AES_KEY *key,
                     unsigned char *ivec, const int enc);
void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out,
                        size_t length, const AES_KEY *key,
                        unsigned char *ivec, int *num, const int enc);
void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out,
                      size_t length, const AES_KEY *key,
                      unsigned char *ivec, int *num, const int enc);
void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out,
                      size_t length, const AES_KEY *key,
                      unsigned char *ivec, int *num, const int enc);
void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out,
                        size_t length, const AES_KEY *key,
                        unsigned char *ivec, int *num);
void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out,
                        size_t length, const AES_KEY *key,
                        unsigned char ivec[AES_BLOCK_SIZE],
                        unsigned char ecount_buf[AES_BLOCK_SIZE],
                        unsigned int *num);
/* NB: the IV is _two_ blocks long */
void AES_ige_encrypt(const unsigned char *in, unsigned char *out,
                     size_t length, const AES_KEY *key,
                     unsigned char *ivec, const int enc);
/* NB: the IV is _four_ blocks long */
void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out,
                        size_t length, const AES_KEY *key,
                        const AES_KEY *key2, const unsigned char *ivec,
                        const int enc);

int AES_wrap_key(AES_KEY *key, const unsigned char *iv,
                 unsigned char *out,
                 const unsigned char *in, unsigned int inlen);
int AES_unwrap_key(AES_KEY *key, const unsigned char *iv,
                   unsigned char *out,
                   const unsigned char *in, unsigned int inlen);


#ifdef  __cplusplus
}
#endif

#endif                          /* !HEADER_AES_H */
openssl/hmac.h000064400000010667151733316600007327 0ustar00/* crypto/hmac/hmac.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */
#ifndef HEADER_HMAC_H
# define HEADER_HMAC_H

# include <openssl/opensslconf.h>

# ifdef OPENSSL_NO_HMAC
#  error HMAC is disabled.
# endif

# include <openssl/evp.h>

# define HMAC_MAX_MD_CBLOCK      128/* largest known is SHA512 */

#ifdef  __cplusplus
extern "C" {
#endif

typedef struct hmac_ctx_st {
    const EVP_MD *md;
    EVP_MD_CTX md_ctx;
    EVP_MD_CTX i_ctx;
    EVP_MD_CTX o_ctx;
    unsigned int key_length;
    unsigned char key[HMAC_MAX_MD_CBLOCK];
} HMAC_CTX;

# define HMAC_size(e)    (EVP_MD_size((e)->md))

void HMAC_CTX_init(HMAC_CTX *ctx);
void HMAC_CTX_cleanup(HMAC_CTX *ctx);

/* deprecated */
# define HMAC_cleanup(ctx) HMAC_CTX_cleanup(ctx)

/* deprecated */
int HMAC_Init(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md);
int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
                 const EVP_MD *md, ENGINE *impl);
int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len);
int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len);
unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
                    const unsigned char *d, size_t n, unsigned char *md,
                    unsigned int *md_len);
int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx);

void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags);

#ifdef  __cplusplus
}
#endif

#endif
openssl/objects.h000064400000134714151733316610010051 0ustar00/* crypto/objects/objects.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#ifndef HEADER_OBJECTS_H
# define HEADER_OBJECTS_H

# define USE_OBJ_MAC

# ifdef USE_OBJ_MAC
#  include <openssl/obj_mac.h>
# else
#  define SN_undef                        "UNDEF"
#  define LN_undef                        "undefined"
#  define NID_undef                       0
#  define OBJ_undef                       0L

#  define SN_Algorithm                    "Algorithm"
#  define LN_algorithm                    "algorithm"
#  define NID_algorithm                   38
#  define OBJ_algorithm                   1L,3L,14L,3L,2L

#  define LN_rsadsi                       "rsadsi"
#  define NID_rsadsi                      1
#  define OBJ_rsadsi                      1L,2L,840L,113549L

#  define LN_pkcs                         "pkcs"
#  define NID_pkcs                        2
#  define OBJ_pkcs                        OBJ_rsadsi,1L

#  define SN_md2                          "MD2"
#  define LN_md2                          "md2"
#  define NID_md2                         3
#  define OBJ_md2                         OBJ_rsadsi,2L,2L

#  define SN_md5                          "MD5"
#  define LN_md5                          "md5"
#  define NID_md5                         4
#  define OBJ_md5                         OBJ_rsadsi,2L,5L

#  define SN_rc4                          "RC4"
#  define LN_rc4                          "rc4"
#  define NID_rc4                         5
#  define OBJ_rc4                         OBJ_rsadsi,3L,4L

#  define LN_rsaEncryption                "rsaEncryption"
#  define NID_rsaEncryption               6
#  define OBJ_rsaEncryption               OBJ_pkcs,1L,1L

#  define SN_md2WithRSAEncryption         "RSA-MD2"
#  define LN_md2WithRSAEncryption         "md2WithRSAEncryption"
#  define NID_md2WithRSAEncryption        7
#  define OBJ_md2WithRSAEncryption        OBJ_pkcs,1L,2L

#  define SN_md5WithRSAEncryption         "RSA-MD5"
#  define LN_md5WithRSAEncryption         "md5WithRSAEncryption"
#  define NID_md5WithRSAEncryption        8
#  define OBJ_md5WithRSAEncryption        OBJ_pkcs,1L,4L

#  define SN_pbeWithMD2AndDES_CBC         "PBE-MD2-DES"
#  define LN_pbeWithMD2AndDES_CBC         "pbeWithMD2AndDES-CBC"
#  define NID_pbeWithMD2AndDES_CBC        9
#  define OBJ_pbeWithMD2AndDES_CBC        OBJ_pkcs,5L,1L

#  define SN_pbeWithMD5AndDES_CBC         "PBE-MD5-DES"
#  define LN_pbeWithMD5AndDES_CBC         "pbeWithMD5AndDES-CBC"
#  define NID_pbeWithMD5AndDES_CBC        10
#  define OBJ_pbeWithMD5AndDES_CBC        OBJ_pkcs,5L,3L

#  define LN_X500                         "X500"
#  define NID_X500                        11
#  define OBJ_X500                        2L,5L

#  define LN_X509                         "X509"
#  define NID_X509                        12
#  define OBJ_X509                        OBJ_X500,4L

#  define SN_commonName                   "CN"
#  define LN_commonName                   "commonName"
#  define NID_commonName                  13
#  define OBJ_commonName                  OBJ_X509,3L

#  define SN_countryName                  "C"
#  define LN_countryName                  "countryName"
#  define NID_countryName                 14
#  define OBJ_countryName                 OBJ_X509,6L

#  define SN_localityName                 "L"
#  define LN_localityName                 "localityName"
#  define NID_localityName                15
#  define OBJ_localityName                OBJ_X509,7L

/* Postal Address? PA */

/* should be "ST" (rfc1327) but MS uses 'S' */
#  define SN_stateOrProvinceName          "ST"
#  define LN_stateOrProvinceName          "stateOrProvinceName"
#  define NID_stateOrProvinceName         16
#  define OBJ_stateOrProvinceName         OBJ_X509,8L

#  define SN_organizationName             "O"
#  define LN_organizationName             "organizationName"
#  define NID_organizationName            17
#  define OBJ_organizationName            OBJ_X509,10L

#  define SN_organizationalUnitName       "OU"
#  define LN_organizationalUnitName       "organizationalUnitName"
#  define NID_organizationalUnitName      18
#  define OBJ_organizationalUnitName      OBJ_X509,11L

#  define SN_rsa                          "RSA"
#  define LN_rsa                          "rsa"
#  define NID_rsa                         19
#  define OBJ_rsa                         OBJ_X500,8L,1L,1L

#  define LN_pkcs7                        "pkcs7"
#  define NID_pkcs7                       20
#  define OBJ_pkcs7                       OBJ_pkcs,7L

#  define LN_pkcs7_data                   "pkcs7-data"
#  define NID_pkcs7_data                  21
#  define OBJ_pkcs7_data                  OBJ_pkcs7,1L

#  define LN_pkcs7_signed                 "pkcs7-signedData"
#  define NID_pkcs7_signed                22
#  define OBJ_pkcs7_signed                OBJ_pkcs7,2L

#  define LN_pkcs7_enveloped              "pkcs7-envelopedData"
#  define NID_pkcs7_enveloped             23
#  define OBJ_pkcs7_enveloped             OBJ_pkcs7,3L

#  define LN_pkcs7_signedAndEnveloped     "pkcs7-signedAndEnvelopedData"
#  define NID_pkcs7_signedAndEnveloped    24
#  define OBJ_pkcs7_signedAndEnveloped    OBJ_pkcs7,4L

#  define LN_pkcs7_digest                 "pkcs7-digestData"
#  define NID_pkcs7_digest                25
#  define OBJ_pkcs7_digest                OBJ_pkcs7,5L

#  define LN_pkcs7_encrypted              "pkcs7-encryptedData"
#  define NID_pkcs7_encrypted             26
#  define OBJ_pkcs7_encrypted             OBJ_pkcs7,6L

#  define LN_pkcs3                        "pkcs3"
#  define NID_pkcs3                       27
#  define OBJ_pkcs3                       OBJ_pkcs,3L

#  define LN_dhKeyAgreement               "dhKeyAgreement"
#  define NID_dhKeyAgreement              28
#  define OBJ_dhKeyAgreement              OBJ_pkcs3,1L

#  define SN_des_ecb                      "DES-ECB"
#  define LN_des_ecb                      "des-ecb"
#  define NID_des_ecb                     29
#  define OBJ_des_ecb                     OBJ_algorithm,6L

#  define SN_des_cfb64                    "DES-CFB"
#  define LN_des_cfb64                    "des-cfb"
#  define NID_des_cfb64                   30
/* IV + num */
#  define OBJ_des_cfb64                   OBJ_algorithm,9L

#  define SN_des_cbc                      "DES-CBC"
#  define LN_des_cbc                      "des-cbc"
#  define NID_des_cbc                     31
/* IV */
#  define OBJ_des_cbc                     OBJ_algorithm,7L

#  define SN_des_ede                      "DES-EDE"
#  define LN_des_ede                      "des-ede"
#  define NID_des_ede                     32
/* ?? */
#  define OBJ_des_ede                     OBJ_algorithm,17L

#  define SN_des_ede3                     "DES-EDE3"
#  define LN_des_ede3                     "des-ede3"
#  define NID_des_ede3                    33

#  define SN_idea_cbc                     "IDEA-CBC"
#  define LN_idea_cbc                     "idea-cbc"
#  define NID_idea_cbc                    34
#  define OBJ_idea_cbc                    1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L

#  define SN_idea_cfb64                   "IDEA-CFB"
#  define LN_idea_cfb64                   "idea-cfb"
#  define NID_idea_cfb64                  35

#  define SN_idea_ecb                     "IDEA-ECB"
#  define LN_idea_ecb                     "idea-ecb"
#  define NID_idea_ecb                    36

#  define SN_rc2_cbc                      "RC2-CBC"
#  define LN_rc2_cbc                      "rc2-cbc"
#  define NID_rc2_cbc                     37
#  define OBJ_rc2_cbc                     OBJ_rsadsi,3L,2L

#  define SN_rc2_ecb                      "RC2-ECB"
#  define LN_rc2_ecb                      "rc2-ecb"
#  define NID_rc2_ecb                     38

#  define SN_rc2_cfb64                    "RC2-CFB"
#  define LN_rc2_cfb64                    "rc2-cfb"
#  define NID_rc2_cfb64                   39

#  define SN_rc2_ofb64                    "RC2-OFB"
#  define LN_rc2_ofb64                    "rc2-ofb"
#  define NID_rc2_ofb64                   40

#  define SN_sha                          "SHA"
#  define LN_sha                          "sha"
#  define NID_sha                         41
#  define OBJ_sha                         OBJ_algorithm,18L

#  define SN_shaWithRSAEncryption         "RSA-SHA"
#  define LN_shaWithRSAEncryption         "shaWithRSAEncryption"
#  define NID_shaWithRSAEncryption        42
#  define OBJ_shaWithRSAEncryption        OBJ_algorithm,15L

#  define SN_des_ede_cbc                  "DES-EDE-CBC"
#  define LN_des_ede_cbc                  "des-ede-cbc"
#  define NID_des_ede_cbc                 43

#  define SN_des_ede3_cbc                 "DES-EDE3-CBC"
#  define LN_des_ede3_cbc                 "des-ede3-cbc"
#  define NID_des_ede3_cbc                44
#  define OBJ_des_ede3_cbc                OBJ_rsadsi,3L,7L

#  define SN_des_ofb64                    "DES-OFB"
#  define LN_des_ofb64                    "des-ofb"
#  define NID_des_ofb64                   45
#  define OBJ_des_ofb64                   OBJ_algorithm,8L

#  define SN_idea_ofb64                   "IDEA-OFB"
#  define LN_idea_ofb64                   "idea-ofb"
#  define NID_idea_ofb64                  46

#  define LN_pkcs9                        "pkcs9"
#  define NID_pkcs9                       47
#  define OBJ_pkcs9                       OBJ_pkcs,9L

#  define SN_pkcs9_emailAddress           "Email"
#  define LN_pkcs9_emailAddress           "emailAddress"
#  define NID_pkcs9_emailAddress          48
#  define OBJ_pkcs9_emailAddress          OBJ_pkcs9,1L

#  define LN_pkcs9_unstructuredName       "unstructuredName"
#  define NID_pkcs9_unstructuredName      49
#  define OBJ_pkcs9_unstructuredName      OBJ_pkcs9,2L

#  define LN_pkcs9_contentType            "contentType"
#  define NID_pkcs9_contentType           50
#  define OBJ_pkcs9_contentType           OBJ_pkcs9,3L

#  define LN_pkcs9_messageDigest          "messageDigest"
#  define NID_pkcs9_messageDigest         51
#  define OBJ_pkcs9_messageDigest         OBJ_pkcs9,4L

#  define LN_pkcs9_signingTime            "signingTime"
#  define NID_pkcs9_signingTime           52
#  define OBJ_pkcs9_signingTime           OBJ_pkcs9,5L

#  define LN_pkcs9_countersignature       "countersignature"
#  define NID_pkcs9_countersignature      53
#  define OBJ_pkcs9_countersignature      OBJ_pkcs9,6L

#  define LN_pkcs9_challengePassword      "challengePassword"
#  define NID_pkcs9_challengePassword     54
#  define OBJ_pkcs9_challengePassword     OBJ_pkcs9,7L

#  define LN_pkcs9_unstructuredAddress    "unstructuredAddress"
#  define NID_pkcs9_unstructuredAddress   55
#  define OBJ_pkcs9_unstructuredAddress   OBJ_pkcs9,8L

#  define LN_pkcs9_extCertAttributes      "extendedCertificateAttributes"
#  define NID_pkcs9_extCertAttributes     56
#  define OBJ_pkcs9_extCertAttributes     OBJ_pkcs9,9L

#  define SN_netscape                     "Netscape"
#  define LN_netscape                     "Netscape Communications Corp."
#  define NID_netscape                    57
#  define OBJ_netscape                    2L,16L,840L,1L,113730L

#  define SN_netscape_cert_extension      "nsCertExt"
#  define LN_netscape_cert_extension      "Netscape Certificate Extension"
#  define NID_netscape_cert_extension     58
#  define OBJ_netscape_cert_extension     OBJ_netscape,1L

#  define SN_netscape_data_type           "nsDataType"
#  define LN_netscape_data_type           "Netscape Data Type"
#  define NID_netscape_data_type          59
#  define OBJ_netscape_data_type          OBJ_netscape,2L

#  define SN_des_ede_cfb64                "DES-EDE-CFB"
#  define LN_des_ede_cfb64                "des-ede-cfb"
#  define NID_des_ede_cfb64               60

#  define SN_des_ede3_cfb64               "DES-EDE3-CFB"
#  define LN_des_ede3_cfb64               "des-ede3-cfb"
#  define NID_des_ede3_cfb64              61

#  define SN_des_ede_ofb64                "DES-EDE-OFB"
#  define LN_des_ede_ofb64                "des-ede-ofb"
#  define NID_des_ede_ofb64               62

#  define SN_des_ede3_ofb64               "DES-EDE3-OFB"
#  define LN_des_ede3_ofb64               "des-ede3-ofb"
#  define NID_des_ede3_ofb64              63

/* I'm not sure about the object ID */
#  define SN_sha1                         "SHA1"
#  define LN_sha1                         "sha1"
#  define NID_sha1                        64
#  define OBJ_sha1                        OBJ_algorithm,26L
/* 28 Jun 1996 - eay */
/* #define OBJ_sha1                     1L,3L,14L,2L,26L,05L <- wrong */

#  define SN_sha1WithRSAEncryption        "RSA-SHA1"
#  define LN_sha1WithRSAEncryption        "sha1WithRSAEncryption"
#  define NID_sha1WithRSAEncryption       65
#  define OBJ_sha1WithRSAEncryption       OBJ_pkcs,1L,5L

#  define SN_dsaWithSHA                   "DSA-SHA"
#  define LN_dsaWithSHA                   "dsaWithSHA"
#  define NID_dsaWithSHA                  66
#  define OBJ_dsaWithSHA                  OBJ_algorithm,13L

#  define SN_dsa_2                        "DSA-old"
#  define LN_dsa_2                        "dsaEncryption-old"
#  define NID_dsa_2                       67
#  define OBJ_dsa_2                       OBJ_algorithm,12L

/* proposed by microsoft to RSA */
#  define SN_pbeWithSHA1AndRC2_CBC        "PBE-SHA1-RC2-64"
#  define LN_pbeWithSHA1AndRC2_CBC        "pbeWithSHA1AndRC2-CBC"
#  define NID_pbeWithSHA1AndRC2_CBC       68
#  define OBJ_pbeWithSHA1AndRC2_CBC       OBJ_pkcs,5L,11L

/*
 * proposed by microsoft to RSA as pbeWithSHA1AndRC4: it is now defined
 * explicitly in PKCS#5 v2.0 as id-PBKDF2 which is something completely
 * different.
 */
#  define LN_id_pbkdf2                    "PBKDF2"
#  define NID_id_pbkdf2                   69
#  define OBJ_id_pbkdf2                   OBJ_pkcs,5L,12L

#  define SN_dsaWithSHA1_2                "DSA-SHA1-old"
#  define LN_dsaWithSHA1_2                "dsaWithSHA1-old"
#  define NID_dsaWithSHA1_2               70
/* Got this one from 'sdn706r20.pdf' which is actually an NSA document :-) */
#  define OBJ_dsaWithSHA1_2               OBJ_algorithm,27L

#  define SN_netscape_cert_type           "nsCertType"
#  define LN_netscape_cert_type           "Netscape Cert Type"
#  define NID_netscape_cert_type          71
#  define OBJ_netscape_cert_type          OBJ_netscape_cert_extension,1L

#  define SN_netscape_base_url            "nsBaseUrl"
#  define LN_netscape_base_url            "Netscape Base Url"
#  define NID_netscape_base_url           72
#  define OBJ_netscape_base_url           OBJ_netscape_cert_extension,2L

#  define SN_netscape_revocation_url      "nsRevocationUrl"
#  define LN_netscape_revocation_url      "Netscape Revocation Url"
#  define NID_netscape_revocation_url     73
#  define OBJ_netscape_revocation_url     OBJ_netscape_cert_extension,3L

#  define SN_netscape_ca_revocation_url   "nsCaRevocationUrl"
#  define LN_netscape_ca_revocation_url   "Netscape CA Revocation Url"
#  define NID_netscape_ca_revocation_url  74
#  define OBJ_netscape_ca_revocation_url  OBJ_netscape_cert_extension,4L

#  define SN_netscape_renewal_url         "nsRenewalUrl"
#  define LN_netscape_renewal_url         "Netscape Renewal Url"
#  define NID_netscape_renewal_url        75
#  define OBJ_netscape_renewal_url        OBJ_netscape_cert_extension,7L

#  define SN_netscape_ca_policy_url       "nsCaPolicyUrl"
#  define LN_netscape_ca_policy_url       "Netscape CA Policy Url"
#  define NID_netscape_ca_policy_url      76
#  define OBJ_netscape_ca_policy_url      OBJ_netscape_cert_extension,8L

#  define SN_netscape_ssl_server_name     "nsSslServerName"
#  define LN_netscape_ssl_server_name     "Netscape SSL Server Name"
#  define NID_netscape_ssl_server_name    77
#  define OBJ_netscape_ssl_server_name    OBJ_netscape_cert_extension,12L

#  define SN_netscape_comment             "nsComment"
#  define LN_netscape_comment             "Netscape Comment"
#  define NID_netscape_comment            78
#  define OBJ_netscape_comment            OBJ_netscape_cert_extension,13L

#  define SN_netscape_cert_sequence       "nsCertSequence"
#  define LN_netscape_cert_sequence       "Netscape Certificate Sequence"
#  define NID_netscape_cert_sequence      79
#  define OBJ_netscape_cert_sequence      OBJ_netscape_data_type,5L

#  define SN_desx_cbc                     "DESX-CBC"
#  define LN_desx_cbc                     "desx-cbc"
#  define NID_desx_cbc                    80

#  define SN_id_ce                        "id-ce"
#  define NID_id_ce                       81
#  define OBJ_id_ce                       2L,5L,29L

#  define SN_subject_key_identifier       "subjectKeyIdentifier"
#  define LN_subject_key_identifier       "X509v3 Subject Key Identifier"
#  define NID_subject_key_identifier      82
#  define OBJ_subject_key_identifier      OBJ_id_ce,14L

#  define SN_key_usage                    "keyUsage"
#  define LN_key_usage                    "X509v3 Key Usage"
#  define NID_key_usage                   83
#  define OBJ_key_usage                   OBJ_id_ce,15L

#  define SN_private_key_usage_period     "privateKeyUsagePeriod"
#  define LN_private_key_usage_period     "X509v3 Private Key Usage Period"
#  define NID_private_key_usage_period    84
#  define OBJ_private_key_usage_period    OBJ_id_ce,16L

#  define SN_subject_alt_name             "subjectAltName"
#  define LN_subject_alt_name             "X509v3 Subject Alternative Name"
#  define NID_subject_alt_name            85
#  define OBJ_subject_alt_name            OBJ_id_ce,17L

#  define SN_issuer_alt_name              "issuerAltName"
#  define LN_issuer_alt_name              "X509v3 Issuer Alternative Name"
#  define NID_issuer_alt_name             86
#  define OBJ_issuer_alt_name             OBJ_id_ce,18L

#  define SN_basic_constraints            "basicConstraints"
#  define LN_basic_constraints            "X509v3 Basic Constraints"
#  define NID_basic_constraints           87
#  define OBJ_basic_constraints           OBJ_id_ce,19L

#  define SN_crl_number                   "crlNumber"
#  define LN_crl_number                   "X509v3 CRL Number"
#  define NID_crl_number                  88
#  define OBJ_crl_number                  OBJ_id_ce,20L

#  define SN_certificate_policies         "certificatePolicies"
#  define LN_certificate_policies         "X509v3 Certificate Policies"
#  define NID_certificate_policies        89
#  define OBJ_certificate_policies        OBJ_id_ce,32L

#  define SN_authority_key_identifier     "authorityKeyIdentifier"
#  define LN_authority_key_identifier     "X509v3 Authority Key Identifier"
#  define NID_authority_key_identifier    90
#  define OBJ_authority_key_identifier    OBJ_id_ce,35L

#  define SN_bf_cbc                       "BF-CBC"
#  define LN_bf_cbc                       "bf-cbc"
#  define NID_bf_cbc                      91
#  define OBJ_bf_cbc                      1L,3L,6L,1L,4L,1L,3029L,1L,2L

#  define SN_bf_ecb                       "BF-ECB"
#  define LN_bf_ecb                       "bf-ecb"
#  define NID_bf_ecb                      92

#  define SN_bf_cfb64                     "BF-CFB"
#  define LN_bf_cfb64                     "bf-cfb"
#  define NID_bf_cfb64                    93

#  define SN_bf_ofb64                     "BF-OFB"
#  define LN_bf_ofb64                     "bf-ofb"
#  define NID_bf_ofb64                    94

#  define SN_mdc2                         "MDC2"
#  define LN_mdc2                         "mdc2"
#  define NID_mdc2                        95
#  define OBJ_mdc2                        2L,5L,8L,3L,101L
/* An alternative?                      1L,3L,14L,3L,2L,19L */

#  define SN_mdc2WithRSA                  "RSA-MDC2"
#  define LN_mdc2WithRSA                  "mdc2withRSA"
#  define NID_mdc2WithRSA                 96
#  define OBJ_mdc2WithRSA                 2L,5L,8L,3L,100L

#  define SN_rc4_40                       "RC4-40"
#  define LN_rc4_40                       "rc4-40"
#  define NID_rc4_40                      97

#  define SN_rc2_40_cbc                   "RC2-40-CBC"
#  define LN_rc2_40_cbc                   "rc2-40-cbc"
#  define NID_rc2_40_cbc                  98

#  define SN_givenName                    "G"
#  define LN_givenName                    "givenName"
#  define NID_givenName                   99
#  define OBJ_givenName                   OBJ_X509,42L

#  define SN_surname                      "S"
#  define LN_surname                      "surname"
#  define NID_surname                     100
#  define OBJ_surname                     OBJ_X509,4L

#  define SN_initials                     "I"
#  define LN_initials                     "initials"
#  define NID_initials                    101
#  define OBJ_initials                    OBJ_X509,43L

#  define SN_uniqueIdentifier             "UID"
#  define LN_uniqueIdentifier             "uniqueIdentifier"
#  define NID_uniqueIdentifier            102
#  define OBJ_uniqueIdentifier            OBJ_X509,45L

#  define SN_crl_distribution_points      "crlDistributionPoints"
#  define LN_crl_distribution_points      "X509v3 CRL Distribution Points"
#  define NID_crl_distribution_points     103
#  define OBJ_crl_distribution_points     OBJ_id_ce,31L

#  define SN_md5WithRSA                   "RSA-NP-MD5"
#  define LN_md5WithRSA                   "md5WithRSA"
#  define NID_md5WithRSA                  104
#  define OBJ_md5WithRSA                  OBJ_algorithm,3L

#  define SN_serialNumber                 "SN"
#  define LN_serialNumber                 "serialNumber"
#  define NID_serialNumber                105
#  define OBJ_serialNumber                OBJ_X509,5L

#  define SN_title                        "T"
#  define LN_title                        "title"
#  define NID_title                       106
#  define OBJ_title                       OBJ_X509,12L

#  define SN_description                  "D"
#  define LN_description                  "description"
#  define NID_description                 107
#  define OBJ_description                 OBJ_X509,13L

/* CAST5 is CAST-128, I'm just sticking with the documentation */
#  define SN_cast5_cbc                    "CAST5-CBC"
#  define LN_cast5_cbc                    "cast5-cbc"
#  define NID_cast5_cbc                   108
#  define OBJ_cast5_cbc                   1L,2L,840L,113533L,7L,66L,10L

#  define SN_cast5_ecb                    "CAST5-ECB"
#  define LN_cast5_ecb                    "cast5-ecb"
#  define NID_cast5_ecb                   109

#  define SN_cast5_cfb64                  "CAST5-CFB"
#  define LN_cast5_cfb64                  "cast5-cfb"
#  define NID_cast5_cfb64                 110

#  define SN_cast5_ofb64                  "CAST5-OFB"
#  define LN_cast5_ofb64                  "cast5-ofb"
#  define NID_cast5_ofb64                 111

#  define LN_pbeWithMD5AndCast5_CBC       "pbeWithMD5AndCast5CBC"
#  define NID_pbeWithMD5AndCast5_CBC      112
#  define OBJ_pbeWithMD5AndCast5_CBC      1L,2L,840L,113533L,7L,66L,12L

/*-
 * This is one sun will soon be using :-(
 * id-dsa-with-sha1 ID  ::= {
 *   iso(1) member-body(2) us(840) x9-57 (10040) x9cm(4) 3 }
 */
#  define SN_dsaWithSHA1                  "DSA-SHA1"
#  define LN_dsaWithSHA1                  "dsaWithSHA1"
#  define NID_dsaWithSHA1                 113
#  define OBJ_dsaWithSHA1                 1L,2L,840L,10040L,4L,3L

#  define NID_md5_sha1                    114
#  define SN_md5_sha1                     "MD5-SHA1"
#  define LN_md5_sha1                     "md5-sha1"

#  define SN_sha1WithRSA                  "RSA-SHA1-2"
#  define LN_sha1WithRSA                  "sha1WithRSA"
#  define NID_sha1WithRSA                 115
#  define OBJ_sha1WithRSA                 OBJ_algorithm,29L

#  define SN_dsa                          "DSA"
#  define LN_dsa                          "dsaEncryption"
#  define NID_dsa                         116
#  define OBJ_dsa                         1L,2L,840L,10040L,4L,1L

#  define SN_ripemd160                    "RIPEMD160"
#  define LN_ripemd160                    "ripemd160"
#  define NID_ripemd160                   117
#  define OBJ_ripemd160                   1L,3L,36L,3L,2L,1L

/*
 * The name should actually be rsaSignatureWithripemd160, but I'm going to
 * continue using the convention I'm using with the other ciphers
 */
#  define SN_ripemd160WithRSA             "RSA-RIPEMD160"
#  define LN_ripemd160WithRSA             "ripemd160WithRSA"
#  define NID_ripemd160WithRSA            119
#  define OBJ_ripemd160WithRSA            1L,3L,36L,3L,3L,1L,2L

/*-
 * Taken from rfc2040
 *  RC5_CBC_Parameters ::= SEQUENCE {
 *      version           INTEGER (v1_0(16)),
 *      rounds            INTEGER (8..127),
 *      blockSizeInBits   INTEGER (64, 128),
 *      iv                OCTET STRING OPTIONAL
 *      }
 */
#  define SN_rc5_cbc                      "RC5-CBC"
#  define LN_rc5_cbc                      "rc5-cbc"
#  define NID_rc5_cbc                     120
#  define OBJ_rc5_cbc                     OBJ_rsadsi,3L,8L

#  define SN_rc5_ecb                      "RC5-ECB"
#  define LN_rc5_ecb                      "rc5-ecb"
#  define NID_rc5_ecb                     121

#  define SN_rc5_cfb64                    "RC5-CFB"
#  define LN_rc5_cfb64                    "rc5-cfb"
#  define NID_rc5_cfb64                   122

#  define SN_rc5_ofb64                    "RC5-OFB"
#  define LN_rc5_ofb64                    "rc5-ofb"
#  define NID_rc5_ofb64                   123

#  define SN_rle_compression              "RLE"
#  define LN_rle_compression              "run length compression"
#  define NID_rle_compression             124
#  define OBJ_rle_compression             1L,1L,1L,1L,666L,1L

#  define SN_zlib_compression             "ZLIB"
#  define LN_zlib_compression             "zlib compression"
#  define NID_zlib_compression            125
#  define OBJ_zlib_compression            1L,1L,1L,1L,666L,2L

#  define SN_ext_key_usage                "extendedKeyUsage"
#  define LN_ext_key_usage                "X509v3 Extended Key Usage"
#  define NID_ext_key_usage               126
#  define OBJ_ext_key_usage               OBJ_id_ce,37

#  define SN_id_pkix                      "PKIX"
#  define NID_id_pkix                     127
#  define OBJ_id_pkix                     1L,3L,6L,1L,5L,5L,7L

#  define SN_id_kp                        "id-kp"
#  define NID_id_kp                       128
#  define OBJ_id_kp                       OBJ_id_pkix,3L

/* PKIX extended key usage OIDs */

#  define SN_server_auth                  "serverAuth"
#  define LN_server_auth                  "TLS Web Server Authentication"
#  define NID_server_auth                 129
#  define OBJ_server_auth                 OBJ_id_kp,1L

#  define SN_client_auth                  "clientAuth"
#  define LN_client_auth                  "TLS Web Client Authentication"
#  define NID_client_auth                 130
#  define OBJ_client_auth                 OBJ_id_kp,2L

#  define SN_code_sign                    "codeSigning"
#  define LN_code_sign                    "Code Signing"
#  define NID_code_sign                   131
#  define OBJ_code_sign                   OBJ_id_kp,3L

#  define SN_email_protect                "emailProtection"
#  define LN_email_protect                "E-mail Protection"
#  define NID_email_protect               132
#  define OBJ_email_protect               OBJ_id_kp,4L

#  define SN_time_stamp                   "timeStamping"
#  define LN_time_stamp                   "Time Stamping"
#  define NID_time_stamp                  133
#  define OBJ_time_stamp                  OBJ_id_kp,8L

/* Additional extended key usage OIDs: Microsoft */

#  define SN_ms_code_ind                  "msCodeInd"
#  define LN_ms_code_ind                  "Microsoft Individual Code Signing"
#  define NID_ms_code_ind                 134
#  define OBJ_ms_code_ind                 1L,3L,6L,1L,4L,1L,311L,2L,1L,21L

#  define SN_ms_code_com                  "msCodeCom"
#  define LN_ms_code_com                  "Microsoft Commercial Code Signing"
#  define NID_ms_code_com                 135
#  define OBJ_ms_code_com                 1L,3L,6L,1L,4L,1L,311L,2L,1L,22L

#  define SN_ms_ctl_sign                  "msCTLSign"
#  define LN_ms_ctl_sign                  "Microsoft Trust List Signing"
#  define NID_ms_ctl_sign                 136
#  define OBJ_ms_ctl_sign                 1L,3L,6L,1L,4L,1L,311L,10L,3L,1L

#  define SN_ms_sgc                       "msSGC"
#  define LN_ms_sgc                       "Microsoft Server Gated Crypto"
#  define NID_ms_sgc                      137
#  define OBJ_ms_sgc                      1L,3L,6L,1L,4L,1L,311L,10L,3L,3L

#  define SN_ms_efs                       "msEFS"
#  define LN_ms_efs                       "Microsoft Encrypted File System"
#  define NID_ms_efs                      138
#  define OBJ_ms_efs                      1L,3L,6L,1L,4L,1L,311L,10L,3L,4L

/* Additional usage: Netscape */

#  define SN_ns_sgc                       "nsSGC"
#  define LN_ns_sgc                       "Netscape Server Gated Crypto"
#  define NID_ns_sgc                      139
#  define OBJ_ns_sgc                      OBJ_netscape,4L,1L

#  define SN_delta_crl                    "deltaCRL"
#  define LN_delta_crl                    "X509v3 Delta CRL Indicator"
#  define NID_delta_crl                   140
#  define OBJ_delta_crl                   OBJ_id_ce,27L

#  define SN_crl_reason                   "CRLReason"
#  define LN_crl_reason                   "CRL Reason Code"
#  define NID_crl_reason                  141
#  define OBJ_crl_reason                  OBJ_id_ce,21L

#  define SN_invalidity_date              "invalidityDate"
#  define LN_invalidity_date              "Invalidity Date"
#  define NID_invalidity_date             142
#  define OBJ_invalidity_date             OBJ_id_ce,24L

#  define SN_sxnet                        "SXNetID"
#  define LN_sxnet                        "Strong Extranet ID"
#  define NID_sxnet                       143
#  define OBJ_sxnet                       1L,3L,101L,1L,4L,1L

/* PKCS12 and related OBJECT IDENTIFIERS */

#  define OBJ_pkcs12                      OBJ_pkcs,12L
#  define OBJ_pkcs12_pbeids               OBJ_pkcs12, 1

#  define SN_pbe_WithSHA1And128BitRC4     "PBE-SHA1-RC4-128"
#  define LN_pbe_WithSHA1And128BitRC4     "pbeWithSHA1And128BitRC4"
#  define NID_pbe_WithSHA1And128BitRC4    144
#  define OBJ_pbe_WithSHA1And128BitRC4    OBJ_pkcs12_pbeids, 1L

#  define SN_pbe_WithSHA1And40BitRC4      "PBE-SHA1-RC4-40"
#  define LN_pbe_WithSHA1And40BitRC4      "pbeWithSHA1And40BitRC4"
#  define NID_pbe_WithSHA1And40BitRC4     145
#  define OBJ_pbe_WithSHA1And40BitRC4     OBJ_pkcs12_pbeids, 2L

#  define SN_pbe_WithSHA1And3_Key_TripleDES_CBC   "PBE-SHA1-3DES"
#  define LN_pbe_WithSHA1And3_Key_TripleDES_CBC   "pbeWithSHA1And3-KeyTripleDES-CBC"
#  define NID_pbe_WithSHA1And3_Key_TripleDES_CBC  146
#  define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC  OBJ_pkcs12_pbeids, 3L

#  define SN_pbe_WithSHA1And2_Key_TripleDES_CBC   "PBE-SHA1-2DES"
#  define LN_pbe_WithSHA1And2_Key_TripleDES_CBC   "pbeWithSHA1And2-KeyTripleDES-CBC"
#  define NID_pbe_WithSHA1And2_Key_TripleDES_CBC  147
#  define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC  OBJ_pkcs12_pbeids, 4L

#  define SN_pbe_WithSHA1And128BitRC2_CBC         "PBE-SHA1-RC2-128"
#  define LN_pbe_WithSHA1And128BitRC2_CBC         "pbeWithSHA1And128BitRC2-CBC"
#  define NID_pbe_WithSHA1And128BitRC2_CBC        148
#  define OBJ_pbe_WithSHA1And128BitRC2_CBC        OBJ_pkcs12_pbeids, 5L

#  define SN_pbe_WithSHA1And40BitRC2_CBC  "PBE-SHA1-RC2-40"
#  define LN_pbe_WithSHA1And40BitRC2_CBC  "pbeWithSHA1And40BitRC2-CBC"
#  define NID_pbe_WithSHA1And40BitRC2_CBC 149
#  define OBJ_pbe_WithSHA1And40BitRC2_CBC OBJ_pkcs12_pbeids, 6L

#  define OBJ_pkcs12_Version1     OBJ_pkcs12, 10L

#  define OBJ_pkcs12_BagIds       OBJ_pkcs12_Version1, 1L

#  define LN_keyBag               "keyBag"
#  define NID_keyBag              150
#  define OBJ_keyBag              OBJ_pkcs12_BagIds, 1L

#  define LN_pkcs8ShroudedKeyBag  "pkcs8ShroudedKeyBag"
#  define NID_pkcs8ShroudedKeyBag 151
#  define OBJ_pkcs8ShroudedKeyBag OBJ_pkcs12_BagIds, 2L

#  define LN_certBag              "certBag"
#  define NID_certBag             152
#  define OBJ_certBag             OBJ_pkcs12_BagIds, 3L

#  define LN_crlBag               "crlBag"
#  define NID_crlBag              153
#  define OBJ_crlBag              OBJ_pkcs12_BagIds, 4L

#  define LN_secretBag            "secretBag"
#  define NID_secretBag           154
#  define OBJ_secretBag           OBJ_pkcs12_BagIds, 5L

#  define LN_safeContentsBag      "safeContentsBag"
#  define NID_safeContentsBag     155
#  define OBJ_safeContentsBag     OBJ_pkcs12_BagIds, 6L

#  define LN_friendlyName         "friendlyName"
#  define NID_friendlyName        156
#  define OBJ_friendlyName        OBJ_pkcs9, 20L

#  define LN_localKeyID           "localKeyID"
#  define NID_localKeyID          157
#  define OBJ_localKeyID          OBJ_pkcs9, 21L

#  define OBJ_certTypes           OBJ_pkcs9, 22L

#  define LN_x509Certificate      "x509Certificate"
#  define NID_x509Certificate     158
#  define OBJ_x509Certificate     OBJ_certTypes, 1L

#  define LN_sdsiCertificate      "sdsiCertificate"
#  define NID_sdsiCertificate     159
#  define OBJ_sdsiCertificate     OBJ_certTypes, 2L

#  define OBJ_crlTypes            OBJ_pkcs9, 23L

#  define LN_x509Crl              "x509Crl"
#  define NID_x509Crl             160
#  define OBJ_x509Crl             OBJ_crlTypes, 1L

/* PKCS#5 v2 OIDs */

#  define LN_pbes2                "PBES2"
#  define NID_pbes2               161
#  define OBJ_pbes2               OBJ_pkcs,5L,13L

#  define LN_pbmac1               "PBMAC1"
#  define NID_pbmac1              162
#  define OBJ_pbmac1              OBJ_pkcs,5L,14L

#  define LN_hmacWithSHA1         "hmacWithSHA1"
#  define NID_hmacWithSHA1        163
#  define OBJ_hmacWithSHA1        OBJ_rsadsi,2L,7L

/* Policy Qualifier Ids */

#  define LN_id_qt_cps            "Policy Qualifier CPS"
#  define SN_id_qt_cps            "id-qt-cps"
#  define NID_id_qt_cps           164
#  define OBJ_id_qt_cps           OBJ_id_pkix,2L,1L

#  define LN_id_qt_unotice        "Policy Qualifier User Notice"
#  define SN_id_qt_unotice        "id-qt-unotice"
#  define NID_id_qt_unotice       165
#  define OBJ_id_qt_unotice       OBJ_id_pkix,2L,2L

#  define SN_rc2_64_cbc                   "RC2-64-CBC"
#  define LN_rc2_64_cbc                   "rc2-64-cbc"
#  define NID_rc2_64_cbc                  166

#  define SN_SMIMECapabilities            "SMIME-CAPS"
#  define LN_SMIMECapabilities            "S/MIME Capabilities"
#  define NID_SMIMECapabilities           167
#  define OBJ_SMIMECapabilities           OBJ_pkcs9,15L

#  define SN_pbeWithMD2AndRC2_CBC         "PBE-MD2-RC2-64"
#  define LN_pbeWithMD2AndRC2_CBC         "pbeWithMD2AndRC2-CBC"
#  define NID_pbeWithMD2AndRC2_CBC        168
#  define OBJ_pbeWithMD2AndRC2_CBC        OBJ_pkcs,5L,4L

#  define SN_pbeWithMD5AndRC2_CBC         "PBE-MD5-RC2-64"
#  define LN_pbeWithMD5AndRC2_CBC         "pbeWithMD5AndRC2-CBC"
#  define NID_pbeWithMD5AndRC2_CBC        169
#  define OBJ_pbeWithMD5AndRC2_CBC        OBJ_pkcs,5L,6L

#  define SN_pbeWithSHA1AndDES_CBC        "PBE-SHA1-DES"
#  define LN_pbeWithSHA1AndDES_CBC        "pbeWithSHA1AndDES-CBC"
#  define NID_pbeWithSHA1AndDES_CBC       170
#  define OBJ_pbeWithSHA1AndDES_CBC       OBJ_pkcs,5L,10L

/* Extension request OIDs */

#  define LN_ms_ext_req                   "Microsoft Extension Request"
#  define SN_ms_ext_req                   "msExtReq"
#  define NID_ms_ext_req                  171
#  define OBJ_ms_ext_req                  1L,3L,6L,1L,4L,1L,311L,2L,1L,14L

#  define LN_ext_req                      "Extension Request"
#  define SN_ext_req                      "extReq"
#  define NID_ext_req                     172
#  define OBJ_ext_req                     OBJ_pkcs9,14L

#  define SN_name                         "name"
#  define LN_name                         "name"
#  define NID_name                        173
#  define OBJ_name                        OBJ_X509,41L

#  define SN_dnQualifier                  "dnQualifier"
#  define LN_dnQualifier                  "dnQualifier"
#  define NID_dnQualifier                 174
#  define OBJ_dnQualifier                 OBJ_X509,46L

#  define SN_id_pe                        "id-pe"
#  define NID_id_pe                       175
#  define OBJ_id_pe                       OBJ_id_pkix,1L

#  define SN_id_ad                        "id-ad"
#  define NID_id_ad                       176
#  define OBJ_id_ad                       OBJ_id_pkix,48L

#  define SN_info_access                  "authorityInfoAccess"
#  define LN_info_access                  "Authority Information Access"
#  define NID_info_access                 177
#  define OBJ_info_access                 OBJ_id_pe,1L

#  define SN_ad_OCSP                      "OCSP"
#  define LN_ad_OCSP                      "OCSP"
#  define NID_ad_OCSP                     178
#  define OBJ_ad_OCSP                     OBJ_id_ad,1L

#  define SN_ad_ca_issuers                "caIssuers"
#  define LN_ad_ca_issuers                "CA Issuers"
#  define NID_ad_ca_issuers               179
#  define OBJ_ad_ca_issuers               OBJ_id_ad,2L

#  define SN_OCSP_sign                    "OCSPSigning"
#  define LN_OCSP_sign                    "OCSP Signing"
#  define NID_OCSP_sign                   180
#  define OBJ_OCSP_sign                   OBJ_id_kp,9L
# endif                         /* USE_OBJ_MAC */

# include <openssl/bio.h>
# include <openssl/asn1.h>

# define OBJ_NAME_TYPE_UNDEF             0x00
# define OBJ_NAME_TYPE_MD_METH           0x01
# define OBJ_NAME_TYPE_CIPHER_METH       0x02
# define OBJ_NAME_TYPE_PKEY_METH         0x03
# define OBJ_NAME_TYPE_COMP_METH         0x04
# define OBJ_NAME_TYPE_NUM               0x05

# define OBJ_NAME_ALIAS                  0x8000

# define OBJ_BSEARCH_VALUE_ON_NOMATCH            0x01
# define OBJ_BSEARCH_FIRST_VALUE_ON_MATCH        0x02


#ifdef  __cplusplus
extern "C" {
#endif

typedef struct obj_name_st {
    int type;
    int alias;
    const char *name;
    const char *data;
} OBJ_NAME;

# define         OBJ_create_and_add_object(a,b,c) OBJ_create(a,b,c)

int OBJ_NAME_init(void);
int OBJ_NAME_new_index(unsigned long (*hash_func) (const char *),
                       int (*cmp_func) (const char *, const char *),
                       void (*free_func) (const char *, int, const char *));
const char *OBJ_NAME_get(const char *name, int type);
int OBJ_NAME_add(const char *name, int type, const char *data);
int OBJ_NAME_remove(const char *name, int type);
void OBJ_NAME_cleanup(int type); /* -1 for everything */
void OBJ_NAME_do_all(int type, void (*fn) (const OBJ_NAME *, void *arg),
                     void *arg);
void OBJ_NAME_do_all_sorted(int type,
                            void (*fn) (const OBJ_NAME *, void *arg),
                            void *arg);

ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o);
ASN1_OBJECT *OBJ_nid2obj(int n);
const char *OBJ_nid2ln(int n);
const char *OBJ_nid2sn(int n);
int OBJ_obj2nid(const ASN1_OBJECT *o);
ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name);
int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name);
int OBJ_txt2nid(const char *s);
int OBJ_ln2nid(const char *s);
int OBJ_sn2nid(const char *s);
int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b);
const void *OBJ_bsearch_(const void *key, const void *base, int num, int size,
                         int (*cmp) (const void *, const void *));
const void *OBJ_bsearch_ex_(const void *key, const void *base, int num,
                            int size,
                            int (*cmp) (const void *, const void *),
                            int flags);

# define _DECLARE_OBJ_BSEARCH_CMP_FN(scope, type1, type2, nm)    \
  static int nm##_cmp_BSEARCH_CMP_FN(const void *, const void *); \
  static int nm##_cmp(type1 const *, type2 const *); \
  scope type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num)

# define DECLARE_OBJ_BSEARCH_CMP_FN(type1, type2, cmp)   \
  _DECLARE_OBJ_BSEARCH_CMP_FN(static, type1, type2, cmp)
# define DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm)     \
  type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num)

/*-
 * Unsolved problem: if a type is actually a pointer type, like
 * nid_triple is, then its impossible to get a const where you need
 * it. Consider:
 *
 * typedef int nid_triple[3];
 * const void *a_;
 * const nid_triple const *a = a_;
 *
 * The assignement discards a const because what you really want is:
 *
 * const int const * const *a = a_;
 *
 * But if you do that, you lose the fact that a is an array of 3 ints,
 * which breaks comparison functions.
 *
 * Thus we end up having to cast, sadly, or unpack the
 * declarations. Or, as I finally did in this case, delcare nid_triple
 * to be a struct, which it should have been in the first place.
 *
 * Ben, August 2008.
 *
 * Also, strictly speaking not all types need be const, but handling
 * the non-constness means a lot of complication, and in practice
 * comparison routines do always not touch their arguments.
 */

# define IMPLEMENT_OBJ_BSEARCH_CMP_FN(type1, type2, nm)  \
  static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_)    \
      { \
      type1 const *a = a_; \
      type2 const *b = b_; \
      return nm##_cmp(a,b); \
      } \
  static type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \
      { \
      return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \
                                        nm##_cmp_BSEARCH_CMP_FN); \
      } \
      extern void dummy_prototype(void)

# define IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm)   \
  static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_)    \
      { \
      type1 const *a = a_; \
      type2 const *b = b_; \
      return nm##_cmp(a,b); \
      } \
  type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \
      { \
      return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \
                                        nm##_cmp_BSEARCH_CMP_FN); \
      } \
      extern void dummy_prototype(void)

# define OBJ_bsearch(type1,key,type2,base,num,cmp)                              \
  ((type2 *)OBJ_bsearch_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \
                         num,sizeof(type2),                             \
                         ((void)CHECKED_PTR_OF(type1,cmp##_type_1),     \
                          (void)CHECKED_PTR_OF(type2,cmp##_type_2),     \
                          cmp##_BSEARCH_CMP_FN)))

# define OBJ_bsearch_ex(type1,key,type2,base,num,cmp,flags)                      \
  ((type2 *)OBJ_bsearch_ex_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \
                         num,sizeof(type2),                             \
                         ((void)CHECKED_PTR_OF(type1,cmp##_type_1),     \
                          (void)type_2=CHECKED_PTR_OF(type2,cmp##_type_2), \
                          cmp##_BSEARCH_CMP_FN)),flags)

int OBJ_new_nid(int num);
int OBJ_add_object(const ASN1_OBJECT *obj);
int OBJ_create(const char *oid, const char *sn, const char *ln);
void OBJ_cleanup(void);
int OBJ_create_objects(BIO *in);

int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid);
int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid);
int OBJ_add_sigid(int signid, int dig_id, int pkey_id);
void OBJ_sigid_free(void);

extern int obj_cleanup_defer;
void check_defer(int nid);

/* BEGIN ERROR CODES */
/*
 * The following lines are auto generated by the script mkerr.pl. Any changes
 * made after this point may be overwritten when the script is next run.
 */
void ERR_load_OBJ_strings(void);

/* Error codes for the OBJ functions. */

/* Function codes. */
# define OBJ_F_OBJ_ADD_OBJECT                             105
# define OBJ_F_OBJ_CREATE                                 100
# define OBJ_F_OBJ_DUP                                    101
# define OBJ_F_OBJ_NAME_NEW_INDEX                         106
# define OBJ_F_OBJ_NID2LN                                 102
# define OBJ_F_OBJ_NID2OBJ                                103
# define OBJ_F_OBJ_NID2SN                                 104

/* Reason codes. */
# define OBJ_R_MALLOC_FAILURE                             100
# define OBJ_R_UNKNOWN_NID                                101

#ifdef  __cplusplus
}
#endif
#endif
openssl/ssl.h000064400000443515151733316610007223 0ustar00/* ssl/ssl.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */
/* ====================================================================
 * Copyright (c) 1998-2018 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */
/* ====================================================================
 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
 * ECC cipher suite support in OpenSSL originally developed by
 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
 */
/* ====================================================================
 * Copyright 2005 Nokia. All rights reserved.
 *
 * The portions of the attached software ("Contribution") is developed by
 * Nokia Corporation and is licensed pursuant to the OpenSSL open source
 * license.
 *
 * The Contribution, originally written by Mika Kousa and Pasi Eronen of
 * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
 * support (see RFC 4279) to OpenSSL.
 *
 * No patent licenses or other rights except those expressly stated in
 * the OpenSSL open source license shall be deemed granted or received
 * expressly, by implication, estoppel, or otherwise.
 *
 * No assurances are provided by Nokia that the Contribution does not
 * infringe the patent or other intellectual property rights of any third
 * party or that the license provides you with all the necessary rights
 * to make use of the Contribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
 * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
 * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
 * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
 * OTHERWISE.
 */

#ifndef HEADER_SSL_H
# define HEADER_SSL_H

# include <openssl/e_os2.h>

# ifndef OPENSSL_NO_COMP
#  include <openssl/comp.h>
# endif
# ifndef OPENSSL_NO_BIO
#  include <openssl/bio.h>
# endif
# ifndef OPENSSL_NO_DEPRECATED
#  ifndef OPENSSL_NO_X509
#   include <openssl/x509.h>
#  endif
#  include <openssl/crypto.h>
#  include <openssl/lhash.h>
#  include <openssl/buffer.h>
# endif
# include <openssl/pem.h>
# include <openssl/hmac.h>

# include <openssl/kssl.h>
# include <openssl/safestack.h>
# include <openssl/symhacks.h>

#ifdef  __cplusplus
extern "C" {
#endif

/* SSLeay version number for ASN.1 encoding of the session information */
/*-
 * Version 0 - initial version
 * Version 1 - added the optional peer certificate
 */
# define SSL_SESSION_ASN1_VERSION 0x0001

/* text strings for the ciphers */
# define SSL_TXT_NULL_WITH_MD5           SSL2_TXT_NULL_WITH_MD5
# define SSL_TXT_RC4_128_WITH_MD5        SSL2_TXT_RC4_128_WITH_MD5
# define SSL_TXT_RC4_128_EXPORT40_WITH_MD5 SSL2_TXT_RC4_128_EXPORT40_WITH_MD5
# define SSL_TXT_RC2_128_CBC_WITH_MD5    SSL2_TXT_RC2_128_CBC_WITH_MD5
# define SSL_TXT_RC2_128_CBC_EXPORT40_WITH_MD5 SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5
# define SSL_TXT_IDEA_128_CBC_WITH_MD5   SSL2_TXT_IDEA_128_CBC_WITH_MD5
# define SSL_TXT_DES_64_CBC_WITH_MD5     SSL2_TXT_DES_64_CBC_WITH_MD5
# define SSL_TXT_DES_64_CBC_WITH_SHA     SSL2_TXT_DES_64_CBC_WITH_SHA
# define SSL_TXT_DES_192_EDE3_CBC_WITH_MD5 SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5
# define SSL_TXT_DES_192_EDE3_CBC_WITH_SHA SSL2_TXT_DES_192_EDE3_CBC_WITH_SHA

/*
 * VRS Additional Kerberos5 entries
 */
# define SSL_TXT_KRB5_DES_64_CBC_SHA   SSL3_TXT_KRB5_DES_64_CBC_SHA
# define SSL_TXT_KRB5_DES_192_CBC3_SHA SSL3_TXT_KRB5_DES_192_CBC3_SHA
# define SSL_TXT_KRB5_RC4_128_SHA      SSL3_TXT_KRB5_RC4_128_SHA
# define SSL_TXT_KRB5_IDEA_128_CBC_SHA SSL3_TXT_KRB5_IDEA_128_CBC_SHA
# define SSL_TXT_KRB5_DES_64_CBC_MD5   SSL3_TXT_KRB5_DES_64_CBC_MD5
# define SSL_TXT_KRB5_DES_192_CBC3_MD5 SSL3_TXT_KRB5_DES_192_CBC3_MD5
# define SSL_TXT_KRB5_RC4_128_MD5      SSL3_TXT_KRB5_RC4_128_MD5
# define SSL_TXT_KRB5_IDEA_128_CBC_MD5 SSL3_TXT_KRB5_IDEA_128_CBC_MD5

# define SSL_TXT_KRB5_DES_40_CBC_SHA   SSL3_TXT_KRB5_DES_40_CBC_SHA
# define SSL_TXT_KRB5_RC2_40_CBC_SHA   SSL3_TXT_KRB5_RC2_40_CBC_SHA
# define SSL_TXT_KRB5_RC4_40_SHA       SSL3_TXT_KRB5_RC4_40_SHA
# define SSL_TXT_KRB5_DES_40_CBC_MD5   SSL3_TXT_KRB5_DES_40_CBC_MD5
# define SSL_TXT_KRB5_RC2_40_CBC_MD5   SSL3_TXT_KRB5_RC2_40_CBC_MD5
# define SSL_TXT_KRB5_RC4_40_MD5       SSL3_TXT_KRB5_RC4_40_MD5

# define SSL_TXT_KRB5_DES_40_CBC_SHA   SSL3_TXT_KRB5_DES_40_CBC_SHA
# define SSL_TXT_KRB5_DES_40_CBC_MD5   SSL3_TXT_KRB5_DES_40_CBC_MD5
# define SSL_TXT_KRB5_DES_64_CBC_SHA   SSL3_TXT_KRB5_DES_64_CBC_SHA
# define SSL_TXT_KRB5_DES_64_CBC_MD5   SSL3_TXT_KRB5_DES_64_CBC_MD5
# define SSL_TXT_KRB5_DES_192_CBC3_SHA SSL3_TXT_KRB5_DES_192_CBC3_SHA
# define SSL_TXT_KRB5_DES_192_CBC3_MD5 SSL3_TXT_KRB5_DES_192_CBC3_MD5
# define SSL_MAX_KRB5_PRINCIPAL_LENGTH  256

# define SSL_MAX_SSL_SESSION_ID_LENGTH           32
# define SSL_MAX_SID_CTX_LENGTH                  32

# define SSL_MIN_RSA_MODULUS_LENGTH_IN_BYTES     (512/8)
# define SSL_MAX_KEY_ARG_LENGTH                  8
# define SSL_MAX_MASTER_KEY_LENGTH               48

/* These are used to specify which ciphers to use and not to use */

# define SSL_TXT_EXP40           "EXPORT40"
# define SSL_TXT_EXP56           "EXPORT56"
# define SSL_TXT_LOW             "LOW"
# define SSL_TXT_MEDIUM          "MEDIUM"
# define SSL_TXT_HIGH            "HIGH"
# define SSL_TXT_FIPS            "FIPS"

# define SSL_TXT_kFZA            "kFZA"/* unused! */
# define SSL_TXT_aFZA            "aFZA"/* unused! */
# define SSL_TXT_eFZA            "eFZA"/* unused! */
# define SSL_TXT_FZA             "FZA"/* unused! */

# define SSL_TXT_aNULL           "aNULL"
# define SSL_TXT_eNULL           "eNULL"
# define SSL_TXT_NULL            "NULL"

# define SSL_TXT_kRSA            "kRSA"
# define SSL_TXT_kDHr            "kDHr"
# define SSL_TXT_kDHd            "kDHd"
# define SSL_TXT_kDH             "kDH"
# define SSL_TXT_kEDH            "kEDH"
# define SSL_TXT_kDHE            "kDHE"/* alias for kEDH */
# define SSL_TXT_kKRB5           "kKRB5"
# define SSL_TXT_kECDHr          "kECDHr"
# define SSL_TXT_kECDHe          "kECDHe"
# define SSL_TXT_kECDH           "kECDH"
# define SSL_TXT_kEECDH          "kEECDH"
# define SSL_TXT_kECDHE          "kECDHE"/* alias for kEECDH */
# define SSL_TXT_kPSK            "kPSK"
# define SSL_TXT_kGOST           "kGOST"
# define SSL_TXT_kSRP            "kSRP"

# define SSL_TXT_aRSA            "aRSA"
# define SSL_TXT_aDSS            "aDSS"
# define SSL_TXT_aDH             "aDH"
# define SSL_TXT_aECDH           "aECDH"
# define SSL_TXT_aKRB5           "aKRB5"
# define SSL_TXT_aECDSA          "aECDSA"
# define SSL_TXT_aPSK            "aPSK"
# define SSL_TXT_aGOST94 "aGOST94"
# define SSL_TXT_aGOST01 "aGOST01"
# define SSL_TXT_aGOST  "aGOST"
# define SSL_TXT_aSRP            "aSRP"

# define SSL_TXT_DSS             "DSS"
# define SSL_TXT_DH              "DH"
# define SSL_TXT_EDH             "EDH"/* same as "kEDH:-ADH" */
# define SSL_TXT_DHE             "DHE"/* alias for EDH */
# define SSL_TXT_ADH             "ADH"
# define SSL_TXT_RSA             "RSA"
# define SSL_TXT_ECDH            "ECDH"
# define SSL_TXT_EECDH           "EECDH"/* same as "kEECDH:-AECDH" */
# define SSL_TXT_ECDHE           "ECDHE"/* alias for ECDHE" */
# define SSL_TXT_AECDH           "AECDH"
# define SSL_TXT_ECDSA           "ECDSA"
# define SSL_TXT_KRB5            "KRB5"
# define SSL_TXT_PSK             "PSK"
# define SSL_TXT_SRP             "SRP"

# define SSL_TXT_DES             "DES"
# define SSL_TXT_3DES            "3DES"
# define SSL_TXT_RC4             "RC4"
# define SSL_TXT_RC2             "RC2"
# define SSL_TXT_IDEA            "IDEA"
# define SSL_TXT_SEED            "SEED"
# define SSL_TXT_AES128          "AES128"
# define SSL_TXT_AES256          "AES256"
# define SSL_TXT_AES             "AES"
# define SSL_TXT_AES_GCM         "AESGCM"
# define SSL_TXT_CAMELLIA128     "CAMELLIA128"
# define SSL_TXT_CAMELLIA256     "CAMELLIA256"
# define SSL_TXT_CAMELLIA        "CAMELLIA"

# define SSL_TXT_MD5             "MD5"
# define SSL_TXT_SHA1            "SHA1"
# define SSL_TXT_SHA             "SHA"/* same as "SHA1" */
# define SSL_TXT_GOST94          "GOST94"
# define SSL_TXT_GOST89MAC               "GOST89MAC"
# define SSL_TXT_SHA256          "SHA256"
# define SSL_TXT_SHA384          "SHA384"

# define SSL_TXT_SSLV2           "SSLv2"
# define SSL_TXT_SSLV3           "SSLv3"
# define SSL_TXT_TLSV1           "TLSv1"
# define SSL_TXT_TLSV1_1         "TLSv1.1"
# define SSL_TXT_TLSV1_2         "TLSv1.2"

# define SSL_TXT_EXP             "EXP"
# define SSL_TXT_EXPORT          "EXPORT"

# define SSL_TXT_ALL             "ALL"

/*-
 * COMPLEMENTOF* definitions. These identifiers are used to (de-select)
 * ciphers normally not being used.
 * Example: "RC4" will activate all ciphers using RC4 including ciphers
 * without authentication, which would normally disabled by DEFAULT (due
 * the "!ADH" being part of default). Therefore "RC4:!COMPLEMENTOFDEFAULT"
 * will make sure that it is also disabled in the specific selection.
 * COMPLEMENTOF* identifiers are portable between version, as adjustments
 * to the default cipher setup will also be included here.
 *
 * COMPLEMENTOFDEFAULT does not experience the same special treatment that
 * DEFAULT gets, as only selection is being done and no sorting as needed
 * for DEFAULT.
 */
# define SSL_TXT_CMPALL          "COMPLEMENTOFALL"
# define SSL_TXT_CMPDEF          "COMPLEMENTOFDEFAULT"

/*
 * The following cipher list is used by default. It also is substituted when
 * an application-defined cipher list string starts with 'DEFAULT'.
 */
# define SSL_DEFAULT_CIPHER_LIST "ALL:!EXPORT:!LOW:!aNULL:!eNULL:!SSLv2"
/*
 * As of OpenSSL 1.0.0, ssl_create_cipher_list() in ssl/ssl_ciph.c always
 * starts with a reasonable order, and all we have to do for DEFAULT is
 * throwing out anonymous and unencrypted ciphersuites! (The latter are not
 * actually enabled by ALL, but "ALL:RSA" would enable some of them.)
 */
# ifdef SYSTEM_CIPHERS_FILE
#  define SSL_SYSTEM_DEFAULT_CIPHER_LIST "PROFILE=SYSTEM"
# else
#  define SSL_SYSTEM_DEFAULT_CIPHER_LIST SSL_DEFAULT_CIPHER_LIST
# endif

/* Used in SSL_set_shutdown()/SSL_get_shutdown(); */
# define SSL_SENT_SHUTDOWN       1
# define SSL_RECEIVED_SHUTDOWN   2

#ifdef __cplusplus
}
#endif

#ifdef  __cplusplus
extern "C" {
#endif

# if (defined(OPENSSL_NO_RSA) || defined(OPENSSL_NO_MD5)) && !defined(OPENSSL_NO_SSL2)
#  define OPENSSL_NO_SSL2
# endif

# define SSL_FILETYPE_ASN1       X509_FILETYPE_ASN1
# define SSL_FILETYPE_PEM        X509_FILETYPE_PEM

/*
 * This is needed to stop compilers complaining about the 'struct ssl_st *'
 * function parameters used to prototype callbacks in SSL_CTX.
 */
typedef struct ssl_st *ssl_crock_st;
typedef struct tls_session_ticket_ext_st TLS_SESSION_TICKET_EXT;
typedef struct ssl_method_st SSL_METHOD;
typedef struct ssl_cipher_st SSL_CIPHER;
typedef struct ssl_session_st SSL_SESSION;
typedef struct tls_sigalgs_st TLS_SIGALGS;
typedef struct ssl_conf_ctx_st SSL_CONF_CTX;

DECLARE_STACK_OF(SSL_CIPHER)

/* SRTP protection profiles for use with the use_srtp extension (RFC 5764)*/
typedef struct srtp_protection_profile_st {
    const char *name;
    unsigned long id;
} SRTP_PROTECTION_PROFILE;

DECLARE_STACK_OF(SRTP_PROTECTION_PROFILE)

typedef int (*tls_session_ticket_ext_cb_fn) (SSL *s,
                                             const unsigned char *data,
                                             int len, void *arg);
typedef int (*tls_session_secret_cb_fn) (SSL *s, void *secret,
                                         int *secret_len,
                                         STACK_OF(SSL_CIPHER) *peer_ciphers,
                                         SSL_CIPHER **cipher, void *arg);

# ifndef OPENSSL_NO_TLSEXT

/* Typedefs for handling custom extensions */

typedef int (*custom_ext_add_cb) (SSL *s, unsigned int ext_type,
                                  const unsigned char **out,
                                  size_t *outlen, int *al, void *add_arg);

typedef void (*custom_ext_free_cb) (SSL *s, unsigned int ext_type,
                                    const unsigned char *out, void *add_arg);

typedef int (*custom_ext_parse_cb) (SSL *s, unsigned int ext_type,
                                    const unsigned char *in,
                                    size_t inlen, int *al, void *parse_arg);

# endif

# ifndef OPENSSL_NO_SSL_INTERN

/* used to hold info on the particular ciphers used */
struct ssl_cipher_st {
    int valid;
    const char *name;           /* text name */
    unsigned long id;           /* id, 4 bytes, first is version */
    /*
     * changed in 0.9.9: these four used to be portions of a single value
     * 'algorithms'
     */
    unsigned long algorithm_mkey; /* key exchange algorithm */
    unsigned long algorithm_auth; /* server authentication */
    unsigned long algorithm_enc; /* symmetric encryption */
    unsigned long algorithm_mac; /* symmetric authentication */
    unsigned long algorithm_ssl; /* (major) protocol version */
    unsigned long algo_strength; /* strength and export flags */
    unsigned long algorithm2;   /* Extra flags */
    int strength_bits;          /* Number of bits really used */
    int alg_bits;               /* Number of bits for algorithm */
};

/* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */
struct ssl_method_st {
    int version;
    int (*ssl_new) (SSL *s);
    void (*ssl_clear) (SSL *s);
    void (*ssl_free) (SSL *s);
    int (*ssl_accept) (SSL *s);
    int (*ssl_connect) (SSL *s);
    int (*ssl_read) (SSL *s, void *buf, int len);
    int (*ssl_peek) (SSL *s, void *buf, int len);
    int (*ssl_write) (SSL *s, const void *buf, int len);
    int (*ssl_shutdown) (SSL *s);
    int (*ssl_renegotiate) (SSL *s);
    int (*ssl_renegotiate_check) (SSL *s);
    long (*ssl_get_message) (SSL *s, int st1, int stn, int mt, long
                             max, int *ok);
    int (*ssl_read_bytes) (SSL *s, int type, unsigned char *buf, int len,
                           int peek);
    int (*ssl_write_bytes) (SSL *s, int type, const void *buf_, int len);
    int (*ssl_dispatch_alert) (SSL *s);
    long (*ssl_ctrl) (SSL *s, int cmd, long larg, void *parg);
    long (*ssl_ctx_ctrl) (SSL_CTX *ctx, int cmd, long larg, void *parg);
    const SSL_CIPHER *(*get_cipher_by_char) (const unsigned char *ptr);
    int (*put_cipher_by_char) (const SSL_CIPHER *cipher, unsigned char *ptr);
    int (*ssl_pending) (const SSL *s);
    int (*num_ciphers) (void);
    const SSL_CIPHER *(*get_cipher) (unsigned ncipher);
    const struct ssl_method_st *(*get_ssl_method) (int version);
    long (*get_timeout) (void);
    struct ssl3_enc_method *ssl3_enc; /* Extra SSLv3/TLS stuff */
    int (*ssl_version) (void);
    long (*ssl_callback_ctrl) (SSL *s, int cb_id, void (*fp) (void));
    long (*ssl_ctx_callback_ctrl) (SSL_CTX *s, int cb_id, void (*fp) (void));
};

/*-
 * Lets make this into an ASN.1 type structure as follows
 * SSL_SESSION_ID ::= SEQUENCE {
 *      version                 INTEGER,        -- structure version number
 *      SSLversion              INTEGER,        -- SSL version number
 *      Cipher                  OCTET STRING,   -- the 3 byte cipher ID
 *      Session_ID              OCTET STRING,   -- the Session ID
 *      Master_key              OCTET STRING,   -- the master key
 *      KRB5_principal          OCTET STRING    -- optional Kerberos principal
 *      Key_Arg [ 0 ] IMPLICIT  OCTET STRING,   -- the optional Key argument
 *      Time [ 1 ] EXPLICIT     INTEGER,        -- optional Start Time
 *      Timeout [ 2 ] EXPLICIT  INTEGER,        -- optional Timeout ins seconds
 *      Peer [ 3 ] EXPLICIT     X509,           -- optional Peer Certificate
 *      Session_ID_context [ 4 ] EXPLICIT OCTET STRING,   -- the Session ID context
 *      Verify_result [ 5 ] EXPLICIT INTEGER,   -- X509_V_... code for `Peer'
 *      HostName [ 6 ] EXPLICIT OCTET STRING,   -- optional HostName from servername TLS extension
 *      PSK_identity_hint [ 7 ] EXPLICIT OCTET STRING, -- optional PSK identity hint
 *      PSK_identity [ 8 ] EXPLICIT OCTET STRING,  -- optional PSK identity
 *      Ticket_lifetime_hint [9] EXPLICIT INTEGER, -- server's lifetime hint for session ticket
 *      Ticket [10]             EXPLICIT OCTET STRING, -- session ticket (clients only)
 *      Compression_meth [11]   EXPLICIT OCTET STRING, -- optional compression method
 *      SRP_username [ 12 ] EXPLICIT OCTET STRING -- optional SRP username
 *      }
 * Look in ssl/ssl_asn1.c for more details
 * I'm using EXPLICIT tags so I can read the damn things using asn1parse :-).
 */
struct ssl_session_st {
    int ssl_version;            /* what ssl version session info is being
                                 * kept in here? */
    /* only really used in SSLv2 */
    unsigned int key_arg_length;
    unsigned char key_arg[SSL_MAX_KEY_ARG_LENGTH];
    int master_key_length;
    unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH];
    /* session_id - valid? */
    unsigned int session_id_length;
    unsigned char session_id[SSL_MAX_SSL_SESSION_ID_LENGTH];
    /*
     * this is used to determine whether the session is being reused in the
     * appropriate context. It is up to the application to set this, via
     * SSL_new
     */
    unsigned int sid_ctx_length;
    unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH];
#  ifndef OPENSSL_NO_KRB5
    unsigned int krb5_client_princ_len;
    unsigned char krb5_client_princ[SSL_MAX_KRB5_PRINCIPAL_LENGTH];
#  endif                        /* OPENSSL_NO_KRB5 */
#  ifndef OPENSSL_NO_PSK
    char *psk_identity_hint;
    char *psk_identity;
#  endif
    /*
     * Used to indicate that session resumption is not allowed. Applications
     * can also set this bit for a new session via not_resumable_session_cb
     * to disable session caching and tickets.
     */
    int not_resumable;
    /* The cert is the certificate used to establish this connection */
    struct sess_cert_st /* SESS_CERT */ *sess_cert;
    /*
     * This is the cert for the other end. On clients, it will be the same as
     * sess_cert->peer_key->x509 (the latter is not enough as sess_cert is
     * not retained in the external representation of sessions, see
     * ssl_asn1.c).
     */
    X509 *peer;
    /*
     * when app_verify_callback accepts a session where the peer's
     * certificate is not ok, we must remember the error for session reuse:
     */
    long verify_result;         /* only for servers */
    int references;
    long timeout;
    long time;
    unsigned int compress_meth; /* Need to lookup the method */
    const SSL_CIPHER *cipher;
    unsigned long cipher_id;    /* when ASN.1 loaded, this needs to be used
                                 * to load the 'cipher' structure */
    STACK_OF(SSL_CIPHER) *ciphers; /* ciphers offered by the client */
    CRYPTO_EX_DATA ex_data;     /* application specific data */
    /*
     * These are used to make removal of session-ids more efficient and to
     * implement a maximum cache size.
     */
    struct ssl_session_st *prev, *next;
#  ifndef OPENSSL_NO_TLSEXT
    char *tlsext_hostname;
#   ifndef OPENSSL_NO_EC
    size_t tlsext_ecpointformatlist_length;
    unsigned char *tlsext_ecpointformatlist; /* peer's list */
    size_t tlsext_ellipticcurvelist_length;
    unsigned char *tlsext_ellipticcurvelist; /* peer's list */
#   endif                       /* OPENSSL_NO_EC */
    /* RFC4507 info */
    unsigned char *tlsext_tick; /* Session ticket */
    size_t tlsext_ticklen;      /* Session ticket length */
    long tlsext_tick_lifetime_hint; /* Session lifetime hint in seconds */
#  endif
#  ifndef OPENSSL_NO_SRP
    char *srp_username;
#  endif
};

# endif

# define SSL_OP_MICROSOFT_SESS_ID_BUG                    0x00000001L
# define SSL_OP_NETSCAPE_CHALLENGE_BUG                   0x00000002L
/* Allow initial connection to servers that don't support RI */
# define SSL_OP_LEGACY_SERVER_CONNECT                    0x00000004L
# define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG         0x00000008L
# define SSL_OP_TLSEXT_PADDING                           0x00000010L
# define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER               0x00000020L
# define SSL_OP_SAFARI_ECDHE_ECDSA_BUG                   0x00000040L
# define SSL_OP_SSLEAY_080_CLIENT_DH_BUG                 0x00000080L
# define SSL_OP_TLS_D5_BUG                               0x00000100L
# define SSL_OP_TLS_BLOCK_PADDING_BUG                    0x00000200L

/* Hasn't done anything since OpenSSL 0.9.7h, retained for compatibility */
# define SSL_OP_MSIE_SSLV2_RSA_PADDING                   0x0
/* Refers to ancient SSLREF and SSLv2, retained for compatibility */
# define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG              0x0

/*
 * Disable SSL 3.0/TLS 1.0 CBC vulnerability workaround that was added in
 * OpenSSL 0.9.6d.  Usually (depending on the application protocol) the
 * workaround is not needed.  Unfortunately some broken SSL/TLS
 * implementations cannot handle it at all, which is why we include it in
 * SSL_OP_ALL.
 */
/* added in 0.9.6e */
# define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS              0x00000800L

/*
 * SSL_OP_ALL: various bug workarounds that should be rather harmless.  This
 * used to be 0x000FFFFFL before 0.9.7.
 */
# define SSL_OP_ALL                                      0x80000BFFL

/* DTLS options */
# define SSL_OP_NO_QUERY_MTU                 0x00001000L
/* Turn on Cookie Exchange (on relevant for servers) */
# define SSL_OP_COOKIE_EXCHANGE              0x00002000L
/* Don't use RFC4507 ticket extension */
# define SSL_OP_NO_TICKET                    0x00004000L
/* Use Cisco's "speshul" version of DTLS_BAD_VER (as client)  */
# define SSL_OP_CISCO_ANYCONNECT             0x00008000L

/* As server, disallow session resumption on renegotiation */
# define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION   0x00010000L
/* Don't use compression even if supported */
# define SSL_OP_NO_COMPRESSION                           0x00020000L
/* Permit unsafe legacy renegotiation */
# define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION        0x00040000L
/* If set, always create a new key when using tmp_ecdh parameters */
# define SSL_OP_SINGLE_ECDH_USE                          0x00080000L
/* Does nothing: retained for compatibility */
# define SSL_OP_SINGLE_DH_USE                            0x00100000L
/* Does nothing: retained for compatibiity */
# define SSL_OP_EPHEMERAL_RSA                            0x0
/*
 * Set on servers to choose the cipher according to the server's preferences
 */
# define SSL_OP_CIPHER_SERVER_PREFERENCE                 0x00400000L
/*
 * If set, a server will allow a client to issue a SSLv3.0 version number as
 * latest version supported in the premaster secret, even when TLSv1.0
 * (version 3.1) was announced in the client hello. Normally this is
 * forbidden to prevent version rollback attacks.
 */
# define SSL_OP_TLS_ROLLBACK_BUG                         0x00800000L

# define SSL_OP_NO_SSLv2                                 0x01000000L
# define SSL_OP_NO_SSLv3                                 0x02000000L
# define SSL_OP_NO_TLSv1                                 0x04000000L
# define SSL_OP_NO_TLSv1_2                               0x08000000L
# define SSL_OP_NO_TLSv1_1                               0x10000000L

# define SSL_OP_NO_DTLSv1                                0x04000000L
# define SSL_OP_NO_DTLSv1_2                              0x08000000L

# define SSL_OP_NO_SSL_MASK (SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|\
        SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1|SSL_OP_NO_TLSv1_2)

/*
 * These next two were never actually used for anything since SSLeay zap so
 * we have some more flags.
 */
/*
 * The next flag deliberately changes the ciphertest, this is a check for the
 * PKCS#1 attack
 */
# define SSL_OP_PKCS1_CHECK_1                            0x0
# define SSL_OP_PKCS1_CHECK_2                            0x0

# define SSL_OP_NETSCAPE_CA_DN_BUG                       0x20000000L
# define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG          0x40000000L
/*
 * Make server add server-hello extension from early version of cryptopro
 * draft, when GOST ciphersuite is negotiated. Required for interoperability
 * with CryptoPro CSP 3.x
 */
# define SSL_OP_CRYPTOPRO_TLSEXT_BUG                     0x80000000L

/*
 * Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report success
 * when just a single record has been written):
 */
# define SSL_MODE_ENABLE_PARTIAL_WRITE       0x00000001L
/*
 * Make it possible to retry SSL_write() with changed buffer location (buffer
 * contents must stay the same!); this is not the default to avoid the
 * misconception that non-blocking SSL_write() behaves like non-blocking
 * write():
 */
# define SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER 0x00000002L
/*
 * Never bother the application with retries if the transport is blocking:
 */
# define SSL_MODE_AUTO_RETRY 0x00000004L
/* Don't attempt to automatically build certificate chain */
# define SSL_MODE_NO_AUTO_CHAIN 0x00000008L
/*
 * Save RAM by releasing read and write buffers when they're empty. (SSL3 and
 * TLS only.) "Released" buffers are put onto a free-list in the context or
 * just freed (depending on the context's setting for freelist_max_len).
 */
# define SSL_MODE_RELEASE_BUFFERS 0x00000010L
/*
 * Send the current time in the Random fields of the ClientHello and
 * ServerHello records for compatibility with hypothetical implementations
 * that require it.
 */
# define SSL_MODE_SEND_CLIENTHELLO_TIME 0x00000020L
# define SSL_MODE_SEND_SERVERHELLO_TIME 0x00000040L
/*
 * Send TLS_FALLBACK_SCSV in the ClientHello. To be set only by applications
 * that reconnect with a downgraded protocol version; see
 * draft-ietf-tls-downgrade-scsv-00 for details. DO NOT ENABLE THIS if your
 * application attempts a normal handshake. Only use this in explicit
 * fallback retries, following the guidance in
 * draft-ietf-tls-downgrade-scsv-00.
 */
# define SSL_MODE_SEND_FALLBACK_SCSV 0x00000080L

/* Cert related flags */
/*
 * Many implementations ignore some aspects of the TLS standards such as
 * enforcing certifcate chain algorithms. When this is set we enforce them.
 */
# define SSL_CERT_FLAG_TLS_STRICT                0x00000001L

/* Suite B modes, takes same values as certificate verify flags */
# define SSL_CERT_FLAG_SUITEB_128_LOS_ONLY       0x10000
/* Suite B 192 bit only mode */
# define SSL_CERT_FLAG_SUITEB_192_LOS            0x20000
/* Suite B 128 bit mode allowing 192 bit algorithms */
# define SSL_CERT_FLAG_SUITEB_128_LOS            0x30000

/* Perform all sorts of protocol violations for testing purposes */
# define SSL_CERT_FLAG_BROKEN_PROTOCOL           0x10000000

/* Flags for building certificate chains */
/* Treat any existing certificates as untrusted CAs */
# define SSL_BUILD_CHAIN_FLAG_UNTRUSTED          0x1
/* Don't include root CA in chain */
# define SSL_BUILD_CHAIN_FLAG_NO_ROOT            0x2
/* Just check certificates already there */
# define SSL_BUILD_CHAIN_FLAG_CHECK              0x4
/* Ignore verification errors */
# define SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR       0x8
/* Clear verification errors from queue */
# define SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR        0x10

/* Flags returned by SSL_check_chain */
/* Certificate can be used with this session */
# define CERT_PKEY_VALID         0x1
/* Certificate can also be used for signing */
# define CERT_PKEY_SIGN          0x2
/* EE certificate signing algorithm OK */
# define CERT_PKEY_EE_SIGNATURE  0x10
/* CA signature algorithms OK */
# define CERT_PKEY_CA_SIGNATURE  0x20
/* EE certificate parameters OK */
# define CERT_PKEY_EE_PARAM      0x40
/* CA certificate parameters OK */
# define CERT_PKEY_CA_PARAM      0x80
/* Signing explicitly allowed as opposed to SHA1 fallback */
# define CERT_PKEY_EXPLICIT_SIGN 0x100
/* Client CA issuer names match (always set for server cert) */
# define CERT_PKEY_ISSUER_NAME   0x200
/* Cert type matches client types (always set for server cert) */
# define CERT_PKEY_CERT_TYPE     0x400
/* Cert chain suitable to Suite B */
# define CERT_PKEY_SUITEB        0x800

# define SSL_CONF_FLAG_CMDLINE           0x1
# define SSL_CONF_FLAG_FILE              0x2
# define SSL_CONF_FLAG_CLIENT            0x4
# define SSL_CONF_FLAG_SERVER            0x8
# define SSL_CONF_FLAG_SHOW_ERRORS       0x10
# define SSL_CONF_FLAG_CERTIFICATE       0x20
/* Configuration value types */
# define SSL_CONF_TYPE_UNKNOWN           0x0
# define SSL_CONF_TYPE_STRING            0x1
# define SSL_CONF_TYPE_FILE              0x2
# define SSL_CONF_TYPE_DIR               0x3

/*
 * Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value, they
 * cannot be used to clear bits.
 */

# define SSL_CTX_set_options(ctx,op) \
        SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,(op),NULL)
# define SSL_CTX_clear_options(ctx,op) \
        SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_OPTIONS,(op),NULL)
# define SSL_CTX_get_options(ctx) \
        SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,0,NULL)
# define SSL_set_options(ssl,op) \
        SSL_ctrl((ssl),SSL_CTRL_OPTIONS,(op),NULL)
# define SSL_clear_options(ssl,op) \
        SSL_ctrl((ssl),SSL_CTRL_CLEAR_OPTIONS,(op),NULL)
# define SSL_get_options(ssl) \
        SSL_ctrl((ssl),SSL_CTRL_OPTIONS,0,NULL)

# define SSL_CTX_set_mode(ctx,op) \
        SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL)
# define SSL_CTX_clear_mode(ctx,op) \
        SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_MODE,(op),NULL)
# define SSL_CTX_get_mode(ctx) \
        SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,0,NULL)
# define SSL_clear_mode(ssl,op) \
        SSL_ctrl((ssl),SSL_CTRL_CLEAR_MODE,(op),NULL)
# define SSL_set_mode(ssl,op) \
        SSL_ctrl((ssl),SSL_CTRL_MODE,(op),NULL)
# define SSL_get_mode(ssl) \
        SSL_ctrl((ssl),SSL_CTRL_MODE,0,NULL)
# define SSL_set_mtu(ssl, mtu) \
        SSL_ctrl((ssl),SSL_CTRL_SET_MTU,(mtu),NULL)
# define DTLS_set_link_mtu(ssl, mtu) \
        SSL_ctrl((ssl),DTLS_CTRL_SET_LINK_MTU,(mtu),NULL)
# define DTLS_get_link_min_mtu(ssl) \
        SSL_ctrl((ssl),DTLS_CTRL_GET_LINK_MIN_MTU,0,NULL)

# define SSL_get_secure_renegotiation_support(ssl) \
        SSL_ctrl((ssl), SSL_CTRL_GET_RI_SUPPORT, 0, NULL)

# ifndef OPENSSL_NO_HEARTBEATS
#  define SSL_heartbeat(ssl) \
        SSL_ctrl((ssl),SSL_CTRL_TLS_EXT_SEND_HEARTBEAT,0,NULL)
# endif

# define SSL_CTX_set_cert_flags(ctx,op) \
        SSL_CTX_ctrl((ctx),SSL_CTRL_CERT_FLAGS,(op),NULL)
# define SSL_set_cert_flags(s,op) \
        SSL_ctrl((s),SSL_CTRL_CERT_FLAGS,(op),NULL)
# define SSL_CTX_clear_cert_flags(ctx,op) \
        SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_CERT_FLAGS,(op),NULL)
# define SSL_clear_cert_flags(s,op) \
        SSL_ctrl((s),SSL_CTRL_CLEAR_CERT_FLAGS,(op),NULL)

void SSL_CTX_set_msg_callback(SSL_CTX *ctx,
                              void (*cb) (int write_p, int version,
                                          int content_type, const void *buf,
                                          size_t len, SSL *ssl, void *arg));
void SSL_set_msg_callback(SSL *ssl,
                          void (*cb) (int write_p, int version,
                                      int content_type, const void *buf,
                                      size_t len, SSL *ssl, void *arg));
# define SSL_CTX_set_msg_callback_arg(ctx, arg) SSL_CTX_ctrl((ctx), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg))
# define SSL_set_msg_callback_arg(ssl, arg) SSL_ctrl((ssl), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg))

# ifndef OPENSSL_NO_SRP

#  ifndef OPENSSL_NO_SSL_INTERN

typedef struct srp_ctx_st {
    /* param for all the callbacks */
    void *SRP_cb_arg;
    /* set client Hello login callback */
    int (*TLS_ext_srp_username_callback) (SSL *, int *, void *);
    /* set SRP N/g param callback for verification */
    int (*SRP_verify_param_callback) (SSL *, void *);
    /* set SRP client passwd callback */
    char *(*SRP_give_srp_client_pwd_callback) (SSL *, void *);
    char *login;
    BIGNUM *N, *g, *s, *B, *A;
    BIGNUM *a, *b, *v;
    char *info;
    int strength;
    unsigned long srp_Mask;
} SRP_CTX;

#  endif

/* see tls_srp.c */
int SSL_SRP_CTX_init(SSL *s);
int SSL_CTX_SRP_CTX_init(SSL_CTX *ctx);
int SSL_SRP_CTX_free(SSL *ctx);
int SSL_CTX_SRP_CTX_free(SSL_CTX *ctx);
int SSL_srp_server_param_with_username(SSL *s, int *ad);
int SRP_generate_server_master_secret(SSL *s, unsigned char *master_key);
int SRP_Calc_A_param(SSL *s);
int SRP_generate_client_master_secret(SSL *s, unsigned char *master_key);

# endif

# if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32)
#  define SSL_MAX_CERT_LIST_DEFAULT 1024*30
                                          /* 30k max cert list :-) */
# else
#  define SSL_MAX_CERT_LIST_DEFAULT 1024*100
                                           /* 100k max cert list :-) */
# endif

# define SSL_SESSION_CACHE_MAX_SIZE_DEFAULT      (1024*20)

/*
 * This callback type is used inside SSL_CTX, SSL, and in the functions that
 * set them. It is used to override the generation of SSL/TLS session IDs in
 * a server. Return value should be zero on an error, non-zero to proceed.
 * Also, callbacks should themselves check if the id they generate is unique
 * otherwise the SSL handshake will fail with an error - callbacks can do
 * this using the 'ssl' value they're passed by;
 * SSL_has_matching_session_id(ssl, id, *id_len) The length value passed in
 * is set at the maximum size the session ID can be. In SSLv2 this is 16
 * bytes, whereas SSLv3/TLSv1 it is 32 bytes. The callback can alter this
 * length to be less if desired, but under SSLv2 session IDs are supposed to
 * be fixed at 16 bytes so the id will be padded after the callback returns
 * in this case. It is also an error for the callback to set the size to
 * zero.
 */
typedef int (*GEN_SESSION_CB) (const SSL *ssl, unsigned char *id,
                               unsigned int *id_len);

typedef struct ssl_comp_st SSL_COMP;

# ifndef OPENSSL_NO_SSL_INTERN

struct ssl_comp_st {
    int id;
    const char *name;
#  ifndef OPENSSL_NO_COMP
    COMP_METHOD *method;
#  else
    char *method;
#  endif
};

DECLARE_STACK_OF(SSL_COMP)
DECLARE_LHASH_OF(SSL_SESSION);

struct ssl_ctx_st {
    const SSL_METHOD *method;
    STACK_OF(SSL_CIPHER) *cipher_list;
    /* same as above but sorted for lookup */
    STACK_OF(SSL_CIPHER) *cipher_list_by_id;
    struct x509_store_st /* X509_STORE */ *cert_store;
    LHASH_OF(SSL_SESSION) *sessions;
    /*
     * Most session-ids that will be cached, default is
     * SSL_SESSION_CACHE_MAX_SIZE_DEFAULT. 0 is unlimited.
     */
    unsigned long session_cache_size;
    struct ssl_session_st *session_cache_head;
    struct ssl_session_st *session_cache_tail;
    /*
     * This can have one of 2 values, ored together, SSL_SESS_CACHE_CLIENT,
     * SSL_SESS_CACHE_SERVER, Default is SSL_SESSION_CACHE_SERVER, which
     * means only SSL_accept which cache SSL_SESSIONS.
     */
    int session_cache_mode;
    /*
     * If timeout is not 0, it is the default timeout value set when
     * SSL_new() is called.  This has been put in to make life easier to set
     * things up
     */
    long session_timeout;
    /*
     * If this callback is not null, it will be called each time a session id
     * is added to the cache.  If this function returns 1, it means that the
     * callback will do a SSL_SESSION_free() when it has finished using it.
     * Otherwise, on 0, it means the callback has finished with it. If
     * remove_session_cb is not null, it will be called when a session-id is
     * removed from the cache.  After the call, OpenSSL will
     * SSL_SESSION_free() it.
     */
    int (*new_session_cb) (struct ssl_st *ssl, SSL_SESSION *sess);
    void (*remove_session_cb) (struct ssl_ctx_st *ctx, SSL_SESSION *sess);
    SSL_SESSION *(*get_session_cb) (struct ssl_st *ssl,
                                    unsigned char *data, int len, int *copy);
    struct {
        int sess_connect;       /* SSL new conn - started */
        int sess_connect_renegotiate; /* SSL reneg - requested */
        int sess_connect_good;  /* SSL new conne/reneg - finished */
        int sess_accept;        /* SSL new accept - started */
        int sess_accept_renegotiate; /* SSL reneg - requested */
        int sess_accept_good;   /* SSL accept/reneg - finished */
        int sess_miss;          /* session lookup misses */
        int sess_timeout;       /* reuse attempt on timeouted session */
        int sess_cache_full;    /* session removed due to full cache */
        int sess_hit;           /* session reuse actually done */
        int sess_cb_hit;        /* session-id that was not in the cache was
                                 * passed back via the callback.  This
                                 * indicates that the application is
                                 * supplying session-id's from other
                                 * processes - spooky :-) */
    } stats;

    int references;

    /* if defined, these override the X509_verify_cert() calls */
    int (*app_verify_callback) (X509_STORE_CTX *, void *);
    void *app_verify_arg;
    /*
     * before OpenSSL 0.9.7, 'app_verify_arg' was ignored
     * ('app_verify_callback' was called with just one argument)
     */

    /* Default password callback. */
    pem_password_cb *default_passwd_callback;

    /* Default password callback user data. */
    void *default_passwd_callback_userdata;

    /* get client cert callback */
    int (*client_cert_cb) (SSL *ssl, X509 **x509, EVP_PKEY **pkey);

    /* cookie generate callback */
    int (*app_gen_cookie_cb) (SSL *ssl, unsigned char *cookie,
                              unsigned int *cookie_len);

    /* verify cookie callback */
    int (*app_verify_cookie_cb) (SSL *ssl, unsigned char *cookie,
                                 unsigned int cookie_len);

    CRYPTO_EX_DATA ex_data;

    const EVP_MD *rsa_md5;      /* For SSLv2 - name is 'ssl2-md5' */
    const EVP_MD *md5;          /* For SSLv3/TLSv1 'ssl3-md5' */
    const EVP_MD *sha1;         /* For SSLv3/TLSv1 'ssl3->sha1' */

    STACK_OF(X509) *extra_certs;
    STACK_OF(SSL_COMP) *comp_methods; /* stack of SSL_COMP, SSLv3/TLSv1 */

    /* Default values used when no per-SSL value is defined follow */

    /* used if SSL's info_callback is NULL */
    void (*info_callback) (const SSL *ssl, int type, int val);

    /* what we put in client cert requests */
    STACK_OF(X509_NAME) *client_CA;

    /*
     * Default values to use in SSL structures follow (these are copied by
     * SSL_new)
     */

    unsigned long options;
    unsigned long mode;
    long max_cert_list;

    struct cert_st /* CERT */ *cert;
    int read_ahead;

    /* callback that allows applications to peek at protocol messages */
    void (*msg_callback) (int write_p, int version, int content_type,
                          const void *buf, size_t len, SSL *ssl, void *arg);
    void *msg_callback_arg;

    int verify_mode;
    unsigned int sid_ctx_length;
    unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH];
    /* called 'verify_callback' in the SSL */
    int (*default_verify_callback) (int ok, X509_STORE_CTX *ctx);

    /* Default generate session ID callback. */
    GEN_SESSION_CB generate_session_id;

    X509_VERIFY_PARAM *param;

#  if 0
    int purpose;                /* Purpose setting */
    int trust;                  /* Trust setting */
#  endif

    int quiet_shutdown;

    /*
     * Maximum amount of data to send in one fragment. actual record size can
     * be more than this due to padding and MAC overheads.
     */
    unsigned int max_send_fragment;

#  ifndef OPENSSL_NO_ENGINE
    /*
     * Engine to pass requests for client certs to
     */
    ENGINE *client_cert_engine;
#  endif

#  ifndef OPENSSL_NO_TLSEXT
    /* TLS extensions servername callback */
    int (*tlsext_servername_callback) (SSL *, int *, void *);
    void *tlsext_servername_arg;
    /* RFC 4507 session ticket keys */
    unsigned char tlsext_tick_key_name[16];
    unsigned char tlsext_tick_hmac_key[16];
    unsigned char tlsext_tick_aes_key[16];
    /* Callback to support customisation of ticket key setting */
    int (*tlsext_ticket_key_cb) (SSL *ssl,
                                 unsigned char *name, unsigned char *iv,
                                 EVP_CIPHER_CTX *ectx,
                                 HMAC_CTX *hctx, int enc);

    /* certificate status request info */
    /* Callback for status request */
    int (*tlsext_status_cb) (SSL *ssl, void *arg);
    void *tlsext_status_arg;

    /* draft-rescorla-tls-opaque-prf-input-00.txt information */
    int (*tlsext_opaque_prf_input_callback) (SSL *, void *peerinput,
                                             size_t len, void *arg);
    void *tlsext_opaque_prf_input_callback_arg;
#  endif

#  ifndef OPENSSL_NO_PSK
    char *psk_identity_hint;
    unsigned int (*psk_client_callback) (SSL *ssl, const char *hint,
                                         char *identity,
                                         unsigned int max_identity_len,
                                         unsigned char *psk,
                                         unsigned int max_psk_len);
    unsigned int (*psk_server_callback) (SSL *ssl, const char *identity,
                                         unsigned char *psk,
                                         unsigned int max_psk_len);
#  endif

#  ifndef OPENSSL_NO_BUF_FREELISTS
#   define SSL_MAX_BUF_FREELIST_LEN_DEFAULT 32
    unsigned int freelist_max_len;
    struct ssl3_buf_freelist_st *wbuf_freelist;
    struct ssl3_buf_freelist_st *rbuf_freelist;
#  endif
#  ifndef OPENSSL_NO_SRP
    SRP_CTX srp_ctx;            /* ctx for SRP authentication */
#  endif

#  ifndef OPENSSL_NO_TLSEXT

#   ifndef OPENSSL_NO_NEXTPROTONEG
    /* Next protocol negotiation information */
    /* (for experimental NPN extension). */

    /*
     * For a server, this contains a callback function by which the set of
     * advertised protocols can be provided.
     */
    int (*next_protos_advertised_cb) (SSL *s, const unsigned char **buf,
                                      unsigned int *len, void *arg);
    void *next_protos_advertised_cb_arg;
    /*
     * For a client, this contains a callback function that selects the next
     * protocol from the list provided by the server.
     */
    int (*next_proto_select_cb) (SSL *s, unsigned char **out,
                                 unsigned char *outlen,
                                 const unsigned char *in,
                                 unsigned int inlen, void *arg);
    void *next_proto_select_cb_arg;
#   endif
    /* SRTP profiles we are willing to do from RFC 5764 */
    STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles;

    /*
     * ALPN information (we are in the process of transitioning from NPN to
     * ALPN.)
     */

    /*-
     * For a server, this contains a callback function that allows the
     * server to select the protocol for the connection.
     *   out: on successful return, this must point to the raw protocol
     *        name (without the length prefix).
     *   outlen: on successful return, this contains the length of |*out|.
     *   in: points to the client's list of supported protocols in
     *       wire-format.
     *   inlen: the length of |in|.
     */
    int (*alpn_select_cb) (SSL *s,
                           const unsigned char **out,
                           unsigned char *outlen,
                           const unsigned char *in,
                           unsigned int inlen, void *arg);
    void *alpn_select_cb_arg;

    /*
     * For a client, this contains the list of supported protocols in wire
     * format.
     */
    unsigned char *alpn_client_proto_list;
    unsigned alpn_client_proto_list_len;

#   ifndef OPENSSL_NO_EC
    /* EC extension values inherited by SSL structure */
    size_t tlsext_ecpointformatlist_length;
    unsigned char *tlsext_ecpointformatlist;
    size_t tlsext_ellipticcurvelist_length;
    unsigned char *tlsext_ellipticcurvelist;
#   endif                       /* OPENSSL_NO_EC */
#  endif
};

# endif

# define SSL_SESS_CACHE_OFF                      0x0000
# define SSL_SESS_CACHE_CLIENT                   0x0001
# define SSL_SESS_CACHE_SERVER                   0x0002
# define SSL_SESS_CACHE_BOTH     (SSL_SESS_CACHE_CLIENT|SSL_SESS_CACHE_SERVER)
# define SSL_SESS_CACHE_NO_AUTO_CLEAR            0x0080
/* enough comments already ... see SSL_CTX_set_session_cache_mode(3) */
# define SSL_SESS_CACHE_NO_INTERNAL_LOOKUP       0x0100
# define SSL_SESS_CACHE_NO_INTERNAL_STORE        0x0200
# define SSL_SESS_CACHE_NO_INTERNAL \
        (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP|SSL_SESS_CACHE_NO_INTERNAL_STORE)

LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx);
# define SSL_CTX_sess_number(ctx) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_NUMBER,0,NULL)
# define SSL_CTX_sess_connect(ctx) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT,0,NULL)
# define SSL_CTX_sess_connect_good(ctx) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_GOOD,0,NULL)
# define SSL_CTX_sess_connect_renegotiate(ctx) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_RENEGOTIATE,0,NULL)
# define SSL_CTX_sess_accept(ctx) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT,0,NULL)
# define SSL_CTX_sess_accept_renegotiate(ctx) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_RENEGOTIATE,0,NULL)
# define SSL_CTX_sess_accept_good(ctx) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_GOOD,0,NULL)
# define SSL_CTX_sess_hits(ctx) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_HIT,0,NULL)
# define SSL_CTX_sess_cb_hits(ctx) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CB_HIT,0,NULL)
# define SSL_CTX_sess_misses(ctx) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_MISSES,0,NULL)
# define SSL_CTX_sess_timeouts(ctx) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_TIMEOUTS,0,NULL)
# define SSL_CTX_sess_cache_full(ctx) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CACHE_FULL,0,NULL)

void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx,
                             int (*new_session_cb) (struct ssl_st *ssl,
                                                    SSL_SESSION *sess));
int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx)) (struct ssl_st *ssl,
                                              SSL_SESSION *sess);
void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx,
                                void (*remove_session_cb) (struct ssl_ctx_st
                                                           *ctx,
                                                           SSL_SESSION
                                                           *sess));
void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx)) (struct ssl_ctx_st *ctx,
                                                  SSL_SESSION *sess);
void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx,
                             SSL_SESSION *(*get_session_cb) (struct ssl_st
                                                             *ssl,
                                                             unsigned char
                                                             *data, int len,
                                                             int *copy));
SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx)) (struct ssl_st *ssl,
                                                       unsigned char *Data,
                                                       int len, int *copy);
void SSL_CTX_set_info_callback(SSL_CTX *ctx,
                               void (*cb) (const SSL *ssl, int type,
                                           int val));
void (*SSL_CTX_get_info_callback(SSL_CTX *ctx)) (const SSL *ssl, int type,
                                                 int val);
void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx,
                                int (*client_cert_cb) (SSL *ssl, X509 **x509,
                                                       EVP_PKEY **pkey));
int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx)) (SSL *ssl, X509 **x509,
                                                 EVP_PKEY **pkey);
# ifndef OPENSSL_NO_ENGINE
int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e);
# endif
void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx,
                                    int (*app_gen_cookie_cb) (SSL *ssl,
                                                              unsigned char
                                                              *cookie,
                                                              unsigned int
                                                              *cookie_len));
void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx,
                                  int (*app_verify_cookie_cb) (SSL *ssl,
                                                               unsigned char
                                                               *cookie,
                                                               unsigned int
                                                               cookie_len));
# ifndef OPENSSL_NO_NEXTPROTONEG
void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *s,
                                           int (*cb) (SSL *ssl,
                                                      const unsigned char
                                                      **out,
                                                      unsigned int *outlen,
                                                      void *arg), void *arg);
void SSL_CTX_set_next_proto_select_cb(SSL_CTX *s,
                                      int (*cb) (SSL *ssl,
                                                 unsigned char **out,
                                                 unsigned char *outlen,
                                                 const unsigned char *in,
                                                 unsigned int inlen,
                                                 void *arg), void *arg);
void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data,
                                    unsigned *len);
# endif

# ifndef OPENSSL_NO_TLSEXT
int SSL_select_next_proto(unsigned char **out, unsigned char *outlen,
                          const unsigned char *in, unsigned int inlen,
                          const unsigned char *client,
                          unsigned int client_len);
# endif

# define OPENSSL_NPN_UNSUPPORTED 0
# define OPENSSL_NPN_NEGOTIATED  1
# define OPENSSL_NPN_NO_OVERLAP  2

int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos,
                            unsigned protos_len);
int SSL_set_alpn_protos(SSL *ssl, const unsigned char *protos,
                        unsigned protos_len);
void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx,
                                int (*cb) (SSL *ssl,
                                           const unsigned char **out,
                                           unsigned char *outlen,
                                           const unsigned char *in,
                                           unsigned int inlen,
                                           void *arg), void *arg);
void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data,
                            unsigned *len);

# ifndef OPENSSL_NO_PSK
/*
 * the maximum length of the buffer given to callbacks containing the
 * resulting identity/psk
 */
#  define PSK_MAX_IDENTITY_LEN 128
#  define PSK_MAX_PSK_LEN 256
void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx,
                                     unsigned int (*psk_client_callback) (SSL
                                                                          *ssl,
                                                                          const
                                                                          char
                                                                          *hint,
                                                                          char
                                                                          *identity,
                                                                          unsigned
                                                                          int
                                                                          max_identity_len,
                                                                          unsigned
                                                                          char
                                                                          *psk,
                                                                          unsigned
                                                                          int
                                                                          max_psk_len));
void SSL_set_psk_client_callback(SSL *ssl,
                                 unsigned int (*psk_client_callback) (SSL
                                                                      *ssl,
                                                                      const
                                                                      char
                                                                      *hint,
                                                                      char
                                                                      *identity,
                                                                      unsigned
                                                                      int
                                                                      max_identity_len,
                                                                      unsigned
                                                                      char
                                                                      *psk,
                                                                      unsigned
                                                                      int
                                                                      max_psk_len));
void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx,
                                     unsigned int (*psk_server_callback) (SSL
                                                                          *ssl,
                                                                          const
                                                                          char
                                                                          *identity,
                                                                          unsigned
                                                                          char
                                                                          *psk,
                                                                          unsigned
                                                                          int
                                                                          max_psk_len));
void SSL_set_psk_server_callback(SSL *ssl,
                                 unsigned int (*psk_server_callback) (SSL
                                                                      *ssl,
                                                                      const
                                                                      char
                                                                      *identity,
                                                                      unsigned
                                                                      char
                                                                      *psk,
                                                                      unsigned
                                                                      int
                                                                      max_psk_len));
int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint);
int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint);
const char *SSL_get_psk_identity_hint(const SSL *s);
const char *SSL_get_psk_identity(const SSL *s);
# endif

# ifndef OPENSSL_NO_TLSEXT
/* Register callbacks to handle custom TLS Extensions for client or server. */

int SSL_CTX_add_client_custom_ext(SSL_CTX *ctx, unsigned int ext_type,
                                  custom_ext_add_cb add_cb,
                                  custom_ext_free_cb free_cb,
                                  void *add_arg,
                                  custom_ext_parse_cb parse_cb,
                                  void *parse_arg);

int SSL_CTX_add_server_custom_ext(SSL_CTX *ctx, unsigned int ext_type,
                                  custom_ext_add_cb add_cb,
                                  custom_ext_free_cb free_cb,
                                  void *add_arg,
                                  custom_ext_parse_cb parse_cb,
                                  void *parse_arg);

int SSL_extension_supported(unsigned int ext_type);

# endif

# define SSL_NOTHING     1
# define SSL_WRITING     2
# define SSL_READING     3
# define SSL_X509_LOOKUP 4

/* These will only be used when doing non-blocking IO */
# define SSL_want_nothing(s)     (SSL_want(s) == SSL_NOTHING)
# define SSL_want_read(s)        (SSL_want(s) == SSL_READING)
# define SSL_want_write(s)       (SSL_want(s) == SSL_WRITING)
# define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_X509_LOOKUP)

# define SSL_MAC_FLAG_READ_MAC_STREAM 1
# define SSL_MAC_FLAG_WRITE_MAC_STREAM 2

# ifndef OPENSSL_NO_SSL_INTERN

struct ssl_st {
    /*
     * protocol version (one of SSL2_VERSION, SSL3_VERSION, TLS1_VERSION,
     * DTLS1_VERSION)
     */
    int version;
    /* SSL_ST_CONNECT or SSL_ST_ACCEPT */
    int type;
    /* SSLv3 */
    const SSL_METHOD *method;
    /*
     * There are 2 BIO's even though they are normally both the same.  This
     * is so data can be read and written to different handlers
     */
#  ifndef OPENSSL_NO_BIO
    /* used by SSL_read */
    BIO *rbio;
    /* used by SSL_write */
    BIO *wbio;
    /* used during session-id reuse to concatenate messages */
    BIO *bbio;
#  else
    /* used by SSL_read */
    char *rbio;
    /* used by SSL_write */
    char *wbio;
    char *bbio;
#  endif
    /*
     * This holds a variable that indicates what we were doing when a 0 or -1
     * is returned.  This is needed for non-blocking IO so we know what
     * request needs re-doing when in SSL_accept or SSL_connect
     */
    int rwstate;
    /* true when we are actually in SSL_accept() or SSL_connect() */
    int in_handshake;
    int (*handshake_func) (SSL *);
    /*
     * Imagine that here's a boolean member "init" that is switched as soon
     * as SSL_set_{accept/connect}_state is called for the first time, so
     * that "state" and "handshake_func" are properly initialized.  But as
     * handshake_func is == 0 until then, we use this test instead of an
     * "init" member.
     */
    /* are we the server side? - mostly used by SSL_clear */
    int server;
    /*
     * Generate a new session or reuse an old one.
     * NB: For servers, the 'new' session may actually be a previously
     * cached session or even the previous session unless
     * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set
     */
    int new_session;
    /* don't send shutdown packets */
    int quiet_shutdown;
    /* we have shut things down, 0x01 sent, 0x02 for received */
    int shutdown;
    /* where we are */
    int state;
    /* where we are when reading */
    int rstate;
    BUF_MEM *init_buf;          /* buffer used during init */
    void *init_msg;             /* pointer to handshake message body, set by
                                 * ssl3_get_message() */
    int init_num;               /* amount read/written */
    int init_off;               /* amount read/written */
    /* used internally to point at a raw packet */
    unsigned char *packet;
    unsigned int packet_length;
    struct ssl2_state_st *s2;   /* SSLv2 variables */
    struct ssl3_state_st *s3;   /* SSLv3 variables */
    struct dtls1_state_st *d1;  /* DTLSv1 variables */
    int read_ahead;             /* Read as many input bytes as possible (for
                                 * non-blocking reads) */
    /* callback that allows applications to peek at protocol messages */
    void (*msg_callback) (int write_p, int version, int content_type,
                          const void *buf, size_t len, SSL *ssl, void *arg);
    void *msg_callback_arg;
    int hit;                    /* reusing a previous session */
    X509_VERIFY_PARAM *param;
#  if 0
    int purpose;                /* Purpose setting */
    int trust;                  /* Trust setting */
#  endif
    /* crypto */
    STACK_OF(SSL_CIPHER) *cipher_list;
    STACK_OF(SSL_CIPHER) *cipher_list_by_id;
    /*
     * These are the ones being used, the ones in SSL_SESSION are the ones to
     * be 'copied' into these ones
     */
    int mac_flags;
    EVP_CIPHER_CTX *enc_read_ctx; /* cryptographic state */
    EVP_MD_CTX *read_hash;      /* used for mac generation */
#  ifndef OPENSSL_NO_COMP
    COMP_CTX *expand;           /* uncompress */
#  else
    char *expand;
#  endif
    EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */
    EVP_MD_CTX *write_hash;     /* used for mac generation */
#  ifndef OPENSSL_NO_COMP
    COMP_CTX *compress;         /* compression */
#  else
    char *compress;
#  endif
    /* session info */
    /* client cert? */
    /* This is used to hold the server certificate used */
    struct cert_st /* CERT */ *cert;
    /*
     * the session_id_context is used to ensure sessions are only reused in
     * the appropriate context
     */
    unsigned int sid_ctx_length;
    unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH];
    /* This can also be in the session once a session is established */
    SSL_SESSION *session;
    /* Default generate session ID callback. */
    GEN_SESSION_CB generate_session_id;
    /* Used in SSL2 and SSL3 */
    /*
     * 0 don't care about verify failure.
     * 1 fail if verify fails
     */
    int verify_mode;
    /* fail if callback returns 0 */
    int (*verify_callback) (int ok, X509_STORE_CTX *ctx);
    /* optional informational callback */
    void (*info_callback) (const SSL *ssl, int type, int val);
    /* error bytes to be written */
    int error;
    /* actual code */
    int error_code;
#  ifndef OPENSSL_NO_KRB5
    /* Kerberos 5 context */
    KSSL_CTX *kssl_ctx;
#  endif                        /* OPENSSL_NO_KRB5 */
#  ifndef OPENSSL_NO_PSK
    unsigned int (*psk_client_callback) (SSL *ssl, const char *hint,
                                         char *identity,
                                         unsigned int max_identity_len,
                                         unsigned char *psk,
                                         unsigned int max_psk_len);
    unsigned int (*psk_server_callback) (SSL *ssl, const char *identity,
                                         unsigned char *psk,
                                         unsigned int max_psk_len);
#  endif
    SSL_CTX *ctx;
    /*
     * set this flag to 1 and a sleep(1) is put into all SSL_read() and
     * SSL_write() calls, good for nbio debuging :-)
     */
    int debug;
    /* extra application data */
    long verify_result;
    CRYPTO_EX_DATA ex_data;
    /* for server side, keep the list of CA_dn we can use */
    STACK_OF(X509_NAME) *client_CA;
    int references;
    /* protocol behaviour */
    unsigned long options;
    /* API behaviour */
    unsigned long mode;
    long max_cert_list;
    int first_packet;
    /* what was passed, used for SSLv3/TLS rollback check */
    int client_version;
    unsigned int max_send_fragment;
#  ifndef OPENSSL_NO_TLSEXT
    /* TLS extension debug callback */
    void (*tlsext_debug_cb) (SSL *s, int client_server, int type,
                             unsigned char *data, int len, void *arg);
    void *tlsext_debug_arg;
    char *tlsext_hostname;
    /*-
     * no further mod of servername
     * 0 : call the servername extension callback.
     * 1 : prepare 2, allow last ack just after in server callback.
     * 2 : don't call servername callback, no ack in server hello
     */
    int servername_done;
    /* certificate status request info */
    /* Status type or -1 if no status type */
    int tlsext_status_type;
    /* Expect OCSP CertificateStatus message */
    int tlsext_status_expected;
    /* OCSP status request only */
    STACK_OF(OCSP_RESPID) *tlsext_ocsp_ids;
    X509_EXTENSIONS *tlsext_ocsp_exts;
    /* OCSP response received or to be sent */
    unsigned char *tlsext_ocsp_resp;
    int tlsext_ocsp_resplen;
    /* RFC4507 session ticket expected to be received or sent */
    int tlsext_ticket_expected;
#   ifndef OPENSSL_NO_EC
    size_t tlsext_ecpointformatlist_length;
    /* our list */
    unsigned char *tlsext_ecpointformatlist;
    size_t tlsext_ellipticcurvelist_length;
    /* our list */
    unsigned char *tlsext_ellipticcurvelist;
#   endif                       /* OPENSSL_NO_EC */
    /*
     * draft-rescorla-tls-opaque-prf-input-00.txt information to be used for
     * handshakes
     */
    void *tlsext_opaque_prf_input;
    size_t tlsext_opaque_prf_input_len;
    /* TLS Session Ticket extension override */
    TLS_SESSION_TICKET_EXT *tlsext_session_ticket;
    /* TLS Session Ticket extension callback */
    tls_session_ticket_ext_cb_fn tls_session_ticket_ext_cb;
    void *tls_session_ticket_ext_cb_arg;
    /* TLS pre-shared secret session resumption */
    tls_session_secret_cb_fn tls_session_secret_cb;
    void *tls_session_secret_cb_arg;
    SSL_CTX *initial_ctx;       /* initial ctx, used to store sessions */
#   ifndef OPENSSL_NO_NEXTPROTONEG
    /*
     * Next protocol negotiation. For the client, this is the protocol that
     * we sent in NextProtocol and is set when handling ServerHello
     * extensions. For a server, this is the client's selected_protocol from
     * NextProtocol and is set when handling the NextProtocol message, before
     * the Finished message.
     */
    unsigned char *next_proto_negotiated;
    unsigned char next_proto_negotiated_len;
#   endif
#   define session_ctx initial_ctx
    /* What we'll do */
    STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles;
    /* What's been chosen */
    SRTP_PROTECTION_PROFILE *srtp_profile;
        /*-
         * Is use of the Heartbeat extension negotiated?
         * 0: disabled
         * 1: enabled
         * 2: enabled, but not allowed to send Requests
         */
    unsigned int tlsext_heartbeat;
    /* Indicates if a HeartbeatRequest is in flight */
    unsigned int tlsext_hb_pending;
    /* HeartbeatRequest sequence number */
    unsigned int tlsext_hb_seq;
#  else
#   define session_ctx ctx
#  endif                        /* OPENSSL_NO_TLSEXT */
    /*-
     * 1 if we are renegotiating.
     * 2 if we are a server and are inside a handshake
     * (i.e. not just sending a HelloRequest)
     */
    int renegotiate;
#  ifndef OPENSSL_NO_SRP
    /* ctx for SRP authentication */
    SRP_CTX srp_ctx;
#  endif
#  ifndef OPENSSL_NO_TLSEXT
    /*
     * For a client, this contains the list of supported protocols in wire
     * format.
     */
    unsigned char *alpn_client_proto_list;
    unsigned alpn_client_proto_list_len;
#  endif                        /* OPENSSL_NO_TLSEXT */
};

# endif

#ifdef __cplusplus
}
#endif

# include <openssl/ssl2.h>
# include <openssl/ssl3.h>
# include <openssl/tls1.h>      /* This is mostly sslv3 with a few tweaks */
# include <openssl/dtls1.h>     /* Datagram TLS */
# include <openssl/ssl23.h>
# include <openssl/srtp.h>      /* Support for the use_srtp extension */

#ifdef  __cplusplus
extern "C" {
#endif

/* compatibility */
# define SSL_set_app_data(s,arg)         (SSL_set_ex_data(s,0,(char *)arg))
# define SSL_get_app_data(s)             (SSL_get_ex_data(s,0))
# define SSL_SESSION_set_app_data(s,a)   (SSL_SESSION_set_ex_data(s,0,(char *)a))
# define SSL_SESSION_get_app_data(s)     (SSL_SESSION_get_ex_data(s,0))
# define SSL_CTX_get_app_data(ctx)       (SSL_CTX_get_ex_data(ctx,0))
# define SSL_CTX_set_app_data(ctx,arg)   (SSL_CTX_set_ex_data(ctx,0,(char *)arg))

/*
 * The following are the possible values for ssl->state are are used to
 * indicate where we are up to in the SSL connection establishment. The
 * macros that follow are about the only things you should need to use and
 * even then, only when using non-blocking IO. It can also be useful to work
 * out where you were when the connection failed
 */

# define SSL_ST_CONNECT                  0x1000
# define SSL_ST_ACCEPT                   0x2000
# define SSL_ST_MASK                     0x0FFF
# define SSL_ST_INIT                     (SSL_ST_CONNECT|SSL_ST_ACCEPT)
# define SSL_ST_BEFORE                   0x4000
# define SSL_ST_OK                       0x03
# define SSL_ST_RENEGOTIATE              (0x04|SSL_ST_INIT)
# define SSL_ST_ERR                      (0x05|SSL_ST_INIT)

# define SSL_CB_LOOP                     0x01
# define SSL_CB_EXIT                     0x02
# define SSL_CB_READ                     0x04
# define SSL_CB_WRITE                    0x08
# define SSL_CB_ALERT                    0x4000/* used in callback */
# define SSL_CB_READ_ALERT               (SSL_CB_ALERT|SSL_CB_READ)
# define SSL_CB_WRITE_ALERT              (SSL_CB_ALERT|SSL_CB_WRITE)
# define SSL_CB_ACCEPT_LOOP              (SSL_ST_ACCEPT|SSL_CB_LOOP)
# define SSL_CB_ACCEPT_EXIT              (SSL_ST_ACCEPT|SSL_CB_EXIT)
# define SSL_CB_CONNECT_LOOP             (SSL_ST_CONNECT|SSL_CB_LOOP)
# define SSL_CB_CONNECT_EXIT             (SSL_ST_CONNECT|SSL_CB_EXIT)
# define SSL_CB_HANDSHAKE_START          0x10
# define SSL_CB_HANDSHAKE_DONE           0x20

/* Is the SSL_connection established? */
# define SSL_get_state(a)                SSL_state(a)
# define SSL_is_init_finished(a)         (SSL_state(a) == SSL_ST_OK)
# define SSL_in_init(a)                  (SSL_state(a)&SSL_ST_INIT)
# define SSL_in_before(a)                (SSL_state(a)&SSL_ST_BEFORE)
# define SSL_in_connect_init(a)          (SSL_state(a)&SSL_ST_CONNECT)
# define SSL_in_accept_init(a)           (SSL_state(a)&SSL_ST_ACCEPT)

/*
 * The following 2 states are kept in ssl->rstate when reads fail, you should
 * not need these
 */
# define SSL_ST_READ_HEADER                      0xF0
# define SSL_ST_READ_BODY                        0xF1
# define SSL_ST_READ_DONE                        0xF2

/*-
 * Obtain latest Finished message
 *   -- that we sent (SSL_get_finished)
 *   -- that we expected from peer (SSL_get_peer_finished).
 * Returns length (0 == no Finished so far), copies up to 'count' bytes.
 */
size_t SSL_get_finished(const SSL *s, void *buf, size_t count);
size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count);

/*
 * use either SSL_VERIFY_NONE or SSL_VERIFY_PEER, the last 2 options are
 * 'ored' with SSL_VERIFY_PEER if they are desired
 */
# define SSL_VERIFY_NONE                 0x00
# define SSL_VERIFY_PEER                 0x01
# define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02
# define SSL_VERIFY_CLIENT_ONCE          0x04

# define OpenSSL_add_ssl_algorithms()    SSL_library_init()
# define SSLeay_add_ssl_algorithms()     SSL_library_init()

/* this is for backward compatibility */
# if 0                          /* NEW_SSLEAY */
#  define SSL_CTX_set_default_verify(a,b,c) SSL_CTX_set_verify(a,b,c)
#  define SSL_set_pref_cipher(c,n)        SSL_set_cipher_list(c,n)
#  define SSL_add_session(a,b)            SSL_CTX_add_session((a),(b))
#  define SSL_remove_session(a,b)         SSL_CTX_remove_session((a),(b))
#  define SSL_flush_sessions(a,b)         SSL_CTX_flush_sessions((a),(b))
# endif
/* More backward compatibility */
# define SSL_get_cipher(s) \
                SSL_CIPHER_get_name(SSL_get_current_cipher(s))
# define SSL_get_cipher_bits(s,np) \
                SSL_CIPHER_get_bits(SSL_get_current_cipher(s),np)
# define SSL_get_cipher_version(s) \
                SSL_CIPHER_get_version(SSL_get_current_cipher(s))
# define SSL_get_cipher_name(s) \
                SSL_CIPHER_get_name(SSL_get_current_cipher(s))
# define SSL_get_time(a)         SSL_SESSION_get_time(a)
# define SSL_set_time(a,b)       SSL_SESSION_set_time((a),(b))
# define SSL_get_timeout(a)      SSL_SESSION_get_timeout(a)
# define SSL_set_timeout(a,b)    SSL_SESSION_set_timeout((a),(b))

# define d2i_SSL_SESSION_bio(bp,s_id) ASN1_d2i_bio_of(SSL_SESSION,SSL_SESSION_new,d2i_SSL_SESSION,bp,s_id)
# define i2d_SSL_SESSION_bio(bp,s_id) ASN1_i2d_bio_of(SSL_SESSION,i2d_SSL_SESSION,bp,s_id)

DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
# define SSL_AD_REASON_OFFSET            1000/* offset to get SSL_R_... value
                                              * from SSL_AD_... */
/* These alert types are for SSLv3 and TLSv1 */
# define SSL_AD_CLOSE_NOTIFY             SSL3_AD_CLOSE_NOTIFY
/* fatal */
# define SSL_AD_UNEXPECTED_MESSAGE       SSL3_AD_UNEXPECTED_MESSAGE
/* fatal */
# define SSL_AD_BAD_RECORD_MAC           SSL3_AD_BAD_RECORD_MAC
# define SSL_AD_DECRYPTION_FAILED        TLS1_AD_DECRYPTION_FAILED
# define SSL_AD_RECORD_OVERFLOW          TLS1_AD_RECORD_OVERFLOW
/* fatal */
# define SSL_AD_DECOMPRESSION_FAILURE    SSL3_AD_DECOMPRESSION_FAILURE
/* fatal */
# define SSL_AD_HANDSHAKE_FAILURE        SSL3_AD_HANDSHAKE_FAILURE
/* Not for TLS */
# define SSL_AD_NO_CERTIFICATE           SSL3_AD_NO_CERTIFICATE
# define SSL_AD_BAD_CERTIFICATE          SSL3_AD_BAD_CERTIFICATE
# define SSL_AD_UNSUPPORTED_CERTIFICATE  SSL3_AD_UNSUPPORTED_CERTIFICATE
# define SSL_AD_CERTIFICATE_REVOKED      SSL3_AD_CERTIFICATE_REVOKED
# define SSL_AD_CERTIFICATE_EXPIRED      SSL3_AD_CERTIFICATE_EXPIRED
# define SSL_AD_CERTIFICATE_UNKNOWN      SSL3_AD_CERTIFICATE_UNKNOWN
/* fatal */
# define SSL_AD_ILLEGAL_PARAMETER        SSL3_AD_ILLEGAL_PARAMETER
/* fatal */
# define SSL_AD_UNKNOWN_CA               TLS1_AD_UNKNOWN_CA
/* fatal */
# define SSL_AD_ACCESS_DENIED            TLS1_AD_ACCESS_DENIED
/* fatal */
# define SSL_AD_DECODE_ERROR             TLS1_AD_DECODE_ERROR
# define SSL_AD_DECRYPT_ERROR            TLS1_AD_DECRYPT_ERROR
/* fatal */
# define SSL_AD_EXPORT_RESTRICTION       TLS1_AD_EXPORT_RESTRICTION
/* fatal */
# define SSL_AD_PROTOCOL_VERSION         TLS1_AD_PROTOCOL_VERSION
/* fatal */
# define SSL_AD_INSUFFICIENT_SECURITY    TLS1_AD_INSUFFICIENT_SECURITY
/* fatal */
# define SSL_AD_INTERNAL_ERROR           TLS1_AD_INTERNAL_ERROR
# define SSL_AD_USER_CANCELLED           TLS1_AD_USER_CANCELLED
# define SSL_AD_NO_RENEGOTIATION         TLS1_AD_NO_RENEGOTIATION
# define SSL_AD_UNSUPPORTED_EXTENSION    TLS1_AD_UNSUPPORTED_EXTENSION
# define SSL_AD_CERTIFICATE_UNOBTAINABLE TLS1_AD_CERTIFICATE_UNOBTAINABLE
# define SSL_AD_UNRECOGNIZED_NAME        TLS1_AD_UNRECOGNIZED_NAME
# define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE
# define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE
/* fatal */
# define SSL_AD_UNKNOWN_PSK_IDENTITY     TLS1_AD_UNKNOWN_PSK_IDENTITY
/* fatal */
# define SSL_AD_INAPPROPRIATE_FALLBACK   TLS1_AD_INAPPROPRIATE_FALLBACK
# define SSL_ERROR_NONE                  0
# define SSL_ERROR_SSL                   1
# define SSL_ERROR_WANT_READ             2
# define SSL_ERROR_WANT_WRITE            3
# define SSL_ERROR_WANT_X509_LOOKUP      4
# define SSL_ERROR_SYSCALL               5/* look at error stack/return
                                           * value/errno */
# define SSL_ERROR_ZERO_RETURN           6
# define SSL_ERROR_WANT_CONNECT          7
# define SSL_ERROR_WANT_ACCEPT           8
# define SSL_CTRL_NEED_TMP_RSA                   1
# define SSL_CTRL_SET_TMP_RSA                    2
# define SSL_CTRL_SET_TMP_DH                     3
# define SSL_CTRL_SET_TMP_ECDH                   4
# define SSL_CTRL_SET_TMP_RSA_CB                 5
# define SSL_CTRL_SET_TMP_DH_CB                  6
# define SSL_CTRL_SET_TMP_ECDH_CB                7
# define SSL_CTRL_GET_SESSION_REUSED             8
# define SSL_CTRL_GET_CLIENT_CERT_REQUEST        9
# define SSL_CTRL_GET_NUM_RENEGOTIATIONS         10
# define SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS       11
# define SSL_CTRL_GET_TOTAL_RENEGOTIATIONS       12
# define SSL_CTRL_GET_FLAGS                      13
# define SSL_CTRL_EXTRA_CHAIN_CERT               14
# define SSL_CTRL_SET_MSG_CALLBACK               15
# define SSL_CTRL_SET_MSG_CALLBACK_ARG           16
/* only applies to datagram connections */
# define SSL_CTRL_SET_MTU                17
/* Stats */
# define SSL_CTRL_SESS_NUMBER                    20
# define SSL_CTRL_SESS_CONNECT                   21
# define SSL_CTRL_SESS_CONNECT_GOOD              22
# define SSL_CTRL_SESS_CONNECT_RENEGOTIATE       23
# define SSL_CTRL_SESS_ACCEPT                    24
# define SSL_CTRL_SESS_ACCEPT_GOOD               25
# define SSL_CTRL_SESS_ACCEPT_RENEGOTIATE        26
# define SSL_CTRL_SESS_HIT                       27
# define SSL_CTRL_SESS_CB_HIT                    28
# define SSL_CTRL_SESS_MISSES                    29
# define SSL_CTRL_SESS_TIMEOUTS                  30
# define SSL_CTRL_SESS_CACHE_FULL                31
# define SSL_CTRL_OPTIONS                        32
# define SSL_CTRL_MODE                           33
# define SSL_CTRL_GET_READ_AHEAD                 40
# define SSL_CTRL_SET_READ_AHEAD                 41
# define SSL_CTRL_SET_SESS_CACHE_SIZE            42
# define SSL_CTRL_GET_SESS_CACHE_SIZE            43
# define SSL_CTRL_SET_SESS_CACHE_MODE            44
# define SSL_CTRL_GET_SESS_CACHE_MODE            45
# define SSL_CTRL_GET_MAX_CERT_LIST              50
# define SSL_CTRL_SET_MAX_CERT_LIST              51
# define SSL_CTRL_SET_MAX_SEND_FRAGMENT          52
/* see tls1.h for macros based on these */
# ifndef OPENSSL_NO_TLSEXT
#  define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB       53
#  define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG      54
#  define SSL_CTRL_SET_TLSEXT_HOSTNAME            55
#  define SSL_CTRL_SET_TLSEXT_DEBUG_CB            56
#  define SSL_CTRL_SET_TLSEXT_DEBUG_ARG           57
#  define SSL_CTRL_GET_TLSEXT_TICKET_KEYS         58
#  define SSL_CTRL_SET_TLSEXT_TICKET_KEYS         59
#  define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT    60
#  define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB 61
#  define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG 62
#  define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB       63
#  define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG   64
#  define SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE     65
#  define SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS     66
#  define SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS     67
#  define SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS      68
#  define SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS      69
#  define SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP        70
#  define SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP        71
#  define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB       72
#  define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB    75
#  define SSL_CTRL_SET_SRP_VERIFY_PARAM_CB                76
#  define SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB             77
#  define SSL_CTRL_SET_SRP_ARG            78
#  define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME               79
#  define SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH               80
#  define SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD               81
#  ifndef OPENSSL_NO_HEARTBEATS
#   define SSL_CTRL_TLS_EXT_SEND_HEARTBEAT                         85
#   define SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING          86
#   define SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS      87
#  endif
# endif                         /* OPENSSL_NO_TLSEXT */
# define DTLS_CTRL_GET_TIMEOUT           73
# define DTLS_CTRL_HANDLE_TIMEOUT        74
# define DTLS_CTRL_LISTEN                        75
# define SSL_CTRL_GET_RI_SUPPORT                 76
# define SSL_CTRL_CLEAR_OPTIONS                  77
# define SSL_CTRL_CLEAR_MODE                     78
# define SSL_CTRL_GET_EXTRA_CHAIN_CERTS          82
# define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS        83
# define SSL_CTRL_CHAIN                          88
# define SSL_CTRL_CHAIN_CERT                     89
# define SSL_CTRL_GET_CURVES                     90
# define SSL_CTRL_SET_CURVES                     91
# define SSL_CTRL_SET_CURVES_LIST                92
# define SSL_CTRL_GET_SHARED_CURVE               93
# define SSL_CTRL_SET_ECDH_AUTO                  94
# define SSL_CTRL_SET_SIGALGS                    97
# define SSL_CTRL_SET_SIGALGS_LIST               98
# define SSL_CTRL_CERT_FLAGS                     99
# define SSL_CTRL_CLEAR_CERT_FLAGS               100
# define SSL_CTRL_SET_CLIENT_SIGALGS             101
# define SSL_CTRL_SET_CLIENT_SIGALGS_LIST        102
# define SSL_CTRL_GET_CLIENT_CERT_TYPES          103
# define SSL_CTRL_SET_CLIENT_CERT_TYPES          104
# define SSL_CTRL_BUILD_CERT_CHAIN               105
# define SSL_CTRL_SET_VERIFY_CERT_STORE          106
# define SSL_CTRL_SET_CHAIN_CERT_STORE           107
# define SSL_CTRL_GET_PEER_SIGNATURE_NID         108
# define SSL_CTRL_GET_SERVER_TMP_KEY             109
# define SSL_CTRL_GET_RAW_CIPHERLIST             110
# define SSL_CTRL_GET_EC_POINT_FORMATS           111
# define SSL_CTRL_GET_CHAIN_CERTS                115
# define SSL_CTRL_SELECT_CURRENT_CERT            116
# define SSL_CTRL_SET_CURRENT_CERT               117
# define SSL_CTRL_CHECK_PROTO_VERSION            119
# define DTLS_CTRL_SET_LINK_MTU                  120
# define DTLS_CTRL_GET_LINK_MIN_MTU              121
# define SSL_CERT_SET_FIRST                      1
# define SSL_CERT_SET_NEXT                       2
# define SSL_CERT_SET_SERVER                     3
# define DTLSv1_get_timeout(ssl, arg) \
        SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg)
# define DTLSv1_handle_timeout(ssl) \
        SSL_ctrl(ssl,DTLS_CTRL_HANDLE_TIMEOUT,0, NULL)
# define DTLSv1_listen(ssl, peer) \
        SSL_ctrl(ssl,DTLS_CTRL_LISTEN,0, (void *)peer)
# define SSL_session_reused(ssl) \
        SSL_ctrl((ssl),SSL_CTRL_GET_SESSION_REUSED,0,NULL)
# define SSL_num_renegotiations(ssl) \
        SSL_ctrl((ssl),SSL_CTRL_GET_NUM_RENEGOTIATIONS,0,NULL)
# define SSL_clear_num_renegotiations(ssl) \
        SSL_ctrl((ssl),SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS,0,NULL)
# define SSL_total_renegotiations(ssl) \
        SSL_ctrl((ssl),SSL_CTRL_GET_TOTAL_RENEGOTIATIONS,0,NULL)
# define SSL_CTX_need_tmp_RSA(ctx) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_NEED_TMP_RSA,0,NULL)
# define SSL_CTX_set_tmp_rsa(ctx,rsa) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_RSA,0,(char *)rsa)
# define SSL_CTX_set_tmp_dh(ctx,dh) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_DH,0,(char *)dh)
# define SSL_CTX_set_tmp_ecdh(ctx,ecdh) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh)
# define SSL_need_tmp_RSA(ssl) \
        SSL_ctrl(ssl,SSL_CTRL_NEED_TMP_RSA,0,NULL)
# define SSL_set_tmp_rsa(ssl,rsa) \
        SSL_ctrl(ssl,SSL_CTRL_SET_TMP_RSA,0,(char *)rsa)
# define SSL_set_tmp_dh(ssl,dh) \
        SSL_ctrl(ssl,SSL_CTRL_SET_TMP_DH,0,(char *)dh)
# define SSL_set_tmp_ecdh(ssl,ecdh) \
        SSL_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh)
# define SSL_CTX_add_extra_chain_cert(ctx,x509) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_EXTRA_CHAIN_CERT,0,(char *)x509)
# define SSL_CTX_get_extra_chain_certs(ctx,px509) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_GET_EXTRA_CHAIN_CERTS,0,px509)
# define SSL_CTX_get_extra_chain_certs_only(ctx,px509) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_GET_EXTRA_CHAIN_CERTS,1,px509)
# define SSL_CTX_clear_extra_chain_certs(ctx) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS,0,NULL)
# define SSL_CTX_set0_chain(ctx,sk) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN,0,(char *)sk)
# define SSL_CTX_set1_chain(ctx,sk) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN,1,(char *)sk)
# define SSL_CTX_add0_chain_cert(ctx,x509) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN_CERT,0,(char *)x509)
# define SSL_CTX_add1_chain_cert(ctx,x509) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN_CERT,1,(char *)x509)
# define SSL_CTX_get0_chain_certs(ctx,px509) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_GET_CHAIN_CERTS,0,px509)
# define SSL_CTX_clear_chain_certs(ctx) \
        SSL_CTX_set0_chain(ctx,NULL)
# define SSL_CTX_build_cert_chain(ctx, flags) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_BUILD_CERT_CHAIN, flags, NULL)
# define SSL_CTX_select_current_cert(ctx,x509) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SELECT_CURRENT_CERT,0,(char *)x509)
# define SSL_CTX_set_current_cert(ctx, op) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CURRENT_CERT, op, NULL)
# define SSL_CTX_set0_verify_cert_store(ctx,st) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_VERIFY_CERT_STORE,0,(char *)st)
# define SSL_CTX_set1_verify_cert_store(ctx,st) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_VERIFY_CERT_STORE,1,(char *)st)
# define SSL_CTX_set0_chain_cert_store(ctx,st) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHAIN_CERT_STORE,0,(char *)st)
# define SSL_CTX_set1_chain_cert_store(ctx,st) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHAIN_CERT_STORE,1,(char *)st)
# define SSL_set0_chain(ctx,sk) \
        SSL_ctrl(ctx,SSL_CTRL_CHAIN,0,(char *)sk)
# define SSL_set1_chain(ctx,sk) \
        SSL_ctrl(ctx,SSL_CTRL_CHAIN,1,(char *)sk)
# define SSL_add0_chain_cert(ctx,x509) \
        SSL_ctrl(ctx,SSL_CTRL_CHAIN_CERT,0,(char *)x509)
# define SSL_add1_chain_cert(ctx,x509) \
        SSL_ctrl(ctx,SSL_CTRL_CHAIN_CERT,1,(char *)x509)
# define SSL_get0_chain_certs(ctx,px509) \
        SSL_ctrl(ctx,SSL_CTRL_GET_CHAIN_CERTS,0,px509)
# define SSL_clear_chain_certs(ctx) \
        SSL_set0_chain(ctx,NULL)
# define SSL_build_cert_chain(s, flags) \
        SSL_ctrl(s,SSL_CTRL_BUILD_CERT_CHAIN, flags, NULL)
# define SSL_select_current_cert(ctx,x509) \
        SSL_ctrl(ctx,SSL_CTRL_SELECT_CURRENT_CERT,0,(char *)x509)
# define SSL_set_current_cert(ctx,op) \
        SSL_ctrl(ctx,SSL_CTRL_SET_CURRENT_CERT, op, NULL)
# define SSL_set0_verify_cert_store(s,st) \
        SSL_ctrl(s,SSL_CTRL_SET_VERIFY_CERT_STORE,0,(char *)st)
# define SSL_set1_verify_cert_store(s,st) \
        SSL_ctrl(s,SSL_CTRL_SET_VERIFY_CERT_STORE,1,(char *)st)
# define SSL_set0_chain_cert_store(s,st) \
        SSL_ctrl(s,SSL_CTRL_SET_CHAIN_CERT_STORE,0,(char *)st)
# define SSL_set1_chain_cert_store(s,st) \
        SSL_ctrl(s,SSL_CTRL_SET_CHAIN_CERT_STORE,1,(char *)st)
# define SSL_get1_curves(ctx, s) \
        SSL_ctrl(ctx,SSL_CTRL_GET_CURVES,0,(char *)s)
# define SSL_CTX_set1_curves(ctx, clist, clistlen) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CURVES,clistlen,(char *)clist)
# define SSL_CTX_set1_curves_list(ctx, s) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CURVES_LIST,0,(char *)s)
# define SSL_set1_curves(ctx, clist, clistlen) \
        SSL_ctrl(ctx,SSL_CTRL_SET_CURVES,clistlen,(char *)clist)
# define SSL_set1_curves_list(ctx, s) \
        SSL_ctrl(ctx,SSL_CTRL_SET_CURVES_LIST,0,(char *)s)
# define SSL_get_shared_curve(s, n) \
        SSL_ctrl(s,SSL_CTRL_GET_SHARED_CURVE,n,NULL)
# define SSL_CTX_set_ecdh_auto(ctx, onoff) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_ECDH_AUTO,onoff,NULL)
# define SSL_set_ecdh_auto(s, onoff) \
        SSL_ctrl(s,SSL_CTRL_SET_ECDH_AUTO,onoff,NULL)
# define SSL_CTX_set1_sigalgs(ctx, slist, slistlen) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SIGALGS,slistlen,(int *)slist)
# define SSL_CTX_set1_sigalgs_list(ctx, s) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SIGALGS_LIST,0,(char *)s)
# define SSL_set1_sigalgs(ctx, slist, slistlen) \
        SSL_ctrl(ctx,SSL_CTRL_SET_SIGALGS,slistlen,(int *)slist)
# define SSL_set1_sigalgs_list(ctx, s) \
        SSL_ctrl(ctx,SSL_CTRL_SET_SIGALGS_LIST,0,(char *)s)
# define SSL_CTX_set1_client_sigalgs(ctx, slist, slistlen) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS,slistlen,(int *)slist)
# define SSL_CTX_set1_client_sigalgs_list(ctx, s) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS_LIST,0,(char *)s)
# define SSL_set1_client_sigalgs(ctx, slist, slistlen) \
        SSL_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS,clistlen,(int *)slist)
# define SSL_set1_client_sigalgs_list(ctx, s) \
        SSL_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS_LIST,0,(char *)s)
# define SSL_get0_certificate_types(s, clist) \
        SSL_ctrl(s, SSL_CTRL_GET_CLIENT_CERT_TYPES, 0, (char *)clist)
# define SSL_CTX_set1_client_certificate_types(ctx, clist, clistlen) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_CERT_TYPES,clistlen,(char *)clist)
# define SSL_set1_client_certificate_types(s, clist, clistlen) \
        SSL_ctrl(s,SSL_CTRL_SET_CLIENT_CERT_TYPES,clistlen,(char *)clist)
# define SSL_get_peer_signature_nid(s, pn) \
        SSL_ctrl(s,SSL_CTRL_GET_PEER_SIGNATURE_NID,0,pn)
# define SSL_get_server_tmp_key(s, pk) \
        SSL_ctrl(s,SSL_CTRL_GET_SERVER_TMP_KEY,0,pk)
# define SSL_get0_raw_cipherlist(s, plst) \
        SSL_ctrl(s,SSL_CTRL_GET_RAW_CIPHERLIST,0,(char *)plst)
# define SSL_get0_ec_point_formats(s, plst) \
        SSL_ctrl(s,SSL_CTRL_GET_EC_POINT_FORMATS,0,(char *)plst)
# ifndef OPENSSL_NO_BIO
BIO_METHOD *BIO_f_ssl(void);
BIO *BIO_new_ssl(SSL_CTX *ctx, int client);
BIO *BIO_new_ssl_connect(SSL_CTX *ctx);
BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx);
int BIO_ssl_copy_session_id(BIO *to, BIO *from);
void BIO_ssl_shutdown(BIO *ssl_bio);

# endif

int SSL_CTX_set_cipher_list(SSL_CTX *, const char *str);
SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth);
void SSL_CTX_free(SSL_CTX *);
long SSL_CTX_set_timeout(SSL_CTX *ctx, long t);
long SSL_CTX_get_timeout(const SSL_CTX *ctx);
X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *);
void SSL_CTX_set_cert_store(SSL_CTX *, X509_STORE *);
int SSL_want(const SSL *s);
int SSL_clear(SSL *s);

void SSL_CTX_flush_sessions(SSL_CTX *ctx, long tm);

const SSL_CIPHER *SSL_get_current_cipher(const SSL *s);
int SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits);
char *SSL_CIPHER_get_version(const SSL_CIPHER *c);
const char *SSL_CIPHER_get_name(const SSL_CIPHER *c);
unsigned long SSL_CIPHER_get_id(const SSL_CIPHER *c);

int SSL_get_fd(const SSL *s);
int SSL_get_rfd(const SSL *s);
int SSL_get_wfd(const SSL *s);
const char *SSL_get_cipher_list(const SSL *s, int n);
char *SSL_get_shared_ciphers(const SSL *s, char *buf, int size);
int SSL_get_read_ahead(const SSL *s);
int SSL_pending(const SSL *s);
# ifndef OPENSSL_NO_SOCK
int SSL_set_fd(SSL *s, int fd);
int SSL_set_rfd(SSL *s, int fd);
int SSL_set_wfd(SSL *s, int fd);
# endif
# ifndef OPENSSL_NO_BIO
void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio);
BIO *SSL_get_rbio(const SSL *s);
BIO *SSL_get_wbio(const SSL *s);
# endif
int SSL_set_cipher_list(SSL *s, const char *str);
void SSL_set_read_ahead(SSL *s, int yes);
int SSL_get_verify_mode(const SSL *s);
int SSL_get_verify_depth(const SSL *s);
int (*SSL_get_verify_callback(const SSL *s)) (int, X509_STORE_CTX *);
void SSL_set_verify(SSL *s, int mode,
                    int (*callback) (int ok, X509_STORE_CTX *ctx));
void SSL_set_verify_depth(SSL *s, int depth);
void SSL_set_cert_cb(SSL *s, int (*cb) (SSL *ssl, void *arg), void *arg);
# ifndef OPENSSL_NO_RSA
int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa);
# endif
int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, unsigned char *d, long len);
int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey);
int SSL_use_PrivateKey_ASN1(int pk, SSL *ssl, const unsigned char *d,
                            long len);
int SSL_use_certificate(SSL *ssl, X509 *x);
int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len);

# ifndef OPENSSL_NO_TLSEXT
/* Set serverinfo data for the current active cert. */
int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo,
                           size_t serverinfo_length);
#  ifndef OPENSSL_NO_STDIO
int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file);
#  endif                        /* NO_STDIO */

# endif

# ifndef OPENSSL_NO_STDIO
int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type);
int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type);
int SSL_use_certificate_file(SSL *ssl, const char *file, int type);
int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type);
int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type);
int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type);
/* PEM type */
int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file);
STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file);
int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs,
                                        const char *file);
#  ifndef OPENSSL_SYS_VMS
/* XXXXX: Better scheme needed! [was: #ifndef MAC_OS_pre_X] */
#   ifndef OPENSSL_SYS_MACINTOSH_CLASSIC
int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs,
                                       const char *dir);
#   endif
#  endif

# endif

void SSL_load_error_strings(void);
const char *SSL_state_string(const SSL *s);
const char *SSL_rstate_string(const SSL *s);
const char *SSL_state_string_long(const SSL *s);
const char *SSL_rstate_string_long(const SSL *s);
long SSL_SESSION_get_time(const SSL_SESSION *s);
long SSL_SESSION_set_time(SSL_SESSION *s, long t);
long SSL_SESSION_get_timeout(const SSL_SESSION *s);
long SSL_SESSION_set_timeout(SSL_SESSION *s, long t);
void SSL_copy_session_id(SSL *to, const SSL *from);
X509 *SSL_SESSION_get0_peer(SSL_SESSION *s);
int SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned char *sid_ctx,
                                unsigned int sid_ctx_len);

SSL_SESSION *SSL_SESSION_new(void);
const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s,
                                        unsigned int *len);
unsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *s);
# ifndef OPENSSL_NO_FP_API
int SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *ses);
# endif
# ifndef OPENSSL_NO_BIO
int SSL_SESSION_print(BIO *fp, const SSL_SESSION *ses);
# endif
void SSL_SESSION_free(SSL_SESSION *ses);
int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp);
int SSL_set_session(SSL *to, SSL_SESSION *session);
int SSL_CTX_add_session(SSL_CTX *s, SSL_SESSION *c);
int SSL_CTX_remove_session(SSL_CTX *, SSL_SESSION *c);
int SSL_CTX_set_generate_session_id(SSL_CTX *, GEN_SESSION_CB);
int SSL_set_generate_session_id(SSL *, GEN_SESSION_CB);
int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id,
                                unsigned int id_len);
SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
                             long length);

# ifdef HEADER_X509_H
X509 *SSL_get_peer_certificate(const SSL *s);
# endif

STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s);

int SSL_CTX_get_verify_mode(const SSL_CTX *ctx);
int SSL_CTX_get_verify_depth(const SSL_CTX *ctx);
int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx)) (int,
                                                        X509_STORE_CTX *);
void SSL_CTX_set_verify(SSL_CTX *ctx, int mode,
                        int (*callback) (int, X509_STORE_CTX *));
void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth);
void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx,
                                      int (*cb) (X509_STORE_CTX *, void *),
                                      void *arg);
void SSL_CTX_set_cert_cb(SSL_CTX *c, int (*cb) (SSL *ssl, void *arg),
                         void *arg);
# ifndef OPENSSL_NO_RSA
int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa);
# endif
int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d,
                                   long len);
int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey);
int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx,
                                const unsigned char *d, long len);
int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x);
int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len,
                                 const unsigned char *d);

void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb);
void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u);

int SSL_CTX_check_private_key(const SSL_CTX *ctx);
int SSL_check_private_key(const SSL *ctx);

int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx,
                                   unsigned int sid_ctx_len);

SSL *SSL_new(SSL_CTX *ctx);
int SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx,
                               unsigned int sid_ctx_len);

int SSL_CTX_set_purpose(SSL_CTX *s, int purpose);
int SSL_set_purpose(SSL *s, int purpose);
int SSL_CTX_set_trust(SSL_CTX *s, int trust);
int SSL_set_trust(SSL *s, int trust);

int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm);
int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm);

X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx);
X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl);

# ifndef OPENSSL_NO_SRP
int SSL_CTX_set_srp_username(SSL_CTX *ctx, char *name);
int SSL_CTX_set_srp_password(SSL_CTX *ctx, char *password);
int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength);
int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx,
                                        char *(*cb) (SSL *, void *));
int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx,
                                          int (*cb) (SSL *, void *));
int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx,
                                      int (*cb) (SSL *, int *, void *));
int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg);

int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g,
                             BIGNUM *sa, BIGNUM *v, char *info);
int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass,
                                const char *grp);

BIGNUM *SSL_get_srp_g(SSL *s);
BIGNUM *SSL_get_srp_N(SSL *s);

char *SSL_get_srp_username(SSL *s);
char *SSL_get_srp_userinfo(SSL *s);
# endif

void SSL_certs_clear(SSL *s);
void SSL_free(SSL *ssl);
int SSL_accept(SSL *ssl);
int SSL_connect(SSL *ssl);
int SSL_read(SSL *ssl, void *buf, int num);
int SSL_peek(SSL *ssl, void *buf, int num);
int SSL_write(SSL *ssl, const void *buf, int num);
long SSL_ctrl(SSL *ssl, int cmd, long larg, void *parg);
long SSL_callback_ctrl(SSL *, int, void (*)(void));
long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg);
long SSL_CTX_callback_ctrl(SSL_CTX *, int, void (*)(void));

int SSL_get_error(const SSL *s, int ret_code);
const char *SSL_get_version(const SSL *s);

/* This sets the 'default' SSL version that SSL_new() will create */
int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth);

# ifndef OPENSSL_NO_SSL2_METHOD
const SSL_METHOD *SSLv2_method(void); /* SSLv2 */
const SSL_METHOD *SSLv2_server_method(void); /* SSLv2 */
const SSL_METHOD *SSLv2_client_method(void); /* SSLv2 */
# endif

# ifndef OPENSSL_NO_SSL3_METHOD
const SSL_METHOD *SSLv3_method(void); /* SSLv3 */
const SSL_METHOD *SSLv3_server_method(void); /* SSLv3 */
const SSL_METHOD *SSLv3_client_method(void); /* SSLv3 */
# endif

const SSL_METHOD *SSLv23_method(void); /* Negotiate highest available SSL/TLS
                                        * version */
const SSL_METHOD *SSLv23_server_method(void); /* Negotiate highest available
                                               * SSL/TLS version */
const SSL_METHOD *SSLv23_client_method(void); /* Negotiate highest available
                                               * SSL/TLS version */

const SSL_METHOD *TLSv1_method(void); /* TLSv1.0 */
const SSL_METHOD *TLSv1_server_method(void); /* TLSv1.0 */
const SSL_METHOD *TLSv1_client_method(void); /* TLSv1.0 */

const SSL_METHOD *TLSv1_1_method(void); /* TLSv1.1 */
const SSL_METHOD *TLSv1_1_server_method(void); /* TLSv1.1 */
const SSL_METHOD *TLSv1_1_client_method(void); /* TLSv1.1 */

const SSL_METHOD *TLSv1_2_method(void); /* TLSv1.2 */
const SSL_METHOD *TLSv1_2_server_method(void); /* TLSv1.2 */
const SSL_METHOD *TLSv1_2_client_method(void); /* TLSv1.2 */

const SSL_METHOD *DTLSv1_method(void); /* DTLSv1.0 */
const SSL_METHOD *DTLSv1_server_method(void); /* DTLSv1.0 */
const SSL_METHOD *DTLSv1_client_method(void); /* DTLSv1.0 */

const SSL_METHOD *DTLSv1_2_method(void); /* DTLSv1.2 */
const SSL_METHOD *DTLSv1_2_server_method(void); /* DTLSv1.2 */
const SSL_METHOD *DTLSv1_2_client_method(void); /* DTLSv1.2 */

const SSL_METHOD *DTLS_method(void); /* DTLS 1.0 and 1.2 */
const SSL_METHOD *DTLS_server_method(void); /* DTLS 1.0 and 1.2 */
const SSL_METHOD *DTLS_client_method(void); /* DTLS 1.0 and 1.2 */

STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s);

int SSL_do_handshake(SSL *s);
int SSL_renegotiate(SSL *s);
int SSL_renegotiate_abbreviated(SSL *s);
int SSL_renegotiate_pending(SSL *s);
int SSL_shutdown(SSL *s);

const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx);
const SSL_METHOD *SSL_get_ssl_method(SSL *s);
int SSL_set_ssl_method(SSL *s, const SSL_METHOD *method);
const char *SSL_alert_type_string_long(int value);
const char *SSL_alert_type_string(int value);
const char *SSL_alert_desc_string_long(int value);
const char *SSL_alert_desc_string(int value);

void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list);
void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list);
STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s);
STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *s);
int SSL_add_client_CA(SSL *ssl, X509 *x);
int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x);

void SSL_set_connect_state(SSL *s);
void SSL_set_accept_state(SSL *s);

long SSL_get_default_timeout(const SSL *s);

int SSL_library_init(void);

char *SSL_CIPHER_description(const SSL_CIPHER *, char *buf, int size);
STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk);

SSL *SSL_dup(SSL *ssl);

X509 *SSL_get_certificate(const SSL *ssl);
/*
 * EVP_PKEY
 */ struct evp_pkey_st *SSL_get_privatekey(const SSL *ssl);

X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx);
EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx);

void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode);
int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx);
void SSL_set_quiet_shutdown(SSL *ssl, int mode);
int SSL_get_quiet_shutdown(const SSL *ssl);
void SSL_set_shutdown(SSL *ssl, int mode);
int SSL_get_shutdown(const SSL *ssl);
int SSL_version(const SSL *ssl);
int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx);
int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
                                  const char *CApath);
# define SSL_get0_session SSL_get_session/* just peek at pointer */
SSL_SESSION *SSL_get_session(const SSL *ssl);
SSL_SESSION *SSL_get1_session(SSL *ssl); /* obtain a reference count */
SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl);
SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx);
void SSL_set_info_callback(SSL *ssl,
                           void (*cb) (const SSL *ssl, int type, int val));
void (*SSL_get_info_callback(const SSL *ssl)) (const SSL *ssl, int type,
                                               int val);
int SSL_state(const SSL *ssl);
void SSL_set_state(SSL *ssl, int state);

void SSL_set_verify_result(SSL *ssl, long v);
long SSL_get_verify_result(const SSL *ssl);

int SSL_set_ex_data(SSL *ssl, int idx, void *data);
void *SSL_get_ex_data(const SSL *ssl, int idx);
int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
                         CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);

int SSL_SESSION_set_ex_data(SSL_SESSION *ss, int idx, void *data);
void *SSL_SESSION_get_ex_data(const SSL_SESSION *ss, int idx);
int SSL_SESSION_get_ex_new_index(long argl, void *argp,
                                 CRYPTO_EX_new *new_func,
                                 CRYPTO_EX_dup *dup_func,
                                 CRYPTO_EX_free *free_func);

int SSL_CTX_set_ex_data(SSL_CTX *ssl, int idx, void *data);
void *SSL_CTX_get_ex_data(const SSL_CTX *ssl, int idx);
int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
                             CRYPTO_EX_dup *dup_func,
                             CRYPTO_EX_free *free_func);

int SSL_get_ex_data_X509_STORE_CTX_idx(void);

# define SSL_CTX_sess_set_cache_size(ctx,t) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_SIZE,t,NULL)
# define SSL_CTX_sess_get_cache_size(ctx) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_SIZE,0,NULL)
# define SSL_CTX_set_session_cache_mode(ctx,m) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_MODE,m,NULL)
# define SSL_CTX_get_session_cache_mode(ctx) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_MODE,0,NULL)

# define SSL_CTX_get_default_read_ahead(ctx) SSL_CTX_get_read_ahead(ctx)
# define SSL_CTX_set_default_read_ahead(ctx,m) SSL_CTX_set_read_ahead(ctx,m)
# define SSL_CTX_get_read_ahead(ctx) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_GET_READ_AHEAD,0,NULL)
# define SSL_CTX_set_read_ahead(ctx,m) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_READ_AHEAD,m,NULL)
# define SSL_CTX_get_max_cert_list(ctx) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL)
# define SSL_CTX_set_max_cert_list(ctx,m) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL)
# define SSL_get_max_cert_list(ssl) \
        SSL_ctrl(ssl,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL)
# define SSL_set_max_cert_list(ssl,m) \
        SSL_ctrl(ssl,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL)

# define SSL_CTX_set_max_send_fragment(ctx,m) \
        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL)
# define SSL_set_max_send_fragment(ssl,m) \
        SSL_ctrl(ssl,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL)

     /* NB: the keylength is only applicable when is_export is true */
# ifndef OPENSSL_NO_RSA
void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx,
                                  RSA *(*cb) (SSL *ssl, int is_export,
                                              int keylength));

void SSL_set_tmp_rsa_callback(SSL *ssl,
                              RSA *(*cb) (SSL *ssl, int is_export,
                                          int keylength));
# endif
# ifndef OPENSSL_NO_DH
void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,
                                 DH *(*dh) (SSL *ssl, int is_export,
                                            int keylength));
void SSL_set_tmp_dh_callback(SSL *ssl,
                             DH *(*dh) (SSL *ssl, int is_export,
                                        int keylength));
# endif
# ifndef OPENSSL_NO_ECDH
void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx,
                                   EC_KEY *(*ecdh) (SSL *ssl, int is_export,
                                                    int keylength));
void SSL_set_tmp_ecdh_callback(SSL *ssl,
                               EC_KEY *(*ecdh) (SSL *ssl, int is_export,
                                                int keylength));
# endif

const COMP_METHOD *SSL_get_current_compression(SSL *s);
const COMP_METHOD *SSL_get_current_expansion(SSL *s);
const char *SSL_COMP_get_name(const COMP_METHOD *comp);
STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void);
STACK_OF(SSL_COMP) *SSL_COMP_set0_compression_methods(STACK_OF(SSL_COMP)
                                                      *meths);
void SSL_COMP_free_compression_methods(void);
int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm);

const SSL_CIPHER *SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr);

/* TLS extensions functions */
int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len);

int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb,
                                  void *arg);

/* Pre-shared secret session resumption functions */
int SSL_set_session_secret_cb(SSL *s,
                              tls_session_secret_cb_fn tls_session_secret_cb,
                              void *arg);

void SSL_set_debug(SSL *s, int debug);
int SSL_cache_hit(SSL *s);
int SSL_is_server(SSL *s);

SSL_CONF_CTX *SSL_CONF_CTX_new(void);
int SSL_CONF_CTX_finish(SSL_CONF_CTX *cctx);
void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx);
unsigned int SSL_CONF_CTX_set_flags(SSL_CONF_CTX *cctx, unsigned int flags);
unsigned int SSL_CONF_CTX_clear_flags(SSL_CONF_CTX *cctx, unsigned int flags);
int SSL_CONF_CTX_set1_prefix(SSL_CONF_CTX *cctx, const char *pre);

void SSL_CONF_CTX_set_ssl(SSL_CONF_CTX *cctx, SSL *ssl);
void SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX *cctx, SSL_CTX *ctx);

int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value);
int SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv);
int SSL_CONF_cmd_value_type(SSL_CONF_CTX *cctx, const char *cmd);

# ifndef OPENSSL_NO_SSL_TRACE
void SSL_trace(int write_p, int version, int content_type,
               const void *buf, size_t len, SSL *ssl, void *arg);
const char *SSL_CIPHER_standard_name(const SSL_CIPHER *c);
# endif

# ifndef OPENSSL_NO_UNIT_TEST
const struct openssl_ssl_test_functions *SSL_test_functions(void);
# endif

/* BEGIN ERROR CODES */
/*
 * The following lines are auto generated by the script mkerr.pl. Any changes
 * made after this point may be overwritten when the script is next run.
 */
void ERR_load_SSL_strings(void);

/* Error codes for the SSL functions. */

/* Function codes. */
# define SSL_F_CHECK_SUITEB_CIPHER_LIST                   331
# define SSL_F_CLIENT_CERTIFICATE                         100
# define SSL_F_CLIENT_FINISHED                            167
# define SSL_F_CLIENT_HELLO                               101
# define SSL_F_CLIENT_MASTER_KEY                          102
# define SSL_F_D2I_SSL_SESSION                            103
# define SSL_F_DO_DTLS1_WRITE                             245
# define SSL_F_DO_SSL3_WRITE                              104
# define SSL_F_DTLS1_ACCEPT                               246
# define SSL_F_DTLS1_ADD_CERT_TO_BUF                      295
# define SSL_F_DTLS1_BUFFER_RECORD                        247
# define SSL_F_DTLS1_CHECK_TIMEOUT_NUM                    316
# define SSL_F_DTLS1_CLIENT_HELLO                         248
# define SSL_F_DTLS1_CONNECT                              249
# define SSL_F_DTLS1_ENC                                  250
# define SSL_F_DTLS1_GET_HELLO_VERIFY                     251
# define SSL_F_DTLS1_GET_MESSAGE                          252
# define SSL_F_DTLS1_GET_MESSAGE_FRAGMENT                 253
# define SSL_F_DTLS1_GET_RECORD                           254
# define SSL_F_DTLS1_HANDLE_TIMEOUT                       297
# define SSL_F_DTLS1_HEARTBEAT                            305
# define SSL_F_DTLS1_OUTPUT_CERT_CHAIN                    255
# define SSL_F_DTLS1_PREPROCESS_FRAGMENT                  288
# define SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS             424
# define SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE           256
# define SSL_F_DTLS1_PROCESS_RECORD                       257
# define SSL_F_DTLS1_READ_BYTES                           258
# define SSL_F_DTLS1_READ_FAILED                          259
# define SSL_F_DTLS1_SEND_CERTIFICATE_REQUEST             260
# define SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE              261
# define SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE             262
# define SSL_F_DTLS1_SEND_CLIENT_VERIFY                   263
# define SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST            264
# define SSL_F_DTLS1_SEND_SERVER_CERTIFICATE              265
# define SSL_F_DTLS1_SEND_SERVER_HELLO                    266
# define SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE             267
# define SSL_F_DTLS1_WRITE_APP_DATA_BYTES                 268
# define SSL_F_GET_CLIENT_FINISHED                        105
# define SSL_F_GET_CLIENT_HELLO                           106
# define SSL_F_GET_CLIENT_MASTER_KEY                      107
# define SSL_F_GET_SERVER_FINISHED                        108
# define SSL_F_GET_SERVER_HELLO                           109
# define SSL_F_GET_SERVER_STATIC_DH_KEY                   340
# define SSL_F_GET_SERVER_VERIFY                          110
# define SSL_F_I2D_SSL_SESSION                            111
# define SSL_F_READ_N                                     112
# define SSL_F_REQUEST_CERTIFICATE                        113
# define SSL_F_SERVER_FINISH                              239
# define SSL_F_SERVER_HELLO                               114
# define SSL_F_SERVER_VERIFY                              240
# define SSL_F_SSL23_ACCEPT                               115
# define SSL_F_SSL23_CLIENT_HELLO                         116
# define SSL_F_SSL23_CONNECT                              117
# define SSL_F_SSL23_GET_CLIENT_HELLO                     118
# define SSL_F_SSL23_GET_SERVER_HELLO                     119
# define SSL_F_SSL23_PEEK                                 237
# define SSL_F_SSL23_READ                                 120
# define SSL_F_SSL23_WRITE                                121
# define SSL_F_SSL2_ACCEPT                                122
# define SSL_F_SSL2_CONNECT                               123
# define SSL_F_SSL2_ENC_INIT                              124
# define SSL_F_SSL2_GENERATE_KEY_MATERIAL                 241
# define SSL_F_SSL2_PEEK                                  234
# define SSL_F_SSL2_READ                                  125
# define SSL_F_SSL2_READ_INTERNAL                         236
# define SSL_F_SSL2_SET_CERTIFICATE                       126
# define SSL_F_SSL2_WRITE                                 127
# define SSL_F_SSL3_ACCEPT                                128
# define SSL_F_SSL3_ADD_CERT_TO_BUF                       296
# define SSL_F_SSL3_CALLBACK_CTRL                         233
# define SSL_F_SSL3_CHANGE_CIPHER_STATE                   129
# define SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM              130
# define SSL_F_SSL3_CHECK_CLIENT_HELLO                    304
# define SSL_F_SSL3_CHECK_FINISHED                        339
# define SSL_F_SSL3_CLIENT_HELLO                          131
# define SSL_F_SSL3_CONNECT                               132
# define SSL_F_SSL3_CTRL                                  213
# define SSL_F_SSL3_CTX_CTRL                              133
# define SSL_F_SSL3_DIGEST_CACHED_RECORDS                 293
# define SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC                 292
# define SSL_F_SSL3_ENC                                   134
# define SSL_F_SSL3_GENERATE_KEY_BLOCK                    238
# define SSL_F_SSL3_GENERATE_MASTER_SECRET                388
# define SSL_F_SSL3_GET_CERTIFICATE_REQUEST               135
# define SSL_F_SSL3_GET_CERT_STATUS                       289
# define SSL_F_SSL3_GET_CERT_VERIFY                       136
# define SSL_F_SSL3_GET_CLIENT_CERTIFICATE                137
# define SSL_F_SSL3_GET_CLIENT_HELLO                      138
# define SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE               139
# define SSL_F_SSL3_GET_FINISHED                          140
# define SSL_F_SSL3_GET_KEY_EXCHANGE                      141
# define SSL_F_SSL3_GET_MESSAGE                           142
# define SSL_F_SSL3_GET_NEW_SESSION_TICKET                283
# define SSL_F_SSL3_GET_NEXT_PROTO                        306
# define SSL_F_SSL3_GET_RECORD                            143
# define SSL_F_SSL3_GET_SERVER_CERTIFICATE                144
# define SSL_F_SSL3_GET_SERVER_DONE                       145
# define SSL_F_SSL3_GET_SERVER_HELLO                      146
# define SSL_F_SSL3_HANDSHAKE_MAC                         285
# define SSL_F_SSL3_NEW_SESSION_TICKET                    287
# define SSL_F_SSL3_OUTPUT_CERT_CHAIN                     147
# define SSL_F_SSL3_PEEK                                  235
# define SSL_F_SSL3_READ_BYTES                            148
# define SSL_F_SSL3_READ_N                                149
# define SSL_F_SSL3_SEND_CERTIFICATE_REQUEST              150
# define SSL_F_SSL3_SEND_CLIENT_CERTIFICATE               151
# define SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE              152
# define SSL_F_SSL3_SEND_CLIENT_VERIFY                    153
# define SSL_F_SSL3_SEND_SERVER_CERTIFICATE               154
# define SSL_F_SSL3_SEND_SERVER_HELLO                     242
# define SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE              155
# define SSL_F_SSL3_SETUP_KEY_BLOCK                       157
# define SSL_F_SSL3_SETUP_READ_BUFFER                     156
# define SSL_F_SSL3_SETUP_WRITE_BUFFER                    291
# define SSL_F_SSL3_WRITE_BYTES                           158
# define SSL_F_SSL3_WRITE_PENDING                         159
# define SSL_F_SSL_ADD_CERT_CHAIN                         318
# define SSL_F_SSL_ADD_CERT_TO_BUF                        319
# define SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT        298
# define SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT                 277
# define SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT           307
# define SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK         215
# define SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK        216
# define SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT        299
# define SSL_F_SSL_ADD_SERVERHELLO_TLSEXT                 278
# define SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT           308
# define SSL_F_SSL_BAD_METHOD                             160
# define SSL_F_SSL_BUILD_CERT_CHAIN                       332
# define SSL_F_SSL_BYTES_TO_CIPHER_LIST                   161
# define SSL_F_SSL_CERT_DUP                               221
# define SSL_F_SSL_CERT_INST                              222
# define SSL_F_SSL_CERT_INSTANTIATE                       214
# define SSL_F_SSL_CERT_NEW                               162
# define SSL_F_SSL_CHECK_PRIVATE_KEY                      163
# define SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT               280
# define SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG            279
# define SSL_F_SSL_CIPHER_PROCESS_RULESTR                 230
# define SSL_F_SSL_CIPHER_STRENGTH_SORT                   231
# define SSL_F_SSL_CLEAR                                  164
# define SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD            165
# define SSL_F_SSL_CONF_CMD                               334
# define SSL_F_SSL_CREATE_CIPHER_LIST                     166
# define SSL_F_SSL_CTRL                                   232
# define SSL_F_SSL_CTX_CHECK_PRIVATE_KEY                  168
# define SSL_F_SSL_CTX_MAKE_PROFILES                      309
# define SSL_F_SSL_CTX_NEW                                169
# define SSL_F_SSL_CTX_SET_CIPHER_LIST                    269
# define SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE             290
# define SSL_F_SSL_CTX_SET_PURPOSE                        226
# define SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT             219
# define SSL_F_SSL_CTX_SET_SSL_VERSION                    170
# define SSL_F_SSL_CTX_SET_TRUST                          229
# define SSL_F_SSL_CTX_USE_CERTIFICATE                    171
# define SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1               172
# define SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE         220
# define SSL_F_SSL_CTX_USE_CERTIFICATE_FILE               173
# define SSL_F_SSL_CTX_USE_PRIVATEKEY                     174
# define SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1                175
# define SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE                176
# define SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT              272
# define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY                  177
# define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1             178
# define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE             179
# define SSL_F_SSL_CTX_USE_SERVERINFO                     336
# define SSL_F_SSL_CTX_USE_SERVERINFO_FILE                337
# define SSL_F_SSL_DO_HANDSHAKE                           180
# define SSL_F_SSL_GET_NEW_SESSION                        181
# define SSL_F_SSL_GET_PREV_SESSION                       217
# define SSL_F_SSL_GET_SERVER_CERT_INDEX                  322
# define SSL_F_SSL_GET_SERVER_SEND_CERT                   182
# define SSL_F_SSL_GET_SERVER_SEND_PKEY                   317
# define SSL_F_SSL_GET_SIGN_PKEY                          183
# define SSL_F_SSL_INIT_WBIO_BUFFER                       184
# define SSL_F_SSL_LOAD_CLIENT_CA_FILE                    185
# define SSL_F_SSL_NEW                                    186
# define SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT      300
# define SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT               302
# define SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT         310
# define SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT      301
# define SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT               303
# define SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT         311
# define SSL_F_SSL_PEEK                                   270
# define SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT             281
# define SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT             282
# define SSL_F_SSL_READ                                   223
# define SSL_F_SSL_RSA_PRIVATE_DECRYPT                    187
# define SSL_F_SSL_RSA_PUBLIC_ENCRYPT                     188
# define SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT                320
# define SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT                321
# define SSL_F_SSL_SESSION_DUP                            348
# define SSL_F_SSL_SESSION_NEW                            189
# define SSL_F_SSL_SESSION_PRINT_FP                       190
# define SSL_F_SSL_SESSION_SET1_ID_CONTEXT                312
# define SSL_F_SSL_SESS_CERT_NEW                          225
# define SSL_F_SSL_SET_CERT                               191
# define SSL_F_SSL_SET_CIPHER_LIST                        271
# define SSL_F_SSL_SET_FD                                 192
# define SSL_F_SSL_SET_PKEY                               193
# define SSL_F_SSL_SET_PURPOSE                            227
# define SSL_F_SSL_SET_RFD                                194
# define SSL_F_SSL_SET_SESSION                            195
# define SSL_F_SSL_SET_SESSION_ID_CONTEXT                 218
# define SSL_F_SSL_SET_SESSION_TICKET_EXT                 294
# define SSL_F_SSL_SET_TRUST                              228
# define SSL_F_SSL_SET_WFD                                196
# define SSL_F_SSL_SHUTDOWN                               224
# define SSL_F_SSL_SRP_CTX_INIT                           313
# define SSL_F_SSL_UNDEFINED_CONST_FUNCTION               243
# define SSL_F_SSL_UNDEFINED_FUNCTION                     197
# define SSL_F_SSL_UNDEFINED_VOID_FUNCTION                244
# define SSL_F_SSL_USE_CERTIFICATE                        198
# define SSL_F_SSL_USE_CERTIFICATE_ASN1                   199
# define SSL_F_SSL_USE_CERTIFICATE_FILE                   200
# define SSL_F_SSL_USE_PRIVATEKEY                         201
# define SSL_F_SSL_USE_PRIVATEKEY_ASN1                    202
# define SSL_F_SSL_USE_PRIVATEKEY_FILE                    203
# define SSL_F_SSL_USE_PSK_IDENTITY_HINT                  273
# define SSL_F_SSL_USE_RSAPRIVATEKEY                      204
# define SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1                 205
# define SSL_F_SSL_USE_RSAPRIVATEKEY_FILE                 206
# define SSL_F_SSL_VERIFY_CERT_CHAIN                      207
# define SSL_F_SSL_WRITE                                  208
# define SSL_F_TLS12_CHECK_PEER_SIGALG                    333
# define SSL_F_TLS1_CERT_VERIFY_MAC                       286
# define SSL_F_TLS1_CHANGE_CIPHER_STATE                   209
# define SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT              274
# define SSL_F_TLS1_ENC                                   210
# define SSL_F_TLS1_EXPORT_KEYING_MATERIAL                314
# define SSL_F_TLS1_GET_CURVELIST                         338
# define SSL_F_TLS1_HEARTBEAT                             315
# define SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT            275
# define SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT            276
# define SSL_F_TLS1_PRF                                   284
# define SSL_F_TLS1_SETUP_KEY_BLOCK                       211
# define SSL_F_TLS1_SET_SERVER_SIGALGS                    335
# define SSL_F_WRITE_PENDING                              212

/* Reason codes. */
# define SSL_R_APP_DATA_IN_HANDSHAKE                      100
# define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272
# define SSL_R_BAD_ALERT_RECORD                           101
# define SSL_R_BAD_AUTHENTICATION_TYPE                    102
# define SSL_R_BAD_CHANGE_CIPHER_SPEC                     103
# define SSL_R_BAD_CHECKSUM                               104
# define SSL_R_BAD_DATA                                   390
# define SSL_R_BAD_DATA_RETURNED_BY_CALLBACK              106
# define SSL_R_BAD_DECOMPRESSION                          107
# define SSL_R_BAD_DH_G_LENGTH                            108
# define SSL_R_BAD_DH_G_VALUE                             375
# define SSL_R_BAD_DH_PUB_KEY_LENGTH                      109
# define SSL_R_BAD_DH_PUB_KEY_VALUE                       393
# define SSL_R_BAD_DH_P_LENGTH                            110
# define SSL_R_BAD_DH_P_VALUE                             395
# define SSL_R_BAD_DIGEST_LENGTH                          111
# define SSL_R_BAD_DSA_SIGNATURE                          112
# define SSL_R_BAD_ECC_CERT                               304
# define SSL_R_BAD_ECDSA_SIGNATURE                        305
# define SSL_R_BAD_ECPOINT                                306
# define SSL_R_BAD_HANDSHAKE_LENGTH                       332
# define SSL_R_BAD_HELLO_REQUEST                          105
# define SSL_R_BAD_LENGTH                                 271
# define SSL_R_BAD_MAC_DECODE                             113
# define SSL_R_BAD_MAC_LENGTH                             333
# define SSL_R_BAD_MESSAGE_TYPE                           114
# define SSL_R_BAD_PACKET_LENGTH                          115
# define SSL_R_BAD_PROTOCOL_VERSION_NUMBER                116
# define SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH               316
# define SSL_R_BAD_RESPONSE_ARGUMENT                      117
# define SSL_R_BAD_RSA_DECRYPT                            118
# define SSL_R_BAD_RSA_ENCRYPT                            119
# define SSL_R_BAD_RSA_E_LENGTH                           120
# define SSL_R_BAD_RSA_MODULUS_LENGTH                     121
# define SSL_R_BAD_RSA_SIGNATURE                          122
# define SSL_R_BAD_SIGNATURE                              123
# define SSL_R_BAD_SRP_A_LENGTH                           347
# define SSL_R_BAD_SRP_B_LENGTH                           348
# define SSL_R_BAD_SRP_G_LENGTH                           349
# define SSL_R_BAD_SRP_N_LENGTH                           350
# define SSL_R_BAD_SRP_PARAMETERS                         371
# define SSL_R_BAD_SRP_S_LENGTH                           351
# define SSL_R_BAD_SRTP_MKI_VALUE                         352
# define SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST           353
# define SSL_R_BAD_SSL_FILETYPE                           124
# define SSL_R_BAD_SSL_SESSION_ID_LENGTH                  125
# define SSL_R_BAD_STATE                                  126
# define SSL_R_BAD_VALUE                                  384
# define SSL_R_BAD_WRITE_RETRY                            127
# define SSL_R_BIO_NOT_SET                                128
# define SSL_R_BLOCK_CIPHER_PAD_IS_WRONG                  129
# define SSL_R_BN_LIB                                     130
# define SSL_R_CA_DN_LENGTH_MISMATCH                      131
# define SSL_R_CA_DN_TOO_LONG                             132
# define SSL_R_CCS_RECEIVED_EARLY                         133
# define SSL_R_CERTIFICATE_VERIFY_FAILED                  134
# define SSL_R_CERT_CB_ERROR                              377
# define SSL_R_CERT_LENGTH_MISMATCH                       135
# define SSL_R_CHALLENGE_IS_DIFFERENT                     136
# define SSL_R_CIPHER_CODE_WRONG_LENGTH                   137
# define SSL_R_CIPHER_OR_HASH_UNAVAILABLE                 138
# define SSL_R_CIPHER_TABLE_SRC_ERROR                     139
# define SSL_R_CLIENTHELLO_TLSEXT                         226
# define SSL_R_COMPRESSED_LENGTH_TOO_LONG                 140
# define SSL_R_COMPRESSION_DISABLED                       343
# define SSL_R_COMPRESSION_FAILURE                        141
# define SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE    307
# define SSL_R_COMPRESSION_LIBRARY_ERROR                  142
# define SSL_R_CONNECTION_ID_IS_DIFFERENT                 143
# define SSL_R_CONNECTION_TYPE_NOT_SET                    144
# define SSL_R_COOKIE_MISMATCH                            308
# define SSL_R_DATA_BETWEEN_CCS_AND_FINISHED              145
# define SSL_R_DATA_LENGTH_TOO_LONG                       146
# define SSL_R_DECRYPTION_FAILED                          147
# define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC        281
# define SSL_R_DH_KEY_TOO_SMALL                           372
# define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG            148
# define SSL_R_DIGEST_CHECK_FAILED                        149
# define SSL_R_DTLS_MESSAGE_TOO_BIG                       334
# define SSL_R_DUPLICATE_COMPRESSION_ID                   309
# define SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT             317
# define SSL_R_ECC_CERT_NOT_FOR_SIGNING                   318
# define SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE         322
# define SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE        323
# define SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE              374
# define SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER               310
# define SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST         354
# define SSL_R_ENCRYPTED_LENGTH_TOO_LONG                  150
# define SSL_R_ERROR_GENERATING_TMP_RSA_KEY               282
# define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST              151
# define SSL_R_EXCESSIVE_MESSAGE_SIZE                     152
# define SSL_R_EXTRA_DATA_IN_MESSAGE                      153
# define SSL_R_GOT_A_FIN_BEFORE_A_CCS                     154
# define SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS                355
# define SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION           356
# define SSL_R_HTTPS_PROXY_REQUEST                        155
# define SSL_R_HTTP_REQUEST                               156
# define SSL_R_ILLEGAL_PADDING                            283
# define SSL_R_ILLEGAL_SUITEB_DIGEST                      380
# define SSL_R_INAPPROPRIATE_FALLBACK                     373
# define SSL_R_INCONSISTENT_COMPRESSION                   340
# define SSL_R_INVALID_CHALLENGE_LENGTH                   158
# define SSL_R_INVALID_COMMAND                            280
# define SSL_R_INVALID_COMPRESSION_ALGORITHM              341
# define SSL_R_INVALID_NULL_CMD_NAME                      385
# define SSL_R_INVALID_PURPOSE                            278
# define SSL_R_INVALID_SERVERINFO_DATA                    388
# define SSL_R_INVALID_SRP_USERNAME                       357
# define SSL_R_INVALID_STATUS_RESPONSE                    328
# define SSL_R_INVALID_TICKET_KEYS_LENGTH                 325
# define SSL_R_INVALID_TRUST                              279
# define SSL_R_KEY_ARG_TOO_LONG                           284
# define SSL_R_KRB5                                       285
# define SSL_R_KRB5_C_CC_PRINC                            286
# define SSL_R_KRB5_C_GET_CRED                            287
# define SSL_R_KRB5_C_INIT                                288
# define SSL_R_KRB5_C_MK_REQ                              289
# define SSL_R_KRB5_S_BAD_TICKET                          290
# define SSL_R_KRB5_S_INIT                                291
# define SSL_R_KRB5_S_RD_REQ                              292
# define SSL_R_KRB5_S_TKT_EXPIRED                         293
# define SSL_R_KRB5_S_TKT_NYV                             294
# define SSL_R_KRB5_S_TKT_SKEW                            295
# define SSL_R_LENGTH_MISMATCH                            159
# define SSL_R_LENGTH_TOO_LONG                            404
# define SSL_R_LENGTH_TOO_SHORT                           160
# define SSL_R_LIBRARY_BUG                                274
# define SSL_R_LIBRARY_HAS_NO_CIPHERS                     161
# define SSL_R_MESSAGE_TOO_LONG                           296
# define SSL_R_MISSING_DH_DSA_CERT                        162
# define SSL_R_MISSING_DH_KEY                             163
# define SSL_R_MISSING_DH_RSA_CERT                        164
# define SSL_R_MISSING_DSA_SIGNING_CERT                   165
# define SSL_R_MISSING_ECDH_CERT                          382
# define SSL_R_MISSING_ECDSA_SIGNING_CERT                 381
# define SSL_R_MISSING_EXPORT_TMP_DH_KEY                  166
# define SSL_R_MISSING_EXPORT_TMP_RSA_KEY                 167
# define SSL_R_MISSING_RSA_CERTIFICATE                    168
# define SSL_R_MISSING_RSA_ENCRYPTING_CERT                169
# define SSL_R_MISSING_RSA_SIGNING_CERT                   170
# define SSL_R_MISSING_SRP_PARAM                          358
# define SSL_R_MISSING_TMP_DH_KEY                         171
# define SSL_R_MISSING_TMP_ECDH_KEY                       311
# define SSL_R_MISSING_TMP_RSA_KEY                        172
# define SSL_R_MISSING_TMP_RSA_PKEY                       173
# define SSL_R_MISSING_VERIFY_MESSAGE                     174
# define SSL_R_MULTIPLE_SGC_RESTARTS                      346
# define SSL_R_NON_SSLV2_INITIAL_PACKET                   175
# define SSL_R_NO_CERTIFICATES_RETURNED                   176
# define SSL_R_NO_CERTIFICATE_ASSIGNED                    177
# define SSL_R_NO_CERTIFICATE_RETURNED                    178
# define SSL_R_NO_CERTIFICATE_SET                         179
# define SSL_R_NO_CERTIFICATE_SPECIFIED                   180
# define SSL_R_NO_CIPHERS_AVAILABLE                       181
# define SSL_R_NO_CIPHERS_PASSED                          182
# define SSL_R_NO_CIPHERS_SPECIFIED                       183
# define SSL_R_NO_CIPHER_LIST                             184
# define SSL_R_NO_CIPHER_MATCH                            185
# define SSL_R_NO_CLIENT_CERT_METHOD                      331
# define SSL_R_NO_CLIENT_CERT_RECEIVED                    186
# define SSL_R_NO_COMPRESSION_SPECIFIED                   187
# define SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER           330
# define SSL_R_NO_METHOD_SPECIFIED                        188
# define SSL_R_NO_PEM_EXTENSIONS                          389
# define SSL_R_NO_PRIVATEKEY                              189
# define SSL_R_NO_PRIVATE_KEY_ASSIGNED                    190
# define SSL_R_NO_PROTOCOLS_AVAILABLE                     191
# define SSL_R_NO_PUBLICKEY                               192
# define SSL_R_NO_RENEGOTIATION                           339
# define SSL_R_NO_REQUIRED_DIGEST                         324
# define SSL_R_NO_SHARED_CIPHER                           193
# define SSL_R_NO_SHARED_SIGATURE_ALGORITHMS              376
# define SSL_R_NO_SRTP_PROFILES                           359
# define SSL_R_NO_VERIFY_CALLBACK                         194
# define SSL_R_NULL_SSL_CTX                               195
# define SSL_R_NULL_SSL_METHOD_PASSED                     196
# define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED            197
# define SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED 344
# define SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE       387
# define SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE        379
# define SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE              297
# define SSL_R_OPAQUE_PRF_INPUT_TOO_LONG                  327
# define SSL_R_PACKET_LENGTH_TOO_LONG                     198
# define SSL_R_PARSE_TLSEXT                               227
# define SSL_R_PATH_TOO_LONG                              270
# define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE          199
# define SSL_R_PEER_ERROR                                 200
# define SSL_R_PEER_ERROR_CERTIFICATE                     201
# define SSL_R_PEER_ERROR_NO_CERTIFICATE                  202
# define SSL_R_PEER_ERROR_NO_CIPHER                       203
# define SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE    204
# define SSL_R_PEM_NAME_BAD_PREFIX                        391
# define SSL_R_PEM_NAME_TOO_SHORT                         392
# define SSL_R_PRE_MAC_LENGTH_TOO_LONG                    205
# define SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS          206
# define SSL_R_PROTOCOL_IS_SHUTDOWN                       207
# define SSL_R_PSK_IDENTITY_NOT_FOUND                     223
# define SSL_R_PSK_NO_CLIENT_CB                           224
# define SSL_R_PSK_NO_SERVER_CB                           225
# define SSL_R_PUBLIC_KEY_ENCRYPT_ERROR                   208
# define SSL_R_PUBLIC_KEY_IS_NOT_RSA                      209
# define SSL_R_PUBLIC_KEY_NOT_RSA                         210
# define SSL_R_READ_BIO_NOT_SET                           211
# define SSL_R_READ_TIMEOUT_EXPIRED                       312
# define SSL_R_READ_WRONG_PACKET_TYPE                     212
# define SSL_R_RECORD_LENGTH_MISMATCH                     213
# define SSL_R_RECORD_TOO_LARGE                           214
# define SSL_R_RECORD_TOO_SMALL                           298
# define SSL_R_RENEGOTIATE_EXT_TOO_LONG                   335
# define SSL_R_RENEGOTIATION_ENCODING_ERR                 336
# define SSL_R_RENEGOTIATION_MISMATCH                     337
# define SSL_R_REQUIRED_CIPHER_MISSING                    215
# define SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING    342
# define SSL_R_REUSE_CERT_LENGTH_NOT_ZERO                 216
# define SSL_R_REUSE_CERT_TYPE_NOT_ZERO                   217
# define SSL_R_REUSE_CIPHER_LIST_NOT_ZERO                 218
# define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING           345
# define SSL_R_SERVERHELLO_TLSEXT                         275
# define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED           277
# define SSL_R_SHORT_READ                                 219
# define SSL_R_SHUTDOWN_WHILE_IN_INIT                     407
# define SSL_R_SIGNATURE_ALGORITHMS_ERROR                 360
# define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE      220
# define SSL_R_SRP_A_CALC                                 361
# define SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES           362
# define SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG      363
# define SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE            364
# define SSL_R_SSL23_DOING_SESSION_ID_REUSE               221
# define SSL_R_SSL2_CONNECTION_ID_TOO_LONG                299
# define SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT             321
# define SSL_R_SSL3_EXT_INVALID_SERVERNAME                319
# define SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE           320
# define SSL_R_SSL3_SESSION_ID_TOO_LONG                   300
# define SSL_R_SSL3_SESSION_ID_TOO_SHORT                  222
# define SSL_R_SSLV3_ALERT_BAD_CERTIFICATE                1042
# define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC                 1020
# define SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED            1045
# define SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED            1044
# define SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN            1046
# define SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE          1030
# define SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE              1040
# define SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER              1047
# define SSL_R_SSLV3_ALERT_NO_CERTIFICATE                 1041
# define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE             1010
# define SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE        1043
# define SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION         228
# define SSL_R_SSL_HANDSHAKE_FAILURE                      229
# define SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS                 230
# define SSL_R_SSL_SESSION_ID_CALLBACK_FAILED             301
# define SSL_R_SSL_SESSION_ID_CONFLICT                    302
# define SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG            273
# define SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH              303
# define SSL_R_SSL_SESSION_ID_IS_DIFFERENT                231
# define SSL_R_TLSV1_ALERT_ACCESS_DENIED                  1049
# define SSL_R_TLSV1_ALERT_DECODE_ERROR                   1050
# define SSL_R_TLSV1_ALERT_DECRYPTION_FAILED              1021
# define SSL_R_TLSV1_ALERT_DECRYPT_ERROR                  1051
# define SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION             1060
# define SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK         1086
# define SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY          1071
# define SSL_R_TLSV1_ALERT_INTERNAL_ERROR                 1080
# define SSL_R_TLSV1_ALERT_NO_RENEGOTIATION               1100
# define SSL_R_TLSV1_ALERT_PROTOCOL_VERSION               1070
# define SSL_R_TLSV1_ALERT_RECORD_OVERFLOW                1022
# define SSL_R_TLSV1_ALERT_UNKNOWN_CA                     1048
# define SSL_R_TLSV1_ALERT_USER_CANCELLED                 1090
# define SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE           1114
# define SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE      1113
# define SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE             1111
# define SSL_R_TLSV1_UNRECOGNIZED_NAME                    1112
# define SSL_R_TLSV1_UNSUPPORTED_EXTENSION                1110
# define SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER       232
# define SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT           365
# define SSL_R_TLS_HEARTBEAT_PENDING                      366
# define SSL_R_TLS_ILLEGAL_EXPORTER_LABEL                 367
# define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST             157
# define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 233
# define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG    234
# define SSL_R_TOO_MANY_WARN_ALERTS                       409
# define SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER            235
# define SSL_R_UNABLE_TO_DECODE_DH_CERTS                  236
# define SSL_R_UNABLE_TO_DECODE_ECDH_CERTS                313
# define SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY               237
# define SSL_R_UNABLE_TO_FIND_DH_PARAMETERS               238
# define SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS             314
# define SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS       239
# define SSL_R_UNABLE_TO_FIND_SSL_METHOD                  240
# define SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES           241
# define SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES           242
# define SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES          243
# define SSL_R_UNEXPECTED_MESSAGE                         244
# define SSL_R_UNEXPECTED_RECORD                          245
# define SSL_R_UNINITIALIZED                              276
# define SSL_R_UNKNOWN_ALERT_TYPE                         246
# define SSL_R_UNKNOWN_CERTIFICATE_TYPE                   247
# define SSL_R_UNKNOWN_CIPHER_RETURNED                    248
# define SSL_R_UNKNOWN_CIPHER_TYPE                        249
# define SSL_R_UNKNOWN_CMD_NAME                           386
# define SSL_R_UNKNOWN_DIGEST                             368
# define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE                  250
# define SSL_R_UNKNOWN_PKEY_TYPE                          251
# define SSL_R_UNKNOWN_PROTOCOL                           252
# define SSL_R_UNKNOWN_REMOTE_ERROR_TYPE                  253
# define SSL_R_UNKNOWN_SSL_VERSION                        254
# define SSL_R_UNKNOWN_STATE                              255
# define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED       338
# define SSL_R_UNSUPPORTED_CIPHER                         256
# define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM          257
# define SSL_R_UNSUPPORTED_DIGEST_TYPE                    326
# define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE                 315
# define SSL_R_UNSUPPORTED_PROTOCOL                       258
# define SSL_R_UNSUPPORTED_SSL_VERSION                    259
# define SSL_R_UNSUPPORTED_STATUS_TYPE                    329
# define SSL_R_USE_SRTP_NOT_NEGOTIATED                    369
# define SSL_R_WRITE_BIO_NOT_SET                          260
# define SSL_R_WRONG_CERTIFICATE_TYPE                     383
# define SSL_R_WRONG_CIPHER_RETURNED                      261
# define SSL_R_WRONG_CURVE                                378
# define SSL_R_WRONG_MESSAGE_TYPE                         262
# define SSL_R_WRONG_NUMBER_OF_KEY_BITS                   263
# define SSL_R_WRONG_SIGNATURE_LENGTH                     264
# define SSL_R_WRONG_SIGNATURE_SIZE                       265
# define SSL_R_WRONG_SIGNATURE_TYPE                       370
# define SSL_R_WRONG_SSL_VERSION                          266
# define SSL_R_WRONG_VERSION_NUMBER                       267
# define SSL_R_X509_LIB                                   268
# define SSL_R_X509_VERIFICATION_SETUP_PROBLEMS           269

#ifdef  __cplusplus
}
#endif
#endif
openssl/lhash.h000064400000022515151733316610007512 0ustar00/* crypto/lhash/lhash.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

/*
 * Header for dynamic hash table routines Author - Eric Young
 */

#ifndef HEADER_LHASH_H
# define HEADER_LHASH_H

# include <openssl/e_os2.h>
# ifndef OPENSSL_NO_FP_API
#  include <stdio.h>
# endif

# ifndef OPENSSL_NO_BIO
#  include <openssl/bio.h>
# endif

#ifdef  __cplusplus
extern "C" {
#endif

typedef struct lhash_node_st {
    void *data;
    struct lhash_node_st *next;
# ifndef OPENSSL_NO_HASH_COMP
    unsigned long hash;
# endif
} LHASH_NODE;

typedef int (*LHASH_COMP_FN_TYPE) (const void *, const void *);
typedef unsigned long (*LHASH_HASH_FN_TYPE) (const void *);
typedef void (*LHASH_DOALL_FN_TYPE) (void *);
typedef void (*LHASH_DOALL_ARG_FN_TYPE) (void *, void *);

/*
 * Macros for declaring and implementing type-safe wrappers for LHASH
 * callbacks. This way, callbacks can be provided to LHASH structures without
 * function pointer casting and the macro-defined callbacks provide
 * per-variable casting before deferring to the underlying type-specific
 * callbacks. NB: It is possible to place a "static" in front of both the
 * DECLARE and IMPLEMENT macros if the functions are strictly internal.
 */

/* First: "hash" functions */
# define DECLARE_LHASH_HASH_FN(name, o_type) \
        unsigned long name##_LHASH_HASH(const void *);
# define IMPLEMENT_LHASH_HASH_FN(name, o_type) \
        unsigned long name##_LHASH_HASH(const void *arg) { \
                const o_type *a = arg; \
                return name##_hash(a); }
# define LHASH_HASH_FN(name) name##_LHASH_HASH

/* Second: "compare" functions */
# define DECLARE_LHASH_COMP_FN(name, o_type) \
        int name##_LHASH_COMP(const void *, const void *);
# define IMPLEMENT_LHASH_COMP_FN(name, o_type) \
        int name##_LHASH_COMP(const void *arg1, const void *arg2) { \
                const o_type *a = arg1;             \
                const o_type *b = arg2; \
                return name##_cmp(a,b); }
# define LHASH_COMP_FN(name) name##_LHASH_COMP

/* Third: "doall" functions */
# define DECLARE_LHASH_DOALL_FN(name, o_type) \
        void name##_LHASH_DOALL(void *);
# define IMPLEMENT_LHASH_DOALL_FN(name, o_type) \
        void name##_LHASH_DOALL(void *arg) { \
                o_type *a = arg; \
                name##_doall(a); }
# define LHASH_DOALL_FN(name) name##_LHASH_DOALL

/* Fourth: "doall_arg" functions */
# define DECLARE_LHASH_DOALL_ARG_FN(name, o_type, a_type) \
        void name##_LHASH_DOALL_ARG(void *, void *);
# define IMPLEMENT_LHASH_DOALL_ARG_FN(name, o_type, a_type) \
        void name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \
                o_type *a = arg1; \
                a_type *b = arg2; \
                name##_doall_arg(a, b); }
# define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG

typedef struct lhash_st {
    LHASH_NODE **b;
    LHASH_COMP_FN_TYPE comp;
    LHASH_HASH_FN_TYPE hash;
    unsigned int num_nodes;
    unsigned int num_alloc_nodes;
    unsigned int p;
    unsigned int pmax;
    unsigned long up_load;      /* load times 256 */
    unsigned long down_load;    /* load times 256 */
    unsigned long num_items;
    unsigned long num_expands;
    unsigned long num_expand_reallocs;
    unsigned long num_contracts;
    unsigned long num_contract_reallocs;
    unsigned long num_hash_calls;
    unsigned long num_comp_calls;
    unsigned long num_insert;
    unsigned long num_replace;
    unsigned long num_delete;
    unsigned long num_no_delete;
    unsigned long num_retrieve;
    unsigned long num_retrieve_miss;
    unsigned long num_hash_comps;
    int error;
} _LHASH;                       /* Do not use _LHASH directly, use LHASH_OF
                                 * and friends */

# define LH_LOAD_MULT    256

/*
 * Indicates a malloc() error in the last call, this is only bad in
 * lh_insert().
 */
# define lh_error(lh)    ((lh)->error)

_LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c);
void lh_free(_LHASH *lh);
void *lh_insert(_LHASH *lh, void *data);
void *lh_delete(_LHASH *lh, const void *data);
void *lh_retrieve(_LHASH *lh, const void *data);
void lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func);
void lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg);
unsigned long lh_strhash(const char *c);
unsigned long lh_num_items(const _LHASH *lh);

# ifndef OPENSSL_NO_FP_API
void lh_stats(const _LHASH *lh, FILE *out);
void lh_node_stats(const _LHASH *lh, FILE *out);
void lh_node_usage_stats(const _LHASH *lh, FILE *out);
# endif

# ifndef OPENSSL_NO_BIO
void lh_stats_bio(const _LHASH *lh, BIO *out);
void lh_node_stats_bio(const _LHASH *lh, BIO *out);
void lh_node_usage_stats_bio(const _LHASH *lh, BIO *out);
# endif

/* Type checking... */

# define LHASH_OF(type) struct lhash_st_##type

# define DECLARE_LHASH_OF(type) LHASH_OF(type) { int dummy; }

# define CHECKED_LHASH_OF(type,lh) \
  ((_LHASH *)CHECKED_PTR_OF(LHASH_OF(type),lh))

/* Define wrapper functions. */
# define LHM_lh_new(type, name) \
  ((LHASH_OF(type) *)lh_new(LHASH_HASH_FN(name), LHASH_COMP_FN(name)))
# define LHM_lh_error(type, lh) \
  lh_error(CHECKED_LHASH_OF(type,lh))
# define LHM_lh_insert(type, lh, inst) \
  ((type *)lh_insert(CHECKED_LHASH_OF(type, lh), \
                     CHECKED_PTR_OF(type, inst)))
# define LHM_lh_retrieve(type, lh, inst) \
  ((type *)lh_retrieve(CHECKED_LHASH_OF(type, lh), \
                       CHECKED_PTR_OF(type, inst)))
# define LHM_lh_delete(type, lh, inst) \
  ((type *)lh_delete(CHECKED_LHASH_OF(type, lh),                        \
                     CHECKED_PTR_OF(type, inst)))
# define LHM_lh_doall(type, lh,fn) lh_doall(CHECKED_LHASH_OF(type, lh), fn)
# define LHM_lh_doall_arg(type, lh, fn, arg_type, arg) \
  lh_doall_arg(CHECKED_LHASH_OF(type, lh), fn, CHECKED_PTR_OF(arg_type, arg))
# define LHM_lh_num_items(type, lh) lh_num_items(CHECKED_LHASH_OF(type, lh))
# define LHM_lh_down_load(type, lh) (CHECKED_LHASH_OF(type, lh)->down_load)
# define LHM_lh_node_stats_bio(type, lh, out) \
  lh_node_stats_bio(CHECKED_LHASH_OF(type, lh), out)
# define LHM_lh_node_usage_stats_bio(type, lh, out) \
  lh_node_usage_stats_bio(CHECKED_LHASH_OF(type, lh), out)
# define LHM_lh_stats_bio(type, lh, out) \
  lh_stats_bio(CHECKED_LHASH_OF(type, lh), out)
# define LHM_lh_free(type, lh) lh_free(CHECKED_LHASH_OF(type, lh))

DECLARE_LHASH_OF(OPENSSL_STRING);
DECLARE_LHASH_OF(OPENSSL_CSTRING);

#ifdef  __cplusplus
}
#endif

#endif
openssl/err.h000064400000040722151733316610007203 0ustar00/* crypto/err/err.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */
/* ====================================================================
 * Copyright (c) 1998-2019 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#ifndef HEADER_ERR_H
# define HEADER_ERR_H

# include <openssl/e_os2.h>

# ifndef OPENSSL_NO_FP_API
#  include <stdio.h>
#  include <stdlib.h>
# endif

# include <openssl/ossl_typ.h>
# ifndef OPENSSL_NO_BIO
#  include <openssl/bio.h>
# endif
# ifndef OPENSSL_NO_LHASH
#  include <openssl/lhash.h>
# endif

#ifdef  __cplusplus
extern "C" {
#endif

# ifndef OPENSSL_NO_ERR
#  define ERR_PUT_error(a,b,c,d,e)        ERR_put_error(a,b,c,d,e)
# else
#  define ERR_PUT_error(a,b,c,d,e)        ERR_put_error(a,b,c,NULL,0)
# endif

# include <errno.h>

# define ERR_TXT_MALLOCED        0x01
# define ERR_TXT_STRING          0x02

# define ERR_FLAG_MARK           0x01
# define ERR_FLAG_CLEAR          0x02

# define ERR_NUM_ERRORS  16
typedef struct err_state_st {
    CRYPTO_THREADID tid;
    int err_flags[ERR_NUM_ERRORS];
    unsigned long err_buffer[ERR_NUM_ERRORS];
    char *err_data[ERR_NUM_ERRORS];
    int err_data_flags[ERR_NUM_ERRORS];
    const char *err_file[ERR_NUM_ERRORS];
    int err_line[ERR_NUM_ERRORS];
    int top, bottom;
} ERR_STATE;

/* library */
# define ERR_LIB_NONE            1
# define ERR_LIB_SYS             2
# define ERR_LIB_BN              3
# define ERR_LIB_RSA             4
# define ERR_LIB_DH              5
# define ERR_LIB_EVP             6
# define ERR_LIB_BUF             7
# define ERR_LIB_OBJ             8
# define ERR_LIB_PEM             9
# define ERR_LIB_DSA             10
# define ERR_LIB_X509            11
/* #define ERR_LIB_METH         12 */
# define ERR_LIB_ASN1            13
# define ERR_LIB_CONF            14
# define ERR_LIB_CRYPTO          15
# define ERR_LIB_EC              16
# define ERR_LIB_SSL             20
/* #define ERR_LIB_SSL23        21 */
/* #define ERR_LIB_SSL2         22 */
/* #define ERR_LIB_SSL3         23 */
/* #define ERR_LIB_RSAREF       30 */
/* #define ERR_LIB_PROXY        31 */
# define ERR_LIB_BIO             32
# define ERR_LIB_PKCS7           33
# define ERR_LIB_X509V3          34
# define ERR_LIB_PKCS12          35
# define ERR_LIB_RAND            36
# define ERR_LIB_DSO             37
# define ERR_LIB_ENGINE          38
# define ERR_LIB_OCSP            39
# define ERR_LIB_UI              40
# define ERR_LIB_COMP            41
# define ERR_LIB_ECDSA           42
# define ERR_LIB_ECDH            43
# define ERR_LIB_STORE           44
# define ERR_LIB_FIPS            45
# define ERR_LIB_CMS             46
# define ERR_LIB_TS              47
# define ERR_LIB_HMAC            48
# define ERR_LIB_JPAKE           49

# define ERR_LIB_USER            128

# define SYSerr(f,r)  ERR_PUT_error(ERR_LIB_SYS,(f),(r),__FILE__,__LINE__)
# define BNerr(f,r)   ERR_PUT_error(ERR_LIB_BN,(f),(r),__FILE__,__LINE__)
# define RSAerr(f,r)  ERR_PUT_error(ERR_LIB_RSA,(f),(r),__FILE__,__LINE__)
# define DHerr(f,r)   ERR_PUT_error(ERR_LIB_DH,(f),(r),__FILE__,__LINE__)
# define EVPerr(f,r)  ERR_PUT_error(ERR_LIB_EVP,(f),(r),__FILE__,__LINE__)
# define BUFerr(f,r)  ERR_PUT_error(ERR_LIB_BUF,(f),(r),__FILE__,__LINE__)
# define OBJerr(f,r)  ERR_PUT_error(ERR_LIB_OBJ,(f),(r),__FILE__,__LINE__)
# define PEMerr(f,r)  ERR_PUT_error(ERR_LIB_PEM,(f),(r),__FILE__,__LINE__)
# define DSAerr(f,r)  ERR_PUT_error(ERR_LIB_DSA,(f),(r),__FILE__,__LINE__)
# define X509err(f,r) ERR_PUT_error(ERR_LIB_X509,(f),(r),__FILE__,__LINE__)
# define ASN1err(f,r) ERR_PUT_error(ERR_LIB_ASN1,(f),(r),__FILE__,__LINE__)
# define CONFerr(f,r) ERR_PUT_error(ERR_LIB_CONF,(f),(r),__FILE__,__LINE__)
# define CRYPTOerr(f,r) ERR_PUT_error(ERR_LIB_CRYPTO,(f),(r),__FILE__,__LINE__)
# define ECerr(f,r)   ERR_PUT_error(ERR_LIB_EC,(f),(r),__FILE__,__LINE__)
# define SSLerr(f,r)  ERR_PUT_error(ERR_LIB_SSL,(f),(r),__FILE__,__LINE__)
# define BIOerr(f,r)  ERR_PUT_error(ERR_LIB_BIO,(f),(r),__FILE__,__LINE__)
# define PKCS7err(f,r) ERR_PUT_error(ERR_LIB_PKCS7,(f),(r),__FILE__,__LINE__)
# define X509V3err(f,r) ERR_PUT_error(ERR_LIB_X509V3,(f),(r),__FILE__,__LINE__)
# define PKCS12err(f,r) ERR_PUT_error(ERR_LIB_PKCS12,(f),(r),__FILE__,__LINE__)
# define RANDerr(f,r) ERR_PUT_error(ERR_LIB_RAND,(f),(r),__FILE__,__LINE__)
# define DSOerr(f,r) ERR_PUT_error(ERR_LIB_DSO,(f),(r),__FILE__,__LINE__)
# define ENGINEerr(f,r) ERR_PUT_error(ERR_LIB_ENGINE,(f),(r),__FILE__,__LINE__)
# define OCSPerr(f,r) ERR_PUT_error(ERR_LIB_OCSP,(f),(r),__FILE__,__LINE__)
# define UIerr(f,r) ERR_PUT_error(ERR_LIB_UI,(f),(r),__FILE__,__LINE__)
# define COMPerr(f,r) ERR_PUT_error(ERR_LIB_COMP,(f),(r),__FILE__,__LINE__)
# define ECDSAerr(f,r)  ERR_PUT_error(ERR_LIB_ECDSA,(f),(r),__FILE__,__LINE__)
# define ECDHerr(f,r)  ERR_PUT_error(ERR_LIB_ECDH,(f),(r),__FILE__,__LINE__)
# define STOREerr(f,r) ERR_PUT_error(ERR_LIB_STORE,(f),(r),__FILE__,__LINE__)
# define FIPSerr(f,r) ERR_PUT_error(ERR_LIB_FIPS,(f),(r),__FILE__,__LINE__)
# define CMSerr(f,r) ERR_PUT_error(ERR_LIB_CMS,(f),(r),__FILE__,__LINE__)
# define TSerr(f,r) ERR_PUT_error(ERR_LIB_TS,(f),(r),__FILE__,__LINE__)
# define HMACerr(f,r) ERR_PUT_error(ERR_LIB_HMAC,(f),(r),__FILE__,__LINE__)
# define JPAKEerr(f,r) ERR_PUT_error(ERR_LIB_JPAKE,(f),(r),__FILE__,__LINE__)

/*
 * Borland C seems too stupid to be able to shift and do longs in the
 * pre-processor :-(
 */
# define ERR_PACK(l,f,r)         (((((unsigned long)l)&0xffL)*0x1000000)| \
                                ((((unsigned long)f)&0xfffL)*0x1000)| \
                                ((((unsigned long)r)&0xfffL)))
# define ERR_GET_LIB(l)          (int)((((unsigned long)l)>>24L)&0xffL)
# define ERR_GET_FUNC(l)         (int)((((unsigned long)l)>>12L)&0xfffL)
# define ERR_GET_REASON(l)       (int)((l)&0xfffL)
# define ERR_FATAL_ERROR(l)      (int)((l)&ERR_R_FATAL)

/* OS functions */
# define SYS_F_FOPEN             1
# define SYS_F_CONNECT           2
# define SYS_F_GETSERVBYNAME     3
# define SYS_F_SOCKET            4
# define SYS_F_IOCTLSOCKET       5
# define SYS_F_BIND              6
# define SYS_F_LISTEN            7
# define SYS_F_ACCEPT            8
# define SYS_F_WSASTARTUP        9/* Winsock stuff */
# define SYS_F_OPENDIR           10
# define SYS_F_FREAD             11
# define SYS_F_FFLUSH            18

/* reasons */
# define ERR_R_SYS_LIB   ERR_LIB_SYS/* 2 */
# define ERR_R_BN_LIB    ERR_LIB_BN/* 3 */
# define ERR_R_RSA_LIB   ERR_LIB_RSA/* 4 */
# define ERR_R_DH_LIB    ERR_LIB_DH/* 5 */
# define ERR_R_EVP_LIB   ERR_LIB_EVP/* 6 */
# define ERR_R_BUF_LIB   ERR_LIB_BUF/* 7 */
# define ERR_R_OBJ_LIB   ERR_LIB_OBJ/* 8 */
# define ERR_R_PEM_LIB   ERR_LIB_PEM/* 9 */
# define ERR_R_DSA_LIB   ERR_LIB_DSA/* 10 */
# define ERR_R_X509_LIB  ERR_LIB_X509/* 11 */
# define ERR_R_ASN1_LIB  ERR_LIB_ASN1/* 13 */
# define ERR_R_CONF_LIB  ERR_LIB_CONF/* 14 */
# define ERR_R_CRYPTO_LIB ERR_LIB_CRYPTO/* 15 */
# define ERR_R_EC_LIB    ERR_LIB_EC/* 16 */
# define ERR_R_SSL_LIB   ERR_LIB_SSL/* 20 */
# define ERR_R_BIO_LIB   ERR_LIB_BIO/* 32 */
# define ERR_R_PKCS7_LIB ERR_LIB_PKCS7/* 33 */
# define ERR_R_X509V3_LIB ERR_LIB_X509V3/* 34 */
# define ERR_R_PKCS12_LIB ERR_LIB_PKCS12/* 35 */
# define ERR_R_RAND_LIB  ERR_LIB_RAND/* 36 */
# define ERR_R_DSO_LIB   ERR_LIB_DSO/* 37 */
# define ERR_R_ENGINE_LIB ERR_LIB_ENGINE/* 38 */
# define ERR_R_OCSP_LIB  ERR_LIB_OCSP/* 39 */
# define ERR_R_UI_LIB    ERR_LIB_UI/* 40 */
# define ERR_R_COMP_LIB  ERR_LIB_COMP/* 41 */
# define ERR_R_ECDSA_LIB ERR_LIB_ECDSA/* 42 */
# define ERR_R_ECDH_LIB  ERR_LIB_ECDH/* 43 */
# define ERR_R_STORE_LIB ERR_LIB_STORE/* 44 */
# define ERR_R_TS_LIB    ERR_LIB_TS/* 45 */

# define ERR_R_NESTED_ASN1_ERROR                 58
# define ERR_R_BAD_ASN1_OBJECT_HEADER            59
# define ERR_R_BAD_GET_ASN1_OBJECT_CALL          60
# define ERR_R_EXPECTING_AN_ASN1_SEQUENCE        61
# define ERR_R_ASN1_LENGTH_MISMATCH              62
# define ERR_R_MISSING_ASN1_EOS                  63

/* fatal error */
# define ERR_R_FATAL                             64
# define ERR_R_MALLOC_FAILURE                    (1|ERR_R_FATAL)
# define ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED       (2|ERR_R_FATAL)
# define ERR_R_PASSED_NULL_PARAMETER             (3|ERR_R_FATAL)
# define ERR_R_INTERNAL_ERROR                    (4|ERR_R_FATAL)
# define ERR_R_DISABLED                          (5|ERR_R_FATAL)

/*
 * 99 is the maximum possible ERR_R_... code, higher values are reserved for
 * the individual libraries
 */

typedef struct ERR_string_data_st {
    unsigned long error;
    const char *string;
} ERR_STRING_DATA;

void ERR_put_error(int lib, int func, int reason, const char *file, int line);
void ERR_set_error_data(char *data, int flags);

unsigned long ERR_get_error(void);
unsigned long ERR_get_error_line(const char **file, int *line);
unsigned long ERR_get_error_line_data(const char **file, int *line,
                                      const char **data, int *flags);
unsigned long ERR_peek_error(void);
unsigned long ERR_peek_error_line(const char **file, int *line);
unsigned long ERR_peek_error_line_data(const char **file, int *line,
                                       const char **data, int *flags);
unsigned long ERR_peek_last_error(void);
unsigned long ERR_peek_last_error_line(const char **file, int *line);
unsigned long ERR_peek_last_error_line_data(const char **file, int *line,
                                            const char **data, int *flags);
void ERR_clear_error(void);
char *ERR_error_string(unsigned long e, char *buf);
void ERR_error_string_n(unsigned long e, char *buf, size_t len);
const char *ERR_lib_error_string(unsigned long e);
const char *ERR_func_error_string(unsigned long e);
const char *ERR_reason_error_string(unsigned long e);
void ERR_print_errors_cb(int (*cb) (const char *str, size_t len, void *u),
                         void *u);
# ifndef OPENSSL_NO_FP_API
void ERR_print_errors_fp(FILE *fp);
# endif
# ifndef OPENSSL_NO_BIO
void ERR_print_errors(BIO *bp);
# endif
void ERR_add_error_data(int num, ...);
void ERR_add_error_vdata(int num, va_list args);
void ERR_load_strings(int lib, ERR_STRING_DATA str[]);
void ERR_unload_strings(int lib, ERR_STRING_DATA str[]);
void ERR_load_ERR_strings(void);
void ERR_load_crypto_strings(void);
void ERR_free_strings(void);

void ERR_remove_thread_state(const CRYPTO_THREADID *tid);
# ifndef OPENSSL_NO_DEPRECATED
void ERR_remove_state(unsigned long pid); /* if zero we look it up */
# endif
ERR_STATE *ERR_get_state(void);

# ifndef OPENSSL_NO_LHASH
LHASH_OF(ERR_STRING_DATA) *ERR_get_string_table(void);
LHASH_OF(ERR_STATE) *ERR_get_err_state_table(void);
void ERR_release_err_state_table(LHASH_OF(ERR_STATE) **hash);
# endif

int ERR_get_next_error_library(void);

int ERR_set_mark(void);
int ERR_pop_to_mark(void);

/* Already defined in ossl_typ.h */
/* typedef struct st_ERR_FNS ERR_FNS; */
/*
 * An application can use this function and provide the return value to
 * loaded modules that should use the application's ERR state/functionality
 */
const ERR_FNS *ERR_get_implementation(void);
/*
 * A loaded module should call this function prior to any ERR operations
 * using the application's "ERR_FNS".
 */
int ERR_set_implementation(const ERR_FNS *fns);

#ifdef  __cplusplus
}
#endif

#endif
openssl/srtp.h000064400000014756151733316610007413 0ustar00/* ssl/srtp.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */
/* ====================================================================
 * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */
/*
 * DTLS code by Eric Rescorla <ekr@rtfm.com>
 *
 * Copyright (C) 2006, Network Resonance, Inc. Copyright (C) 2011, RTFM, Inc.
 */

#ifndef HEADER_D1_SRTP_H
# define HEADER_D1_SRTP_H

# include <openssl/ssl.h>

#ifdef  __cplusplus
extern "C" {
#endif

# define SRTP_AES128_CM_SHA1_80 0x0001
# define SRTP_AES128_CM_SHA1_32 0x0002
# define SRTP_AES128_F8_SHA1_80 0x0003
# define SRTP_AES128_F8_SHA1_32 0x0004
# define SRTP_NULL_SHA1_80      0x0005
# define SRTP_NULL_SHA1_32      0x0006

# ifndef OPENSSL_NO_SRTP

int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles);
int SSL_set_tlsext_use_srtp(SSL *ctx, const char *profiles);

STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *ssl);
SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s);

# endif

#ifdef  __cplusplus
}
#endif

#endif
openssl/comp.h000064400000004507151733316610007352 0ustar00
#ifndef HEADER_COMP_H
# define HEADER_COMP_H

# include <openssl/crypto.h>

# ifdef OPENSSL_NO_COMP
#  error COMP is disabled.
# endif

#ifdef  __cplusplus
extern "C" {
#endif

typedef struct comp_ctx_st COMP_CTX;

struct comp_method_st {
    int type;                   /* NID for compression library */
    const char *name;           /* A text string to identify the library */
    int (*init) (COMP_CTX *ctx);
    void (*finish) (COMP_CTX *ctx);
    int (*compress) (COMP_CTX *ctx,
                     unsigned char *out, unsigned int olen,
                     unsigned char *in, unsigned int ilen);
    int (*expand) (COMP_CTX *ctx,
                   unsigned char *out, unsigned int olen,
                   unsigned char *in, unsigned int ilen);
    /*
     * The following two do NOTHING, but are kept for backward compatibility
     */
    long (*ctrl) (void);
    long (*callback_ctrl) (void);
};

struct comp_ctx_st {
    COMP_METHOD *meth;
    unsigned long compress_in;
    unsigned long compress_out;
    unsigned long expand_in;
    unsigned long expand_out;
    CRYPTO_EX_DATA ex_data;
};

COMP_CTX *COMP_CTX_new(COMP_METHOD *meth);
void COMP_CTX_free(COMP_CTX *ctx);
int COMP_compress_block(COMP_CTX *ctx, unsigned char *out, int olen,
                        unsigned char *in, int ilen);
int COMP_expand_block(COMP_CTX *ctx, unsigned char *out, int olen,
                      unsigned char *in, int ilen);
COMP_METHOD *COMP_rle(void);
COMP_METHOD *COMP_zlib(void);
void COMP_zlib_cleanup(void);

# ifdef HEADER_BIO_H
#  ifdef ZLIB
BIO_METHOD *BIO_f_zlib(void);
#  endif
# endif

/* BEGIN ERROR CODES */
/*
 * The following lines are auto generated by the script mkerr.pl. Any changes
 * made after this point may be overwritten when the script is next run.
 */
void ERR_load_COMP_strings(void);

/* Error codes for the COMP functions. */

/* Function codes. */
# define COMP_F_BIO_ZLIB_FLUSH                            99
# define COMP_F_BIO_ZLIB_NEW                              100
# define COMP_F_BIO_ZLIB_READ                             101
# define COMP_F_BIO_ZLIB_WRITE                            102

/* Reason codes. */
# define COMP_R_ZLIB_DEFLATE_ERROR                        99
# define COMP_R_ZLIB_INFLATE_ERROR                        100
# define COMP_R_ZLIB_NOT_SUPPORTED                        101

#ifdef  __cplusplus
}
#endif
#endif
openssl/crypto.h000064400000066356151733316610007746 0ustar00/* crypto/crypto.h */
/* ====================================================================
 * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */
/* ====================================================================
 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
 * ECDH support in OpenSSL originally developed by
 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
 */

#ifndef HEADER_CRYPTO_H
# define HEADER_CRYPTO_H

# include <stdlib.h>

# include <openssl/e_os2.h>

# ifndef OPENSSL_NO_FP_API
#  include <stdio.h>
# endif

# include <openssl/stack.h>
# include <openssl/safestack.h>
# include <openssl/opensslv.h>
# include <openssl/ossl_typ.h>

# ifdef CHARSET_EBCDIC
#  include <openssl/ebcdic.h>
# endif

/*
 * Resolve problems on some operating systems with symbol names that clash
 * one way or another
 */
# include <openssl/symhacks.h>

#ifdef  __cplusplus
extern "C" {
#endif

/* Backward compatibility to SSLeay */
/*
 * This is more to be used to check the correct DLL is being used in the MS
 * world.
 */
# define SSLEAY_VERSION_NUMBER   OPENSSL_VERSION_NUMBER
# define SSLEAY_VERSION          0
/* #define SSLEAY_OPTIONS       1 no longer supported */
# define SSLEAY_CFLAGS           2
# define SSLEAY_BUILT_ON         3
# define SSLEAY_PLATFORM         4
# define SSLEAY_DIR              5

/* Already declared in ossl_typ.h */
# if 0
typedef struct crypto_ex_data_st CRYPTO_EX_DATA;
/* Called when a new object is created */
typedef int CRYPTO_EX_new (void *parent, void *ptr, CRYPTO_EX_DATA *ad,
                           int idx, long argl, void *argp);
/* Called when an object is free()ed */
typedef void CRYPTO_EX_free (void *parent, void *ptr, CRYPTO_EX_DATA *ad,
                             int idx, long argl, void *argp);
/* Called when we need to dup an object */
typedef int CRYPTO_EX_dup (CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from,
                           void *from_d, int idx, long argl, void *argp);
# endif

/* A generic structure to pass assorted data in a expandable way */
typedef struct openssl_item_st {
    int code;
    void *value;                /* Not used for flag attributes */
    size_t value_size;          /* Max size of value for output, length for
                                 * input */
    size_t *value_length;       /* Returned length of value for output */
} OPENSSL_ITEM;

/*
 * When changing the CRYPTO_LOCK_* list, be sure to maintin the text lock
 * names in cryptlib.c
 */

# define CRYPTO_LOCK_ERR                 1
# define CRYPTO_LOCK_EX_DATA             2
# define CRYPTO_LOCK_X509                3
# define CRYPTO_LOCK_X509_INFO           4
# define CRYPTO_LOCK_X509_PKEY           5
# define CRYPTO_LOCK_X509_CRL            6
# define CRYPTO_LOCK_X509_REQ            7
# define CRYPTO_LOCK_DSA                 8
# define CRYPTO_LOCK_RSA                 9
# define CRYPTO_LOCK_EVP_PKEY            10
# define CRYPTO_LOCK_X509_STORE          11
# define CRYPTO_LOCK_SSL_CTX             12
# define CRYPTO_LOCK_SSL_CERT            13
# define CRYPTO_LOCK_SSL_SESSION         14
# define CRYPTO_LOCK_SSL_SESS_CERT       15
# define CRYPTO_LOCK_SSL                 16
# define CRYPTO_LOCK_SSL_METHOD          17
# define CRYPTO_LOCK_RAND                18
# define CRYPTO_LOCK_RAND2               19
# define CRYPTO_LOCK_MALLOC              20
# define CRYPTO_LOCK_BIO                 21
# define CRYPTO_LOCK_GETHOSTBYNAME       22
# define CRYPTO_LOCK_GETSERVBYNAME       23
# define CRYPTO_LOCK_READDIR             24
# define CRYPTO_LOCK_RSA_BLINDING        25
# define CRYPTO_LOCK_DH                  26
# define CRYPTO_LOCK_MALLOC2             27
# define CRYPTO_LOCK_DSO                 28
# define CRYPTO_LOCK_DYNLOCK             29
# define CRYPTO_LOCK_ENGINE              30
# define CRYPTO_LOCK_UI                  31
# define CRYPTO_LOCK_ECDSA               32
# define CRYPTO_LOCK_EC                  33
# define CRYPTO_LOCK_ECDH                34
# define CRYPTO_LOCK_BN                  35
# define CRYPTO_LOCK_EC_PRE_COMP         36
# define CRYPTO_LOCK_STORE               37
# define CRYPTO_LOCK_COMP                38
# define CRYPTO_LOCK_FIPS                39
# define CRYPTO_LOCK_FIPS2               40
# define CRYPTO_NUM_LOCKS                41

# define CRYPTO_LOCK             1
# define CRYPTO_UNLOCK           2
# define CRYPTO_READ             4
# define CRYPTO_WRITE            8

# ifndef OPENSSL_NO_LOCKING
#  ifndef CRYPTO_w_lock
#   define CRYPTO_w_lock(type)     \
        CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,__FILE__,__LINE__)
#   define CRYPTO_w_unlock(type)   \
        CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,__FILE__,__LINE__)
#   define CRYPTO_r_lock(type)     \
        CRYPTO_lock(CRYPTO_LOCK|CRYPTO_READ,type,__FILE__,__LINE__)
#   define CRYPTO_r_unlock(type)   \
        CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_READ,type,__FILE__,__LINE__)
#   define CRYPTO_add(addr,amount,type)    \
        CRYPTO_add_lock(addr,amount,type,__FILE__,__LINE__)
#  endif
# else
#  define CRYPTO_w_lock(a)
#  define CRYPTO_w_unlock(a)
#  define CRYPTO_r_lock(a)
#  define CRYPTO_r_unlock(a)
#  define CRYPTO_add(a,b,c)       ((*(a))+=(b))
# endif

/*
 * Some applications as well as some parts of OpenSSL need to allocate and
 * deallocate locks in a dynamic fashion.  The following typedef makes this
 * possible in a type-safe manner.
 */
/* struct CRYPTO_dynlock_value has to be defined by the application. */
typedef struct {
    int references;
    struct CRYPTO_dynlock_value *data;
} CRYPTO_dynlock;

/*
 * The following can be used to detect memory leaks in the SSLeay library. It
 * used, it turns on malloc checking
 */

# define CRYPTO_MEM_CHECK_OFF    0x0/* an enume */
# define CRYPTO_MEM_CHECK_ON     0x1/* a bit */
# define CRYPTO_MEM_CHECK_ENABLE 0x2/* a bit */
# define CRYPTO_MEM_CHECK_DISABLE 0x3/* an enume */

/*
 * The following are bit values to turn on or off options connected to the
 * malloc checking functionality
 */

/* Adds time to the memory checking information */
# define V_CRYPTO_MDEBUG_TIME    0x1/* a bit */
/* Adds thread number to the memory checking information */
# define V_CRYPTO_MDEBUG_THREAD  0x2/* a bit */

# define V_CRYPTO_MDEBUG_ALL (V_CRYPTO_MDEBUG_TIME | V_CRYPTO_MDEBUG_THREAD)

/* predec of the BIO type */
typedef struct bio_st BIO_dummy;

struct crypto_ex_data_st {
    STACK_OF(void) *sk;
    /* gcc is screwing up this data structure :-( */
    int dummy;
};
DECLARE_STACK_OF(void)

/*
 * This stuff is basically class callback functions The current classes are
 * SSL_CTX, SSL, SSL_SESSION, and a few more
 */

typedef struct crypto_ex_data_func_st {
    long argl;                  /* Arbitary long */
    void *argp;                 /* Arbitary void * */
    CRYPTO_EX_new *new_func;
    CRYPTO_EX_free *free_func;
    CRYPTO_EX_dup *dup_func;
} CRYPTO_EX_DATA_FUNCS;

DECLARE_STACK_OF(CRYPTO_EX_DATA_FUNCS)

/*
 * Per class, we have a STACK of CRYPTO_EX_DATA_FUNCS for each CRYPTO_EX_DATA
 * entry.
 */

# define CRYPTO_EX_INDEX_BIO             0
# define CRYPTO_EX_INDEX_SSL             1
# define CRYPTO_EX_INDEX_SSL_CTX         2
# define CRYPTO_EX_INDEX_SSL_SESSION     3
# define CRYPTO_EX_INDEX_X509_STORE      4
# define CRYPTO_EX_INDEX_X509_STORE_CTX  5
# define CRYPTO_EX_INDEX_RSA             6
# define CRYPTO_EX_INDEX_DSA             7
# define CRYPTO_EX_INDEX_DH              8
# define CRYPTO_EX_INDEX_ENGINE          9
# define CRYPTO_EX_INDEX_X509            10
# define CRYPTO_EX_INDEX_UI              11
# define CRYPTO_EX_INDEX_ECDSA           12
# define CRYPTO_EX_INDEX_ECDH            13
# define CRYPTO_EX_INDEX_COMP            14
# define CRYPTO_EX_INDEX_STORE           15

/*
 * Dynamically assigned indexes start from this value (don't use directly,
 * use via CRYPTO_ex_data_new_class).
 */
# define CRYPTO_EX_INDEX_USER            100

/*
 * This is the default callbacks, but we can have others as well: this is
 * needed in Win32 where the application malloc and the library malloc may
 * not be the same.
 */
# define CRYPTO_malloc_init()    CRYPTO_set_mem_functions(\
        malloc, realloc, free)

# if defined CRYPTO_MDEBUG_ALL || defined CRYPTO_MDEBUG_TIME || defined CRYPTO_MDEBUG_THREAD
#  ifndef CRYPTO_MDEBUG         /* avoid duplicate #define */
#   define CRYPTO_MDEBUG
#  endif
# endif

/*
 * Set standard debugging functions (not done by default unless CRYPTO_MDEBUG
 * is defined)
 */
# define CRYPTO_malloc_debug_init()      do {\
        CRYPTO_set_mem_debug_functions(\
                CRYPTO_dbg_malloc,\
                CRYPTO_dbg_realloc,\
                CRYPTO_dbg_free,\
                CRYPTO_dbg_set_options,\
                CRYPTO_dbg_get_options);\
        } while(0)

int CRYPTO_mem_ctrl(int mode);
int CRYPTO_is_mem_check_on(void);

/* for applications */
# define MemCheck_start() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON)
# define MemCheck_stop() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF)

/* for library-internal use */
# define MemCheck_on()   CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE)
# define MemCheck_off()  CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE)
# define is_MemCheck_on() CRYPTO_is_mem_check_on()

# define OPENSSL_malloc(num)     CRYPTO_malloc((int)num,__FILE__,__LINE__)
# define OPENSSL_strdup(str)     CRYPTO_strdup((str),__FILE__,__LINE__)
# define OPENSSL_realloc(addr,num) \
        CRYPTO_realloc((char *)addr,(int)num,__FILE__,__LINE__)
# define OPENSSL_realloc_clean(addr,old_num,num) \
        CRYPTO_realloc_clean(addr,old_num,num,__FILE__,__LINE__)
# define OPENSSL_remalloc(addr,num) \
        CRYPTO_remalloc((char **)addr,(int)num,__FILE__,__LINE__)
# define OPENSSL_freeFunc        CRYPTO_free
# define OPENSSL_free(addr)      CRYPTO_free(addr)

# define OPENSSL_malloc_locked(num) \
        CRYPTO_malloc_locked((int)num,__FILE__,__LINE__)
# define OPENSSL_free_locked(addr) CRYPTO_free_locked(addr)

const char *SSLeay_version(int type);
unsigned long SSLeay(void);

int OPENSSL_issetugid(void);

/* An opaque type representing an implementation of "ex_data" support */
typedef struct st_CRYPTO_EX_DATA_IMPL CRYPTO_EX_DATA_IMPL;
/* Return an opaque pointer to the current "ex_data" implementation */
const CRYPTO_EX_DATA_IMPL *CRYPTO_get_ex_data_implementation(void);
/* Sets the "ex_data" implementation to be used (if it's not too late) */
int CRYPTO_set_ex_data_implementation(const CRYPTO_EX_DATA_IMPL *i);
/* Get a new "ex_data" class, and return the corresponding "class_index" */
int CRYPTO_ex_data_new_class(void);
/* Within a given class, get/register a new index */
int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
                            CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
                            CRYPTO_EX_free *free_func);
/*
 * Initialise/duplicate/free CRYPTO_EX_DATA variables corresponding to a
 * given class (invokes whatever per-class callbacks are applicable)
 */
int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad);
int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
                       CRYPTO_EX_DATA *from);
void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad);
/*
 * Get/set data in a CRYPTO_EX_DATA variable corresponding to a particular
 * index (relative to the class type involved)
 */
int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val);
void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx);
/*
 * This function cleans up all "ex_data" state. It mustn't be called under
 * potential race-conditions.
 */
void CRYPTO_cleanup_all_ex_data(void);

int CRYPTO_get_new_lockid(char *name);

int CRYPTO_num_locks(void);     /* return CRYPTO_NUM_LOCKS (shared libs!) */
void CRYPTO_lock(int mode, int type, const char *file, int line);
void CRYPTO_set_locking_callback(void (*func) (int mode, int type,
                                               const char *file, int line));
void (*CRYPTO_get_locking_callback(void)) (int mode, int type,
                                           const char *file, int line);
void CRYPTO_set_add_lock_callback(int (*func)
                                   (int *num, int mount, int type,
                                    const char *file, int line));
int (*CRYPTO_get_add_lock_callback(void)) (int *num, int mount, int type,
                                           const char *file, int line);

/* Don't use this structure directly. */
typedef struct crypto_threadid_st {
    void *ptr;
    unsigned long val;
} CRYPTO_THREADID;
/* Only use CRYPTO_THREADID_set_[numeric|pointer]() within callbacks */
void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val);
void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr);
int CRYPTO_THREADID_set_callback(void (*threadid_func) (CRYPTO_THREADID *));
void (*CRYPTO_THREADID_get_callback(void)) (CRYPTO_THREADID *);
void CRYPTO_THREADID_current(CRYPTO_THREADID *id);
int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b);
void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src);
unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id);
# ifndef OPENSSL_NO_DEPRECATED
void CRYPTO_set_id_callback(unsigned long (*func) (void));
unsigned long (*CRYPTO_get_id_callback(void)) (void);
unsigned long CRYPTO_thread_id(void);
# endif

const char *CRYPTO_get_lock_name(int type);
int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,
                    int line);

int CRYPTO_get_new_dynlockid(void);
void CRYPTO_destroy_dynlockid(int i);
struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i);
void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value
                                        *(*dyn_create_function) (const char
                                                                 *file,
                                                                 int line));
void CRYPTO_set_dynlock_lock_callback(void (*dyn_lock_function)
                                       (int mode,
                                        struct CRYPTO_dynlock_value *l,
                                        const char *file, int line));
void CRYPTO_set_dynlock_destroy_callback(void (*dyn_destroy_function)
                                          (struct CRYPTO_dynlock_value *l,
                                           const char *file, int line));
struct CRYPTO_dynlock_value
*(*CRYPTO_get_dynlock_create_callback(void)) (const char *file, int line);
void (*CRYPTO_get_dynlock_lock_callback(void)) (int mode,
                                                struct CRYPTO_dynlock_value
                                                *l, const char *file,
                                                int line);
void (*CRYPTO_get_dynlock_destroy_callback(void)) (struct CRYPTO_dynlock_value
                                                   *l, const char *file,
                                                   int line);

/*
 * CRYPTO_set_mem_functions includes CRYPTO_set_locked_mem_functions -- call
 * the latter last if you need different functions
 */
int CRYPTO_set_mem_functions(void *(*m) (size_t), void *(*r) (void *, size_t),
                             void (*f) (void *));
int CRYPTO_set_locked_mem_functions(void *(*m) (size_t),
                                    void (*free_func) (void *));
int CRYPTO_set_mem_ex_functions(void *(*m) (size_t, const char *, int),
                                void *(*r) (void *, size_t, const char *,
                                            int), void (*f) (void *));
int CRYPTO_set_locked_mem_ex_functions(void *(*m) (size_t, const char *, int),
                                       void (*free_func) (void *));
int CRYPTO_set_mem_debug_functions(void (*m)
                                    (void *, int, const char *, int, int),
                                   void (*r) (void *, void *, int,
                                              const char *, int, int),
                                   void (*f) (void *, int), void (*so) (long),
                                   long (*go) (void));
void CRYPTO_get_mem_functions(void *(**m) (size_t),
                              void *(**r) (void *, size_t),
                              void (**f) (void *));
void CRYPTO_get_locked_mem_functions(void *(**m) (size_t),
                                     void (**f) (void *));
void CRYPTO_get_mem_ex_functions(void *(**m) (size_t, const char *, int),
                                 void *(**r) (void *, size_t, const char *,
                                              int), void (**f) (void *));
void CRYPTO_get_locked_mem_ex_functions(void
                                        *(**m) (size_t, const char *, int),
                                        void (**f) (void *));
void CRYPTO_get_mem_debug_functions(void (**m)
                                     (void *, int, const char *, int, int),
                                    void (**r) (void *, void *, int,
                                                const char *, int, int),
                                    void (**f) (void *, int),
                                    void (**so) (long), long (**go) (void));

void *CRYPTO_malloc_locked(int num, const char *file, int line);
void CRYPTO_free_locked(void *ptr);
void *CRYPTO_malloc(int num, const char *file, int line);
char *CRYPTO_strdup(const char *str, const char *file, int line);
void CRYPTO_free(void *ptr);
void *CRYPTO_realloc(void *addr, int num, const char *file, int line);
void *CRYPTO_realloc_clean(void *addr, int old_num, int num, const char *file,
                           int line);
void *CRYPTO_remalloc(void *addr, int num, const char *file, int line);

void OPENSSL_cleanse(void *ptr, size_t len);

void CRYPTO_set_mem_debug_options(long bits);
long CRYPTO_get_mem_debug_options(void);

# define CRYPTO_push_info(info) \
        CRYPTO_push_info_(info, __FILE__, __LINE__);
int CRYPTO_push_info_(const char *info, const char *file, int line);
int CRYPTO_pop_info(void);
int CRYPTO_remove_all_info(void);

/*
 * Default debugging functions (enabled by CRYPTO_malloc_debug_init() macro;
 * used as default in CRYPTO_MDEBUG compilations):
 */
/*-
 * The last argument has the following significance:
 *
 * 0:   called before the actual memory allocation has taken place
 * 1:   called after the actual memory allocation has taken place
 */
void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line,
                       int before_p);
void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num, const char *file,
                        int line, int before_p);
void CRYPTO_dbg_free(void *addr, int before_p);
/*-
 * Tell the debugging code about options.  By default, the following values
 * apply:
 *
 * 0:                           Clear all options.
 * V_CRYPTO_MDEBUG_TIME (1):    Set the "Show Time" option.
 * V_CRYPTO_MDEBUG_THREAD (2):  Set the "Show Thread Number" option.
 * V_CRYPTO_MDEBUG_ALL (3):     1 + 2
 */
void CRYPTO_dbg_set_options(long bits);
long CRYPTO_dbg_get_options(void);

# ifndef OPENSSL_NO_FP_API
void CRYPTO_mem_leaks_fp(FILE *);
# endif
void CRYPTO_mem_leaks(struct bio_st *bio);
/* unsigned long order, char *file, int line, int num_bytes, char *addr */
typedef void *CRYPTO_MEM_LEAK_CB (unsigned long, const char *, int, int,
                                  void *);
void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb);

/* die if we have to */
void OpenSSLDie(const char *file, int line, const char *assertion);
# define OPENSSL_assert(e)       (void)((e) ? 0 : (OpenSSLDie(__FILE__, __LINE__, #e),1))

unsigned long *OPENSSL_ia32cap_loc(void);
# define OPENSSL_ia32cap (*(OPENSSL_ia32cap_loc()))
int OPENSSL_isservice(void);

int FIPS_mode(void);
int FIPS_mode_set(int r);

void OPENSSL_init(void);

# define fips_md_init(alg) fips_md_init_ctx(alg, alg)
# define nonfips_md_init(alg) nonfips_md_init_ctx(alg, alg)
# define fips_md_init_ctx(alg, cx) \
        int alg##_Init(cx##_CTX *c)

# ifdef OPENSSL_FIPS
#  define nonfips_md_init_ctx(alg, cx) \
        int alg##_Init(cx##_CTX *c) \
        { \
        if (FIPS_mode()) OpenSSLDie(__FILE__, __LINE__, \
                "Digest " #alg " forbidden in FIPS mode!"); \
        return private_##alg##_Init(c); \
        } \
        int private_##alg##_Init(cx##_CTX *c)

#  define fips_cipher_abort(alg) \
        if (FIPS_mode()) OpenSSLDie(__FILE__, __LINE__, \
                "Cipher " #alg " forbidden in FIPS mode!")

/* die if FIPS selftest failed */
void FIPS_selftest_check(void);

# else
#  define nonfips_md_init_ctx(alg, cx) fips_md_init_ctx(alg, cx)
#  define fips_cipher_abort(alg) while(0)
# endif

/*
 * CRYPTO_memcmp returns zero iff the |len| bytes at |a| and |b| are equal.
 * It takes an amount of time dependent on |len|, but independent of the
 * contents of |a| and |b|. Unlike memcmp, it cannot be used to put elements
 * into a defined order as the return value when a != b is undefined, other
 * than to be non-zero.
 */
int CRYPTO_memcmp(const volatile void *a, const volatile void *b, size_t len);

/* BEGIN ERROR CODES */
/*
 * The following lines are auto generated by the script mkerr.pl. Any changes
 * made after this point may be overwritten when the script is next run.
 */
void ERR_load_CRYPTO_strings(void);

# define OPENSSL_HAVE_INIT       1
void OPENSSL_init_library(void);

/* Error codes for the CRYPTO functions. */

/* Function codes. */
# define CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX                 100
# define CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID                103
# define CRYPTO_F_CRYPTO_GET_NEW_LOCKID                   101
# define CRYPTO_F_CRYPTO_SET_EX_DATA                      102
# define CRYPTO_F_DEF_ADD_INDEX                           104
# define CRYPTO_F_DEF_GET_CLASS                           105
# define CRYPTO_F_FIPS_MODE_SET                           109
# define CRYPTO_F_INT_DUP_EX_DATA                         106
# define CRYPTO_F_INT_FREE_EX_DATA                        107
# define CRYPTO_F_INT_NEW_EX_DATA                         108

/* Reason codes. */
# define CRYPTO_R_FIPS_MODE_NOT_SUPPORTED                 101
# define CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK              100

#ifdef  __cplusplus
}
#endif
#endif
openssl/rc2.h000064400000010702151733316620007075 0ustar00/* crypto/rc2/rc2.h */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#ifndef HEADER_RC2_H
# define HEADER_RC2_H

# include <openssl/opensslconf.h>/* OPENSSL_NO_RC2, RC2_INT */
# ifdef OPENSSL_NO_RC2
#  error RC2 is disabled.
# endif

# define RC2_ENCRYPT     1
# define RC2_DECRYPT     0

# define RC2_BLOCK       8
# define RC2_KEY_LENGTH  16

#ifdef  __cplusplus
extern "C" {
#endif

typedef struct rc2_key_st {
    RC2_INT data[64];
} RC2_KEY;

# ifdef OPENSSL_FIPS
void private_RC2_set_key(RC2_KEY *key, int len, const unsigned char *data,
                         int bits);
# endif
void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits);
void RC2_ecb_encrypt(const unsigned char *in, unsigned char *out,
                     RC2_KEY *key, int enc);
void RC2_encrypt(unsigned long *data, RC2_KEY *key);
void RC2_decrypt(unsigned long *data, RC2_KEY *key);
void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
                     RC2_KEY *ks, unsigned char *iv, int enc);
void RC2_cfb64_encrypt(const unsigned char *in, unsigned char *out,
                       long length, RC2_KEY *schedule, unsigned char *ivec,
                       int *num, int enc);
void RC2_ofb64_encrypt(const unsigned char *in, unsigned char *out,
                       long length, RC2_KEY *schedule, unsigned char *ivec,
                       int *num);

#ifdef  __cplusplus
}
#endif

#endif
openssl/md2.h000064400000007622151733316620007100 0ustar00/* crypto/md/md2.h */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#ifndef HEADER_MD2_H
# define HEADER_MD2_H

# include <openssl/opensslconf.h>/* OPENSSL_NO_MD2, MD2_INT */
# ifdef OPENSSL_NO_MD2
#  error MD2 is disabled.
# endif
# include <stddef.h>

# define MD2_DIGEST_LENGTH       16
# define MD2_BLOCK               16

#ifdef  __cplusplus
extern "C" {
#endif

typedef struct MD2state_st {
    unsigned int num;
    unsigned char data[MD2_BLOCK];
    MD2_INT cksm[MD2_BLOCK];
    MD2_INT state[MD2_BLOCK];
} MD2_CTX;

const char *MD2_options(void);
# ifdef OPENSSL_FIPS
int private_MD2_Init(MD2_CTX *c);
# endif
int MD2_Init(MD2_CTX *c);
int MD2_Update(MD2_CTX *c, const unsigned char *data, size_t len);
int MD2_Final(unsigned char *md, MD2_CTX *c);
unsigned char *MD2(const unsigned char *d, size_t n, unsigned char *md);
#ifdef  __cplusplus
}
#endif

#endif
openssl/kssl.h000064400000015305151733316620007367 0ustar00/* ssl/kssl.h */
/*
 * Written by Vern Staats <staatsvr@asc.hpc.mil> for the OpenSSL project
 * 2000. project 2000.
 */
/* ====================================================================
 * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

/*
 **      19990701        VRS     Started.
 */

#ifndef KSSL_H
# define KSSL_H

# include <openssl/opensslconf.h>

# ifndef OPENSSL_NO_KRB5

#  include <stdio.h>
#  include <ctype.h>
#  include <krb5.h>
#  ifdef OPENSSL_SYS_WIN32
/*
 * These can sometimes get redefined indirectly by krb5 header files after
 * they get undefed in ossl_typ.h
 */
#   undef X509_NAME
#   undef X509_EXTENSIONS
#   undef OCSP_REQUEST
#   undef OCSP_RESPONSE
#  endif

#ifdef  __cplusplus
extern "C" {
#endif

/*
 *      Depending on which KRB5 implementation used, some types from
 *      the other may be missing.  Resolve that here and now
 */
#  ifdef KRB5_HEIMDAL
typedef unsigned char krb5_octet;
#   define FAR
#  else

#   ifndef FAR
#    define FAR
#   endif

#  endif

/*-
 *      Uncomment this to debug kssl problems or
 *      to trace usage of the Kerberos session key
 *
 *      #define         KSSL_DEBUG
 */

#  ifndef KRB5SVC
#   define KRB5SVC "host"
#  endif

#  ifndef KRB5KEYTAB
#   define KRB5KEYTAB      "/etc/krb5.keytab"
#  endif

#  ifndef KRB5SENDAUTH
#   define KRB5SENDAUTH    1
#  endif

#  ifndef KRB5CHECKAUTH
#   define KRB5CHECKAUTH   1
#  endif

#  ifndef KSSL_CLOCKSKEW
#   define KSSL_CLOCKSKEW  300;
#  endif

#  define KSSL_ERR_MAX    255
typedef struct kssl_err_st {
    int reason;
    char text[KSSL_ERR_MAX + 1];
} KSSL_ERR;

/*-     Context for passing
 *              (1) Kerberos session key to SSL, and
 *              (2)     Config data between application and SSL lib
 */
typedef struct kssl_ctx_st {
    /*      used by:    disposition:            */
    char *service_name;         /* C,S default ok (kssl) */
    char *service_host;         /* C input, REQUIRED */
    char *client_princ;         /* S output from krb5 ticket */
    char *keytab_file;          /* S NULL (/etc/krb5.keytab) */
    char *cred_cache;           /* C NULL (default) */
    krb5_enctype enctype;
    int length;
    krb5_octet FAR *key;
} KSSL_CTX;

#  define KSSL_CLIENT     1
#  define KSSL_SERVER     2
#  define KSSL_SERVICE    3
#  define KSSL_KEYTAB     4

#  define KSSL_CTX_OK     0
#  define KSSL_CTX_ERR    1
#  define KSSL_NOMEM      2

/* Public (for use by applications that use OpenSSL with Kerberos 5 support */
krb5_error_code kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text);
KSSL_CTX *kssl_ctx_new(void);
KSSL_CTX *kssl_ctx_free(KSSL_CTX *kssl_ctx);
void kssl_ctx_show(KSSL_CTX *kssl_ctx);
krb5_error_code kssl_ctx_setprinc(KSSL_CTX *kssl_ctx, int which,
                                  krb5_data *realm, krb5_data *entity,
                                  int nentities);
krb5_error_code kssl_cget_tkt(KSSL_CTX *kssl_ctx, krb5_data **enc_tktp,
                              krb5_data *authenp, KSSL_ERR *kssl_err);
krb5_error_code kssl_sget_tkt(KSSL_CTX *kssl_ctx, krb5_data *indata,
                              krb5_ticket_times *ttimes, KSSL_ERR *kssl_err);
krb5_error_code kssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session);
void kssl_err_set(KSSL_ERR *kssl_err, int reason, char *text);
void kssl_krb5_free_data_contents(krb5_context context, krb5_data *data);
krb5_error_code kssl_build_principal_2(krb5_context context,
                                       krb5_principal *princ, int rlen,
                                       const char *realm, int slen,
                                       const char *svc, int hlen,
                                       const char *host);
krb5_error_code kssl_validate_times(krb5_timestamp atime,
                                    krb5_ticket_times *ttimes);
krb5_error_code kssl_check_authent(KSSL_CTX *kssl_ctx, krb5_data *authentp,
                                   krb5_timestamp *atimep,
                                   KSSL_ERR *kssl_err);
unsigned char *kssl_skip_confound(krb5_enctype enctype, unsigned char *authn);

void SSL_set0_kssl_ctx(SSL *s, KSSL_CTX *kctx);
KSSL_CTX *SSL_get0_kssl_ctx(SSL *s);
char *kssl_ctx_get0_client_princ(KSSL_CTX *kctx);

#ifdef  __cplusplus
}
#endif
# endif                         /* OPENSSL_NO_KRB5 */
#endif                          /* KSSL_H */
openssl/fips.h000064400000032477151733316620007365 0ustar00/* ====================================================================
 * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <openssl/opensslconf.h>
#include <openssl/crypto.h>
#include <stdarg.h>

#ifndef OPENSSL_FIPS
# error FIPS is disabled.
#endif

#ifdef OPENSSL_FIPS

# ifdef  __cplusplus
extern "C" {
# endif

    struct dsa_st;
    struct rsa_st;
    struct evp_pkey_st;
    struct env_md_st;
    struct env_md_ctx_st;
    struct evp_cipher_st;
    struct evp_cipher_ctx_st;
    struct dh_method;
    struct CMAC_CTX_st;
    struct hmac_ctx_st;

    int FIPS_module_mode_set(int onoff, const char *auth);
    int FIPS_module_mode(void);
    int FIPS_module_installed(void);
    const void *FIPS_rand_check(void);
    int FIPS_selftest(void);
    int FIPS_selftest_failed(void);
    void FIPS_corrupt_sha1(void);
    int FIPS_selftest_sha1(void);
    int FIPS_selftest_sha2(void);
    void FIPS_corrupt_aes(void);
    int FIPS_selftest_aes_ccm(void);
    int FIPS_selftest_aes_gcm(void);
    int FIPS_selftest_aes_xts(void);
    int FIPS_selftest_aes(void);
    void FIPS_corrupt_des(void);
    int FIPS_selftest_des(void);
    void FIPS_corrupt_rsa(void);
    void FIPS_corrupt_rsa_keygen(void);
    int FIPS_selftest_rsa(void);
    void FIPS_corrupt_dsa(void);
    void FIPS_corrupt_dsa_keygen(void);
    int FIPS_selftest_dsa(void);
    int FIPS_selftest_ecdsa(void);
    int FIPS_selftest_ecdh(void);
    int FIPS_selftest_dh(void);
    void FIPS_corrupt_rng(void);
    void FIPS_rng_stick(void);
    void FIPS_x931_stick(int onoff);
    void FIPS_drbg_stick(int onoff);
    int FIPS_selftest_rng(void);
    int FIPS_selftest_x931(void);
    int FIPS_selftest_hmac(void);
    int FIPS_selftest_drbg(void);
    int FIPS_selftest_drbg_all(void);
    int FIPS_selftest_cmac(void);

    void FIPS_get_timevec(unsigned char *buf, unsigned long *pctr);

# define FIPS_ERROR_IGNORED(alg) OpenSSLDie(__FILE__, __LINE__, \
                alg " previous FIPS forbidden algorithm error ignored");

    int fips_pkey_signature_test(struct evp_pkey_st *pkey,
                                 const unsigned char *tbs, int tbslen,
                                 const unsigned char *kat,
                                 unsigned int katlen,
                                 const struct env_md_st *digest,
                                 unsigned int md_flags, const char *fail_str);

    int fips_cipher_test(struct evp_cipher_ctx_st *ctx,
                         const struct evp_cipher_st *cipher,
                         const unsigned char *key,
                         const unsigned char *iv,
                         const unsigned char *plaintext,
                         const unsigned char *ciphertext, int len);

    void fips_set_selftest_fail(void);

    const struct env_md_st *FIPS_get_digestbynid(int nid);

    const struct evp_cipher_st *FIPS_get_cipherbynid(int nid);

/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes
 * made after this point may be overwritten when the script is next run.
 */
    void ERR_load_FIPS_strings(void);

/* Error codes for the FIPS functions. */

/* Function codes. */
# define FIPS_F_DH_BUILTIN_GENPARAMS                      100
# define FIPS_F_DH_INIT                                   148
# define FIPS_F_DRBG_RESEED                               162
# define FIPS_F_DSA_BUILTIN_PARAMGEN                      101
# define FIPS_F_DSA_BUILTIN_PARAMGEN2                     107
# define FIPS_F_DSA_DO_SIGN                               102
# define FIPS_F_DSA_DO_VERIFY                             103
# define FIPS_F_ECDH_COMPUTE_KEY                          163
# define FIPS_F_ECDSA_DO_SIGN                             164
# define FIPS_F_ECDSA_DO_VERIFY                           165
# define FIPS_F_EC_KEY_GENERATE_KEY                       166
# define FIPS_F_EVP_CIPHERINIT_EX                         124
# define FIPS_F_EVP_DIGESTINIT_EX                         125
# define FIPS_F_FIPS_CHECK_DSA                            104
# define FIPS_F_FIPS_CHECK_DSA_PRNG                       151
# define FIPS_F_FIPS_CHECK_EC                             142
# define FIPS_F_FIPS_CHECK_EC_PRNG                        152
# define FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT             105
# define FIPS_F_FIPS_CHECK_RSA                            106
# define FIPS_F_FIPS_CHECK_RSA_PRNG                       150
# define FIPS_F_FIPS_CIPHER                               160
# define FIPS_F_FIPS_CIPHERINIT                           143
# define FIPS_F_FIPS_CIPHER_CTX_CTRL                      161
# define FIPS_F_FIPS_DIGESTFINAL                          158
# define FIPS_F_FIPS_DIGESTINIT                           128
# define FIPS_F_FIPS_DIGESTUPDATE                         159
# define FIPS_F_FIPS_DRBG_BYTES                           131
# define FIPS_F_FIPS_DRBG_CHECK                           146
# define FIPS_F_FIPS_DRBG_CPRNG_TEST                      132
# define FIPS_F_FIPS_DRBG_ERROR_CHECK                     136
# define FIPS_F_FIPS_DRBG_GENERATE                        134
# define FIPS_F_FIPS_DRBG_INIT                            135
# define FIPS_F_FIPS_DRBG_INSTANTIATE                     138
# define FIPS_F_FIPS_DRBG_NEW                             139
# define FIPS_F_FIPS_DRBG_RESEED                          140
# define FIPS_F_FIPS_DRBG_SINGLE_KAT                      141
# define FIPS_F_FIPS_DSA_CHECK           /* unused */     107
# define FIPS_F_FIPS_DSA_SIGN_DIGEST                      154
# define FIPS_F_FIPS_DSA_VERIFY_DIGEST                    155
# define FIPS_F_FIPS_GET_ENTROPY                          147
# define FIPS_F_FIPS_MODE_SET            /* unused */     108
# define FIPS_F_FIPS_MODULE_MODE_SET                      108
# define FIPS_F_FIPS_PKEY_SIGNATURE_TEST                  109
# define FIPS_F_FIPS_RAND_ADD                             137
# define FIPS_F_FIPS_RAND_BYTES                           122
# define FIPS_F_FIPS_RAND_PSEUDO_BYTES                    167
# define FIPS_F_FIPS_RAND_SEED                            168
# define FIPS_F_FIPS_RAND_SET_METHOD                      126
# define FIPS_F_FIPS_RAND_STATUS                          127
# define FIPS_F_FIPS_RSA_SIGN_DIGEST                      156
# define FIPS_F_FIPS_RSA_VERIFY_DIGEST                    157
# define FIPS_F_FIPS_SELFTEST_AES                         110
# define FIPS_F_FIPS_SELFTEST_AES_CCM                     145
# define FIPS_F_FIPS_SELFTEST_AES_GCM                     129
# define FIPS_F_FIPS_SELFTEST_AES_XTS                     144
# define FIPS_F_FIPS_SELFTEST_CMAC                        130
# define FIPS_F_FIPS_SELFTEST_DES                         111
# define FIPS_F_FIPS_SELFTEST_DSA                         112
# define FIPS_F_FIPS_SELFTEST_ECDSA                       133
# define FIPS_F_FIPS_SELFTEST_HMAC                        113
# define FIPS_F_FIPS_SELFTEST_RNG        /* unused */     114
# define FIPS_F_FIPS_SELFTEST_SHA1                        115
# define FIPS_F_FIPS_SELFTEST_X931                        114
# define FIPS_F_FIPS_SET_PRNG_KEY                         153
# define FIPS_F_HASH_FINAL                                123
# define FIPS_F_RSA_BUILTIN_KEYGEN                        116
# define FIPS_F_RSA_EAY_INIT                              149
# define FIPS_F_RSA_EAY_PRIVATE_DECRYPT                   117
# define FIPS_F_RSA_EAY_PRIVATE_ENCRYPT                   118
# define FIPS_F_RSA_EAY_PUBLIC_DECRYPT                    119
# define FIPS_F_RSA_EAY_PUBLIC_ENCRYPT                    120
# define FIPS_F_RSA_X931_GENERATE_KEY_EX                  121
# define FIPS_F_SSLEAY_RAND_BYTES        /* unused */     122

/* Reason codes. */
# define FIPS_R_ADDITIONAL_INPUT_ERROR_UNDETECTED         150
# define FIPS_R_ADDITIONAL_INPUT_TOO_LONG                 125
# define FIPS_R_ALREADY_INSTANTIATED                      134
# define FIPS_R_AUTHENTICATION_FAILURE                    151
# define FIPS_R_CANNOT_READ_EXE          /* unused */     103
# define FIPS_R_CANNOT_READ_EXE_DIGEST   /* unused */     104
# define FIPS_R_CONTRADICTING_EVIDENCE                    114
# define FIPS_R_DRBG_NOT_INITIALISED                      152
# define FIPS_R_DRBG_STUCK                                103
# define FIPS_R_ENTROPY_ERROR_UNDETECTED                  104
# define FIPS_R_ENTROPY_NOT_REQUESTED_FOR_RESEED          105
# define FIPS_R_ENTROPY_SOURCE_STUCK                      142
# define FIPS_R_ERROR_INITIALISING_DRBG                   115
# define FIPS_R_ERROR_INSTANTIATING_DRBG                  127
# define FIPS_R_ERROR_RETRIEVING_ADDITIONAL_INPUT         124
# define FIPS_R_ERROR_RETRIEVING_ENTROPY                  122
# define FIPS_R_ERROR_RETRIEVING_NONCE                    140
# define FIPS_R_EXE_DIGEST_DOES_NOT_MATCH   /* unused */  105
# define FIPS_R_FINGERPRINT_DOES_NOT_MATCH                110
# define FIPS_R_FINGERPRINT_DOES_NOT_MATCH_NONPIC_RELOCATED 111
# define FIPS_R_FINGERPRINT_DOES_NOT_MATCH_SEGMENT_ALIASING 112
# define FIPS_R_FIPS_MODE_ALREADY_SET                     102
# define FIPS_R_FIPS_SELFTEST_FAILED                      106
# define FIPS_R_FUNCTION_ERROR                            116
# define FIPS_R_GENERATE_ERROR                            137
# define FIPS_R_GENERATE_ERROR_UNDETECTED                 118
# define FIPS_R_INSTANTIATE_ERROR                         119
# define FIPS_R_INSUFFICIENT_SECURITY_STRENGTH            120
# define FIPS_R_INTERNAL_ERROR                            121
# define FIPS_R_INVALID_KEY_LENGTH                        109
# define FIPS_R_INVALID_PARAMETERS                        144
# define FIPS_R_IN_ERROR_STATE                            123
# define FIPS_R_KEY_TOO_SHORT                             108
# define FIPS_R_NONCE_ERROR_UNDETECTED                    149
# define FIPS_R_NON_FIPS_METHOD                           100
# define FIPS_R_NOPR_TEST1_FAILURE                        145
# define FIPS_R_NOPR_TEST2_FAILURE                        146
# define FIPS_R_NOT_INSTANTIATED                          126
# define FIPS_R_PAIRWISE_TEST_FAILED                      107
# define FIPS_R_PERSONALISATION_ERROR_UNDETECTED          128
# define FIPS_R_PERSONALISATION_STRING_TOO_LONG           129
# define FIPS_R_PRNG_STRENGTH_TOO_LOW                     143
# define FIPS_R_PR_TEST1_FAILURE                          147
# define FIPS_R_PR_TEST2_FAILURE                          148
# define FIPS_R_REQUEST_LENGTH_ERROR_UNDETECTED           130
# define FIPS_R_REQUEST_TOO_LARGE_FOR_DRBG                131
# define FIPS_R_RESEED_COUNTER_ERROR                      132
# define FIPS_R_RESEED_ERROR                              133
# define FIPS_R_RSA_DECRYPT_ERROR        /* unused */     115
# define FIPS_R_RSA_ENCRYPT_ERROR        /* unused */     116
# define FIPS_R_SELFTEST_FAILED                           101
# define FIPS_R_SELFTEST_FAILURE                          135
# define FIPS_R_STRENGTH_ERROR_UNDETECTED                 136
# define FIPS_R_TEST_FAILURE                              117
# define FIPS_R_UNINSTANTIATE_ERROR                       141
# define FIPS_R_UNINSTANTIATE_ZEROISE_ERROR               138
# define FIPS_R_UNSUPPORTED_DRBG_TYPE                     139
# define FIPS_R_UNSUPPORTED_PLATFORM                      113

# ifdef  __cplusplus
}
# endif
#endif
openssl/safestack.h000064400000614227151733316620010367 0ustar00/* ====================================================================
 * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#ifndef HEADER_SAFESTACK_H
# define HEADER_SAFESTACK_H

# include <openssl/stack.h>

#ifdef __cplusplus
extern "C" {
#endif

# ifndef CHECKED_PTR_OF
#  define CHECKED_PTR_OF(type, p) \
    ((void*) (1 ? p : (type*)0))
# endif

/*
 * In C++ we get problems because an explicit cast is needed from (void *) we
 * use CHECKED_STACK_OF to ensure the correct type is passed in the macros
 * below.
 */

# define CHECKED_STACK_OF(type, p) \
    ((_STACK*) (1 ? p : (STACK_OF(type)*)0))

# define CHECKED_SK_COPY_FUNC(type, p) \
    ((void *(*)(void *)) ((1 ? p : (type *(*)(const type *))0)))

# define CHECKED_SK_FREE_FUNC(type, p) \
    ((void (*)(void *)) ((1 ? p : (void (*)(type *))0)))

# define CHECKED_SK_CMP_FUNC(type, p) \
    ((int (*)(const void *, const void *)) \
        ((1 ? p : (int (*)(const type * const *, const type * const *))0)))

# define STACK_OF(type) struct stack_st_##type
# define PREDECLARE_STACK_OF(type) STACK_OF(type);

# define DECLARE_STACK_OF(type) \
STACK_OF(type) \
    { \
    _STACK stack; \
    };
# define DECLARE_SPECIAL_STACK_OF(type, type2) \
STACK_OF(type) \
    { \
    _STACK stack; \
    };

/* nada (obsolete in new safestack approach)*/
# define IMPLEMENT_STACK_OF(type)

/*-
 * Strings are special: normally an lhash entry will point to a single
 * (somewhat) mutable object. In the case of strings:
 *
 * a) Instead of a single char, there is an array of chars, NUL-terminated.
 * b) The string may have be immutable.
 *
 * So, they need their own declarations. Especially important for
 * type-checking tools, such as Deputy.
 *
 * In practice, however, it appears to be hard to have a const
 * string. For now, I'm settling for dealing with the fact it is a
 * string at all.
 */
typedef char *OPENSSL_STRING;

typedef const char *OPENSSL_CSTRING;

/*
 * Confusingly, LHASH_OF(STRING) deals with char ** throughout, but
 * STACK_OF(STRING) is really more like STACK_OF(char), only, as mentioned
 * above, instead of a single char each entry is a NUL-terminated array of
 * chars. So, we have to implement STRING specially for STACK_OF. This is
 * dealt with in the autogenerated macros below.
 */

DECLARE_SPECIAL_STACK_OF(OPENSSL_STRING, char)

/*
 * Similarly, we sometimes use a block of characters, NOT nul-terminated.
 * These should also be distinguished from "normal" stacks.
 */
typedef void *OPENSSL_BLOCK;
DECLARE_SPECIAL_STACK_OF(OPENSSL_BLOCK, void)

/*
 * SKM_sk_... stack macros are internal to safestack.h: never use them
 * directly, use sk_<type>_... instead
 */
# define SKM_sk_new(type, cmp) \
        ((STACK_OF(type) *)sk_new(CHECKED_SK_CMP_FUNC(type, cmp)))
# define SKM_sk_new_null(type) \
        ((STACK_OF(type) *)sk_new_null())
# define SKM_sk_free(type, st) \
        sk_free(CHECKED_STACK_OF(type, st))
# define SKM_sk_num(type, st) \
        sk_num(CHECKED_STACK_OF(type, st))
# define SKM_sk_value(type, st,i) \
        ((type *)sk_value(CHECKED_STACK_OF(type, st), i))
# define SKM_sk_set(type, st,i,val) \
        sk_set(CHECKED_STACK_OF(type, st), i, CHECKED_PTR_OF(type, val))
# define SKM_sk_zero(type, st) \
        sk_zero(CHECKED_STACK_OF(type, st))
# define SKM_sk_push(type, st, val) \
        sk_push(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val))
# define SKM_sk_unshift(type, st, val) \
        sk_unshift(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val))
# define SKM_sk_find(type, st, val) \
        sk_find(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val))
# define SKM_sk_find_ex(type, st, val) \
        sk_find_ex(CHECKED_STACK_OF(type, st), \
                   CHECKED_PTR_OF(type, val))
# define SKM_sk_delete(type, st, i) \
        (type *)sk_delete(CHECKED_STACK_OF(type, st), i)
# define SKM_sk_delete_ptr(type, st, ptr) \
        (type *)sk_delete_ptr(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, ptr))
# define SKM_sk_insert(type, st,val, i) \
        sk_insert(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val), i)
# define SKM_sk_set_cmp_func(type, st, cmp) \
        ((int (*)(const type * const *,const type * const *)) \
        sk_set_cmp_func(CHECKED_STACK_OF(type, st), CHECKED_SK_CMP_FUNC(type, cmp)))
# define SKM_sk_dup(type, st) \
        (STACK_OF(type) *)sk_dup(CHECKED_STACK_OF(type, st))
# define SKM_sk_pop_free(type, st, free_func) \
        sk_pop_free(CHECKED_STACK_OF(type, st), CHECKED_SK_FREE_FUNC(type, free_func))
# define SKM_sk_deep_copy(type, st, copy_func, free_func) \
        (STACK_OF(type) *)sk_deep_copy(CHECKED_STACK_OF(type, st), CHECKED_SK_COPY_FUNC(type, copy_func), CHECKED_SK_FREE_FUNC(type, free_func))
# define SKM_sk_shift(type, st) \
        (type *)sk_shift(CHECKED_STACK_OF(type, st))
# define SKM_sk_pop(type, st) \
        (type *)sk_pop(CHECKED_STACK_OF(type, st))
# define SKM_sk_sort(type, st) \
        sk_sort(CHECKED_STACK_OF(type, st))
# define SKM_sk_is_sorted(type, st) \
        sk_is_sorted(CHECKED_STACK_OF(type, st))
# define SKM_ASN1_SET_OF_d2i(type, st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
  (STACK_OF(type) *)d2i_ASN1_SET( \
                                (STACK_OF(OPENSSL_BLOCK) **)CHECKED_PTR_OF(STACK_OF(type)*, st), \
                                pp, length, \
                                CHECKED_D2I_OF(type, d2i_func), \
                                CHECKED_SK_FREE_FUNC(type, free_func), \
                                ex_tag, ex_class)
# define SKM_ASN1_SET_OF_i2d(type, st, pp, i2d_func, ex_tag, ex_class, is_set) \
  i2d_ASN1_SET((STACK_OF(OPENSSL_BLOCK) *)CHECKED_STACK_OF(type, st), pp, \
                                CHECKED_I2D_OF(type, i2d_func), \
                                ex_tag, ex_class, is_set)
# define SKM_ASN1_seq_pack(type, st, i2d_func, buf, len) \
        ASN1_seq_pack(CHECKED_PTR_OF(STACK_OF(type), st), \
                        CHECKED_I2D_OF(type, i2d_func), buf, len)
# define SKM_ASN1_seq_unpack(type, buf, len, d2i_func, free_func) \
        (STACK_OF(type) *)ASN1_seq_unpack(buf, len, CHECKED_D2I_OF(type, d2i_func), CHECKED_SK_FREE_FUNC(type, free_func))
# define SKM_PKCS12_decrypt_d2i(type, algor, d2i_func, free_func, pass, passlen, oct, seq) \
        (STACK_OF(type) *)PKCS12_decrypt_d2i(algor, \
                                CHECKED_D2I_OF(type, d2i_func), \
                                CHECKED_SK_FREE_FUNC(type, free_func), \
                                pass, passlen, oct, seq)
/*
 * This block of defines is updated by util/mkstack.pl, please do not touch!
 */
# define sk_ACCESS_DESCRIPTION_new(cmp) SKM_sk_new(ACCESS_DESCRIPTION, (cmp))
# define sk_ACCESS_DESCRIPTION_new_null() SKM_sk_new_null(ACCESS_DESCRIPTION)
# define sk_ACCESS_DESCRIPTION_free(st) SKM_sk_free(ACCESS_DESCRIPTION, (st))
# define sk_ACCESS_DESCRIPTION_num(st) SKM_sk_num(ACCESS_DESCRIPTION, (st))
# define sk_ACCESS_DESCRIPTION_value(st, i) SKM_sk_value(ACCESS_DESCRIPTION, (st), (i))
# define sk_ACCESS_DESCRIPTION_set(st, i, val) SKM_sk_set(ACCESS_DESCRIPTION, (st), (i), (val))
# define sk_ACCESS_DESCRIPTION_zero(st) SKM_sk_zero(ACCESS_DESCRIPTION, (st))
# define sk_ACCESS_DESCRIPTION_push(st, val) SKM_sk_push(ACCESS_DESCRIPTION, (st), (val))
# define sk_ACCESS_DESCRIPTION_unshift(st, val) SKM_sk_unshift(ACCESS_DESCRIPTION, (st), (val))
# define sk_ACCESS_DESCRIPTION_find(st, val) SKM_sk_find(ACCESS_DESCRIPTION, (st), (val))
# define sk_ACCESS_DESCRIPTION_find_ex(st, val) SKM_sk_find_ex(ACCESS_DESCRIPTION, (st), (val))
# define sk_ACCESS_DESCRIPTION_delete(st, i) SKM_sk_delete(ACCESS_DESCRIPTION, (st), (i))
# define sk_ACCESS_DESCRIPTION_delete_ptr(st, ptr) SKM_sk_delete_ptr(ACCESS_DESCRIPTION, (st), (ptr))
# define sk_ACCESS_DESCRIPTION_insert(st, val, i) SKM_sk_insert(ACCESS_DESCRIPTION, (st), (val), (i))
# define sk_ACCESS_DESCRIPTION_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ACCESS_DESCRIPTION, (st), (cmp))
# define sk_ACCESS_DESCRIPTION_dup(st) SKM_sk_dup(ACCESS_DESCRIPTION, st)
# define sk_ACCESS_DESCRIPTION_pop_free(st, free_func) SKM_sk_pop_free(ACCESS_DESCRIPTION, (st), (free_func))
# define sk_ACCESS_DESCRIPTION_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ACCESS_DESCRIPTION, (st), (copy_func), (free_func))
# define sk_ACCESS_DESCRIPTION_shift(st) SKM_sk_shift(ACCESS_DESCRIPTION, (st))
# define sk_ACCESS_DESCRIPTION_pop(st) SKM_sk_pop(ACCESS_DESCRIPTION, (st))
# define sk_ACCESS_DESCRIPTION_sort(st) SKM_sk_sort(ACCESS_DESCRIPTION, (st))
# define sk_ACCESS_DESCRIPTION_is_sorted(st) SKM_sk_is_sorted(ACCESS_DESCRIPTION, (st))
# define sk_ASIdOrRange_new(cmp) SKM_sk_new(ASIdOrRange, (cmp))
# define sk_ASIdOrRange_new_null() SKM_sk_new_null(ASIdOrRange)
# define sk_ASIdOrRange_free(st) SKM_sk_free(ASIdOrRange, (st))
# define sk_ASIdOrRange_num(st) SKM_sk_num(ASIdOrRange, (st))
# define sk_ASIdOrRange_value(st, i) SKM_sk_value(ASIdOrRange, (st), (i))
# define sk_ASIdOrRange_set(st, i, val) SKM_sk_set(ASIdOrRange, (st), (i), (val))
# define sk_ASIdOrRange_zero(st) SKM_sk_zero(ASIdOrRange, (st))
# define sk_ASIdOrRange_push(st, val) SKM_sk_push(ASIdOrRange, (st), (val))
# define sk_ASIdOrRange_unshift(st, val) SKM_sk_unshift(ASIdOrRange, (st), (val))
# define sk_ASIdOrRange_find(st, val) SKM_sk_find(ASIdOrRange, (st), (val))
# define sk_ASIdOrRange_find_ex(st, val) SKM_sk_find_ex(ASIdOrRange, (st), (val))
# define sk_ASIdOrRange_delete(st, i) SKM_sk_delete(ASIdOrRange, (st), (i))
# define sk_ASIdOrRange_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASIdOrRange, (st), (ptr))
# define sk_ASIdOrRange_insert(st, val, i) SKM_sk_insert(ASIdOrRange, (st), (val), (i))
# define sk_ASIdOrRange_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASIdOrRange, (st), (cmp))
# define sk_ASIdOrRange_dup(st) SKM_sk_dup(ASIdOrRange, st)
# define sk_ASIdOrRange_pop_free(st, free_func) SKM_sk_pop_free(ASIdOrRange, (st), (free_func))
# define sk_ASIdOrRange_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASIdOrRange, (st), (copy_func), (free_func))
# define sk_ASIdOrRange_shift(st) SKM_sk_shift(ASIdOrRange, (st))
# define sk_ASIdOrRange_pop(st) SKM_sk_pop(ASIdOrRange, (st))
# define sk_ASIdOrRange_sort(st) SKM_sk_sort(ASIdOrRange, (st))
# define sk_ASIdOrRange_is_sorted(st) SKM_sk_is_sorted(ASIdOrRange, (st))
# define sk_ASN1_GENERALSTRING_new(cmp) SKM_sk_new(ASN1_GENERALSTRING, (cmp))
# define sk_ASN1_GENERALSTRING_new_null() SKM_sk_new_null(ASN1_GENERALSTRING)
# define sk_ASN1_GENERALSTRING_free(st) SKM_sk_free(ASN1_GENERALSTRING, (st))
# define sk_ASN1_GENERALSTRING_num(st) SKM_sk_num(ASN1_GENERALSTRING, (st))
# define sk_ASN1_GENERALSTRING_value(st, i) SKM_sk_value(ASN1_GENERALSTRING, (st), (i))
# define sk_ASN1_GENERALSTRING_set(st, i, val) SKM_sk_set(ASN1_GENERALSTRING, (st), (i), (val))
# define sk_ASN1_GENERALSTRING_zero(st) SKM_sk_zero(ASN1_GENERALSTRING, (st))
# define sk_ASN1_GENERALSTRING_push(st, val) SKM_sk_push(ASN1_GENERALSTRING, (st), (val))
# define sk_ASN1_GENERALSTRING_unshift(st, val) SKM_sk_unshift(ASN1_GENERALSTRING, (st), (val))
# define sk_ASN1_GENERALSTRING_find(st, val) SKM_sk_find(ASN1_GENERALSTRING, (st), (val))
# define sk_ASN1_GENERALSTRING_find_ex(st, val) SKM_sk_find_ex(ASN1_GENERALSTRING, (st), (val))
# define sk_ASN1_GENERALSTRING_delete(st, i) SKM_sk_delete(ASN1_GENERALSTRING, (st), (i))
# define sk_ASN1_GENERALSTRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_GENERALSTRING, (st), (ptr))
# define sk_ASN1_GENERALSTRING_insert(st, val, i) SKM_sk_insert(ASN1_GENERALSTRING, (st), (val), (i))
# define sk_ASN1_GENERALSTRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_GENERALSTRING, (st), (cmp))
# define sk_ASN1_GENERALSTRING_dup(st) SKM_sk_dup(ASN1_GENERALSTRING, st)
# define sk_ASN1_GENERALSTRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_GENERALSTRING, (st), (free_func))
# define sk_ASN1_GENERALSTRING_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_GENERALSTRING, (st), (copy_func), (free_func))
# define sk_ASN1_GENERALSTRING_shift(st) SKM_sk_shift(ASN1_GENERALSTRING, (st))
# define sk_ASN1_GENERALSTRING_pop(st) SKM_sk_pop(ASN1_GENERALSTRING, (st))
# define sk_ASN1_GENERALSTRING_sort(st) SKM_sk_sort(ASN1_GENERALSTRING, (st))
# define sk_ASN1_GENERALSTRING_is_sorted(st) SKM_sk_is_sorted(ASN1_GENERALSTRING, (st))
# define sk_ASN1_INTEGER_new(cmp) SKM_sk_new(ASN1_INTEGER, (cmp))
# define sk_ASN1_INTEGER_new_null() SKM_sk_new_null(ASN1_INTEGER)
# define sk_ASN1_INTEGER_free(st) SKM_sk_free(ASN1_INTEGER, (st))
# define sk_ASN1_INTEGER_num(st) SKM_sk_num(ASN1_INTEGER, (st))
# define sk_ASN1_INTEGER_value(st, i) SKM_sk_value(ASN1_INTEGER, (st), (i))
# define sk_ASN1_INTEGER_set(st, i, val) SKM_sk_set(ASN1_INTEGER, (st), (i), (val))
# define sk_ASN1_INTEGER_zero(st) SKM_sk_zero(ASN1_INTEGER, (st))
# define sk_ASN1_INTEGER_push(st, val) SKM_sk_push(ASN1_INTEGER, (st), (val))
# define sk_ASN1_INTEGER_unshift(st, val) SKM_sk_unshift(ASN1_INTEGER, (st), (val))
# define sk_ASN1_INTEGER_find(st, val) SKM_sk_find(ASN1_INTEGER, (st), (val))
# define sk_ASN1_INTEGER_find_ex(st, val) SKM_sk_find_ex(ASN1_INTEGER, (st), (val))
# define sk_ASN1_INTEGER_delete(st, i) SKM_sk_delete(ASN1_INTEGER, (st), (i))
# define sk_ASN1_INTEGER_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_INTEGER, (st), (ptr))
# define sk_ASN1_INTEGER_insert(st, val, i) SKM_sk_insert(ASN1_INTEGER, (st), (val), (i))
# define sk_ASN1_INTEGER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_INTEGER, (st), (cmp))
# define sk_ASN1_INTEGER_dup(st) SKM_sk_dup(ASN1_INTEGER, st)
# define sk_ASN1_INTEGER_pop_free(st, free_func) SKM_sk_pop_free(ASN1_INTEGER, (st), (free_func))
# define sk_ASN1_INTEGER_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_INTEGER, (st), (copy_func), (free_func))
# define sk_ASN1_INTEGER_shift(st) SKM_sk_shift(ASN1_INTEGER, (st))
# define sk_ASN1_INTEGER_pop(st) SKM_sk_pop(ASN1_INTEGER, (st))
# define sk_ASN1_INTEGER_sort(st) SKM_sk_sort(ASN1_INTEGER, (st))
# define sk_ASN1_INTEGER_is_sorted(st) SKM_sk_is_sorted(ASN1_INTEGER, (st))
# define sk_ASN1_OBJECT_new(cmp) SKM_sk_new(ASN1_OBJECT, (cmp))
# define sk_ASN1_OBJECT_new_null() SKM_sk_new_null(ASN1_OBJECT)
# define sk_ASN1_OBJECT_free(st) SKM_sk_free(ASN1_OBJECT, (st))
# define sk_ASN1_OBJECT_num(st) SKM_sk_num(ASN1_OBJECT, (st))
# define sk_ASN1_OBJECT_value(st, i) SKM_sk_value(ASN1_OBJECT, (st), (i))
# define sk_ASN1_OBJECT_set(st, i, val) SKM_sk_set(ASN1_OBJECT, (st), (i), (val))
# define sk_ASN1_OBJECT_zero(st) SKM_sk_zero(ASN1_OBJECT, (st))
# define sk_ASN1_OBJECT_push(st, val) SKM_sk_push(ASN1_OBJECT, (st), (val))
# define sk_ASN1_OBJECT_unshift(st, val) SKM_sk_unshift(ASN1_OBJECT, (st), (val))
# define sk_ASN1_OBJECT_find(st, val) SKM_sk_find(ASN1_OBJECT, (st), (val))
# define sk_ASN1_OBJECT_find_ex(st, val) SKM_sk_find_ex(ASN1_OBJECT, (st), (val))
# define sk_ASN1_OBJECT_delete(st, i) SKM_sk_delete(ASN1_OBJECT, (st), (i))
# define sk_ASN1_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_OBJECT, (st), (ptr))
# define sk_ASN1_OBJECT_insert(st, val, i) SKM_sk_insert(ASN1_OBJECT, (st), (val), (i))
# define sk_ASN1_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_OBJECT, (st), (cmp))
# define sk_ASN1_OBJECT_dup(st) SKM_sk_dup(ASN1_OBJECT, st)
# define sk_ASN1_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(ASN1_OBJECT, (st), (free_func))
# define sk_ASN1_OBJECT_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_OBJECT, (st), (copy_func), (free_func))
# define sk_ASN1_OBJECT_shift(st) SKM_sk_shift(ASN1_OBJECT, (st))
# define sk_ASN1_OBJECT_pop(st) SKM_sk_pop(ASN1_OBJECT, (st))
# define sk_ASN1_OBJECT_sort(st) SKM_sk_sort(ASN1_OBJECT, (st))
# define sk_ASN1_OBJECT_is_sorted(st) SKM_sk_is_sorted(ASN1_OBJECT, (st))
# define sk_ASN1_STRING_TABLE_new(cmp) SKM_sk_new(ASN1_STRING_TABLE, (cmp))
# define sk_ASN1_STRING_TABLE_new_null() SKM_sk_new_null(ASN1_STRING_TABLE)
# define sk_ASN1_STRING_TABLE_free(st) SKM_sk_free(ASN1_STRING_TABLE, (st))
# define sk_ASN1_STRING_TABLE_num(st) SKM_sk_num(ASN1_STRING_TABLE, (st))
# define sk_ASN1_STRING_TABLE_value(st, i) SKM_sk_value(ASN1_STRING_TABLE, (st), (i))
# define sk_ASN1_STRING_TABLE_set(st, i, val) SKM_sk_set(ASN1_STRING_TABLE, (st), (i), (val))
# define sk_ASN1_STRING_TABLE_zero(st) SKM_sk_zero(ASN1_STRING_TABLE, (st))
# define sk_ASN1_STRING_TABLE_push(st, val) SKM_sk_push(ASN1_STRING_TABLE, (st), (val))
# define sk_ASN1_STRING_TABLE_unshift(st, val) SKM_sk_unshift(ASN1_STRING_TABLE, (st), (val))
# define sk_ASN1_STRING_TABLE_find(st, val) SKM_sk_find(ASN1_STRING_TABLE, (st), (val))
# define sk_ASN1_STRING_TABLE_find_ex(st, val) SKM_sk_find_ex(ASN1_STRING_TABLE, (st), (val))
# define sk_ASN1_STRING_TABLE_delete(st, i) SKM_sk_delete(ASN1_STRING_TABLE, (st), (i))
# define sk_ASN1_STRING_TABLE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_STRING_TABLE, (st), (ptr))
# define sk_ASN1_STRING_TABLE_insert(st, val, i) SKM_sk_insert(ASN1_STRING_TABLE, (st), (val), (i))
# define sk_ASN1_STRING_TABLE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_STRING_TABLE, (st), (cmp))
# define sk_ASN1_STRING_TABLE_dup(st) SKM_sk_dup(ASN1_STRING_TABLE, st)
# define sk_ASN1_STRING_TABLE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_STRING_TABLE, (st), (free_func))
# define sk_ASN1_STRING_TABLE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_STRING_TABLE, (st), (copy_func), (free_func))
# define sk_ASN1_STRING_TABLE_shift(st) SKM_sk_shift(ASN1_STRING_TABLE, (st))
# define sk_ASN1_STRING_TABLE_pop(st) SKM_sk_pop(ASN1_STRING_TABLE, (st))
# define sk_ASN1_STRING_TABLE_sort(st) SKM_sk_sort(ASN1_STRING_TABLE, (st))
# define sk_ASN1_STRING_TABLE_is_sorted(st) SKM_sk_is_sorted(ASN1_STRING_TABLE, (st))
# define sk_ASN1_TYPE_new(cmp) SKM_sk_new(ASN1_TYPE, (cmp))
# define sk_ASN1_TYPE_new_null() SKM_sk_new_null(ASN1_TYPE)
# define sk_ASN1_TYPE_free(st) SKM_sk_free(ASN1_TYPE, (st))
# define sk_ASN1_TYPE_num(st) SKM_sk_num(ASN1_TYPE, (st))
# define sk_ASN1_TYPE_value(st, i) SKM_sk_value(ASN1_TYPE, (st), (i))
# define sk_ASN1_TYPE_set(st, i, val) SKM_sk_set(ASN1_TYPE, (st), (i), (val))
# define sk_ASN1_TYPE_zero(st) SKM_sk_zero(ASN1_TYPE, (st))
# define sk_ASN1_TYPE_push(st, val) SKM_sk_push(ASN1_TYPE, (st), (val))
# define sk_ASN1_TYPE_unshift(st, val) SKM_sk_unshift(ASN1_TYPE, (st), (val))
# define sk_ASN1_TYPE_find(st, val) SKM_sk_find(ASN1_TYPE, (st), (val))
# define sk_ASN1_TYPE_find_ex(st, val) SKM_sk_find_ex(ASN1_TYPE, (st), (val))
# define sk_ASN1_TYPE_delete(st, i) SKM_sk_delete(ASN1_TYPE, (st), (i))
# define sk_ASN1_TYPE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_TYPE, (st), (ptr))
# define sk_ASN1_TYPE_insert(st, val, i) SKM_sk_insert(ASN1_TYPE, (st), (val), (i))
# define sk_ASN1_TYPE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_TYPE, (st), (cmp))
# define sk_ASN1_TYPE_dup(st) SKM_sk_dup(ASN1_TYPE, st)
# define sk_ASN1_TYPE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_TYPE, (st), (free_func))
# define sk_ASN1_TYPE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_TYPE, (st), (copy_func), (free_func))
# define sk_ASN1_TYPE_shift(st) SKM_sk_shift(ASN1_TYPE, (st))
# define sk_ASN1_TYPE_pop(st) SKM_sk_pop(ASN1_TYPE, (st))
# define sk_ASN1_TYPE_sort(st) SKM_sk_sort(ASN1_TYPE, (st))
# define sk_ASN1_TYPE_is_sorted(st) SKM_sk_is_sorted(ASN1_TYPE, (st))
# define sk_ASN1_UTF8STRING_new(cmp) SKM_sk_new(ASN1_UTF8STRING, (cmp))
# define sk_ASN1_UTF8STRING_new_null() SKM_sk_new_null(ASN1_UTF8STRING)
# define sk_ASN1_UTF8STRING_free(st) SKM_sk_free(ASN1_UTF8STRING, (st))
# define sk_ASN1_UTF8STRING_num(st) SKM_sk_num(ASN1_UTF8STRING, (st))
# define sk_ASN1_UTF8STRING_value(st, i) SKM_sk_value(ASN1_UTF8STRING, (st), (i))
# define sk_ASN1_UTF8STRING_set(st, i, val) SKM_sk_set(ASN1_UTF8STRING, (st), (i), (val))
# define sk_ASN1_UTF8STRING_zero(st) SKM_sk_zero(ASN1_UTF8STRING, (st))
# define sk_ASN1_UTF8STRING_push(st, val) SKM_sk_push(ASN1_UTF8STRING, (st), (val))
# define sk_ASN1_UTF8STRING_unshift(st, val) SKM_sk_unshift(ASN1_UTF8STRING, (st), (val))
# define sk_ASN1_UTF8STRING_find(st, val) SKM_sk_find(ASN1_UTF8STRING, (st), (val))
# define sk_ASN1_UTF8STRING_find_ex(st, val) SKM_sk_find_ex(ASN1_UTF8STRING, (st), (val))
# define sk_ASN1_UTF8STRING_delete(st, i) SKM_sk_delete(ASN1_UTF8STRING, (st), (i))
# define sk_ASN1_UTF8STRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_UTF8STRING, (st), (ptr))
# define sk_ASN1_UTF8STRING_insert(st, val, i) SKM_sk_insert(ASN1_UTF8STRING, (st), (val), (i))
# define sk_ASN1_UTF8STRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_UTF8STRING, (st), (cmp))
# define sk_ASN1_UTF8STRING_dup(st) SKM_sk_dup(ASN1_UTF8STRING, st)
# define sk_ASN1_UTF8STRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_UTF8STRING, (st), (free_func))
# define sk_ASN1_UTF8STRING_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_UTF8STRING, (st), (copy_func), (free_func))
# define sk_ASN1_UTF8STRING_shift(st) SKM_sk_shift(ASN1_UTF8STRING, (st))
# define sk_ASN1_UTF8STRING_pop(st) SKM_sk_pop(ASN1_UTF8STRING, (st))
# define sk_ASN1_UTF8STRING_sort(st) SKM_sk_sort(ASN1_UTF8STRING, (st))
# define sk_ASN1_UTF8STRING_is_sorted(st) SKM_sk_is_sorted(ASN1_UTF8STRING, (st))
# define sk_ASN1_VALUE_new(cmp) SKM_sk_new(ASN1_VALUE, (cmp))
# define sk_ASN1_VALUE_new_null() SKM_sk_new_null(ASN1_VALUE)
# define sk_ASN1_VALUE_free(st) SKM_sk_free(ASN1_VALUE, (st))
# define sk_ASN1_VALUE_num(st) SKM_sk_num(ASN1_VALUE, (st))
# define sk_ASN1_VALUE_value(st, i) SKM_sk_value(ASN1_VALUE, (st), (i))
# define sk_ASN1_VALUE_set(st, i, val) SKM_sk_set(ASN1_VALUE, (st), (i), (val))
# define sk_ASN1_VALUE_zero(st) SKM_sk_zero(ASN1_VALUE, (st))
# define sk_ASN1_VALUE_push(st, val) SKM_sk_push(ASN1_VALUE, (st), (val))
# define sk_ASN1_VALUE_unshift(st, val) SKM_sk_unshift(ASN1_VALUE, (st), (val))
# define sk_ASN1_VALUE_find(st, val) SKM_sk_find(ASN1_VALUE, (st), (val))
# define sk_ASN1_VALUE_find_ex(st, val) SKM_sk_find_ex(ASN1_VALUE, (st), (val))
# define sk_ASN1_VALUE_delete(st, i) SKM_sk_delete(ASN1_VALUE, (st), (i))
# define sk_ASN1_VALUE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_VALUE, (st), (ptr))
# define sk_ASN1_VALUE_insert(st, val, i) SKM_sk_insert(ASN1_VALUE, (st), (val), (i))
# define sk_ASN1_VALUE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_VALUE, (st), (cmp))
# define sk_ASN1_VALUE_dup(st) SKM_sk_dup(ASN1_VALUE, st)
# define sk_ASN1_VALUE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_VALUE, (st), (free_func))
# define sk_ASN1_VALUE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_VALUE, (st), (copy_func), (free_func))
# define sk_ASN1_VALUE_shift(st) SKM_sk_shift(ASN1_VALUE, (st))
# define sk_ASN1_VALUE_pop(st) SKM_sk_pop(ASN1_VALUE, (st))
# define sk_ASN1_VALUE_sort(st) SKM_sk_sort(ASN1_VALUE, (st))
# define sk_ASN1_VALUE_is_sorted(st) SKM_sk_is_sorted(ASN1_VALUE, (st))
# define sk_BIO_new(cmp) SKM_sk_new(BIO, (cmp))
# define sk_BIO_new_null() SKM_sk_new_null(BIO)
# define sk_BIO_free(st) SKM_sk_free(BIO, (st))
# define sk_BIO_num(st) SKM_sk_num(BIO, (st))
# define sk_BIO_value(st, i) SKM_sk_value(BIO, (st), (i))
# define sk_BIO_set(st, i, val) SKM_sk_set(BIO, (st), (i), (val))
# define sk_BIO_zero(st) SKM_sk_zero(BIO, (st))
# define sk_BIO_push(st, val) SKM_sk_push(BIO, (st), (val))
# define sk_BIO_unshift(st, val) SKM_sk_unshift(BIO, (st), (val))
# define sk_BIO_find(st, val) SKM_sk_find(BIO, (st), (val))
# define sk_BIO_find_ex(st, val) SKM_sk_find_ex(BIO, (st), (val))
# define sk_BIO_delete(st, i) SKM_sk_delete(BIO, (st), (i))
# define sk_BIO_delete_ptr(st, ptr) SKM_sk_delete_ptr(BIO, (st), (ptr))
# define sk_BIO_insert(st, val, i) SKM_sk_insert(BIO, (st), (val), (i))
# define sk_BIO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BIO, (st), (cmp))
# define sk_BIO_dup(st) SKM_sk_dup(BIO, st)
# define sk_BIO_pop_free(st, free_func) SKM_sk_pop_free(BIO, (st), (free_func))
# define sk_BIO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(BIO, (st), (copy_func), (free_func))
# define sk_BIO_shift(st) SKM_sk_shift(BIO, (st))
# define sk_BIO_pop(st) SKM_sk_pop(BIO, (st))
# define sk_BIO_sort(st) SKM_sk_sort(BIO, (st))
# define sk_BIO_is_sorted(st) SKM_sk_is_sorted(BIO, (st))
# define sk_BY_DIR_ENTRY_new(cmp) SKM_sk_new(BY_DIR_ENTRY, (cmp))
# define sk_BY_DIR_ENTRY_new_null() SKM_sk_new_null(BY_DIR_ENTRY)
# define sk_BY_DIR_ENTRY_free(st) SKM_sk_free(BY_DIR_ENTRY, (st))
# define sk_BY_DIR_ENTRY_num(st) SKM_sk_num(BY_DIR_ENTRY, (st))
# define sk_BY_DIR_ENTRY_value(st, i) SKM_sk_value(BY_DIR_ENTRY, (st), (i))
# define sk_BY_DIR_ENTRY_set(st, i, val) SKM_sk_set(BY_DIR_ENTRY, (st), (i), (val))
# define sk_BY_DIR_ENTRY_zero(st) SKM_sk_zero(BY_DIR_ENTRY, (st))
# define sk_BY_DIR_ENTRY_push(st, val) SKM_sk_push(BY_DIR_ENTRY, (st), (val))
# define sk_BY_DIR_ENTRY_unshift(st, val) SKM_sk_unshift(BY_DIR_ENTRY, (st), (val))
# define sk_BY_DIR_ENTRY_find(st, val) SKM_sk_find(BY_DIR_ENTRY, (st), (val))
# define sk_BY_DIR_ENTRY_find_ex(st, val) SKM_sk_find_ex(BY_DIR_ENTRY, (st), (val))
# define sk_BY_DIR_ENTRY_delete(st, i) SKM_sk_delete(BY_DIR_ENTRY, (st), (i))
# define sk_BY_DIR_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_ENTRY, (st), (ptr))
# define sk_BY_DIR_ENTRY_insert(st, val, i) SKM_sk_insert(BY_DIR_ENTRY, (st), (val), (i))
# define sk_BY_DIR_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_ENTRY, (st), (cmp))
# define sk_BY_DIR_ENTRY_dup(st) SKM_sk_dup(BY_DIR_ENTRY, st)
# define sk_BY_DIR_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_ENTRY, (st), (free_func))
# define sk_BY_DIR_ENTRY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(BY_DIR_ENTRY, (st), (copy_func), (free_func))
# define sk_BY_DIR_ENTRY_shift(st) SKM_sk_shift(BY_DIR_ENTRY, (st))
# define sk_BY_DIR_ENTRY_pop(st) SKM_sk_pop(BY_DIR_ENTRY, (st))
# define sk_BY_DIR_ENTRY_sort(st) SKM_sk_sort(BY_DIR_ENTRY, (st))
# define sk_BY_DIR_ENTRY_is_sorted(st) SKM_sk_is_sorted(BY_DIR_ENTRY, (st))
# define sk_BY_DIR_HASH_new(cmp) SKM_sk_new(BY_DIR_HASH, (cmp))
# define sk_BY_DIR_HASH_new_null() SKM_sk_new_null(BY_DIR_HASH)
# define sk_BY_DIR_HASH_free(st) SKM_sk_free(BY_DIR_HASH, (st))
# define sk_BY_DIR_HASH_num(st) SKM_sk_num(BY_DIR_HASH, (st))
# define sk_BY_DIR_HASH_value(st, i) SKM_sk_value(BY_DIR_HASH, (st), (i))
# define sk_BY_DIR_HASH_set(st, i, val) SKM_sk_set(BY_DIR_HASH, (st), (i), (val))
# define sk_BY_DIR_HASH_zero(st) SKM_sk_zero(BY_DIR_HASH, (st))
# define sk_BY_DIR_HASH_push(st, val) SKM_sk_push(BY_DIR_HASH, (st), (val))
# define sk_BY_DIR_HASH_unshift(st, val) SKM_sk_unshift(BY_DIR_HASH, (st), (val))
# define sk_BY_DIR_HASH_find(st, val) SKM_sk_find(BY_DIR_HASH, (st), (val))
# define sk_BY_DIR_HASH_find_ex(st, val) SKM_sk_find_ex(BY_DIR_HASH, (st), (val))
# define sk_BY_DIR_HASH_delete(st, i) SKM_sk_delete(BY_DIR_HASH, (st), (i))
# define sk_BY_DIR_HASH_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_HASH, (st), (ptr))
# define sk_BY_DIR_HASH_insert(st, val, i) SKM_sk_insert(BY_DIR_HASH, (st), (val), (i))
# define sk_BY_DIR_HASH_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_HASH, (st), (cmp))
# define sk_BY_DIR_HASH_dup(st) SKM_sk_dup(BY_DIR_HASH, st)
# define sk_BY_DIR_HASH_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_HASH, (st), (free_func))
# define sk_BY_DIR_HASH_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(BY_DIR_HASH, (st), (copy_func), (free_func))
# define sk_BY_DIR_HASH_shift(st) SKM_sk_shift(BY_DIR_HASH, (st))
# define sk_BY_DIR_HASH_pop(st) SKM_sk_pop(BY_DIR_HASH, (st))
# define sk_BY_DIR_HASH_sort(st) SKM_sk_sort(BY_DIR_HASH, (st))
# define sk_BY_DIR_HASH_is_sorted(st) SKM_sk_is_sorted(BY_DIR_HASH, (st))
# define sk_CMS_CertificateChoices_new(cmp) SKM_sk_new(CMS_CertificateChoices, (cmp))
# define sk_CMS_CertificateChoices_new_null() SKM_sk_new_null(CMS_CertificateChoices)
# define sk_CMS_CertificateChoices_free(st) SKM_sk_free(CMS_CertificateChoices, (st))
# define sk_CMS_CertificateChoices_num(st) SKM_sk_num(CMS_CertificateChoices, (st))
# define sk_CMS_CertificateChoices_value(st, i) SKM_sk_value(CMS_CertificateChoices, (st), (i))
# define sk_CMS_CertificateChoices_set(st, i, val) SKM_sk_set(CMS_CertificateChoices, (st), (i), (val))
# define sk_CMS_CertificateChoices_zero(st) SKM_sk_zero(CMS_CertificateChoices, (st))
# define sk_CMS_CertificateChoices_push(st, val) SKM_sk_push(CMS_CertificateChoices, (st), (val))
# define sk_CMS_CertificateChoices_unshift(st, val) SKM_sk_unshift(CMS_CertificateChoices, (st), (val))
# define sk_CMS_CertificateChoices_find(st, val) SKM_sk_find(CMS_CertificateChoices, (st), (val))
# define sk_CMS_CertificateChoices_find_ex(st, val) SKM_sk_find_ex(CMS_CertificateChoices, (st), (val))
# define sk_CMS_CertificateChoices_delete(st, i) SKM_sk_delete(CMS_CertificateChoices, (st), (i))
# define sk_CMS_CertificateChoices_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_CertificateChoices, (st), (ptr))
# define sk_CMS_CertificateChoices_insert(st, val, i) SKM_sk_insert(CMS_CertificateChoices, (st), (val), (i))
# define sk_CMS_CertificateChoices_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_CertificateChoices, (st), (cmp))
# define sk_CMS_CertificateChoices_dup(st) SKM_sk_dup(CMS_CertificateChoices, st)
# define sk_CMS_CertificateChoices_pop_free(st, free_func) SKM_sk_pop_free(CMS_CertificateChoices, (st), (free_func))
# define sk_CMS_CertificateChoices_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CMS_CertificateChoices, (st), (copy_func), (free_func))
# define sk_CMS_CertificateChoices_shift(st) SKM_sk_shift(CMS_CertificateChoices, (st))
# define sk_CMS_CertificateChoices_pop(st) SKM_sk_pop(CMS_CertificateChoices, (st))
# define sk_CMS_CertificateChoices_sort(st) SKM_sk_sort(CMS_CertificateChoices, (st))
# define sk_CMS_CertificateChoices_is_sorted(st) SKM_sk_is_sorted(CMS_CertificateChoices, (st))
# define sk_CMS_RecipientEncryptedKey_new(cmp) SKM_sk_new(CMS_RecipientEncryptedKey, (cmp))
# define sk_CMS_RecipientEncryptedKey_new_null() SKM_sk_new_null(CMS_RecipientEncryptedKey)
# define sk_CMS_RecipientEncryptedKey_free(st) SKM_sk_free(CMS_RecipientEncryptedKey, (st))
# define sk_CMS_RecipientEncryptedKey_num(st) SKM_sk_num(CMS_RecipientEncryptedKey, (st))
# define sk_CMS_RecipientEncryptedKey_value(st, i) SKM_sk_value(CMS_RecipientEncryptedKey, (st), (i))
# define sk_CMS_RecipientEncryptedKey_set(st, i, val) SKM_sk_set(CMS_RecipientEncryptedKey, (st), (i), (val))
# define sk_CMS_RecipientEncryptedKey_zero(st) SKM_sk_zero(CMS_RecipientEncryptedKey, (st))
# define sk_CMS_RecipientEncryptedKey_push(st, val) SKM_sk_push(CMS_RecipientEncryptedKey, (st), (val))
# define sk_CMS_RecipientEncryptedKey_unshift(st, val) SKM_sk_unshift(CMS_RecipientEncryptedKey, (st), (val))
# define sk_CMS_RecipientEncryptedKey_find(st, val) SKM_sk_find(CMS_RecipientEncryptedKey, (st), (val))
# define sk_CMS_RecipientEncryptedKey_find_ex(st, val) SKM_sk_find_ex(CMS_RecipientEncryptedKey, (st), (val))
# define sk_CMS_RecipientEncryptedKey_delete(st, i) SKM_sk_delete(CMS_RecipientEncryptedKey, (st), (i))
# define sk_CMS_RecipientEncryptedKey_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RecipientEncryptedKey, (st), (ptr))
# define sk_CMS_RecipientEncryptedKey_insert(st, val, i) SKM_sk_insert(CMS_RecipientEncryptedKey, (st), (val), (i))
# define sk_CMS_RecipientEncryptedKey_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RecipientEncryptedKey, (st), (cmp))
# define sk_CMS_RecipientEncryptedKey_dup(st) SKM_sk_dup(CMS_RecipientEncryptedKey, st)
# define sk_CMS_RecipientEncryptedKey_pop_free(st, free_func) SKM_sk_pop_free(CMS_RecipientEncryptedKey, (st), (free_func))
# define sk_CMS_RecipientEncryptedKey_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CMS_RecipientEncryptedKey, (st), (copy_func), (free_func))
# define sk_CMS_RecipientEncryptedKey_shift(st) SKM_sk_shift(CMS_RecipientEncryptedKey, (st))
# define sk_CMS_RecipientEncryptedKey_pop(st) SKM_sk_pop(CMS_RecipientEncryptedKey, (st))
# define sk_CMS_RecipientEncryptedKey_sort(st) SKM_sk_sort(CMS_RecipientEncryptedKey, (st))
# define sk_CMS_RecipientEncryptedKey_is_sorted(st) SKM_sk_is_sorted(CMS_RecipientEncryptedKey, (st))
# define sk_CMS_RecipientInfo_new(cmp) SKM_sk_new(CMS_RecipientInfo, (cmp))
# define sk_CMS_RecipientInfo_new_null() SKM_sk_new_null(CMS_RecipientInfo)
# define sk_CMS_RecipientInfo_free(st) SKM_sk_free(CMS_RecipientInfo, (st))
# define sk_CMS_RecipientInfo_num(st) SKM_sk_num(CMS_RecipientInfo, (st))
# define sk_CMS_RecipientInfo_value(st, i) SKM_sk_value(CMS_RecipientInfo, (st), (i))
# define sk_CMS_RecipientInfo_set(st, i, val) SKM_sk_set(CMS_RecipientInfo, (st), (i), (val))
# define sk_CMS_RecipientInfo_zero(st) SKM_sk_zero(CMS_RecipientInfo, (st))
# define sk_CMS_RecipientInfo_push(st, val) SKM_sk_push(CMS_RecipientInfo, (st), (val))
# define sk_CMS_RecipientInfo_unshift(st, val) SKM_sk_unshift(CMS_RecipientInfo, (st), (val))
# define sk_CMS_RecipientInfo_find(st, val) SKM_sk_find(CMS_RecipientInfo, (st), (val))
# define sk_CMS_RecipientInfo_find_ex(st, val) SKM_sk_find_ex(CMS_RecipientInfo, (st), (val))
# define sk_CMS_RecipientInfo_delete(st, i) SKM_sk_delete(CMS_RecipientInfo, (st), (i))
# define sk_CMS_RecipientInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RecipientInfo, (st), (ptr))
# define sk_CMS_RecipientInfo_insert(st, val, i) SKM_sk_insert(CMS_RecipientInfo, (st), (val), (i))
# define sk_CMS_RecipientInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RecipientInfo, (st), (cmp))
# define sk_CMS_RecipientInfo_dup(st) SKM_sk_dup(CMS_RecipientInfo, st)
# define sk_CMS_RecipientInfo_pop_free(st, free_func) SKM_sk_pop_free(CMS_RecipientInfo, (st), (free_func))
# define sk_CMS_RecipientInfo_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CMS_RecipientInfo, (st), (copy_func), (free_func))
# define sk_CMS_RecipientInfo_shift(st) SKM_sk_shift(CMS_RecipientInfo, (st))
# define sk_CMS_RecipientInfo_pop(st) SKM_sk_pop(CMS_RecipientInfo, (st))
# define sk_CMS_RecipientInfo_sort(st) SKM_sk_sort(CMS_RecipientInfo, (st))
# define sk_CMS_RecipientInfo_is_sorted(st) SKM_sk_is_sorted(CMS_RecipientInfo, (st))
# define sk_CMS_RevocationInfoChoice_new(cmp) SKM_sk_new(CMS_RevocationInfoChoice, (cmp))
# define sk_CMS_RevocationInfoChoice_new_null() SKM_sk_new_null(CMS_RevocationInfoChoice)
# define sk_CMS_RevocationInfoChoice_free(st) SKM_sk_free(CMS_RevocationInfoChoice, (st))
# define sk_CMS_RevocationInfoChoice_num(st) SKM_sk_num(CMS_RevocationInfoChoice, (st))
# define sk_CMS_RevocationInfoChoice_value(st, i) SKM_sk_value(CMS_RevocationInfoChoice, (st), (i))
# define sk_CMS_RevocationInfoChoice_set(st, i, val) SKM_sk_set(CMS_RevocationInfoChoice, (st), (i), (val))
# define sk_CMS_RevocationInfoChoice_zero(st) SKM_sk_zero(CMS_RevocationInfoChoice, (st))
# define sk_CMS_RevocationInfoChoice_push(st, val) SKM_sk_push(CMS_RevocationInfoChoice, (st), (val))
# define sk_CMS_RevocationInfoChoice_unshift(st, val) SKM_sk_unshift(CMS_RevocationInfoChoice, (st), (val))
# define sk_CMS_RevocationInfoChoice_find(st, val) SKM_sk_find(CMS_RevocationInfoChoice, (st), (val))
# define sk_CMS_RevocationInfoChoice_find_ex(st, val) SKM_sk_find_ex(CMS_RevocationInfoChoice, (st), (val))
# define sk_CMS_RevocationInfoChoice_delete(st, i) SKM_sk_delete(CMS_RevocationInfoChoice, (st), (i))
# define sk_CMS_RevocationInfoChoice_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RevocationInfoChoice, (st), (ptr))
# define sk_CMS_RevocationInfoChoice_insert(st, val, i) SKM_sk_insert(CMS_RevocationInfoChoice, (st), (val), (i))
# define sk_CMS_RevocationInfoChoice_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RevocationInfoChoice, (st), (cmp))
# define sk_CMS_RevocationInfoChoice_dup(st) SKM_sk_dup(CMS_RevocationInfoChoice, st)
# define sk_CMS_RevocationInfoChoice_pop_free(st, free_func) SKM_sk_pop_free(CMS_RevocationInfoChoice, (st), (free_func))
# define sk_CMS_RevocationInfoChoice_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CMS_RevocationInfoChoice, (st), (copy_func), (free_func))
# define sk_CMS_RevocationInfoChoice_shift(st) SKM_sk_shift(CMS_RevocationInfoChoice, (st))
# define sk_CMS_RevocationInfoChoice_pop(st) SKM_sk_pop(CMS_RevocationInfoChoice, (st))
# define sk_CMS_RevocationInfoChoice_sort(st) SKM_sk_sort(CMS_RevocationInfoChoice, (st))
# define sk_CMS_RevocationInfoChoice_is_sorted(st) SKM_sk_is_sorted(CMS_RevocationInfoChoice, (st))
# define sk_CMS_SignerInfo_new(cmp) SKM_sk_new(CMS_SignerInfo, (cmp))
# define sk_CMS_SignerInfo_new_null() SKM_sk_new_null(CMS_SignerInfo)
# define sk_CMS_SignerInfo_free(st) SKM_sk_free(CMS_SignerInfo, (st))
# define sk_CMS_SignerInfo_num(st) SKM_sk_num(CMS_SignerInfo, (st))
# define sk_CMS_SignerInfo_value(st, i) SKM_sk_value(CMS_SignerInfo, (st), (i))
# define sk_CMS_SignerInfo_set(st, i, val) SKM_sk_set(CMS_SignerInfo, (st), (i), (val))
# define sk_CMS_SignerInfo_zero(st) SKM_sk_zero(CMS_SignerInfo, (st))
# define sk_CMS_SignerInfo_push(st, val) SKM_sk_push(CMS_SignerInfo, (st), (val))
# define sk_CMS_SignerInfo_unshift(st, val) SKM_sk_unshift(CMS_SignerInfo, (st), (val))
# define sk_CMS_SignerInfo_find(st, val) SKM_sk_find(CMS_SignerInfo, (st), (val))
# define sk_CMS_SignerInfo_find_ex(st, val) SKM_sk_find_ex(CMS_SignerInfo, (st), (val))
# define sk_CMS_SignerInfo_delete(st, i) SKM_sk_delete(CMS_SignerInfo, (st), (i))
# define sk_CMS_SignerInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_SignerInfo, (st), (ptr))
# define sk_CMS_SignerInfo_insert(st, val, i) SKM_sk_insert(CMS_SignerInfo, (st), (val), (i))
# define sk_CMS_SignerInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_SignerInfo, (st), (cmp))
# define sk_CMS_SignerInfo_dup(st) SKM_sk_dup(CMS_SignerInfo, st)
# define sk_CMS_SignerInfo_pop_free(st, free_func) SKM_sk_pop_free(CMS_SignerInfo, (st), (free_func))
# define sk_CMS_SignerInfo_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CMS_SignerInfo, (st), (copy_func), (free_func))
# define sk_CMS_SignerInfo_shift(st) SKM_sk_shift(CMS_SignerInfo, (st))
# define sk_CMS_SignerInfo_pop(st) SKM_sk_pop(CMS_SignerInfo, (st))
# define sk_CMS_SignerInfo_sort(st) SKM_sk_sort(CMS_SignerInfo, (st))
# define sk_CMS_SignerInfo_is_sorted(st) SKM_sk_is_sorted(CMS_SignerInfo, (st))
# define sk_CONF_IMODULE_new(cmp) SKM_sk_new(CONF_IMODULE, (cmp))
# define sk_CONF_IMODULE_new_null() SKM_sk_new_null(CONF_IMODULE)
# define sk_CONF_IMODULE_free(st) SKM_sk_free(CONF_IMODULE, (st))
# define sk_CONF_IMODULE_num(st) SKM_sk_num(CONF_IMODULE, (st))
# define sk_CONF_IMODULE_value(st, i) SKM_sk_value(CONF_IMODULE, (st), (i))
# define sk_CONF_IMODULE_set(st, i, val) SKM_sk_set(CONF_IMODULE, (st), (i), (val))
# define sk_CONF_IMODULE_zero(st) SKM_sk_zero(CONF_IMODULE, (st))
# define sk_CONF_IMODULE_push(st, val) SKM_sk_push(CONF_IMODULE, (st), (val))
# define sk_CONF_IMODULE_unshift(st, val) SKM_sk_unshift(CONF_IMODULE, (st), (val))
# define sk_CONF_IMODULE_find(st, val) SKM_sk_find(CONF_IMODULE, (st), (val))
# define sk_CONF_IMODULE_find_ex(st, val) SKM_sk_find_ex(CONF_IMODULE, (st), (val))
# define sk_CONF_IMODULE_delete(st, i) SKM_sk_delete(CONF_IMODULE, (st), (i))
# define sk_CONF_IMODULE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_IMODULE, (st), (ptr))
# define sk_CONF_IMODULE_insert(st, val, i) SKM_sk_insert(CONF_IMODULE, (st), (val), (i))
# define sk_CONF_IMODULE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_IMODULE, (st), (cmp))
# define sk_CONF_IMODULE_dup(st) SKM_sk_dup(CONF_IMODULE, st)
# define sk_CONF_IMODULE_pop_free(st, free_func) SKM_sk_pop_free(CONF_IMODULE, (st), (free_func))
# define sk_CONF_IMODULE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CONF_IMODULE, (st), (copy_func), (free_func))
# define sk_CONF_IMODULE_shift(st) SKM_sk_shift(CONF_IMODULE, (st))
# define sk_CONF_IMODULE_pop(st) SKM_sk_pop(CONF_IMODULE, (st))
# define sk_CONF_IMODULE_sort(st) SKM_sk_sort(CONF_IMODULE, (st))
# define sk_CONF_IMODULE_is_sorted(st) SKM_sk_is_sorted(CONF_IMODULE, (st))
# define sk_CONF_MODULE_new(cmp) SKM_sk_new(CONF_MODULE, (cmp))
# define sk_CONF_MODULE_new_null() SKM_sk_new_null(CONF_MODULE)
# define sk_CONF_MODULE_free(st) SKM_sk_free(CONF_MODULE, (st))
# define sk_CONF_MODULE_num(st) SKM_sk_num(CONF_MODULE, (st))
# define sk_CONF_MODULE_value(st, i) SKM_sk_value(CONF_MODULE, (st), (i))
# define sk_CONF_MODULE_set(st, i, val) SKM_sk_set(CONF_MODULE, (st), (i), (val))
# define sk_CONF_MODULE_zero(st) SKM_sk_zero(CONF_MODULE, (st))
# define sk_CONF_MODULE_push(st, val) SKM_sk_push(CONF_MODULE, (st), (val))
# define sk_CONF_MODULE_unshift(st, val) SKM_sk_unshift(CONF_MODULE, (st), (val))
# define sk_CONF_MODULE_find(st, val) SKM_sk_find(CONF_MODULE, (st), (val))
# define sk_CONF_MODULE_find_ex(st, val) SKM_sk_find_ex(CONF_MODULE, (st), (val))
# define sk_CONF_MODULE_delete(st, i) SKM_sk_delete(CONF_MODULE, (st), (i))
# define sk_CONF_MODULE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_MODULE, (st), (ptr))
# define sk_CONF_MODULE_insert(st, val, i) SKM_sk_insert(CONF_MODULE, (st), (val), (i))
# define sk_CONF_MODULE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_MODULE, (st), (cmp))
# define sk_CONF_MODULE_dup(st) SKM_sk_dup(CONF_MODULE, st)
# define sk_CONF_MODULE_pop_free(st, free_func) SKM_sk_pop_free(CONF_MODULE, (st), (free_func))
# define sk_CONF_MODULE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CONF_MODULE, (st), (copy_func), (free_func))
# define sk_CONF_MODULE_shift(st) SKM_sk_shift(CONF_MODULE, (st))
# define sk_CONF_MODULE_pop(st) SKM_sk_pop(CONF_MODULE, (st))
# define sk_CONF_MODULE_sort(st) SKM_sk_sort(CONF_MODULE, (st))
# define sk_CONF_MODULE_is_sorted(st) SKM_sk_is_sorted(CONF_MODULE, (st))
# define sk_CONF_VALUE_new(cmp) SKM_sk_new(CONF_VALUE, (cmp))
# define sk_CONF_VALUE_new_null() SKM_sk_new_null(CONF_VALUE)
# define sk_CONF_VALUE_free(st) SKM_sk_free(CONF_VALUE, (st))
# define sk_CONF_VALUE_num(st) SKM_sk_num(CONF_VALUE, (st))
# define sk_CONF_VALUE_value(st, i) SKM_sk_value(CONF_VALUE, (st), (i))
# define sk_CONF_VALUE_set(st, i, val) SKM_sk_set(CONF_VALUE, (st), (i), (val))
# define sk_CONF_VALUE_zero(st) SKM_sk_zero(CONF_VALUE, (st))
# define sk_CONF_VALUE_push(st, val) SKM_sk_push(CONF_VALUE, (st), (val))
# define sk_CONF_VALUE_unshift(st, val) SKM_sk_unshift(CONF_VALUE, (st), (val))
# define sk_CONF_VALUE_find(st, val) SKM_sk_find(CONF_VALUE, (st), (val))
# define sk_CONF_VALUE_find_ex(st, val) SKM_sk_find_ex(CONF_VALUE, (st), (val))
# define sk_CONF_VALUE_delete(st, i) SKM_sk_delete(CONF_VALUE, (st), (i))
# define sk_CONF_VALUE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_VALUE, (st), (ptr))
# define sk_CONF_VALUE_insert(st, val, i) SKM_sk_insert(CONF_VALUE, (st), (val), (i))
# define sk_CONF_VALUE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_VALUE, (st), (cmp))
# define sk_CONF_VALUE_dup(st) SKM_sk_dup(CONF_VALUE, st)
# define sk_CONF_VALUE_pop_free(st, free_func) SKM_sk_pop_free(CONF_VALUE, (st), (free_func))
# define sk_CONF_VALUE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CONF_VALUE, (st), (copy_func), (free_func))
# define sk_CONF_VALUE_shift(st) SKM_sk_shift(CONF_VALUE, (st))
# define sk_CONF_VALUE_pop(st) SKM_sk_pop(CONF_VALUE, (st))
# define sk_CONF_VALUE_sort(st) SKM_sk_sort(CONF_VALUE, (st))
# define sk_CONF_VALUE_is_sorted(st) SKM_sk_is_sorted(CONF_VALUE, (st))
# define sk_CRYPTO_EX_DATA_FUNCS_new(cmp) SKM_sk_new(CRYPTO_EX_DATA_FUNCS, (cmp))
# define sk_CRYPTO_EX_DATA_FUNCS_new_null() SKM_sk_new_null(CRYPTO_EX_DATA_FUNCS)
# define sk_CRYPTO_EX_DATA_FUNCS_free(st) SKM_sk_free(CRYPTO_EX_DATA_FUNCS, (st))
# define sk_CRYPTO_EX_DATA_FUNCS_num(st) SKM_sk_num(CRYPTO_EX_DATA_FUNCS, (st))
# define sk_CRYPTO_EX_DATA_FUNCS_value(st, i) SKM_sk_value(CRYPTO_EX_DATA_FUNCS, (st), (i))
# define sk_CRYPTO_EX_DATA_FUNCS_set(st, i, val) SKM_sk_set(CRYPTO_EX_DATA_FUNCS, (st), (i), (val))
# define sk_CRYPTO_EX_DATA_FUNCS_zero(st) SKM_sk_zero(CRYPTO_EX_DATA_FUNCS, (st))
# define sk_CRYPTO_EX_DATA_FUNCS_push(st, val) SKM_sk_push(CRYPTO_EX_DATA_FUNCS, (st), (val))
# define sk_CRYPTO_EX_DATA_FUNCS_unshift(st, val) SKM_sk_unshift(CRYPTO_EX_DATA_FUNCS, (st), (val))
# define sk_CRYPTO_EX_DATA_FUNCS_find(st, val) SKM_sk_find(CRYPTO_EX_DATA_FUNCS, (st), (val))
# define sk_CRYPTO_EX_DATA_FUNCS_find_ex(st, val) SKM_sk_find_ex(CRYPTO_EX_DATA_FUNCS, (st), (val))
# define sk_CRYPTO_EX_DATA_FUNCS_delete(st, i) SKM_sk_delete(CRYPTO_EX_DATA_FUNCS, (st), (i))
# define sk_CRYPTO_EX_DATA_FUNCS_delete_ptr(st, ptr) SKM_sk_delete_ptr(CRYPTO_EX_DATA_FUNCS, (st), (ptr))
# define sk_CRYPTO_EX_DATA_FUNCS_insert(st, val, i) SKM_sk_insert(CRYPTO_EX_DATA_FUNCS, (st), (val), (i))
# define sk_CRYPTO_EX_DATA_FUNCS_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CRYPTO_EX_DATA_FUNCS, (st), (cmp))
# define sk_CRYPTO_EX_DATA_FUNCS_dup(st) SKM_sk_dup(CRYPTO_EX_DATA_FUNCS, st)
# define sk_CRYPTO_EX_DATA_FUNCS_pop_free(st, free_func) SKM_sk_pop_free(CRYPTO_EX_DATA_FUNCS, (st), (free_func))
# define sk_CRYPTO_EX_DATA_FUNCS_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CRYPTO_EX_DATA_FUNCS, (st), (copy_func), (free_func))
# define sk_CRYPTO_EX_DATA_FUNCS_shift(st) SKM_sk_shift(CRYPTO_EX_DATA_FUNCS, (st))
# define sk_CRYPTO_EX_DATA_FUNCS_pop(st) SKM_sk_pop(CRYPTO_EX_DATA_FUNCS, (st))
# define sk_CRYPTO_EX_DATA_FUNCS_sort(st) SKM_sk_sort(CRYPTO_EX_DATA_FUNCS, (st))
# define sk_CRYPTO_EX_DATA_FUNCS_is_sorted(st) SKM_sk_is_sorted(CRYPTO_EX_DATA_FUNCS, (st))
# define sk_CRYPTO_dynlock_new(cmp) SKM_sk_new(CRYPTO_dynlock, (cmp))
# define sk_CRYPTO_dynlock_new_null() SKM_sk_new_null(CRYPTO_dynlock)
# define sk_CRYPTO_dynlock_free(st) SKM_sk_free(CRYPTO_dynlock, (st))
# define sk_CRYPTO_dynlock_num(st) SKM_sk_num(CRYPTO_dynlock, (st))
# define sk_CRYPTO_dynlock_value(st, i) SKM_sk_value(CRYPTO_dynlock, (st), (i))
# define sk_CRYPTO_dynlock_set(st, i, val) SKM_sk_set(CRYPTO_dynlock, (st), (i), (val))
# define sk_CRYPTO_dynlock_zero(st) SKM_sk_zero(CRYPTO_dynlock, (st))
# define sk_CRYPTO_dynlock_push(st, val) SKM_sk_push(CRYPTO_dynlock, (st), (val))
# define sk_CRYPTO_dynlock_unshift(st, val) SKM_sk_unshift(CRYPTO_dynlock, (st), (val))
# define sk_CRYPTO_dynlock_find(st, val) SKM_sk_find(CRYPTO_dynlock, (st), (val))
# define sk_CRYPTO_dynlock_find_ex(st, val) SKM_sk_find_ex(CRYPTO_dynlock, (st), (val))
# define sk_CRYPTO_dynlock_delete(st, i) SKM_sk_delete(CRYPTO_dynlock, (st), (i))
# define sk_CRYPTO_dynlock_delete_ptr(st, ptr) SKM_sk_delete_ptr(CRYPTO_dynlock, (st), (ptr))
# define sk_CRYPTO_dynlock_insert(st, val, i) SKM_sk_insert(CRYPTO_dynlock, (st), (val), (i))
# define sk_CRYPTO_dynlock_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CRYPTO_dynlock, (st), (cmp))
# define sk_CRYPTO_dynlock_dup(st) SKM_sk_dup(CRYPTO_dynlock, st)
# define sk_CRYPTO_dynlock_pop_free(st, free_func) SKM_sk_pop_free(CRYPTO_dynlock, (st), (free_func))
# define sk_CRYPTO_dynlock_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CRYPTO_dynlock, (st), (copy_func), (free_func))
# define sk_CRYPTO_dynlock_shift(st) SKM_sk_shift(CRYPTO_dynlock, (st))
# define sk_CRYPTO_dynlock_pop(st) SKM_sk_pop(CRYPTO_dynlock, (st))
# define sk_CRYPTO_dynlock_sort(st) SKM_sk_sort(CRYPTO_dynlock, (st))
# define sk_CRYPTO_dynlock_is_sorted(st) SKM_sk_is_sorted(CRYPTO_dynlock, (st))
# define sk_DIST_POINT_new(cmp) SKM_sk_new(DIST_POINT, (cmp))
# define sk_DIST_POINT_new_null() SKM_sk_new_null(DIST_POINT)
# define sk_DIST_POINT_free(st) SKM_sk_free(DIST_POINT, (st))
# define sk_DIST_POINT_num(st) SKM_sk_num(DIST_POINT, (st))
# define sk_DIST_POINT_value(st, i) SKM_sk_value(DIST_POINT, (st), (i))
# define sk_DIST_POINT_set(st, i, val) SKM_sk_set(DIST_POINT, (st), (i), (val))
# define sk_DIST_POINT_zero(st) SKM_sk_zero(DIST_POINT, (st))
# define sk_DIST_POINT_push(st, val) SKM_sk_push(DIST_POINT, (st), (val))
# define sk_DIST_POINT_unshift(st, val) SKM_sk_unshift(DIST_POINT, (st), (val))
# define sk_DIST_POINT_find(st, val) SKM_sk_find(DIST_POINT, (st), (val))
# define sk_DIST_POINT_find_ex(st, val) SKM_sk_find_ex(DIST_POINT, (st), (val))
# define sk_DIST_POINT_delete(st, i) SKM_sk_delete(DIST_POINT, (st), (i))
# define sk_DIST_POINT_delete_ptr(st, ptr) SKM_sk_delete_ptr(DIST_POINT, (st), (ptr))
# define sk_DIST_POINT_insert(st, val, i) SKM_sk_insert(DIST_POINT, (st), (val), (i))
# define sk_DIST_POINT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(DIST_POINT, (st), (cmp))
# define sk_DIST_POINT_dup(st) SKM_sk_dup(DIST_POINT, st)
# define sk_DIST_POINT_pop_free(st, free_func) SKM_sk_pop_free(DIST_POINT, (st), (free_func))
# define sk_DIST_POINT_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(DIST_POINT, (st), (copy_func), (free_func))
# define sk_DIST_POINT_shift(st) SKM_sk_shift(DIST_POINT, (st))
# define sk_DIST_POINT_pop(st) SKM_sk_pop(DIST_POINT, (st))
# define sk_DIST_POINT_sort(st) SKM_sk_sort(DIST_POINT, (st))
# define sk_DIST_POINT_is_sorted(st) SKM_sk_is_sorted(DIST_POINT, (st))
# define sk_ENGINE_new(cmp) SKM_sk_new(ENGINE, (cmp))
# define sk_ENGINE_new_null() SKM_sk_new_null(ENGINE)
# define sk_ENGINE_free(st) SKM_sk_free(ENGINE, (st))
# define sk_ENGINE_num(st) SKM_sk_num(ENGINE, (st))
# define sk_ENGINE_value(st, i) SKM_sk_value(ENGINE, (st), (i))
# define sk_ENGINE_set(st, i, val) SKM_sk_set(ENGINE, (st), (i), (val))
# define sk_ENGINE_zero(st) SKM_sk_zero(ENGINE, (st))
# define sk_ENGINE_push(st, val) SKM_sk_push(ENGINE, (st), (val))
# define sk_ENGINE_unshift(st, val) SKM_sk_unshift(ENGINE, (st), (val))
# define sk_ENGINE_find(st, val) SKM_sk_find(ENGINE, (st), (val))
# define sk_ENGINE_find_ex(st, val) SKM_sk_find_ex(ENGINE, (st), (val))
# define sk_ENGINE_delete(st, i) SKM_sk_delete(ENGINE, (st), (i))
# define sk_ENGINE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ENGINE, (st), (ptr))
# define sk_ENGINE_insert(st, val, i) SKM_sk_insert(ENGINE, (st), (val), (i))
# define sk_ENGINE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ENGINE, (st), (cmp))
# define sk_ENGINE_dup(st) SKM_sk_dup(ENGINE, st)
# define sk_ENGINE_pop_free(st, free_func) SKM_sk_pop_free(ENGINE, (st), (free_func))
# define sk_ENGINE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ENGINE, (st), (copy_func), (free_func))
# define sk_ENGINE_shift(st) SKM_sk_shift(ENGINE, (st))
# define sk_ENGINE_pop(st) SKM_sk_pop(ENGINE, (st))
# define sk_ENGINE_sort(st) SKM_sk_sort(ENGINE, (st))
# define sk_ENGINE_is_sorted(st) SKM_sk_is_sorted(ENGINE, (st))
# define sk_ENGINE_CLEANUP_ITEM_new(cmp) SKM_sk_new(ENGINE_CLEANUP_ITEM, (cmp))
# define sk_ENGINE_CLEANUP_ITEM_new_null() SKM_sk_new_null(ENGINE_CLEANUP_ITEM)
# define sk_ENGINE_CLEANUP_ITEM_free(st) SKM_sk_free(ENGINE_CLEANUP_ITEM, (st))
# define sk_ENGINE_CLEANUP_ITEM_num(st) SKM_sk_num(ENGINE_CLEANUP_ITEM, (st))
# define sk_ENGINE_CLEANUP_ITEM_value(st, i) SKM_sk_value(ENGINE_CLEANUP_ITEM, (st), (i))
# define sk_ENGINE_CLEANUP_ITEM_set(st, i, val) SKM_sk_set(ENGINE_CLEANUP_ITEM, (st), (i), (val))
# define sk_ENGINE_CLEANUP_ITEM_zero(st) SKM_sk_zero(ENGINE_CLEANUP_ITEM, (st))
# define sk_ENGINE_CLEANUP_ITEM_push(st, val) SKM_sk_push(ENGINE_CLEANUP_ITEM, (st), (val))
# define sk_ENGINE_CLEANUP_ITEM_unshift(st, val) SKM_sk_unshift(ENGINE_CLEANUP_ITEM, (st), (val))
# define sk_ENGINE_CLEANUP_ITEM_find(st, val) SKM_sk_find(ENGINE_CLEANUP_ITEM, (st), (val))
# define sk_ENGINE_CLEANUP_ITEM_find_ex(st, val) SKM_sk_find_ex(ENGINE_CLEANUP_ITEM, (st), (val))
# define sk_ENGINE_CLEANUP_ITEM_delete(st, i) SKM_sk_delete(ENGINE_CLEANUP_ITEM, (st), (i))
# define sk_ENGINE_CLEANUP_ITEM_delete_ptr(st, ptr) SKM_sk_delete_ptr(ENGINE_CLEANUP_ITEM, (st), (ptr))
# define sk_ENGINE_CLEANUP_ITEM_insert(st, val, i) SKM_sk_insert(ENGINE_CLEANUP_ITEM, (st), (val), (i))
# define sk_ENGINE_CLEANUP_ITEM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ENGINE_CLEANUP_ITEM, (st), (cmp))
# define sk_ENGINE_CLEANUP_ITEM_dup(st) SKM_sk_dup(ENGINE_CLEANUP_ITEM, st)
# define sk_ENGINE_CLEANUP_ITEM_pop_free(st, free_func) SKM_sk_pop_free(ENGINE_CLEANUP_ITEM, (st), (free_func))
# define sk_ENGINE_CLEANUP_ITEM_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ENGINE_CLEANUP_ITEM, (st), (copy_func), (free_func))
# define sk_ENGINE_CLEANUP_ITEM_shift(st) SKM_sk_shift(ENGINE_CLEANUP_ITEM, (st))
# define sk_ENGINE_CLEANUP_ITEM_pop(st) SKM_sk_pop(ENGINE_CLEANUP_ITEM, (st))
# define sk_ENGINE_CLEANUP_ITEM_sort(st) SKM_sk_sort(ENGINE_CLEANUP_ITEM, (st))
# define sk_ENGINE_CLEANUP_ITEM_is_sorted(st) SKM_sk_is_sorted(ENGINE_CLEANUP_ITEM, (st))
# define sk_ESS_CERT_ID_new(cmp) SKM_sk_new(ESS_CERT_ID, (cmp))
# define sk_ESS_CERT_ID_new_null() SKM_sk_new_null(ESS_CERT_ID)
# define sk_ESS_CERT_ID_free(st) SKM_sk_free(ESS_CERT_ID, (st))
# define sk_ESS_CERT_ID_num(st) SKM_sk_num(ESS_CERT_ID, (st))
# define sk_ESS_CERT_ID_value(st, i) SKM_sk_value(ESS_CERT_ID, (st), (i))
# define sk_ESS_CERT_ID_set(st, i, val) SKM_sk_set(ESS_CERT_ID, (st), (i), (val))
# define sk_ESS_CERT_ID_zero(st) SKM_sk_zero(ESS_CERT_ID, (st))
# define sk_ESS_CERT_ID_push(st, val) SKM_sk_push(ESS_CERT_ID, (st), (val))
# define sk_ESS_CERT_ID_unshift(st, val) SKM_sk_unshift(ESS_CERT_ID, (st), (val))
# define sk_ESS_CERT_ID_find(st, val) SKM_sk_find(ESS_CERT_ID, (st), (val))
# define sk_ESS_CERT_ID_find_ex(st, val) SKM_sk_find_ex(ESS_CERT_ID, (st), (val))
# define sk_ESS_CERT_ID_delete(st, i) SKM_sk_delete(ESS_CERT_ID, (st), (i))
# define sk_ESS_CERT_ID_delete_ptr(st, ptr) SKM_sk_delete_ptr(ESS_CERT_ID, (st), (ptr))
# define sk_ESS_CERT_ID_insert(st, val, i) SKM_sk_insert(ESS_CERT_ID, (st), (val), (i))
# define sk_ESS_CERT_ID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ESS_CERT_ID, (st), (cmp))
# define sk_ESS_CERT_ID_dup(st) SKM_sk_dup(ESS_CERT_ID, st)
# define sk_ESS_CERT_ID_pop_free(st, free_func) SKM_sk_pop_free(ESS_CERT_ID, (st), (free_func))
# define sk_ESS_CERT_ID_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ESS_CERT_ID, (st), (copy_func), (free_func))
# define sk_ESS_CERT_ID_shift(st) SKM_sk_shift(ESS_CERT_ID, (st))
# define sk_ESS_CERT_ID_pop(st) SKM_sk_pop(ESS_CERT_ID, (st))
# define sk_ESS_CERT_ID_sort(st) SKM_sk_sort(ESS_CERT_ID, (st))
# define sk_ESS_CERT_ID_is_sorted(st) SKM_sk_is_sorted(ESS_CERT_ID, (st))
# define sk_EVP_MD_new(cmp) SKM_sk_new(EVP_MD, (cmp))
# define sk_EVP_MD_new_null() SKM_sk_new_null(EVP_MD)
# define sk_EVP_MD_free(st) SKM_sk_free(EVP_MD, (st))
# define sk_EVP_MD_num(st) SKM_sk_num(EVP_MD, (st))
# define sk_EVP_MD_value(st, i) SKM_sk_value(EVP_MD, (st), (i))
# define sk_EVP_MD_set(st, i, val) SKM_sk_set(EVP_MD, (st), (i), (val))
# define sk_EVP_MD_zero(st) SKM_sk_zero(EVP_MD, (st))
# define sk_EVP_MD_push(st, val) SKM_sk_push(EVP_MD, (st), (val))
# define sk_EVP_MD_unshift(st, val) SKM_sk_unshift(EVP_MD, (st), (val))
# define sk_EVP_MD_find(st, val) SKM_sk_find(EVP_MD, (st), (val))
# define sk_EVP_MD_find_ex(st, val) SKM_sk_find_ex(EVP_MD, (st), (val))
# define sk_EVP_MD_delete(st, i) SKM_sk_delete(EVP_MD, (st), (i))
# define sk_EVP_MD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_MD, (st), (ptr))
# define sk_EVP_MD_insert(st, val, i) SKM_sk_insert(EVP_MD, (st), (val), (i))
# define sk_EVP_MD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_MD, (st), (cmp))
# define sk_EVP_MD_dup(st) SKM_sk_dup(EVP_MD, st)
# define sk_EVP_MD_pop_free(st, free_func) SKM_sk_pop_free(EVP_MD, (st), (free_func))
# define sk_EVP_MD_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(EVP_MD, (st), (copy_func), (free_func))
# define sk_EVP_MD_shift(st) SKM_sk_shift(EVP_MD, (st))
# define sk_EVP_MD_pop(st) SKM_sk_pop(EVP_MD, (st))
# define sk_EVP_MD_sort(st) SKM_sk_sort(EVP_MD, (st))
# define sk_EVP_MD_is_sorted(st) SKM_sk_is_sorted(EVP_MD, (st))
# define sk_EVP_PBE_CTL_new(cmp) SKM_sk_new(EVP_PBE_CTL, (cmp))
# define sk_EVP_PBE_CTL_new_null() SKM_sk_new_null(EVP_PBE_CTL)
# define sk_EVP_PBE_CTL_free(st) SKM_sk_free(EVP_PBE_CTL, (st))
# define sk_EVP_PBE_CTL_num(st) SKM_sk_num(EVP_PBE_CTL, (st))
# define sk_EVP_PBE_CTL_value(st, i) SKM_sk_value(EVP_PBE_CTL, (st), (i))
# define sk_EVP_PBE_CTL_set(st, i, val) SKM_sk_set(EVP_PBE_CTL, (st), (i), (val))
# define sk_EVP_PBE_CTL_zero(st) SKM_sk_zero(EVP_PBE_CTL, (st))
# define sk_EVP_PBE_CTL_push(st, val) SKM_sk_push(EVP_PBE_CTL, (st), (val))
# define sk_EVP_PBE_CTL_unshift(st, val) SKM_sk_unshift(EVP_PBE_CTL, (st), (val))
# define sk_EVP_PBE_CTL_find(st, val) SKM_sk_find(EVP_PBE_CTL, (st), (val))
# define sk_EVP_PBE_CTL_find_ex(st, val) SKM_sk_find_ex(EVP_PBE_CTL, (st), (val))
# define sk_EVP_PBE_CTL_delete(st, i) SKM_sk_delete(EVP_PBE_CTL, (st), (i))
# define sk_EVP_PBE_CTL_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PBE_CTL, (st), (ptr))
# define sk_EVP_PBE_CTL_insert(st, val, i) SKM_sk_insert(EVP_PBE_CTL, (st), (val), (i))
# define sk_EVP_PBE_CTL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PBE_CTL, (st), (cmp))
# define sk_EVP_PBE_CTL_dup(st) SKM_sk_dup(EVP_PBE_CTL, st)
# define sk_EVP_PBE_CTL_pop_free(st, free_func) SKM_sk_pop_free(EVP_PBE_CTL, (st), (free_func))
# define sk_EVP_PBE_CTL_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(EVP_PBE_CTL, (st), (copy_func), (free_func))
# define sk_EVP_PBE_CTL_shift(st) SKM_sk_shift(EVP_PBE_CTL, (st))
# define sk_EVP_PBE_CTL_pop(st) SKM_sk_pop(EVP_PBE_CTL, (st))
# define sk_EVP_PBE_CTL_sort(st) SKM_sk_sort(EVP_PBE_CTL, (st))
# define sk_EVP_PBE_CTL_is_sorted(st) SKM_sk_is_sorted(EVP_PBE_CTL, (st))
# define sk_EVP_PKEY_ASN1_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_ASN1_METHOD, (cmp))
# define sk_EVP_PKEY_ASN1_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_ASN1_METHOD)
# define sk_EVP_PKEY_ASN1_METHOD_free(st) SKM_sk_free(EVP_PKEY_ASN1_METHOD, (st))
# define sk_EVP_PKEY_ASN1_METHOD_num(st) SKM_sk_num(EVP_PKEY_ASN1_METHOD, (st))
# define sk_EVP_PKEY_ASN1_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_ASN1_METHOD, (st), (i))
# define sk_EVP_PKEY_ASN1_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_ASN1_METHOD, (st), (i), (val))
# define sk_EVP_PKEY_ASN1_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_ASN1_METHOD, (st))
# define sk_EVP_PKEY_ASN1_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_ASN1_METHOD, (st), (val))
# define sk_EVP_PKEY_ASN1_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_ASN1_METHOD, (st), (val))
# define sk_EVP_PKEY_ASN1_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_ASN1_METHOD, (st), (val))
# define sk_EVP_PKEY_ASN1_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_ASN1_METHOD, (st), (val))
# define sk_EVP_PKEY_ASN1_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_ASN1_METHOD, (st), (i))
# define sk_EVP_PKEY_ASN1_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_ASN1_METHOD, (st), (ptr))
# define sk_EVP_PKEY_ASN1_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_ASN1_METHOD, (st), (val), (i))
# define sk_EVP_PKEY_ASN1_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_ASN1_METHOD, (st), (cmp))
# define sk_EVP_PKEY_ASN1_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_ASN1_METHOD, st)
# define sk_EVP_PKEY_ASN1_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_ASN1_METHOD, (st), (free_func))
# define sk_EVP_PKEY_ASN1_METHOD_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(EVP_PKEY_ASN1_METHOD, (st), (copy_func), (free_func))
# define sk_EVP_PKEY_ASN1_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_ASN1_METHOD, (st))
# define sk_EVP_PKEY_ASN1_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_ASN1_METHOD, (st))
# define sk_EVP_PKEY_ASN1_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_ASN1_METHOD, (st))
# define sk_EVP_PKEY_ASN1_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_ASN1_METHOD, (st))
# define sk_EVP_PKEY_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_METHOD, (cmp))
# define sk_EVP_PKEY_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_METHOD)
# define sk_EVP_PKEY_METHOD_free(st) SKM_sk_free(EVP_PKEY_METHOD, (st))
# define sk_EVP_PKEY_METHOD_num(st) SKM_sk_num(EVP_PKEY_METHOD, (st))
# define sk_EVP_PKEY_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_METHOD, (st), (i))
# define sk_EVP_PKEY_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_METHOD, (st), (i), (val))
# define sk_EVP_PKEY_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_METHOD, (st))
# define sk_EVP_PKEY_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_METHOD, (st), (val))
# define sk_EVP_PKEY_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_METHOD, (st), (val))
# define sk_EVP_PKEY_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_METHOD, (st), (val))
# define sk_EVP_PKEY_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_METHOD, (st), (val))
# define sk_EVP_PKEY_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_METHOD, (st), (i))
# define sk_EVP_PKEY_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_METHOD, (st), (ptr))
# define sk_EVP_PKEY_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_METHOD, (st), (val), (i))
# define sk_EVP_PKEY_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_METHOD, (st), (cmp))
# define sk_EVP_PKEY_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_METHOD, st)
# define sk_EVP_PKEY_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_METHOD, (st), (free_func))
# define sk_EVP_PKEY_METHOD_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(EVP_PKEY_METHOD, (st), (copy_func), (free_func))
# define sk_EVP_PKEY_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_METHOD, (st))
# define sk_EVP_PKEY_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_METHOD, (st))
# define sk_EVP_PKEY_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_METHOD, (st))
# define sk_EVP_PKEY_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_METHOD, (st))
# define sk_GENERAL_NAME_new(cmp) SKM_sk_new(GENERAL_NAME, (cmp))
# define sk_GENERAL_NAME_new_null() SKM_sk_new_null(GENERAL_NAME)
# define sk_GENERAL_NAME_free(st) SKM_sk_free(GENERAL_NAME, (st))
# define sk_GENERAL_NAME_num(st) SKM_sk_num(GENERAL_NAME, (st))
# define sk_GENERAL_NAME_value(st, i) SKM_sk_value(GENERAL_NAME, (st), (i))
# define sk_GENERAL_NAME_set(st, i, val) SKM_sk_set(GENERAL_NAME, (st), (i), (val))
# define sk_GENERAL_NAME_zero(st) SKM_sk_zero(GENERAL_NAME, (st))
# define sk_GENERAL_NAME_push(st, val) SKM_sk_push(GENERAL_NAME, (st), (val))
# define sk_GENERAL_NAME_unshift(st, val) SKM_sk_unshift(GENERAL_NAME, (st), (val))
# define sk_GENERAL_NAME_find(st, val) SKM_sk_find(GENERAL_NAME, (st), (val))
# define sk_GENERAL_NAME_find_ex(st, val) SKM_sk_find_ex(GENERAL_NAME, (st), (val))
# define sk_GENERAL_NAME_delete(st, i) SKM_sk_delete(GENERAL_NAME, (st), (i))
# define sk_GENERAL_NAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_NAME, (st), (ptr))
# define sk_GENERAL_NAME_insert(st, val, i) SKM_sk_insert(GENERAL_NAME, (st), (val), (i))
# define sk_GENERAL_NAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_NAME, (st), (cmp))
# define sk_GENERAL_NAME_dup(st) SKM_sk_dup(GENERAL_NAME, st)
# define sk_GENERAL_NAME_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_NAME, (st), (free_func))
# define sk_GENERAL_NAME_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(GENERAL_NAME, (st), (copy_func), (free_func))
# define sk_GENERAL_NAME_shift(st) SKM_sk_shift(GENERAL_NAME, (st))
# define sk_GENERAL_NAME_pop(st) SKM_sk_pop(GENERAL_NAME, (st))
# define sk_GENERAL_NAME_sort(st) SKM_sk_sort(GENERAL_NAME, (st))
# define sk_GENERAL_NAME_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAME, (st))
# define sk_GENERAL_NAMES_new(cmp) SKM_sk_new(GENERAL_NAMES, (cmp))
# define sk_GENERAL_NAMES_new_null() SKM_sk_new_null(GENERAL_NAMES)
# define sk_GENERAL_NAMES_free(st) SKM_sk_free(GENERAL_NAMES, (st))
# define sk_GENERAL_NAMES_num(st) SKM_sk_num(GENERAL_NAMES, (st))
# define sk_GENERAL_NAMES_value(st, i) SKM_sk_value(GENERAL_NAMES, (st), (i))
# define sk_GENERAL_NAMES_set(st, i, val) SKM_sk_set(GENERAL_NAMES, (st), (i), (val))
# define sk_GENERAL_NAMES_zero(st) SKM_sk_zero(GENERAL_NAMES, (st))
# define sk_GENERAL_NAMES_push(st, val) SKM_sk_push(GENERAL_NAMES, (st), (val))
# define sk_GENERAL_NAMES_unshift(st, val) SKM_sk_unshift(GENERAL_NAMES, (st), (val))
# define sk_GENERAL_NAMES_find(st, val) SKM_sk_find(GENERAL_NAMES, (st), (val))
# define sk_GENERAL_NAMES_find_ex(st, val) SKM_sk_find_ex(GENERAL_NAMES, (st), (val))
# define sk_GENERAL_NAMES_delete(st, i) SKM_sk_delete(GENERAL_NAMES, (st), (i))
# define sk_GENERAL_NAMES_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_NAMES, (st), (ptr))
# define sk_GENERAL_NAMES_insert(st, val, i) SKM_sk_insert(GENERAL_NAMES, (st), (val), (i))
# define sk_GENERAL_NAMES_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_NAMES, (st), (cmp))
# define sk_GENERAL_NAMES_dup(st) SKM_sk_dup(GENERAL_NAMES, st)
# define sk_GENERAL_NAMES_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_NAMES, (st), (free_func))
# define sk_GENERAL_NAMES_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(GENERAL_NAMES, (st), (copy_func), (free_func))
# define sk_GENERAL_NAMES_shift(st) SKM_sk_shift(GENERAL_NAMES, (st))
# define sk_GENERAL_NAMES_pop(st) SKM_sk_pop(GENERAL_NAMES, (st))
# define sk_GENERAL_NAMES_sort(st) SKM_sk_sort(GENERAL_NAMES, (st))
# define sk_GENERAL_NAMES_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAMES, (st))
# define sk_GENERAL_SUBTREE_new(cmp) SKM_sk_new(GENERAL_SUBTREE, (cmp))
# define sk_GENERAL_SUBTREE_new_null() SKM_sk_new_null(GENERAL_SUBTREE)
# define sk_GENERAL_SUBTREE_free(st) SKM_sk_free(GENERAL_SUBTREE, (st))
# define sk_GENERAL_SUBTREE_num(st) SKM_sk_num(GENERAL_SUBTREE, (st))
# define sk_GENERAL_SUBTREE_value(st, i) SKM_sk_value(GENERAL_SUBTREE, (st), (i))
# define sk_GENERAL_SUBTREE_set(st, i, val) SKM_sk_set(GENERAL_SUBTREE, (st), (i), (val))
# define sk_GENERAL_SUBTREE_zero(st) SKM_sk_zero(GENERAL_SUBTREE, (st))
# define sk_GENERAL_SUBTREE_push(st, val) SKM_sk_push(GENERAL_SUBTREE, (st), (val))
# define sk_GENERAL_SUBTREE_unshift(st, val) SKM_sk_unshift(GENERAL_SUBTREE, (st), (val))
# define sk_GENERAL_SUBTREE_find(st, val) SKM_sk_find(GENERAL_SUBTREE, (st), (val))
# define sk_GENERAL_SUBTREE_find_ex(st, val) SKM_sk_find_ex(GENERAL_SUBTREE, (st), (val))
# define sk_GENERAL_SUBTREE_delete(st, i) SKM_sk_delete(GENERAL_SUBTREE, (st), (i))
# define sk_GENERAL_SUBTREE_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_SUBTREE, (st), (ptr))
# define sk_GENERAL_SUBTREE_insert(st, val, i) SKM_sk_insert(GENERAL_SUBTREE, (st), (val), (i))
# define sk_GENERAL_SUBTREE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_SUBTREE, (st), (cmp))
# define sk_GENERAL_SUBTREE_dup(st) SKM_sk_dup(GENERAL_SUBTREE, st)
# define sk_GENERAL_SUBTREE_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_SUBTREE, (st), (free_func))
# define sk_GENERAL_SUBTREE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(GENERAL_SUBTREE, (st), (copy_func), (free_func))
# define sk_GENERAL_SUBTREE_shift(st) SKM_sk_shift(GENERAL_SUBTREE, (st))
# define sk_GENERAL_SUBTREE_pop(st) SKM_sk_pop(GENERAL_SUBTREE, (st))
# define sk_GENERAL_SUBTREE_sort(st) SKM_sk_sort(GENERAL_SUBTREE, (st))
# define sk_GENERAL_SUBTREE_is_sorted(st) SKM_sk_is_sorted(GENERAL_SUBTREE, (st))
# define sk_IPAddressFamily_new(cmp) SKM_sk_new(IPAddressFamily, (cmp))
# define sk_IPAddressFamily_new_null() SKM_sk_new_null(IPAddressFamily)
# define sk_IPAddressFamily_free(st) SKM_sk_free(IPAddressFamily, (st))
# define sk_IPAddressFamily_num(st) SKM_sk_num(IPAddressFamily, (st))
# define sk_IPAddressFamily_value(st, i) SKM_sk_value(IPAddressFamily, (st), (i))
# define sk_IPAddressFamily_set(st, i, val) SKM_sk_set(IPAddressFamily, (st), (i), (val))
# define sk_IPAddressFamily_zero(st) SKM_sk_zero(IPAddressFamily, (st))
# define sk_IPAddressFamily_push(st, val) SKM_sk_push(IPAddressFamily, (st), (val))
# define sk_IPAddressFamily_unshift(st, val) SKM_sk_unshift(IPAddressFamily, (st), (val))
# define sk_IPAddressFamily_find(st, val) SKM_sk_find(IPAddressFamily, (st), (val))
# define sk_IPAddressFamily_find_ex(st, val) SKM_sk_find_ex(IPAddressFamily, (st), (val))
# define sk_IPAddressFamily_delete(st, i) SKM_sk_delete(IPAddressFamily, (st), (i))
# define sk_IPAddressFamily_delete_ptr(st, ptr) SKM_sk_delete_ptr(IPAddressFamily, (st), (ptr))
# define sk_IPAddressFamily_insert(st, val, i) SKM_sk_insert(IPAddressFamily, (st), (val), (i))
# define sk_IPAddressFamily_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(IPAddressFamily, (st), (cmp))
# define sk_IPAddressFamily_dup(st) SKM_sk_dup(IPAddressFamily, st)
# define sk_IPAddressFamily_pop_free(st, free_func) SKM_sk_pop_free(IPAddressFamily, (st), (free_func))
# define sk_IPAddressFamily_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(IPAddressFamily, (st), (copy_func), (free_func))
# define sk_IPAddressFamily_shift(st) SKM_sk_shift(IPAddressFamily, (st))
# define sk_IPAddressFamily_pop(st) SKM_sk_pop(IPAddressFamily, (st))
# define sk_IPAddressFamily_sort(st) SKM_sk_sort(IPAddressFamily, (st))
# define sk_IPAddressFamily_is_sorted(st) SKM_sk_is_sorted(IPAddressFamily, (st))
# define sk_IPAddressOrRange_new(cmp) SKM_sk_new(IPAddressOrRange, (cmp))
# define sk_IPAddressOrRange_new_null() SKM_sk_new_null(IPAddressOrRange)
# define sk_IPAddressOrRange_free(st) SKM_sk_free(IPAddressOrRange, (st))
# define sk_IPAddressOrRange_num(st) SKM_sk_num(IPAddressOrRange, (st))
# define sk_IPAddressOrRange_value(st, i) SKM_sk_value(IPAddressOrRange, (st), (i))
# define sk_IPAddressOrRange_set(st, i, val) SKM_sk_set(IPAddressOrRange, (st), (i), (val))
# define sk_IPAddressOrRange_zero(st) SKM_sk_zero(IPAddressOrRange, (st))
# define sk_IPAddressOrRange_push(st, val) SKM_sk_push(IPAddressOrRange, (st), (val))
# define sk_IPAddressOrRange_unshift(st, val) SKM_sk_unshift(IPAddressOrRange, (st), (val))
# define sk_IPAddressOrRange_find(st, val) SKM_sk_find(IPAddressOrRange, (st), (val))
# define sk_IPAddressOrRange_find_ex(st, val) SKM_sk_find_ex(IPAddressOrRange, (st), (val))
# define sk_IPAddressOrRange_delete(st, i) SKM_sk_delete(IPAddressOrRange, (st), (i))
# define sk_IPAddressOrRange_delete_ptr(st, ptr) SKM_sk_delete_ptr(IPAddressOrRange, (st), (ptr))
# define sk_IPAddressOrRange_insert(st, val, i) SKM_sk_insert(IPAddressOrRange, (st), (val), (i))
# define sk_IPAddressOrRange_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(IPAddressOrRange, (st), (cmp))
# define sk_IPAddressOrRange_dup(st) SKM_sk_dup(IPAddressOrRange, st)
# define sk_IPAddressOrRange_pop_free(st, free_func) SKM_sk_pop_free(IPAddressOrRange, (st), (free_func))
# define sk_IPAddressOrRange_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(IPAddressOrRange, (st), (copy_func), (free_func))
# define sk_IPAddressOrRange_shift(st) SKM_sk_shift(IPAddressOrRange, (st))
# define sk_IPAddressOrRange_pop(st) SKM_sk_pop(IPAddressOrRange, (st))
# define sk_IPAddressOrRange_sort(st) SKM_sk_sort(IPAddressOrRange, (st))
# define sk_IPAddressOrRange_is_sorted(st) SKM_sk_is_sorted(IPAddressOrRange, (st))
# define sk_KRB5_APREQBODY_new(cmp) SKM_sk_new(KRB5_APREQBODY, (cmp))
# define sk_KRB5_APREQBODY_new_null() SKM_sk_new_null(KRB5_APREQBODY)
# define sk_KRB5_APREQBODY_free(st) SKM_sk_free(KRB5_APREQBODY, (st))
# define sk_KRB5_APREQBODY_num(st) SKM_sk_num(KRB5_APREQBODY, (st))
# define sk_KRB5_APREQBODY_value(st, i) SKM_sk_value(KRB5_APREQBODY, (st), (i))
# define sk_KRB5_APREQBODY_set(st, i, val) SKM_sk_set(KRB5_APREQBODY, (st), (i), (val))
# define sk_KRB5_APREQBODY_zero(st) SKM_sk_zero(KRB5_APREQBODY, (st))
# define sk_KRB5_APREQBODY_push(st, val) SKM_sk_push(KRB5_APREQBODY, (st), (val))
# define sk_KRB5_APREQBODY_unshift(st, val) SKM_sk_unshift(KRB5_APREQBODY, (st), (val))
# define sk_KRB5_APREQBODY_find(st, val) SKM_sk_find(KRB5_APREQBODY, (st), (val))
# define sk_KRB5_APREQBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_APREQBODY, (st), (val))
# define sk_KRB5_APREQBODY_delete(st, i) SKM_sk_delete(KRB5_APREQBODY, (st), (i))
# define sk_KRB5_APREQBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_APREQBODY, (st), (ptr))
# define sk_KRB5_APREQBODY_insert(st, val, i) SKM_sk_insert(KRB5_APREQBODY, (st), (val), (i))
# define sk_KRB5_APREQBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_APREQBODY, (st), (cmp))
# define sk_KRB5_APREQBODY_dup(st) SKM_sk_dup(KRB5_APREQBODY, st)
# define sk_KRB5_APREQBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_APREQBODY, (st), (free_func))
# define sk_KRB5_APREQBODY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_APREQBODY, (st), (copy_func), (free_func))
# define sk_KRB5_APREQBODY_shift(st) SKM_sk_shift(KRB5_APREQBODY, (st))
# define sk_KRB5_APREQBODY_pop(st) SKM_sk_pop(KRB5_APREQBODY, (st))
# define sk_KRB5_APREQBODY_sort(st) SKM_sk_sort(KRB5_APREQBODY, (st))
# define sk_KRB5_APREQBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_APREQBODY, (st))
# define sk_KRB5_AUTHDATA_new(cmp) SKM_sk_new(KRB5_AUTHDATA, (cmp))
# define sk_KRB5_AUTHDATA_new_null() SKM_sk_new_null(KRB5_AUTHDATA)
# define sk_KRB5_AUTHDATA_free(st) SKM_sk_free(KRB5_AUTHDATA, (st))
# define sk_KRB5_AUTHDATA_num(st) SKM_sk_num(KRB5_AUTHDATA, (st))
# define sk_KRB5_AUTHDATA_value(st, i) SKM_sk_value(KRB5_AUTHDATA, (st), (i))
# define sk_KRB5_AUTHDATA_set(st, i, val) SKM_sk_set(KRB5_AUTHDATA, (st), (i), (val))
# define sk_KRB5_AUTHDATA_zero(st) SKM_sk_zero(KRB5_AUTHDATA, (st))
# define sk_KRB5_AUTHDATA_push(st, val) SKM_sk_push(KRB5_AUTHDATA, (st), (val))
# define sk_KRB5_AUTHDATA_unshift(st, val) SKM_sk_unshift(KRB5_AUTHDATA, (st), (val))
# define sk_KRB5_AUTHDATA_find(st, val) SKM_sk_find(KRB5_AUTHDATA, (st), (val))
# define sk_KRB5_AUTHDATA_find_ex(st, val) SKM_sk_find_ex(KRB5_AUTHDATA, (st), (val))
# define sk_KRB5_AUTHDATA_delete(st, i) SKM_sk_delete(KRB5_AUTHDATA, (st), (i))
# define sk_KRB5_AUTHDATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_AUTHDATA, (st), (ptr))
# define sk_KRB5_AUTHDATA_insert(st, val, i) SKM_sk_insert(KRB5_AUTHDATA, (st), (val), (i))
# define sk_KRB5_AUTHDATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_AUTHDATA, (st), (cmp))
# define sk_KRB5_AUTHDATA_dup(st) SKM_sk_dup(KRB5_AUTHDATA, st)
# define sk_KRB5_AUTHDATA_pop_free(st, free_func) SKM_sk_pop_free(KRB5_AUTHDATA, (st), (free_func))
# define sk_KRB5_AUTHDATA_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_AUTHDATA, (st), (copy_func), (free_func))
# define sk_KRB5_AUTHDATA_shift(st) SKM_sk_shift(KRB5_AUTHDATA, (st))
# define sk_KRB5_AUTHDATA_pop(st) SKM_sk_pop(KRB5_AUTHDATA, (st))
# define sk_KRB5_AUTHDATA_sort(st) SKM_sk_sort(KRB5_AUTHDATA, (st))
# define sk_KRB5_AUTHDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHDATA, (st))
# define sk_KRB5_AUTHENTBODY_new(cmp) SKM_sk_new(KRB5_AUTHENTBODY, (cmp))
# define sk_KRB5_AUTHENTBODY_new_null() SKM_sk_new_null(KRB5_AUTHENTBODY)
# define sk_KRB5_AUTHENTBODY_free(st) SKM_sk_free(KRB5_AUTHENTBODY, (st))
# define sk_KRB5_AUTHENTBODY_num(st) SKM_sk_num(KRB5_AUTHENTBODY, (st))
# define sk_KRB5_AUTHENTBODY_value(st, i) SKM_sk_value(KRB5_AUTHENTBODY, (st), (i))
# define sk_KRB5_AUTHENTBODY_set(st, i, val) SKM_sk_set(KRB5_AUTHENTBODY, (st), (i), (val))
# define sk_KRB5_AUTHENTBODY_zero(st) SKM_sk_zero(KRB5_AUTHENTBODY, (st))
# define sk_KRB5_AUTHENTBODY_push(st, val) SKM_sk_push(KRB5_AUTHENTBODY, (st), (val))
# define sk_KRB5_AUTHENTBODY_unshift(st, val) SKM_sk_unshift(KRB5_AUTHENTBODY, (st), (val))
# define sk_KRB5_AUTHENTBODY_find(st, val) SKM_sk_find(KRB5_AUTHENTBODY, (st), (val))
# define sk_KRB5_AUTHENTBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_AUTHENTBODY, (st), (val))
# define sk_KRB5_AUTHENTBODY_delete(st, i) SKM_sk_delete(KRB5_AUTHENTBODY, (st), (i))
# define sk_KRB5_AUTHENTBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_AUTHENTBODY, (st), (ptr))
# define sk_KRB5_AUTHENTBODY_insert(st, val, i) SKM_sk_insert(KRB5_AUTHENTBODY, (st), (val), (i))
# define sk_KRB5_AUTHENTBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_AUTHENTBODY, (st), (cmp))
# define sk_KRB5_AUTHENTBODY_dup(st) SKM_sk_dup(KRB5_AUTHENTBODY, st)
# define sk_KRB5_AUTHENTBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_AUTHENTBODY, (st), (free_func))
# define sk_KRB5_AUTHENTBODY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_AUTHENTBODY, (st), (copy_func), (free_func))
# define sk_KRB5_AUTHENTBODY_shift(st) SKM_sk_shift(KRB5_AUTHENTBODY, (st))
# define sk_KRB5_AUTHENTBODY_pop(st) SKM_sk_pop(KRB5_AUTHENTBODY, (st))
# define sk_KRB5_AUTHENTBODY_sort(st) SKM_sk_sort(KRB5_AUTHENTBODY, (st))
# define sk_KRB5_AUTHENTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHENTBODY, (st))
# define sk_KRB5_CHECKSUM_new(cmp) SKM_sk_new(KRB5_CHECKSUM, (cmp))
# define sk_KRB5_CHECKSUM_new_null() SKM_sk_new_null(KRB5_CHECKSUM)
# define sk_KRB5_CHECKSUM_free(st) SKM_sk_free(KRB5_CHECKSUM, (st))
# define sk_KRB5_CHECKSUM_num(st) SKM_sk_num(KRB5_CHECKSUM, (st))
# define sk_KRB5_CHECKSUM_value(st, i) SKM_sk_value(KRB5_CHECKSUM, (st), (i))
# define sk_KRB5_CHECKSUM_set(st, i, val) SKM_sk_set(KRB5_CHECKSUM, (st), (i), (val))
# define sk_KRB5_CHECKSUM_zero(st) SKM_sk_zero(KRB5_CHECKSUM, (st))
# define sk_KRB5_CHECKSUM_push(st, val) SKM_sk_push(KRB5_CHECKSUM, (st), (val))
# define sk_KRB5_CHECKSUM_unshift(st, val) SKM_sk_unshift(KRB5_CHECKSUM, (st), (val))
# define sk_KRB5_CHECKSUM_find(st, val) SKM_sk_find(KRB5_CHECKSUM, (st), (val))
# define sk_KRB5_CHECKSUM_find_ex(st, val) SKM_sk_find_ex(KRB5_CHECKSUM, (st), (val))
# define sk_KRB5_CHECKSUM_delete(st, i) SKM_sk_delete(KRB5_CHECKSUM, (st), (i))
# define sk_KRB5_CHECKSUM_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_CHECKSUM, (st), (ptr))
# define sk_KRB5_CHECKSUM_insert(st, val, i) SKM_sk_insert(KRB5_CHECKSUM, (st), (val), (i))
# define sk_KRB5_CHECKSUM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_CHECKSUM, (st), (cmp))
# define sk_KRB5_CHECKSUM_dup(st) SKM_sk_dup(KRB5_CHECKSUM, st)
# define sk_KRB5_CHECKSUM_pop_free(st, free_func) SKM_sk_pop_free(KRB5_CHECKSUM, (st), (free_func))
# define sk_KRB5_CHECKSUM_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_CHECKSUM, (st), (copy_func), (free_func))
# define sk_KRB5_CHECKSUM_shift(st) SKM_sk_shift(KRB5_CHECKSUM, (st))
# define sk_KRB5_CHECKSUM_pop(st) SKM_sk_pop(KRB5_CHECKSUM, (st))
# define sk_KRB5_CHECKSUM_sort(st) SKM_sk_sort(KRB5_CHECKSUM, (st))
# define sk_KRB5_CHECKSUM_is_sorted(st) SKM_sk_is_sorted(KRB5_CHECKSUM, (st))
# define sk_KRB5_ENCDATA_new(cmp) SKM_sk_new(KRB5_ENCDATA, (cmp))
# define sk_KRB5_ENCDATA_new_null() SKM_sk_new_null(KRB5_ENCDATA)
# define sk_KRB5_ENCDATA_free(st) SKM_sk_free(KRB5_ENCDATA, (st))
# define sk_KRB5_ENCDATA_num(st) SKM_sk_num(KRB5_ENCDATA, (st))
# define sk_KRB5_ENCDATA_value(st, i) SKM_sk_value(KRB5_ENCDATA, (st), (i))
# define sk_KRB5_ENCDATA_set(st, i, val) SKM_sk_set(KRB5_ENCDATA, (st), (i), (val))
# define sk_KRB5_ENCDATA_zero(st) SKM_sk_zero(KRB5_ENCDATA, (st))
# define sk_KRB5_ENCDATA_push(st, val) SKM_sk_push(KRB5_ENCDATA, (st), (val))
# define sk_KRB5_ENCDATA_unshift(st, val) SKM_sk_unshift(KRB5_ENCDATA, (st), (val))
# define sk_KRB5_ENCDATA_find(st, val) SKM_sk_find(KRB5_ENCDATA, (st), (val))
# define sk_KRB5_ENCDATA_find_ex(st, val) SKM_sk_find_ex(KRB5_ENCDATA, (st), (val))
# define sk_KRB5_ENCDATA_delete(st, i) SKM_sk_delete(KRB5_ENCDATA, (st), (i))
# define sk_KRB5_ENCDATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_ENCDATA, (st), (ptr))
# define sk_KRB5_ENCDATA_insert(st, val, i) SKM_sk_insert(KRB5_ENCDATA, (st), (val), (i))
# define sk_KRB5_ENCDATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_ENCDATA, (st), (cmp))
# define sk_KRB5_ENCDATA_dup(st) SKM_sk_dup(KRB5_ENCDATA, st)
# define sk_KRB5_ENCDATA_pop_free(st, free_func) SKM_sk_pop_free(KRB5_ENCDATA, (st), (free_func))
# define sk_KRB5_ENCDATA_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_ENCDATA, (st), (copy_func), (free_func))
# define sk_KRB5_ENCDATA_shift(st) SKM_sk_shift(KRB5_ENCDATA, (st))
# define sk_KRB5_ENCDATA_pop(st) SKM_sk_pop(KRB5_ENCDATA, (st))
# define sk_KRB5_ENCDATA_sort(st) SKM_sk_sort(KRB5_ENCDATA, (st))
# define sk_KRB5_ENCDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCDATA, (st))
# define sk_KRB5_ENCKEY_new(cmp) SKM_sk_new(KRB5_ENCKEY, (cmp))
# define sk_KRB5_ENCKEY_new_null() SKM_sk_new_null(KRB5_ENCKEY)
# define sk_KRB5_ENCKEY_free(st) SKM_sk_free(KRB5_ENCKEY, (st))
# define sk_KRB5_ENCKEY_num(st) SKM_sk_num(KRB5_ENCKEY, (st))
# define sk_KRB5_ENCKEY_value(st, i) SKM_sk_value(KRB5_ENCKEY, (st), (i))
# define sk_KRB5_ENCKEY_set(st, i, val) SKM_sk_set(KRB5_ENCKEY, (st), (i), (val))
# define sk_KRB5_ENCKEY_zero(st) SKM_sk_zero(KRB5_ENCKEY, (st))
# define sk_KRB5_ENCKEY_push(st, val) SKM_sk_push(KRB5_ENCKEY, (st), (val))
# define sk_KRB5_ENCKEY_unshift(st, val) SKM_sk_unshift(KRB5_ENCKEY, (st), (val))
# define sk_KRB5_ENCKEY_find(st, val) SKM_sk_find(KRB5_ENCKEY, (st), (val))
# define sk_KRB5_ENCKEY_find_ex(st, val) SKM_sk_find_ex(KRB5_ENCKEY, (st), (val))
# define sk_KRB5_ENCKEY_delete(st, i) SKM_sk_delete(KRB5_ENCKEY, (st), (i))
# define sk_KRB5_ENCKEY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_ENCKEY, (st), (ptr))
# define sk_KRB5_ENCKEY_insert(st, val, i) SKM_sk_insert(KRB5_ENCKEY, (st), (val), (i))
# define sk_KRB5_ENCKEY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_ENCKEY, (st), (cmp))
# define sk_KRB5_ENCKEY_dup(st) SKM_sk_dup(KRB5_ENCKEY, st)
# define sk_KRB5_ENCKEY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_ENCKEY, (st), (free_func))
# define sk_KRB5_ENCKEY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_ENCKEY, (st), (copy_func), (free_func))
# define sk_KRB5_ENCKEY_shift(st) SKM_sk_shift(KRB5_ENCKEY, (st))
# define sk_KRB5_ENCKEY_pop(st) SKM_sk_pop(KRB5_ENCKEY, (st))
# define sk_KRB5_ENCKEY_sort(st) SKM_sk_sort(KRB5_ENCKEY, (st))
# define sk_KRB5_ENCKEY_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCKEY, (st))
# define sk_KRB5_PRINCNAME_new(cmp) SKM_sk_new(KRB5_PRINCNAME, (cmp))
# define sk_KRB5_PRINCNAME_new_null() SKM_sk_new_null(KRB5_PRINCNAME)
# define sk_KRB5_PRINCNAME_free(st) SKM_sk_free(KRB5_PRINCNAME, (st))
# define sk_KRB5_PRINCNAME_num(st) SKM_sk_num(KRB5_PRINCNAME, (st))
# define sk_KRB5_PRINCNAME_value(st, i) SKM_sk_value(KRB5_PRINCNAME, (st), (i))
# define sk_KRB5_PRINCNAME_set(st, i, val) SKM_sk_set(KRB5_PRINCNAME, (st), (i), (val))
# define sk_KRB5_PRINCNAME_zero(st) SKM_sk_zero(KRB5_PRINCNAME, (st))
# define sk_KRB5_PRINCNAME_push(st, val) SKM_sk_push(KRB5_PRINCNAME, (st), (val))
# define sk_KRB5_PRINCNAME_unshift(st, val) SKM_sk_unshift(KRB5_PRINCNAME, (st), (val))
# define sk_KRB5_PRINCNAME_find(st, val) SKM_sk_find(KRB5_PRINCNAME, (st), (val))
# define sk_KRB5_PRINCNAME_find_ex(st, val) SKM_sk_find_ex(KRB5_PRINCNAME, (st), (val))
# define sk_KRB5_PRINCNAME_delete(st, i) SKM_sk_delete(KRB5_PRINCNAME, (st), (i))
# define sk_KRB5_PRINCNAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_PRINCNAME, (st), (ptr))
# define sk_KRB5_PRINCNAME_insert(st, val, i) SKM_sk_insert(KRB5_PRINCNAME, (st), (val), (i))
# define sk_KRB5_PRINCNAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_PRINCNAME, (st), (cmp))
# define sk_KRB5_PRINCNAME_dup(st) SKM_sk_dup(KRB5_PRINCNAME, st)
# define sk_KRB5_PRINCNAME_pop_free(st, free_func) SKM_sk_pop_free(KRB5_PRINCNAME, (st), (free_func))
# define sk_KRB5_PRINCNAME_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_PRINCNAME, (st), (copy_func), (free_func))
# define sk_KRB5_PRINCNAME_shift(st) SKM_sk_shift(KRB5_PRINCNAME, (st))
# define sk_KRB5_PRINCNAME_pop(st) SKM_sk_pop(KRB5_PRINCNAME, (st))
# define sk_KRB5_PRINCNAME_sort(st) SKM_sk_sort(KRB5_PRINCNAME, (st))
# define sk_KRB5_PRINCNAME_is_sorted(st) SKM_sk_is_sorted(KRB5_PRINCNAME, (st))
# define sk_KRB5_TKTBODY_new(cmp) SKM_sk_new(KRB5_TKTBODY, (cmp))
# define sk_KRB5_TKTBODY_new_null() SKM_sk_new_null(KRB5_TKTBODY)
# define sk_KRB5_TKTBODY_free(st) SKM_sk_free(KRB5_TKTBODY, (st))
# define sk_KRB5_TKTBODY_num(st) SKM_sk_num(KRB5_TKTBODY, (st))
# define sk_KRB5_TKTBODY_value(st, i) SKM_sk_value(KRB5_TKTBODY, (st), (i))
# define sk_KRB5_TKTBODY_set(st, i, val) SKM_sk_set(KRB5_TKTBODY, (st), (i), (val))
# define sk_KRB5_TKTBODY_zero(st) SKM_sk_zero(KRB5_TKTBODY, (st))
# define sk_KRB5_TKTBODY_push(st, val) SKM_sk_push(KRB5_TKTBODY, (st), (val))
# define sk_KRB5_TKTBODY_unshift(st, val) SKM_sk_unshift(KRB5_TKTBODY, (st), (val))
# define sk_KRB5_TKTBODY_find(st, val) SKM_sk_find(KRB5_TKTBODY, (st), (val))
# define sk_KRB5_TKTBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_TKTBODY, (st), (val))
# define sk_KRB5_TKTBODY_delete(st, i) SKM_sk_delete(KRB5_TKTBODY, (st), (i))
# define sk_KRB5_TKTBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_TKTBODY, (st), (ptr))
# define sk_KRB5_TKTBODY_insert(st, val, i) SKM_sk_insert(KRB5_TKTBODY, (st), (val), (i))
# define sk_KRB5_TKTBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_TKTBODY, (st), (cmp))
# define sk_KRB5_TKTBODY_dup(st) SKM_sk_dup(KRB5_TKTBODY, st)
# define sk_KRB5_TKTBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_TKTBODY, (st), (free_func))
# define sk_KRB5_TKTBODY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_TKTBODY, (st), (copy_func), (free_func))
# define sk_KRB5_TKTBODY_shift(st) SKM_sk_shift(KRB5_TKTBODY, (st))
# define sk_KRB5_TKTBODY_pop(st) SKM_sk_pop(KRB5_TKTBODY, (st))
# define sk_KRB5_TKTBODY_sort(st) SKM_sk_sort(KRB5_TKTBODY, (st))
# define sk_KRB5_TKTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_TKTBODY, (st))
# define sk_MEM_OBJECT_DATA_new(cmp) SKM_sk_new(MEM_OBJECT_DATA, (cmp))
# define sk_MEM_OBJECT_DATA_new_null() SKM_sk_new_null(MEM_OBJECT_DATA)
# define sk_MEM_OBJECT_DATA_free(st) SKM_sk_free(MEM_OBJECT_DATA, (st))
# define sk_MEM_OBJECT_DATA_num(st) SKM_sk_num(MEM_OBJECT_DATA, (st))
# define sk_MEM_OBJECT_DATA_value(st, i) SKM_sk_value(MEM_OBJECT_DATA, (st), (i))
# define sk_MEM_OBJECT_DATA_set(st, i, val) SKM_sk_set(MEM_OBJECT_DATA, (st), (i), (val))
# define sk_MEM_OBJECT_DATA_zero(st) SKM_sk_zero(MEM_OBJECT_DATA, (st))
# define sk_MEM_OBJECT_DATA_push(st, val) SKM_sk_push(MEM_OBJECT_DATA, (st), (val))
# define sk_MEM_OBJECT_DATA_unshift(st, val) SKM_sk_unshift(MEM_OBJECT_DATA, (st), (val))
# define sk_MEM_OBJECT_DATA_find(st, val) SKM_sk_find(MEM_OBJECT_DATA, (st), (val))
# define sk_MEM_OBJECT_DATA_find_ex(st, val) SKM_sk_find_ex(MEM_OBJECT_DATA, (st), (val))
# define sk_MEM_OBJECT_DATA_delete(st, i) SKM_sk_delete(MEM_OBJECT_DATA, (st), (i))
# define sk_MEM_OBJECT_DATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(MEM_OBJECT_DATA, (st), (ptr))
# define sk_MEM_OBJECT_DATA_insert(st, val, i) SKM_sk_insert(MEM_OBJECT_DATA, (st), (val), (i))
# define sk_MEM_OBJECT_DATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MEM_OBJECT_DATA, (st), (cmp))
# define sk_MEM_OBJECT_DATA_dup(st) SKM_sk_dup(MEM_OBJECT_DATA, st)
# define sk_MEM_OBJECT_DATA_pop_free(st, free_func) SKM_sk_pop_free(MEM_OBJECT_DATA, (st), (free_func))
# define sk_MEM_OBJECT_DATA_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(MEM_OBJECT_DATA, (st), (copy_func), (free_func))
# define sk_MEM_OBJECT_DATA_shift(st) SKM_sk_shift(MEM_OBJECT_DATA, (st))
# define sk_MEM_OBJECT_DATA_pop(st) SKM_sk_pop(MEM_OBJECT_DATA, (st))
# define sk_MEM_OBJECT_DATA_sort(st) SKM_sk_sort(MEM_OBJECT_DATA, (st))
# define sk_MEM_OBJECT_DATA_is_sorted(st) SKM_sk_is_sorted(MEM_OBJECT_DATA, (st))
# define sk_MIME_HEADER_new(cmp) SKM_sk_new(MIME_HEADER, (cmp))
# define sk_MIME_HEADER_new_null() SKM_sk_new_null(MIME_HEADER)
# define sk_MIME_HEADER_free(st) SKM_sk_free(MIME_HEADER, (st))
# define sk_MIME_HEADER_num(st) SKM_sk_num(MIME_HEADER, (st))
# define sk_MIME_HEADER_value(st, i) SKM_sk_value(MIME_HEADER, (st), (i))
# define sk_MIME_HEADER_set(st, i, val) SKM_sk_set(MIME_HEADER, (st), (i), (val))
# define sk_MIME_HEADER_zero(st) SKM_sk_zero(MIME_HEADER, (st))
# define sk_MIME_HEADER_push(st, val) SKM_sk_push(MIME_HEADER, (st), (val))
# define sk_MIME_HEADER_unshift(st, val) SKM_sk_unshift(MIME_HEADER, (st), (val))
# define sk_MIME_HEADER_find(st, val) SKM_sk_find(MIME_HEADER, (st), (val))
# define sk_MIME_HEADER_find_ex(st, val) SKM_sk_find_ex(MIME_HEADER, (st), (val))
# define sk_MIME_HEADER_delete(st, i) SKM_sk_delete(MIME_HEADER, (st), (i))
# define sk_MIME_HEADER_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_HEADER, (st), (ptr))
# define sk_MIME_HEADER_insert(st, val, i) SKM_sk_insert(MIME_HEADER, (st), (val), (i))
# define sk_MIME_HEADER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_HEADER, (st), (cmp))
# define sk_MIME_HEADER_dup(st) SKM_sk_dup(MIME_HEADER, st)
# define sk_MIME_HEADER_pop_free(st, free_func) SKM_sk_pop_free(MIME_HEADER, (st), (free_func))
# define sk_MIME_HEADER_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(MIME_HEADER, (st), (copy_func), (free_func))
# define sk_MIME_HEADER_shift(st) SKM_sk_shift(MIME_HEADER, (st))
# define sk_MIME_HEADER_pop(st) SKM_sk_pop(MIME_HEADER, (st))
# define sk_MIME_HEADER_sort(st) SKM_sk_sort(MIME_HEADER, (st))
# define sk_MIME_HEADER_is_sorted(st) SKM_sk_is_sorted(MIME_HEADER, (st))
# define sk_MIME_PARAM_new(cmp) SKM_sk_new(MIME_PARAM, (cmp))
# define sk_MIME_PARAM_new_null() SKM_sk_new_null(MIME_PARAM)
# define sk_MIME_PARAM_free(st) SKM_sk_free(MIME_PARAM, (st))
# define sk_MIME_PARAM_num(st) SKM_sk_num(MIME_PARAM, (st))
# define sk_MIME_PARAM_value(st, i) SKM_sk_value(MIME_PARAM, (st), (i))
# define sk_MIME_PARAM_set(st, i, val) SKM_sk_set(MIME_PARAM, (st), (i), (val))
# define sk_MIME_PARAM_zero(st) SKM_sk_zero(MIME_PARAM, (st))
# define sk_MIME_PARAM_push(st, val) SKM_sk_push(MIME_PARAM, (st), (val))
# define sk_MIME_PARAM_unshift(st, val) SKM_sk_unshift(MIME_PARAM, (st), (val))
# define sk_MIME_PARAM_find(st, val) SKM_sk_find(MIME_PARAM, (st), (val))
# define sk_MIME_PARAM_find_ex(st, val) SKM_sk_find_ex(MIME_PARAM, (st), (val))
# define sk_MIME_PARAM_delete(st, i) SKM_sk_delete(MIME_PARAM, (st), (i))
# define sk_MIME_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_PARAM, (st), (ptr))
# define sk_MIME_PARAM_insert(st, val, i) SKM_sk_insert(MIME_PARAM, (st), (val), (i))
# define sk_MIME_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_PARAM, (st), (cmp))
# define sk_MIME_PARAM_dup(st) SKM_sk_dup(MIME_PARAM, st)
# define sk_MIME_PARAM_pop_free(st, free_func) SKM_sk_pop_free(MIME_PARAM, (st), (free_func))
# define sk_MIME_PARAM_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(MIME_PARAM, (st), (copy_func), (free_func))
# define sk_MIME_PARAM_shift(st) SKM_sk_shift(MIME_PARAM, (st))
# define sk_MIME_PARAM_pop(st) SKM_sk_pop(MIME_PARAM, (st))
# define sk_MIME_PARAM_sort(st) SKM_sk_sort(MIME_PARAM, (st))
# define sk_MIME_PARAM_is_sorted(st) SKM_sk_is_sorted(MIME_PARAM, (st))
# define sk_NAME_FUNCS_new(cmp) SKM_sk_new(NAME_FUNCS, (cmp))
# define sk_NAME_FUNCS_new_null() SKM_sk_new_null(NAME_FUNCS)
# define sk_NAME_FUNCS_free(st) SKM_sk_free(NAME_FUNCS, (st))
# define sk_NAME_FUNCS_num(st) SKM_sk_num(NAME_FUNCS, (st))
# define sk_NAME_FUNCS_value(st, i) SKM_sk_value(NAME_FUNCS, (st), (i))
# define sk_NAME_FUNCS_set(st, i, val) SKM_sk_set(NAME_FUNCS, (st), (i), (val))
# define sk_NAME_FUNCS_zero(st) SKM_sk_zero(NAME_FUNCS, (st))
# define sk_NAME_FUNCS_push(st, val) SKM_sk_push(NAME_FUNCS, (st), (val))
# define sk_NAME_FUNCS_unshift(st, val) SKM_sk_unshift(NAME_FUNCS, (st), (val))
# define sk_NAME_FUNCS_find(st, val) SKM_sk_find(NAME_FUNCS, (st), (val))
# define sk_NAME_FUNCS_find_ex(st, val) SKM_sk_find_ex(NAME_FUNCS, (st), (val))
# define sk_NAME_FUNCS_delete(st, i) SKM_sk_delete(NAME_FUNCS, (st), (i))
# define sk_NAME_FUNCS_delete_ptr(st, ptr) SKM_sk_delete_ptr(NAME_FUNCS, (st), (ptr))
# define sk_NAME_FUNCS_insert(st, val, i) SKM_sk_insert(NAME_FUNCS, (st), (val), (i))
# define sk_NAME_FUNCS_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(NAME_FUNCS, (st), (cmp))
# define sk_NAME_FUNCS_dup(st) SKM_sk_dup(NAME_FUNCS, st)
# define sk_NAME_FUNCS_pop_free(st, free_func) SKM_sk_pop_free(NAME_FUNCS, (st), (free_func))
# define sk_NAME_FUNCS_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(NAME_FUNCS, (st), (copy_func), (free_func))
# define sk_NAME_FUNCS_shift(st) SKM_sk_shift(NAME_FUNCS, (st))
# define sk_NAME_FUNCS_pop(st) SKM_sk_pop(NAME_FUNCS, (st))
# define sk_NAME_FUNCS_sort(st) SKM_sk_sort(NAME_FUNCS, (st))
# define sk_NAME_FUNCS_is_sorted(st) SKM_sk_is_sorted(NAME_FUNCS, (st))
# define sk_OCSP_CERTID_new(cmp) SKM_sk_new(OCSP_CERTID, (cmp))
# define sk_OCSP_CERTID_new_null() SKM_sk_new_null(OCSP_CERTID)
# define sk_OCSP_CERTID_free(st) SKM_sk_free(OCSP_CERTID, (st))
# define sk_OCSP_CERTID_num(st) SKM_sk_num(OCSP_CERTID, (st))
# define sk_OCSP_CERTID_value(st, i) SKM_sk_value(OCSP_CERTID, (st), (i))
# define sk_OCSP_CERTID_set(st, i, val) SKM_sk_set(OCSP_CERTID, (st), (i), (val))
# define sk_OCSP_CERTID_zero(st) SKM_sk_zero(OCSP_CERTID, (st))
# define sk_OCSP_CERTID_push(st, val) SKM_sk_push(OCSP_CERTID, (st), (val))
# define sk_OCSP_CERTID_unshift(st, val) SKM_sk_unshift(OCSP_CERTID, (st), (val))
# define sk_OCSP_CERTID_find(st, val) SKM_sk_find(OCSP_CERTID, (st), (val))
# define sk_OCSP_CERTID_find_ex(st, val) SKM_sk_find_ex(OCSP_CERTID, (st), (val))
# define sk_OCSP_CERTID_delete(st, i) SKM_sk_delete(OCSP_CERTID, (st), (i))
# define sk_OCSP_CERTID_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_CERTID, (st), (ptr))
# define sk_OCSP_CERTID_insert(st, val, i) SKM_sk_insert(OCSP_CERTID, (st), (val), (i))
# define sk_OCSP_CERTID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_CERTID, (st), (cmp))
# define sk_OCSP_CERTID_dup(st) SKM_sk_dup(OCSP_CERTID, st)
# define sk_OCSP_CERTID_pop_free(st, free_func) SKM_sk_pop_free(OCSP_CERTID, (st), (free_func))
# define sk_OCSP_CERTID_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(OCSP_CERTID, (st), (copy_func), (free_func))
# define sk_OCSP_CERTID_shift(st) SKM_sk_shift(OCSP_CERTID, (st))
# define sk_OCSP_CERTID_pop(st) SKM_sk_pop(OCSP_CERTID, (st))
# define sk_OCSP_CERTID_sort(st) SKM_sk_sort(OCSP_CERTID, (st))
# define sk_OCSP_CERTID_is_sorted(st) SKM_sk_is_sorted(OCSP_CERTID, (st))
# define sk_OCSP_ONEREQ_new(cmp) SKM_sk_new(OCSP_ONEREQ, (cmp))
# define sk_OCSP_ONEREQ_new_null() SKM_sk_new_null(OCSP_ONEREQ)
# define sk_OCSP_ONEREQ_free(st) SKM_sk_free(OCSP_ONEREQ, (st))
# define sk_OCSP_ONEREQ_num(st) SKM_sk_num(OCSP_ONEREQ, (st))
# define sk_OCSP_ONEREQ_value(st, i) SKM_sk_value(OCSP_ONEREQ, (st), (i))
# define sk_OCSP_ONEREQ_set(st, i, val) SKM_sk_set(OCSP_ONEREQ, (st), (i), (val))
# define sk_OCSP_ONEREQ_zero(st) SKM_sk_zero(OCSP_ONEREQ, (st))
# define sk_OCSP_ONEREQ_push(st, val) SKM_sk_push(OCSP_ONEREQ, (st), (val))
# define sk_OCSP_ONEREQ_unshift(st, val) SKM_sk_unshift(OCSP_ONEREQ, (st), (val))
# define sk_OCSP_ONEREQ_find(st, val) SKM_sk_find(OCSP_ONEREQ, (st), (val))
# define sk_OCSP_ONEREQ_find_ex(st, val) SKM_sk_find_ex(OCSP_ONEREQ, (st), (val))
# define sk_OCSP_ONEREQ_delete(st, i) SKM_sk_delete(OCSP_ONEREQ, (st), (i))
# define sk_OCSP_ONEREQ_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_ONEREQ, (st), (ptr))
# define sk_OCSP_ONEREQ_insert(st, val, i) SKM_sk_insert(OCSP_ONEREQ, (st), (val), (i))
# define sk_OCSP_ONEREQ_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_ONEREQ, (st), (cmp))
# define sk_OCSP_ONEREQ_dup(st) SKM_sk_dup(OCSP_ONEREQ, st)
# define sk_OCSP_ONEREQ_pop_free(st, free_func) SKM_sk_pop_free(OCSP_ONEREQ, (st), (free_func))
# define sk_OCSP_ONEREQ_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(OCSP_ONEREQ, (st), (copy_func), (free_func))
# define sk_OCSP_ONEREQ_shift(st) SKM_sk_shift(OCSP_ONEREQ, (st))
# define sk_OCSP_ONEREQ_pop(st) SKM_sk_pop(OCSP_ONEREQ, (st))
# define sk_OCSP_ONEREQ_sort(st) SKM_sk_sort(OCSP_ONEREQ, (st))
# define sk_OCSP_ONEREQ_is_sorted(st) SKM_sk_is_sorted(OCSP_ONEREQ, (st))
# define sk_OCSP_RESPID_new(cmp) SKM_sk_new(OCSP_RESPID, (cmp))
# define sk_OCSP_RESPID_new_null() SKM_sk_new_null(OCSP_RESPID)
# define sk_OCSP_RESPID_free(st) SKM_sk_free(OCSP_RESPID, (st))
# define sk_OCSP_RESPID_num(st) SKM_sk_num(OCSP_RESPID, (st))
# define sk_OCSP_RESPID_value(st, i) SKM_sk_value(OCSP_RESPID, (st), (i))
# define sk_OCSP_RESPID_set(st, i, val) SKM_sk_set(OCSP_RESPID, (st), (i), (val))
# define sk_OCSP_RESPID_zero(st) SKM_sk_zero(OCSP_RESPID, (st))
# define sk_OCSP_RESPID_push(st, val) SKM_sk_push(OCSP_RESPID, (st), (val))
# define sk_OCSP_RESPID_unshift(st, val) SKM_sk_unshift(OCSP_RESPID, (st), (val))
# define sk_OCSP_RESPID_find(st, val) SKM_sk_find(OCSP_RESPID, (st), (val))
# define sk_OCSP_RESPID_find_ex(st, val) SKM_sk_find_ex(OCSP_RESPID, (st), (val))
# define sk_OCSP_RESPID_delete(st, i) SKM_sk_delete(OCSP_RESPID, (st), (i))
# define sk_OCSP_RESPID_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_RESPID, (st), (ptr))
# define sk_OCSP_RESPID_insert(st, val, i) SKM_sk_insert(OCSP_RESPID, (st), (val), (i))
# define sk_OCSP_RESPID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_RESPID, (st), (cmp))
# define sk_OCSP_RESPID_dup(st) SKM_sk_dup(OCSP_RESPID, st)
# define sk_OCSP_RESPID_pop_free(st, free_func) SKM_sk_pop_free(OCSP_RESPID, (st), (free_func))
# define sk_OCSP_RESPID_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(OCSP_RESPID, (st), (copy_func), (free_func))
# define sk_OCSP_RESPID_shift(st) SKM_sk_shift(OCSP_RESPID, (st))
# define sk_OCSP_RESPID_pop(st) SKM_sk_pop(OCSP_RESPID, (st))
# define sk_OCSP_RESPID_sort(st) SKM_sk_sort(OCSP_RESPID, (st))
# define sk_OCSP_RESPID_is_sorted(st) SKM_sk_is_sorted(OCSP_RESPID, (st))
# define sk_OCSP_SINGLERESP_new(cmp) SKM_sk_new(OCSP_SINGLERESP, (cmp))
# define sk_OCSP_SINGLERESP_new_null() SKM_sk_new_null(OCSP_SINGLERESP)
# define sk_OCSP_SINGLERESP_free(st) SKM_sk_free(OCSP_SINGLERESP, (st))
# define sk_OCSP_SINGLERESP_num(st) SKM_sk_num(OCSP_SINGLERESP, (st))
# define sk_OCSP_SINGLERESP_value(st, i) SKM_sk_value(OCSP_SINGLERESP, (st), (i))
# define sk_OCSP_SINGLERESP_set(st, i, val) SKM_sk_set(OCSP_SINGLERESP, (st), (i), (val))
# define sk_OCSP_SINGLERESP_zero(st) SKM_sk_zero(OCSP_SINGLERESP, (st))
# define sk_OCSP_SINGLERESP_push(st, val) SKM_sk_push(OCSP_SINGLERESP, (st), (val))
# define sk_OCSP_SINGLERESP_unshift(st, val) SKM_sk_unshift(OCSP_SINGLERESP, (st), (val))
# define sk_OCSP_SINGLERESP_find(st, val) SKM_sk_find(OCSP_SINGLERESP, (st), (val))
# define sk_OCSP_SINGLERESP_find_ex(st, val) SKM_sk_find_ex(OCSP_SINGLERESP, (st), (val))
# define sk_OCSP_SINGLERESP_delete(st, i) SKM_sk_delete(OCSP_SINGLERESP, (st), (i))
# define sk_OCSP_SINGLERESP_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_SINGLERESP, (st), (ptr))
# define sk_OCSP_SINGLERESP_insert(st, val, i) SKM_sk_insert(OCSP_SINGLERESP, (st), (val), (i))
# define sk_OCSP_SINGLERESP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_SINGLERESP, (st), (cmp))
# define sk_OCSP_SINGLERESP_dup(st) SKM_sk_dup(OCSP_SINGLERESP, st)
# define sk_OCSP_SINGLERESP_pop_free(st, free_func) SKM_sk_pop_free(OCSP_SINGLERESP, (st), (free_func))
# define sk_OCSP_SINGLERESP_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(OCSP_SINGLERESP, (st), (copy_func), (free_func))
# define sk_OCSP_SINGLERESP_shift(st) SKM_sk_shift(OCSP_SINGLERESP, (st))
# define sk_OCSP_SINGLERESP_pop(st) SKM_sk_pop(OCSP_SINGLERESP, (st))
# define sk_OCSP_SINGLERESP_sort(st) SKM_sk_sort(OCSP_SINGLERESP, (st))
# define sk_OCSP_SINGLERESP_is_sorted(st) SKM_sk_is_sorted(OCSP_SINGLERESP, (st))
# define sk_PKCS12_SAFEBAG_new(cmp) SKM_sk_new(PKCS12_SAFEBAG, (cmp))
# define sk_PKCS12_SAFEBAG_new_null() SKM_sk_new_null(PKCS12_SAFEBAG)
# define sk_PKCS12_SAFEBAG_free(st) SKM_sk_free(PKCS12_SAFEBAG, (st))
# define sk_PKCS12_SAFEBAG_num(st) SKM_sk_num(PKCS12_SAFEBAG, (st))
# define sk_PKCS12_SAFEBAG_value(st, i) SKM_sk_value(PKCS12_SAFEBAG, (st), (i))
# define sk_PKCS12_SAFEBAG_set(st, i, val) SKM_sk_set(PKCS12_SAFEBAG, (st), (i), (val))
# define sk_PKCS12_SAFEBAG_zero(st) SKM_sk_zero(PKCS12_SAFEBAG, (st))
# define sk_PKCS12_SAFEBAG_push(st, val) SKM_sk_push(PKCS12_SAFEBAG, (st), (val))
# define sk_PKCS12_SAFEBAG_unshift(st, val) SKM_sk_unshift(PKCS12_SAFEBAG, (st), (val))
# define sk_PKCS12_SAFEBAG_find(st, val) SKM_sk_find(PKCS12_SAFEBAG, (st), (val))
# define sk_PKCS12_SAFEBAG_find_ex(st, val) SKM_sk_find_ex(PKCS12_SAFEBAG, (st), (val))
# define sk_PKCS12_SAFEBAG_delete(st, i) SKM_sk_delete(PKCS12_SAFEBAG, (st), (i))
# define sk_PKCS12_SAFEBAG_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS12_SAFEBAG, (st), (ptr))
# define sk_PKCS12_SAFEBAG_insert(st, val, i) SKM_sk_insert(PKCS12_SAFEBAG, (st), (val), (i))
# define sk_PKCS12_SAFEBAG_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS12_SAFEBAG, (st), (cmp))
# define sk_PKCS12_SAFEBAG_dup(st) SKM_sk_dup(PKCS12_SAFEBAG, st)
# define sk_PKCS12_SAFEBAG_pop_free(st, free_func) SKM_sk_pop_free(PKCS12_SAFEBAG, (st), (free_func))
# define sk_PKCS12_SAFEBAG_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(PKCS12_SAFEBAG, (st), (copy_func), (free_func))
# define sk_PKCS12_SAFEBAG_shift(st) SKM_sk_shift(PKCS12_SAFEBAG, (st))
# define sk_PKCS12_SAFEBAG_pop(st) SKM_sk_pop(PKCS12_SAFEBAG, (st))
# define sk_PKCS12_SAFEBAG_sort(st) SKM_sk_sort(PKCS12_SAFEBAG, (st))
# define sk_PKCS12_SAFEBAG_is_sorted(st) SKM_sk_is_sorted(PKCS12_SAFEBAG, (st))
# define sk_PKCS7_new(cmp) SKM_sk_new(PKCS7, (cmp))
# define sk_PKCS7_new_null() SKM_sk_new_null(PKCS7)
# define sk_PKCS7_free(st) SKM_sk_free(PKCS7, (st))
# define sk_PKCS7_num(st) SKM_sk_num(PKCS7, (st))
# define sk_PKCS7_value(st, i) SKM_sk_value(PKCS7, (st), (i))
# define sk_PKCS7_set(st, i, val) SKM_sk_set(PKCS7, (st), (i), (val))
# define sk_PKCS7_zero(st) SKM_sk_zero(PKCS7, (st))
# define sk_PKCS7_push(st, val) SKM_sk_push(PKCS7, (st), (val))
# define sk_PKCS7_unshift(st, val) SKM_sk_unshift(PKCS7, (st), (val))
# define sk_PKCS7_find(st, val) SKM_sk_find(PKCS7, (st), (val))
# define sk_PKCS7_find_ex(st, val) SKM_sk_find_ex(PKCS7, (st), (val))
# define sk_PKCS7_delete(st, i) SKM_sk_delete(PKCS7, (st), (i))
# define sk_PKCS7_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7, (st), (ptr))
# define sk_PKCS7_insert(st, val, i) SKM_sk_insert(PKCS7, (st), (val), (i))
# define sk_PKCS7_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7, (st), (cmp))
# define sk_PKCS7_dup(st) SKM_sk_dup(PKCS7, st)
# define sk_PKCS7_pop_free(st, free_func) SKM_sk_pop_free(PKCS7, (st), (free_func))
# define sk_PKCS7_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(PKCS7, (st), (copy_func), (free_func))
# define sk_PKCS7_shift(st) SKM_sk_shift(PKCS7, (st))
# define sk_PKCS7_pop(st) SKM_sk_pop(PKCS7, (st))
# define sk_PKCS7_sort(st) SKM_sk_sort(PKCS7, (st))
# define sk_PKCS7_is_sorted(st) SKM_sk_is_sorted(PKCS7, (st))
# define sk_PKCS7_RECIP_INFO_new(cmp) SKM_sk_new(PKCS7_RECIP_INFO, (cmp))
# define sk_PKCS7_RECIP_INFO_new_null() SKM_sk_new_null(PKCS7_RECIP_INFO)
# define sk_PKCS7_RECIP_INFO_free(st) SKM_sk_free(PKCS7_RECIP_INFO, (st))
# define sk_PKCS7_RECIP_INFO_num(st) SKM_sk_num(PKCS7_RECIP_INFO, (st))
# define sk_PKCS7_RECIP_INFO_value(st, i) SKM_sk_value(PKCS7_RECIP_INFO, (st), (i))
# define sk_PKCS7_RECIP_INFO_set(st, i, val) SKM_sk_set(PKCS7_RECIP_INFO, (st), (i), (val))
# define sk_PKCS7_RECIP_INFO_zero(st) SKM_sk_zero(PKCS7_RECIP_INFO, (st))
# define sk_PKCS7_RECIP_INFO_push(st, val) SKM_sk_push(PKCS7_RECIP_INFO, (st), (val))
# define sk_PKCS7_RECIP_INFO_unshift(st, val) SKM_sk_unshift(PKCS7_RECIP_INFO, (st), (val))
# define sk_PKCS7_RECIP_INFO_find(st, val) SKM_sk_find(PKCS7_RECIP_INFO, (st), (val))
# define sk_PKCS7_RECIP_INFO_find_ex(st, val) SKM_sk_find_ex(PKCS7_RECIP_INFO, (st), (val))
# define sk_PKCS7_RECIP_INFO_delete(st, i) SKM_sk_delete(PKCS7_RECIP_INFO, (st), (i))
# define sk_PKCS7_RECIP_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7_RECIP_INFO, (st), (ptr))
# define sk_PKCS7_RECIP_INFO_insert(st, val, i) SKM_sk_insert(PKCS7_RECIP_INFO, (st), (val), (i))
# define sk_PKCS7_RECIP_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7_RECIP_INFO, (st), (cmp))
# define sk_PKCS7_RECIP_INFO_dup(st) SKM_sk_dup(PKCS7_RECIP_INFO, st)
# define sk_PKCS7_RECIP_INFO_pop_free(st, free_func) SKM_sk_pop_free(PKCS7_RECIP_INFO, (st), (free_func))
# define sk_PKCS7_RECIP_INFO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(PKCS7_RECIP_INFO, (st), (copy_func), (free_func))
# define sk_PKCS7_RECIP_INFO_shift(st) SKM_sk_shift(PKCS7_RECIP_INFO, (st))
# define sk_PKCS7_RECIP_INFO_pop(st) SKM_sk_pop(PKCS7_RECIP_INFO, (st))
# define sk_PKCS7_RECIP_INFO_sort(st) SKM_sk_sort(PKCS7_RECIP_INFO, (st))
# define sk_PKCS7_RECIP_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_RECIP_INFO, (st))
# define sk_PKCS7_SIGNER_INFO_new(cmp) SKM_sk_new(PKCS7_SIGNER_INFO, (cmp))
# define sk_PKCS7_SIGNER_INFO_new_null() SKM_sk_new_null(PKCS7_SIGNER_INFO)
# define sk_PKCS7_SIGNER_INFO_free(st) SKM_sk_free(PKCS7_SIGNER_INFO, (st))
# define sk_PKCS7_SIGNER_INFO_num(st) SKM_sk_num(PKCS7_SIGNER_INFO, (st))
# define sk_PKCS7_SIGNER_INFO_value(st, i) SKM_sk_value(PKCS7_SIGNER_INFO, (st), (i))
# define sk_PKCS7_SIGNER_INFO_set(st, i, val) SKM_sk_set(PKCS7_SIGNER_INFO, (st), (i), (val))
# define sk_PKCS7_SIGNER_INFO_zero(st) SKM_sk_zero(PKCS7_SIGNER_INFO, (st))
# define sk_PKCS7_SIGNER_INFO_push(st, val) SKM_sk_push(PKCS7_SIGNER_INFO, (st), (val))
# define sk_PKCS7_SIGNER_INFO_unshift(st, val) SKM_sk_unshift(PKCS7_SIGNER_INFO, (st), (val))
# define sk_PKCS7_SIGNER_INFO_find(st, val) SKM_sk_find(PKCS7_SIGNER_INFO, (st), (val))
# define sk_PKCS7_SIGNER_INFO_find_ex(st, val) SKM_sk_find_ex(PKCS7_SIGNER_INFO, (st), (val))
# define sk_PKCS7_SIGNER_INFO_delete(st, i) SKM_sk_delete(PKCS7_SIGNER_INFO, (st), (i))
# define sk_PKCS7_SIGNER_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7_SIGNER_INFO, (st), (ptr))
# define sk_PKCS7_SIGNER_INFO_insert(st, val, i) SKM_sk_insert(PKCS7_SIGNER_INFO, (st), (val), (i))
# define sk_PKCS7_SIGNER_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7_SIGNER_INFO, (st), (cmp))
# define sk_PKCS7_SIGNER_INFO_dup(st) SKM_sk_dup(PKCS7_SIGNER_INFO, st)
# define sk_PKCS7_SIGNER_INFO_pop_free(st, free_func) SKM_sk_pop_free(PKCS7_SIGNER_INFO, (st), (free_func))
# define sk_PKCS7_SIGNER_INFO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(PKCS7_SIGNER_INFO, (st), (copy_func), (free_func))
# define sk_PKCS7_SIGNER_INFO_shift(st) SKM_sk_shift(PKCS7_SIGNER_INFO, (st))
# define sk_PKCS7_SIGNER_INFO_pop(st) SKM_sk_pop(PKCS7_SIGNER_INFO, (st))
# define sk_PKCS7_SIGNER_INFO_sort(st) SKM_sk_sort(PKCS7_SIGNER_INFO, (st))
# define sk_PKCS7_SIGNER_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_SIGNER_INFO, (st))
# define sk_POLICYINFO_new(cmp) SKM_sk_new(POLICYINFO, (cmp))
# define sk_POLICYINFO_new_null() SKM_sk_new_null(POLICYINFO)
# define sk_POLICYINFO_free(st) SKM_sk_free(POLICYINFO, (st))
# define sk_POLICYINFO_num(st) SKM_sk_num(POLICYINFO, (st))
# define sk_POLICYINFO_value(st, i) SKM_sk_value(POLICYINFO, (st), (i))
# define sk_POLICYINFO_set(st, i, val) SKM_sk_set(POLICYINFO, (st), (i), (val))
# define sk_POLICYINFO_zero(st) SKM_sk_zero(POLICYINFO, (st))
# define sk_POLICYINFO_push(st, val) SKM_sk_push(POLICYINFO, (st), (val))
# define sk_POLICYINFO_unshift(st, val) SKM_sk_unshift(POLICYINFO, (st), (val))
# define sk_POLICYINFO_find(st, val) SKM_sk_find(POLICYINFO, (st), (val))
# define sk_POLICYINFO_find_ex(st, val) SKM_sk_find_ex(POLICYINFO, (st), (val))
# define sk_POLICYINFO_delete(st, i) SKM_sk_delete(POLICYINFO, (st), (i))
# define sk_POLICYINFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICYINFO, (st), (ptr))
# define sk_POLICYINFO_insert(st, val, i) SKM_sk_insert(POLICYINFO, (st), (val), (i))
# define sk_POLICYINFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICYINFO, (st), (cmp))
# define sk_POLICYINFO_dup(st) SKM_sk_dup(POLICYINFO, st)
# define sk_POLICYINFO_pop_free(st, free_func) SKM_sk_pop_free(POLICYINFO, (st), (free_func))
# define sk_POLICYINFO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(POLICYINFO, (st), (copy_func), (free_func))
# define sk_POLICYINFO_shift(st) SKM_sk_shift(POLICYINFO, (st))
# define sk_POLICYINFO_pop(st) SKM_sk_pop(POLICYINFO, (st))
# define sk_POLICYINFO_sort(st) SKM_sk_sort(POLICYINFO, (st))
# define sk_POLICYINFO_is_sorted(st) SKM_sk_is_sorted(POLICYINFO, (st))
# define sk_POLICYQUALINFO_new(cmp) SKM_sk_new(POLICYQUALINFO, (cmp))
# define sk_POLICYQUALINFO_new_null() SKM_sk_new_null(POLICYQUALINFO)
# define sk_POLICYQUALINFO_free(st) SKM_sk_free(POLICYQUALINFO, (st))
# define sk_POLICYQUALINFO_num(st) SKM_sk_num(POLICYQUALINFO, (st))
# define sk_POLICYQUALINFO_value(st, i) SKM_sk_value(POLICYQUALINFO, (st), (i))
# define sk_POLICYQUALINFO_set(st, i, val) SKM_sk_set(POLICYQUALINFO, (st), (i), (val))
# define sk_POLICYQUALINFO_zero(st) SKM_sk_zero(POLICYQUALINFO, (st))
# define sk_POLICYQUALINFO_push(st, val) SKM_sk_push(POLICYQUALINFO, (st), (val))
# define sk_POLICYQUALINFO_unshift(st, val) SKM_sk_unshift(POLICYQUALINFO, (st), (val))
# define sk_POLICYQUALINFO_find(st, val) SKM_sk_find(POLICYQUALINFO, (st), (val))
# define sk_POLICYQUALINFO_find_ex(st, val) SKM_sk_find_ex(POLICYQUALINFO, (st), (val))
# define sk_POLICYQUALINFO_delete(st, i) SKM_sk_delete(POLICYQUALINFO, (st), (i))
# define sk_POLICYQUALINFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICYQUALINFO, (st), (ptr))
# define sk_POLICYQUALINFO_insert(st, val, i) SKM_sk_insert(POLICYQUALINFO, (st), (val), (i))
# define sk_POLICYQUALINFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICYQUALINFO, (st), (cmp))
# define sk_POLICYQUALINFO_dup(st) SKM_sk_dup(POLICYQUALINFO, st)
# define sk_POLICYQUALINFO_pop_free(st, free_func) SKM_sk_pop_free(POLICYQUALINFO, (st), (free_func))
# define sk_POLICYQUALINFO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(POLICYQUALINFO, (st), (copy_func), (free_func))
# define sk_POLICYQUALINFO_shift(st) SKM_sk_shift(POLICYQUALINFO, (st))
# define sk_POLICYQUALINFO_pop(st) SKM_sk_pop(POLICYQUALINFO, (st))
# define sk_POLICYQUALINFO_sort(st) SKM_sk_sort(POLICYQUALINFO, (st))
# define sk_POLICYQUALINFO_is_sorted(st) SKM_sk_is_sorted(POLICYQUALINFO, (st))
# define sk_POLICY_MAPPING_new(cmp) SKM_sk_new(POLICY_MAPPING, (cmp))
# define sk_POLICY_MAPPING_new_null() SKM_sk_new_null(POLICY_MAPPING)
# define sk_POLICY_MAPPING_free(st) SKM_sk_free(POLICY_MAPPING, (st))
# define sk_POLICY_MAPPING_num(st) SKM_sk_num(POLICY_MAPPING, (st))
# define sk_POLICY_MAPPING_value(st, i) SKM_sk_value(POLICY_MAPPING, (st), (i))
# define sk_POLICY_MAPPING_set(st, i, val) SKM_sk_set(POLICY_MAPPING, (st), (i), (val))
# define sk_POLICY_MAPPING_zero(st) SKM_sk_zero(POLICY_MAPPING, (st))
# define sk_POLICY_MAPPING_push(st, val) SKM_sk_push(POLICY_MAPPING, (st), (val))
# define sk_POLICY_MAPPING_unshift(st, val) SKM_sk_unshift(POLICY_MAPPING, (st), (val))
# define sk_POLICY_MAPPING_find(st, val) SKM_sk_find(POLICY_MAPPING, (st), (val))
# define sk_POLICY_MAPPING_find_ex(st, val) SKM_sk_find_ex(POLICY_MAPPING, (st), (val))
# define sk_POLICY_MAPPING_delete(st, i) SKM_sk_delete(POLICY_MAPPING, (st), (i))
# define sk_POLICY_MAPPING_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICY_MAPPING, (st), (ptr))
# define sk_POLICY_MAPPING_insert(st, val, i) SKM_sk_insert(POLICY_MAPPING, (st), (val), (i))
# define sk_POLICY_MAPPING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICY_MAPPING, (st), (cmp))
# define sk_POLICY_MAPPING_dup(st) SKM_sk_dup(POLICY_MAPPING, st)
# define sk_POLICY_MAPPING_pop_free(st, free_func) SKM_sk_pop_free(POLICY_MAPPING, (st), (free_func))
# define sk_POLICY_MAPPING_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(POLICY_MAPPING, (st), (copy_func), (free_func))
# define sk_POLICY_MAPPING_shift(st) SKM_sk_shift(POLICY_MAPPING, (st))
# define sk_POLICY_MAPPING_pop(st) SKM_sk_pop(POLICY_MAPPING, (st))
# define sk_POLICY_MAPPING_sort(st) SKM_sk_sort(POLICY_MAPPING, (st))
# define sk_POLICY_MAPPING_is_sorted(st) SKM_sk_is_sorted(POLICY_MAPPING, (st))
# define sk_SCT_new(cmp) SKM_sk_new(SCT, (cmp))
# define sk_SCT_new_null() SKM_sk_new_null(SCT)
# define sk_SCT_free(st) SKM_sk_free(SCT, (st))
# define sk_SCT_num(st) SKM_sk_num(SCT, (st))
# define sk_SCT_value(st, i) SKM_sk_value(SCT, (st), (i))
# define sk_SCT_set(st, i, val) SKM_sk_set(SCT, (st), (i), (val))
# define sk_SCT_zero(st) SKM_sk_zero(SCT, (st))
# define sk_SCT_push(st, val) SKM_sk_push(SCT, (st), (val))
# define sk_SCT_unshift(st, val) SKM_sk_unshift(SCT, (st), (val))
# define sk_SCT_find(st, val) SKM_sk_find(SCT, (st), (val))
# define sk_SCT_find_ex(st, val) SKM_sk_find_ex(SCT, (st), (val))
# define sk_SCT_delete(st, i) SKM_sk_delete(SCT, (st), (i))
# define sk_SCT_delete_ptr(st, ptr) SKM_sk_delete_ptr(SCT, (st), (ptr))
# define sk_SCT_insert(st, val, i) SKM_sk_insert(SCT, (st), (val), (i))
# define sk_SCT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SCT, (st), (cmp))
# define sk_SCT_dup(st) SKM_sk_dup(SCT, st)
# define sk_SCT_pop_free(st, free_func) SKM_sk_pop_free(SCT, (st), (free_func))
# define sk_SCT_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SCT, (st), (copy_func), (free_func))
# define sk_SCT_shift(st) SKM_sk_shift(SCT, (st))
# define sk_SCT_pop(st) SKM_sk_pop(SCT, (st))
# define sk_SCT_sort(st) SKM_sk_sort(SCT, (st))
# define sk_SCT_is_sorted(st) SKM_sk_is_sorted(SCT, (st))
# define sk_SRP_gN_new(cmp) SKM_sk_new(SRP_gN, (cmp))
# define sk_SRP_gN_new_null() SKM_sk_new_null(SRP_gN)
# define sk_SRP_gN_free(st) SKM_sk_free(SRP_gN, (st))
# define sk_SRP_gN_num(st) SKM_sk_num(SRP_gN, (st))
# define sk_SRP_gN_value(st, i) SKM_sk_value(SRP_gN, (st), (i))
# define sk_SRP_gN_set(st, i, val) SKM_sk_set(SRP_gN, (st), (i), (val))
# define sk_SRP_gN_zero(st) SKM_sk_zero(SRP_gN, (st))
# define sk_SRP_gN_push(st, val) SKM_sk_push(SRP_gN, (st), (val))
# define sk_SRP_gN_unshift(st, val) SKM_sk_unshift(SRP_gN, (st), (val))
# define sk_SRP_gN_find(st, val) SKM_sk_find(SRP_gN, (st), (val))
# define sk_SRP_gN_find_ex(st, val) SKM_sk_find_ex(SRP_gN, (st), (val))
# define sk_SRP_gN_delete(st, i) SKM_sk_delete(SRP_gN, (st), (i))
# define sk_SRP_gN_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_gN, (st), (ptr))
# define sk_SRP_gN_insert(st, val, i) SKM_sk_insert(SRP_gN, (st), (val), (i))
# define sk_SRP_gN_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_gN, (st), (cmp))
# define sk_SRP_gN_dup(st) SKM_sk_dup(SRP_gN, st)
# define sk_SRP_gN_pop_free(st, free_func) SKM_sk_pop_free(SRP_gN, (st), (free_func))
# define sk_SRP_gN_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SRP_gN, (st), (copy_func), (free_func))
# define sk_SRP_gN_shift(st) SKM_sk_shift(SRP_gN, (st))
# define sk_SRP_gN_pop(st) SKM_sk_pop(SRP_gN, (st))
# define sk_SRP_gN_sort(st) SKM_sk_sort(SRP_gN, (st))
# define sk_SRP_gN_is_sorted(st) SKM_sk_is_sorted(SRP_gN, (st))
# define sk_SRP_gN_cache_new(cmp) SKM_sk_new(SRP_gN_cache, (cmp))
# define sk_SRP_gN_cache_new_null() SKM_sk_new_null(SRP_gN_cache)
# define sk_SRP_gN_cache_free(st) SKM_sk_free(SRP_gN_cache, (st))
# define sk_SRP_gN_cache_num(st) SKM_sk_num(SRP_gN_cache, (st))
# define sk_SRP_gN_cache_value(st, i) SKM_sk_value(SRP_gN_cache, (st), (i))
# define sk_SRP_gN_cache_set(st, i, val) SKM_sk_set(SRP_gN_cache, (st), (i), (val))
# define sk_SRP_gN_cache_zero(st) SKM_sk_zero(SRP_gN_cache, (st))
# define sk_SRP_gN_cache_push(st, val) SKM_sk_push(SRP_gN_cache, (st), (val))
# define sk_SRP_gN_cache_unshift(st, val) SKM_sk_unshift(SRP_gN_cache, (st), (val))
# define sk_SRP_gN_cache_find(st, val) SKM_sk_find(SRP_gN_cache, (st), (val))
# define sk_SRP_gN_cache_find_ex(st, val) SKM_sk_find_ex(SRP_gN_cache, (st), (val))
# define sk_SRP_gN_cache_delete(st, i) SKM_sk_delete(SRP_gN_cache, (st), (i))
# define sk_SRP_gN_cache_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_gN_cache, (st), (ptr))
# define sk_SRP_gN_cache_insert(st, val, i) SKM_sk_insert(SRP_gN_cache, (st), (val), (i))
# define sk_SRP_gN_cache_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_gN_cache, (st), (cmp))
# define sk_SRP_gN_cache_dup(st) SKM_sk_dup(SRP_gN_cache, st)
# define sk_SRP_gN_cache_pop_free(st, free_func) SKM_sk_pop_free(SRP_gN_cache, (st), (free_func))
# define sk_SRP_gN_cache_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SRP_gN_cache, (st), (copy_func), (free_func))
# define sk_SRP_gN_cache_shift(st) SKM_sk_shift(SRP_gN_cache, (st))
# define sk_SRP_gN_cache_pop(st) SKM_sk_pop(SRP_gN_cache, (st))
# define sk_SRP_gN_cache_sort(st) SKM_sk_sort(SRP_gN_cache, (st))
# define sk_SRP_gN_cache_is_sorted(st) SKM_sk_is_sorted(SRP_gN_cache, (st))
# define sk_SRP_user_pwd_new(cmp) SKM_sk_new(SRP_user_pwd, (cmp))
# define sk_SRP_user_pwd_new_null() SKM_sk_new_null(SRP_user_pwd)
# define sk_SRP_user_pwd_free(st) SKM_sk_free(SRP_user_pwd, (st))
# define sk_SRP_user_pwd_num(st) SKM_sk_num(SRP_user_pwd, (st))
# define sk_SRP_user_pwd_value(st, i) SKM_sk_value(SRP_user_pwd, (st), (i))
# define sk_SRP_user_pwd_set(st, i, val) SKM_sk_set(SRP_user_pwd, (st), (i), (val))
# define sk_SRP_user_pwd_zero(st) SKM_sk_zero(SRP_user_pwd, (st))
# define sk_SRP_user_pwd_push(st, val) SKM_sk_push(SRP_user_pwd, (st), (val))
# define sk_SRP_user_pwd_unshift(st, val) SKM_sk_unshift(SRP_user_pwd, (st), (val))
# define sk_SRP_user_pwd_find(st, val) SKM_sk_find(SRP_user_pwd, (st), (val))
# define sk_SRP_user_pwd_find_ex(st, val) SKM_sk_find_ex(SRP_user_pwd, (st), (val))
# define sk_SRP_user_pwd_delete(st, i) SKM_sk_delete(SRP_user_pwd, (st), (i))
# define sk_SRP_user_pwd_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_user_pwd, (st), (ptr))
# define sk_SRP_user_pwd_insert(st, val, i) SKM_sk_insert(SRP_user_pwd, (st), (val), (i))
# define sk_SRP_user_pwd_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_user_pwd, (st), (cmp))
# define sk_SRP_user_pwd_dup(st) SKM_sk_dup(SRP_user_pwd, st)
# define sk_SRP_user_pwd_pop_free(st, free_func) SKM_sk_pop_free(SRP_user_pwd, (st), (free_func))
# define sk_SRP_user_pwd_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SRP_user_pwd, (st), (copy_func), (free_func))
# define sk_SRP_user_pwd_shift(st) SKM_sk_shift(SRP_user_pwd, (st))
# define sk_SRP_user_pwd_pop(st) SKM_sk_pop(SRP_user_pwd, (st))
# define sk_SRP_user_pwd_sort(st) SKM_sk_sort(SRP_user_pwd, (st))
# define sk_SRP_user_pwd_is_sorted(st) SKM_sk_is_sorted(SRP_user_pwd, (st))
# define sk_SRTP_PROTECTION_PROFILE_new(cmp) SKM_sk_new(SRTP_PROTECTION_PROFILE, (cmp))
# define sk_SRTP_PROTECTION_PROFILE_new_null() SKM_sk_new_null(SRTP_PROTECTION_PROFILE)
# define sk_SRTP_PROTECTION_PROFILE_free(st) SKM_sk_free(SRTP_PROTECTION_PROFILE, (st))
# define sk_SRTP_PROTECTION_PROFILE_num(st) SKM_sk_num(SRTP_PROTECTION_PROFILE, (st))
# define sk_SRTP_PROTECTION_PROFILE_value(st, i) SKM_sk_value(SRTP_PROTECTION_PROFILE, (st), (i))
# define sk_SRTP_PROTECTION_PROFILE_set(st, i, val) SKM_sk_set(SRTP_PROTECTION_PROFILE, (st), (i), (val))
# define sk_SRTP_PROTECTION_PROFILE_zero(st) SKM_sk_zero(SRTP_PROTECTION_PROFILE, (st))
# define sk_SRTP_PROTECTION_PROFILE_push(st, val) SKM_sk_push(SRTP_PROTECTION_PROFILE, (st), (val))
# define sk_SRTP_PROTECTION_PROFILE_unshift(st, val) SKM_sk_unshift(SRTP_PROTECTION_PROFILE, (st), (val))
# define sk_SRTP_PROTECTION_PROFILE_find(st, val) SKM_sk_find(SRTP_PROTECTION_PROFILE, (st), (val))
# define sk_SRTP_PROTECTION_PROFILE_find_ex(st, val) SKM_sk_find_ex(SRTP_PROTECTION_PROFILE, (st), (val))
# define sk_SRTP_PROTECTION_PROFILE_delete(st, i) SKM_sk_delete(SRTP_PROTECTION_PROFILE, (st), (i))
# define sk_SRTP_PROTECTION_PROFILE_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRTP_PROTECTION_PROFILE, (st), (ptr))
# define sk_SRTP_PROTECTION_PROFILE_insert(st, val, i) SKM_sk_insert(SRTP_PROTECTION_PROFILE, (st), (val), (i))
# define sk_SRTP_PROTECTION_PROFILE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRTP_PROTECTION_PROFILE, (st), (cmp))
# define sk_SRTP_PROTECTION_PROFILE_dup(st) SKM_sk_dup(SRTP_PROTECTION_PROFILE, st)
# define sk_SRTP_PROTECTION_PROFILE_pop_free(st, free_func) SKM_sk_pop_free(SRTP_PROTECTION_PROFILE, (st), (free_func))
# define sk_SRTP_PROTECTION_PROFILE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SRTP_PROTECTION_PROFILE, (st), (copy_func), (free_func))
# define sk_SRTP_PROTECTION_PROFILE_shift(st) SKM_sk_shift(SRTP_PROTECTION_PROFILE, (st))
# define sk_SRTP_PROTECTION_PROFILE_pop(st) SKM_sk_pop(SRTP_PROTECTION_PROFILE, (st))
# define sk_SRTP_PROTECTION_PROFILE_sort(st) SKM_sk_sort(SRTP_PROTECTION_PROFILE, (st))
# define sk_SRTP_PROTECTION_PROFILE_is_sorted(st) SKM_sk_is_sorted(SRTP_PROTECTION_PROFILE, (st))
# define sk_SSL_CIPHER_new(cmp) SKM_sk_new(SSL_CIPHER, (cmp))
# define sk_SSL_CIPHER_new_null() SKM_sk_new_null(SSL_CIPHER)
# define sk_SSL_CIPHER_free(st) SKM_sk_free(SSL_CIPHER, (st))
# define sk_SSL_CIPHER_num(st) SKM_sk_num(SSL_CIPHER, (st))
# define sk_SSL_CIPHER_value(st, i) SKM_sk_value(SSL_CIPHER, (st), (i))
# define sk_SSL_CIPHER_set(st, i, val) SKM_sk_set(SSL_CIPHER, (st), (i), (val))
# define sk_SSL_CIPHER_zero(st) SKM_sk_zero(SSL_CIPHER, (st))
# define sk_SSL_CIPHER_push(st, val) SKM_sk_push(SSL_CIPHER, (st), (val))
# define sk_SSL_CIPHER_unshift(st, val) SKM_sk_unshift(SSL_CIPHER, (st), (val))
# define sk_SSL_CIPHER_find(st, val) SKM_sk_find(SSL_CIPHER, (st), (val))
# define sk_SSL_CIPHER_find_ex(st, val) SKM_sk_find_ex(SSL_CIPHER, (st), (val))
# define sk_SSL_CIPHER_delete(st, i) SKM_sk_delete(SSL_CIPHER, (st), (i))
# define sk_SSL_CIPHER_delete_ptr(st, ptr) SKM_sk_delete_ptr(SSL_CIPHER, (st), (ptr))
# define sk_SSL_CIPHER_insert(st, val, i) SKM_sk_insert(SSL_CIPHER, (st), (val), (i))
# define sk_SSL_CIPHER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SSL_CIPHER, (st), (cmp))
# define sk_SSL_CIPHER_dup(st) SKM_sk_dup(SSL_CIPHER, st)
# define sk_SSL_CIPHER_pop_free(st, free_func) SKM_sk_pop_free(SSL_CIPHER, (st), (free_func))
# define sk_SSL_CIPHER_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SSL_CIPHER, (st), (copy_func), (free_func))
# define sk_SSL_CIPHER_shift(st) SKM_sk_shift(SSL_CIPHER, (st))
# define sk_SSL_CIPHER_pop(st) SKM_sk_pop(SSL_CIPHER, (st))
# define sk_SSL_CIPHER_sort(st) SKM_sk_sort(SSL_CIPHER, (st))
# define sk_SSL_CIPHER_is_sorted(st) SKM_sk_is_sorted(SSL_CIPHER, (st))
# define sk_SSL_COMP_new(cmp) SKM_sk_new(SSL_COMP, (cmp))
# define sk_SSL_COMP_new_null() SKM_sk_new_null(SSL_COMP)
# define sk_SSL_COMP_free(st) SKM_sk_free(SSL_COMP, (st))
# define sk_SSL_COMP_num(st) SKM_sk_num(SSL_COMP, (st))
# define sk_SSL_COMP_value(st, i) SKM_sk_value(SSL_COMP, (st), (i))
# define sk_SSL_COMP_set(st, i, val) SKM_sk_set(SSL_COMP, (st), (i), (val))
# define sk_SSL_COMP_zero(st) SKM_sk_zero(SSL_COMP, (st))
# define sk_SSL_COMP_push(st, val) SKM_sk_push(SSL_COMP, (st), (val))
# define sk_SSL_COMP_unshift(st, val) SKM_sk_unshift(SSL_COMP, (st), (val))
# define sk_SSL_COMP_find(st, val) SKM_sk_find(SSL_COMP, (st), (val))
# define sk_SSL_COMP_find_ex(st, val) SKM_sk_find_ex(SSL_COMP, (st), (val))
# define sk_SSL_COMP_delete(st, i) SKM_sk_delete(SSL_COMP, (st), (i))
# define sk_SSL_COMP_delete_ptr(st, ptr) SKM_sk_delete_ptr(SSL_COMP, (st), (ptr))
# define sk_SSL_COMP_insert(st, val, i) SKM_sk_insert(SSL_COMP, (st), (val), (i))
# define sk_SSL_COMP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SSL_COMP, (st), (cmp))
# define sk_SSL_COMP_dup(st) SKM_sk_dup(SSL_COMP, st)
# define sk_SSL_COMP_pop_free(st, free_func) SKM_sk_pop_free(SSL_COMP, (st), (free_func))
# define sk_SSL_COMP_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SSL_COMP, (st), (copy_func), (free_func))
# define sk_SSL_COMP_shift(st) SKM_sk_shift(SSL_COMP, (st))
# define sk_SSL_COMP_pop(st) SKM_sk_pop(SSL_COMP, (st))
# define sk_SSL_COMP_sort(st) SKM_sk_sort(SSL_COMP, (st))
# define sk_SSL_COMP_is_sorted(st) SKM_sk_is_sorted(SSL_COMP, (st))
# define sk_STACK_OF_X509_NAME_ENTRY_new(cmp) SKM_sk_new(STACK_OF_X509_NAME_ENTRY, (cmp))
# define sk_STACK_OF_X509_NAME_ENTRY_new_null() SKM_sk_new_null(STACK_OF_X509_NAME_ENTRY)
# define sk_STACK_OF_X509_NAME_ENTRY_free(st) SKM_sk_free(STACK_OF_X509_NAME_ENTRY, (st))
# define sk_STACK_OF_X509_NAME_ENTRY_num(st) SKM_sk_num(STACK_OF_X509_NAME_ENTRY, (st))
# define sk_STACK_OF_X509_NAME_ENTRY_value(st, i) SKM_sk_value(STACK_OF_X509_NAME_ENTRY, (st), (i))
# define sk_STACK_OF_X509_NAME_ENTRY_set(st, i, val) SKM_sk_set(STACK_OF_X509_NAME_ENTRY, (st), (i), (val))
# define sk_STACK_OF_X509_NAME_ENTRY_zero(st) SKM_sk_zero(STACK_OF_X509_NAME_ENTRY, (st))
# define sk_STACK_OF_X509_NAME_ENTRY_push(st, val) SKM_sk_push(STACK_OF_X509_NAME_ENTRY, (st), (val))
# define sk_STACK_OF_X509_NAME_ENTRY_unshift(st, val) SKM_sk_unshift(STACK_OF_X509_NAME_ENTRY, (st), (val))
# define sk_STACK_OF_X509_NAME_ENTRY_find(st, val) SKM_sk_find(STACK_OF_X509_NAME_ENTRY, (st), (val))
# define sk_STACK_OF_X509_NAME_ENTRY_find_ex(st, val) SKM_sk_find_ex(STACK_OF_X509_NAME_ENTRY, (st), (val))
# define sk_STACK_OF_X509_NAME_ENTRY_delete(st, i) SKM_sk_delete(STACK_OF_X509_NAME_ENTRY, (st), (i))
# define sk_STACK_OF_X509_NAME_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(STACK_OF_X509_NAME_ENTRY, (st), (ptr))
# define sk_STACK_OF_X509_NAME_ENTRY_insert(st, val, i) SKM_sk_insert(STACK_OF_X509_NAME_ENTRY, (st), (val), (i))
# define sk_STACK_OF_X509_NAME_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STACK_OF_X509_NAME_ENTRY, (st), (cmp))
# define sk_STACK_OF_X509_NAME_ENTRY_dup(st) SKM_sk_dup(STACK_OF_X509_NAME_ENTRY, st)
# define sk_STACK_OF_X509_NAME_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(STACK_OF_X509_NAME_ENTRY, (st), (free_func))
# define sk_STACK_OF_X509_NAME_ENTRY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(STACK_OF_X509_NAME_ENTRY, (st), (copy_func), (free_func))
# define sk_STACK_OF_X509_NAME_ENTRY_shift(st) SKM_sk_shift(STACK_OF_X509_NAME_ENTRY, (st))
# define sk_STACK_OF_X509_NAME_ENTRY_pop(st) SKM_sk_pop(STACK_OF_X509_NAME_ENTRY, (st))
# define sk_STACK_OF_X509_NAME_ENTRY_sort(st) SKM_sk_sort(STACK_OF_X509_NAME_ENTRY, (st))
# define sk_STACK_OF_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(STACK_OF_X509_NAME_ENTRY, (st))
# define sk_STORE_ATTR_INFO_new(cmp) SKM_sk_new(STORE_ATTR_INFO, (cmp))
# define sk_STORE_ATTR_INFO_new_null() SKM_sk_new_null(STORE_ATTR_INFO)
# define sk_STORE_ATTR_INFO_free(st) SKM_sk_free(STORE_ATTR_INFO, (st))
# define sk_STORE_ATTR_INFO_num(st) SKM_sk_num(STORE_ATTR_INFO, (st))
# define sk_STORE_ATTR_INFO_value(st, i) SKM_sk_value(STORE_ATTR_INFO, (st), (i))
# define sk_STORE_ATTR_INFO_set(st, i, val) SKM_sk_set(STORE_ATTR_INFO, (st), (i), (val))
# define sk_STORE_ATTR_INFO_zero(st) SKM_sk_zero(STORE_ATTR_INFO, (st))
# define sk_STORE_ATTR_INFO_push(st, val) SKM_sk_push(STORE_ATTR_INFO, (st), (val))
# define sk_STORE_ATTR_INFO_unshift(st, val) SKM_sk_unshift(STORE_ATTR_INFO, (st), (val))
# define sk_STORE_ATTR_INFO_find(st, val) SKM_sk_find(STORE_ATTR_INFO, (st), (val))
# define sk_STORE_ATTR_INFO_find_ex(st, val) SKM_sk_find_ex(STORE_ATTR_INFO, (st), (val))
# define sk_STORE_ATTR_INFO_delete(st, i) SKM_sk_delete(STORE_ATTR_INFO, (st), (i))
# define sk_STORE_ATTR_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(STORE_ATTR_INFO, (st), (ptr))
# define sk_STORE_ATTR_INFO_insert(st, val, i) SKM_sk_insert(STORE_ATTR_INFO, (st), (val), (i))
# define sk_STORE_ATTR_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STORE_ATTR_INFO, (st), (cmp))
# define sk_STORE_ATTR_INFO_dup(st) SKM_sk_dup(STORE_ATTR_INFO, st)
# define sk_STORE_ATTR_INFO_pop_free(st, free_func) SKM_sk_pop_free(STORE_ATTR_INFO, (st), (free_func))
# define sk_STORE_ATTR_INFO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(STORE_ATTR_INFO, (st), (copy_func), (free_func))
# define sk_STORE_ATTR_INFO_shift(st) SKM_sk_shift(STORE_ATTR_INFO, (st))
# define sk_STORE_ATTR_INFO_pop(st) SKM_sk_pop(STORE_ATTR_INFO, (st))
# define sk_STORE_ATTR_INFO_sort(st) SKM_sk_sort(STORE_ATTR_INFO, (st))
# define sk_STORE_ATTR_INFO_is_sorted(st) SKM_sk_is_sorted(STORE_ATTR_INFO, (st))
# define sk_STORE_OBJECT_new(cmp) SKM_sk_new(STORE_OBJECT, (cmp))
# define sk_STORE_OBJECT_new_null() SKM_sk_new_null(STORE_OBJECT)
# define sk_STORE_OBJECT_free(st) SKM_sk_free(STORE_OBJECT, (st))
# define sk_STORE_OBJECT_num(st) SKM_sk_num(STORE_OBJECT, (st))
# define sk_STORE_OBJECT_value(st, i) SKM_sk_value(STORE_OBJECT, (st), (i))
# define sk_STORE_OBJECT_set(st, i, val) SKM_sk_set(STORE_OBJECT, (st), (i), (val))
# define sk_STORE_OBJECT_zero(st) SKM_sk_zero(STORE_OBJECT, (st))
# define sk_STORE_OBJECT_push(st, val) SKM_sk_push(STORE_OBJECT, (st), (val))
# define sk_STORE_OBJECT_unshift(st, val) SKM_sk_unshift(STORE_OBJECT, (st), (val))
# define sk_STORE_OBJECT_find(st, val) SKM_sk_find(STORE_OBJECT, (st), (val))
# define sk_STORE_OBJECT_find_ex(st, val) SKM_sk_find_ex(STORE_OBJECT, (st), (val))
# define sk_STORE_OBJECT_delete(st, i) SKM_sk_delete(STORE_OBJECT, (st), (i))
# define sk_STORE_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(STORE_OBJECT, (st), (ptr))
# define sk_STORE_OBJECT_insert(st, val, i) SKM_sk_insert(STORE_OBJECT, (st), (val), (i))
# define sk_STORE_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STORE_OBJECT, (st), (cmp))
# define sk_STORE_OBJECT_dup(st) SKM_sk_dup(STORE_OBJECT, st)
# define sk_STORE_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(STORE_OBJECT, (st), (free_func))
# define sk_STORE_OBJECT_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(STORE_OBJECT, (st), (copy_func), (free_func))
# define sk_STORE_OBJECT_shift(st) SKM_sk_shift(STORE_OBJECT, (st))
# define sk_STORE_OBJECT_pop(st) SKM_sk_pop(STORE_OBJECT, (st))
# define sk_STORE_OBJECT_sort(st) SKM_sk_sort(STORE_OBJECT, (st))
# define sk_STORE_OBJECT_is_sorted(st) SKM_sk_is_sorted(STORE_OBJECT, (st))
# define sk_SXNETID_new(cmp) SKM_sk_new(SXNETID, (cmp))
# define sk_SXNETID_new_null() SKM_sk_new_null(SXNETID)
# define sk_SXNETID_free(st) SKM_sk_free(SXNETID, (st))
# define sk_SXNETID_num(st) SKM_sk_num(SXNETID, (st))
# define sk_SXNETID_value(st, i) SKM_sk_value(SXNETID, (st), (i))
# define sk_SXNETID_set(st, i, val) SKM_sk_set(SXNETID, (st), (i), (val))
# define sk_SXNETID_zero(st) SKM_sk_zero(SXNETID, (st))
# define sk_SXNETID_push(st, val) SKM_sk_push(SXNETID, (st), (val))
# define sk_SXNETID_unshift(st, val) SKM_sk_unshift(SXNETID, (st), (val))
# define sk_SXNETID_find(st, val) SKM_sk_find(SXNETID, (st), (val))
# define sk_SXNETID_find_ex(st, val) SKM_sk_find_ex(SXNETID, (st), (val))
# define sk_SXNETID_delete(st, i) SKM_sk_delete(SXNETID, (st), (i))
# define sk_SXNETID_delete_ptr(st, ptr) SKM_sk_delete_ptr(SXNETID, (st), (ptr))
# define sk_SXNETID_insert(st, val, i) SKM_sk_insert(SXNETID, (st), (val), (i))
# define sk_SXNETID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SXNETID, (st), (cmp))
# define sk_SXNETID_dup(st) SKM_sk_dup(SXNETID, st)
# define sk_SXNETID_pop_free(st, free_func) SKM_sk_pop_free(SXNETID, (st), (free_func))
# define sk_SXNETID_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SXNETID, (st), (copy_func), (free_func))
# define sk_SXNETID_shift(st) SKM_sk_shift(SXNETID, (st))
# define sk_SXNETID_pop(st) SKM_sk_pop(SXNETID, (st))
# define sk_SXNETID_sort(st) SKM_sk_sort(SXNETID, (st))
# define sk_SXNETID_is_sorted(st) SKM_sk_is_sorted(SXNETID, (st))
# define sk_UI_STRING_new(cmp) SKM_sk_new(UI_STRING, (cmp))
# define sk_UI_STRING_new_null() SKM_sk_new_null(UI_STRING)
# define sk_UI_STRING_free(st) SKM_sk_free(UI_STRING, (st))
# define sk_UI_STRING_num(st) SKM_sk_num(UI_STRING, (st))
# define sk_UI_STRING_value(st, i) SKM_sk_value(UI_STRING, (st), (i))
# define sk_UI_STRING_set(st, i, val) SKM_sk_set(UI_STRING, (st), (i), (val))
# define sk_UI_STRING_zero(st) SKM_sk_zero(UI_STRING, (st))
# define sk_UI_STRING_push(st, val) SKM_sk_push(UI_STRING, (st), (val))
# define sk_UI_STRING_unshift(st, val) SKM_sk_unshift(UI_STRING, (st), (val))
# define sk_UI_STRING_find(st, val) SKM_sk_find(UI_STRING, (st), (val))
# define sk_UI_STRING_find_ex(st, val) SKM_sk_find_ex(UI_STRING, (st), (val))
# define sk_UI_STRING_delete(st, i) SKM_sk_delete(UI_STRING, (st), (i))
# define sk_UI_STRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(UI_STRING, (st), (ptr))
# define sk_UI_STRING_insert(st, val, i) SKM_sk_insert(UI_STRING, (st), (val), (i))
# define sk_UI_STRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(UI_STRING, (st), (cmp))
# define sk_UI_STRING_dup(st) SKM_sk_dup(UI_STRING, st)
# define sk_UI_STRING_pop_free(st, free_func) SKM_sk_pop_free(UI_STRING, (st), (free_func))
# define sk_UI_STRING_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(UI_STRING, (st), (copy_func), (free_func))
# define sk_UI_STRING_shift(st) SKM_sk_shift(UI_STRING, (st))
# define sk_UI_STRING_pop(st) SKM_sk_pop(UI_STRING, (st))
# define sk_UI_STRING_sort(st) SKM_sk_sort(UI_STRING, (st))
# define sk_UI_STRING_is_sorted(st) SKM_sk_is_sorted(UI_STRING, (st))
# define sk_X509_new(cmp) SKM_sk_new(X509, (cmp))
# define sk_X509_new_null() SKM_sk_new_null(X509)
# define sk_X509_free(st) SKM_sk_free(X509, (st))
# define sk_X509_num(st) SKM_sk_num(X509, (st))
# define sk_X509_value(st, i) SKM_sk_value(X509, (st), (i))
# define sk_X509_set(st, i, val) SKM_sk_set(X509, (st), (i), (val))
# define sk_X509_zero(st) SKM_sk_zero(X509, (st))
# define sk_X509_push(st, val) SKM_sk_push(X509, (st), (val))
# define sk_X509_unshift(st, val) SKM_sk_unshift(X509, (st), (val))
# define sk_X509_find(st, val) SKM_sk_find(X509, (st), (val))
# define sk_X509_find_ex(st, val) SKM_sk_find_ex(X509, (st), (val))
# define sk_X509_delete(st, i) SKM_sk_delete(X509, (st), (i))
# define sk_X509_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509, (st), (ptr))
# define sk_X509_insert(st, val, i) SKM_sk_insert(X509, (st), (val), (i))
# define sk_X509_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509, (st), (cmp))
# define sk_X509_dup(st) SKM_sk_dup(X509, st)
# define sk_X509_pop_free(st, free_func) SKM_sk_pop_free(X509, (st), (free_func))
# define sk_X509_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509, (st), (copy_func), (free_func))
# define sk_X509_shift(st) SKM_sk_shift(X509, (st))
# define sk_X509_pop(st) SKM_sk_pop(X509, (st))
# define sk_X509_sort(st) SKM_sk_sort(X509, (st))
# define sk_X509_is_sorted(st) SKM_sk_is_sorted(X509, (st))
# define sk_X509V3_EXT_METHOD_new(cmp) SKM_sk_new(X509V3_EXT_METHOD, (cmp))
# define sk_X509V3_EXT_METHOD_new_null() SKM_sk_new_null(X509V3_EXT_METHOD)
# define sk_X509V3_EXT_METHOD_free(st) SKM_sk_free(X509V3_EXT_METHOD, (st))
# define sk_X509V3_EXT_METHOD_num(st) SKM_sk_num(X509V3_EXT_METHOD, (st))
# define sk_X509V3_EXT_METHOD_value(st, i) SKM_sk_value(X509V3_EXT_METHOD, (st), (i))
# define sk_X509V3_EXT_METHOD_set(st, i, val) SKM_sk_set(X509V3_EXT_METHOD, (st), (i), (val))
# define sk_X509V3_EXT_METHOD_zero(st) SKM_sk_zero(X509V3_EXT_METHOD, (st))
# define sk_X509V3_EXT_METHOD_push(st, val) SKM_sk_push(X509V3_EXT_METHOD, (st), (val))
# define sk_X509V3_EXT_METHOD_unshift(st, val) SKM_sk_unshift(X509V3_EXT_METHOD, (st), (val))
# define sk_X509V3_EXT_METHOD_find(st, val) SKM_sk_find(X509V3_EXT_METHOD, (st), (val))
# define sk_X509V3_EXT_METHOD_find_ex(st, val) SKM_sk_find_ex(X509V3_EXT_METHOD, (st), (val))
# define sk_X509V3_EXT_METHOD_delete(st, i) SKM_sk_delete(X509V3_EXT_METHOD, (st), (i))
# define sk_X509V3_EXT_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509V3_EXT_METHOD, (st), (ptr))
# define sk_X509V3_EXT_METHOD_insert(st, val, i) SKM_sk_insert(X509V3_EXT_METHOD, (st), (val), (i))
# define sk_X509V3_EXT_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509V3_EXT_METHOD, (st), (cmp))
# define sk_X509V3_EXT_METHOD_dup(st) SKM_sk_dup(X509V3_EXT_METHOD, st)
# define sk_X509V3_EXT_METHOD_pop_free(st, free_func) SKM_sk_pop_free(X509V3_EXT_METHOD, (st), (free_func))
# define sk_X509V3_EXT_METHOD_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509V3_EXT_METHOD, (st), (copy_func), (free_func))
# define sk_X509V3_EXT_METHOD_shift(st) SKM_sk_shift(X509V3_EXT_METHOD, (st))
# define sk_X509V3_EXT_METHOD_pop(st) SKM_sk_pop(X509V3_EXT_METHOD, (st))
# define sk_X509V3_EXT_METHOD_sort(st) SKM_sk_sort(X509V3_EXT_METHOD, (st))
# define sk_X509V3_EXT_METHOD_is_sorted(st) SKM_sk_is_sorted(X509V3_EXT_METHOD, (st))
# define sk_X509_ALGOR_new(cmp) SKM_sk_new(X509_ALGOR, (cmp))
# define sk_X509_ALGOR_new_null() SKM_sk_new_null(X509_ALGOR)
# define sk_X509_ALGOR_free(st) SKM_sk_free(X509_ALGOR, (st))
# define sk_X509_ALGOR_num(st) SKM_sk_num(X509_ALGOR, (st))
# define sk_X509_ALGOR_value(st, i) SKM_sk_value(X509_ALGOR, (st), (i))
# define sk_X509_ALGOR_set(st, i, val) SKM_sk_set(X509_ALGOR, (st), (i), (val))
# define sk_X509_ALGOR_zero(st) SKM_sk_zero(X509_ALGOR, (st))
# define sk_X509_ALGOR_push(st, val) SKM_sk_push(X509_ALGOR, (st), (val))
# define sk_X509_ALGOR_unshift(st, val) SKM_sk_unshift(X509_ALGOR, (st), (val))
# define sk_X509_ALGOR_find(st, val) SKM_sk_find(X509_ALGOR, (st), (val))
# define sk_X509_ALGOR_find_ex(st, val) SKM_sk_find_ex(X509_ALGOR, (st), (val))
# define sk_X509_ALGOR_delete(st, i) SKM_sk_delete(X509_ALGOR, (st), (i))
# define sk_X509_ALGOR_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_ALGOR, (st), (ptr))
# define sk_X509_ALGOR_insert(st, val, i) SKM_sk_insert(X509_ALGOR, (st), (val), (i))
# define sk_X509_ALGOR_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_ALGOR, (st), (cmp))
# define sk_X509_ALGOR_dup(st) SKM_sk_dup(X509_ALGOR, st)
# define sk_X509_ALGOR_pop_free(st, free_func) SKM_sk_pop_free(X509_ALGOR, (st), (free_func))
# define sk_X509_ALGOR_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_ALGOR, (st), (copy_func), (free_func))
# define sk_X509_ALGOR_shift(st) SKM_sk_shift(X509_ALGOR, (st))
# define sk_X509_ALGOR_pop(st) SKM_sk_pop(X509_ALGOR, (st))
# define sk_X509_ALGOR_sort(st) SKM_sk_sort(X509_ALGOR, (st))
# define sk_X509_ALGOR_is_sorted(st) SKM_sk_is_sorted(X509_ALGOR, (st))
# define sk_X509_ATTRIBUTE_new(cmp) SKM_sk_new(X509_ATTRIBUTE, (cmp))
# define sk_X509_ATTRIBUTE_new_null() SKM_sk_new_null(X509_ATTRIBUTE)
# define sk_X509_ATTRIBUTE_free(st) SKM_sk_free(X509_ATTRIBUTE, (st))
# define sk_X509_ATTRIBUTE_num(st) SKM_sk_num(X509_ATTRIBUTE, (st))
# define sk_X509_ATTRIBUTE_value(st, i) SKM_sk_value(X509_ATTRIBUTE, (st), (i))
# define sk_X509_ATTRIBUTE_set(st, i, val) SKM_sk_set(X509_ATTRIBUTE, (st), (i), (val))
# define sk_X509_ATTRIBUTE_zero(st) SKM_sk_zero(X509_ATTRIBUTE, (st))
# define sk_X509_ATTRIBUTE_push(st, val) SKM_sk_push(X509_ATTRIBUTE, (st), (val))
# define sk_X509_ATTRIBUTE_unshift(st, val) SKM_sk_unshift(X509_ATTRIBUTE, (st), (val))
# define sk_X509_ATTRIBUTE_find(st, val) SKM_sk_find(X509_ATTRIBUTE, (st), (val))
# define sk_X509_ATTRIBUTE_find_ex(st, val) SKM_sk_find_ex(X509_ATTRIBUTE, (st), (val))
# define sk_X509_ATTRIBUTE_delete(st, i) SKM_sk_delete(X509_ATTRIBUTE, (st), (i))
# define sk_X509_ATTRIBUTE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_ATTRIBUTE, (st), (ptr))
# define sk_X509_ATTRIBUTE_insert(st, val, i) SKM_sk_insert(X509_ATTRIBUTE, (st), (val), (i))
# define sk_X509_ATTRIBUTE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_ATTRIBUTE, (st), (cmp))
# define sk_X509_ATTRIBUTE_dup(st) SKM_sk_dup(X509_ATTRIBUTE, st)
# define sk_X509_ATTRIBUTE_pop_free(st, free_func) SKM_sk_pop_free(X509_ATTRIBUTE, (st), (free_func))
# define sk_X509_ATTRIBUTE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_ATTRIBUTE, (st), (copy_func), (free_func))
# define sk_X509_ATTRIBUTE_shift(st) SKM_sk_shift(X509_ATTRIBUTE, (st))
# define sk_X509_ATTRIBUTE_pop(st) SKM_sk_pop(X509_ATTRIBUTE, (st))
# define sk_X509_ATTRIBUTE_sort(st) SKM_sk_sort(X509_ATTRIBUTE, (st))
# define sk_X509_ATTRIBUTE_is_sorted(st) SKM_sk_is_sorted(X509_ATTRIBUTE, (st))
# define sk_X509_CRL_new(cmp) SKM_sk_new(X509_CRL, (cmp))
# define sk_X509_CRL_new_null() SKM_sk_new_null(X509_CRL)
# define sk_X509_CRL_free(st) SKM_sk_free(X509_CRL, (st))
# define sk_X509_CRL_num(st) SKM_sk_num(X509_CRL, (st))
# define sk_X509_CRL_value(st, i) SKM_sk_value(X509_CRL, (st), (i))
# define sk_X509_CRL_set(st, i, val) SKM_sk_set(X509_CRL, (st), (i), (val))
# define sk_X509_CRL_zero(st) SKM_sk_zero(X509_CRL, (st))
# define sk_X509_CRL_push(st, val) SKM_sk_push(X509_CRL, (st), (val))
# define sk_X509_CRL_unshift(st, val) SKM_sk_unshift(X509_CRL, (st), (val))
# define sk_X509_CRL_find(st, val) SKM_sk_find(X509_CRL, (st), (val))
# define sk_X509_CRL_find_ex(st, val) SKM_sk_find_ex(X509_CRL, (st), (val))
# define sk_X509_CRL_delete(st, i) SKM_sk_delete(X509_CRL, (st), (i))
# define sk_X509_CRL_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_CRL, (st), (ptr))
# define sk_X509_CRL_insert(st, val, i) SKM_sk_insert(X509_CRL, (st), (val), (i))
# define sk_X509_CRL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_CRL, (st), (cmp))
# define sk_X509_CRL_dup(st) SKM_sk_dup(X509_CRL, st)
# define sk_X509_CRL_pop_free(st, free_func) SKM_sk_pop_free(X509_CRL, (st), (free_func))
# define sk_X509_CRL_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_CRL, (st), (copy_func), (free_func))
# define sk_X509_CRL_shift(st) SKM_sk_shift(X509_CRL, (st))
# define sk_X509_CRL_pop(st) SKM_sk_pop(X509_CRL, (st))
# define sk_X509_CRL_sort(st) SKM_sk_sort(X509_CRL, (st))
# define sk_X509_CRL_is_sorted(st) SKM_sk_is_sorted(X509_CRL, (st))
# define sk_X509_EXTENSION_new(cmp) SKM_sk_new(X509_EXTENSION, (cmp))
# define sk_X509_EXTENSION_new_null() SKM_sk_new_null(X509_EXTENSION)
# define sk_X509_EXTENSION_free(st) SKM_sk_free(X509_EXTENSION, (st))
# define sk_X509_EXTENSION_num(st) SKM_sk_num(X509_EXTENSION, (st))
# define sk_X509_EXTENSION_value(st, i) SKM_sk_value(X509_EXTENSION, (st), (i))
# define sk_X509_EXTENSION_set(st, i, val) SKM_sk_set(X509_EXTENSION, (st), (i), (val))
# define sk_X509_EXTENSION_zero(st) SKM_sk_zero(X509_EXTENSION, (st))
# define sk_X509_EXTENSION_push(st, val) SKM_sk_push(X509_EXTENSION, (st), (val))
# define sk_X509_EXTENSION_unshift(st, val) SKM_sk_unshift(X509_EXTENSION, (st), (val))
# define sk_X509_EXTENSION_find(st, val) SKM_sk_find(X509_EXTENSION, (st), (val))
# define sk_X509_EXTENSION_find_ex(st, val) SKM_sk_find_ex(X509_EXTENSION, (st), (val))
# define sk_X509_EXTENSION_delete(st, i) SKM_sk_delete(X509_EXTENSION, (st), (i))
# define sk_X509_EXTENSION_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_EXTENSION, (st), (ptr))
# define sk_X509_EXTENSION_insert(st, val, i) SKM_sk_insert(X509_EXTENSION, (st), (val), (i))
# define sk_X509_EXTENSION_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_EXTENSION, (st), (cmp))
# define sk_X509_EXTENSION_dup(st) SKM_sk_dup(X509_EXTENSION, st)
# define sk_X509_EXTENSION_pop_free(st, free_func) SKM_sk_pop_free(X509_EXTENSION, (st), (free_func))
# define sk_X509_EXTENSION_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_EXTENSION, (st), (copy_func), (free_func))
# define sk_X509_EXTENSION_shift(st) SKM_sk_shift(X509_EXTENSION, (st))
# define sk_X509_EXTENSION_pop(st) SKM_sk_pop(X509_EXTENSION, (st))
# define sk_X509_EXTENSION_sort(st) SKM_sk_sort(X509_EXTENSION, (st))
# define sk_X509_EXTENSION_is_sorted(st) SKM_sk_is_sorted(X509_EXTENSION, (st))
# define sk_X509_INFO_new(cmp) SKM_sk_new(X509_INFO, (cmp))
# define sk_X509_INFO_new_null() SKM_sk_new_null(X509_INFO)
# define sk_X509_INFO_free(st) SKM_sk_free(X509_INFO, (st))
# define sk_X509_INFO_num(st) SKM_sk_num(X509_INFO, (st))
# define sk_X509_INFO_value(st, i) SKM_sk_value(X509_INFO, (st), (i))
# define sk_X509_INFO_set(st, i, val) SKM_sk_set(X509_INFO, (st), (i), (val))
# define sk_X509_INFO_zero(st) SKM_sk_zero(X509_INFO, (st))
# define sk_X509_INFO_push(st, val) SKM_sk_push(X509_INFO, (st), (val))
# define sk_X509_INFO_unshift(st, val) SKM_sk_unshift(X509_INFO, (st), (val))
# define sk_X509_INFO_find(st, val) SKM_sk_find(X509_INFO, (st), (val))
# define sk_X509_INFO_find_ex(st, val) SKM_sk_find_ex(X509_INFO, (st), (val))
# define sk_X509_INFO_delete(st, i) SKM_sk_delete(X509_INFO, (st), (i))
# define sk_X509_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_INFO, (st), (ptr))
# define sk_X509_INFO_insert(st, val, i) SKM_sk_insert(X509_INFO, (st), (val), (i))
# define sk_X509_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_INFO, (st), (cmp))
# define sk_X509_INFO_dup(st) SKM_sk_dup(X509_INFO, st)
# define sk_X509_INFO_pop_free(st, free_func) SKM_sk_pop_free(X509_INFO, (st), (free_func))
# define sk_X509_INFO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_INFO, (st), (copy_func), (free_func))
# define sk_X509_INFO_shift(st) SKM_sk_shift(X509_INFO, (st))
# define sk_X509_INFO_pop(st) SKM_sk_pop(X509_INFO, (st))
# define sk_X509_INFO_sort(st) SKM_sk_sort(X509_INFO, (st))
# define sk_X509_INFO_is_sorted(st) SKM_sk_is_sorted(X509_INFO, (st))
# define sk_X509_LOOKUP_new(cmp) SKM_sk_new(X509_LOOKUP, (cmp))
# define sk_X509_LOOKUP_new_null() SKM_sk_new_null(X509_LOOKUP)
# define sk_X509_LOOKUP_free(st) SKM_sk_free(X509_LOOKUP, (st))
# define sk_X509_LOOKUP_num(st) SKM_sk_num(X509_LOOKUP, (st))
# define sk_X509_LOOKUP_value(st, i) SKM_sk_value(X509_LOOKUP, (st), (i))
# define sk_X509_LOOKUP_set(st, i, val) SKM_sk_set(X509_LOOKUP, (st), (i), (val))
# define sk_X509_LOOKUP_zero(st) SKM_sk_zero(X509_LOOKUP, (st))
# define sk_X509_LOOKUP_push(st, val) SKM_sk_push(X509_LOOKUP, (st), (val))
# define sk_X509_LOOKUP_unshift(st, val) SKM_sk_unshift(X509_LOOKUP, (st), (val))
# define sk_X509_LOOKUP_find(st, val) SKM_sk_find(X509_LOOKUP, (st), (val))
# define sk_X509_LOOKUP_find_ex(st, val) SKM_sk_find_ex(X509_LOOKUP, (st), (val))
# define sk_X509_LOOKUP_delete(st, i) SKM_sk_delete(X509_LOOKUP, (st), (i))
# define sk_X509_LOOKUP_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_LOOKUP, (st), (ptr))
# define sk_X509_LOOKUP_insert(st, val, i) SKM_sk_insert(X509_LOOKUP, (st), (val), (i))
# define sk_X509_LOOKUP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_LOOKUP, (st), (cmp))
# define sk_X509_LOOKUP_dup(st) SKM_sk_dup(X509_LOOKUP, st)
# define sk_X509_LOOKUP_pop_free(st, free_func) SKM_sk_pop_free(X509_LOOKUP, (st), (free_func))
# define sk_X509_LOOKUP_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_LOOKUP, (st), (copy_func), (free_func))
# define sk_X509_LOOKUP_shift(st) SKM_sk_shift(X509_LOOKUP, (st))
# define sk_X509_LOOKUP_pop(st) SKM_sk_pop(X509_LOOKUP, (st))
# define sk_X509_LOOKUP_sort(st) SKM_sk_sort(X509_LOOKUP, (st))
# define sk_X509_LOOKUP_is_sorted(st) SKM_sk_is_sorted(X509_LOOKUP, (st))
# define sk_X509_NAME_new(cmp) SKM_sk_new(X509_NAME, (cmp))
# define sk_X509_NAME_new_null() SKM_sk_new_null(X509_NAME)
# define sk_X509_NAME_free(st) SKM_sk_free(X509_NAME, (st))
# define sk_X509_NAME_num(st) SKM_sk_num(X509_NAME, (st))
# define sk_X509_NAME_value(st, i) SKM_sk_value(X509_NAME, (st), (i))
# define sk_X509_NAME_set(st, i, val) SKM_sk_set(X509_NAME, (st), (i), (val))
# define sk_X509_NAME_zero(st) SKM_sk_zero(X509_NAME, (st))
# define sk_X509_NAME_push(st, val) SKM_sk_push(X509_NAME, (st), (val))
# define sk_X509_NAME_unshift(st, val) SKM_sk_unshift(X509_NAME, (st), (val))
# define sk_X509_NAME_find(st, val) SKM_sk_find(X509_NAME, (st), (val))
# define sk_X509_NAME_find_ex(st, val) SKM_sk_find_ex(X509_NAME, (st), (val))
# define sk_X509_NAME_delete(st, i) SKM_sk_delete(X509_NAME, (st), (i))
# define sk_X509_NAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_NAME, (st), (ptr))
# define sk_X509_NAME_insert(st, val, i) SKM_sk_insert(X509_NAME, (st), (val), (i))
# define sk_X509_NAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_NAME, (st), (cmp))
# define sk_X509_NAME_dup(st) SKM_sk_dup(X509_NAME, st)
# define sk_X509_NAME_pop_free(st, free_func) SKM_sk_pop_free(X509_NAME, (st), (free_func))
# define sk_X509_NAME_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_NAME, (st), (copy_func), (free_func))
# define sk_X509_NAME_shift(st) SKM_sk_shift(X509_NAME, (st))
# define sk_X509_NAME_pop(st) SKM_sk_pop(X509_NAME, (st))
# define sk_X509_NAME_sort(st) SKM_sk_sort(X509_NAME, (st))
# define sk_X509_NAME_is_sorted(st) SKM_sk_is_sorted(X509_NAME, (st))
# define sk_X509_NAME_ENTRY_new(cmp) SKM_sk_new(X509_NAME_ENTRY, (cmp))
# define sk_X509_NAME_ENTRY_new_null() SKM_sk_new_null(X509_NAME_ENTRY)
# define sk_X509_NAME_ENTRY_free(st) SKM_sk_free(X509_NAME_ENTRY, (st))
# define sk_X509_NAME_ENTRY_num(st) SKM_sk_num(X509_NAME_ENTRY, (st))
# define sk_X509_NAME_ENTRY_value(st, i) SKM_sk_value(X509_NAME_ENTRY, (st), (i))
# define sk_X509_NAME_ENTRY_set(st, i, val) SKM_sk_set(X509_NAME_ENTRY, (st), (i), (val))
# define sk_X509_NAME_ENTRY_zero(st) SKM_sk_zero(X509_NAME_ENTRY, (st))
# define sk_X509_NAME_ENTRY_push(st, val) SKM_sk_push(X509_NAME_ENTRY, (st), (val))
# define sk_X509_NAME_ENTRY_unshift(st, val) SKM_sk_unshift(X509_NAME_ENTRY, (st), (val))
# define sk_X509_NAME_ENTRY_find(st, val) SKM_sk_find(X509_NAME_ENTRY, (st), (val))
# define sk_X509_NAME_ENTRY_find_ex(st, val) SKM_sk_find_ex(X509_NAME_ENTRY, (st), (val))
# define sk_X509_NAME_ENTRY_delete(st, i) SKM_sk_delete(X509_NAME_ENTRY, (st), (i))
# define sk_X509_NAME_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_NAME_ENTRY, (st), (ptr))
# define sk_X509_NAME_ENTRY_insert(st, val, i) SKM_sk_insert(X509_NAME_ENTRY, (st), (val), (i))
# define sk_X509_NAME_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_NAME_ENTRY, (st), (cmp))
# define sk_X509_NAME_ENTRY_dup(st) SKM_sk_dup(X509_NAME_ENTRY, st)
# define sk_X509_NAME_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(X509_NAME_ENTRY, (st), (free_func))
# define sk_X509_NAME_ENTRY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_NAME_ENTRY, (st), (copy_func), (free_func))
# define sk_X509_NAME_ENTRY_shift(st) SKM_sk_shift(X509_NAME_ENTRY, (st))
# define sk_X509_NAME_ENTRY_pop(st) SKM_sk_pop(X509_NAME_ENTRY, (st))
# define sk_X509_NAME_ENTRY_sort(st) SKM_sk_sort(X509_NAME_ENTRY, (st))
# define sk_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(X509_NAME_ENTRY, (st))
# define sk_X509_OBJECT_new(cmp) SKM_sk_new(X509_OBJECT, (cmp))
# define sk_X509_OBJECT_new_null() SKM_sk_new_null(X509_OBJECT)
# define sk_X509_OBJECT_free(st) SKM_sk_free(X509_OBJECT, (st))
# define sk_X509_OBJECT_num(st) SKM_sk_num(X509_OBJECT, (st))
# define sk_X509_OBJECT_value(st, i) SKM_sk_value(X509_OBJECT, (st), (i))
# define sk_X509_OBJECT_set(st, i, val) SKM_sk_set(X509_OBJECT, (st), (i), (val))
# define sk_X509_OBJECT_zero(st) SKM_sk_zero(X509_OBJECT, (st))
# define sk_X509_OBJECT_push(st, val) SKM_sk_push(X509_OBJECT, (st), (val))
# define sk_X509_OBJECT_unshift(st, val) SKM_sk_unshift(X509_OBJECT, (st), (val))
# define sk_X509_OBJECT_find(st, val) SKM_sk_find(X509_OBJECT, (st), (val))
# define sk_X509_OBJECT_find_ex(st, val) SKM_sk_find_ex(X509_OBJECT, (st), (val))
# define sk_X509_OBJECT_delete(st, i) SKM_sk_delete(X509_OBJECT, (st), (i))
# define sk_X509_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_OBJECT, (st), (ptr))
# define sk_X509_OBJECT_insert(st, val, i) SKM_sk_insert(X509_OBJECT, (st), (val), (i))
# define sk_X509_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_OBJECT, (st), (cmp))
# define sk_X509_OBJECT_dup(st) SKM_sk_dup(X509_OBJECT, st)
# define sk_X509_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(X509_OBJECT, (st), (free_func))
# define sk_X509_OBJECT_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_OBJECT, (st), (copy_func), (free_func))
# define sk_X509_OBJECT_shift(st) SKM_sk_shift(X509_OBJECT, (st))
# define sk_X509_OBJECT_pop(st) SKM_sk_pop(X509_OBJECT, (st))
# define sk_X509_OBJECT_sort(st) SKM_sk_sort(X509_OBJECT, (st))
# define sk_X509_OBJECT_is_sorted(st) SKM_sk_is_sorted(X509_OBJECT, (st))
# define sk_X509_POLICY_DATA_new(cmp) SKM_sk_new(X509_POLICY_DATA, (cmp))
# define sk_X509_POLICY_DATA_new_null() SKM_sk_new_null(X509_POLICY_DATA)
# define sk_X509_POLICY_DATA_free(st) SKM_sk_free(X509_POLICY_DATA, (st))
# define sk_X509_POLICY_DATA_num(st) SKM_sk_num(X509_POLICY_DATA, (st))
# define sk_X509_POLICY_DATA_value(st, i) SKM_sk_value(X509_POLICY_DATA, (st), (i))
# define sk_X509_POLICY_DATA_set(st, i, val) SKM_sk_set(X509_POLICY_DATA, (st), (i), (val))
# define sk_X509_POLICY_DATA_zero(st) SKM_sk_zero(X509_POLICY_DATA, (st))
# define sk_X509_POLICY_DATA_push(st, val) SKM_sk_push(X509_POLICY_DATA, (st), (val))
# define sk_X509_POLICY_DATA_unshift(st, val) SKM_sk_unshift(X509_POLICY_DATA, (st), (val))
# define sk_X509_POLICY_DATA_find(st, val) SKM_sk_find(X509_POLICY_DATA, (st), (val))
# define sk_X509_POLICY_DATA_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_DATA, (st), (val))
# define sk_X509_POLICY_DATA_delete(st, i) SKM_sk_delete(X509_POLICY_DATA, (st), (i))
# define sk_X509_POLICY_DATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_DATA, (st), (ptr))
# define sk_X509_POLICY_DATA_insert(st, val, i) SKM_sk_insert(X509_POLICY_DATA, (st), (val), (i))
# define sk_X509_POLICY_DATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_DATA, (st), (cmp))
# define sk_X509_POLICY_DATA_dup(st) SKM_sk_dup(X509_POLICY_DATA, st)
# define sk_X509_POLICY_DATA_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_DATA, (st), (free_func))
# define sk_X509_POLICY_DATA_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_POLICY_DATA, (st), (copy_func), (free_func))
# define sk_X509_POLICY_DATA_shift(st) SKM_sk_shift(X509_POLICY_DATA, (st))
# define sk_X509_POLICY_DATA_pop(st) SKM_sk_pop(X509_POLICY_DATA, (st))
# define sk_X509_POLICY_DATA_sort(st) SKM_sk_sort(X509_POLICY_DATA, (st))
# define sk_X509_POLICY_DATA_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_DATA, (st))
# define sk_X509_POLICY_NODE_new(cmp) SKM_sk_new(X509_POLICY_NODE, (cmp))
# define sk_X509_POLICY_NODE_new_null() SKM_sk_new_null(X509_POLICY_NODE)
# define sk_X509_POLICY_NODE_free(st) SKM_sk_free(X509_POLICY_NODE, (st))
# define sk_X509_POLICY_NODE_num(st) SKM_sk_num(X509_POLICY_NODE, (st))
# define sk_X509_POLICY_NODE_value(st, i) SKM_sk_value(X509_POLICY_NODE, (st), (i))
# define sk_X509_POLICY_NODE_set(st, i, val) SKM_sk_set(X509_POLICY_NODE, (st), (i), (val))
# define sk_X509_POLICY_NODE_zero(st) SKM_sk_zero(X509_POLICY_NODE, (st))
# define sk_X509_POLICY_NODE_push(st, val) SKM_sk_push(X509_POLICY_NODE, (st), (val))
# define sk_X509_POLICY_NODE_unshift(st, val) SKM_sk_unshift(X509_POLICY_NODE, (st), (val))
# define sk_X509_POLICY_NODE_find(st, val) SKM_sk_find(X509_POLICY_NODE, (st), (val))
# define sk_X509_POLICY_NODE_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_NODE, (st), (val))
# define sk_X509_POLICY_NODE_delete(st, i) SKM_sk_delete(X509_POLICY_NODE, (st), (i))
# define sk_X509_POLICY_NODE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_NODE, (st), (ptr))
# define sk_X509_POLICY_NODE_insert(st, val, i) SKM_sk_insert(X509_POLICY_NODE, (st), (val), (i))
# define sk_X509_POLICY_NODE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_NODE, (st), (cmp))
# define sk_X509_POLICY_NODE_dup(st) SKM_sk_dup(X509_POLICY_NODE, st)
# define sk_X509_POLICY_NODE_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_NODE, (st), (free_func))
# define sk_X509_POLICY_NODE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_POLICY_NODE, (st), (copy_func), (free_func))
# define sk_X509_POLICY_NODE_shift(st) SKM_sk_shift(X509_POLICY_NODE, (st))
# define sk_X509_POLICY_NODE_pop(st) SKM_sk_pop(X509_POLICY_NODE, (st))
# define sk_X509_POLICY_NODE_sort(st) SKM_sk_sort(X509_POLICY_NODE, (st))
# define sk_X509_POLICY_NODE_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_NODE, (st))
# define sk_X509_PURPOSE_new(cmp) SKM_sk_new(X509_PURPOSE, (cmp))
# define sk_X509_PURPOSE_new_null() SKM_sk_new_null(X509_PURPOSE)
# define sk_X509_PURPOSE_free(st) SKM_sk_free(X509_PURPOSE, (st))
# define sk_X509_PURPOSE_num(st) SKM_sk_num(X509_PURPOSE, (st))
# define sk_X509_PURPOSE_value(st, i) SKM_sk_value(X509_PURPOSE, (st), (i))
# define sk_X509_PURPOSE_set(st, i, val) SKM_sk_set(X509_PURPOSE, (st), (i), (val))
# define sk_X509_PURPOSE_zero(st) SKM_sk_zero(X509_PURPOSE, (st))
# define sk_X509_PURPOSE_push(st, val) SKM_sk_push(X509_PURPOSE, (st), (val))
# define sk_X509_PURPOSE_unshift(st, val) SKM_sk_unshift(X509_PURPOSE, (st), (val))
# define sk_X509_PURPOSE_find(st, val) SKM_sk_find(X509_PURPOSE, (st), (val))
# define sk_X509_PURPOSE_find_ex(st, val) SKM_sk_find_ex(X509_PURPOSE, (st), (val))
# define sk_X509_PURPOSE_delete(st, i) SKM_sk_delete(X509_PURPOSE, (st), (i))
# define sk_X509_PURPOSE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_PURPOSE, (st), (ptr))
# define sk_X509_PURPOSE_insert(st, val, i) SKM_sk_insert(X509_PURPOSE, (st), (val), (i))
# define sk_X509_PURPOSE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_PURPOSE, (st), (cmp))
# define sk_X509_PURPOSE_dup(st) SKM_sk_dup(X509_PURPOSE, st)
# define sk_X509_PURPOSE_pop_free(st, free_func) SKM_sk_pop_free(X509_PURPOSE, (st), (free_func))
# define sk_X509_PURPOSE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_PURPOSE, (st), (copy_func), (free_func))
# define sk_X509_PURPOSE_shift(st) SKM_sk_shift(X509_PURPOSE, (st))
# define sk_X509_PURPOSE_pop(st) SKM_sk_pop(X509_PURPOSE, (st))
# define sk_X509_PURPOSE_sort(st) SKM_sk_sort(X509_PURPOSE, (st))
# define sk_X509_PURPOSE_is_sorted(st) SKM_sk_is_sorted(X509_PURPOSE, (st))
# define sk_X509_REVOKED_new(cmp) SKM_sk_new(X509_REVOKED, (cmp))
# define sk_X509_REVOKED_new_null() SKM_sk_new_null(X509_REVOKED)
# define sk_X509_REVOKED_free(st) SKM_sk_free(X509_REVOKED, (st))
# define sk_X509_REVOKED_num(st) SKM_sk_num(X509_REVOKED, (st))
# define sk_X509_REVOKED_value(st, i) SKM_sk_value(X509_REVOKED, (st), (i))
# define sk_X509_REVOKED_set(st, i, val) SKM_sk_set(X509_REVOKED, (st), (i), (val))
# define sk_X509_REVOKED_zero(st) SKM_sk_zero(X509_REVOKED, (st))
# define sk_X509_REVOKED_push(st, val) SKM_sk_push(X509_REVOKED, (st), (val))
# define sk_X509_REVOKED_unshift(st, val) SKM_sk_unshift(X509_REVOKED, (st), (val))
# define sk_X509_REVOKED_find(st, val) SKM_sk_find(X509_REVOKED, (st), (val))
# define sk_X509_REVOKED_find_ex(st, val) SKM_sk_find_ex(X509_REVOKED, (st), (val))
# define sk_X509_REVOKED_delete(st, i) SKM_sk_delete(X509_REVOKED, (st), (i))
# define sk_X509_REVOKED_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_REVOKED, (st), (ptr))
# define sk_X509_REVOKED_insert(st, val, i) SKM_sk_insert(X509_REVOKED, (st), (val), (i))
# define sk_X509_REVOKED_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_REVOKED, (st), (cmp))
# define sk_X509_REVOKED_dup(st) SKM_sk_dup(X509_REVOKED, st)
# define sk_X509_REVOKED_pop_free(st, free_func) SKM_sk_pop_free(X509_REVOKED, (st), (free_func))
# define sk_X509_REVOKED_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_REVOKED, (st), (copy_func), (free_func))
# define sk_X509_REVOKED_shift(st) SKM_sk_shift(X509_REVOKED, (st))
# define sk_X509_REVOKED_pop(st) SKM_sk_pop(X509_REVOKED, (st))
# define sk_X509_REVOKED_sort(st) SKM_sk_sort(X509_REVOKED, (st))
# define sk_X509_REVOKED_is_sorted(st) SKM_sk_is_sorted(X509_REVOKED, (st))
# define sk_X509_TRUST_new(cmp) SKM_sk_new(X509_TRUST, (cmp))
# define sk_X509_TRUST_new_null() SKM_sk_new_null(X509_TRUST)
# define sk_X509_TRUST_free(st) SKM_sk_free(X509_TRUST, (st))
# define sk_X509_TRUST_num(st) SKM_sk_num(X509_TRUST, (st))
# define sk_X509_TRUST_value(st, i) SKM_sk_value(X509_TRUST, (st), (i))
# define sk_X509_TRUST_set(st, i, val) SKM_sk_set(X509_TRUST, (st), (i), (val))
# define sk_X509_TRUST_zero(st) SKM_sk_zero(X509_TRUST, (st))
# define sk_X509_TRUST_push(st, val) SKM_sk_push(X509_TRUST, (st), (val))
# define sk_X509_TRUST_unshift(st, val) SKM_sk_unshift(X509_TRUST, (st), (val))
# define sk_X509_TRUST_find(st, val) SKM_sk_find(X509_TRUST, (st), (val))
# define sk_X509_TRUST_find_ex(st, val) SKM_sk_find_ex(X509_TRUST, (st), (val))
# define sk_X509_TRUST_delete(st, i) SKM_sk_delete(X509_TRUST, (st), (i))
# define sk_X509_TRUST_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_TRUST, (st), (ptr))
# define sk_X509_TRUST_insert(st, val, i) SKM_sk_insert(X509_TRUST, (st), (val), (i))
# define sk_X509_TRUST_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_TRUST, (st), (cmp))
# define sk_X509_TRUST_dup(st) SKM_sk_dup(X509_TRUST, st)
# define sk_X509_TRUST_pop_free(st, free_func) SKM_sk_pop_free(X509_TRUST, (st), (free_func))
# define sk_X509_TRUST_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_TRUST, (st), (copy_func), (free_func))
# define sk_X509_TRUST_shift(st) SKM_sk_shift(X509_TRUST, (st))
# define sk_X509_TRUST_pop(st) SKM_sk_pop(X509_TRUST, (st))
# define sk_X509_TRUST_sort(st) SKM_sk_sort(X509_TRUST, (st))
# define sk_X509_TRUST_is_sorted(st) SKM_sk_is_sorted(X509_TRUST, (st))
# define sk_X509_VERIFY_PARAM_new(cmp) SKM_sk_new(X509_VERIFY_PARAM, (cmp))
# define sk_X509_VERIFY_PARAM_new_null() SKM_sk_new_null(X509_VERIFY_PARAM)
# define sk_X509_VERIFY_PARAM_free(st) SKM_sk_free(X509_VERIFY_PARAM, (st))
# define sk_X509_VERIFY_PARAM_num(st) SKM_sk_num(X509_VERIFY_PARAM, (st))
# define sk_X509_VERIFY_PARAM_value(st, i) SKM_sk_value(X509_VERIFY_PARAM, (st), (i))
# define sk_X509_VERIFY_PARAM_set(st, i, val) SKM_sk_set(X509_VERIFY_PARAM, (st), (i), (val))
# define sk_X509_VERIFY_PARAM_zero(st) SKM_sk_zero(X509_VERIFY_PARAM, (st))
# define sk_X509_VERIFY_PARAM_push(st, val) SKM_sk_push(X509_VERIFY_PARAM, (st), (val))
# define sk_X509_VERIFY_PARAM_unshift(st, val) SKM_sk_unshift(X509_VERIFY_PARAM, (st), (val))
# define sk_X509_VERIFY_PARAM_find(st, val) SKM_sk_find(X509_VERIFY_PARAM, (st), (val))
# define sk_X509_VERIFY_PARAM_find_ex(st, val) SKM_sk_find_ex(X509_VERIFY_PARAM, (st), (val))
# define sk_X509_VERIFY_PARAM_delete(st, i) SKM_sk_delete(X509_VERIFY_PARAM, (st), (i))
# define sk_X509_VERIFY_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_VERIFY_PARAM, (st), (ptr))
# define sk_X509_VERIFY_PARAM_insert(st, val, i) SKM_sk_insert(X509_VERIFY_PARAM, (st), (val), (i))
# define sk_X509_VERIFY_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_VERIFY_PARAM, (st), (cmp))
# define sk_X509_VERIFY_PARAM_dup(st) SKM_sk_dup(X509_VERIFY_PARAM, st)
# define sk_X509_VERIFY_PARAM_pop_free(st, free_func) SKM_sk_pop_free(X509_VERIFY_PARAM, (st), (free_func))
# define sk_X509_VERIFY_PARAM_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_VERIFY_PARAM, (st), (copy_func), (free_func))
# define sk_X509_VERIFY_PARAM_shift(st) SKM_sk_shift(X509_VERIFY_PARAM, (st))
# define sk_X509_VERIFY_PARAM_pop(st) SKM_sk_pop(X509_VERIFY_PARAM, (st))
# define sk_X509_VERIFY_PARAM_sort(st) SKM_sk_sort(X509_VERIFY_PARAM, (st))
# define sk_X509_VERIFY_PARAM_is_sorted(st) SKM_sk_is_sorted(X509_VERIFY_PARAM, (st))
# define sk_nid_triple_new(cmp) SKM_sk_new(nid_triple, (cmp))
# define sk_nid_triple_new_null() SKM_sk_new_null(nid_triple)
# define sk_nid_triple_free(st) SKM_sk_free(nid_triple, (st))
# define sk_nid_triple_num(st) SKM_sk_num(nid_triple, (st))
# define sk_nid_triple_value(st, i) SKM_sk_value(nid_triple, (st), (i))
# define sk_nid_triple_set(st, i, val) SKM_sk_set(nid_triple, (st), (i), (val))
# define sk_nid_triple_zero(st) SKM_sk_zero(nid_triple, (st))
# define sk_nid_triple_push(st, val) SKM_sk_push(nid_triple, (st), (val))
# define sk_nid_triple_unshift(st, val) SKM_sk_unshift(nid_triple, (st), (val))
# define sk_nid_triple_find(st, val) SKM_sk_find(nid_triple, (st), (val))
# define sk_nid_triple_find_ex(st, val) SKM_sk_find_ex(nid_triple, (st), (val))
# define sk_nid_triple_delete(st, i) SKM_sk_delete(nid_triple, (st), (i))
# define sk_nid_triple_delete_ptr(st, ptr) SKM_sk_delete_ptr(nid_triple, (st), (ptr))
# define sk_nid_triple_insert(st, val, i) SKM_sk_insert(nid_triple, (st), (val), (i))
# define sk_nid_triple_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(nid_triple, (st), (cmp))
# define sk_nid_triple_dup(st) SKM_sk_dup(nid_triple, st)
# define sk_nid_triple_pop_free(st, free_func) SKM_sk_pop_free(nid_triple, (st), (free_func))
# define sk_nid_triple_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(nid_triple, (st), (copy_func), (free_func))
# define sk_nid_triple_shift(st) SKM_sk_shift(nid_triple, (st))
# define sk_nid_triple_pop(st) SKM_sk_pop(nid_triple, (st))
# define sk_nid_triple_sort(st) SKM_sk_sort(nid_triple, (st))
# define sk_nid_triple_is_sorted(st) SKM_sk_is_sorted(nid_triple, (st))
# define sk_void_new(cmp) SKM_sk_new(void, (cmp))
# define sk_void_new_null() SKM_sk_new_null(void)
# define sk_void_free(st) SKM_sk_free(void, (st))
# define sk_void_num(st) SKM_sk_num(void, (st))
# define sk_void_value(st, i) SKM_sk_value(void, (st), (i))
# define sk_void_set(st, i, val) SKM_sk_set(void, (st), (i), (val))
# define sk_void_zero(st) SKM_sk_zero(void, (st))
# define sk_void_push(st, val) SKM_sk_push(void, (st), (val))
# define sk_void_unshift(st, val) SKM_sk_unshift(void, (st), (val))
# define sk_void_find(st, val) SKM_sk_find(void, (st), (val))
# define sk_void_find_ex(st, val) SKM_sk_find_ex(void, (st), (val))
# define sk_void_delete(st, i) SKM_sk_delete(void, (st), (i))
# define sk_void_delete_ptr(st, ptr) SKM_sk_delete_ptr(void, (st), (ptr))
# define sk_void_insert(st, val, i) SKM_sk_insert(void, (st), (val), (i))
# define sk_void_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(void, (st), (cmp))
# define sk_void_dup(st) SKM_sk_dup(void, st)
# define sk_void_pop_free(st, free_func) SKM_sk_pop_free(void, (st), (free_func))
# define sk_void_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(void, (st), (copy_func), (free_func))
# define sk_void_shift(st) SKM_sk_shift(void, (st))
# define sk_void_pop(st) SKM_sk_pop(void, (st))
# define sk_void_sort(st) SKM_sk_sort(void, (st))
# define sk_void_is_sorted(st) SKM_sk_is_sorted(void, (st))
# define sk_OPENSSL_STRING_new(cmp) ((STACK_OF(OPENSSL_STRING) *)sk_new(CHECKED_SK_CMP_FUNC(char, cmp)))
# define sk_OPENSSL_STRING_new_null() ((STACK_OF(OPENSSL_STRING) *)sk_new_null())
# define sk_OPENSSL_STRING_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val))
# define sk_OPENSSL_STRING_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val))
# define sk_OPENSSL_STRING_value(st, i) ((OPENSSL_STRING)sk_value(CHECKED_STACK_OF(OPENSSL_STRING, st), i))
# define sk_OPENSSL_STRING_num(st) SKM_sk_num(OPENSSL_STRING, st)
# define sk_OPENSSL_STRING_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_SK_FREE_FUNC(char, free_func))
# define sk_OPENSSL_STRING_deep_copy(st, copy_func, free_func) ((STACK_OF(OPENSSL_STRING) *)sk_deep_copy(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_SK_COPY_FUNC(char, copy_func), CHECKED_SK_FREE_FUNC(char, free_func)))
# define sk_OPENSSL_STRING_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val), i)
# define sk_OPENSSL_STRING_free(st) SKM_sk_free(OPENSSL_STRING, st)
# define sk_OPENSSL_STRING_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_STRING, st), i, CHECKED_PTR_OF(char, val))
# define sk_OPENSSL_STRING_zero(st) SKM_sk_zero(OPENSSL_STRING, (st))
# define sk_OPENSSL_STRING_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val))
# define sk_OPENSSL_STRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_CONST_PTR_OF(char, val))
# define sk_OPENSSL_STRING_delete(st, i) SKM_sk_delete(OPENSSL_STRING, (st), (i))
# define sk_OPENSSL_STRING_delete_ptr(st, ptr) (OPENSSL_STRING *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, ptr))
# define sk_OPENSSL_STRING_set_cmp_func(st, cmp)  \
        ((int (*)(const char * const *,const char * const *)) \
        sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_SK_CMP_FUNC(char, cmp)))
# define sk_OPENSSL_STRING_dup(st) SKM_sk_dup(OPENSSL_STRING, st)
# define sk_OPENSSL_STRING_shift(st) SKM_sk_shift(OPENSSL_STRING, (st))
# define sk_OPENSSL_STRING_pop(st) (char *)sk_pop(CHECKED_STACK_OF(OPENSSL_STRING, st))
# define sk_OPENSSL_STRING_sort(st) SKM_sk_sort(OPENSSL_STRING, (st))
# define sk_OPENSSL_STRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_STRING, (st))
# define sk_OPENSSL_BLOCK_new(cmp) ((STACK_OF(OPENSSL_BLOCK) *)sk_new(CHECKED_SK_CMP_FUNC(void, cmp)))
# define sk_OPENSSL_BLOCK_new_null() ((STACK_OF(OPENSSL_BLOCK) *)sk_new_null())
# define sk_OPENSSL_BLOCK_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val))
# define sk_OPENSSL_BLOCK_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val))
# define sk_OPENSSL_BLOCK_value(st, i) ((OPENSSL_BLOCK)sk_value(CHECKED_STACK_OF(OPENSSL_BLOCK, st), i))
# define sk_OPENSSL_BLOCK_num(st) SKM_sk_num(OPENSSL_BLOCK, st)
# define sk_OPENSSL_BLOCK_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_SK_FREE_FUNC(void, free_func))
# define sk_OPENSSL_BLOCK_deep_copy(st, copy_func, free_func) ((STACK_OF(OPENSSL_BLOCK) *)sk_deep_copy(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_SK_COPY_FUNC(void, copy_func), CHECKED_SK_FREE_FUNC(void, free_func)))
# define sk_OPENSSL_BLOCK_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val), i)
# define sk_OPENSSL_BLOCK_free(st) SKM_sk_free(OPENSSL_BLOCK, st)
# define sk_OPENSSL_BLOCK_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_BLOCK, st), i, CHECKED_PTR_OF(void, val))
# define sk_OPENSSL_BLOCK_zero(st) SKM_sk_zero(OPENSSL_BLOCK, (st))
# define sk_OPENSSL_BLOCK_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val))
# define sk_OPENSSL_BLOCK_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_CONST_PTR_OF(void, val))
# define sk_OPENSSL_BLOCK_delete(st, i) SKM_sk_delete(OPENSSL_BLOCK, (st), (i))
# define sk_OPENSSL_BLOCK_delete_ptr(st, ptr) (OPENSSL_BLOCK *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, ptr))
# define sk_OPENSSL_BLOCK_set_cmp_func(st, cmp)  \
        ((int (*)(const void * const *,const void * const *)) \
        sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_SK_CMP_FUNC(void, cmp)))
# define sk_OPENSSL_BLOCK_dup(st) SKM_sk_dup(OPENSSL_BLOCK, st)
# define sk_OPENSSL_BLOCK_shift(st) SKM_sk_shift(OPENSSL_BLOCK, (st))
# define sk_OPENSSL_BLOCK_pop(st) (void *)sk_pop(CHECKED_STACK_OF(OPENSSL_BLOCK, st))
# define sk_OPENSSL_BLOCK_sort(st) SKM_sk_sort(OPENSSL_BLOCK, (st))
# define sk_OPENSSL_BLOCK_is_sorted(st) SKM_sk_is_sorted(OPENSSL_BLOCK, (st))
# define sk_OPENSSL_PSTRING_new(cmp) ((STACK_OF(OPENSSL_PSTRING) *)sk_new(CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp)))
# define sk_OPENSSL_PSTRING_new_null() ((STACK_OF(OPENSSL_PSTRING) *)sk_new_null())
# define sk_OPENSSL_PSTRING_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val))
# define sk_OPENSSL_PSTRING_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val))
# define sk_OPENSSL_PSTRING_value(st, i) ((OPENSSL_PSTRING)sk_value(CHECKED_STACK_OF(OPENSSL_PSTRING, st), i))
# define sk_OPENSSL_PSTRING_num(st) SKM_sk_num(OPENSSL_PSTRING, st)
# define sk_OPENSSL_PSTRING_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_FREE_FUNC(OPENSSL_STRING, free_func))
# define sk_OPENSSL_PSTRING_deep_copy(st, copy_func, free_func) ((STACK_OF(OPENSSL_PSTRING) *)sk_deep_copy(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_COPY_FUNC(OPENSSL_STRING, copy_func), CHECKED_SK_FREE_FUNC(OPENSSL_STRING, free_func)))
# define sk_OPENSSL_PSTRING_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val), i)
# define sk_OPENSSL_PSTRING_free(st) SKM_sk_free(OPENSSL_PSTRING, st)
# define sk_OPENSSL_PSTRING_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_PSTRING, st), i, CHECKED_PTR_OF(OPENSSL_STRING, val))
# define sk_OPENSSL_PSTRING_zero(st) SKM_sk_zero(OPENSSL_PSTRING, (st))
# define sk_OPENSSL_PSTRING_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val))
# define sk_OPENSSL_PSTRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_CONST_PTR_OF(OPENSSL_STRING, val))
# define sk_OPENSSL_PSTRING_delete(st, i) SKM_sk_delete(OPENSSL_PSTRING, (st), (i))
# define sk_OPENSSL_PSTRING_delete_ptr(st, ptr) (OPENSSL_PSTRING *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, ptr))
# define sk_OPENSSL_PSTRING_set_cmp_func(st, cmp)  \
        ((int (*)(const OPENSSL_STRING * const *,const OPENSSL_STRING * const *)) \
        sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp)))
# define sk_OPENSSL_PSTRING_dup(st) SKM_sk_dup(OPENSSL_PSTRING, st)
# define sk_OPENSSL_PSTRING_shift(st) SKM_sk_shift(OPENSSL_PSTRING, (st))
# define sk_OPENSSL_PSTRING_pop(st) (OPENSSL_STRING *)sk_pop(CHECKED_STACK_OF(OPENSSL_PSTRING, st))
# define sk_OPENSSL_PSTRING_sort(st) SKM_sk_sort(OPENSSL_PSTRING, (st))
# define sk_OPENSSL_PSTRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_PSTRING, (st))
# define d2i_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        SKM_ASN1_SET_OF_d2i(ACCESS_DESCRIPTION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
# define i2d_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        SKM_ASN1_SET_OF_i2d(ACCESS_DESCRIPTION, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
# define ASN1_seq_pack_ACCESS_DESCRIPTION(st, i2d_func, buf, len) \
        SKM_ASN1_seq_pack(ACCESS_DESCRIPTION, (st), (i2d_func), (buf), (len))
# define ASN1_seq_unpack_ACCESS_DESCRIPTION(buf, len, d2i_func, free_func) \
        SKM_ASN1_seq_unpack(ACCESS_DESCRIPTION, (buf), (len), (d2i_func), (free_func))
# define d2i_ASN1_SET_OF_ASN1_INTEGER(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        SKM_ASN1_SET_OF_d2i(ASN1_INTEGER, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
# define i2d_ASN1_SET_OF_ASN1_INTEGER(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        SKM_ASN1_SET_OF_i2d(ASN1_INTEGER, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
# define ASN1_seq_pack_ASN1_INTEGER(st, i2d_func, buf, len) \
        SKM_ASN1_seq_pack(ASN1_INTEGER, (st), (i2d_func), (buf), (len))
# define ASN1_seq_unpack_ASN1_INTEGER(buf, len, d2i_func, free_func) \
        SKM_ASN1_seq_unpack(ASN1_INTEGER, (buf), (len), (d2i_func), (free_func))
# define d2i_ASN1_SET_OF_ASN1_OBJECT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        SKM_ASN1_SET_OF_d2i(ASN1_OBJECT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
# define i2d_ASN1_SET_OF_ASN1_OBJECT(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        SKM_ASN1_SET_OF_i2d(ASN1_OBJECT, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
# define ASN1_seq_pack_ASN1_OBJECT(st, i2d_func, buf, len) \
        SKM_ASN1_seq_pack(ASN1_OBJECT, (st), (i2d_func), (buf), (len))
# define ASN1_seq_unpack_ASN1_OBJECT(buf, len, d2i_func, free_func) \
        SKM_ASN1_seq_unpack(ASN1_OBJECT, (buf), (len), (d2i_func), (free_func))
# define d2i_ASN1_SET_OF_ASN1_TYPE(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        SKM_ASN1_SET_OF_d2i(ASN1_TYPE, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
# define i2d_ASN1_SET_OF_ASN1_TYPE(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        SKM_ASN1_SET_OF_i2d(ASN1_TYPE, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
# define ASN1_seq_pack_ASN1_TYPE(st, i2d_func, buf, len) \
        SKM_ASN1_seq_pack(ASN1_TYPE, (st), (i2d_func), (buf), (len))
# define ASN1_seq_unpack_ASN1_TYPE(buf, len, d2i_func, free_func) \
        SKM_ASN1_seq_unpack(ASN1_TYPE, (buf), (len), (d2i_func), (free_func))
# define d2i_ASN1_SET_OF_ASN1_UTF8STRING(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        SKM_ASN1_SET_OF_d2i(ASN1_UTF8STRING, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
# define i2d_ASN1_SET_OF_ASN1_UTF8STRING(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        SKM_ASN1_SET_OF_i2d(ASN1_UTF8STRING, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
# define ASN1_seq_pack_ASN1_UTF8STRING(st, i2d_func, buf, len) \
        SKM_ASN1_seq_pack(ASN1_UTF8STRING, (st), (i2d_func), (buf), (len))
# define ASN1_seq_unpack_ASN1_UTF8STRING(buf, len, d2i_func, free_func) \
        SKM_ASN1_seq_unpack(ASN1_UTF8STRING, (buf), (len), (d2i_func), (free_func))
# define d2i_ASN1_SET_OF_DIST_POINT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        SKM_ASN1_SET_OF_d2i(DIST_POINT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
# define i2d_ASN1_SET_OF_DIST_POINT(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        SKM_ASN1_SET_OF_i2d(DIST_POINT, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
# define ASN1_seq_pack_DIST_POINT(st, i2d_func, buf, len) \
        SKM_ASN1_seq_pack(DIST_POINT, (st), (i2d_func), (buf), (len))
# define ASN1_seq_unpack_DIST_POINT(buf, len, d2i_func, free_func) \
        SKM_ASN1_seq_unpack(DIST_POINT, (buf), (len), (d2i_func), (free_func))
# define d2i_ASN1_SET_OF_ESS_CERT_ID(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        SKM_ASN1_SET_OF_d2i(ESS_CERT_ID, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
# define i2d_ASN1_SET_OF_ESS_CERT_ID(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        SKM_ASN1_SET_OF_i2d(ESS_CERT_ID, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
# define ASN1_seq_pack_ESS_CERT_ID(st, i2d_func, buf, len) \
        SKM_ASN1_seq_pack(ESS_CERT_ID, (st), (i2d_func), (buf), (len))
# define ASN1_seq_unpack_ESS_CERT_ID(buf, len, d2i_func, free_func) \
        SKM_ASN1_seq_unpack(ESS_CERT_ID, (buf), (len), (d2i_func), (free_func))
# define d2i_ASN1_SET_OF_EVP_MD(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        SKM_ASN1_SET_OF_d2i(EVP_MD, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
# define i2d_ASN1_SET_OF_EVP_MD(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        SKM_ASN1_SET_OF_i2d(EVP_MD, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
# define ASN1_seq_pack_EVP_MD(st, i2d_func, buf, len) \
        SKM_ASN1_seq_pack(EVP_MD, (st), (i2d_func), (buf), (len))
# define ASN1_seq_unpack_EVP_MD(buf, len, d2i_func, free_func) \
        SKM_ASN1_seq_unpack(EVP_MD, (buf), (len), (d2i_func), (free_func))
# define d2i_ASN1_SET_OF_GENERAL_NAME(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        SKM_ASN1_SET_OF_d2i(GENERAL_NAME, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
# define i2d_ASN1_SET_OF_GENERAL_NAME(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        SKM_ASN1_SET_OF_i2d(GENERAL_NAME, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
# define ASN1_seq_pack_GENERAL_NAME(st, i2d_func, buf, len) \
        SKM_ASN1_seq_pack(GENERAL_NAME, (st), (i2d_func), (buf), (len))
# define ASN1_seq_unpack_GENERAL_NAME(buf, len, d2i_func, free_func) \
        SKM_ASN1_seq_unpack(GENERAL_NAME, (buf), (len), (d2i_func), (free_func))
# define d2i_ASN1_SET_OF_OCSP_ONEREQ(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        SKM_ASN1_SET_OF_d2i(OCSP_ONEREQ, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
# define i2d_ASN1_SET_OF_OCSP_ONEREQ(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        SKM_ASN1_SET_OF_i2d(OCSP_ONEREQ, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
# define ASN1_seq_pack_OCSP_ONEREQ(st, i2d_func, buf, len) \
        SKM_ASN1_seq_pack(OCSP_ONEREQ, (st), (i2d_func), (buf), (len))
# define ASN1_seq_unpack_OCSP_ONEREQ(buf, len, d2i_func, free_func) \
        SKM_ASN1_seq_unpack(OCSP_ONEREQ, (buf), (len), (d2i_func), (free_func))
# define d2i_ASN1_SET_OF_OCSP_SINGLERESP(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        SKM_ASN1_SET_OF_d2i(OCSP_SINGLERESP, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
# define i2d_ASN1_SET_OF_OCSP_SINGLERESP(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        SKM_ASN1_SET_OF_i2d(OCSP_SINGLERESP, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
# define ASN1_seq_pack_OCSP_SINGLERESP(st, i2d_func, buf, len) \
        SKM_ASN1_seq_pack(OCSP_SINGLERESP, (st), (i2d_func), (buf), (len))
# define ASN1_seq_unpack_OCSP_SINGLERESP(buf, len, d2i_func, free_func) \
        SKM_ASN1_seq_unpack(OCSP_SINGLERESP, (buf), (len), (d2i_func), (free_func))
# define d2i_ASN1_SET_OF_PKCS12_SAFEBAG(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        SKM_ASN1_SET_OF_d2i(PKCS12_SAFEBAG, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
# define i2d_ASN1_SET_OF_PKCS12_SAFEBAG(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        SKM_ASN1_SET_OF_i2d(PKCS12_SAFEBAG, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
# define ASN1_seq_pack_PKCS12_SAFEBAG(st, i2d_func, buf, len) \
        SKM_ASN1_seq_pack(PKCS12_SAFEBAG, (st), (i2d_func), (buf), (len))
# define ASN1_seq_unpack_PKCS12_SAFEBAG(buf, len, d2i_func, free_func) \
        SKM_ASN1_seq_unpack(PKCS12_SAFEBAG, (buf), (len), (d2i_func), (free_func))
# define d2i_ASN1_SET_OF_PKCS7(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        SKM_ASN1_SET_OF_d2i(PKCS7, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
# define i2d_ASN1_SET_OF_PKCS7(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        SKM_ASN1_SET_OF_i2d(PKCS7, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
# define ASN1_seq_pack_PKCS7(st, i2d_func, buf, len) \
        SKM_ASN1_seq_pack(PKCS7, (st), (i2d_func), (buf), (len))
# define ASN1_seq_unpack_PKCS7(buf, len, d2i_func, free_func) \
        SKM_ASN1_seq_unpack(PKCS7, (buf), (len), (d2i_func), (free_func))
# define d2i_ASN1_SET_OF_PKCS7_RECIP_INFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        SKM_ASN1_SET_OF_d2i(PKCS7_RECIP_INFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
# define i2d_ASN1_SET_OF_PKCS7_RECIP_INFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        SKM_ASN1_SET_OF_i2d(PKCS7_RECIP_INFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
# define ASN1_seq_pack_PKCS7_RECIP_INFO(st, i2d_func, buf, len) \
        SKM_ASN1_seq_pack(PKCS7_RECIP_INFO, (st), (i2d_func), (buf), (len))
# define ASN1_seq_unpack_PKCS7_RECIP_INFO(buf, len, d2i_func, free_func) \
        SKM_ASN1_seq_unpack(PKCS7_RECIP_INFO, (buf), (len), (d2i_func), (free_func))
# define d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        SKM_ASN1_SET_OF_d2i(PKCS7_SIGNER_INFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
# define i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        SKM_ASN1_SET_OF_i2d(PKCS7_SIGNER_INFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
# define ASN1_seq_pack_PKCS7_SIGNER_INFO(st, i2d_func, buf, len) \
        SKM_ASN1_seq_pack(PKCS7_SIGNER_INFO, (st), (i2d_func), (buf), (len))
# define ASN1_seq_unpack_PKCS7_SIGNER_INFO(buf, len, d2i_func, free_func) \
        SKM_ASN1_seq_unpack(PKCS7_SIGNER_INFO, (buf), (len), (d2i_func), (free_func))
# define d2i_ASN1_SET_OF_POLICYINFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        SKM_ASN1_SET_OF_d2i(POLICYINFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
# define i2d_ASN1_SET_OF_POLICYINFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        SKM_ASN1_SET_OF_i2d(POLICYINFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
# define ASN1_seq_pack_POLICYINFO(st, i2d_func, buf, len) \
        SKM_ASN1_seq_pack(POLICYINFO, (st), (i2d_func), (buf), (len))
# define ASN1_seq_unpack_POLICYINFO(buf, len, d2i_func, free_func) \
        SKM_ASN1_seq_unpack(POLICYINFO, (buf), (len), (d2i_func), (free_func))
# define d2i_ASN1_SET_OF_POLICYQUALINFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        SKM_ASN1_SET_OF_d2i(POLICYQUALINFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
# define i2d_ASN1_SET_OF_POLICYQUALINFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        SKM_ASN1_SET_OF_i2d(POLICYQUALINFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
# define ASN1_seq_pack_POLICYQUALINFO(st, i2d_func, buf, len) \
        SKM_ASN1_seq_pack(POLICYQUALINFO, (st), (i2d_func), (buf), (len))
# define ASN1_seq_unpack_POLICYQUALINFO(buf, len, d2i_func, free_func) \
        SKM_ASN1_seq_unpack(POLICYQUALINFO, (buf), (len), (d2i_func), (free_func))
# define d2i_ASN1_SET_OF_SXNETID(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        SKM_ASN1_SET_OF_d2i(SXNETID, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
# define i2d_ASN1_SET_OF_SXNETID(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        SKM_ASN1_SET_OF_i2d(SXNETID, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
# define ASN1_seq_pack_SXNETID(st, i2d_func, buf, len) \
        SKM_ASN1_seq_pack(SXNETID, (st), (i2d_func), (buf), (len))
# define ASN1_seq_unpack_SXNETID(buf, len, d2i_func, free_func) \
        SKM_ASN1_seq_unpack(SXNETID, (buf), (len), (d2i_func), (free_func))
# define d2i_ASN1_SET_OF_X509(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        SKM_ASN1_SET_OF_d2i(X509, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
# define i2d_ASN1_SET_OF_X509(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        SKM_ASN1_SET_OF_i2d(X509, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
# define ASN1_seq_pack_X509(st, i2d_func, buf, len) \
        SKM_ASN1_seq_pack(X509, (st), (i2d_func), (buf), (len))
# define ASN1_seq_unpack_X509(buf, len, d2i_func, free_func) \
        SKM_ASN1_seq_unpack(X509, (buf), (len), (d2i_func), (free_func))
# define d2i_ASN1_SET_OF_X509_ALGOR(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        SKM_ASN1_SET_OF_d2i(X509_ALGOR, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
# define i2d_ASN1_SET_OF_X509_ALGOR(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        SKM_ASN1_SET_OF_i2d(X509_ALGOR, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
# define ASN1_seq_pack_X509_ALGOR(st, i2d_func, buf, len) \
        SKM_ASN1_seq_pack(X509_ALGOR, (st), (i2d_func), (buf), (len))
# define ASN1_seq_unpack_X509_ALGOR(buf, len, d2i_func, free_func) \
        SKM_ASN1_seq_unpack(X509_ALGOR, (buf), (len), (d2i_func), (free_func))
# define d2i_ASN1_SET_OF_X509_ATTRIBUTE(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        SKM_ASN1_SET_OF_d2i(X509_ATTRIBUTE, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
# define i2d_ASN1_SET_OF_X509_ATTRIBUTE(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        SKM_ASN1_SET_OF_i2d(X509_ATTRIBUTE, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
# define ASN1_seq_pack_X509_ATTRIBUTE(st, i2d_func, buf, len) \
        SKM_ASN1_seq_pack(X509_ATTRIBUTE, (st), (i2d_func), (buf), (len))
# define ASN1_seq_unpack_X509_ATTRIBUTE(buf, len, d2i_func, free_func) \
        SKM_ASN1_seq_unpack(X509_ATTRIBUTE, (buf), (len), (d2i_func), (free_func))
# define d2i_ASN1_SET_OF_X509_CRL(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        SKM_ASN1_SET_OF_d2i(X509_CRL, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
# define i2d_ASN1_SET_OF_X509_CRL(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        SKM_ASN1_SET_OF_i2d(X509_CRL, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
# define ASN1_seq_pack_X509_CRL(st, i2d_func, buf, len) \
        SKM_ASN1_seq_pack(X509_CRL, (st), (i2d_func), (buf), (len))
# define ASN1_seq_unpack_X509_CRL(buf, len, d2i_func, free_func) \
        SKM_ASN1_seq_unpack(X509_CRL, (buf), (len), (d2i_func), (free_func))
# define d2i_ASN1_SET_OF_X509_EXTENSION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        SKM_ASN1_SET_OF_d2i(X509_EXTENSION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
# define i2d_ASN1_SET_OF_X509_EXTENSION(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        SKM_ASN1_SET_OF_i2d(X509_EXTENSION, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
# define ASN1_seq_pack_X509_EXTENSION(st, i2d_func, buf, len) \
        SKM_ASN1_seq_pack(X509_EXTENSION, (st), (i2d_func), (buf), (len))
# define ASN1_seq_unpack_X509_EXTENSION(buf, len, d2i_func, free_func) \
        SKM_ASN1_seq_unpack(X509_EXTENSION, (buf), (len), (d2i_func), (free_func))
# define d2i_ASN1_SET_OF_X509_NAME_ENTRY(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        SKM_ASN1_SET_OF_d2i(X509_NAME_ENTRY, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
# define i2d_ASN1_SET_OF_X509_NAME_ENTRY(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        SKM_ASN1_SET_OF_i2d(X509_NAME_ENTRY, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
# define ASN1_seq_pack_X509_NAME_ENTRY(st, i2d_func, buf, len) \
        SKM_ASN1_seq_pack(X509_NAME_ENTRY, (st), (i2d_func), (buf), (len))
# define ASN1_seq_unpack_X509_NAME_ENTRY(buf, len, d2i_func, free_func) \
        SKM_ASN1_seq_unpack(X509_NAME_ENTRY, (buf), (len), (d2i_func), (free_func))
# define d2i_ASN1_SET_OF_X509_REVOKED(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
        SKM_ASN1_SET_OF_d2i(X509_REVOKED, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
# define i2d_ASN1_SET_OF_X509_REVOKED(st, pp, i2d_func, ex_tag, ex_class, is_set) \
        SKM_ASN1_SET_OF_i2d(X509_REVOKED, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
# define ASN1_seq_pack_X509_REVOKED(st, i2d_func, buf, len) \
        SKM_ASN1_seq_pack(X509_REVOKED, (st), (i2d_func), (buf), (len))
# define ASN1_seq_unpack_X509_REVOKED(buf, len, d2i_func, free_func) \
        SKM_ASN1_seq_unpack(X509_REVOKED, (buf), (len), (d2i_func), (free_func))
# define PKCS12_decrypt_d2i_PKCS12_SAFEBAG(algor, d2i_func, free_func, pass, passlen, oct, seq) \
        SKM_PKCS12_decrypt_d2i(PKCS12_SAFEBAG, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq))
# define PKCS12_decrypt_d2i_PKCS7(algor, d2i_func, free_func, pass, passlen, oct, seq) \
        SKM_PKCS12_decrypt_d2i(PKCS7, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq))
# define lh_ADDED_OBJ_new() LHM_lh_new(ADDED_OBJ,added_obj)
# define lh_ADDED_OBJ_insert(lh,inst) LHM_lh_insert(ADDED_OBJ,lh,inst)
# define lh_ADDED_OBJ_retrieve(lh,inst) LHM_lh_retrieve(ADDED_OBJ,lh,inst)
# define lh_ADDED_OBJ_delete(lh,inst) LHM_lh_delete(ADDED_OBJ,lh,inst)
# define lh_ADDED_OBJ_doall(lh,fn) LHM_lh_doall(ADDED_OBJ,lh,fn)
# define lh_ADDED_OBJ_doall_arg(lh,fn,arg_type,arg) \
  LHM_lh_doall_arg(ADDED_OBJ,lh,fn,arg_type,arg)
# define lh_ADDED_OBJ_error(lh) LHM_lh_error(ADDED_OBJ,lh)
# define lh_ADDED_OBJ_num_items(lh) LHM_lh_num_items(ADDED_OBJ,lh)
# define lh_ADDED_OBJ_down_load(lh) LHM_lh_down_load(ADDED_OBJ,lh)
# define lh_ADDED_OBJ_node_stats_bio(lh,out) \
  LHM_lh_node_stats_bio(ADDED_OBJ,lh,out)
# define lh_ADDED_OBJ_node_usage_stats_bio(lh,out) \
  LHM_lh_node_usage_stats_bio(ADDED_OBJ,lh,out)
# define lh_ADDED_OBJ_stats_bio(lh,out) \
  LHM_lh_stats_bio(ADDED_OBJ,lh,out)
# define lh_ADDED_OBJ_free(lh) LHM_lh_free(ADDED_OBJ,lh)
# define lh_APP_INFO_new() LHM_lh_new(APP_INFO,app_info)
# define lh_APP_INFO_insert(lh,inst) LHM_lh_insert(APP_INFO,lh,inst)
# define lh_APP_INFO_retrieve(lh,inst) LHM_lh_retrieve(APP_INFO,lh,inst)
# define lh_APP_INFO_delete(lh,inst) LHM_lh_delete(APP_INFO,lh,inst)
# define lh_APP_INFO_doall(lh,fn) LHM_lh_doall(APP_INFO,lh,fn)
# define lh_APP_INFO_doall_arg(lh,fn,arg_type,arg) \
  LHM_lh_doall_arg(APP_INFO,lh,fn,arg_type,arg)
# define lh_APP_INFO_error(lh) LHM_lh_error(APP_INFO,lh)
# define lh_APP_INFO_num_items(lh) LHM_lh_num_items(APP_INFO,lh)
# define lh_APP_INFO_down_load(lh) LHM_lh_down_load(APP_INFO,lh)
# define lh_APP_INFO_node_stats_bio(lh,out) \
  LHM_lh_node_stats_bio(APP_INFO,lh,out)
# define lh_APP_INFO_node_usage_stats_bio(lh,out) \
  LHM_lh_node_usage_stats_bio(APP_INFO,lh,out)
# define lh_APP_INFO_stats_bio(lh,out) \
  LHM_lh_stats_bio(APP_INFO,lh,out)
# define lh_APP_INFO_free(lh) LHM_lh_free(APP_INFO,lh)
# define lh_CONF_VALUE_new() LHM_lh_new(CONF_VALUE,conf_value)
# define lh_CONF_VALUE_insert(lh,inst) LHM_lh_insert(CONF_VALUE,lh,inst)
# define lh_CONF_VALUE_retrieve(lh,inst) LHM_lh_retrieve(CONF_VALUE,lh,inst)
# define lh_CONF_VALUE_delete(lh,inst) LHM_lh_delete(CONF_VALUE,lh,inst)
# define lh_CONF_VALUE_doall(lh,fn) LHM_lh_doall(CONF_VALUE,lh,fn)
# define lh_CONF_VALUE_doall_arg(lh,fn,arg_type,arg) \
  LHM_lh_doall_arg(CONF_VALUE,lh,fn,arg_type,arg)
# define lh_CONF_VALUE_error(lh) LHM_lh_error(CONF_VALUE,lh)
# define lh_CONF_VALUE_num_items(lh) LHM_lh_num_items(CONF_VALUE,lh)
# define lh_CONF_VALUE_down_load(lh) LHM_lh_down_load(CONF_VALUE,lh)
# define lh_CONF_VALUE_node_stats_bio(lh,out) \
  LHM_lh_node_stats_bio(CONF_VALUE,lh,out)
# define lh_CONF_VALUE_node_usage_stats_bio(lh,out) \
  LHM_lh_node_usage_stats_bio(CONF_VALUE,lh,out)
# define lh_CONF_VALUE_stats_bio(lh,out) \
  LHM_lh_stats_bio(CONF_VALUE,lh,out)
# define lh_CONF_VALUE_free(lh) LHM_lh_free(CONF_VALUE,lh)
# define lh_ENGINE_PILE_new() LHM_lh_new(ENGINE_PILE,engine_pile)
# define lh_ENGINE_PILE_insert(lh,inst) LHM_lh_insert(ENGINE_PILE,lh,inst)
# define lh_ENGINE_PILE_retrieve(lh,inst) LHM_lh_retrieve(ENGINE_PILE,lh,inst)
# define lh_ENGINE_PILE_delete(lh,inst) LHM_lh_delete(ENGINE_PILE,lh,inst)
# define lh_ENGINE_PILE_doall(lh,fn) LHM_lh_doall(ENGINE_PILE,lh,fn)
# define lh_ENGINE_PILE_doall_arg(lh,fn,arg_type,arg) \
  LHM_lh_doall_arg(ENGINE_PILE,lh,fn,arg_type,arg)
# define lh_ENGINE_PILE_error(lh) LHM_lh_error(ENGINE_PILE,lh)
# define lh_ENGINE_PILE_num_items(lh) LHM_lh_num_items(ENGINE_PILE,lh)
# define lh_ENGINE_PILE_down_load(lh) LHM_lh_down_load(ENGINE_PILE,lh)
# define lh_ENGINE_PILE_node_stats_bio(lh,out) \
  LHM_lh_node_stats_bio(ENGINE_PILE,lh,out)
# define lh_ENGINE_PILE_node_usage_stats_bio(lh,out) \
  LHM_lh_node_usage_stats_bio(ENGINE_PILE,lh,out)
# define lh_ENGINE_PILE_stats_bio(lh,out) \
  LHM_lh_stats_bio(ENGINE_PILE,lh,out)
# define lh_ENGINE_PILE_free(lh) LHM_lh_free(ENGINE_PILE,lh)
# define lh_ERR_STATE_new() LHM_lh_new(ERR_STATE,err_state)
# define lh_ERR_STATE_insert(lh,inst) LHM_lh_insert(ERR_STATE,lh,inst)
# define lh_ERR_STATE_retrieve(lh,inst) LHM_lh_retrieve(ERR_STATE,lh,inst)
# define lh_ERR_STATE_delete(lh,inst) LHM_lh_delete(ERR_STATE,lh,inst)
# define lh_ERR_STATE_doall(lh,fn) LHM_lh_doall(ERR_STATE,lh,fn)
# define lh_ERR_STATE_doall_arg(lh,fn,arg_type,arg) \
  LHM_lh_doall_arg(ERR_STATE,lh,fn,arg_type,arg)
# define lh_ERR_STATE_error(lh) LHM_lh_error(ERR_STATE,lh)
# define lh_ERR_STATE_num_items(lh) LHM_lh_num_items(ERR_STATE,lh)
# define lh_ERR_STATE_down_load(lh) LHM_lh_down_load(ERR_STATE,lh)
# define lh_ERR_STATE_node_stats_bio(lh,out) \
  LHM_lh_node_stats_bio(ERR_STATE,lh,out)
# define lh_ERR_STATE_node_usage_stats_bio(lh,out) \
  LHM_lh_node_usage_stats_bio(ERR_STATE,lh,out)
# define lh_ERR_STATE_stats_bio(lh,out) \
  LHM_lh_stats_bio(ERR_STATE,lh,out)
# define lh_ERR_STATE_free(lh) LHM_lh_free(ERR_STATE,lh)
# define lh_ERR_STRING_DATA_new() LHM_lh_new(ERR_STRING_DATA,err_string_data)
# define lh_ERR_STRING_DATA_insert(lh,inst) LHM_lh_insert(ERR_STRING_DATA,lh,inst)
# define lh_ERR_STRING_DATA_retrieve(lh,inst) LHM_lh_retrieve(ERR_STRING_DATA,lh,inst)
# define lh_ERR_STRING_DATA_delete(lh,inst) LHM_lh_delete(ERR_STRING_DATA,lh,inst)
# define lh_ERR_STRING_DATA_doall(lh,fn) LHM_lh_doall(ERR_STRING_DATA,lh,fn)
# define lh_ERR_STRING_DATA_doall_arg(lh,fn,arg_type,arg) \
  LHM_lh_doall_arg(ERR_STRING_DATA,lh,fn,arg_type,arg)
# define lh_ERR_STRING_DATA_error(lh) LHM_lh_error(ERR_STRING_DATA,lh)
# define lh_ERR_STRING_DATA_num_items(lh) LHM_lh_num_items(ERR_STRING_DATA,lh)
# define lh_ERR_STRING_DATA_down_load(lh) LHM_lh_down_load(ERR_STRING_DATA,lh)
# define lh_ERR_STRING_DATA_node_stats_bio(lh,out) \
  LHM_lh_node_stats_bio(ERR_STRING_DATA,lh,out)
# define lh_ERR_STRING_DATA_node_usage_stats_bio(lh,out) \
  LHM_lh_node_usage_stats_bio(ERR_STRING_DATA,lh,out)
# define lh_ERR_STRING_DATA_stats_bio(lh,out) \
  LHM_lh_stats_bio(ERR_STRING_DATA,lh,out)
# define lh_ERR_STRING_DATA_free(lh) LHM_lh_free(ERR_STRING_DATA,lh)
# define lh_EX_CLASS_ITEM_new() LHM_lh_new(EX_CLASS_ITEM,ex_class_item)
# define lh_EX_CLASS_ITEM_insert(lh,inst) LHM_lh_insert(EX_CLASS_ITEM,lh,inst)
# define lh_EX_CLASS_ITEM_retrieve(lh,inst) LHM_lh_retrieve(EX_CLASS_ITEM,lh,inst)
# define lh_EX_CLASS_ITEM_delete(lh,inst) LHM_lh_delete(EX_CLASS_ITEM,lh,inst)
# define lh_EX_CLASS_ITEM_doall(lh,fn) LHM_lh_doall(EX_CLASS_ITEM,lh,fn)
# define lh_EX_CLASS_ITEM_doall_arg(lh,fn,arg_type,arg) \
  LHM_lh_doall_arg(EX_CLASS_ITEM,lh,fn,arg_type,arg)
# define lh_EX_CLASS_ITEM_error(lh) LHM_lh_error(EX_CLASS_ITEM,lh)
# define lh_EX_CLASS_ITEM_num_items(lh) LHM_lh_num_items(EX_CLASS_ITEM,lh)
# define lh_EX_CLASS_ITEM_down_load(lh) LHM_lh_down_load(EX_CLASS_ITEM,lh)
# define lh_EX_CLASS_ITEM_node_stats_bio(lh,out) \
  LHM_lh_node_stats_bio(EX_CLASS_ITEM,lh,out)
# define lh_EX_CLASS_ITEM_node_usage_stats_bio(lh,out) \
  LHM_lh_node_usage_stats_bio(EX_CLASS_ITEM,lh,out)
# define lh_EX_CLASS_ITEM_stats_bio(lh,out) \
  LHM_lh_stats_bio(EX_CLASS_ITEM,lh,out)
# define lh_EX_CLASS_ITEM_free(lh) LHM_lh_free(EX_CLASS_ITEM,lh)
# define lh_FUNCTION_new() LHM_lh_new(FUNCTION,function)
# define lh_FUNCTION_insert(lh,inst) LHM_lh_insert(FUNCTION,lh,inst)
# define lh_FUNCTION_retrieve(lh,inst) LHM_lh_retrieve(FUNCTION,lh,inst)
# define lh_FUNCTION_delete(lh,inst) LHM_lh_delete(FUNCTION,lh,inst)
# define lh_FUNCTION_doall(lh,fn) LHM_lh_doall(FUNCTION,lh,fn)
# define lh_FUNCTION_doall_arg(lh,fn,arg_type,arg) \
  LHM_lh_doall_arg(FUNCTION,lh,fn,arg_type,arg)
# define lh_FUNCTION_error(lh) LHM_lh_error(FUNCTION,lh)
# define lh_FUNCTION_num_items(lh) LHM_lh_num_items(FUNCTION,lh)
# define lh_FUNCTION_down_load(lh) LHM_lh_down_load(FUNCTION,lh)
# define lh_FUNCTION_node_stats_bio(lh,out) \
  LHM_lh_node_stats_bio(FUNCTION,lh,out)
# define lh_FUNCTION_node_usage_stats_bio(lh,out) \
  LHM_lh_node_usage_stats_bio(FUNCTION,lh,out)
# define lh_FUNCTION_stats_bio(lh,out) \
  LHM_lh_stats_bio(FUNCTION,lh,out)
# define lh_FUNCTION_free(lh) LHM_lh_free(FUNCTION,lh)
# define lh_MEM_new() LHM_lh_new(MEM,mem)
# define lh_MEM_insert(lh,inst) LHM_lh_insert(MEM,lh,inst)
# define lh_MEM_retrieve(lh,inst) LHM_lh_retrieve(MEM,lh,inst)
# define lh_MEM_delete(lh,inst) LHM_lh_delete(MEM,lh,inst)
# define lh_MEM_doall(lh,fn) LHM_lh_doall(MEM,lh,fn)
# define lh_MEM_doall_arg(lh,fn,arg_type,arg) \
  LHM_lh_doall_arg(MEM,lh,fn,arg_type,arg)
# define lh_MEM_error(lh) LHM_lh_error(MEM,lh)
# define lh_MEM_num_items(lh) LHM_lh_num_items(MEM,lh)
# define lh_MEM_down_load(lh) LHM_lh_down_load(MEM,lh)
# define lh_MEM_node_stats_bio(lh,out) \
  LHM_lh_node_stats_bio(MEM,lh,out)
# define lh_MEM_node_usage_stats_bio(lh,out) \
  LHM_lh_node_usage_stats_bio(MEM,lh,out)
# define lh_MEM_stats_bio(lh,out) \
  LHM_lh_stats_bio(MEM,lh,out)
# define lh_MEM_free(lh) LHM_lh_free(MEM,lh)
# define lh_OBJ_NAME_new() LHM_lh_new(OBJ_NAME,obj_name)
# define lh_OBJ_NAME_insert(lh,inst) LHM_lh_insert(OBJ_NAME,lh,inst)
# define lh_OBJ_NAME_retrieve(lh,inst) LHM_lh_retrieve(OBJ_NAME,lh,inst)
# define lh_OBJ_NAME_delete(lh,inst) LHM_lh_delete(OBJ_NAME,lh,inst)
# define lh_OBJ_NAME_doall(lh,fn) LHM_lh_doall(OBJ_NAME,lh,fn)
# define lh_OBJ_NAME_doall_arg(lh,fn,arg_type,arg) \
  LHM_lh_doall_arg(OBJ_NAME,lh,fn,arg_type,arg)
# define lh_OBJ_NAME_error(lh) LHM_lh_error(OBJ_NAME,lh)
# define lh_OBJ_NAME_num_items(lh) LHM_lh_num_items(OBJ_NAME,lh)
# define lh_OBJ_NAME_down_load(lh) LHM_lh_down_load(OBJ_NAME,lh)
# define lh_OBJ_NAME_node_stats_bio(lh,out) \
  LHM_lh_node_stats_bio(OBJ_NAME,lh,out)
# define lh_OBJ_NAME_node_usage_stats_bio(lh,out) \
  LHM_lh_node_usage_stats_bio(OBJ_NAME,lh,out)
# define lh_OBJ_NAME_stats_bio(lh,out) \
  LHM_lh_stats_bio(OBJ_NAME,lh,out)
# define lh_OBJ_NAME_free(lh) LHM_lh_free(OBJ_NAME,lh)
# define lh_OPENSSL_CSTRING_new() LHM_lh_new(OPENSSL_CSTRING,openssl_cstring)
# define lh_OPENSSL_CSTRING_insert(lh,inst) LHM_lh_insert(OPENSSL_CSTRING,lh,inst)
# define lh_OPENSSL_CSTRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_CSTRING,lh,inst)
# define lh_OPENSSL_CSTRING_delete(lh,inst) LHM_lh_delete(OPENSSL_CSTRING,lh,inst)
# define lh_OPENSSL_CSTRING_doall(lh,fn) LHM_lh_doall(OPENSSL_CSTRING,lh,fn)
# define lh_OPENSSL_CSTRING_doall_arg(lh,fn,arg_type,arg) \
  LHM_lh_doall_arg(OPENSSL_CSTRING,lh,fn,arg_type,arg)
# define lh_OPENSSL_CSTRING_error(lh) LHM_lh_error(OPENSSL_CSTRING,lh)
# define lh_OPENSSL_CSTRING_num_items(lh) LHM_lh_num_items(OPENSSL_CSTRING,lh)
# define lh_OPENSSL_CSTRING_down_load(lh) LHM_lh_down_load(OPENSSL_CSTRING,lh)
# define lh_OPENSSL_CSTRING_node_stats_bio(lh,out) \
  LHM_lh_node_stats_bio(OPENSSL_CSTRING,lh,out)
# define lh_OPENSSL_CSTRING_node_usage_stats_bio(lh,out) \
  LHM_lh_node_usage_stats_bio(OPENSSL_CSTRING,lh,out)
# define lh_OPENSSL_CSTRING_stats_bio(lh,out) \
  LHM_lh_stats_bio(OPENSSL_CSTRING,lh,out)
# define lh_OPENSSL_CSTRING_free(lh) LHM_lh_free(OPENSSL_CSTRING,lh)
# define lh_OPENSSL_STRING_new() LHM_lh_new(OPENSSL_STRING,openssl_string)
# define lh_OPENSSL_STRING_insert(lh,inst) LHM_lh_insert(OPENSSL_STRING,lh,inst)
# define lh_OPENSSL_STRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_STRING,lh,inst)
# define lh_OPENSSL_STRING_delete(lh,inst) LHM_lh_delete(OPENSSL_STRING,lh,inst)
# define lh_OPENSSL_STRING_doall(lh,fn) LHM_lh_doall(OPENSSL_STRING,lh,fn)
# define lh_OPENSSL_STRING_doall_arg(lh,fn,arg_type,arg) \
  LHM_lh_doall_arg(OPENSSL_STRING,lh,fn,arg_type,arg)
# define lh_OPENSSL_STRING_error(lh) LHM_lh_error(OPENSSL_STRING,lh)
# define lh_OPENSSL_STRING_num_items(lh) LHM_lh_num_items(OPENSSL_STRING,lh)
# define lh_OPENSSL_STRING_down_load(lh) LHM_lh_down_load(OPENSSL_STRING,lh)
# define lh_OPENSSL_STRING_node_stats_bio(lh,out) \
  LHM_lh_node_stats_bio(OPENSSL_STRING,lh,out)
# define lh_OPENSSL_STRING_node_usage_stats_bio(lh,out) \
  LHM_lh_node_usage_stats_bio(OPENSSL_STRING,lh,out)
# define lh_OPENSSL_STRING_stats_bio(lh,out) \
  LHM_lh_stats_bio(OPENSSL_STRING,lh,out)
# define lh_OPENSSL_STRING_free(lh) LHM_lh_free(OPENSSL_STRING,lh)
# define lh_SSL_SESSION_new() LHM_lh_new(SSL_SESSION,ssl_session)
# define lh_SSL_SESSION_insert(lh,inst) LHM_lh_insert(SSL_SESSION,lh,inst)
# define lh_SSL_SESSION_retrieve(lh,inst) LHM_lh_retrieve(SSL_SESSION,lh,inst)
# define lh_SSL_SESSION_delete(lh,inst) LHM_lh_delete(SSL_SESSION,lh,inst)
# define lh_SSL_SESSION_doall(lh,fn) LHM_lh_doall(SSL_SESSION,lh,fn)
# define lh_SSL_SESSION_doall_arg(lh,fn,arg_type,arg) \
  LHM_lh_doall_arg(SSL_SESSION,lh,fn,arg_type,arg)
# define lh_SSL_SESSION_error(lh) LHM_lh_error(SSL_SESSION,lh)
# define lh_SSL_SESSION_num_items(lh) LHM_lh_num_items(SSL_SESSION,lh)
# define lh_SSL_SESSION_down_load(lh) LHM_lh_down_load(SSL_SESSION,lh)
# define lh_SSL_SESSION_node_stats_bio(lh,out) \
  LHM_lh_node_stats_bio(SSL_SESSION,lh,out)
# define lh_SSL_SESSION_node_usage_stats_bio(lh,out) \
  LHM_lh_node_usage_stats_bio(SSL_SESSION,lh,out)
# define lh_SSL_SESSION_stats_bio(lh,out) \
  LHM_lh_stats_bio(SSL_SESSION,lh,out)
# define lh_SSL_SESSION_free(lh) LHM_lh_free(SSL_SESSION,lh)
#ifdef  __cplusplus
}
#endif
#endif                          /* !defined HEADER_SAFESTACK_H */
openssl/dsa.h000064400000035542151733316620007167 0ustar00/* crypto/dsa/dsa.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

/*
 * The DSS routines are based on patches supplied by
 * Steven Schoch <schoch@sheba.arc.nasa.gov>.  He basically did the
 * work and I have just tweaked them a little to fit into my
 * stylistic vision for SSLeay :-) */

#ifndef HEADER_DSA_H
# define HEADER_DSA_H

# include <openssl/e_os2.h>

# ifdef OPENSSL_NO_DSA
#  error DSA is disabled.
# endif

# ifndef OPENSSL_NO_BIO
#  include <openssl/bio.h>
# endif
# include <openssl/crypto.h>
# include <openssl/ossl_typ.h>

# ifndef OPENSSL_NO_DEPRECATED
#  include <openssl/bn.h>
#  ifndef OPENSSL_NO_DH
#   include <openssl/dh.h>
#  endif
# endif

# ifndef OPENSSL_DSA_MAX_MODULUS_BITS
#  define OPENSSL_DSA_MAX_MODULUS_BITS   10000
# endif

# define OPENSSL_DSA_FIPS_MIN_MODULUS_BITS 1024
# define OPENSSL_DSA_FIPS_MIN_MODULUS_BITS_GEN (getenv("OPENSSL_ENFORCE_MODULUS_BITS")?2048:1024)

# define DSA_FLAG_CACHE_MONT_P   0x01
/*
 * new with 0.9.7h; the built-in DSA implementation now uses constant time
 * modular exponentiation for secret exponents by default. This flag causes
 * the faster variable sliding window method to be used for all exponents.
 */
# define DSA_FLAG_NO_EXP_CONSTTIME       0x02

/*
 * If this flag is set the DSA method is FIPS compliant and can be used in
 * FIPS mode. This is set in the validated module method. If an application
 * sets this flag in its own methods it is its reposibility to ensure the
 * result is compliant.
 */

# define DSA_FLAG_FIPS_METHOD                    0x0400

/*
 * If this flag is set the operations normally disabled in FIPS mode are
 * permitted it is then the applications responsibility to ensure that the
 * usage is compliant.
 */

# define DSA_FLAG_NON_FIPS_ALLOW                 0x0400

#ifdef  __cplusplus
extern "C" {
#endif

/* Already defined in ossl_typ.h */
/* typedef struct dsa_st DSA; */
/* typedef struct dsa_method DSA_METHOD; */

typedef struct DSA_SIG_st {
    BIGNUM *r;
    BIGNUM *s;
} DSA_SIG;

struct dsa_method {
    const char *name;
    DSA_SIG *(*dsa_do_sign) (const unsigned char *dgst, int dlen, DSA *dsa);
    int (*dsa_sign_setup) (DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
                           BIGNUM **rp);
    int (*dsa_do_verify) (const unsigned char *dgst, int dgst_len,
                          DSA_SIG *sig, DSA *dsa);
    int (*dsa_mod_exp) (DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1,
                        BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx,
                        BN_MONT_CTX *in_mont);
    /* Can be null */
    int (*bn_mod_exp) (DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
                       const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
    int (*init) (DSA *dsa);
    int (*finish) (DSA *dsa);
    int flags;
    char *app_data;
    /* If this is non-NULL, it is used to generate DSA parameters */
    int (*dsa_paramgen) (DSA *dsa, int bits,
                         const unsigned char *seed, int seed_len,
                         int *counter_ret, unsigned long *h_ret,
                         BN_GENCB *cb);
    /* If this is non-NULL, it is used to generate DSA keys */
    int (*dsa_keygen) (DSA *dsa);
};

struct dsa_st {
    /*
     * This first variable is used to pick up errors where a DSA is passed
     * instead of of a EVP_PKEY
     */
    int pad;
    long version;
    int write_params;
    BIGNUM *p;
    BIGNUM *q;                  /* == 20 */
    BIGNUM *g;
    BIGNUM *pub_key;            /* y public key */
    BIGNUM *priv_key;           /* x private key */
    BIGNUM *kinv;               /* Signing pre-calc */
    BIGNUM *r;                  /* Signing pre-calc */
    int flags;
    /* Normally used to cache montgomery values */
    BN_MONT_CTX *method_mont_p;
    int references;
    CRYPTO_EX_DATA ex_data;
    const DSA_METHOD *meth;
    /* functional reference if 'meth' is ENGINE-provided */
    ENGINE *engine;
};

# define d2i_DSAparams_fp(fp,x) (DSA *)ASN1_d2i_fp((char *(*)())DSA_new, \
                (char *(*)())d2i_DSAparams,(fp),(unsigned char **)(x))
# define i2d_DSAparams_fp(fp,x) ASN1_i2d_fp(i2d_DSAparams,(fp), \
                (unsigned char *)(x))
# define d2i_DSAparams_bio(bp,x) ASN1_d2i_bio_of(DSA,DSA_new,d2i_DSAparams,bp,x)
# define i2d_DSAparams_bio(bp,x) ASN1_i2d_bio_of_const(DSA,i2d_DSAparams,bp,x)

DSA *DSAparams_dup(DSA *x);
DSA_SIG *DSA_SIG_new(void);
void DSA_SIG_free(DSA_SIG *a);
int i2d_DSA_SIG(const DSA_SIG *a, unsigned char **pp);
DSA_SIG *d2i_DSA_SIG(DSA_SIG **v, const unsigned char **pp, long length);

DSA_SIG *DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
int DSA_do_verify(const unsigned char *dgst, int dgst_len,
                  DSA_SIG *sig, DSA *dsa);

const DSA_METHOD *DSA_OpenSSL(void);

void DSA_set_default_method(const DSA_METHOD *);
const DSA_METHOD *DSA_get_default_method(void);
int DSA_set_method(DSA *dsa, const DSA_METHOD *);

DSA *DSA_new(void);
DSA *DSA_new_method(ENGINE *engine);
void DSA_free(DSA *r);
/* "up" the DSA object's reference count */
int DSA_up_ref(DSA *r);
int DSA_size(const DSA *);
        /* next 4 return -1 on error */
int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp);
int DSA_sign(int type, const unsigned char *dgst, int dlen,
             unsigned char *sig, unsigned int *siglen, DSA *dsa);
int DSA_verify(int type, const unsigned char *dgst, int dgst_len,
               const unsigned char *sigbuf, int siglen, DSA *dsa);
int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
                         CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
int DSA_set_ex_data(DSA *d, int idx, void *arg);
void *DSA_get_ex_data(DSA *d, int idx);

DSA *d2i_DSAPublicKey(DSA **a, const unsigned char **pp, long length);
DSA *d2i_DSAPrivateKey(DSA **a, const unsigned char **pp, long length);
DSA *d2i_DSAparams(DSA **a, const unsigned char **pp, long length);

/* Deprecated version */
# ifndef OPENSSL_NO_DEPRECATED
DSA *DSA_generate_parameters(int bits,
                             unsigned char *seed, int seed_len,
                             int *counter_ret, unsigned long *h_ret, void
                              (*callback) (int, int, void *), void *cb_arg);
# endif                         /* !defined(OPENSSL_NO_DEPRECATED) */

/* New version */
int DSA_generate_parameters_ex(DSA *dsa, int bits,
                               const unsigned char *seed, int seed_len,
                               int *counter_ret, unsigned long *h_ret,
                               BN_GENCB *cb);

int DSA_generate_key(DSA *a);
int i2d_DSAPublicKey(const DSA *a, unsigned char **pp);
int i2d_DSAPrivateKey(const DSA *a, unsigned char **pp);
int i2d_DSAparams(const DSA *a, unsigned char **pp);

# ifndef OPENSSL_NO_BIO
int DSAparams_print(BIO *bp, const DSA *x);
int DSA_print(BIO *bp, const DSA *x, int off);
# endif
# ifndef OPENSSL_NO_FP_API
int DSAparams_print_fp(FILE *fp, const DSA *x);
int DSA_print_fp(FILE *bp, const DSA *x, int off);
# endif

# define DSS_prime_checks 64
/*
 * Primality test according to FIPS PUB 186-4, Appendix C.3. Since we only
 * have one value here we set the number of checks to 64 which is the 128 bit
 * security level that is the highest level and valid for creating a 3072 bit
 * DSA key.
 */
# define DSA_is_prime(n, callback, cb_arg) \
        BN_is_prime(n, DSS_prime_checks, callback, NULL, cb_arg)

# ifndef OPENSSL_NO_DH
/*
 * Convert DSA structure (key or just parameters) into DH structure (be
 * careful to avoid small subgroup attacks when using this!)
 */
DH *DSA_dup_DH(const DSA *r);
# endif

# ifdef OPENSSL_FIPS
int FIPS_dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
                              const EVP_MD *evpmd,
                              const unsigned char *seed_in,
                              size_t seed_len, int *counter_ret,
                              unsigned long *h_ret, BN_GENCB *cb);
int FIPS_dsa_generate_pq(BN_CTX *ctx, size_t bits, size_t qbits,
                         const EVP_MD *evpmd, unsigned char *seed,
                         int seed_len, BIGNUM **p_ret, BIGNUM **q_ret,
                         int *counter_ret, BN_GENCB *cb);
int FIPS_dsa_generate_g(BN_CTX *ctx, BIGNUM *p, BIGNUM *q, BIGNUM **g_ret,
                            unsigned long *h_ret, BN_GENCB *cb);
# endif

# define EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \
                                EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, nbits, NULL)

# define EVP_PKEY_CTRL_DSA_PARAMGEN_BITS         (EVP_PKEY_ALG_CTRL + 1)
# define EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS       (EVP_PKEY_ALG_CTRL + 2)
# define EVP_PKEY_CTRL_DSA_PARAMGEN_MD           (EVP_PKEY_ALG_CTRL + 3)

/* BEGIN ERROR CODES */
/*
 * The following lines are auto generated by the script mkerr.pl. Any changes
 * made after this point may be overwritten when the script is next run.
 */
void ERR_load_DSA_strings(void);

/* Error codes for the DSA functions. */

/* Function codes. */
# define DSA_F_D2I_DSA_SIG                                110
# define DSA_F_DO_DSA_PRINT                               104
# define DSA_F_DSAPARAMS_PRINT                            100
# define DSA_F_DSAPARAMS_PRINT_FP                         101
# define DSA_F_DSA_BUILTIN_KEYGEN                         124
# define DSA_F_DSA_BUILTIN_PARAMGEN                       123
# define DSA_F_DSA_BUILTIN_PARAMGEN2                      226
# define DSA_F_DSA_DO_SIGN                                112
# define DSA_F_DSA_DO_VERIFY                              113
# define DSA_F_DSA_GENERATE_KEY                           126
# define DSA_F_DSA_GENERATE_PARAMETERS_EX                 127
# define DSA_F_DSA_GENERATE_PARAMETERS   /* unused */     125
# define DSA_F_DSA_NEW_METHOD                             103
# define DSA_F_DSA_PARAM_DECODE                           119
# define DSA_F_DSA_PRINT_FP                               105
# define DSA_F_DSA_PRIV_DECODE                            115
# define DSA_F_DSA_PRIV_ENCODE                            116
# define DSA_F_DSA_PUB_DECODE                             117
# define DSA_F_DSA_PUB_ENCODE                             118
# define DSA_F_DSA_SIGN                                   106
# define DSA_F_DSA_SIGN_SETUP                             107
# define DSA_F_DSA_SIG_NEW                                109
# define DSA_F_DSA_SIG_PRINT                              125
# define DSA_F_DSA_VERIFY                                 108
# define DSA_F_I2D_DSA_SIG                                111
# define DSA_F_OLD_DSA_PRIV_DECODE                        122
# define DSA_F_PKEY_DSA_CTRL                              120
# define DSA_F_PKEY_DSA_CTRL_STR                          127
# define DSA_F_PKEY_DSA_KEYGEN                            121
# define DSA_F_SIG_CB                                     114

/* Reason codes. */
# define DSA_R_BAD_Q_VALUE                                102
# define DSA_R_BN_DECODE_ERROR                            108
# define DSA_R_BN_ERROR                                   109
# define DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE                100
# define DSA_R_DECODE_ERROR                               104
# define DSA_R_INVALID_DIGEST_TYPE                        106
# define DSA_R_INVALID_PARAMETERS                         212
# define DSA_R_KEY_SIZE_INVALID                           113
# define DSA_R_KEY_SIZE_TOO_SMALL                         110
# define DSA_R_MISSING_PARAMETERS                         101
# define DSA_R_MODULUS_TOO_LARGE                          103
# define DSA_R_NEED_NEW_SETUP_VALUES                      112
# define DSA_R_NON_FIPS_DSA_METHOD                        111
# define DSA_R_NON_FIPS_METHOD                            111
# define DSA_R_NO_PARAMETERS_SET                          107
# define DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE /* unused */ 112
# define DSA_R_PARAMETER_ENCODING_ERROR                   105
# define DSA_R_Q_NOT_PRIME                                113

#ifdef  __cplusplus
}
#endif
#endif
openssl/bio.h000064400000113526151733316620007170 0ustar00/* crypto/bio/bio.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#ifndef HEADER_BIO_H
# define HEADER_BIO_H

# include <openssl/e_os2.h>

# ifndef OPENSSL_NO_FP_API
#  include <stdio.h>
# endif
# include <stdarg.h>

# include <openssl/crypto.h>

# ifndef OPENSSL_NO_SCTP
#  ifndef OPENSSL_SYS_VMS
#   include <stdint.h>
#  else
#   include <inttypes.h>
#  endif
# endif

#ifdef  __cplusplus
extern "C" {
#endif

/* These are the 'types' of BIOs */
# define BIO_TYPE_NONE           0
# define BIO_TYPE_MEM            (1|0x0400)
# define BIO_TYPE_FILE           (2|0x0400)

# define BIO_TYPE_FD             (4|0x0400|0x0100)
# define BIO_TYPE_SOCKET         (5|0x0400|0x0100)
# define BIO_TYPE_NULL           (6|0x0400)
# define BIO_TYPE_SSL            (7|0x0200)
# define BIO_TYPE_MD             (8|0x0200)/* passive filter */
# define BIO_TYPE_BUFFER         (9|0x0200)/* filter */
# define BIO_TYPE_CIPHER         (10|0x0200)/* filter */
# define BIO_TYPE_BASE64         (11|0x0200)/* filter */
# define BIO_TYPE_CONNECT        (12|0x0400|0x0100)/* socket - connect */
# define BIO_TYPE_ACCEPT         (13|0x0400|0x0100)/* socket for accept */
# define BIO_TYPE_PROXY_CLIENT   (14|0x0200)/* client proxy BIO */
# define BIO_TYPE_PROXY_SERVER   (15|0x0200)/* server proxy BIO */
# define BIO_TYPE_NBIO_TEST      (16|0x0200)/* server proxy BIO */
# define BIO_TYPE_NULL_FILTER    (17|0x0200)
# define BIO_TYPE_BER            (18|0x0200)/* BER -> bin filter */
# define BIO_TYPE_BIO            (19|0x0400)/* (half a) BIO pair */
# define BIO_TYPE_LINEBUFFER     (20|0x0200)/* filter */
# define BIO_TYPE_DGRAM          (21|0x0400|0x0100)
# ifndef OPENSSL_NO_SCTP
#  define BIO_TYPE_DGRAM_SCTP     (24|0x0400|0x0100)
# endif
# define BIO_TYPE_ASN1           (22|0x0200)/* filter */
# define BIO_TYPE_COMP           (23|0x0200)/* filter */

# define BIO_TYPE_DESCRIPTOR     0x0100/* socket, fd, connect or accept */
# define BIO_TYPE_FILTER         0x0200
# define BIO_TYPE_SOURCE_SINK    0x0400

/*
 * BIO_FILENAME_READ|BIO_CLOSE to open or close on free.
 * BIO_set_fp(in,stdin,BIO_NOCLOSE);
 */
# define BIO_NOCLOSE             0x00
# define BIO_CLOSE               0x01

/*
 * These are used in the following macros and are passed to BIO_ctrl()
 */
# define BIO_CTRL_RESET          1/* opt - rewind/zero etc */
# define BIO_CTRL_EOF            2/* opt - are we at the eof */
# define BIO_CTRL_INFO           3/* opt - extra tit-bits */
# define BIO_CTRL_SET            4/* man - set the 'IO' type */
# define BIO_CTRL_GET            5/* man - get the 'IO' type */
# define BIO_CTRL_PUSH           6/* opt - internal, used to signify change */
# define BIO_CTRL_POP            7/* opt - internal, used to signify change */
# define BIO_CTRL_GET_CLOSE      8/* man - set the 'close' on free */
# define BIO_CTRL_SET_CLOSE      9/* man - set the 'close' on free */
# define BIO_CTRL_PENDING        10/* opt - is their more data buffered */
# define BIO_CTRL_FLUSH          11/* opt - 'flush' buffered output */
# define BIO_CTRL_DUP            12/* man - extra stuff for 'duped' BIO */
# define BIO_CTRL_WPENDING       13/* opt - number of bytes still to write */
/* callback is int cb(BIO *bio,state,ret); */
# define BIO_CTRL_SET_CALLBACK   14/* opt - set callback function */
# define BIO_CTRL_GET_CALLBACK   15/* opt - set callback function */

# define BIO_CTRL_SET_FILENAME   30/* BIO_s_file special */

/* dgram BIO stuff */
# define BIO_CTRL_DGRAM_CONNECT       31/* BIO dgram special */
# define BIO_CTRL_DGRAM_SET_CONNECTED 32/* allow for an externally connected
                                         * socket to be passed in */
# define BIO_CTRL_DGRAM_SET_RECV_TIMEOUT 33/* setsockopt, essentially */
# define BIO_CTRL_DGRAM_GET_RECV_TIMEOUT 34/* getsockopt, essentially */
# define BIO_CTRL_DGRAM_SET_SEND_TIMEOUT 35/* setsockopt, essentially */
# define BIO_CTRL_DGRAM_GET_SEND_TIMEOUT 36/* getsockopt, essentially */

# define BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP 37/* flag whether the last */
# define BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP 38/* I/O operation tiemd out */

/* #ifdef IP_MTU_DISCOVER */
# define BIO_CTRL_DGRAM_MTU_DISCOVER       39/* set DF bit on egress packets */
/* #endif */

# define BIO_CTRL_DGRAM_QUERY_MTU          40/* as kernel for current MTU */
# define BIO_CTRL_DGRAM_GET_FALLBACK_MTU   47
# define BIO_CTRL_DGRAM_GET_MTU            41/* get cached value for MTU */
# define BIO_CTRL_DGRAM_SET_MTU            42/* set cached value for MTU.
                                              * want to use this if asking
                                              * the kernel fails */

# define BIO_CTRL_DGRAM_MTU_EXCEEDED       43/* check whether the MTU was
                                              * exceed in the previous write
                                              * operation */

# define BIO_CTRL_DGRAM_GET_PEER           46
# define BIO_CTRL_DGRAM_SET_PEER           44/* Destination for the data */

# define BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT   45/* Next DTLS handshake timeout
                                              * to adjust socket timeouts */
# define BIO_CTRL_DGRAM_SET_DONT_FRAG      48

# define BIO_CTRL_DGRAM_GET_MTU_OVERHEAD   49

# ifndef OPENSSL_NO_SCTP
/* SCTP stuff */
#  define BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE    50
#  define BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY                51
#  define BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY               52
#  define BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD               53
#  define BIO_CTRL_DGRAM_SCTP_GET_SNDINFO         60
#  define BIO_CTRL_DGRAM_SCTP_SET_SNDINFO         61
#  define BIO_CTRL_DGRAM_SCTP_GET_RCVINFO         62
#  define BIO_CTRL_DGRAM_SCTP_SET_RCVINFO         63
#  define BIO_CTRL_DGRAM_SCTP_GET_PRINFO                  64
#  define BIO_CTRL_DGRAM_SCTP_SET_PRINFO                  65
#  define BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN               70
# endif

/* modifiers */
# define BIO_FP_READ             0x02
# define BIO_FP_WRITE            0x04
# define BIO_FP_APPEND           0x08
# define BIO_FP_TEXT             0x10

# define BIO_FLAGS_READ          0x01
# define BIO_FLAGS_WRITE         0x02
# define BIO_FLAGS_IO_SPECIAL    0x04
# define BIO_FLAGS_RWS (BIO_FLAGS_READ|BIO_FLAGS_WRITE|BIO_FLAGS_IO_SPECIAL)
# define BIO_FLAGS_SHOULD_RETRY  0x08
# ifndef BIO_FLAGS_UPLINK
/*
 * "UPLINK" flag denotes file descriptors provided by application. It
 * defaults to 0, as most platforms don't require UPLINK interface.
 */
#  define BIO_FLAGS_UPLINK        0
# endif

/* Used in BIO_gethostbyname() */
# define BIO_GHBN_CTRL_HITS              1
# define BIO_GHBN_CTRL_MISSES            2
# define BIO_GHBN_CTRL_CACHE_SIZE        3
# define BIO_GHBN_CTRL_GET_ENTRY         4
# define BIO_GHBN_CTRL_FLUSH             5

/* Mostly used in the SSL BIO */
/*-
 * Not used anymore
 * #define BIO_FLAGS_PROTOCOL_DELAYED_READ 0x10
 * #define BIO_FLAGS_PROTOCOL_DELAYED_WRITE 0x20
 * #define BIO_FLAGS_PROTOCOL_STARTUP   0x40
 */

# define BIO_FLAGS_BASE64_NO_NL  0x100

/*
 * This is used with memory BIOs: it means we shouldn't free up or change the
 * data in any way.
 */
# define BIO_FLAGS_MEM_RDONLY    0x200

typedef struct bio_st BIO;

void BIO_set_flags(BIO *b, int flags);
int BIO_test_flags(const BIO *b, int flags);
void BIO_clear_flags(BIO *b, int flags);

# define BIO_get_flags(b) BIO_test_flags(b, ~(0x0))
# define BIO_set_retry_special(b) \
                BIO_set_flags(b, (BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY))
# define BIO_set_retry_read(b) \
                BIO_set_flags(b, (BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY))
# define BIO_set_retry_write(b) \
                BIO_set_flags(b, (BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY))

/* These are normally used internally in BIOs */
# define BIO_clear_retry_flags(b) \
                BIO_clear_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY))
# define BIO_get_retry_flags(b) \
                BIO_test_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY))

/* These should be used by the application to tell why we should retry */
# define BIO_should_read(a)              BIO_test_flags(a, BIO_FLAGS_READ)
# define BIO_should_write(a)             BIO_test_flags(a, BIO_FLAGS_WRITE)
# define BIO_should_io_special(a)        BIO_test_flags(a, BIO_FLAGS_IO_SPECIAL)
# define BIO_retry_type(a)               BIO_test_flags(a, BIO_FLAGS_RWS)
# define BIO_should_retry(a)             BIO_test_flags(a, BIO_FLAGS_SHOULD_RETRY)

/*
 * The next three are used in conjunction with the BIO_should_io_special()
 * condition.  After this returns true, BIO *BIO_get_retry_BIO(BIO *bio, int
 * *reason); will walk the BIO stack and return the 'reason' for the special
 * and the offending BIO. Given a BIO, BIO_get_retry_reason(bio) will return
 * the code.
 */
/*
 * Returned from the SSL bio when the certificate retrieval code had an error
 */
# define BIO_RR_SSL_X509_LOOKUP          0x01
/* Returned from the connect BIO when a connect would have blocked */
# define BIO_RR_CONNECT                  0x02
/* Returned from the accept BIO when an accept would have blocked */
# define BIO_RR_ACCEPT                   0x03

/* These are passed by the BIO callback */
# define BIO_CB_FREE     0x01
# define BIO_CB_READ     0x02
# define BIO_CB_WRITE    0x03
# define BIO_CB_PUTS     0x04
# define BIO_CB_GETS     0x05
# define BIO_CB_CTRL     0x06

/*
 * The callback is called before and after the underling operation, The
 * BIO_CB_RETURN flag indicates if it is after the call
 */
# define BIO_CB_RETURN   0x80
# define BIO_CB_return(a) ((a)|BIO_CB_RETURN)
# define BIO_cb_pre(a)   (!((a)&BIO_CB_RETURN))
# define BIO_cb_post(a)  ((a)&BIO_CB_RETURN)

long (*BIO_get_callback(const BIO *b)) (struct bio_st *, int, const char *,
                                        int, long, long);
void BIO_set_callback(BIO *b,
                      long (*callback) (struct bio_st *, int, const char *,
                                        int, long, long));
char *BIO_get_callback_arg(const BIO *b);
void BIO_set_callback_arg(BIO *b, char *arg);

const char *BIO_method_name(const BIO *b);
int BIO_method_type(const BIO *b);

typedef void bio_info_cb (struct bio_st *, int, const char *, int, long,
                          long);

typedef struct bio_method_st {
    int type;
    const char *name;
    int (*bwrite) (BIO *, const char *, int);
    int (*bread) (BIO *, char *, int);
    int (*bputs) (BIO *, const char *);
    int (*bgets) (BIO *, char *, int);
    long (*ctrl) (BIO *, int, long, void *);
    int (*create) (BIO *);
    int (*destroy) (BIO *);
    long (*callback_ctrl) (BIO *, int, bio_info_cb *);
} BIO_METHOD;

struct bio_st {
    BIO_METHOD *method;
    /* bio, mode, argp, argi, argl, ret */
    long (*callback) (struct bio_st *, int, const char *, int, long, long);
    char *cb_arg;               /* first argument for the callback */
    int init;
    int shutdown;
    int flags;                  /* extra storage */
    int retry_reason;
    int num;
    void *ptr;
    struct bio_st *next_bio;    /* used by filter BIOs */
    struct bio_st *prev_bio;    /* used by filter BIOs */
    int references;
    unsigned long num_read;
    unsigned long num_write;
    CRYPTO_EX_DATA ex_data;
};

DECLARE_STACK_OF(BIO)

typedef struct bio_f_buffer_ctx_struct {
    /*-
     * Buffers are setup like this:
     *
     * <---------------------- size ----------------------->
     * +---------------------------------------------------+
     * | consumed | remaining          | free space        |
     * +---------------------------------------------------+
     * <-- off --><------- len ------->
     */
    /*- BIO *bio; *//*
     * this is now in the BIO struct
     */
    int ibuf_size;              /* how big is the input buffer */
    int obuf_size;              /* how big is the output buffer */
    char *ibuf;                 /* the char array */
    int ibuf_len;               /* how many bytes are in it */
    int ibuf_off;               /* write/read offset */
    char *obuf;                 /* the char array */
    int obuf_len;               /* how many bytes are in it */
    int obuf_off;               /* write/read offset */
} BIO_F_BUFFER_CTX;

/* Prefix and suffix callback in ASN1 BIO */
typedef int asn1_ps_func (BIO *b, unsigned char **pbuf, int *plen,
                          void *parg);

# ifndef OPENSSL_NO_SCTP
/* SCTP parameter structs */
struct bio_dgram_sctp_sndinfo {
    uint16_t snd_sid;
    uint16_t snd_flags;
    uint32_t snd_ppid;
    uint32_t snd_context;
};

struct bio_dgram_sctp_rcvinfo {
    uint16_t rcv_sid;
    uint16_t rcv_ssn;
    uint16_t rcv_flags;
    uint32_t rcv_ppid;
    uint32_t rcv_tsn;
    uint32_t rcv_cumtsn;
    uint32_t rcv_context;
};

struct bio_dgram_sctp_prinfo {
    uint16_t pr_policy;
    uint32_t pr_value;
};
# endif

/* connect BIO stuff */
# define BIO_CONN_S_BEFORE               1
# define BIO_CONN_S_GET_IP               2
# define BIO_CONN_S_GET_PORT             3
# define BIO_CONN_S_CREATE_SOCKET        4
# define BIO_CONN_S_CONNECT              5
# define BIO_CONN_S_OK                   6
# define BIO_CONN_S_BLOCKED_CONNECT      7
# define BIO_CONN_S_NBIO                 8
/*
 * #define BIO_CONN_get_param_hostname BIO_ctrl
 */

# define BIO_C_SET_CONNECT                       100
# define BIO_C_DO_STATE_MACHINE                  101
# define BIO_C_SET_NBIO                          102
# define BIO_C_SET_PROXY_PARAM                   103
# define BIO_C_SET_FD                            104
# define BIO_C_GET_FD                            105
# define BIO_C_SET_FILE_PTR                      106
# define BIO_C_GET_FILE_PTR                      107
# define BIO_C_SET_FILENAME                      108
# define BIO_C_SET_SSL                           109
# define BIO_C_GET_SSL                           110
# define BIO_C_SET_MD                            111
# define BIO_C_GET_MD                            112
# define BIO_C_GET_CIPHER_STATUS                 113
# define BIO_C_SET_BUF_MEM                       114
# define BIO_C_GET_BUF_MEM_PTR                   115
# define BIO_C_GET_BUFF_NUM_LINES                116
# define BIO_C_SET_BUFF_SIZE                     117
# define BIO_C_SET_ACCEPT                        118
# define BIO_C_SSL_MODE                          119
# define BIO_C_GET_MD_CTX                        120
# define BIO_C_GET_PROXY_PARAM                   121
# define BIO_C_SET_BUFF_READ_DATA                122/* data to read first */
# define BIO_C_GET_CONNECT                       123
# define BIO_C_GET_ACCEPT                        124
# define BIO_C_SET_SSL_RENEGOTIATE_BYTES         125
# define BIO_C_GET_SSL_NUM_RENEGOTIATES          126
# define BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT       127
# define BIO_C_FILE_SEEK                         128
# define BIO_C_GET_CIPHER_CTX                    129
# define BIO_C_SET_BUF_MEM_EOF_RETURN            130/* return end of input
                                                     * value */
# define BIO_C_SET_BIND_MODE                     131
# define BIO_C_GET_BIND_MODE                     132
# define BIO_C_FILE_TELL                         133
# define BIO_C_GET_SOCKS                         134
# define BIO_C_SET_SOCKS                         135

# define BIO_C_SET_WRITE_BUF_SIZE                136/* for BIO_s_bio */
# define BIO_C_GET_WRITE_BUF_SIZE                137
# define BIO_C_MAKE_BIO_PAIR                     138
# define BIO_C_DESTROY_BIO_PAIR                  139
# define BIO_C_GET_WRITE_GUARANTEE               140
# define BIO_C_GET_READ_REQUEST                  141
# define BIO_C_SHUTDOWN_WR                       142
# define BIO_C_NREAD0                            143
# define BIO_C_NREAD                             144
# define BIO_C_NWRITE0                           145
# define BIO_C_NWRITE                            146
# define BIO_C_RESET_READ_REQUEST                147
# define BIO_C_SET_MD_CTX                        148

# define BIO_C_SET_PREFIX                        149
# define BIO_C_GET_PREFIX                        150
# define BIO_C_SET_SUFFIX                        151
# define BIO_C_GET_SUFFIX                        152

# define BIO_C_SET_EX_ARG                        153
# define BIO_C_GET_EX_ARG                        154

# define BIO_set_app_data(s,arg)         BIO_set_ex_data(s,0,arg)
# define BIO_get_app_data(s)             BIO_get_ex_data(s,0)

/* BIO_s_connect() and BIO_s_socks4a_connect() */
# define BIO_set_conn_hostname(b,name) BIO_ctrl(b,BIO_C_SET_CONNECT,0,(char *)name)
# define BIO_set_conn_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,1,(char *)port)
# define BIO_set_conn_ip(b,ip)     BIO_ctrl(b,BIO_C_SET_CONNECT,2,(char *)ip)
# define BIO_set_conn_int_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,3,(char *)port)
# define BIO_get_conn_hostname(b)  BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,0)
# define BIO_get_conn_port(b)      BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,1)
# define BIO_get_conn_ip(b)               BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,2)
# define BIO_get_conn_int_port(b) BIO_ctrl(b,BIO_C_GET_CONNECT,3,NULL)

# define BIO_set_nbio(b,n)       BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL)

/* BIO_s_accept() */
# define BIO_set_accept_port(b,name) BIO_ctrl(b,BIO_C_SET_ACCEPT,0,(char *)name)
# define BIO_get_accept_port(b)  BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,0)
/* #define BIO_set_nbio(b,n)    BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) */
# define BIO_set_nbio_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,1,(n)?(void *)"a":NULL)
# define BIO_set_accept_bios(b,bio) BIO_ctrl(b,BIO_C_SET_ACCEPT,2,(char *)bio)

# define BIO_BIND_NORMAL                 0
# define BIO_BIND_REUSEADDR_IF_UNUSED    1
# define BIO_BIND_REUSEADDR              2
# define BIO_set_bind_mode(b,mode) BIO_ctrl(b,BIO_C_SET_BIND_MODE,mode,NULL)
# define BIO_get_bind_mode(b,mode) BIO_ctrl(b,BIO_C_GET_BIND_MODE,0,NULL)

/* BIO_s_accept() and BIO_s_connect() */
# define BIO_do_connect(b)       BIO_do_handshake(b)
# define BIO_do_accept(b)        BIO_do_handshake(b)
# define BIO_do_handshake(b)     BIO_ctrl(b,BIO_C_DO_STATE_MACHINE,0,NULL)

/* BIO_s_proxy_client() */
# define BIO_set_url(b,url)      BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,0,(char *)(url))
# define BIO_set_proxies(b,p)    BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,1,(char *)(p))
/* BIO_set_nbio(b,n) */
# define BIO_set_filter_bio(b,s) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,2,(char *)(s))
/* BIO *BIO_get_filter_bio(BIO *bio); */
# define BIO_set_proxy_cb(b,cb) BIO_callback_ctrl(b,BIO_C_SET_PROXY_PARAM,3,(void *(*cb)()))
# define BIO_set_proxy_header(b,sk) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,4,(char *)sk)
# define BIO_set_no_connect_return(b,bool) BIO_int_ctrl(b,BIO_C_SET_PROXY_PARAM,5,bool)

# define BIO_get_proxy_header(b,skp) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,0,(char *)skp)
# define BIO_get_proxies(b,pxy_p) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,1,(char *)(pxy_p))
# define BIO_get_url(b,url)      BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,2,(char *)(url))
# define BIO_get_no_connect_return(b)    BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,5,NULL)

/* BIO_s_datagram(), BIO_s_fd(), BIO_s_socket(), BIO_s_accept() and BIO_s_connect() */
# define BIO_set_fd(b,fd,c)      BIO_int_ctrl(b,BIO_C_SET_FD,c,fd)
# define BIO_get_fd(b,c)         BIO_ctrl(b,BIO_C_GET_FD,0,(char *)c)

/* BIO_s_file() */
# define BIO_set_fp(b,fp,c)      BIO_ctrl(b,BIO_C_SET_FILE_PTR,c,(char *)fp)
# define BIO_get_fp(b,fpp)       BIO_ctrl(b,BIO_C_GET_FILE_PTR,0,(char *)fpp)

/* BIO_s_fd() and BIO_s_file() */
# define BIO_seek(b,ofs) (int)BIO_ctrl(b,BIO_C_FILE_SEEK,ofs,NULL)
# define BIO_tell(b)     (int)BIO_ctrl(b,BIO_C_FILE_TELL,0,NULL)

/*
 * name is cast to lose const, but might be better to route through a
 * function so we can do it safely
 */
# ifdef CONST_STRICT
/*
 * If you are wondering why this isn't defined, its because CONST_STRICT is
 * purely a compile-time kludge to allow const to be checked.
 */
int BIO_read_filename(BIO *b, const char *name);
# else
#  define BIO_read_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
                BIO_CLOSE|BIO_FP_READ,(char *)name)
# endif
# define BIO_write_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
                BIO_CLOSE|BIO_FP_WRITE,name)
# define BIO_append_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
                BIO_CLOSE|BIO_FP_APPEND,name)
# define BIO_rw_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
                BIO_CLOSE|BIO_FP_READ|BIO_FP_WRITE,name)

/*
 * WARNING WARNING, this ups the reference count on the read bio of the SSL
 * structure.  This is because the ssl read BIO is now pointed to by the
 * next_bio field in the bio.  So when you free the BIO, make sure you are
 * doing a BIO_free_all() to catch the underlying BIO.
 */
# define BIO_set_ssl(b,ssl,c)    BIO_ctrl(b,BIO_C_SET_SSL,c,(char *)ssl)
# define BIO_get_ssl(b,sslp)     BIO_ctrl(b,BIO_C_GET_SSL,0,(char *)sslp)
# define BIO_set_ssl_mode(b,client)      BIO_ctrl(b,BIO_C_SSL_MODE,client,NULL)
# define BIO_set_ssl_renegotiate_bytes(b,num) \
        BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_BYTES,num,NULL)
# define BIO_get_num_renegotiates(b) \
        BIO_ctrl(b,BIO_C_GET_SSL_NUM_RENEGOTIATES,0,NULL)
# define BIO_set_ssl_renegotiate_timeout(b,seconds) \
        BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT,seconds,NULL)

/* defined in evp.h */
/* #define BIO_set_md(b,md)     BIO_ctrl(b,BIO_C_SET_MD,1,(char *)md) */

# define BIO_get_mem_data(b,pp)  BIO_ctrl(b,BIO_CTRL_INFO,0,(char *)pp)
# define BIO_set_mem_buf(b,bm,c) BIO_ctrl(b,BIO_C_SET_BUF_MEM,c,(char *)bm)
# define BIO_get_mem_ptr(b,pp)   BIO_ctrl(b,BIO_C_GET_BUF_MEM_PTR,0,(char *)pp)
# define BIO_set_mem_eof_return(b,v) \
                                BIO_ctrl(b,BIO_C_SET_BUF_MEM_EOF_RETURN,v,NULL)

/* For the BIO_f_buffer() type */
# define BIO_get_buffer_num_lines(b)     BIO_ctrl(b,BIO_C_GET_BUFF_NUM_LINES,0,NULL)
# define BIO_set_buffer_size(b,size)     BIO_ctrl(b,BIO_C_SET_BUFF_SIZE,size,NULL)
# define BIO_set_read_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,0)
# define BIO_set_write_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,1)
# define BIO_set_buffer_read_data(b,buf,num) BIO_ctrl(b,BIO_C_SET_BUFF_READ_DATA,num,buf)

/* Don't use the next one unless you know what you are doing :-) */
# define BIO_dup_state(b,ret)    BIO_ctrl(b,BIO_CTRL_DUP,0,(char *)(ret))

# define BIO_reset(b)            (int)BIO_ctrl(b,BIO_CTRL_RESET,0,NULL)
# define BIO_eof(b)              (int)BIO_ctrl(b,BIO_CTRL_EOF,0,NULL)
# define BIO_set_close(b,c)      (int)BIO_ctrl(b,BIO_CTRL_SET_CLOSE,(c),NULL)
# define BIO_get_close(b)        (int)BIO_ctrl(b,BIO_CTRL_GET_CLOSE,0,NULL)
# define BIO_pending(b)          (int)BIO_ctrl(b,BIO_CTRL_PENDING,0,NULL)
# define BIO_wpending(b)         (int)BIO_ctrl(b,BIO_CTRL_WPENDING,0,NULL)
/* ...pending macros have inappropriate return type */
size_t BIO_ctrl_pending(BIO *b);
size_t BIO_ctrl_wpending(BIO *b);
# define BIO_flush(b)            (int)BIO_ctrl(b,BIO_CTRL_FLUSH,0,NULL)
# define BIO_get_info_callback(b,cbp) (int)BIO_ctrl(b,BIO_CTRL_GET_CALLBACK,0, \
                                                   cbp)
# define BIO_set_info_callback(b,cb) (int)BIO_callback_ctrl(b,BIO_CTRL_SET_CALLBACK,cb)

/* For the BIO_f_buffer() type */
# define BIO_buffer_get_num_lines(b) BIO_ctrl(b,BIO_CTRL_GET,0,NULL)

/* For BIO_s_bio() */
# define BIO_set_write_buf_size(b,size) (int)BIO_ctrl(b,BIO_C_SET_WRITE_BUF_SIZE,size,NULL)
# define BIO_get_write_buf_size(b,size) (size_t)BIO_ctrl(b,BIO_C_GET_WRITE_BUF_SIZE,size,NULL)
# define BIO_make_bio_pair(b1,b2)   (int)BIO_ctrl(b1,BIO_C_MAKE_BIO_PAIR,0,b2)
# define BIO_destroy_bio_pair(b)    (int)BIO_ctrl(b,BIO_C_DESTROY_BIO_PAIR,0,NULL)
# define BIO_shutdown_wr(b) (int)BIO_ctrl(b, BIO_C_SHUTDOWN_WR, 0, NULL)
/* macros with inappropriate type -- but ...pending macros use int too: */
# define BIO_get_write_guarantee(b) (int)BIO_ctrl(b,BIO_C_GET_WRITE_GUARANTEE,0,NULL)
# define BIO_get_read_request(b)    (int)BIO_ctrl(b,BIO_C_GET_READ_REQUEST,0,NULL)
size_t BIO_ctrl_get_write_guarantee(BIO *b);
size_t BIO_ctrl_get_read_request(BIO *b);
int BIO_ctrl_reset_read_request(BIO *b);

/* ctrl macros for dgram */
# define BIO_ctrl_dgram_connect(b,peer)  \
                     (int)BIO_ctrl(b,BIO_CTRL_DGRAM_CONNECT,0, (char *)peer)
# define BIO_ctrl_set_connected(b, state, peer) \
         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_CONNECTED, state, (char *)peer)
# define BIO_dgram_recv_timedout(b) \
         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP, 0, NULL)
# define BIO_dgram_send_timedout(b) \
         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP, 0, NULL)
# define BIO_dgram_get_peer(b,peer) \
         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_PEER, 0, (char *)peer)
# define BIO_dgram_set_peer(b,peer) \
         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, (char *)peer)
# define BIO_dgram_get_mtu_overhead(b) \
         (unsigned int)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_MTU_OVERHEAD, 0, NULL)

/* These two aren't currently implemented */
/* int BIO_get_ex_num(BIO *bio); */
/* void BIO_set_ex_free_func(BIO *bio,int idx,void (*cb)()); */
int BIO_set_ex_data(BIO *bio, int idx, void *data);
void *BIO_get_ex_data(BIO *bio, int idx);
int BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
                         CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
unsigned long BIO_number_read(BIO *bio);
unsigned long BIO_number_written(BIO *bio);

/* For BIO_f_asn1() */
int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix,
                        asn1_ps_func *prefix_free);
int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix,
                        asn1_ps_func **pprefix_free);
int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix,
                        asn1_ps_func *suffix_free);
int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix,
                        asn1_ps_func **psuffix_free);

# ifndef OPENSSL_NO_FP_API
BIO_METHOD *BIO_s_file(void);
BIO *BIO_new_file(const char *filename, const char *mode);
BIO *BIO_new_fp(FILE *stream, int close_flag);
#  define BIO_s_file_internal    BIO_s_file
# endif
BIO *BIO_new(BIO_METHOD *type);
int BIO_set(BIO *a, BIO_METHOD *type);
int BIO_free(BIO *a);
void BIO_vfree(BIO *a);
int BIO_read(BIO *b, void *data, int len);
int BIO_gets(BIO *bp, char *buf, int size);
int BIO_write(BIO *b, const void *data, int len);
int BIO_puts(BIO *bp, const char *buf);
int BIO_indent(BIO *b, int indent, int max);
long BIO_ctrl(BIO *bp, int cmd, long larg, void *parg);
long BIO_callback_ctrl(BIO *b, int cmd,
                       void (*fp) (struct bio_st *, int, const char *, int,
                                   long, long));
char *BIO_ptr_ctrl(BIO *bp, int cmd, long larg);
long BIO_int_ctrl(BIO *bp, int cmd, long larg, int iarg);
BIO *BIO_push(BIO *b, BIO *append);
BIO *BIO_pop(BIO *b);
void BIO_free_all(BIO *a);
BIO *BIO_find_type(BIO *b, int bio_type);
BIO *BIO_next(BIO *b);
BIO *BIO_get_retry_BIO(BIO *bio, int *reason);
int BIO_get_retry_reason(BIO *bio);
BIO *BIO_dup_chain(BIO *in);

int BIO_nread0(BIO *bio, char **buf);
int BIO_nread(BIO *bio, char **buf, int num);
int BIO_nwrite0(BIO *bio, char **buf);
int BIO_nwrite(BIO *bio, char **buf, int num);

long BIO_debug_callback(BIO *bio, int cmd, const char *argp, int argi,
                        long argl, long ret);

BIO_METHOD *BIO_s_mem(void);
BIO *BIO_new_mem_buf(const void *buf, int len);
BIO_METHOD *BIO_s_socket(void);
BIO_METHOD *BIO_s_connect(void);
BIO_METHOD *BIO_s_accept(void);
BIO_METHOD *BIO_s_fd(void);
# ifndef OPENSSL_SYS_OS2
BIO_METHOD *BIO_s_log(void);
# endif
BIO_METHOD *BIO_s_bio(void);
BIO_METHOD *BIO_s_null(void);
BIO_METHOD *BIO_f_null(void);
BIO_METHOD *BIO_f_buffer(void);
# ifdef OPENSSL_SYS_VMS
BIO_METHOD *BIO_f_linebuffer(void);
# endif
BIO_METHOD *BIO_f_nbio_test(void);
# ifndef OPENSSL_NO_DGRAM
BIO_METHOD *BIO_s_datagram(void);
#  ifndef OPENSSL_NO_SCTP
BIO_METHOD *BIO_s_datagram_sctp(void);
#  endif
# endif

/* BIO_METHOD *BIO_f_ber(void); */

int BIO_sock_should_retry(int i);
int BIO_sock_non_fatal_error(int error);
int BIO_dgram_non_fatal_error(int error);

int BIO_fd_should_retry(int i);
int BIO_fd_non_fatal_error(int error);
int BIO_dump_cb(int (*cb) (const void *data, size_t len, void *u),
                void *u, const char *s, int len);
int BIO_dump_indent_cb(int (*cb) (const void *data, size_t len, void *u),
                       void *u, const char *s, int len, int indent);
int BIO_dump(BIO *b, const char *bytes, int len);
int BIO_dump_indent(BIO *b, const char *bytes, int len, int indent);
# ifndef OPENSSL_NO_FP_API
int BIO_dump_fp(FILE *fp, const char *s, int len);
int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent);
# endif
int BIO_hex_string(BIO *out, int indent, int width, unsigned char *data,
                   int datalen);

struct hostent *BIO_gethostbyname(const char *name);
/*-
 * We might want a thread-safe interface too:
 * struct hostent *BIO_gethostbyname_r(const char *name,
 *     struct hostent *result, void *buffer, size_t buflen);
 * or something similar (caller allocates a struct hostent,
 * pointed to by "result", and additional buffer space for the various
 * substructures; if the buffer does not suffice, NULL is returned
 * and an appropriate error code is set).
 */
int BIO_sock_error(int sock);
int BIO_socket_ioctl(int fd, long type, void *arg);
int BIO_socket_nbio(int fd, int mode);
int BIO_get_port(const char *str, unsigned short *port_ptr);
int BIO_get_host_ip(const char *str, unsigned char *ip);
int BIO_get_accept_socket(char *host_port, int mode);
int BIO_accept(int sock, char **ip_port);
int BIO_sock_init(void);
void BIO_sock_cleanup(void);
int BIO_set_tcp_ndelay(int sock, int turn_on);

BIO *BIO_new_socket(int sock, int close_flag);
BIO *BIO_new_dgram(int fd, int close_flag);
# ifndef OPENSSL_NO_SCTP
BIO *BIO_new_dgram_sctp(int fd, int close_flag);
int BIO_dgram_is_sctp(BIO *bio);
int BIO_dgram_sctp_notification_cb(BIO *b,
                                   void (*handle_notifications) (BIO *bio,
                                                                 void
                                                                 *context,
                                                                 void *buf),
                                   void *context);
int BIO_dgram_sctp_wait_for_dry(BIO *b);
int BIO_dgram_sctp_msg_waiting(BIO *b);
# endif
BIO *BIO_new_fd(int fd, int close_flag);
BIO *BIO_new_connect(const char *host_port);
BIO *BIO_new_accept(const char *host_port);

int BIO_new_bio_pair(BIO **bio1, size_t writebuf1,
                     BIO **bio2, size_t writebuf2);
/*
 * If successful, returns 1 and in *bio1, *bio2 two BIO pair endpoints.
 * Otherwise returns 0 and sets *bio1 and *bio2 to NULL. Size 0 uses default
 * value.
 */

void BIO_copy_next_retry(BIO *b);

/*
 * long BIO_ghbn_ctrl(int cmd,int iarg,char *parg);
 */

# ifdef __GNUC__
#  define __bio_h__attr__ __attribute__
# else
#  define __bio_h__attr__(x)
# endif
int BIO_printf(BIO *bio, const char *format, ...)
__bio_h__attr__((__format__(__printf__, 2, 3)));
int BIO_vprintf(BIO *bio, const char *format, va_list args)
__bio_h__attr__((__format__(__printf__, 2, 0)));
int BIO_snprintf(char *buf, size_t n, const char *format, ...)
__bio_h__attr__((__format__(__printf__, 3, 4)));
int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
__bio_h__attr__((__format__(__printf__, 3, 0)));
# undef __bio_h__attr__

/* BEGIN ERROR CODES */
/*
 * The following lines are auto generated by the script mkerr.pl. Any changes
 * made after this point may be overwritten when the script is next run.
 */
void ERR_load_BIO_strings(void);

/* Error codes for the BIO functions. */

/* Function codes. */
# define BIO_F_ACPT_STATE                                 100
# define BIO_F_BIO_ACCEPT                                 101
# define BIO_F_BIO_BER_GET_HEADER                         102
# define BIO_F_BIO_CALLBACK_CTRL                          131
# define BIO_F_BIO_CTRL                                   103
# define BIO_F_BIO_GETHOSTBYNAME                          120
# define BIO_F_BIO_GETS                                   104
# define BIO_F_BIO_GET_ACCEPT_SOCKET                      105
# define BIO_F_BIO_GET_HOST_IP                            106
# define BIO_F_BIO_GET_PORT                               107
# define BIO_F_BIO_MAKE_PAIR                              121
# define BIO_F_BIO_NEW                                    108
# define BIO_F_BIO_NEW_FILE                               109
# define BIO_F_BIO_NEW_MEM_BUF                            126
# define BIO_F_BIO_NREAD                                  123
# define BIO_F_BIO_NREAD0                                 124
# define BIO_F_BIO_NWRITE                                 125
# define BIO_F_BIO_NWRITE0                                122
# define BIO_F_BIO_PUTS                                   110
# define BIO_F_BIO_READ                                   111
# define BIO_F_BIO_SOCK_INIT                              112
# define BIO_F_BIO_WRITE                                  113
# define BIO_F_BUFFER_CTRL                                114
# define BIO_F_CONN_CTRL                                  127
# define BIO_F_CONN_STATE                                 115
# define BIO_F_DGRAM_SCTP_READ                            132
# define BIO_F_DGRAM_SCTP_WRITE                           133
# define BIO_F_FILE_CTRL                                  116
# define BIO_F_FILE_READ                                  130
# define BIO_F_LINEBUFFER_CTRL                            129
# define BIO_F_MEM_READ                                   128
# define BIO_F_MEM_WRITE                                  117
# define BIO_F_SSL_NEW                                    118
# define BIO_F_WSASTARTUP                                 119

/* Reason codes. */
# define BIO_R_ACCEPT_ERROR                               100
# define BIO_R_BAD_FOPEN_MODE                             101
# define BIO_R_BAD_HOSTNAME_LOOKUP                        102
# define BIO_R_BROKEN_PIPE                                124
# define BIO_R_CONNECT_ERROR                              103
# define BIO_R_EOF_ON_MEMORY_BIO                          127
# define BIO_R_ERROR_SETTING_NBIO                         104
# define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET      105
# define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET        106
# define BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET          107
# define BIO_R_INVALID_ARGUMENT                           125
# define BIO_R_INVALID_IP_ADDRESS                         108
# define BIO_R_IN_USE                                     123
# define BIO_R_KEEPALIVE                                  109
# define BIO_R_NBIO_CONNECT_ERROR                         110
# define BIO_R_NO_ACCEPT_PORT_SPECIFIED                   111
# define BIO_R_NO_HOSTNAME_SPECIFIED                      112
# define BIO_R_NO_PORT_DEFINED                            113
# define BIO_R_NO_PORT_SPECIFIED                          114
# define BIO_R_NO_SUCH_FILE                               128
# define BIO_R_NULL_PARAMETER                             115
# define BIO_R_TAG_MISMATCH                               116
# define BIO_R_UNABLE_TO_BIND_SOCKET                      117
# define BIO_R_UNABLE_TO_CREATE_SOCKET                    118
# define BIO_R_UNABLE_TO_LISTEN_SOCKET                    119
# define BIO_R_UNINITIALIZED                              120
# define BIO_R_UNSUPPORTED_METHOD                         121
# define BIO_R_WRITE_TO_READ_ONLY_BIO                     126
# define BIO_R_WSASTARTUP                                 122

#ifdef  __cplusplus
}
#endif
#endif
openssl/whrlpool.h000064400000002073151733316620010257 0ustar00#ifndef HEADER_WHRLPOOL_H
# define HEADER_WHRLPOOL_H

# include <openssl/e_os2.h>
# include <stddef.h>

#ifdef __cplusplus
extern "C" {
#endif

# define WHIRLPOOL_DIGEST_LENGTH (512/8)
# define WHIRLPOOL_BBLOCK        512
# define WHIRLPOOL_COUNTER       (256/8)

typedef struct {
    union {
        unsigned char c[WHIRLPOOL_DIGEST_LENGTH];
        /* double q is here to ensure 64-bit alignment */
        double q[WHIRLPOOL_DIGEST_LENGTH / sizeof(double)];
    } H;
    unsigned char data[WHIRLPOOL_BBLOCK / 8];
    unsigned int bitoff;
    size_t bitlen[WHIRLPOOL_COUNTER / sizeof(size_t)];
} WHIRLPOOL_CTX;

# ifndef OPENSSL_NO_WHIRLPOOL
#  ifdef OPENSSL_FIPS
int private_WHIRLPOOL_Init(WHIRLPOOL_CTX *c);
#  endif
int WHIRLPOOL_Init(WHIRLPOOL_CTX *c);
int WHIRLPOOL_Update(WHIRLPOOL_CTX *c, const void *inp, size_t bytes);
void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c, const void *inp, size_t bits);
int WHIRLPOOL_Final(unsigned char *md, WHIRLPOOL_CTX *c);
unsigned char *WHIRLPOOL(const void *inp, size_t bytes, unsigned char *md);
# endif

#ifdef __cplusplus
}
#endif

#endif
openssl/ocsp.h000064400000065013151733316620007360 0ustar00/* ocsp.h */
/*
 * Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL
 * project.
 */

/*
 * History: This file was transfered to Richard Levitte from CertCo by Kathy
 * Weinhold in mid-spring 2000 to be included in OpenSSL or released as a
 * patch kit.
 */

/* ====================================================================
 * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#ifndef HEADER_OCSP_H
# define HEADER_OCSP_H

# include <openssl/ossl_typ.h>
# include <openssl/x509.h>
# include <openssl/x509v3.h>
# include <openssl/safestack.h>

#ifdef  __cplusplus
extern "C" {
#endif

/* Various flags and values */

# define OCSP_DEFAULT_NONCE_LENGTH       16

# define OCSP_NOCERTS                    0x1
# define OCSP_NOINTERN                   0x2
# define OCSP_NOSIGS                     0x4
# define OCSP_NOCHAIN                    0x8
# define OCSP_NOVERIFY                   0x10
# define OCSP_NOEXPLICIT                 0x20
# define OCSP_NOCASIGN                   0x40
# define OCSP_NODELEGATED                0x80
# define OCSP_NOCHECKS                   0x100
# define OCSP_TRUSTOTHER                 0x200
# define OCSP_RESPID_KEY                 0x400
# define OCSP_NOTIME                     0x800

/*-  CertID ::= SEQUENCE {
 *       hashAlgorithm            AlgorithmIdentifier,
 *       issuerNameHash     OCTET STRING, -- Hash of Issuer's DN
 *       issuerKeyHash      OCTET STRING, -- Hash of Issuers public key (excluding the tag & length fields)
 *       serialNumber       CertificateSerialNumber }
 */
typedef struct ocsp_cert_id_st {
    X509_ALGOR *hashAlgorithm;
    ASN1_OCTET_STRING *issuerNameHash;
    ASN1_OCTET_STRING *issuerKeyHash;
    ASN1_INTEGER *serialNumber;
} OCSP_CERTID;

DECLARE_STACK_OF(OCSP_CERTID)

/*-  Request ::=     SEQUENCE {
 *       reqCert                    CertID,
 *       singleRequestExtensions    [0] EXPLICIT Extensions OPTIONAL }
 */
typedef struct ocsp_one_request_st {
    OCSP_CERTID *reqCert;
    STACK_OF(X509_EXTENSION) *singleRequestExtensions;
} OCSP_ONEREQ;

DECLARE_STACK_OF(OCSP_ONEREQ)
DECLARE_ASN1_SET_OF(OCSP_ONEREQ)

/*-  TBSRequest      ::=     SEQUENCE {
 *       version             [0] EXPLICIT Version DEFAULT v1,
 *       requestorName       [1] EXPLICIT GeneralName OPTIONAL,
 *       requestList             SEQUENCE OF Request,
 *       requestExtensions   [2] EXPLICIT Extensions OPTIONAL }
 */
typedef struct ocsp_req_info_st {
    ASN1_INTEGER *version;
    GENERAL_NAME *requestorName;
    STACK_OF(OCSP_ONEREQ) *requestList;
    STACK_OF(X509_EXTENSION) *requestExtensions;
} OCSP_REQINFO;

/*-  Signature       ::=     SEQUENCE {
 *       signatureAlgorithm   AlgorithmIdentifier,
 *       signature            BIT STRING,
 *       certs                [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
 */
typedef struct ocsp_signature_st {
    X509_ALGOR *signatureAlgorithm;
    ASN1_BIT_STRING *signature;
    STACK_OF(X509) *certs;
} OCSP_SIGNATURE;

/*-  OCSPRequest     ::=     SEQUENCE {
 *       tbsRequest                  TBSRequest,
 *       optionalSignature   [0]     EXPLICIT Signature OPTIONAL }
 */
typedef struct ocsp_request_st {
    OCSP_REQINFO *tbsRequest;
    OCSP_SIGNATURE *optionalSignature; /* OPTIONAL */
} OCSP_REQUEST;

/*-  OCSPResponseStatus ::= ENUMERATED {
 *       successful            (0),      --Response has valid confirmations
 *       malformedRequest      (1),      --Illegal confirmation request
 *       internalError         (2),      --Internal error in issuer
 *       tryLater              (3),      --Try again later
 *                                       --(4) is not used
 *       sigRequired           (5),      --Must sign the request
 *       unauthorized          (6)       --Request unauthorized
 *   }
 */
# define OCSP_RESPONSE_STATUS_SUCCESSFUL          0
# define OCSP_RESPONSE_STATUS_MALFORMEDREQUEST     1
# define OCSP_RESPONSE_STATUS_INTERNALERROR        2
# define OCSP_RESPONSE_STATUS_TRYLATER             3
# define OCSP_RESPONSE_STATUS_SIGREQUIRED          5
# define OCSP_RESPONSE_STATUS_UNAUTHORIZED         6

/*-  ResponseBytes ::=       SEQUENCE {
 *       responseType   OBJECT IDENTIFIER,
 *       response       OCTET STRING }
 */
typedef struct ocsp_resp_bytes_st {
    ASN1_OBJECT *responseType;
    ASN1_OCTET_STRING *response;
} OCSP_RESPBYTES;

/*-  OCSPResponse ::= SEQUENCE {
 *      responseStatus         OCSPResponseStatus,
 *      responseBytes          [0] EXPLICIT ResponseBytes OPTIONAL }
 */
struct ocsp_response_st {
    ASN1_ENUMERATED *responseStatus;
    OCSP_RESPBYTES *responseBytes;
};

/*-  ResponderID ::= CHOICE {
 *      byName   [1] Name,
 *      byKey    [2] KeyHash }
 */
# define V_OCSP_RESPID_NAME 0
# define V_OCSP_RESPID_KEY  1
struct ocsp_responder_id_st {
    int type;
    union {
        X509_NAME *byName;
        ASN1_OCTET_STRING *byKey;
    } value;
};

DECLARE_STACK_OF(OCSP_RESPID)
DECLARE_ASN1_FUNCTIONS(OCSP_RESPID)

/*-  KeyHash ::= OCTET STRING --SHA-1 hash of responder's public key
 *                            --(excluding the tag and length fields)
 */

/*-  RevokedInfo ::= SEQUENCE {
 *       revocationTime              GeneralizedTime,
 *       revocationReason    [0]     EXPLICIT CRLReason OPTIONAL }
 */
typedef struct ocsp_revoked_info_st {
    ASN1_GENERALIZEDTIME *revocationTime;
    ASN1_ENUMERATED *revocationReason;
} OCSP_REVOKEDINFO;

/*-  CertStatus ::= CHOICE {
 *       good                [0]     IMPLICIT NULL,
 *       revoked             [1]     IMPLICIT RevokedInfo,
 *       unknown             [2]     IMPLICIT UnknownInfo }
 */
# define V_OCSP_CERTSTATUS_GOOD    0
# define V_OCSP_CERTSTATUS_REVOKED 1
# define V_OCSP_CERTSTATUS_UNKNOWN 2
typedef struct ocsp_cert_status_st {
    int type;
    union {
        ASN1_NULL *good;
        OCSP_REVOKEDINFO *revoked;
        ASN1_NULL *unknown;
    } value;
} OCSP_CERTSTATUS;

/*-  SingleResponse ::= SEQUENCE {
 *      certID                       CertID,
 *      certStatus                   CertStatus,
 *      thisUpdate                   GeneralizedTime,
 *      nextUpdate           [0]     EXPLICIT GeneralizedTime OPTIONAL,
 *      singleExtensions     [1]     EXPLICIT Extensions OPTIONAL }
 */
typedef struct ocsp_single_response_st {
    OCSP_CERTID *certId;
    OCSP_CERTSTATUS *certStatus;
    ASN1_GENERALIZEDTIME *thisUpdate;
    ASN1_GENERALIZEDTIME *nextUpdate;
    STACK_OF(X509_EXTENSION) *singleExtensions;
} OCSP_SINGLERESP;

DECLARE_STACK_OF(OCSP_SINGLERESP)
DECLARE_ASN1_SET_OF(OCSP_SINGLERESP)

/*-  ResponseData ::= SEQUENCE {
 *      version              [0] EXPLICIT Version DEFAULT v1,
 *      responderID              ResponderID,
 *      producedAt               GeneralizedTime,
 *      responses                SEQUENCE OF SingleResponse,
 *      responseExtensions   [1] EXPLICIT Extensions OPTIONAL }
 */
typedef struct ocsp_response_data_st {
    ASN1_INTEGER *version;
    OCSP_RESPID *responderId;
    ASN1_GENERALIZEDTIME *producedAt;
    STACK_OF(OCSP_SINGLERESP) *responses;
    STACK_OF(X509_EXTENSION) *responseExtensions;
} OCSP_RESPDATA;

/*-  BasicOCSPResponse       ::= SEQUENCE {
 *      tbsResponseData      ResponseData,
 *      signatureAlgorithm   AlgorithmIdentifier,
 *      signature            BIT STRING,
 *      certs                [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
 */
  /*
   * Note 1: The value for "signature" is specified in the OCSP rfc2560 as
   * follows: "The value for the signature SHALL be computed on the hash of
   * the DER encoding ResponseData." This means that you must hash the
   * DER-encoded tbsResponseData, and then run it through a crypto-signing
   * function, which will (at least w/RSA) do a hash-'n'-private-encrypt
   * operation.  This seems a bit odd, but that's the spec.  Also note that
   * the data structures do not leave anywhere to independently specify the
   * algorithm used for the initial hash. So, we look at the
   * signature-specification algorithm, and try to do something intelligent.
   * -- Kathy Weinhold, CertCo
   */
  /*
   * Note 2: It seems that the mentioned passage from RFC 2560 (section
   * 4.2.1) is open for interpretation.  I've done tests against another
   * responder, and found that it doesn't do the double hashing that the RFC
   * seems to say one should.  Therefore, all relevant functions take a flag
   * saying which variant should be used.  -- Richard Levitte, OpenSSL team
   * and CeloCom
   */
typedef struct ocsp_basic_response_st {
    OCSP_RESPDATA *tbsResponseData;
    X509_ALGOR *signatureAlgorithm;
    ASN1_BIT_STRING *signature;
    STACK_OF(X509) *certs;
} OCSP_BASICRESP;

/*-
 *   CRLReason ::= ENUMERATED {
 *        unspecified             (0),
 *        keyCompromise           (1),
 *        cACompromise            (2),
 *        affiliationChanged      (3),
 *        superseded              (4),
 *        cessationOfOperation    (5),
 *        certificateHold         (6),
 *        removeFromCRL           (8) }
 */
# define OCSP_REVOKED_STATUS_NOSTATUS               -1
# define OCSP_REVOKED_STATUS_UNSPECIFIED             0
# define OCSP_REVOKED_STATUS_KEYCOMPROMISE           1
# define OCSP_REVOKED_STATUS_CACOMPROMISE            2
# define OCSP_REVOKED_STATUS_AFFILIATIONCHANGED      3
# define OCSP_REVOKED_STATUS_SUPERSEDED              4
# define OCSP_REVOKED_STATUS_CESSATIONOFOPERATION    5
# define OCSP_REVOKED_STATUS_CERTIFICATEHOLD         6
# define OCSP_REVOKED_STATUS_REMOVEFROMCRL           8

/*-
 * CrlID ::= SEQUENCE {
 *     crlUrl               [0]     EXPLICIT IA5String OPTIONAL,
 *     crlNum               [1]     EXPLICIT INTEGER OPTIONAL,
 *     crlTime              [2]     EXPLICIT GeneralizedTime OPTIONAL }
 */
typedef struct ocsp_crl_id_st {
    ASN1_IA5STRING *crlUrl;
    ASN1_INTEGER *crlNum;
    ASN1_GENERALIZEDTIME *crlTime;
} OCSP_CRLID;

/*-
 * ServiceLocator ::= SEQUENCE {
 *      issuer    Name,
 *      locator   AuthorityInfoAccessSyntax OPTIONAL }
 */
typedef struct ocsp_service_locator_st {
    X509_NAME *issuer;
    STACK_OF(ACCESS_DESCRIPTION) *locator;
} OCSP_SERVICELOC;

# define PEM_STRING_OCSP_REQUEST "OCSP REQUEST"
# define PEM_STRING_OCSP_RESPONSE "OCSP RESPONSE"

# define d2i_OCSP_REQUEST_bio(bp,p) ASN1_d2i_bio_of(OCSP_REQUEST,OCSP_REQUEST_new,d2i_OCSP_REQUEST,bp,p)

# define d2i_OCSP_RESPONSE_bio(bp,p) ASN1_d2i_bio_of(OCSP_RESPONSE,OCSP_RESPONSE_new,d2i_OCSP_RESPONSE,bp,p)

# define PEM_read_bio_OCSP_REQUEST(bp,x,cb) (OCSP_REQUEST *)PEM_ASN1_read_bio( \
     (char *(*)())d2i_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST,bp,(char **)x,cb,NULL)

# define PEM_read_bio_OCSP_RESPONSE(bp,x,cb)(OCSP_RESPONSE *)PEM_ASN1_read_bio(\
     (char *(*)())d2i_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE,bp,(char **)x,cb,NULL)

# define PEM_write_bio_OCSP_REQUEST(bp,o) \
    PEM_ASN1_write_bio((int (*)())i2d_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST,\
                        bp,(char *)o, NULL,NULL,0,NULL,NULL)

# define PEM_write_bio_OCSP_RESPONSE(bp,o) \
    PEM_ASN1_write_bio((int (*)())i2d_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE,\
                        bp,(char *)o, NULL,NULL,0,NULL,NULL)

# define i2d_OCSP_RESPONSE_bio(bp,o) ASN1_i2d_bio_of(OCSP_RESPONSE,i2d_OCSP_RESPONSE,bp,o)

# define i2d_OCSP_REQUEST_bio(bp,o) ASN1_i2d_bio_of(OCSP_REQUEST,i2d_OCSP_REQUEST,bp,o)

# define OCSP_REQUEST_sign(o,pkey,md) \
        ASN1_item_sign(ASN1_ITEM_rptr(OCSP_REQINFO),\
                o->optionalSignature->signatureAlgorithm,NULL,\
                o->optionalSignature->signature,o->tbsRequest,pkey,md)

# define OCSP_BASICRESP_sign(o,pkey,md,d) \
        ASN1_item_sign(ASN1_ITEM_rptr(OCSP_RESPDATA),o->signatureAlgorithm,NULL,\
                o->signature,o->tbsResponseData,pkey,md)

# define OCSP_REQUEST_verify(a,r) ASN1_item_verify(ASN1_ITEM_rptr(OCSP_REQINFO),\
        a->optionalSignature->signatureAlgorithm,\
        a->optionalSignature->signature,a->tbsRequest,r)

# define OCSP_BASICRESP_verify(a,r,d) ASN1_item_verify(ASN1_ITEM_rptr(OCSP_RESPDATA),\
        a->signatureAlgorithm,a->signature,a->tbsResponseData,r)

# define ASN1_BIT_STRING_digest(data,type,md,len) \
        ASN1_item_digest(ASN1_ITEM_rptr(ASN1_BIT_STRING),type,data,md,len)

# define OCSP_CERTSTATUS_dup(cs)\
                (OCSP_CERTSTATUS*)ASN1_dup((int(*)())i2d_OCSP_CERTSTATUS,\
                (char *(*)())d2i_OCSP_CERTSTATUS,(char *)(cs))

OCSP_CERTID *OCSP_CERTID_dup(OCSP_CERTID *id);

OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, const char *path, OCSP_REQUEST *req);
OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, const char *path, OCSP_REQUEST *req,
                               int maxline);
int OCSP_REQ_CTX_nbio(OCSP_REQ_CTX *rctx);
int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx);
OCSP_REQ_CTX *OCSP_REQ_CTX_new(BIO *io, int maxline);
void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx);
void OCSP_set_max_response_length(OCSP_REQ_CTX *rctx, unsigned long len);
int OCSP_REQ_CTX_i2d(OCSP_REQ_CTX *rctx, const ASN1_ITEM *it,
                     ASN1_VALUE *val);
int OCSP_REQ_CTX_nbio_d2i(OCSP_REQ_CTX *rctx, ASN1_VALUE **pval,
                          const ASN1_ITEM *it);
BIO *OCSP_REQ_CTX_get0_mem_bio(OCSP_REQ_CTX *rctx);
int OCSP_REQ_CTX_i2d(OCSP_REQ_CTX *rctx, const ASN1_ITEM *it,
                     ASN1_VALUE *val);
int OCSP_REQ_CTX_http(OCSP_REQ_CTX *rctx, const char *op, const char *path);
int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req);
int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx,
                             const char *name, const char *value);

OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer);

OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst,
                              X509_NAME *issuerName,
                              ASN1_BIT_STRING *issuerKey,
                              ASN1_INTEGER *serialNumber);

OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid);

int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len);
int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len);
int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs);
int OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req);

int OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm);
int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert);

int OCSP_request_sign(OCSP_REQUEST *req,
                      X509 *signer,
                      EVP_PKEY *key,
                      const EVP_MD *dgst,
                      STACK_OF(X509) *certs, unsigned long flags);

int OCSP_response_status(OCSP_RESPONSE *resp);
OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp);

int OCSP_resp_count(OCSP_BASICRESP *bs);
OCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx);
int OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last);
int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason,
                            ASN1_GENERALIZEDTIME **revtime,
                            ASN1_GENERALIZEDTIME **thisupd,
                            ASN1_GENERALIZEDTIME **nextupd);
int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status,
                          int *reason,
                          ASN1_GENERALIZEDTIME **revtime,
                          ASN1_GENERALIZEDTIME **thisupd,
                          ASN1_GENERALIZEDTIME **nextupd);
int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd,
                        ASN1_GENERALIZEDTIME *nextupd, long sec, long maxsec);

int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs,
                        X509_STORE *store, unsigned long flags);

int OCSP_parse_url(const char *url, char **phost, char **pport, char **ppath,
                   int *pssl);

int OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b);
int OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b);

int OCSP_request_onereq_count(OCSP_REQUEST *req);
OCSP_ONEREQ *OCSP_request_onereq_get0(OCSP_REQUEST *req, int i);
OCSP_CERTID *OCSP_onereq_get0_id(OCSP_ONEREQ *one);
int OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd,
                      ASN1_OCTET_STRING **pikeyHash,
                      ASN1_INTEGER **pserial, OCSP_CERTID *cid);
int OCSP_request_is_signed(OCSP_REQUEST *req);
OCSP_RESPONSE *OCSP_response_create(int status, OCSP_BASICRESP *bs);
OCSP_SINGLERESP *OCSP_basic_add1_status(OCSP_BASICRESP *rsp,
                                        OCSP_CERTID *cid,
                                        int status, int reason,
                                        ASN1_TIME *revtime,
                                        ASN1_TIME *thisupd,
                                        ASN1_TIME *nextupd);
int OCSP_basic_add1_cert(OCSP_BASICRESP *resp, X509 *cert);
int OCSP_basic_sign(OCSP_BASICRESP *brsp,
                    X509 *signer, EVP_PKEY *key, const EVP_MD *dgst,
                    STACK_OF(X509) *certs, unsigned long flags);

X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim);

X509_EXTENSION *OCSP_accept_responses_new(char **oids);

X509_EXTENSION *OCSP_archive_cutoff_new(char *tim);

X509_EXTENSION *OCSP_url_svcloc_new(X509_NAME *issuer, char **urls);

int OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x);
int OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos);
int OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, ASN1_OBJECT *obj,
                                int lastpos);
int OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos);
X509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc);
X509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc);
void *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit,
                                int *idx);
int OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit,
                              unsigned long flags);
int OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc);

int OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x);
int OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos);
int OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, ASN1_OBJECT *obj, int lastpos);
int OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos);
X509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc);
X509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc);
void *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx);
int OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit,
                             unsigned long flags);
int OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc);

int OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x);
int OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos);
int OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, ASN1_OBJECT *obj,
                                  int lastpos);
int OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit,
                                       int lastpos);
X509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc);
X509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc);
void *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit,
                                  int *idx);
int OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value,
                                int crit, unsigned long flags);
int OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc);

int OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x);
int OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos);
int OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, ASN1_OBJECT *obj,
                                   int lastpos);
int OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit,
                                        int lastpos);
X509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc);
X509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc);
void *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit,
                                   int *idx);
int OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value,
                                 int crit, unsigned long flags);
int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc);

DECLARE_ASN1_FUNCTIONS(OCSP_SINGLERESP)
DECLARE_ASN1_FUNCTIONS(OCSP_CERTSTATUS)
DECLARE_ASN1_FUNCTIONS(OCSP_REVOKEDINFO)
DECLARE_ASN1_FUNCTIONS(OCSP_BASICRESP)
DECLARE_ASN1_FUNCTIONS(OCSP_RESPDATA)
DECLARE_ASN1_FUNCTIONS(OCSP_RESPID)
DECLARE_ASN1_FUNCTIONS(OCSP_RESPONSE)
DECLARE_ASN1_FUNCTIONS(OCSP_RESPBYTES)
DECLARE_ASN1_FUNCTIONS(OCSP_ONEREQ)
DECLARE_ASN1_FUNCTIONS(OCSP_CERTID)
DECLARE_ASN1_FUNCTIONS(OCSP_REQUEST)
DECLARE_ASN1_FUNCTIONS(OCSP_SIGNATURE)
DECLARE_ASN1_FUNCTIONS(OCSP_REQINFO)
DECLARE_ASN1_FUNCTIONS(OCSP_CRLID)
DECLARE_ASN1_FUNCTIONS(OCSP_SERVICELOC)

const char *OCSP_response_status_str(long s);
const char *OCSP_cert_status_str(long s);
const char *OCSP_crl_reason_str(long s);

int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST *a, unsigned long flags);
int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE *o, unsigned long flags);

int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
                      X509_STORE *st, unsigned long flags);

/* BEGIN ERROR CODES */
/*
 * The following lines are auto generated by the script mkerr.pl. Any changes
 * made after this point may be overwritten when the script is next run.
 */
void ERR_load_OCSP_strings(void);

/* Error codes for the OCSP functions. */

/* Function codes. */
# define OCSP_F_ASN1_STRING_ENCODE                        100
# define OCSP_F_D2I_OCSP_NONCE                            102
# define OCSP_F_OCSP_BASIC_ADD1_STATUS                    103
# define OCSP_F_OCSP_BASIC_SIGN                           104
# define OCSP_F_OCSP_BASIC_VERIFY                         105
# define OCSP_F_OCSP_CERT_ID_NEW                          101
# define OCSP_F_OCSP_CHECK_DELEGATED                      106
# define OCSP_F_OCSP_CHECK_IDS                            107
# define OCSP_F_OCSP_CHECK_ISSUER                         108
# define OCSP_F_OCSP_CHECK_VALIDITY                       115
# define OCSP_F_OCSP_MATCH_ISSUERID                       109
# define OCSP_F_OCSP_PARSE_URL                            114
# define OCSP_F_OCSP_REQUEST_SIGN                         110
# define OCSP_F_OCSP_REQUEST_VERIFY                       116
# define OCSP_F_OCSP_RESPONSE_GET1_BASIC                  111
# define OCSP_F_OCSP_SENDREQ_BIO                          112
# define OCSP_F_OCSP_SENDREQ_NBIO                         117
# define OCSP_F_PARSE_HTTP_LINE1                          118
# define OCSP_F_REQUEST_VERIFY                            113

/* Reason codes. */
# define OCSP_R_BAD_DATA                                  100
# define OCSP_R_CERTIFICATE_VERIFY_ERROR                  101
# define OCSP_R_DIGEST_ERR                                102
# define OCSP_R_ERROR_IN_NEXTUPDATE_FIELD                 122
# define OCSP_R_ERROR_IN_THISUPDATE_FIELD                 123
# define OCSP_R_ERROR_PARSING_URL                         121
# define OCSP_R_MISSING_OCSPSIGNING_USAGE                 103
# define OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE              124
# define OCSP_R_NOT_BASIC_RESPONSE                        104
# define OCSP_R_NO_CERTIFICATES_IN_CHAIN                  105
# define OCSP_R_NO_CONTENT                                106
# define OCSP_R_NO_PUBLIC_KEY                             107
# define OCSP_R_NO_RESPONSE_DATA                          108
# define OCSP_R_NO_REVOKED_TIME                           109
# define OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE    110
# define OCSP_R_REQUEST_NOT_SIGNED                        128
# define OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA      111
# define OCSP_R_ROOT_CA_NOT_TRUSTED                       112
# define OCSP_R_SERVER_READ_ERROR                         113
# define OCSP_R_SERVER_RESPONSE_ERROR                     114
# define OCSP_R_SERVER_RESPONSE_PARSE_ERROR               115
# define OCSP_R_SERVER_WRITE_ERROR                        116
# define OCSP_R_SIGNATURE_FAILURE                         117
# define OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND              118
# define OCSP_R_STATUS_EXPIRED                            125
# define OCSP_R_STATUS_NOT_YET_VALID                      126
# define OCSP_R_STATUS_TOO_OLD                            127
# define OCSP_R_UNKNOWN_MESSAGE_DIGEST                    119
# define OCSP_R_UNKNOWN_NID                               120
# define OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE            129

#ifdef  __cplusplus
}
#endif
#endif
openssl/md4.h000064400000011262151733316620007075 0ustar00/* crypto/md4/md4.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#ifndef HEADER_MD4_H
# define HEADER_MD4_H

# include <openssl/e_os2.h>
# include <stddef.h>

#ifdef  __cplusplus
extern "C" {
#endif

# ifdef OPENSSL_NO_MD4
#  error MD4 is disabled.
# endif

/*-
 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 * ! MD4_LONG has to be at least 32 bits wide. If it's wider, then !
 * ! MD4_LONG_LOG2 has to be defined along.                        !
 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 */

# if defined(__LP32__)
#  define MD4_LONG unsigned long
# elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
#  define MD4_LONG unsigned long
#  define MD4_LONG_LOG2 3
/*
 * _CRAY note. I could declare short, but I have no idea what impact
 * does it have on performance on none-T3E machines. I could declare
 * int, but at least on C90 sizeof(int) can be chosen at compile time.
 * So I've chosen long...
 *                                      <appro@fy.chalmers.se>
 */
# else
#  define MD4_LONG unsigned int
# endif

# define MD4_CBLOCK      64
# define MD4_LBLOCK      (MD4_CBLOCK/4)
# define MD4_DIGEST_LENGTH 16

typedef struct MD4state_st {
    MD4_LONG A, B, C, D;
    MD4_LONG Nl, Nh;
    MD4_LONG data[MD4_LBLOCK];
    unsigned int num;
} MD4_CTX;

# ifdef OPENSSL_FIPS
int private_MD4_Init(MD4_CTX *c);
# endif
int MD4_Init(MD4_CTX *c);
int MD4_Update(MD4_CTX *c, const void *data, size_t len);
int MD4_Final(unsigned char *md, MD4_CTX *c);
unsigned char *MD4(const unsigned char *d, size_t n, unsigned char *md);
void MD4_Transform(MD4_CTX *c, const unsigned char *b);
#ifdef  __cplusplus
}
#endif

#endif
openssl/ecdh.h000064400000012107151733316620007313 0ustar00/* crypto/ecdh/ecdh.h */
/* ====================================================================
 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
 *
 * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
 * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
 * to the OpenSSL project.
 *
 * The ECC Code is licensed pursuant to the OpenSSL open source
 * license provided below.
 *
 * The ECDH software is originally written by Douglas Stebila of
 * Sun Microsystems Laboratories.
 *
 */
/* ====================================================================
 * Copyright (c) 2000-2002 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */
#ifndef HEADER_ECDH_H
# define HEADER_ECDH_H

# include <openssl/opensslconf.h>

# ifdef OPENSSL_NO_ECDH
#  error ECDH is disabled.
# endif

# include <openssl/ec.h>
# include <openssl/ossl_typ.h>
# ifndef OPENSSL_NO_DEPRECATED
#  include <openssl/bn.h>
# endif

#ifdef __cplusplus
extern "C" {
#endif

# define EC_FLAG_COFACTOR_ECDH   0x1000

const ECDH_METHOD *ECDH_OpenSSL(void);

void ECDH_set_default_method(const ECDH_METHOD *);
const ECDH_METHOD *ECDH_get_default_method(void);
int ECDH_set_method(EC_KEY *, const ECDH_METHOD *);

int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
                     EC_KEY *ecdh, void *(*KDF) (const void *in, size_t inlen,
                                                 void *out, size_t *outlen));

int ECDH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new
                          *new_func, CRYPTO_EX_dup *dup_func,
                          CRYPTO_EX_free *free_func);
int ECDH_set_ex_data(EC_KEY *d, int idx, void *arg);
void *ECDH_get_ex_data(EC_KEY *d, int idx);

int ECDH_KDF_X9_62(unsigned char *out, size_t outlen,
                   const unsigned char *Z, size_t Zlen,
                   const unsigned char *sinfo, size_t sinfolen,
                   const EVP_MD *md);

/* BEGIN ERROR CODES */
/*
 * The following lines are auto generated by the script mkerr.pl. Any changes
 * made after this point may be overwritten when the script is next run.
 */
void ERR_load_ECDH_strings(void);

/* Error codes for the ECDH functions. */

/* Function codes. */
# define ECDH_F_ECDH_CHECK                                102
# define ECDH_F_ECDH_COMPUTE_KEY                          100
# define ECDH_F_ECDH_DATA_NEW_METHOD                      101

/* Reason codes. */
# define ECDH_R_KDF_FAILED                                102
# define ECDH_R_NON_FIPS_METHOD                           103
# define ECDH_R_NO_PRIVATE_VALUE                          100
# define ECDH_R_POINT_ARITHMETIC_FAILURE                  101

#ifdef  __cplusplus
}
#endif
#endif
openssl/pkcs12.h000064400000035003151733316620007513 0ustar00/* pkcs12.h */
/*
 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
 * 1999.
 */
/* ====================================================================
 * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#ifndef HEADER_PKCS12_H
# define HEADER_PKCS12_H

# include <openssl/bio.h>
# include <openssl/x509.h>

#ifdef __cplusplus
extern "C" {
#endif

# define PKCS12_KEY_ID   1
# define PKCS12_IV_ID    2
# define PKCS12_MAC_ID   3

/* Default iteration count */
# ifndef PKCS12_DEFAULT_ITER
#  define PKCS12_DEFAULT_ITER     PKCS5_DEFAULT_ITER
# endif

# define PKCS12_MAC_KEY_LENGTH 20

# define PKCS12_SALT_LEN 8

/* Uncomment out next line for unicode password and names, otherwise ASCII */

/*
 * #define PBE_UNICODE
 */

# ifdef PBE_UNICODE
#  define PKCS12_key_gen PKCS12_key_gen_uni
#  define PKCS12_add_friendlyname PKCS12_add_friendlyname_uni
# else
#  define PKCS12_key_gen PKCS12_key_gen_asc
#  define PKCS12_add_friendlyname PKCS12_add_friendlyname_asc
# endif

/* MS key usage constants */

# define KEY_EX  0x10
# define KEY_SIG 0x80

typedef struct {
    X509_SIG *dinfo;
    ASN1_OCTET_STRING *salt;
    ASN1_INTEGER *iter;         /* defaults to 1 */
} PKCS12_MAC_DATA;

typedef struct {
    ASN1_INTEGER *version;
    PKCS12_MAC_DATA *mac;
    PKCS7 *authsafes;
} PKCS12;

typedef struct {
    ASN1_OBJECT *type;
    union {
        struct pkcs12_bag_st *bag; /* secret, crl and certbag */
        struct pkcs8_priv_key_info_st *keybag; /* keybag */
        X509_SIG *shkeybag;     /* shrouded key bag */
        STACK_OF(PKCS12_SAFEBAG) *safes;
        ASN1_TYPE *other;
    } value;
    STACK_OF(X509_ATTRIBUTE) *attrib;
} PKCS12_SAFEBAG;

DECLARE_STACK_OF(PKCS12_SAFEBAG)
DECLARE_ASN1_SET_OF(PKCS12_SAFEBAG)
DECLARE_PKCS12_STACK_OF(PKCS12_SAFEBAG)

typedef struct pkcs12_bag_st {
    ASN1_OBJECT *type;
    union {
        ASN1_OCTET_STRING *x509cert;
        ASN1_OCTET_STRING *x509crl;
        ASN1_OCTET_STRING *octet;
        ASN1_IA5STRING *sdsicert;
        ASN1_TYPE *other;       /* Secret or other bag */
    } value;
} PKCS12_BAGS;

# define PKCS12_ERROR    0
# define PKCS12_OK       1

/* Compatibility macros */

# define M_PKCS12_x5092certbag PKCS12_x5092certbag
# define M_PKCS12_x509crl2certbag PKCS12_x509crl2certbag

# define M_PKCS12_certbag2x509 PKCS12_certbag2x509
# define M_PKCS12_certbag2x509crl PKCS12_certbag2x509crl

# define M_PKCS12_unpack_p7data PKCS12_unpack_p7data
# define M_PKCS12_pack_authsafes PKCS12_pack_authsafes
# define M_PKCS12_unpack_authsafes PKCS12_unpack_authsafes
# define M_PKCS12_unpack_p7encdata PKCS12_unpack_p7encdata

# define M_PKCS12_decrypt_skey PKCS12_decrypt_skey
# define M_PKCS8_decrypt PKCS8_decrypt

# define M_PKCS12_bag_type(bg) OBJ_obj2nid((bg)->type)
# define M_PKCS12_cert_bag_type(bg) OBJ_obj2nid((bg)->value.bag->type)
# define M_PKCS12_crl_bag_type M_PKCS12_cert_bag_type

# define PKCS12_get_attr(bag, attr_nid) \
                         PKCS12_get_attr_gen(bag->attrib, attr_nid)

# define PKCS8_get_attr(p8, attr_nid) \
                PKCS12_get_attr_gen(p8->attributes, attr_nid)

# define PKCS12_mac_present(p12) ((p12)->mac ? 1 : 0)

PKCS12_SAFEBAG *PKCS12_x5092certbag(X509 *x509);
PKCS12_SAFEBAG *PKCS12_x509crl2certbag(X509_CRL *crl);
X509 *PKCS12_certbag2x509(PKCS12_SAFEBAG *bag);
X509_CRL *PKCS12_certbag2x509crl(PKCS12_SAFEBAG *bag);

PKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it,
                                         int nid1, int nid2);
PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG(PKCS8_PRIV_KEY_INFO *p8);
PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *p8, const char *pass,
                                   int passlen);
PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(PKCS12_SAFEBAG *bag,
                                         const char *pass, int passlen);
X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher,
                        const char *pass, int passlen, unsigned char *salt,
                        int saltlen, int iter, PKCS8_PRIV_KEY_INFO *p8);
PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass,
                                     int passlen, unsigned char *salt,
                                     int saltlen, int iter,
                                     PKCS8_PRIV_KEY_INFO *p8);
PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk);
STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7);
PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen,
                             unsigned char *salt, int saltlen, int iter,
                             STACK_OF(PKCS12_SAFEBAG) *bags);
STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass,
                                                  int passlen);

int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes);
STACK_OF(PKCS7) *PKCS12_unpack_authsafes(PKCS12 *p12);

int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name,
                          int namelen);
int PKCS12_add_friendlyname_asc(PKCS12_SAFEBAG *bag, const char *name,
                                int namelen);
int PKCS12_add_CSPName_asc(PKCS12_SAFEBAG *bag, const char *name,
                           int namelen);
int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag,
                                const unsigned char *name, int namelen);
int PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage);
ASN1_TYPE *PKCS12_get_attr_gen(STACK_OF(X509_ATTRIBUTE) *attrs, int attr_nid);
char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag);
unsigned char *PKCS12_pbe_crypt(X509_ALGOR *algor, const char *pass,
                                int passlen, unsigned char *in, int inlen,
                                unsigned char **data, int *datalen,
                                int en_de);
void *PKCS12_item_decrypt_d2i(X509_ALGOR *algor, const ASN1_ITEM *it,
                              const char *pass, int passlen,
                              ASN1_OCTET_STRING *oct, int zbuf);
ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor,
                                           const ASN1_ITEM *it,
                                           const char *pass, int passlen,
                                           void *obj, int zbuf);
PKCS12 *PKCS12_init(int mode);
int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt,
                       int saltlen, int id, int iter, int n,
                       unsigned char *out, const EVP_MD *md_type);
int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
                       int saltlen, int id, int iter, int n,
                       unsigned char *out, const EVP_MD *md_type);
int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
                        ASN1_TYPE *param, const EVP_CIPHER *cipher,
                        const EVP_MD *md_type, int en_de);
int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
                   unsigned char *mac, unsigned int *maclen);
int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen);
int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen,
                   unsigned char *salt, int saltlen, int iter,
                   const EVP_MD *md_type);
int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt,
                     int saltlen, const EVP_MD *md_type);
unsigned char *OPENSSL_asc2uni(const char *asc, int asclen,
                               unsigned char **uni, int *unilen);
char *OPENSSL_uni2asc(unsigned char *uni, int unilen);

DECLARE_ASN1_FUNCTIONS(PKCS12)
DECLARE_ASN1_FUNCTIONS(PKCS12_MAC_DATA)
DECLARE_ASN1_FUNCTIONS(PKCS12_SAFEBAG)
DECLARE_ASN1_FUNCTIONS(PKCS12_BAGS)

DECLARE_ASN1_ITEM(PKCS12_SAFEBAGS)
DECLARE_ASN1_ITEM(PKCS12_AUTHSAFES)

void PKCS12_PBE_add(void);
int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
                 STACK_OF(X509) **ca);
PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert,
                      STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter,
                      int mac_iter, int keytype);

PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert);
PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags,
                               EVP_PKEY *key, int key_usage, int iter,
                               int key_nid, char *pass);
int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
                    int safe_nid, int iter, char *pass);
PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int p7_nid);

int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12);
int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12);
PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12);
PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12);
int PKCS12_newpass(PKCS12 *p12, const char *oldpass, const char *newpass);

/* BEGIN ERROR CODES */
/*
 * The following lines are auto generated by the script mkerr.pl. Any changes
 * made after this point may be overwritten when the script is next run.
 */
void ERR_load_PKCS12_strings(void);

/* Error codes for the PKCS12 functions. */

/* Function codes. */
# define PKCS12_F_PARSE_BAG                               129
# define PKCS12_F_PARSE_BAGS                              103
# define PKCS12_F_PKCS12_ADD_FRIENDLYNAME                 100
# define PKCS12_F_PKCS12_ADD_FRIENDLYNAME_ASC             127
# define PKCS12_F_PKCS12_ADD_FRIENDLYNAME_UNI             102
# define PKCS12_F_PKCS12_ADD_LOCALKEYID                   104
# define PKCS12_F_PKCS12_CREATE                           105
# define PKCS12_F_PKCS12_GEN_MAC                          107
# define PKCS12_F_PKCS12_INIT                             109
# define PKCS12_F_PKCS12_ITEM_DECRYPT_D2I                 106
# define PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT                 108
# define PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG                117
# define PKCS12_F_PKCS12_KEY_GEN_ASC                      110
# define PKCS12_F_PKCS12_KEY_GEN_UNI                      111
# define PKCS12_F_PKCS12_MAKE_KEYBAG                      112
# define PKCS12_F_PKCS12_MAKE_SHKEYBAG                    113
# define PKCS12_F_PKCS12_NEWPASS                          128
# define PKCS12_F_PKCS12_PACK_P7DATA                      114
# define PKCS12_F_PKCS12_PACK_P7ENCDATA                   115
# define PKCS12_F_PKCS12_PARSE                            118
# define PKCS12_F_PKCS12_PBE_CRYPT                        119
# define PKCS12_F_PKCS12_PBE_KEYIVGEN                     120
# define PKCS12_F_PKCS12_SETUP_MAC                        122
# define PKCS12_F_PKCS12_SET_MAC                          123
# define PKCS12_F_PKCS12_UNPACK_AUTHSAFES                 130
# define PKCS12_F_PKCS12_UNPACK_P7DATA                    131
# define PKCS12_F_PKCS12_VERIFY_MAC                       126
# define PKCS12_F_PKCS8_ADD_KEYUSAGE                      124
# define PKCS12_F_PKCS8_ENCRYPT                           125

/* Reason codes. */
# define PKCS12_R_CANT_PACK_STRUCTURE                     100
# define PKCS12_R_CONTENT_TYPE_NOT_DATA                   121
# define PKCS12_R_DECODE_ERROR                            101
# define PKCS12_R_ENCODE_ERROR                            102
# define PKCS12_R_ENCRYPT_ERROR                           103
# define PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE       120
# define PKCS12_R_INVALID_NULL_ARGUMENT                   104
# define PKCS12_R_INVALID_NULL_PKCS12_POINTER             105
# define PKCS12_R_IV_GEN_ERROR                            106
# define PKCS12_R_KEY_GEN_ERROR                           107
# define PKCS12_R_MAC_ABSENT                              108
# define PKCS12_R_MAC_GENERATION_ERROR                    109
# define PKCS12_R_MAC_SETUP_ERROR                         110
# define PKCS12_R_MAC_STRING_SET_ERROR                    111
# define PKCS12_R_MAC_VERIFY_ERROR                        112
# define PKCS12_R_MAC_VERIFY_FAILURE                      113
# define PKCS12_R_PARSE_ERROR                             114
# define PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR           115
# define PKCS12_R_PKCS12_CIPHERFINAL_ERROR                116
# define PKCS12_R_PKCS12_PBE_CRYPT_ERROR                  117
# define PKCS12_R_UNKNOWN_DIGEST_ALGORITHM                118
# define PKCS12_R_UNSUPPORTED_PKCS12_MODE                 119

#ifdef  __cplusplus
}
#endif
#endif
openssl/e_os2.h000064400000025301151733316620007417 0ustar00/* e_os2.h */
/* ====================================================================
 * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#include <openssl/opensslconf.h>

#ifndef HEADER_E_OS2_H
# define HEADER_E_OS2_H

#ifdef  __cplusplus
extern "C" {
#endif

/******************************************************************************
 * Detect operating systems.  This probably needs completing.
 * The result is that at least one OPENSSL_SYS_os macro should be defined.
 * However, if none is defined, Unix is assumed.
 **/

# define OPENSSL_SYS_UNIX

/* ---------------------- Macintosh, before MacOS X ----------------------- */
# if defined(__MWERKS__) && defined(macintosh) || defined(OPENSSL_SYSNAME_MAC)
#  undef OPENSSL_SYS_UNIX
#  define OPENSSL_SYS_MACINTOSH_CLASSIC
# endif

/* ---------------------- NetWare ----------------------------------------- */
# if defined(NETWARE) || defined(OPENSSL_SYSNAME_NETWARE)
#  undef OPENSSL_SYS_UNIX
#  define OPENSSL_SYS_NETWARE
# endif

/* --------------------- Microsoft operating systems ---------------------- */

/*
 * Note that MSDOS actually denotes 32-bit environments running on top of
 * MS-DOS, such as DJGPP one.
 */
# if defined(OPENSSL_SYSNAME_MSDOS)
#  undef OPENSSL_SYS_UNIX
#  define OPENSSL_SYS_MSDOS
# endif

/*
 * For 32 bit environment, there seems to be the CygWin environment and then
 * all the others that try to do the same thing Microsoft does...
 */
# if defined(OPENSSL_SYSNAME_UWIN)
#  undef OPENSSL_SYS_UNIX
#  define OPENSSL_SYS_WIN32_UWIN
# else
#  if defined(__CYGWIN__) || defined(OPENSSL_SYSNAME_CYGWIN)
#   undef OPENSSL_SYS_UNIX
#   define OPENSSL_SYS_WIN32_CYGWIN
#  else
#   if defined(_WIN32) || defined(OPENSSL_SYSNAME_WIN32)
#    undef OPENSSL_SYS_UNIX
#    define OPENSSL_SYS_WIN32
#   endif
#   if defined(_WIN64) || defined(OPENSSL_SYSNAME_WIN64)
#    undef OPENSSL_SYS_UNIX
#    if !defined(OPENSSL_SYS_WIN64)
#     define OPENSSL_SYS_WIN64
#    endif
#   endif
#   if defined(OPENSSL_SYSNAME_WINNT)
#    undef OPENSSL_SYS_UNIX
#    define OPENSSL_SYS_WINNT
#   endif
#   if defined(OPENSSL_SYSNAME_WINCE)
#    undef OPENSSL_SYS_UNIX
#    define OPENSSL_SYS_WINCE
#   endif
#  endif
# endif

/* Anything that tries to look like Microsoft is "Windows" */
# if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN64) || defined(OPENSSL_SYS_WINNT) || defined(OPENSSL_SYS_WINCE)
#  undef OPENSSL_SYS_UNIX
#  define OPENSSL_SYS_WINDOWS
#  ifndef OPENSSL_SYS_MSDOS
#   define OPENSSL_SYS_MSDOS
#  endif
# endif

/*
 * DLL settings.  This part is a bit tough, because it's up to the
 * application implementor how he or she will link the application, so it
 * requires some macro to be used.
 */
# ifdef OPENSSL_SYS_WINDOWS
#  ifndef OPENSSL_OPT_WINDLL
#   if defined(_WINDLL)         /* This is used when building OpenSSL to
                                 * indicate that DLL linkage should be used */
#    define OPENSSL_OPT_WINDLL
#   endif
#  endif
# endif

/* ------------------------------- OpenVMS -------------------------------- */
# if defined(__VMS) || defined(VMS) || defined(OPENSSL_SYSNAME_VMS)
#  undef OPENSSL_SYS_UNIX
#  define OPENSSL_SYS_VMS
#  if defined(__DECC)
#   define OPENSSL_SYS_VMS_DECC
#  elif defined(__DECCXX)
#   define OPENSSL_SYS_VMS_DECC
#   define OPENSSL_SYS_VMS_DECCXX
#  else
#   define OPENSSL_SYS_VMS_NODECC
#  endif
# endif

/* -------------------------------- OS/2 ---------------------------------- */
# if defined(__EMX__) || defined(__OS2__)
#  undef OPENSSL_SYS_UNIX
#  define OPENSSL_SYS_OS2
# endif

/* -------------------------------- Unix ---------------------------------- */
# ifdef OPENSSL_SYS_UNIX
#  if defined(linux) || defined(__linux__) || defined(OPENSSL_SYSNAME_LINUX)
#   define OPENSSL_SYS_LINUX
#  endif
#  ifdef OPENSSL_SYSNAME_MPE
#   define OPENSSL_SYS_MPE
#  endif
#  ifdef OPENSSL_SYSNAME_SNI
#   define OPENSSL_SYS_SNI
#  endif
#  ifdef OPENSSL_SYSNAME_ULTRASPARC
#   define OPENSSL_SYS_ULTRASPARC
#  endif
#  ifdef OPENSSL_SYSNAME_NEWS4
#   define OPENSSL_SYS_NEWS4
#  endif
#  ifdef OPENSSL_SYSNAME_MACOSX
#   define OPENSSL_SYS_MACOSX
#  endif
#  ifdef OPENSSL_SYSNAME_MACOSX_RHAPSODY
#   define OPENSSL_SYS_MACOSX_RHAPSODY
#   define OPENSSL_SYS_MACOSX
#  endif
#  ifdef OPENSSL_SYSNAME_SUNOS
#   define OPENSSL_SYS_SUNOS
#  endif
#  if defined(_CRAY) || defined(OPENSSL_SYSNAME_CRAY)
#   define OPENSSL_SYS_CRAY
#  endif
#  if defined(_AIX) || defined(OPENSSL_SYSNAME_AIX)
#   define OPENSSL_SYS_AIX
#  endif
# endif

/* -------------------------------- VOS ----------------------------------- */
# if defined(__VOS__) || defined(OPENSSL_SYSNAME_VOS)
#  define OPENSSL_SYS_VOS
#  ifdef __HPPA__
#   define OPENSSL_SYS_VOS_HPPA
#  endif
#  ifdef __IA32__
#   define OPENSSL_SYS_VOS_IA32
#  endif
# endif

/* ------------------------------ VxWorks --------------------------------- */
# ifdef OPENSSL_SYSNAME_VXWORKS
#  define OPENSSL_SYS_VXWORKS
# endif

/* -------------------------------- BeOS ---------------------------------- */
# if defined(__BEOS__)
#  define OPENSSL_SYS_BEOS
#  include <sys/socket.h>
#  if defined(BONE_VERSION)
#   define OPENSSL_SYS_BEOS_BONE
#  else
#   define OPENSSL_SYS_BEOS_R5
#  endif
# endif

/**
 * That's it for OS-specific stuff
 *****************************************************************************/

/* Specials for I/O an exit */
# ifdef OPENSSL_SYS_MSDOS
#  define OPENSSL_UNISTD_IO <io.h>
#  define OPENSSL_DECLARE_EXIT extern void exit(int);
# else
#  define OPENSSL_UNISTD_IO OPENSSL_UNISTD
#  define OPENSSL_DECLARE_EXIT  /* declared in unistd.h */
# endif

/*-
 * Definitions of OPENSSL_GLOBAL and OPENSSL_EXTERN, to define and declare
 * certain global symbols that, with some compilers under VMS, have to be
 * defined and declared explicitely with globaldef and globalref.
 * Definitions of OPENSSL_EXPORT and OPENSSL_IMPORT, to define and declare
 * DLL exports and imports for compilers under Win32.  These are a little
 * more complicated to use.  Basically, for any library that exports some
 * global variables, the following code must be present in the header file
 * that declares them, before OPENSSL_EXTERN is used:
 *
 * #ifdef SOME_BUILD_FLAG_MACRO
 * # undef OPENSSL_EXTERN
 * # define OPENSSL_EXTERN OPENSSL_EXPORT
 * #endif
 *
 * The default is to have OPENSSL_EXPORT, OPENSSL_IMPORT and OPENSSL_GLOBAL
 * have some generally sensible values, and for OPENSSL_EXTERN to have the
 * value OPENSSL_IMPORT.
 */

# if defined(OPENSSL_SYS_VMS_NODECC)
#  define OPENSSL_EXPORT globalref
#  define OPENSSL_IMPORT globalref
#  define OPENSSL_GLOBAL globaldef
# elif defined(OPENSSL_SYS_WINDOWS) && defined(OPENSSL_OPT_WINDLL)
#  define OPENSSL_EXPORT extern __declspec(dllexport)
#  define OPENSSL_IMPORT extern __declspec(dllimport)
#  define OPENSSL_GLOBAL
# else
#  define OPENSSL_EXPORT extern
#  define OPENSSL_IMPORT extern
#  define OPENSSL_GLOBAL
# endif
# define OPENSSL_EXTERN OPENSSL_IMPORT

/*-
 * Macros to allow global variables to be reached through function calls when
 * required (if a shared library version requires it, for example.
 * The way it's done allows definitions like this:
 *
 *      // in foobar.c
 *      OPENSSL_IMPLEMENT_GLOBAL(int,foobar,0)
 *      // in foobar.h
 *      OPENSSL_DECLARE_GLOBAL(int,foobar);
 *      #define foobar OPENSSL_GLOBAL_REF(foobar)
 */
# ifdef OPENSSL_EXPORT_VAR_AS_FUNCTION
#  define OPENSSL_IMPLEMENT_GLOBAL(type,name,value)                      \
        type *_shadow_##name(void)                                      \
        { static type _hide_##name=value; return &_hide_##name; }
#  define OPENSSL_DECLARE_GLOBAL(type,name) type *_shadow_##name(void)
#  define OPENSSL_GLOBAL_REF(name) (*(_shadow_##name()))
# else
#  define OPENSSL_IMPLEMENT_GLOBAL(type,name,value) OPENSSL_GLOBAL type _shadow_##name=value;
#  define OPENSSL_DECLARE_GLOBAL(type,name) OPENSSL_EXPORT type _shadow_##name
#  define OPENSSL_GLOBAL_REF(name) _shadow_##name
# endif

# if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) && macintosh==1 && !defined(MAC_OS_GUSI_SOURCE)
#  define ossl_ssize_t long
# endif

# ifdef OPENSSL_SYS_MSDOS
#  define ossl_ssize_t long
# endif

# if defined(NeXT) || defined(OPENSSL_SYS_NEWS4) || defined(OPENSSL_SYS_SUNOS)
#  define ssize_t int
# endif

# if defined(__ultrix) && !defined(ssize_t)
#  define ossl_ssize_t int
# endif

# ifndef ossl_ssize_t
#  define ossl_ssize_t ssize_t
# endif

#ifdef  __cplusplus
}
#endif
#endif
openssl/ecdsa.h000064400000033326151733316620007475 0ustar00/* crypto/ecdsa/ecdsa.h */
/**
 * \file   crypto/ecdsa/ecdsa.h Include file for the OpenSSL ECDSA functions
 * \author Written by Nils Larsch for the OpenSSL project
 */
/* ====================================================================
 * Copyright (c) 2000-2005 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */
#ifndef HEADER_ECDSA_H
# define HEADER_ECDSA_H

# include <openssl/opensslconf.h>

# ifdef OPENSSL_NO_ECDSA
#  error ECDSA is disabled.
# endif

# include <openssl/ec.h>
# include <openssl/ossl_typ.h>
# ifndef OPENSSL_NO_DEPRECATED
#  include <openssl/bn.h>
# endif

#ifdef __cplusplus
extern "C" {
#endif

typedef struct ECDSA_SIG_st {
    BIGNUM *r;
    BIGNUM *s;
} ECDSA_SIG;

/** Allocates and initialize a ECDSA_SIG structure
 *  \return pointer to a ECDSA_SIG structure or NULL if an error occurred
 */
ECDSA_SIG *ECDSA_SIG_new(void);

/** frees a ECDSA_SIG structure
 *  \param  sig  pointer to the ECDSA_SIG structure
 */
void ECDSA_SIG_free(ECDSA_SIG *sig);

/** DER encode content of ECDSA_SIG object (note: this function modifies *pp
 *  (*pp += length of the DER encoded signature)).
 *  \param  sig  pointer to the ECDSA_SIG object
 *  \param  pp   pointer to a unsigned char pointer for the output or NULL
 *  \return the length of the DER encoded ECDSA_SIG object or 0
 */
int i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp);

/** Decodes a DER encoded ECDSA signature (note: this function changes *pp
 *  (*pp += len)).
 *  \param  sig  pointer to ECDSA_SIG pointer (may be NULL)
 *  \param  pp   memory buffer with the DER encoded signature
 *  \param  len  length of the buffer
 *  \return pointer to the decoded ECDSA_SIG structure (or NULL)
 */
ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **sig, const unsigned char **pp, long len);

/** Computes the ECDSA signature of the given hash value using
 *  the supplied private key and returns the created signature.
 *  \param  dgst      pointer to the hash value
 *  \param  dgst_len  length of the hash value
 *  \param  eckey     EC_KEY object containing a private EC key
 *  \return pointer to a ECDSA_SIG structure or NULL if an error occurred
 */
ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dgst_len,
                         EC_KEY *eckey);

/** Computes ECDSA signature of a given hash value using the supplied
 *  private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
 *  \param  dgst     pointer to the hash value to sign
 *  \param  dgstlen  length of the hash value
 *  \param  kinv     BIGNUM with a pre-computed inverse k (optional)
 *  \param  rp       BIGNUM with a pre-computed rp value (optioanl),
 *                   see ECDSA_sign_setup
 *  \param  eckey    EC_KEY object containing a private EC key
 *  \return pointer to a ECDSA_SIG structure or NULL if an error occurred
 */
ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dgstlen,
                            const BIGNUM *kinv, const BIGNUM *rp,
                            EC_KEY *eckey);

/** Verifies that the supplied signature is a valid ECDSA
 *  signature of the supplied hash value using the supplied public key.
 *  \param  dgst      pointer to the hash value
 *  \param  dgst_len  length of the hash value
 *  \param  sig       ECDSA_SIG structure
 *  \param  eckey     EC_KEY object containing a public EC key
 *  \return 1 if the signature is valid, 0 if the signature is invalid
 *          and -1 on error
 */
int ECDSA_do_verify(const unsigned char *dgst, int dgst_len,
                    const ECDSA_SIG *sig, EC_KEY *eckey);

const ECDSA_METHOD *ECDSA_OpenSSL(void);

/** Sets the default ECDSA method
 *  \param  meth  new default ECDSA_METHOD
 */
void ECDSA_set_default_method(const ECDSA_METHOD *meth);

/** Returns the default ECDSA method
 *  \return pointer to ECDSA_METHOD structure containing the default method
 */
const ECDSA_METHOD *ECDSA_get_default_method(void);

/** Sets method to be used for the ECDSA operations
 *  \param  eckey  EC_KEY object
 *  \param  meth   new method
 *  \return 1 on success and 0 otherwise
 */
int ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth);

/** Returns the maximum length of the DER encoded signature
 *  \param  eckey  EC_KEY object
 *  \return numbers of bytes required for the DER encoded signature
 */
int ECDSA_size(const EC_KEY *eckey);

/** Precompute parts of the signing operation
 *  \param  eckey  EC_KEY object containing a private EC key
 *  \param  ctx    BN_CTX object (optional)
 *  \param  kinv   BIGNUM pointer for the inverse of k
 *  \param  rp     BIGNUM pointer for x coordinate of k * generator
 *  \return 1 on success and 0 otherwise
 */
int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, BIGNUM **rp);

/** Computes ECDSA signature of a given hash value using the supplied
 *  private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
 *  \param  type     this parameter is ignored
 *  \param  dgst     pointer to the hash value to sign
 *  \param  dgstlen  length of the hash value
 *  \param  sig      memory for the DER encoded created signature
 *  \param  siglen   pointer to the length of the returned signature
 *  \param  eckey    EC_KEY object containing a private EC key
 *  \return 1 on success and 0 otherwise
 */
int ECDSA_sign(int type, const unsigned char *dgst, int dgstlen,
               unsigned char *sig, unsigned int *siglen, EC_KEY *eckey);

/** Computes ECDSA signature of a given hash value using the supplied
 *  private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
 *  \param  type     this parameter is ignored
 *  \param  dgst     pointer to the hash value to sign
 *  \param  dgstlen  length of the hash value
 *  \param  sig      buffer to hold the DER encoded signature
 *  \param  siglen   pointer to the length of the returned signature
 *  \param  kinv     BIGNUM with a pre-computed inverse k (optional)
 *  \param  rp       BIGNUM with a pre-computed rp value (optioanl),
 *                   see ECDSA_sign_setup
 *  \param  eckey    EC_KEY object containing a private EC key
 *  \return 1 on success and 0 otherwise
 */
int ECDSA_sign_ex(int type, const unsigned char *dgst, int dgstlen,
                  unsigned char *sig, unsigned int *siglen,
                  const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey);

/** Verifies that the given signature is valid ECDSA signature
 *  of the supplied hash value using the specified public key.
 *  \param  type     this parameter is ignored
 *  \param  dgst     pointer to the hash value
 *  \param  dgstlen  length of the hash value
 *  \param  sig      pointer to the DER encoded signature
 *  \param  siglen   length of the DER encoded signature
 *  \param  eckey    EC_KEY object containing a public EC key
 *  \return 1 if the signature is valid, 0 if the signature is invalid
 *          and -1 on error
 */
int ECDSA_verify(int type, const unsigned char *dgst, int dgstlen,
                 const unsigned char *sig, int siglen, EC_KEY *eckey);

/* the standard ex_data functions */
int ECDSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new
                           *new_func, CRYPTO_EX_dup *dup_func,
                           CRYPTO_EX_free *free_func);
int ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg);
void *ECDSA_get_ex_data(EC_KEY *d, int idx);

/** Allocates and initialize a ECDSA_METHOD structure
 *  \param ecdsa_method pointer to ECDSA_METHOD to copy.  (May be NULL)
 *  \return pointer to a ECDSA_METHOD structure or NULL if an error occurred
 */

ECDSA_METHOD *ECDSA_METHOD_new(const ECDSA_METHOD *ecdsa_method);

/** frees a ECDSA_METHOD structure
 *  \param  ecdsa_method  pointer to the ECDSA_METHOD structure
 */
void ECDSA_METHOD_free(ECDSA_METHOD *ecdsa_method);

/**  Sets application specific data in the ECDSA_METHOD
 *   \param  ecdsa_method pointer to existing ECDSA_METHOD
 *   \param  app application specific data to set
 */

void ECDSA_METHOD_set_app_data(ECDSA_METHOD *ecdsa_method, void *app);

/** Returns application specific data from a ECDSA_METHOD structure
 *  \param ecdsa_method pointer to ECDSA_METHOD structure
 *  \return pointer to application specific data.
 */

void *ECDSA_METHOD_get_app_data(ECDSA_METHOD *ecdsa_method);

/**  Set the ECDSA_do_sign function in the ECDSA_METHOD
 *   \param  ecdsa_method  pointer to existing ECDSA_METHOD
 *   \param  ecdsa_do_sign a funtion of type ECDSA_do_sign
 */

void ECDSA_METHOD_set_sign(ECDSA_METHOD *ecdsa_method,
                           ECDSA_SIG *(*ecdsa_do_sign) (const unsigned char
                                                        *dgst, int dgst_len,
                                                        const BIGNUM *inv,
                                                        const BIGNUM *rp,
                                                        EC_KEY *eckey));

/**  Set the  ECDSA_sign_setup function in the ECDSA_METHOD
 *   \param  ecdsa_method  pointer to existing ECDSA_METHOD
 *   \param  ecdsa_sign_setup a funtion of type ECDSA_sign_setup
 */

void ECDSA_METHOD_set_sign_setup(ECDSA_METHOD *ecdsa_method,
                                 int (*ecdsa_sign_setup) (EC_KEY *eckey,
                                                          BN_CTX *ctx,
                                                          BIGNUM **kinv,
                                                          BIGNUM **r));

/**  Set the ECDSA_do_verify function in the ECDSA_METHOD
 *   \param  ecdsa_method  pointer to existing ECDSA_METHOD
 *   \param  ecdsa_do_verify a funtion of type ECDSA_do_verify
 */

void ECDSA_METHOD_set_verify(ECDSA_METHOD *ecdsa_method,
                             int (*ecdsa_do_verify) (const unsigned char
                                                     *dgst, int dgst_len,
                                                     const ECDSA_SIG *sig,
                                                     EC_KEY *eckey));

void ECDSA_METHOD_set_flags(ECDSA_METHOD *ecdsa_method, int flags);

/**  Set the flags field in the ECDSA_METHOD
 *   \param  ecdsa_method  pointer to existing ECDSA_METHOD
 *   \param  flags flags value to set
 */

void ECDSA_METHOD_set_name(ECDSA_METHOD *ecdsa_method, char *name);

/**  Set the name field in the ECDSA_METHOD
 *   \param  ecdsa_method  pointer to existing ECDSA_METHOD
 *   \param  name name to set
 */

/* BEGIN ERROR CODES */
/*
 * The following lines are auto generated by the script mkerr.pl. Any changes
 * made after this point may be overwritten when the script is next run.
 */
void ERR_load_ECDSA_strings(void);

/* Error codes for the ECDSA functions. */

/* Function codes. */
# define ECDSA_F_ECDSA_CHECK                              104
# define ECDSA_F_ECDSA_DATA_NEW_METHOD                    100
# define ECDSA_F_ECDSA_DO_SIGN                            101
# define ECDSA_F_ECDSA_DO_VERIFY                          102
# define ECDSA_F_ECDSA_METHOD_NEW                         105
# define ECDSA_F_ECDSA_SIGN_SETUP                         103

/* Reason codes. */
# define ECDSA_R_BAD_SIGNATURE                            100
# define ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE              101
# define ECDSA_R_ERR_EC_LIB                               102
# define ECDSA_R_MISSING_PARAMETERS                       103
# define ECDSA_R_NEED_NEW_SETUP_VALUES                    106
# define ECDSA_R_NON_FIPS_METHOD                          107
# define ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED          104
# define ECDSA_R_SIGNATURE_MALLOC_FAILED                  105

#ifdef  __cplusplus
}
#endif
#endif
openssl/ripemd.h000064400000010423151733316620007667 0ustar00/* crypto/ripemd/ripemd.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#ifndef HEADER_RIPEMD_H
# define HEADER_RIPEMD_H

# include <openssl/e_os2.h>
# include <stddef.h>

#ifdef  __cplusplus
extern "C" {
#endif

# ifdef OPENSSL_NO_RIPEMD
#  error RIPEMD is disabled.
# endif

# if defined(__LP32__)
#  define RIPEMD160_LONG unsigned long
# elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
#  define RIPEMD160_LONG unsigned long
#  define RIPEMD160_LONG_LOG2 3
# else
#  define RIPEMD160_LONG unsigned int
# endif

# define RIPEMD160_CBLOCK        64
# define RIPEMD160_LBLOCK        (RIPEMD160_CBLOCK/4)
# define RIPEMD160_DIGEST_LENGTH 20

typedef struct RIPEMD160state_st {
    RIPEMD160_LONG A, B, C, D, E;
    RIPEMD160_LONG Nl, Nh;
    RIPEMD160_LONG data[RIPEMD160_LBLOCK];
    unsigned int num;
} RIPEMD160_CTX;

# ifdef OPENSSL_FIPS
int private_RIPEMD160_Init(RIPEMD160_CTX *c);
# endif
int RIPEMD160_Init(RIPEMD160_CTX *c);
int RIPEMD160_Update(RIPEMD160_CTX *c, const void *data, size_t len);
int RIPEMD160_Final(unsigned char *md, RIPEMD160_CTX *c);
unsigned char *RIPEMD160(const unsigned char *d, size_t n, unsigned char *md);
void RIPEMD160_Transform(RIPEMD160_CTX *c, const unsigned char *b);
#ifdef  __cplusplus
}
#endif

#endif
openssl/opensslconf-x86_64.h000064400000017655151733316620011712 0ustar00/* Prepended at openssl package build-time.  Don't include this file directly,
 * use <openssl/opensslconf.h> instead. */

#ifndef openssl_opensslconf_multilib_redirection_h
#error "Don't include this file directly, use <openssl/opensslconf.h> instead!"
#endif

/* opensslconf.h */
/* WARNING: Generated automatically from opensslconf.h.in by Configure. */

#ifdef  __cplusplus
extern "C" {
#endif
/* OpenSSL was configured with the following options: */
#ifndef OPENSSL_DOING_MAKEDEPEND


#ifndef OPENSSL_NO_EC2M
# define OPENSSL_NO_EC2M
#endif
#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
# define OPENSSL_NO_EC_NISTP_64_GCC_128
#endif
#ifndef OPENSSL_NO_GMP
# define OPENSSL_NO_GMP
#endif
#ifndef OPENSSL_NO_GOST
# define OPENSSL_NO_GOST
#endif
#ifndef OPENSSL_NO_JPAKE
# define OPENSSL_NO_JPAKE
#endif
#ifndef OPENSSL_NO_LIBUNBOUND
# define OPENSSL_NO_LIBUNBOUND
#endif
#ifndef OPENSSL_NO_MDC2
# define OPENSSL_NO_MDC2
#endif
#ifndef OPENSSL_NO_RSAX
# define OPENSSL_NO_RSAX
#endif
#ifndef OPENSSL_NO_SRP
# define OPENSSL_NO_SRP
#endif
#ifndef OPENSSL_NO_SSL_TRACE
# define OPENSSL_NO_SSL_TRACE
#endif
#ifndef OPENSSL_NO_SSL2
# define OPENSSL_NO_SSL2
#endif
#ifndef OPENSSL_NO_STORE
# define OPENSSL_NO_STORE
#endif
#ifndef OPENSSL_NO_UNIT_TEST
# define OPENSSL_NO_UNIT_TEST
#endif
#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
# define OPENSSL_NO_WEAK_SSL_CIPHERS
#endif

#endif /* OPENSSL_DOING_MAKEDEPEND */

#ifndef OPENSSL_THREADS
# define OPENSSL_THREADS
#endif
#ifndef OPENSSL_NO_STATIC_ENGINE
# define OPENSSL_NO_STATIC_ENGINE
#endif
#ifndef OPENSSL_FIPS
# define OPENSSL_FIPS
#endif

/* The OPENSSL_NO_* macros are also defined as NO_* if the application
   asks for it.  This is a transient feature that is provided for those
   who haven't had the time to do the appropriate changes in their
   applications.  */
#ifdef OPENSSL_ALGORITHM_DEFINES
# if defined(OPENSSL_NO_EC2M) && !defined(NO_EC2M)
#  define NO_EC2M
# endif
# if defined(OPENSSL_NO_EC_NISTP_64_GCC_128) && !defined(NO_EC_NISTP_64_GCC_128)
#  define NO_EC_NISTP_64_GCC_128
# endif
# if defined(OPENSSL_NO_GMP) && !defined(NO_GMP)
#  define NO_GMP
# endif
# if defined(OPENSSL_NO_GOST) && !defined(NO_GOST)
#  define NO_GOST
# endif
# if defined(OPENSSL_NO_JPAKE) && !defined(NO_JPAKE)
#  define NO_JPAKE
# endif
# if defined(OPENSSL_NO_LIBUNBOUND) && !defined(NO_LIBUNBOUND)
#  define NO_LIBUNBOUND
# endif
# if defined(OPENSSL_NO_MDC2) && !defined(NO_MDC2)
#  define NO_MDC2
# endif
# if defined(OPENSSL_NO_RSAX) && !defined(NO_RSAX)
#  define NO_RSAX
# endif
# if defined(OPENSSL_NO_SRP) && !defined(NO_SRP)
#  define NO_SRP
# endif
# if defined(OPENSSL_NO_SSL_TRACE) && !defined(NO_SSL_TRACE)
#  define NO_SSL_TRACE
# endif
# if defined(OPENSSL_NO_SSL2) && !defined(NO_SSL2)
#  define NO_SSL2
# endif
# if defined(OPENSSL_NO_STORE) && !defined(NO_STORE)
#  define NO_STORE
# endif
# if defined(OPENSSL_NO_UNIT_TEST) && !defined(NO_UNIT_TEST)
#  define NO_UNIT_TEST
# endif
# if defined(OPENSSL_NO_WEAK_SSL_CIPHERS) && !defined(NO_WEAK_SSL_CIPHERS)
#  define NO_WEAK_SSL_CIPHERS
# endif
#endif

#define OPENSSL_CPUID_OBJ

/* crypto/opensslconf.h.in */

#ifdef OPENSSL_DOING_MAKEDEPEND

/* Include any symbols here that have to be explicitly set to enable a feature
 * that should be visible to makedepend.
 *
 * [Our "make depend" doesn't actually look at this, we use actual build settings
 * instead; we want to make it easy to remove subdirectories with disabled algorithms.]
 */

#ifndef OPENSSL_FIPS
#define OPENSSL_FIPS
#endif

#endif

/* Generate 80386 code? */
#undef I386_ONLY

#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */
#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
#define ENGINESDIR "/opt/alt/openssl/lib64/openssl/engines"
#define OPENSSLDIR "/opt/alt/openssl/etc/pki/tls"
#endif
#endif

#define SYSTEM_CIPHERS_FILE "/opt/alt/openssl/etc/crypto-policies/back-ends/openssl.config"

#undef OPENSSL_UNISTD
#define OPENSSL_UNISTD <unistd.h>

#undef OPENSSL_EXPORT_VAR_AS_FUNCTION

#if defined(HEADER_IDEA_H) && !defined(IDEA_INT)
#define IDEA_INT unsigned int
#endif

#if defined(HEADER_MD2_H) && !defined(MD2_INT)
#define MD2_INT unsigned int
#endif

#if defined(HEADER_RC2_H) && !defined(RC2_INT)
/* I need to put in a mod for the alpha - eay */
#define RC2_INT unsigned int
#endif

#if defined(HEADER_RC4_H)
#if !defined(RC4_INT)
/* using int types make the structure larger but make the code faster
 * on most boxes I have tested - up to %20 faster. */
/*
 * I don't know what does "most" mean, but declaring "int" is a must on:
 * - Intel P6 because partial register stalls are very expensive;
 * - elder Alpha because it lacks byte load/store instructions;
 */
#define RC4_INT unsigned int
#endif
#if !defined(RC4_CHUNK)
/*
 * This enables code handling data aligned at natural CPU word
 * boundary. See crypto/rc4/rc4_enc.c for further details.
 */
#define RC4_CHUNK unsigned long
#endif
#endif

#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG)
/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
 * %20 speed up (longs are 8 bytes, int's are 4). */
#ifndef DES_LONG
#define DES_LONG unsigned int
#endif
#endif

#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H)
#define CONFIG_HEADER_BN_H
#undef BN_LLONG

/* Should we define BN_DIV2W here? */

/* Only one for the following should be defined */
#define SIXTY_FOUR_BIT_LONG
#undef SIXTY_FOUR_BIT
#undef THIRTY_TWO_BIT
#endif

#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
#define CONFIG_HEADER_RC4_LOCL_H
/* if this is defined data[i] is used instead of *data, this is a %20
 * speedup on x86 */
#undef RC4_INDEX
#endif

#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
#define CONFIG_HEADER_BF_LOCL_H
#undef BF_PTR
#endif /* HEADER_BF_LOCL_H */

#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
#define CONFIG_HEADER_DES_LOCL_H
#ifndef DES_DEFAULT_OPTIONS
/* the following is tweaked from a config script, that is why it is a
 * protected undef/define */
#ifndef DES_PTR
#undef DES_PTR
#endif

/* This helps C compiler generate the correct code for multiple functional
 * units.  It reduces register dependancies at the expense of 2 more
 * registers */
#ifndef DES_RISC1
#undef DES_RISC1
#endif

#ifndef DES_RISC2
#undef DES_RISC2
#endif

#if defined(DES_RISC1) && defined(DES_RISC2)
#error YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
#endif

/* Unroll the inner loop, this sometimes helps, sometimes hinders.
 * Very mucy CPU dependant */
#ifndef DES_UNROLL
#define DES_UNROLL
#endif

/* These default values were supplied by
 * Peter Gutman <pgut001@cs.auckland.ac.nz>
 * They are only used if nothing else has been defined */
#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
/* Special defines which change the way the code is built depending on the
   CPU and OS.  For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
   even newer MIPS CPU's, but at the moment one size fits all for
   optimization options.  Older Sparc's work better with only UNROLL, but
   there's no way to tell at compile time what it is you're running on */
 
#if defined( __sun ) || defined ( sun )		/* Newer Sparc's */
#  define DES_PTR
#  define DES_RISC1
#  define DES_UNROLL
#elif defined( __ultrix )	/* Older MIPS */
#  define DES_PTR
#  define DES_RISC2
#  define DES_UNROLL
#elif defined( __osf1__ )	/* Alpha */
#  define DES_PTR
#  define DES_RISC2
#elif defined ( _AIX )		/* RS6000 */
  /* Unknown */
#elif defined( __hpux )		/* HP-PA */
  /* Unknown */
#elif defined( __aux )		/* 68K */
  /* Unknown */
#elif defined( __dgux )		/* 88K (but P6 in latest boxes) */
#  define DES_UNROLL
#elif defined( __sgi )		/* Newer MIPS */
#  define DES_PTR
#  define DES_RISC2
#  define DES_UNROLL
#elif defined(i386) || defined(__i386__)	/* x86 boxes, should be gcc */
#  define DES_PTR
#  define DES_RISC1
#  define DES_UNROLL
#endif /* Systems-specific speed defines */
#endif

#endif /* DES_DEFAULT_OPTIONS */
#endif /* HEADER_DES_LOCL_H */
#ifdef  __cplusplus
}
#endif
openssl/opensslconf.h000064400000003055151733316620010743 0ustar00/* This file is here to prevent a file conflict on multiarch systems.  A
 * conflict will frequently occur because arch-specific build-time
 * configuration options are stored (and used, so they can't just be stripped
 * out) in opensslconf.h.  The original opensslconf.h has been renamed.
 * DO NOT INCLUDE THE NEW FILE DIRECTLY -- ALWAYS INCLUDE THIS ONE INSTEAD. */

#ifdef openssl_opensslconf_multilib_redirection_h
#error "Do not define openssl_opensslconf_multilib_redirection_h!"
#endif
#define openssl_opensslconf_multilib_redirection_h

#if defined(__i386__)
#include "opensslconf-i386.h"
#elif defined(__ia64__)
#include "opensslconf-ia64.h"
#elif defined(__mips64) && defined(__MIPSEL__)
#include "opensslconf-mips64el.h"
#elif defined(__mips64)
#include "opensslconf-mips64.h"
#elif defined(__mips) && defined(__MIPSEL__)
#include "opensslconf-mipsel.h"
#elif defined(__mips)
#include "opensslconf-mips.h"
#elif defined(__powerpc64__)
#include <endian.h>
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#include "opensslconf-ppc64.h"
#else
#include "opensslconf-ppc64le.h"
#endif
#elif defined(__powerpc__)
#include "opensslconf-ppc.h"
#elif defined(__s390x__)
#include "opensslconf-s390x.h"
#elif defined(__s390__)
#include "opensslconf-s390.h"
#elif defined(__sparc__) && defined(__arch64__)
#include "opensslconf-sparc64.h"
#elif defined(__sparc__)
#include "opensslconf-sparc.h"
#elif defined(__x86_64__)
#include "opensslconf-x86_64.h"
#else
#error "This openssl-devel package does not work your architecture?"
#endif

#undef openssl_opensslconf_multilib_redirection_h
openssl/bn.h000064400000125450151733316620007015 0ustar00/* crypto/bn/bn.h */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */
/* ====================================================================
 * Copyright (c) 1998-2018 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */
/* ====================================================================
 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
 *
 * Portions of the attached software ("Contribution") are developed by
 * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
 *
 * The Contribution is licensed pursuant to the Eric Young open source
 * license provided above.
 *
 * The binary polynomial arithmetic software is originally written by
 * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
 *
 */

#ifndef HEADER_BN_H
# define HEADER_BN_H

# include <limits.h>
# include <openssl/e_os2.h>
# ifndef OPENSSL_NO_FP_API
#  include <stdio.h>            /* FILE */
# endif
# include <openssl/ossl_typ.h>
# include <openssl/crypto.h>

#ifdef  __cplusplus
extern "C" {
#endif

/*
 * These preprocessor symbols control various aspects of the bignum headers
 * and library code. They're not defined by any "normal" configuration, as
 * they are intended for development and testing purposes. NB: defining all
 * three can be useful for debugging application code as well as openssl
 * itself. BN_DEBUG - turn on various debugging alterations to the bignum
 * code BN_DEBUG_RAND - uses random poisoning of unused words to trip up
 * mismanagement of bignum internals. You must also define BN_DEBUG.
 */
/* #define BN_DEBUG */
/* #define BN_DEBUG_RAND */

# ifndef OPENSSL_SMALL_FOOTPRINT
#  define BN_MUL_COMBA
#  define BN_SQR_COMBA
#  define BN_RECURSION
# endif

/*
 * This next option uses the C libraries (2 word)/(1 word) function. If it is
 * not defined, I use my C version (which is slower). The reason for this
 * flag is that when the particular C compiler library routine is used, and
 * the library is linked with a different compiler, the library is missing.
 * This mostly happens when the library is built with gcc and then linked
 * using normal cc.  This would be a common occurrence because gcc normally
 * produces code that is 2 times faster than system compilers for the big
 * number stuff. For machines with only one compiler (or shared libraries),
 * this should be on.  Again this in only really a problem on machines using
 * "long long's", are 32bit, and are not using my assembler code.
 */
# if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || \
    defined(OPENSSL_SYS_WIN32) || defined(linux)
#  ifndef BN_DIV2W
#   define BN_DIV2W
#  endif
# endif

/*
 * assuming long is 64bit - this is the DEC Alpha unsigned long long is only
 * 64 bits :-(, don't define BN_LLONG for the DEC Alpha
 */
# ifdef SIXTY_FOUR_BIT_LONG
#  define BN_ULLONG       unsigned long long
#  define BN_ULONG        unsigned long
#  define BN_LONG         long
#  define BN_BITS         128
#  define BN_BYTES        8
#  define BN_BITS2        64
#  define BN_BITS4        32
#  define BN_MASK         (0xffffffffffffffffffffffffffffffffLL)
#  define BN_MASK2        (0xffffffffffffffffL)
#  define BN_MASK2l       (0xffffffffL)
#  define BN_MASK2h       (0xffffffff00000000L)
#  define BN_MASK2h1      (0xffffffff80000000L)
#  define BN_TBIT         (0x8000000000000000L)
#  define BN_DEC_CONV     (10000000000000000000UL)
#  define BN_DEC_FMT1     "%lu"
#  define BN_DEC_FMT2     "%019lu"
#  define BN_DEC_NUM      19
#  define BN_HEX_FMT1     "%lX"
#  define BN_HEX_FMT2     "%016lX"
# endif

/*
 * This is where the long long data type is 64 bits, but long is 32. For
 * machines where there are 64bit registers, this is the mode to use. IRIX,
 * on R4000 and above should use this mode, along with the relevant assembler
 * code :-).  Do NOT define BN_LLONG.
 */
# ifdef SIXTY_FOUR_BIT
#  undef BN_LLONG
#  undef BN_ULLONG
#  define BN_ULONG        unsigned long long
#  define BN_LONG         long long
#  define BN_BITS         128
#  define BN_BYTES        8
#  define BN_BITS2        64
#  define BN_BITS4        32
#  define BN_MASK2        (0xffffffffffffffffLL)
#  define BN_MASK2l       (0xffffffffL)
#  define BN_MASK2h       (0xffffffff00000000LL)
#  define BN_MASK2h1      (0xffffffff80000000LL)
#  define BN_TBIT         (0x8000000000000000LL)
#  define BN_DEC_CONV     (10000000000000000000ULL)
#  define BN_DEC_FMT1     "%llu"
#  define BN_DEC_FMT2     "%019llu"
#  define BN_DEC_NUM      19
#  define BN_HEX_FMT1     "%llX"
#  define BN_HEX_FMT2     "%016llX"
# endif

# ifdef THIRTY_TWO_BIT
#  ifdef BN_LLONG
#   if defined(_WIN32) && !defined(__GNUC__)
#    define BN_ULLONG     unsigned __int64
#    define BN_MASK       (0xffffffffffffffffI64)
#   else
#    define BN_ULLONG     unsigned long long
#    define BN_MASK       (0xffffffffffffffffLL)
#   endif
#  endif
#  define BN_ULONG        unsigned int
#  define BN_LONG         int
#  define BN_BITS         64
#  define BN_BYTES        4
#  define BN_BITS2        32
#  define BN_BITS4        16
#  define BN_MASK2        (0xffffffffL)
#  define BN_MASK2l       (0xffff)
#  define BN_MASK2h1      (0xffff8000L)
#  define BN_MASK2h       (0xffff0000L)
#  define BN_TBIT         (0x80000000L)
#  define BN_DEC_CONV     (1000000000L)
#  define BN_DEC_FMT1     "%u"
#  define BN_DEC_FMT2     "%09u"
#  define BN_DEC_NUM      9
#  define BN_HEX_FMT1     "%X"
#  define BN_HEX_FMT2     "%08X"
# endif

# define BN_DEFAULT_BITS 1280

# define BN_FLG_MALLOCED         0x01
# define BN_FLG_STATIC_DATA      0x02

/*
 * avoid leaking exponent information through timing,
 * BN_mod_exp_mont() will call BN_mod_exp_mont_consttime,
 * BN_div() will call BN_div_no_branch,
 * BN_mod_inverse() will call BN_mod_inverse_no_branch.
 */
# define BN_FLG_CONSTTIME        0x04

# ifdef OPENSSL_NO_DEPRECATED
/* deprecated name for the flag */
#  define BN_FLG_EXP_CONSTTIME BN_FLG_CONSTTIME
/*
 * avoid leaking exponent information through timings
 * (BN_mod_exp_mont() will call BN_mod_exp_mont_consttime)
 */
# endif

# ifndef OPENSSL_NO_DEPRECATED
#  define BN_FLG_FREE             0x8000
                                       /* used for debuging */
# endif
# define BN_set_flags(b,n)       ((b)->flags|=(n))
# define BN_get_flags(b,n)       ((b)->flags&(n))

/*
 * get a clone of a BIGNUM with changed flags, for *temporary* use only (the
 * two BIGNUMs cannot not be used in parallel!)
 */
# define BN_with_flags(dest,b,n)  ((dest)->d=(b)->d, \
                                  (dest)->top=(b)->top, \
                                  (dest)->dmax=(b)->dmax, \
                                  (dest)->neg=(b)->neg, \
                                  (dest)->flags=(((dest)->flags & BN_FLG_MALLOCED) \
                                                 |  ((b)->flags & ~BN_FLG_MALLOCED) \
                                                 |  BN_FLG_STATIC_DATA \
                                                 |  (n)))

/* Already declared in ossl_typ.h */
# if 0
typedef struct bignum_st BIGNUM;
/* Used for temp variables (declaration hidden in bn_lcl.h) */
typedef struct bignum_ctx BN_CTX;
typedef struct bn_blinding_st BN_BLINDING;
typedef struct bn_mont_ctx_st BN_MONT_CTX;
typedef struct bn_recp_ctx_st BN_RECP_CTX;
typedef struct bn_gencb_st BN_GENCB;
# endif

struct bignum_st {
    BN_ULONG *d;                /* Pointer to an array of 'BN_BITS2' bit
                                 * chunks. */
    int top;                    /* Index of last used d +1. */
    /* The next are internal book keeping for bn_expand. */
    int dmax;                   /* Size of the d array. */
    int neg;                    /* one if the number is negative */
    int flags;
};

/* Used for montgomery multiplication */
struct bn_mont_ctx_st {
    int ri;                     /* number of bits in R */
    BIGNUM RR;                  /* used to convert to montgomery form */
    BIGNUM N;                   /* The modulus */
    BIGNUM Ni;                  /* R*(1/R mod N) - N*Ni = 1 (Ni is only
                                 * stored for bignum algorithm) */
    BN_ULONG n0[2];             /* least significant word(s) of Ni; (type
                                 * changed with 0.9.9, was "BN_ULONG n0;"
                                 * before) */
    int flags;
};

/*
 * Used for reciprocal division/mod functions It cannot be shared between
 * threads
 */
struct bn_recp_ctx_st {
    BIGNUM N;                   /* the divisor */
    BIGNUM Nr;                  /* the reciprocal */
    int num_bits;
    int shift;
    int flags;
};

/* Used for slow "generation" functions. */
struct bn_gencb_st {
    unsigned int ver;           /* To handle binary (in)compatibility */
    void *arg;                  /* callback-specific data */
    union {
        /* if(ver==1) - handles old style callbacks */
        void (*cb_1) (int, int, void *);
        /* if(ver==2) - new callback style */
        int (*cb_2) (int, int, BN_GENCB *);
    } cb;
};
/* Wrapper function to make using BN_GENCB easier,  */
int BN_GENCB_call(BN_GENCB *cb, int a, int b);
/* Macro to populate a BN_GENCB structure with an "old"-style callback */
# define BN_GENCB_set_old(gencb, callback, cb_arg) { \
                BN_GENCB *tmp_gencb = (gencb); \
                tmp_gencb->ver = 1; \
                tmp_gencb->arg = (cb_arg); \
                tmp_gencb->cb.cb_1 = (callback); }
/* Macro to populate a BN_GENCB structure with a "new"-style callback */
# define BN_GENCB_set(gencb, callback, cb_arg) { \
                BN_GENCB *tmp_gencb = (gencb); \
                tmp_gencb->ver = 2; \
                tmp_gencb->arg = (cb_arg); \
                tmp_gencb->cb.cb_2 = (callback); }

# define BN_prime_checks 0      /* default: select number of iterations based
                                 * on the size of the number */

/*
 * BN_prime_checks_for_size() returns the number of Miller-Rabin iterations
 * that will be done for checking that a random number is probably prime. The
 * error rate for accepting a composite number as prime depends on the size of
 * the prime |b|. The error rates used are for calculating an RSA key with 2 primes,
 * and so the level is what you would expect for a key of double the size of the
 * prime.
 *
 * This table is generated using the algorithm of FIPS PUB 186-4
 * Digital Signature Standard (DSS), section F.1, page 117.
 * (https://dx.doi.org/10.6028/NIST.FIPS.186-4)
 *
 * The following magma script was used to generate the output:
 * securitybits:=125;
 * k:=1024;
 * for t:=1 to 65 do
 *   for M:=3 to Floor(2*Sqrt(k-1)-1) do
 *     S:=0;
 *     // Sum over m
 *     for m:=3 to M do
 *       s:=0;
 *       // Sum over j
 *       for j:=2 to m do
 *         s+:=(RealField(32)!2)^-(j+(k-1)/j);
 *       end for;
 *       S+:=2^(m-(m-1)*t)*s;
 *     end for;
 *     A:=2^(k-2-M*t);
 *     B:=8*(Pi(RealField(32))^2-6)/3*2^(k-2)*S;
 *     pkt:=2.00743*Log(2)*k*2^-k*(A+B);
 *     seclevel:=Floor(-Log(2,pkt));
 *     if seclevel ge securitybits then
 *       printf "k: %5o, security: %o bits  (t: %o, M: %o)\n",k,seclevel,t,M;
 *       break;
 *     end if;
 *   end for;
 *   if seclevel ge securitybits then break; end if;
 * end for;
 *
 * It can be run online at:
 * http://magma.maths.usyd.edu.au/calc
 *
 * And will output:
 * k:  1024, security: 129 bits  (t: 6, M: 23)
 *
 * k is the number of bits of the prime, securitybits is the level we want to
 * reach.
 *
 * prime length | RSA key size | # MR tests | security level
 * -------------+--------------|------------+---------------
 *  (b) >= 6394 |     >= 12788 |          3 |        256 bit
 *  (b) >= 3747 |     >=  7494 |          3 |        192 bit
 *  (b) >= 1345 |     >=  2690 |          4 |        128 bit
 *  (b) >= 1080 |     >=  2160 |          5 |        128 bit
 *  (b) >=  852 |     >=  1704 |          5 |        112 bit
 *  (b) >=  476 |     >=   952 |          5 |         80 bit
 *  (b) >=  400 |     >=   800 |          6 |         80 bit
 *  (b) >=  347 |     >=   694 |          7 |         80 bit
 *  (b) >=  308 |     >=   616 |          8 |         80 bit
 *  (b) >=   55 |     >=   110 |         27 |         64 bit
 *  (b) >=    6 |     >=    12 |         34 |         64 bit
 */

# define BN_prime_checks_for_size(b) ((b) >= 3747 ?  3 : \
                                (b) >=  1345 ?  4 : \
                                (b) >=  476 ?  5 : \
                                (b) >=  400 ?  6 : \
                                (b) >=  347 ?  7 : \
                                (b) >=  308 ?  8 : \
                                (b) >=  55  ? 27 : \
                                /* b >= 6 */ 34)

# define BN_num_bytes(a) ((BN_num_bits(a)+7)/8)

/* Note that BN_abs_is_word didn't work reliably for w == 0 until 0.9.8 */
# define BN_abs_is_word(a,w) ((((a)->top == 1) && ((a)->d[0] == (BN_ULONG)(w))) || \
                                (((w) == 0) && ((a)->top == 0)))
# define BN_is_zero(a)       ((a)->top == 0)
# define BN_is_one(a)        (BN_abs_is_word((a),1) && !(a)->neg)
# define BN_is_word(a,w)     (BN_abs_is_word((a),(w)) && (!(w) || !(a)->neg))
# define BN_is_odd(a)        (((a)->top > 0) && ((a)->d[0] & 1))

# define BN_one(a)       (BN_set_word((a),1))
# define BN_zero_ex(a) \
        do { \
                BIGNUM *_tmp_bn = (a); \
                _tmp_bn->top = 0; \
                _tmp_bn->neg = 0; \
        } while(0)
# ifdef OPENSSL_NO_DEPRECATED
#  define BN_zero(a)      BN_zero_ex(a)
# else
#  define BN_zero(a)      (BN_set_word((a),0))
# endif

const BIGNUM *BN_value_one(void);
char *BN_options(void);
BN_CTX *BN_CTX_new(void);
# ifndef OPENSSL_NO_DEPRECATED
void BN_CTX_init(BN_CTX *c);
# endif
void BN_CTX_free(BN_CTX *c);
void BN_CTX_start(BN_CTX *ctx);
BIGNUM *BN_CTX_get(BN_CTX *ctx);
void BN_CTX_end(BN_CTX *ctx);
int BN_rand(BIGNUM *rnd, int bits, int top, int bottom);
int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom);
int BN_rand_range(BIGNUM *rnd, const BIGNUM *range);
int BN_pseudo_rand_range(BIGNUM *rnd, const BIGNUM *range);
int BN_num_bits(const BIGNUM *a);
int BN_num_bits_word(BN_ULONG);
BIGNUM *BN_new(void);
void BN_init(BIGNUM *);
void BN_clear_free(BIGNUM *a);
BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b);
void BN_swap(BIGNUM *a, BIGNUM *b);
BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret);
int BN_bn2bin(const BIGNUM *a, unsigned char *to);
BIGNUM *BN_mpi2bn(const unsigned char *s, int len, BIGNUM *ret);
int BN_bn2mpi(const BIGNUM *a, unsigned char *to);
int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx);
/** BN_set_negative sets sign of a BIGNUM
 * \param  b  pointer to the BIGNUM object
 * \param  n  0 if the BIGNUM b should be positive and a value != 0 otherwise
 */
void BN_set_negative(BIGNUM *b, int n);
/** BN_is_negative returns 1 if the BIGNUM is negative
 * \param  a  pointer to the BIGNUM object
 * \return 1 if a < 0 and 0 otherwise
 */
# define BN_is_negative(a) ((a)->neg != 0)

int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
           BN_CTX *ctx);
# define BN_mod(rem,m,d,ctx) BN_div(NULL,(rem),(m),(d),(ctx))
int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx);
int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
               BN_CTX *ctx);
int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
                     const BIGNUM *m);
int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
               BN_CTX *ctx);
int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
                     const BIGNUM *m);
int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
               BN_CTX *ctx);
int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m);
int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m,
                  BN_CTX *ctx);
int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m);

BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w);
BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w);
int BN_mul_word(BIGNUM *a, BN_ULONG w);
int BN_add_word(BIGNUM *a, BN_ULONG w);
int BN_sub_word(BIGNUM *a, BN_ULONG w);
int BN_set_word(BIGNUM *a, BN_ULONG w);
BN_ULONG BN_get_word(const BIGNUM *a);

int BN_cmp(const BIGNUM *a, const BIGNUM *b);
void BN_free(BIGNUM *a);
int BN_is_bit_set(const BIGNUM *a, int n);
int BN_lshift(BIGNUM *r, const BIGNUM *a, int n);
int BN_lshift1(BIGNUM *r, const BIGNUM *a);
int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);

int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
               const BIGNUM *m, BN_CTX *ctx);
int BN_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
                    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
                              const BIGNUM *m, BN_CTX *ctx,
                              BN_MONT_CTX *in_mont);
int BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p,
                         const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
int BN_mod_exp2_mont(BIGNUM *r, const BIGNUM *a1, const BIGNUM *p1,
                     const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m,
                     BN_CTX *ctx, BN_MONT_CTX *m_ctx);
int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
                      const BIGNUM *m, BN_CTX *ctx);

int BN_mask_bits(BIGNUM *a, int n);
# ifndef OPENSSL_NO_FP_API
int BN_print_fp(FILE *fp, const BIGNUM *a);
# endif
# ifdef HEADER_BIO_H
int BN_print(BIO *fp, const BIGNUM *a);
# else
int BN_print(void *fp, const BIGNUM *a);
# endif
int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx);
int BN_rshift(BIGNUM *r, const BIGNUM *a, int n);
int BN_rshift1(BIGNUM *r, const BIGNUM *a);
void BN_clear(BIGNUM *a);
BIGNUM *BN_dup(const BIGNUM *a);
int BN_ucmp(const BIGNUM *a, const BIGNUM *b);
int BN_set_bit(BIGNUM *a, int n);
int BN_clear_bit(BIGNUM *a, int n);
char *BN_bn2hex(const BIGNUM *a);
char *BN_bn2dec(const BIGNUM *a);
int BN_hex2bn(BIGNUM **a, const char *str);
int BN_dec2bn(BIGNUM **a, const char *str);
int BN_asc2bn(BIGNUM **a, const char *str);
int BN_gcd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); /* returns
                                                                  * -2 for
                                                                  * error */
BIGNUM *BN_mod_inverse(BIGNUM *ret,
                       const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx);
BIGNUM *BN_mod_sqrt(BIGNUM *ret,
                    const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx);

void BN_consttime_swap(BN_ULONG swap, BIGNUM *a, BIGNUM *b, int nwords);

/* Deprecated versions */
# ifndef OPENSSL_NO_DEPRECATED
BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe,
                          const BIGNUM *add, const BIGNUM *rem,
                          void (*callback) (int, int, void *), void *cb_arg);
int BN_is_prime(const BIGNUM *p, int nchecks,
                void (*callback) (int, int, void *),
                BN_CTX *ctx, void *cb_arg);
int BN_is_prime_fasttest(const BIGNUM *p, int nchecks,
                         void (*callback) (int, int, void *), BN_CTX *ctx,
                         void *cb_arg, int do_trial_division);
# endif                         /* !defined(OPENSSL_NO_DEPRECATED) */

/* Newer versions */
int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add,
                         const BIGNUM *rem, BN_GENCB *cb);
int BN_is_prime_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, BN_GENCB *cb);
int BN_is_prime_fasttest_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx,
                            int do_trial_division, BN_GENCB *cb);

int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx);

int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
                            const BIGNUM *Xp, const BIGNUM *Xp1,
                            const BIGNUM *Xp2, const BIGNUM *e, BN_CTX *ctx,
                            BN_GENCB *cb);
int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, BIGNUM *Xp1,
                              BIGNUM *Xp2, const BIGNUM *Xp, const BIGNUM *e,
                              BN_CTX *ctx, BN_GENCB *cb);

BN_MONT_CTX *BN_MONT_CTX_new(void);
void BN_MONT_CTX_init(BN_MONT_CTX *ctx);
int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
                          BN_MONT_CTX *mont, BN_CTX *ctx);
# define BN_to_montgomery(r,a,mont,ctx)  BN_mod_mul_montgomery(\
        (r),(a),&((mont)->RR),(mont),(ctx))
int BN_from_montgomery(BIGNUM *r, const BIGNUM *a,
                       BN_MONT_CTX *mont, BN_CTX *ctx);
void BN_MONT_CTX_free(BN_MONT_CTX *mont);
int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx);
BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from);
BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock,
                                    const BIGNUM *mod, BN_CTX *ctx);

/* BN_BLINDING flags */
# define BN_BLINDING_NO_UPDATE   0x00000001
# define BN_BLINDING_NO_RECREATE 0x00000002

BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod);
void BN_BLINDING_free(BN_BLINDING *b);
int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx);
int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *);
int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b,
                          BN_CTX *);
# ifndef OPENSSL_NO_DEPRECATED
unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *);
void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long);
# endif
CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *);
unsigned long BN_BLINDING_get_flags(const BN_BLINDING *);
void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long);
BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
                                      const BIGNUM *e, BIGNUM *m, BN_CTX *ctx,
                                      int (*bn_mod_exp) (BIGNUM *r,
                                                         const BIGNUM *a,
                                                         const BIGNUM *p,
                                                         const BIGNUM *m,
                                                         BN_CTX *ctx,
                                                         BN_MONT_CTX *m_ctx),
                                      BN_MONT_CTX *m_ctx);

# ifndef OPENSSL_NO_DEPRECATED
void BN_set_params(int mul, int high, int low, int mont);
int BN_get_params(int which);   /* 0, mul, 1 high, 2 low, 3 mont */
# endif

void BN_RECP_CTX_init(BN_RECP_CTX *recp);
BN_RECP_CTX *BN_RECP_CTX_new(void);
void BN_RECP_CTX_free(BN_RECP_CTX *recp);
int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *rdiv, BN_CTX *ctx);
int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y,
                          BN_RECP_CTX *recp, BN_CTX *ctx);
int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
                    const BIGNUM *m, BN_CTX *ctx);
int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
                BN_RECP_CTX *recp, BN_CTX *ctx);

# ifndef OPENSSL_NO_EC2M

/*
 * Functions for arithmetic over binary polynomials represented by BIGNUMs.
 * The BIGNUM::neg property of BIGNUMs representing binary polynomials is
 * ignored. Note that input arguments are not const so that their bit arrays
 * can be expanded to the appropriate size if needed.
 */

/*
 * r = a + b
 */
int BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
#  define BN_GF2m_sub(r, a, b) BN_GF2m_add(r, a, b)
/*
 * r=a mod p
 */
int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p);
/* r = (a * b) mod p */
int BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
                    const BIGNUM *p, BN_CTX *ctx);
/* r = (a * a) mod p */
int BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
/* r = (1 / b) mod p */
int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx);
/* r = (a / b) mod p */
int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
                    const BIGNUM *p, BN_CTX *ctx);
/* r = (a ^ b) mod p */
int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
                    const BIGNUM *p, BN_CTX *ctx);
/* r = sqrt(a) mod p */
int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
                     BN_CTX *ctx);
/* r^2 + r = a mod p */
int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
                           BN_CTX *ctx);
#  define BN_GF2m_cmp(a, b) BN_ucmp((a), (b))
/*-
 * Some functions allow for representation of the irreducible polynomials
 * as an unsigned int[], say p.  The irreducible f(t) is then of the form:
 *     t^p[0] + t^p[1] + ... + t^p[k]
 * where m = p[0] > p[1] > ... > p[k] = 0.
 */
/* r = a mod p */
int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[]);
/* r = (a * b) mod p */
int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
                        const int p[], BN_CTX *ctx);
/* r = (a * a) mod p */
int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[],
                        BN_CTX *ctx);
/* r = (1 / b) mod p */
int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *b, const int p[],
                        BN_CTX *ctx);
/* r = (a / b) mod p */
int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
                        const int p[], BN_CTX *ctx);
/* r = (a ^ b) mod p */
int BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
                        const int p[], BN_CTX *ctx);
/* r = sqrt(a) mod p */
int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a,
                         const int p[], BN_CTX *ctx);
/* r^2 + r = a mod p */
int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a,
                               const int p[], BN_CTX *ctx);
int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max);
int BN_GF2m_arr2poly(const int p[], BIGNUM *a);

# endif

/*
 * faster mod functions for the 'NIST primes' 0 <= a < p^2
 */
int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);

const BIGNUM *BN_get0_nist_prime_192(void);
const BIGNUM *BN_get0_nist_prime_224(void);
const BIGNUM *BN_get0_nist_prime_256(void);
const BIGNUM *BN_get0_nist_prime_384(void);
const BIGNUM *BN_get0_nist_prime_521(void);

/* library internal functions */

# define bn_expand(a,bits) \
    ( \
        bits > (INT_MAX - BN_BITS2 + 1) ? \
            NULL \
        : \
            (((bits+BN_BITS2-1)/BN_BITS2) <= (a)->dmax) ? \
                (a) \
            : \
                bn_expand2((a),(bits+BN_BITS2-1)/BN_BITS2) \
    )

# define bn_wexpand(a,words) (((words) <= (a)->dmax)?(a):bn_expand2((a),(words)))
BIGNUM *bn_expand2(BIGNUM *a, int words);
# ifndef OPENSSL_NO_DEPRECATED
BIGNUM *bn_dup_expand(const BIGNUM *a, int words); /* unused */
# endif

/*-
 * Bignum consistency macros
 * There is one "API" macro, bn_fix_top(), for stripping leading zeroes from
 * bignum data after direct manipulations on the data. There is also an
 * "internal" macro, bn_check_top(), for verifying that there are no leading
 * zeroes. Unfortunately, some auditing is required due to the fact that
 * bn_fix_top() has become an overabused duct-tape because bignum data is
 * occasionally passed around in an inconsistent state. So the following
 * changes have been made to sort this out;
 * - bn_fix_top()s implementation has been moved to bn_correct_top()
 * - if BN_DEBUG isn't defined, bn_fix_top() maps to bn_correct_top(), and
 *   bn_check_top() is as before.
 * - if BN_DEBUG *is* defined;
 *   - bn_check_top() tries to pollute unused words even if the bignum 'top' is
 *     consistent. (ed: only if BN_DEBUG_RAND is defined)
 *   - bn_fix_top() maps to bn_check_top() rather than "fixing" anything.
 * The idea is to have debug builds flag up inconsistent bignums when they
 * occur. If that occurs in a bn_fix_top(), we examine the code in question; if
 * the use of bn_fix_top() was appropriate (ie. it follows directly after code
 * that manipulates the bignum) it is converted to bn_correct_top(), and if it
 * was not appropriate, we convert it permanently to bn_check_top() and track
 * down the cause of the bug. Eventually, no internal code should be using the
 * bn_fix_top() macro. External applications and libraries should try this with
 * their own code too, both in terms of building against the openssl headers
 * with BN_DEBUG defined *and* linking with a version of OpenSSL built with it
 * defined. This not only improves external code, it provides more test
 * coverage for openssl's own code.
 */

# ifdef BN_DEBUG

/* We only need assert() when debugging */
#  include <assert.h>

/*
 * The new BN_FLG_FIXED_TOP flag marks vectors that were not treated with
 * bn_correct_top, in other words such vectors are permitted to have zeros
 * in most significant limbs. Such vectors are used internally to achieve
 * execution time invariance for critical operations with private keys.
 * It's BN_DEBUG-only flag, because user application is not supposed to
 * observe it anyway. Moreover, optimizing compiler would actually remove
 * all operations manipulating the bit in question in non-BN_DEBUG build.
 */
#  define BN_FLG_FIXED_TOP 0x10000
#  ifdef BN_DEBUG_RAND
/* To avoid "make update" cvs wars due to BN_DEBUG, use some tricks */
#   ifndef RAND_pseudo_bytes
int RAND_pseudo_bytes(unsigned char *buf, int num);
#    define BN_DEBUG_TRIX
#   endif
#   define bn_pollute(a) \
        do { \
                const BIGNUM *_bnum1 = (a); \
                if(_bnum1->top < _bnum1->dmax) { \
                        unsigned char _tmp_char; \
                        /* We cast away const without the compiler knowing, any \
                         * *genuinely* constant variables that aren't mutable \
                         * wouldn't be constructed with top!=dmax. */ \
                        BN_ULONG *_not_const; \
                        memcpy(&_not_const, &_bnum1->d, sizeof(BN_ULONG*)); \
                        /* Debug only - safe to ignore error return */ \
                        RAND_pseudo_bytes(&_tmp_char, 1); \
                        memset((unsigned char *)(_not_const + _bnum1->top), _tmp_char, \
                                (_bnum1->dmax - _bnum1->top) * sizeof(BN_ULONG)); \
                } \
        } while(0)
#   ifdef BN_DEBUG_TRIX
#    undef RAND_pseudo_bytes
#   endif
#  else
#   define bn_pollute(a)
#  endif
#  define bn_check_top(a) \
        do { \
                const BIGNUM *_bnum2 = (a); \
                if (_bnum2 != NULL) { \
                        int _top = _bnum2->top; \
                        assert((_top == 0) || \
                               (_bnum2->flags & BN_FLG_FIXED_TOP) || \
                               (_bnum2->d[_top - 1] != 0)); \
                        bn_pollute(_bnum2); \
                } \
        } while(0)

#  define bn_fix_top(a)           bn_check_top(a)

#  define bn_check_size(bn, bits) bn_wcheck_size(bn, ((bits+BN_BITS2-1))/BN_BITS2)
#  define bn_wcheck_size(bn, words) \
        do { \
                const BIGNUM *_bnum2 = (bn); \
                assert((words) <= (_bnum2)->dmax && (words) >= (_bnum2)->top); \
                /* avoid unused variable warning with NDEBUG */ \
                (void)(_bnum2); \
        } while(0)

# else                          /* !BN_DEBUG */

#  define BN_FLG_FIXED_TOP 0
#  define bn_pollute(a)
#  define bn_check_top(a)
#  define bn_fix_top(a)           bn_correct_top(a)
#  define bn_check_size(bn, bits)
#  define bn_wcheck_size(bn, words)

# endif

# define bn_correct_top(a) \
        { \
        BN_ULONG *ftl; \
        int tmp_top = (a)->top; \
        if (tmp_top > 0) \
                { \
                for (ftl= &((a)->d[tmp_top-1]); tmp_top > 0; tmp_top--) \
                        if (*(ftl--)) break; \
                (a)->top = tmp_top; \
                } \
        if ((a)->top == 0) \
            (a)->neg = 0; \
        bn_pollute(a); \
        }

BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
                          BN_ULONG w);
BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
void bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num);
BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d);
BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
                      int num);
BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
                      int num);

/* Primes from RFC 2409 */
BIGNUM *get_rfc2409_prime_768(BIGNUM *bn);
BIGNUM *get_rfc2409_prime_1024(BIGNUM *bn);

/* Primes from RFC 3526 */
BIGNUM *get_rfc3526_prime_1536(BIGNUM *bn);
BIGNUM *get_rfc3526_prime_2048(BIGNUM *bn);
BIGNUM *get_rfc3526_prime_3072(BIGNUM *bn);
BIGNUM *get_rfc3526_prime_4096(BIGNUM *bn);
BIGNUM *get_rfc3526_prime_6144(BIGNUM *bn);
BIGNUM *get_rfc3526_prime_8192(BIGNUM *bn);

int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom);

/* BEGIN ERROR CODES */
/*
 * The following lines are auto generated by the script mkerr.pl. Any changes
 * made after this point may be overwritten when the script is next run.
 */
void ERR_load_BN_strings(void);

/* Error codes for the BN functions. */

/* Function codes. */
# define BN_F_BNRAND                                      127
# define BN_F_BN_BLINDING_CONVERT_EX                      100
# define BN_F_BN_BLINDING_CREATE_PARAM                    128
# define BN_F_BN_BLINDING_INVERT_EX                       101
# define BN_F_BN_BLINDING_NEW                             102
# define BN_F_BN_BLINDING_UPDATE                          103
# define BN_F_BN_BN2DEC                                   104
# define BN_F_BN_BN2HEX                                   105
# define BN_F_BN_CTX_GET                                  116
# define BN_F_BN_CTX_NEW                                  106
# define BN_F_BN_CTX_START                                129
# define BN_F_BN_DIV                                      107
# define BN_F_BN_DIV_NO_BRANCH                            138
# define BN_F_BN_DIV_RECP                                 130
# define BN_F_BN_EXP                                      123
# define BN_F_BN_EXPAND2                                  108
# define BN_F_BN_EXPAND_INTERNAL                          120
# define BN_F_BN_GF2M_MOD                                 131
# define BN_F_BN_GF2M_MOD_EXP                             132
# define BN_F_BN_GF2M_MOD_MUL                             133
# define BN_F_BN_GF2M_MOD_SOLVE_QUAD                      134
# define BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR                  135
# define BN_F_BN_GF2M_MOD_SQR                             136
# define BN_F_BN_GF2M_MOD_SQRT                            137
# define BN_F_BN_LSHIFT                                   145
# define BN_F_BN_MOD_EXP2_MONT                            118
# define BN_F_BN_MOD_EXP_MONT                             109
# define BN_F_BN_MOD_EXP_MONT_CONSTTIME                   124
# define BN_F_BN_MOD_EXP_MONT_WORD                        117
# define BN_F_BN_MOD_EXP_RECP                             125
# define BN_F_BN_MOD_EXP_SIMPLE                           126
# define BN_F_BN_MOD_INVERSE                              110
# define BN_F_BN_MOD_INVERSE_NO_BRANCH                    139
# define BN_F_BN_MOD_LSHIFT_QUICK                         119
# define BN_F_BN_MOD_MUL_RECIPROCAL                       111
# define BN_F_BN_MOD_SQRT                                 121
# define BN_F_BN_MPI2BN                                   112
# define BN_F_BN_NEW                                      113
# define BN_F_BN_RAND                                     114
# define BN_F_BN_RAND_RANGE                               122
# define BN_F_BN_RSHIFT                                   146
# define BN_F_BN_USUB                                     115

/* Reason codes. */
# define BN_R_ARG2_LT_ARG3                                100
# define BN_R_BAD_RECIPROCAL                              101
# define BN_R_BIGNUM_TOO_LONG                             114
# define BN_R_BITS_TOO_SMALL                              118
# define BN_R_CALLED_WITH_EVEN_MODULUS                    102
# define BN_R_DIV_BY_ZERO                                 103
# define BN_R_ENCODING_ERROR                              104
# define BN_R_EXPAND_ON_STATIC_BIGNUM_DATA                105
# define BN_R_INPUT_NOT_REDUCED                           110
# define BN_R_INVALID_LENGTH                              106
# define BN_R_INVALID_RANGE                               115
# define BN_R_INVALID_SHIFT                               119
# define BN_R_NOT_A_SQUARE                                111
# define BN_R_NOT_INITIALIZED                             107
# define BN_R_NO_INVERSE                                  108
# define BN_R_NO_SOLUTION                                 116
# define BN_R_P_IS_NOT_PRIME                              112
# define BN_R_TOO_MANY_ITERATIONS                         113
# define BN_R_TOO_MANY_TEMPORARY_VARIABLES                109

#ifdef  __cplusplus
}
#endif
#endif
openssl/ui.h000064400000044377151733316630007044 0ustar00/* crypto/ui/ui.h */
/*
 * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project
 * 2001.
 */
/* ====================================================================
 * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#ifndef HEADER_UI_H
# define HEADER_UI_H

# ifndef OPENSSL_NO_DEPRECATED
#  include <openssl/crypto.h>
# endif
# include <openssl/safestack.h>
# include <openssl/ossl_typ.h>

#ifdef  __cplusplus
extern "C" {
#endif

/* Declared already in ossl_typ.h */
/* typedef struct ui_st UI; */
/* typedef struct ui_method_st UI_METHOD; */

/*
 * All the following functions return -1 or NULL on error and in some cases
 * (UI_process()) -2 if interrupted or in some other way cancelled. When
 * everything is fine, they return 0, a positive value or a non-NULL pointer,
 * all depending on their purpose.
 */

/* Creators and destructor.   */
UI *UI_new(void);
UI *UI_new_method(const UI_METHOD *method);
void UI_free(UI *ui);

/*-
   The following functions are used to add strings to be printed and prompt
   strings to prompt for data.  The names are UI_{add,dup}_<function>_string
   and UI_{add,dup}_input_boolean.

   UI_{add,dup}_<function>_string have the following meanings:
        add     add a text or prompt string.  The pointers given to these
                functions are used verbatim, no copying is done.
        dup     make a copy of the text or prompt string, then add the copy
                to the collection of strings in the user interface.
        <function>
                The function is a name for the functionality that the given
                string shall be used for.  It can be one of:
                        input   use the string as data prompt.
                        verify  use the string as verification prompt.  This
                                is used to verify a previous input.
                        info    use the string for informational output.
                        error   use the string for error output.
   Honestly, there's currently no difference between info and error for the
   moment.

   UI_{add,dup}_input_boolean have the same semantics for "add" and "dup",
   and are typically used when one wants to prompt for a yes/no response.

   All of the functions in this group take a UI and a prompt string.
   The string input and verify addition functions also take a flag argument,
   a buffer for the result to end up with, a minimum input size and a maximum
   input size (the result buffer MUST be large enough to be able to contain
   the maximum number of characters).  Additionally, the verify addition
   functions takes another buffer to compare the result against.
   The boolean input functions take an action description string (which should
   be safe to ignore if the expected user action is obvious, for example with
   a dialog box with an OK button and a Cancel button), a string of acceptable
   characters to mean OK and to mean Cancel.  The two last strings are checked
   to make sure they don't have common characters.  Additionally, the same
   flag argument as for the string input is taken, as well as a result buffer.
   The result buffer is required to be at least one byte long.  Depending on
   the answer, the first character from the OK or the Cancel character strings
   will be stored in the first byte of the result buffer.  No NUL will be
   added, so the result is *not* a string.

   On success, the all return an index of the added information.  That index
   is usefull when retrieving results with UI_get0_result(). */
int UI_add_input_string(UI *ui, const char *prompt, int flags,
                        char *result_buf, int minsize, int maxsize);
int UI_dup_input_string(UI *ui, const char *prompt, int flags,
                        char *result_buf, int minsize, int maxsize);
int UI_add_verify_string(UI *ui, const char *prompt, int flags,
                         char *result_buf, int minsize, int maxsize,
                         const char *test_buf);
int UI_dup_verify_string(UI *ui, const char *prompt, int flags,
                         char *result_buf, int minsize, int maxsize,
                         const char *test_buf);
int UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc,
                         const char *ok_chars, const char *cancel_chars,
                         int flags, char *result_buf);
int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc,
                         const char *ok_chars, const char *cancel_chars,
                         int flags, char *result_buf);
int UI_add_info_string(UI *ui, const char *text);
int UI_dup_info_string(UI *ui, const char *text);
int UI_add_error_string(UI *ui, const char *text);
int UI_dup_error_string(UI *ui, const char *text);

/* These are the possible flags.  They can be or'ed together. */
/* Use to have echoing of input */
# define UI_INPUT_FLAG_ECHO              0x01
/*
 * Use a default password.  Where that password is found is completely up to
 * the application, it might for example be in the user data set with
 * UI_add_user_data().  It is not recommended to have more than one input in
 * each UI being marked with this flag, or the application might get
 * confused.
 */
# define UI_INPUT_FLAG_DEFAULT_PWD       0x02

/*-
 * The user of these routines may want to define flags of their own.  The core
 * UI won't look at those, but will pass them on to the method routines.  They
 * must use higher bits so they don't get confused with the UI bits above.
 * UI_INPUT_FLAG_USER_BASE tells which is the lowest bit to use.  A good
 * example of use is this:
 *
 *    #define MY_UI_FLAG1       (0x01 << UI_INPUT_FLAG_USER_BASE)
 *
*/
# define UI_INPUT_FLAG_USER_BASE 16

/*-
 * The following function helps construct a prompt.  object_desc is a
 * textual short description of the object, for example "pass phrase",
 * and object_name is the name of the object (might be a card name or
 * a file name.
 * The returned string shall always be allocated on the heap with
 * OPENSSL_malloc(), and need to be free'd with OPENSSL_free().
 *
 * If the ui_method doesn't contain a pointer to a user-defined prompt
 * constructor, a default string is built, looking like this:
 *
 *       "Enter {object_desc} for {object_name}:"
 *
 * So, if object_desc has the value "pass phrase" and object_name has
 * the value "foo.key", the resulting string is:
 *
 *       "Enter pass phrase for foo.key:"
*/
char *UI_construct_prompt(UI *ui_method,
                          const char *object_desc, const char *object_name);

/*
 * The following function is used to store a pointer to user-specific data.
 * Any previous such pointer will be returned and replaced.
 *
 * For callback purposes, this function makes a lot more sense than using
 * ex_data, since the latter requires that different parts of OpenSSL or
 * applications share the same ex_data index.
 *
 * Note that the UI_OpenSSL() method completely ignores the user data. Other
 * methods may not, however.
 */
void *UI_add_user_data(UI *ui, void *user_data);
/* We need a user data retrieving function as well.  */
void *UI_get0_user_data(UI *ui);

/* Return the result associated with a prompt given with the index i. */
const char *UI_get0_result(UI *ui, int i);

/* When all strings have been added, process the whole thing. */
int UI_process(UI *ui);

/*
 * Give a user interface parametrised control commands.  This can be used to
 * send down an integer, a data pointer or a function pointer, as well as be
 * used to get information from a UI.
 */
int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f) (void));

/* The commands */
/*
 * Use UI_CONTROL_PRINT_ERRORS with the value 1 to have UI_process print the
 * OpenSSL error stack before printing any info or added error messages and
 * before any prompting.
 */
# define UI_CTRL_PRINT_ERRORS            1
/*
 * Check if a UI_process() is possible to do again with the same instance of
 * a user interface.  This makes UI_ctrl() return 1 if it is redoable, and 0
 * if not.
 */
# define UI_CTRL_IS_REDOABLE             2

/* Some methods may use extra data */
# define UI_set_app_data(s,arg)         UI_set_ex_data(s,0,arg)
# define UI_get_app_data(s)             UI_get_ex_data(s,0)
int UI_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
                        CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
int UI_set_ex_data(UI *r, int idx, void *arg);
void *UI_get_ex_data(UI *r, int idx);

/* Use specific methods instead of the built-in one */
void UI_set_default_method(const UI_METHOD *meth);
const UI_METHOD *UI_get_default_method(void);
const UI_METHOD *UI_get_method(UI *ui);
const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth);

/* The method with all the built-in thingies */
UI_METHOD *UI_OpenSSL(void);

/* ---------- For method writers ---------- */
/*-
   A method contains a number of functions that implement the low level
   of the User Interface.  The functions are:

        an opener       This function starts a session, maybe by opening
                        a channel to a tty, or by opening a window.
        a writer        This function is called to write a given string,
                        maybe to the tty, maybe as a field label in a
                        window.
        a flusher       This function is called to flush everything that
                        has been output so far.  It can be used to actually
                        display a dialog box after it has been built.
        a reader        This function is called to read a given prompt,
                        maybe from the tty, maybe from a field in a
                        window.  Note that it's called wth all string
                        structures, not only the prompt ones, so it must
                        check such things itself.
        a closer        This function closes the session, maybe by closing
                        the channel to the tty, or closing the window.

   All these functions are expected to return:

        0       on error.
        1       on success.
        -1      on out-of-band events, for example if some prompting has
                been canceled (by pressing Ctrl-C, for example).  This is
                only checked when returned by the flusher or the reader.

   The way this is used, the opener is first called, then the writer for all
   strings, then the flusher, then the reader for all strings and finally the
   closer.  Note that if you want to prompt from a terminal or other command
   line interface, the best is to have the reader also write the prompts
   instead of having the writer do it.  If you want to prompt from a dialog
   box, the writer can be used to build up the contents of the box, and the
   flusher to actually display the box and run the event loop until all data
   has been given, after which the reader only grabs the given data and puts
   them back into the UI strings.

   All method functions take a UI as argument.  Additionally, the writer and
   the reader take a UI_STRING.
*/

/*
 * The UI_STRING type is the data structure that contains all the needed info
 * about a string or a prompt, including test data for a verification prompt.
 */
typedef struct ui_string_st UI_STRING;
DECLARE_STACK_OF(UI_STRING)

/*
 * The different types of strings that are currently supported. This is only
 * needed by method authors.
 */
enum UI_string_types {
    UIT_NONE = 0,
    UIT_PROMPT,                 /* Prompt for a string */
    UIT_VERIFY,                 /* Prompt for a string and verify */
    UIT_BOOLEAN,                /* Prompt for a yes/no response */
    UIT_INFO,                   /* Send info to the user */
    UIT_ERROR                   /* Send an error message to the user */
};

/* Create and manipulate methods */
UI_METHOD *UI_create_method(char *name);
void UI_destroy_method(UI_METHOD *ui_method);
int UI_method_set_opener(UI_METHOD *method, int (*opener) (UI *ui));
int UI_method_set_writer(UI_METHOD *method,
                         int (*writer) (UI *ui, UI_STRING *uis));
int UI_method_set_flusher(UI_METHOD *method, int (*flusher) (UI *ui));
int UI_method_set_reader(UI_METHOD *method,
                         int (*reader) (UI *ui, UI_STRING *uis));
int UI_method_set_closer(UI_METHOD *method, int (*closer) (UI *ui));
int UI_method_set_prompt_constructor(UI_METHOD *method,
                                     char *(*prompt_constructor) (UI *ui,
                                                                  const char
                                                                  *object_desc,
                                                                  const char
                                                                  *object_name));
int (*UI_method_get_opener(UI_METHOD *method)) (UI *);
int (*UI_method_get_writer(UI_METHOD *method)) (UI *, UI_STRING *);
int (*UI_method_get_flusher(UI_METHOD *method)) (UI *);
int (*UI_method_get_reader(UI_METHOD *method)) (UI *, UI_STRING *);
int (*UI_method_get_closer(UI_METHOD *method)) (UI *);
char *(*UI_method_get_prompt_constructor(UI_METHOD *method)) (UI *,
                                                              const char *,
                                                              const char *);

/*
 * The following functions are helpers for method writers to access relevant
 * data from a UI_STRING.
 */

/* Return type of the UI_STRING */
enum UI_string_types UI_get_string_type(UI_STRING *uis);
/* Return input flags of the UI_STRING */
int UI_get_input_flags(UI_STRING *uis);
/* Return the actual string to output (the prompt, info or error) */
const char *UI_get0_output_string(UI_STRING *uis);
/*
 * Return the optional action string to output (the boolean promtp
 * instruction)
 */
const char *UI_get0_action_string(UI_STRING *uis);
/* Return the result of a prompt */
const char *UI_get0_result_string(UI_STRING *uis);
/*
 * Return the string to test the result against.  Only useful with verifies.
 */
const char *UI_get0_test_string(UI_STRING *uis);
/* Return the required minimum size of the result */
int UI_get_result_minsize(UI_STRING *uis);
/* Return the required maximum size of the result */
int UI_get_result_maxsize(UI_STRING *uis);
/* Set the result of a UI_STRING. */
int UI_set_result(UI *ui, UI_STRING *uis, const char *result);

/* A couple of popular utility functions */
int UI_UTIL_read_pw_string(char *buf, int length, const char *prompt,
                           int verify);
int UI_UTIL_read_pw(char *buf, char *buff, int size, const char *prompt,
                    int verify);

/* BEGIN ERROR CODES */
/*
 * The following lines are auto generated by the script mkerr.pl. Any changes
 * made after this point may be overwritten when the script is next run.
 */
void ERR_load_UI_strings(void);

/* Error codes for the UI functions. */

/* Function codes. */
# define UI_F_GENERAL_ALLOCATE_BOOLEAN                    108
# define UI_F_GENERAL_ALLOCATE_PROMPT                     109
# define UI_F_GENERAL_ALLOCATE_STRING                     100
# define UI_F_UI_CTRL                                     111
# define UI_F_UI_DUP_ERROR_STRING                         101
# define UI_F_UI_DUP_INFO_STRING                          102
# define UI_F_UI_DUP_INPUT_BOOLEAN                        110
# define UI_F_UI_DUP_INPUT_STRING                         103
# define UI_F_UI_DUP_VERIFY_STRING                        106
# define UI_F_UI_GET0_RESULT                              107
# define UI_F_UI_NEW_METHOD                               104
# define UI_F_UI_SET_RESULT                               105

/* Reason codes. */
# define UI_R_COMMON_OK_AND_CANCEL_CHARACTERS             104
# define UI_R_INDEX_TOO_LARGE                             102
# define UI_R_INDEX_TOO_SMALL                             103
# define UI_R_NO_RESULT_BUFFER                            105
# define UI_R_RESULT_TOO_LARGE                            100
# define UI_R_RESULT_TOO_SMALL                            101
# define UI_R_UNKNOWN_CONTROL_COMMAND                     106

#ifdef  __cplusplus
}
#endif
#endif
openssl/conf_api.h000064400000010063151733316630010166 0ustar00/* conf_api.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#ifndef  HEADER_CONF_API_H
# define HEADER_CONF_API_H

# include <openssl/lhash.h>
# include <openssl/conf.h>

#ifdef  __cplusplus
extern "C" {
#endif

/* Up until OpenSSL 0.9.5a, this was new_section */
CONF_VALUE *_CONF_new_section(CONF *conf, const char *section);
/* Up until OpenSSL 0.9.5a, this was get_section */
CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section);
/* Up until OpenSSL 0.9.5a, this was CONF_get_section */
STACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf,
                                               const char *section);

int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value);
char *_CONF_get_string(const CONF *conf, const char *section,
                       const char *name);
long _CONF_get_number(const CONF *conf, const char *section,
                      const char *name);

int _CONF_new_data(CONF *conf);
void _CONF_free_data(CONF *conf);

#ifdef  __cplusplus
}
#endif
#endif
openssl/cms.h000064400000067741151733316630007211 0ustar00/* crypto/cms/cms.h */
/*
 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
 * project.
 */
/* ====================================================================
 * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 */

#ifndef HEADER_CMS_H
# define HEADER_CMS_H

# include <openssl/x509.h>

# ifdef OPENSSL_NO_CMS
#  error CMS is disabled.
# endif

#ifdef __cplusplus
extern "C" {
#endif

typedef struct CMS_ContentInfo_st CMS_ContentInfo;
typedef struct CMS_SignerInfo_st CMS_SignerInfo;
typedef struct CMS_CertificateChoices CMS_CertificateChoices;
typedef struct CMS_RevocationInfoChoice_st CMS_RevocationInfoChoice;
typedef struct CMS_RecipientInfo_st CMS_RecipientInfo;
typedef struct CMS_ReceiptRequest_st CMS_ReceiptRequest;
typedef struct CMS_Receipt_st CMS_Receipt;
typedef struct CMS_RecipientEncryptedKey_st CMS_RecipientEncryptedKey;
typedef struct CMS_OtherKeyAttribute_st CMS_OtherKeyAttribute;

DECLARE_STACK_OF(CMS_SignerInfo)
DECLARE_STACK_OF(GENERAL_NAMES)
DECLARE_STACK_OF(CMS_RecipientEncryptedKey)
DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo)
DECLARE_ASN1_FUNCTIONS(CMS_ReceiptRequest)
DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo)

# define CMS_SIGNERINFO_ISSUER_SERIAL    0
# define CMS_SIGNERINFO_KEYIDENTIFIER    1

# define CMS_RECIPINFO_NONE              -1
# define CMS_RECIPINFO_TRANS             0
# define CMS_RECIPINFO_AGREE             1
# define CMS_RECIPINFO_KEK               2
# define CMS_RECIPINFO_PASS              3
# define CMS_RECIPINFO_OTHER             4

/* S/MIME related flags */

# define CMS_TEXT                        0x1
# define CMS_NOCERTS                     0x2
# define CMS_NO_CONTENT_VERIFY           0x4
# define CMS_NO_ATTR_VERIFY              0x8
# define CMS_NOSIGS                      \
                        (CMS_NO_CONTENT_VERIFY|CMS_NO_ATTR_VERIFY)
# define CMS_NOINTERN                    0x10
# define CMS_NO_SIGNER_CERT_VERIFY       0x20
# define CMS_NOVERIFY                    0x20
# define CMS_DETACHED                    0x40
# define CMS_BINARY                      0x80
# define CMS_NOATTR                      0x100
# define CMS_NOSMIMECAP                  0x200
# define CMS_NOOLDMIMETYPE               0x400
# define CMS_CRLFEOL                     0x800
# define CMS_STREAM                      0x1000
# define CMS_NOCRL                       0x2000
# define CMS_PARTIAL                     0x4000
# define CMS_REUSE_DIGEST                0x8000
# define CMS_USE_KEYID                   0x10000
# define CMS_DEBUG_DECRYPT               0x20000
# define CMS_KEY_PARAM                   0x40000

const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms);

BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont);
int CMS_dataFinal(CMS_ContentInfo *cms, BIO *bio);

ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms);
int CMS_is_detached(CMS_ContentInfo *cms);
int CMS_set_detached(CMS_ContentInfo *cms, int detached);

# ifdef HEADER_PEM_H
DECLARE_PEM_rw_const(CMS, CMS_ContentInfo)
# endif
int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms);
CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms);
int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms);

BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms);
int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags);
int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in,
                             int flags);
CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont);
int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags);

int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont,
              unsigned int flags);

CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey,
                          STACK_OF(X509) *certs, BIO *data,
                          unsigned int flags);

CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
                                  X509 *signcert, EVP_PKEY *pkey,
                                  STACK_OF(X509) *certs, unsigned int flags);

int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags);
CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags);

int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
                      unsigned int flags);
CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
                                   unsigned int flags);

int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
                              const unsigned char *key, size_t keylen,
                              BIO *dcont, BIO *out, unsigned int flags);

CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
                                           const unsigned char *key,
                                           size_t keylen, unsigned int flags);

int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
                               const unsigned char *key, size_t keylen);

int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
               X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags);

int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms,
                       STACK_OF(X509) *certs,
                       X509_STORE *store, unsigned int flags);

STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms);

CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in,
                             const EVP_CIPHER *cipher, unsigned int flags);

int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert,
                BIO *dcont, BIO *out, unsigned int flags);

int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert);
int CMS_decrypt_set1_key(CMS_ContentInfo *cms,
                         unsigned char *key, size_t keylen,
                         unsigned char *id, size_t idlen);
int CMS_decrypt_set1_password(CMS_ContentInfo *cms,
                              unsigned char *pass, ossl_ssize_t passlen);

STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms);
int CMS_RecipientInfo_type(CMS_RecipientInfo *ri);
EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri);
CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher);
CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
                                           X509 *recip, unsigned int flags);
int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey);
int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert);
int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri,
                                     EVP_PKEY **pk, X509 **recip,
                                     X509_ALGOR **palg);
int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
                                          ASN1_OCTET_STRING **keyid,
                                          X509_NAME **issuer,
                                          ASN1_INTEGER **sno);

CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid,
                                          unsigned char *key, size_t keylen,
                                          unsigned char *id, size_t idlen,
                                          ASN1_GENERALIZEDTIME *date,
                                          ASN1_OBJECT *otherTypeId,
                                          ASN1_TYPE *otherType);

int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri,
                                    X509_ALGOR **palg,
                                    ASN1_OCTET_STRING **pid,
                                    ASN1_GENERALIZEDTIME **pdate,
                                    ASN1_OBJECT **potherid,
                                    ASN1_TYPE **pothertype);

int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri,
                               unsigned char *key, size_t keylen);

int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri,
                                   const unsigned char *id, size_t idlen);

int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri,
                                    unsigned char *pass,
                                    ossl_ssize_t passlen);

CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms,
                                               int iter, int wrap_nid,
                                               int pbe_nid,
                                               unsigned char *pass,
                                               ossl_ssize_t passlen,
                                               const EVP_CIPHER *kekciph);

int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri);
int CMS_RecipientInfo_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri);

int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
                   unsigned int flags);
CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags);

int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid);
const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms);

CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms);
int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert);
int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert);
STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms);

CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms);
int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl);
int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl);
STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms);

int CMS_SignedData_init(CMS_ContentInfo *cms);
CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
                                X509 *signer, EVP_PKEY *pk, const EVP_MD *md,
                                unsigned int flags);
EVP_PKEY_CTX *CMS_SignerInfo_get0_pkey_ctx(CMS_SignerInfo *si);
EVP_MD_CTX *CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si);
STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms);

void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer);
int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si,
                                  ASN1_OCTET_STRING **keyid,
                                  X509_NAME **issuer, ASN1_INTEGER **sno);
int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert);
int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
                           unsigned int flags);
void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk,
                              X509 **signer, X509_ALGOR **pdig,
                              X509_ALGOR **psig);
ASN1_OCTET_STRING *CMS_SignerInfo_get0_signature(CMS_SignerInfo *si);
int CMS_SignerInfo_sign(CMS_SignerInfo *si);
int CMS_SignerInfo_verify(CMS_SignerInfo *si);
int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain);

int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs);
int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs,
                            int algnid, int keysize);
int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap);

int CMS_signed_get_attr_count(const CMS_SignerInfo *si);
int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
                               int lastpos);
int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj,
                               int lastpos);
X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc);
X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc);
int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr);
int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si,
                                const ASN1_OBJECT *obj, int type,
                                const void *bytes, int len);
int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si,
                                int nid, int type,
                                const void *bytes, int len);
int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si,
                                const char *attrname, int type,
                                const void *bytes, int len);
void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
                                  int lastpos, int type);

int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si);
int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
                                 int lastpos);
int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj,
                                 int lastpos);
X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc);
X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc);
int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr);
int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si,
                                  const ASN1_OBJECT *obj, int type,
                                  const void *bytes, int len);
int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si,
                                  int nid, int type,
                                  const void *bytes, int len);
int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si,
                                  const char *attrname, int type,
                                  const void *bytes, int len);
void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
                                    int lastpos, int type);

# ifdef HEADER_X509V3_H

int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr);
CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
                                               int allorfirst,
                                               STACK_OF(GENERAL_NAMES)
                                               *receiptList, STACK_OF(GENERAL_NAMES)
                                               *receiptsTo);
int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr);
void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr,
                                    ASN1_STRING **pcid,
                                    int *pallorfirst,
                                    STACK_OF(GENERAL_NAMES) **plist,
                                    STACK_OF(GENERAL_NAMES) **prto);
# endif
int CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri,
                                    X509_ALGOR **palg,
                                    ASN1_OCTET_STRING **pukm);
STACK_OF(CMS_RecipientEncryptedKey)
*CMS_RecipientInfo_kari_get0_reks(CMS_RecipientInfo *ri);

int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri,
                                        X509_ALGOR **pubalg,
                                        ASN1_BIT_STRING **pubkey,
                                        ASN1_OCTET_STRING **keyid,
                                        X509_NAME **issuer,
                                        ASN1_INTEGER **sno);

int CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo *ri, X509 *cert);

int CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek,
                                      ASN1_OCTET_STRING **keyid,
                                      ASN1_GENERALIZEDTIME **tm,
                                      CMS_OtherKeyAttribute **other,
                                      X509_NAME **issuer, ASN1_INTEGER **sno);
int CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek,
                                       X509 *cert);
int CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk);
EVP_CIPHER_CTX *CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo *ri);
int CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms,
                                   CMS_RecipientInfo *ri,
                                   CMS_RecipientEncryptedKey *rek);

int CMS_SharedInfo_encode(unsigned char **pder, X509_ALGOR *kekalg,
                          ASN1_OCTET_STRING *ukm, int keylen);

/* BEGIN ERROR CODES */
/*
 * The following lines are auto generated by the script mkerr.pl. Any changes
 * made after this point may be overwritten when the script is next run.
 */
void ERR_load_CMS_strings(void);

/* Error codes for the CMS functions. */

/* Function codes. */
# define CMS_F_CHECK_CONTENT                              99
# define CMS_F_CMS_ADD0_CERT                              164
# define CMS_F_CMS_ADD0_RECIPIENT_KEY                     100
# define CMS_F_CMS_ADD0_RECIPIENT_PASSWORD                165
# define CMS_F_CMS_ADD1_RECEIPTREQUEST                    158
# define CMS_F_CMS_ADD1_RECIPIENT_CERT                    101
# define CMS_F_CMS_ADD1_SIGNER                            102
# define CMS_F_CMS_ADD1_SIGNINGTIME                       103
# define CMS_F_CMS_COMPRESS                               104
# define CMS_F_CMS_COMPRESSEDDATA_CREATE                  105
# define CMS_F_CMS_COMPRESSEDDATA_INIT_BIO                106
# define CMS_F_CMS_COPY_CONTENT                           107
# define CMS_F_CMS_COPY_MESSAGEDIGEST                     108
# define CMS_F_CMS_DATA                                   109
# define CMS_F_CMS_DATAFINAL                              110
# define CMS_F_CMS_DATAINIT                               111
# define CMS_F_CMS_DECRYPT                                112
# define CMS_F_CMS_DECRYPT_SET1_KEY                       113
# define CMS_F_CMS_DECRYPT_SET1_PASSWORD                  166
# define CMS_F_CMS_DECRYPT_SET1_PKEY                      114
# define CMS_F_CMS_DIGESTALGORITHM_FIND_CTX               115
# define CMS_F_CMS_DIGESTALGORITHM_INIT_BIO               116
# define CMS_F_CMS_DIGESTEDDATA_DO_FINAL                  117
# define CMS_F_CMS_DIGEST_VERIFY                          118
# define CMS_F_CMS_ENCODE_RECEIPT                         161
# define CMS_F_CMS_ENCRYPT                                119
# define CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO              120
# define CMS_F_CMS_ENCRYPTEDDATA_DECRYPT                  121
# define CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT                  122
# define CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY                 123
# define CMS_F_CMS_ENVELOPEDDATA_CREATE                   124
# define CMS_F_CMS_ENVELOPEDDATA_INIT_BIO                 125
# define CMS_F_CMS_ENVELOPED_DATA_INIT                    126
# define CMS_F_CMS_ENV_ASN1_CTRL                          171
# define CMS_F_CMS_FINAL                                  127
# define CMS_F_CMS_GET0_CERTIFICATE_CHOICES               128
# define CMS_F_CMS_GET0_CONTENT                           129
# define CMS_F_CMS_GET0_ECONTENT_TYPE                     130
# define CMS_F_CMS_GET0_ENVELOPED                         131
# define CMS_F_CMS_GET0_REVOCATION_CHOICES                132
# define CMS_F_CMS_GET0_SIGNED                            133
# define CMS_F_CMS_MSGSIGDIGEST_ADD1                      162
# define CMS_F_CMS_RECEIPTREQUEST_CREATE0                 159
# define CMS_F_CMS_RECEIPT_VERIFY                         160
# define CMS_F_CMS_RECIPIENTINFO_DECRYPT                  134
# define CMS_F_CMS_RECIPIENTINFO_ENCRYPT                  169
# define CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT             178
# define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG            175
# define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID        173
# define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_REKS           172
# define CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP         174
# define CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT            135
# define CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT            136
# define CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID            137
# define CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP             138
# define CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP            139
# define CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT             140
# define CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT             141
# define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS           142
# define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID      143
# define CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT               167
# define CMS_F_CMS_RECIPIENTINFO_SET0_KEY                 144
# define CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD            168
# define CMS_F_CMS_RECIPIENTINFO_SET0_PKEY                145
# define CMS_F_CMS_SD_ASN1_CTRL                           170
# define CMS_F_CMS_SET1_IAS                               176
# define CMS_F_CMS_SET1_KEYID                             177
# define CMS_F_CMS_SET1_SIGNERIDENTIFIER                  146
# define CMS_F_CMS_SET_DETACHED                           147
# define CMS_F_CMS_SIGN                                   148
# define CMS_F_CMS_SIGNED_DATA_INIT                       149
# define CMS_F_CMS_SIGNERINFO_CONTENT_SIGN                150
# define CMS_F_CMS_SIGNERINFO_SIGN                        151
# define CMS_F_CMS_SIGNERINFO_VERIFY                      152
# define CMS_F_CMS_SIGNERINFO_VERIFY_CERT                 153
# define CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT              154
# define CMS_F_CMS_SIGN_RECEIPT                           163
# define CMS_F_CMS_STREAM                                 155
# define CMS_F_CMS_UNCOMPRESS                             156
# define CMS_F_CMS_VERIFY                                 157

/* Reason codes. */
# define CMS_R_ADD_SIGNER_ERROR                           99
# define CMS_R_CERTIFICATE_ALREADY_PRESENT                175
# define CMS_R_CERTIFICATE_HAS_NO_KEYID                   160
# define CMS_R_CERTIFICATE_VERIFY_ERROR                   100
# define CMS_R_CIPHER_INITIALISATION_ERROR                101
# define CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR      102
# define CMS_R_CMS_DATAFINAL_ERROR                        103
# define CMS_R_CMS_LIB                                    104
# define CMS_R_CONTENTIDENTIFIER_MISMATCH                 170
# define CMS_R_CONTENT_NOT_FOUND                          105
# define CMS_R_CONTENT_TYPE_MISMATCH                      171
# define CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA           106
# define CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA            107
# define CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA               108
# define CMS_R_CONTENT_VERIFY_ERROR                       109
# define CMS_R_CTRL_ERROR                                 110
# define CMS_R_CTRL_FAILURE                               111
# define CMS_R_DECRYPT_ERROR                              112
# define CMS_R_DIGEST_ERROR                               161
# define CMS_R_ERROR_GETTING_PUBLIC_KEY                   113
# define CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE      114
# define CMS_R_ERROR_SETTING_KEY                          115
# define CMS_R_ERROR_SETTING_RECIPIENTINFO                116
# define CMS_R_INVALID_ENCRYPTED_KEY_LENGTH               117
# define CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER           176
# define CMS_R_INVALID_KEY_LENGTH                         118
# define CMS_R_MD_BIO_INIT_ERROR                          119
# define CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH       120
# define CMS_R_MESSAGEDIGEST_WRONG_LENGTH                 121
# define CMS_R_MSGSIGDIGEST_ERROR                         172
# define CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE          162
# define CMS_R_MSGSIGDIGEST_WRONG_LENGTH                  163
# define CMS_R_NEED_ONE_SIGNER                            164
# define CMS_R_NOT_A_SIGNED_RECEIPT                       165
# define CMS_R_NOT_ENCRYPTED_DATA                         122
# define CMS_R_NOT_KEK                                    123
# define CMS_R_NOT_KEY_AGREEMENT                          181
# define CMS_R_NOT_KEY_TRANSPORT                          124
# define CMS_R_NOT_PWRI                                   177
# define CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE            125
# define CMS_R_NO_CIPHER                                  126
# define CMS_R_NO_CONTENT                                 127
# define CMS_R_NO_CONTENT_TYPE                            173
# define CMS_R_NO_DEFAULT_DIGEST                          128
# define CMS_R_NO_DIGEST_SET                              129
# define CMS_R_NO_KEY                                     130
# define CMS_R_NO_KEY_OR_CERT                             174
# define CMS_R_NO_MATCHING_DIGEST                         131
# define CMS_R_NO_MATCHING_RECIPIENT                      132
# define CMS_R_NO_MATCHING_SIGNATURE                      166
# define CMS_R_NO_MSGSIGDIGEST                            167
# define CMS_R_NO_PASSWORD                                178
# define CMS_R_NO_PRIVATE_KEY                             133
# define CMS_R_NO_PUBLIC_KEY                              134
# define CMS_R_NO_RECEIPT_REQUEST                         168
# define CMS_R_NO_SIGNERS                                 135
# define CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE     136
# define CMS_R_RECEIPT_DECODE_ERROR                       169
# define CMS_R_RECIPIENT_ERROR                            137
# define CMS_R_SIGNER_CERTIFICATE_NOT_FOUND               138
# define CMS_R_SIGNFINAL_ERROR                            139
# define CMS_R_SMIME_TEXT_ERROR                           140
# define CMS_R_STORE_INIT_ERROR                           141
# define CMS_R_TYPE_NOT_COMPRESSED_DATA                   142
# define CMS_R_TYPE_NOT_DATA                              143
# define CMS_R_TYPE_NOT_DIGESTED_DATA                     144
# define CMS_R_TYPE_NOT_ENCRYPTED_DATA                    145
# define CMS_R_TYPE_NOT_ENVELOPED_DATA                    146
# define CMS_R_UNABLE_TO_FINALIZE_CONTEXT                 147
# define CMS_R_UNKNOWN_CIPHER                             148
# define CMS_R_UNKNOWN_DIGEST_ALGORIHM                    149
# define CMS_R_UNKNOWN_ID                                 150
# define CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM          151
# define CMS_R_UNSUPPORTED_CONTENT_TYPE                   152
# define CMS_R_UNSUPPORTED_KEK_ALGORITHM                  153
# define CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM       179
# define CMS_R_UNSUPPORTED_RECIPIENT_TYPE                 154
# define CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE              155
# define CMS_R_UNSUPPORTED_TYPE                           156
# define CMS_R_UNWRAP_ERROR                               157
# define CMS_R_UNWRAP_FAILURE                             180
# define CMS_R_VERIFICATION_FAILURE                       158
# define CMS_R_WRAP_ERROR                                 159

#ifdef  __cplusplus
}
#endif
#endif
openssl/pem2.h000064400000005456151733316630007265 0ustar00/* ====================================================================
 * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

/*
 * This header only exists to break a circular dependency between pem and err
 * Ben 30 Jan 1999.
 */

#ifdef __cplusplus
extern "C" {
#endif

#ifndef HEADER_PEM_H
void ERR_load_PEM_strings(void);
#endif

#ifdef __cplusplus
}
#endif
openssl/asn1.h000064400000173641151733316630007266 0ustar00/* crypto/asn1/asn1.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#ifndef HEADER_ASN1_H
# define HEADER_ASN1_H

# include <time.h>
# include <openssl/e_os2.h>
# ifndef OPENSSL_NO_BIO
#  include <openssl/bio.h>
# endif
# include <openssl/stack.h>
# include <openssl/safestack.h>

# include <openssl/symhacks.h>

# include <openssl/ossl_typ.h>
# ifndef OPENSSL_NO_DEPRECATED
#  include <openssl/bn.h>
# endif

# ifdef OPENSSL_BUILD_SHLIBCRYPTO
#  undef OPENSSL_EXTERN
#  define OPENSSL_EXTERN OPENSSL_EXPORT
# endif

#ifdef  __cplusplus
extern "C" {
#endif

# define V_ASN1_UNIVERSAL                0x00
# define V_ASN1_APPLICATION              0x40
# define V_ASN1_CONTEXT_SPECIFIC         0x80
# define V_ASN1_PRIVATE                  0xc0

# define V_ASN1_CONSTRUCTED              0x20
# define V_ASN1_PRIMITIVE_TAG            0x1f
# define V_ASN1_PRIMATIVE_TAG            0x1f

# define V_ASN1_APP_CHOOSE               -2/* let the recipient choose */
# define V_ASN1_OTHER                    -3/* used in ASN1_TYPE */
# define V_ASN1_ANY                      -4/* used in ASN1 template code */

# define V_ASN1_NEG                      0x100/* negative flag */

# define V_ASN1_UNDEF                    -1
# define V_ASN1_EOC                      0
# define V_ASN1_BOOLEAN                  1 /**/
# define V_ASN1_INTEGER                  2
# define V_ASN1_NEG_INTEGER              (2 | V_ASN1_NEG)
# define V_ASN1_BIT_STRING               3
# define V_ASN1_OCTET_STRING             4
# define V_ASN1_NULL                     5
# define V_ASN1_OBJECT                   6
# define V_ASN1_OBJECT_DESCRIPTOR        7
# define V_ASN1_EXTERNAL                 8
# define V_ASN1_REAL                     9
# define V_ASN1_ENUMERATED               10
# define V_ASN1_NEG_ENUMERATED           (10 | V_ASN1_NEG)
# define V_ASN1_UTF8STRING               12
# define V_ASN1_SEQUENCE                 16
# define V_ASN1_SET                      17
# define V_ASN1_NUMERICSTRING            18 /**/
# define V_ASN1_PRINTABLESTRING          19
# define V_ASN1_T61STRING                20
# define V_ASN1_TELETEXSTRING            20/* alias */
# define V_ASN1_VIDEOTEXSTRING           21 /**/
# define V_ASN1_IA5STRING                22
# define V_ASN1_UTCTIME                  23
# define V_ASN1_GENERALIZEDTIME          24 /**/
# define V_ASN1_GRAPHICSTRING            25 /**/
# define V_ASN1_ISO64STRING              26 /**/
# define V_ASN1_VISIBLESTRING            26/* alias */
# define V_ASN1_GENERALSTRING            27 /**/
# define V_ASN1_UNIVERSALSTRING          28 /**/
# define V_ASN1_BMPSTRING                30
/* For use with d2i_ASN1_type_bytes() */
# define B_ASN1_NUMERICSTRING    0x0001
# define B_ASN1_PRINTABLESTRING  0x0002
# define B_ASN1_T61STRING        0x0004
# define B_ASN1_TELETEXSTRING    0x0004
# define B_ASN1_VIDEOTEXSTRING   0x0008
# define B_ASN1_IA5STRING        0x0010
# define B_ASN1_GRAPHICSTRING    0x0020
# define B_ASN1_ISO64STRING      0x0040
# define B_ASN1_VISIBLESTRING    0x0040
# define B_ASN1_GENERALSTRING    0x0080
# define B_ASN1_UNIVERSALSTRING  0x0100
# define B_ASN1_OCTET_STRING     0x0200
# define B_ASN1_BIT_STRING       0x0400
# define B_ASN1_BMPSTRING        0x0800
# define B_ASN1_UNKNOWN          0x1000
# define B_ASN1_UTF8STRING       0x2000
# define B_ASN1_UTCTIME          0x4000
# define B_ASN1_GENERALIZEDTIME  0x8000
# define B_ASN1_SEQUENCE         0x10000
/* For use with ASN1_mbstring_copy() */
# define MBSTRING_FLAG           0x1000
# define MBSTRING_UTF8           (MBSTRING_FLAG)
# define MBSTRING_ASC            (MBSTRING_FLAG|1)
# define MBSTRING_BMP            (MBSTRING_FLAG|2)
# define MBSTRING_UNIV           (MBSTRING_FLAG|4)
# define SMIME_OLDMIME           0x400
# define SMIME_CRLFEOL           0x800
# define SMIME_STREAM            0x1000
    struct X509_algor_st;
DECLARE_STACK_OF(X509_ALGOR)

# define DECLARE_ASN1_SET_OF(type)/* filled in by mkstack.pl */
# define IMPLEMENT_ASN1_SET_OF(type)/* nothing, no longer needed */

/*
 * We MUST make sure that, except for constness, asn1_ctx_st and
 * asn1_const_ctx are exactly the same.  Fortunately, as soon as the old ASN1
 * parsing macros are gone, we can throw this away as well...
 */
typedef struct asn1_ctx_st {
    unsigned char *p;           /* work char pointer */
    int eos;                    /* end of sequence read for indefinite
                                 * encoding */
    int error;                  /* error code to use when returning an error */
    int inf;                    /* constructed if 0x20, indefinite is 0x21 */
    int tag;                    /* tag from last 'get object' */
    int xclass;                 /* class from last 'get object' */
    long slen;                  /* length of last 'get object' */
    unsigned char *max;         /* largest value of p allowed */
    unsigned char *q;           /* temporary variable */
    unsigned char **pp;         /* variable */
    int line;                   /* used in error processing */
} ASN1_CTX;

typedef struct asn1_const_ctx_st {
    const unsigned char *p;     /* work char pointer */
    int eos;                    /* end of sequence read for indefinite
                                 * encoding */
    int error;                  /* error code to use when returning an error */
    int inf;                    /* constructed if 0x20, indefinite is 0x21 */
    int tag;                    /* tag from last 'get object' */
    int xclass;                 /* class from last 'get object' */
    long slen;                  /* length of last 'get object' */
    const unsigned char *max;   /* largest value of p allowed */
    const unsigned char *q;     /* temporary variable */
    const unsigned char **pp;   /* variable */
    int line;                   /* used in error processing */
} ASN1_const_CTX;

/*
 * These are used internally in the ASN1_OBJECT to keep track of whether the
 * names and data need to be free()ed
 */
# define ASN1_OBJECT_FLAG_DYNAMIC         0x01/* internal use */
# define ASN1_OBJECT_FLAG_CRITICAL        0x02/* critical x509v3 object id */
# define ASN1_OBJECT_FLAG_DYNAMIC_STRINGS 0x04/* internal use */
# define ASN1_OBJECT_FLAG_DYNAMIC_DATA    0x08/* internal use */
struct asn1_object_st {
    const char *sn, *ln;
    int nid;
    int length;
    const unsigned char *data;  /* data remains const after init */
    int flags;                  /* Should we free this one */
};

# define ASN1_STRING_FLAG_BITS_LEFT 0x08/* Set if 0x07 has bits left value */
/*
 * This indicates that the ASN1_STRING is not a real value but just a place
 * holder for the location where indefinite length constructed data should be
 * inserted in the memory buffer
 */
# define ASN1_STRING_FLAG_NDEF 0x010

/*
 * This flag is used by the CMS code to indicate that a string is not
 * complete and is a place holder for content when it had all been accessed.
 * The flag will be reset when content has been written to it.
 */

# define ASN1_STRING_FLAG_CONT 0x020
/*
 * This flag is used by ASN1 code to indicate an ASN1_STRING is an MSTRING
 * type.
 */
# define ASN1_STRING_FLAG_MSTRING 0x040
/* This is the base type that holds just about everything :-) */
struct asn1_string_st {
    int length;
    int type;
    unsigned char *data;
    /*
     * The value of the following field depends on the type being held.  It
     * is mostly being used for BIT_STRING so if the input data has a
     * non-zero 'unused bits' value, it will be handled correctly
     */
    long flags;
};

/*
 * ASN1_ENCODING structure: this is used to save the received encoding of an
 * ASN1 type. This is useful to get round problems with invalid encodings
 * which can break signatures.
 */

typedef struct ASN1_ENCODING_st {
    unsigned char *enc;         /* DER encoding */
    long len;                   /* Length of encoding */
    int modified;               /* set to 1 if 'enc' is invalid */
} ASN1_ENCODING;

/* Used with ASN1 LONG type: if a long is set to this it is omitted */
# define ASN1_LONG_UNDEF 0x7fffffffL

# define STABLE_FLAGS_MALLOC     0x01
# define STABLE_NO_MASK          0x02
# define DIRSTRING_TYPE  \
 (B_ASN1_PRINTABLESTRING|B_ASN1_T61STRING|B_ASN1_BMPSTRING|B_ASN1_UTF8STRING)
# define PKCS9STRING_TYPE (DIRSTRING_TYPE|B_ASN1_IA5STRING)

typedef struct asn1_string_table_st {
    int nid;
    long minsize;
    long maxsize;
    unsigned long mask;
    unsigned long flags;
} ASN1_STRING_TABLE;

DECLARE_STACK_OF(ASN1_STRING_TABLE)

/* size limits: this stuff is taken straight from RFC2459 */

# define ub_name                         32768
# define ub_common_name                  64
# define ub_locality_name                128
# define ub_state_name                   128
# define ub_organization_name            64
# define ub_organization_unit_name       64
# define ub_title                        64
# define ub_email_address                128

/*
 * Declarations for template structures: for full definitions see asn1t.h
 */
typedef struct ASN1_TEMPLATE_st ASN1_TEMPLATE;
typedef struct ASN1_TLC_st ASN1_TLC;
/* This is just an opaque pointer */
typedef struct ASN1_VALUE_st ASN1_VALUE;

/* Declare ASN1 functions: the implement macro in in asn1t.h */

# define DECLARE_ASN1_FUNCTIONS(type) DECLARE_ASN1_FUNCTIONS_name(type, type)

# define DECLARE_ASN1_ALLOC_FUNCTIONS(type) \
        DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, type)

# define DECLARE_ASN1_FUNCTIONS_name(type, name) \
        DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
        DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name)

# define DECLARE_ASN1_FUNCTIONS_fname(type, itname, name) \
        DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
        DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name)

# define DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) \
        type *d2i_##name(type **a, const unsigned char **in, long len); \
        int i2d_##name(type *a, unsigned char **out); \
        DECLARE_ASN1_ITEM(itname)

# define DECLARE_ASN1_ENCODE_FUNCTIONS_const(type, name) \
        type *d2i_##name(type **a, const unsigned char **in, long len); \
        int i2d_##name(const type *a, unsigned char **out); \
        DECLARE_ASN1_ITEM(name)

# define DECLARE_ASN1_NDEF_FUNCTION(name) \
        int i2d_##name##_NDEF(name *a, unsigned char **out);

# define DECLARE_ASN1_FUNCTIONS_const(name) \
        DECLARE_ASN1_ALLOC_FUNCTIONS(name) \
        DECLARE_ASN1_ENCODE_FUNCTIONS_const(name, name)

# define DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
        type *name##_new(void); \
        void name##_free(type *a);

# define DECLARE_ASN1_PRINT_FUNCTION(stname) \
        DECLARE_ASN1_PRINT_FUNCTION_fname(stname, stname)

# define DECLARE_ASN1_PRINT_FUNCTION_fname(stname, fname) \
        int fname##_print_ctx(BIO *out, stname *x, int indent, \
                                         const ASN1_PCTX *pctx);

# define D2I_OF(type) type *(*)(type **,const unsigned char **,long)
# define I2D_OF(type) int (*)(type *,unsigned char **)
# define I2D_OF_const(type) int (*)(const type *,unsigned char **)

# define CHECKED_D2I_OF(type, d2i) \
    ((d2i_of_void*) (1 ? d2i : ((D2I_OF(type))0)))
# define CHECKED_I2D_OF(type, i2d) \
    ((i2d_of_void*) (1 ? i2d : ((I2D_OF(type))0)))
# define CHECKED_NEW_OF(type, xnew) \
    ((void *(*)(void)) (1 ? xnew : ((type *(*)(void))0)))
# define CHECKED_PTR_OF(type, p) \
    ((void*) (1 ? p : (type*)0))
# define CHECKED_PPTR_OF(type, p) \
    ((void**) (1 ? p : (type**)0))

# define TYPEDEF_D2I_OF(type) typedef type *d2i_of_##type(type **,const unsigned char **,long)
# define TYPEDEF_I2D_OF(type) typedef int i2d_of_##type(type *,unsigned char **)
# define TYPEDEF_D2I2D_OF(type) TYPEDEF_D2I_OF(type); TYPEDEF_I2D_OF(type)

TYPEDEF_D2I2D_OF(void);

/*-
 * The following macros and typedefs allow an ASN1_ITEM
 * to be embedded in a structure and referenced. Since
 * the ASN1_ITEM pointers need to be globally accessible
 * (possibly from shared libraries) they may exist in
 * different forms. On platforms that support it the
 * ASN1_ITEM structure itself will be globally exported.
 * Other platforms will export a function that returns
 * an ASN1_ITEM pointer.
 *
 * To handle both cases transparently the macros below
 * should be used instead of hard coding an ASN1_ITEM
 * pointer in a structure.
 *
 * The structure will look like this:
 *
 * typedef struct SOMETHING_st {
 *      ...
 *      ASN1_ITEM_EXP *iptr;
 *      ...
 * } SOMETHING;
 *
 * It would be initialised as e.g.:
 *
 * SOMETHING somevar = {...,ASN1_ITEM_ref(X509),...};
 *
 * and the actual pointer extracted with:
 *
 * const ASN1_ITEM *it = ASN1_ITEM_ptr(somevar.iptr);
 *
 * Finally an ASN1_ITEM pointer can be extracted from an
 * appropriate reference with: ASN1_ITEM_rptr(X509). This
 * would be used when a function takes an ASN1_ITEM * argument.
 *
 */

# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION

/* ASN1_ITEM pointer exported type */
typedef const ASN1_ITEM ASN1_ITEM_EXP;

/* Macro to obtain ASN1_ITEM pointer from exported type */
#  define ASN1_ITEM_ptr(iptr) (iptr)

/* Macro to include ASN1_ITEM pointer from base type */
#  define ASN1_ITEM_ref(iptr) (&(iptr##_it))

#  define ASN1_ITEM_rptr(ref) (&(ref##_it))

#  define DECLARE_ASN1_ITEM(name) \
        OPENSSL_EXTERN const ASN1_ITEM name##_it;

# else

/*
 * Platforms that can't easily handle shared global variables are declared as
 * functions returning ASN1_ITEM pointers.
 */

/* ASN1_ITEM pointer exported type */
typedef const ASN1_ITEM *ASN1_ITEM_EXP (void);

/* Macro to obtain ASN1_ITEM pointer from exported type */
#  define ASN1_ITEM_ptr(iptr) (iptr())

/* Macro to include ASN1_ITEM pointer from base type */
#  define ASN1_ITEM_ref(iptr) (iptr##_it)

#  define ASN1_ITEM_rptr(ref) (ref##_it())

#  define DECLARE_ASN1_ITEM(name) \
        const ASN1_ITEM * name##_it(void);

# endif

/* Parameters used by ASN1_STRING_print_ex() */

/*
 * These determine which characters to escape: RFC2253 special characters,
 * control characters and MSB set characters
 */

# define ASN1_STRFLGS_ESC_2253           1
# define ASN1_STRFLGS_ESC_CTRL           2
# define ASN1_STRFLGS_ESC_MSB            4

/*
 * This flag determines how we do escaping: normally RC2253 backslash only,
 * set this to use backslash and quote.
 */

# define ASN1_STRFLGS_ESC_QUOTE          8

/* These three flags are internal use only. */

/* Character is a valid PrintableString character */
# define CHARTYPE_PRINTABLESTRING        0x10
/* Character needs escaping if it is the first character */
# define CHARTYPE_FIRST_ESC_2253         0x20
/* Character needs escaping if it is the last character */
# define CHARTYPE_LAST_ESC_2253          0x40

/*
 * NB the internal flags are safely reused below by flags handled at the top
 * level.
 */

/*
 * If this is set we convert all character strings to UTF8 first
 */

# define ASN1_STRFLGS_UTF8_CONVERT       0x10

/*
 * If this is set we don't attempt to interpret content: just assume all
 * strings are 1 byte per character. This will produce some pretty odd
 * looking output!
 */

# define ASN1_STRFLGS_IGNORE_TYPE        0x20

/* If this is set we include the string type in the output */
# define ASN1_STRFLGS_SHOW_TYPE          0x40

/*
 * This determines which strings to display and which to 'dump' (hex dump of
 * content octets or DER encoding). We can only dump non character strings or
 * everything. If we don't dump 'unknown' they are interpreted as character
 * strings with 1 octet per character and are subject to the usual escaping
 * options.
 */

# define ASN1_STRFLGS_DUMP_ALL           0x80
# define ASN1_STRFLGS_DUMP_UNKNOWN       0x100

/*
 * These determine what 'dumping' does, we can dump the content octets or the
 * DER encoding: both use the RFC2253 #XXXXX notation.
 */

# define ASN1_STRFLGS_DUMP_DER           0x200

/*
 * All the string flags consistent with RFC2253, escaping control characters
 * isn't essential in RFC2253 but it is advisable anyway.
 */

# define ASN1_STRFLGS_RFC2253    (ASN1_STRFLGS_ESC_2253 | \
                                ASN1_STRFLGS_ESC_CTRL | \
                                ASN1_STRFLGS_ESC_MSB | \
                                ASN1_STRFLGS_UTF8_CONVERT | \
                                ASN1_STRFLGS_DUMP_UNKNOWN | \
                                ASN1_STRFLGS_DUMP_DER)

DECLARE_STACK_OF(ASN1_INTEGER)
DECLARE_ASN1_SET_OF(ASN1_INTEGER)

DECLARE_STACK_OF(ASN1_GENERALSTRING)

typedef struct asn1_type_st {
    int type;
    union {
        char *ptr;
        ASN1_BOOLEAN boolean;
        ASN1_STRING *asn1_string;
        ASN1_OBJECT *object;
        ASN1_INTEGER *integer;
        ASN1_ENUMERATED *enumerated;
        ASN1_BIT_STRING *bit_string;
        ASN1_OCTET_STRING *octet_string;
        ASN1_PRINTABLESTRING *printablestring;
        ASN1_T61STRING *t61string;
        ASN1_IA5STRING *ia5string;
        ASN1_GENERALSTRING *generalstring;
        ASN1_BMPSTRING *bmpstring;
        ASN1_UNIVERSALSTRING *universalstring;
        ASN1_UTCTIME *utctime;
        ASN1_GENERALIZEDTIME *generalizedtime;
        ASN1_VISIBLESTRING *visiblestring;
        ASN1_UTF8STRING *utf8string;
        /*
         * set and sequence are left complete and still contain the set or
         * sequence bytes
         */
        ASN1_STRING *set;
        ASN1_STRING *sequence;
        ASN1_VALUE *asn1_value;
    } value;
} ASN1_TYPE;

DECLARE_STACK_OF(ASN1_TYPE)
DECLARE_ASN1_SET_OF(ASN1_TYPE)

typedef STACK_OF(ASN1_TYPE) ASN1_SEQUENCE_ANY;

DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY)
DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SET_ANY)

typedef struct NETSCAPE_X509_st {
    ASN1_OCTET_STRING *header;
    X509 *cert;
} NETSCAPE_X509;

/* This is used to contain a list of bit names */
typedef struct BIT_STRING_BITNAME_st {
    int bitnum;
    const char *lname;
    const char *sname;
} BIT_STRING_BITNAME;

# define M_ASN1_STRING_length(x) ((x)->length)
# define M_ASN1_STRING_length_set(x, n)  ((x)->length = (n))
# define M_ASN1_STRING_type(x)   ((x)->type)
# define M_ASN1_STRING_data(x)   ((x)->data)

/* Macros for string operations */
# define M_ASN1_BIT_STRING_new() (ASN1_BIT_STRING *)\
                ASN1_STRING_type_new(V_ASN1_BIT_STRING)
# define M_ASN1_BIT_STRING_free(a)       ASN1_STRING_free((ASN1_STRING *)a)
# define M_ASN1_BIT_STRING_dup(a) (ASN1_BIT_STRING *)\
                ASN1_STRING_dup((const ASN1_STRING *)a)
# define M_ASN1_BIT_STRING_cmp(a,b) ASN1_STRING_cmp(\
                (const ASN1_STRING *)a,(const ASN1_STRING *)b)
# define M_ASN1_BIT_STRING_set(a,b,c) ASN1_STRING_set((ASN1_STRING *)a,b,c)

# define M_ASN1_INTEGER_new()    (ASN1_INTEGER *)\
                ASN1_STRING_type_new(V_ASN1_INTEGER)
# define M_ASN1_INTEGER_free(a)          ASN1_STRING_free((ASN1_STRING *)a)
# define M_ASN1_INTEGER_dup(a) (ASN1_INTEGER *)\
                ASN1_STRING_dup((const ASN1_STRING *)a)
# define M_ASN1_INTEGER_cmp(a,b) ASN1_STRING_cmp(\
                (const ASN1_STRING *)a,(const ASN1_STRING *)b)

# define M_ASN1_ENUMERATED_new() (ASN1_ENUMERATED *)\
                ASN1_STRING_type_new(V_ASN1_ENUMERATED)
# define M_ASN1_ENUMERATED_free(a)       ASN1_STRING_free((ASN1_STRING *)a)
# define M_ASN1_ENUMERATED_dup(a) (ASN1_ENUMERATED *)\
                ASN1_STRING_dup((const ASN1_STRING *)a)
# define M_ASN1_ENUMERATED_cmp(a,b)      ASN1_STRING_cmp(\
                (const ASN1_STRING *)a,(const ASN1_STRING *)b)

# define M_ASN1_OCTET_STRING_new()       (ASN1_OCTET_STRING *)\
                ASN1_STRING_type_new(V_ASN1_OCTET_STRING)
# define M_ASN1_OCTET_STRING_free(a)     ASN1_STRING_free((ASN1_STRING *)a)
# define M_ASN1_OCTET_STRING_dup(a) (ASN1_OCTET_STRING *)\
                ASN1_STRING_dup((const ASN1_STRING *)a)
# define M_ASN1_OCTET_STRING_cmp(a,b) ASN1_STRING_cmp(\
                (const ASN1_STRING *)a,(const ASN1_STRING *)b)
# define M_ASN1_OCTET_STRING_set(a,b,c)  ASN1_STRING_set((ASN1_STRING *)a,b,c)
# define M_ASN1_OCTET_STRING_print(a,b)  ASN1_STRING_print(a,(ASN1_STRING *)b)
# define M_i2d_ASN1_OCTET_STRING(a,pp) \
                i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_OCTET_STRING,\
                V_ASN1_UNIVERSAL)

# define B_ASN1_TIME \
                        B_ASN1_UTCTIME | \
                        B_ASN1_GENERALIZEDTIME

# define B_ASN1_PRINTABLE \
                        B_ASN1_NUMERICSTRING| \
                        B_ASN1_PRINTABLESTRING| \
                        B_ASN1_T61STRING| \
                        B_ASN1_IA5STRING| \
                        B_ASN1_BIT_STRING| \
                        B_ASN1_UNIVERSALSTRING|\
                        B_ASN1_BMPSTRING|\
                        B_ASN1_UTF8STRING|\
                        B_ASN1_SEQUENCE|\
                        B_ASN1_UNKNOWN

# define B_ASN1_DIRECTORYSTRING \
                        B_ASN1_PRINTABLESTRING| \
                        B_ASN1_TELETEXSTRING|\
                        B_ASN1_BMPSTRING|\
                        B_ASN1_UNIVERSALSTRING|\
                        B_ASN1_UTF8STRING

# define B_ASN1_DISPLAYTEXT \
                        B_ASN1_IA5STRING| \
                        B_ASN1_VISIBLESTRING| \
                        B_ASN1_BMPSTRING|\
                        B_ASN1_UTF8STRING

# define M_ASN1_PRINTABLE_new()  ASN1_STRING_type_new(V_ASN1_T61STRING)
# define M_ASN1_PRINTABLE_free(a)        ASN1_STRING_free((ASN1_STRING *)a)
# define M_i2d_ASN1_PRINTABLE(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\
                pp,a->type,V_ASN1_UNIVERSAL)
# define M_d2i_ASN1_PRINTABLE(a,pp,l) \
                d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \
                        B_ASN1_PRINTABLE)

# define M_DIRECTORYSTRING_new() ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING)
# define M_DIRECTORYSTRING_free(a)       ASN1_STRING_free((ASN1_STRING *)a)
# define M_i2d_DIRECTORYSTRING(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\
                                                pp,a->type,V_ASN1_UNIVERSAL)
# define M_d2i_DIRECTORYSTRING(a,pp,l) \
                d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \
                        B_ASN1_DIRECTORYSTRING)

# define M_DISPLAYTEXT_new() ASN1_STRING_type_new(V_ASN1_VISIBLESTRING)
# define M_DISPLAYTEXT_free(a) ASN1_STRING_free((ASN1_STRING *)a)
# define M_i2d_DISPLAYTEXT(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\
                                                pp,a->type,V_ASN1_UNIVERSAL)
# define M_d2i_DISPLAYTEXT(a,pp,l) \
                d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \
                        B_ASN1_DISPLAYTEXT)

# define M_ASN1_PRINTABLESTRING_new() (ASN1_PRINTABLESTRING *)\
                ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING)
# define M_ASN1_PRINTABLESTRING_free(a)  ASN1_STRING_free((ASN1_STRING *)a)
# define M_i2d_ASN1_PRINTABLESTRING(a,pp) \
                i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_PRINTABLESTRING,\
                V_ASN1_UNIVERSAL)
# define M_d2i_ASN1_PRINTABLESTRING(a,pp,l) \
                (ASN1_PRINTABLESTRING *)d2i_ASN1_type_bytes\
                ((ASN1_STRING **)a,pp,l,B_ASN1_PRINTABLESTRING)

# define M_ASN1_T61STRING_new()  (ASN1_T61STRING *)\
                ASN1_STRING_type_new(V_ASN1_T61STRING)
# define M_ASN1_T61STRING_free(a)        ASN1_STRING_free((ASN1_STRING *)a)
# define M_i2d_ASN1_T61STRING(a,pp) \
                i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_T61STRING,\
                V_ASN1_UNIVERSAL)
# define M_d2i_ASN1_T61STRING(a,pp,l) \
                (ASN1_T61STRING *)d2i_ASN1_type_bytes\
                ((ASN1_STRING **)a,pp,l,B_ASN1_T61STRING)

# define M_ASN1_IA5STRING_new()  (ASN1_IA5STRING *)\
                ASN1_STRING_type_new(V_ASN1_IA5STRING)
# define M_ASN1_IA5STRING_free(a)        ASN1_STRING_free((ASN1_STRING *)a)
# define M_ASN1_IA5STRING_dup(a) \
                (ASN1_IA5STRING *)ASN1_STRING_dup((const ASN1_STRING *)a)
# define M_i2d_ASN1_IA5STRING(a,pp) \
                i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_IA5STRING,\
                        V_ASN1_UNIVERSAL)
# define M_d2i_ASN1_IA5STRING(a,pp,l) \
                (ASN1_IA5STRING *)d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l,\
                        B_ASN1_IA5STRING)

# define M_ASN1_UTCTIME_new()    (ASN1_UTCTIME *)\
                ASN1_STRING_type_new(V_ASN1_UTCTIME)
# define M_ASN1_UTCTIME_free(a)  ASN1_STRING_free((ASN1_STRING *)a)
# define M_ASN1_UTCTIME_dup(a) (ASN1_UTCTIME *)\
                ASN1_STRING_dup((const ASN1_STRING *)a)

# define M_ASN1_GENERALIZEDTIME_new()    (ASN1_GENERALIZEDTIME *)\
                ASN1_STRING_type_new(V_ASN1_GENERALIZEDTIME)
# define M_ASN1_GENERALIZEDTIME_free(a)  ASN1_STRING_free((ASN1_STRING *)a)
# define M_ASN1_GENERALIZEDTIME_dup(a) (ASN1_GENERALIZEDTIME *)ASN1_STRING_dup(\
        (const ASN1_STRING *)a)

# define M_ASN1_TIME_new()       (ASN1_TIME *)\
                ASN1_STRING_type_new(V_ASN1_UTCTIME)
# define M_ASN1_TIME_free(a)     ASN1_STRING_free((ASN1_STRING *)a)
# define M_ASN1_TIME_dup(a) (ASN1_TIME *)\
        ASN1_STRING_dup((const ASN1_STRING *)a)

# define M_ASN1_GENERALSTRING_new()      (ASN1_GENERALSTRING *)\
                ASN1_STRING_type_new(V_ASN1_GENERALSTRING)
# define M_ASN1_GENERALSTRING_free(a)    ASN1_STRING_free((ASN1_STRING *)a)
# define M_i2d_ASN1_GENERALSTRING(a,pp) \
                i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_GENERALSTRING,\
                        V_ASN1_UNIVERSAL)
# define M_d2i_ASN1_GENERALSTRING(a,pp,l) \
                (ASN1_GENERALSTRING *)d2i_ASN1_type_bytes\
                ((ASN1_STRING **)a,pp,l,B_ASN1_GENERALSTRING)

# define M_ASN1_UNIVERSALSTRING_new()    (ASN1_UNIVERSALSTRING *)\
                ASN1_STRING_type_new(V_ASN1_UNIVERSALSTRING)
# define M_ASN1_UNIVERSALSTRING_free(a)  ASN1_STRING_free((ASN1_STRING *)a)
# define M_i2d_ASN1_UNIVERSALSTRING(a,pp) \
                i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_UNIVERSALSTRING,\
                        V_ASN1_UNIVERSAL)
# define M_d2i_ASN1_UNIVERSALSTRING(a,pp,l) \
                (ASN1_UNIVERSALSTRING *)d2i_ASN1_type_bytes\
                ((ASN1_STRING **)a,pp,l,B_ASN1_UNIVERSALSTRING)

# define M_ASN1_BMPSTRING_new()  (ASN1_BMPSTRING *)\
                ASN1_STRING_type_new(V_ASN1_BMPSTRING)
# define M_ASN1_BMPSTRING_free(a)        ASN1_STRING_free((ASN1_STRING *)a)
# define M_i2d_ASN1_BMPSTRING(a,pp) \
                i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_BMPSTRING,\
                        V_ASN1_UNIVERSAL)
# define M_d2i_ASN1_BMPSTRING(a,pp,l) \
                (ASN1_BMPSTRING *)d2i_ASN1_type_bytes\
                ((ASN1_STRING **)a,pp,l,B_ASN1_BMPSTRING)

# define M_ASN1_VISIBLESTRING_new()      (ASN1_VISIBLESTRING *)\
                ASN1_STRING_type_new(V_ASN1_VISIBLESTRING)
# define M_ASN1_VISIBLESTRING_free(a)    ASN1_STRING_free((ASN1_STRING *)a)
# define M_i2d_ASN1_VISIBLESTRING(a,pp) \
                i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_VISIBLESTRING,\
                        V_ASN1_UNIVERSAL)
# define M_d2i_ASN1_VISIBLESTRING(a,pp,l) \
                (ASN1_VISIBLESTRING *)d2i_ASN1_type_bytes\
                ((ASN1_STRING **)a,pp,l,B_ASN1_VISIBLESTRING)

# define M_ASN1_UTF8STRING_new() (ASN1_UTF8STRING *)\
                ASN1_STRING_type_new(V_ASN1_UTF8STRING)
# define M_ASN1_UTF8STRING_free(a)       ASN1_STRING_free((ASN1_STRING *)a)
# define M_i2d_ASN1_UTF8STRING(a,pp) \
                i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_UTF8STRING,\
                        V_ASN1_UNIVERSAL)
# define M_d2i_ASN1_UTF8STRING(a,pp,l) \
                (ASN1_UTF8STRING *)d2i_ASN1_type_bytes\
                ((ASN1_STRING **)a,pp,l,B_ASN1_UTF8STRING)

  /* for the is_set parameter to i2d_ASN1_SET */
# define IS_SEQUENCE     0
# define IS_SET          1

DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE)

int ASN1_TYPE_get(ASN1_TYPE *a);
void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value);
int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value);
int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b);

ASN1_OBJECT *ASN1_OBJECT_new(void);
void ASN1_OBJECT_free(ASN1_OBJECT *a);
int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp);
ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
                             long length);
ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
                             long length);

DECLARE_ASN1_ITEM(ASN1_OBJECT)

DECLARE_STACK_OF(ASN1_OBJECT)
DECLARE_ASN1_SET_OF(ASN1_OBJECT)

ASN1_STRING *ASN1_STRING_new(void);
void ASN1_STRING_free(ASN1_STRING *a);
void ASN1_STRING_clear_free(ASN1_STRING *a);
int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str);
ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *a);
ASN1_STRING *ASN1_STRING_type_new(int type);
int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b);
  /*
   * Since this is used to store all sorts of things, via macros, for now,
   * make its data void *
   */
int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len);
void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len);
int ASN1_STRING_length(const ASN1_STRING *x);
void ASN1_STRING_length_set(ASN1_STRING *x, int n);
int ASN1_STRING_type(ASN1_STRING *x);
unsigned char *ASN1_STRING_data(ASN1_STRING *x);

DECLARE_ASN1_FUNCTIONS(ASN1_BIT_STRING)
int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp);
ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
                                     const unsigned char **pp, long length);
int ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d, int length);
int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value);
int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n);
int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a,
                          unsigned char *flags, int flags_len);

# ifndef OPENSSL_NO_BIO
int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs,
                               BIT_STRING_BITNAME *tbl, int indent);
# endif
int ASN1_BIT_STRING_num_asc(char *name, BIT_STRING_BITNAME *tbl);
int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value,
                            BIT_STRING_BITNAME *tbl);

int i2d_ASN1_BOOLEAN(int a, unsigned char **pp);
int d2i_ASN1_BOOLEAN(int *a, const unsigned char **pp, long length);

DECLARE_ASN1_FUNCTIONS(ASN1_INTEGER)
int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp);
ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp,
                               long length);
ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp,
                                long length);
ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x);
int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y);

DECLARE_ASN1_FUNCTIONS(ASN1_ENUMERATED)

int ASN1_UTCTIME_check(const ASN1_UTCTIME *a);
ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t);
ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t,
                               int offset_day, long offset_sec);
int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str);
int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t);
# if 0
time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s);
# endif

int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *a);
ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,
                                               time_t t);
ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
                                               time_t t, int offset_day,
                                               long offset_sec);
int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str);
int ASN1_TIME_diff(int *pday, int *psec,
                   const ASN1_TIME *from, const ASN1_TIME *to);

DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING)
ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *a);
int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a,
                          const ASN1_OCTET_STRING *b);
int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, const unsigned char *data,
                          int len);

DECLARE_ASN1_FUNCTIONS(ASN1_VISIBLESTRING)
DECLARE_ASN1_FUNCTIONS(ASN1_UNIVERSALSTRING)
DECLARE_ASN1_FUNCTIONS(ASN1_UTF8STRING)
DECLARE_ASN1_FUNCTIONS(ASN1_NULL)
DECLARE_ASN1_FUNCTIONS(ASN1_BMPSTRING)

int UTF8_getc(const unsigned char *str, int len, unsigned long *val);
int UTF8_putc(unsigned char *str, int len, unsigned long value);

DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE)

DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING)
DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT)
DECLARE_ASN1_FUNCTIONS(ASN1_PRINTABLESTRING)
DECLARE_ASN1_FUNCTIONS(ASN1_T61STRING)
DECLARE_ASN1_FUNCTIONS(ASN1_IA5STRING)
DECLARE_ASN1_FUNCTIONS(ASN1_GENERALSTRING)
DECLARE_ASN1_FUNCTIONS(ASN1_UTCTIME)
DECLARE_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME)
DECLARE_ASN1_FUNCTIONS(ASN1_TIME)

DECLARE_ASN1_ITEM(ASN1_OCTET_STRING_NDEF)

ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t);
ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t,
                         int offset_day, long offset_sec);
int ASN1_TIME_check(ASN1_TIME *t);
ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME
                                                   **out);
int ASN1_TIME_set_string(ASN1_TIME *s, const char *str);

int i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp,
                 i2d_of_void *i2d, int ex_tag, int ex_class, int is_set);
STACK_OF(OPENSSL_BLOCK) *d2i_ASN1_SET(STACK_OF(OPENSSL_BLOCK) **a,
                                      const unsigned char **pp,
                                      long length, d2i_of_void *d2i,
                                      void (*free_func) (OPENSSL_BLOCK),
                                      int ex_tag, int ex_class);

# ifndef OPENSSL_NO_BIO
int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a);
int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size);
int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a);
int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size);
int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a);
int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size);
int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type);
# endif
int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a);

int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num);
ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len,
                                const char *sn, const char *ln);

int ASN1_INTEGER_set(ASN1_INTEGER *a, long v);
long ASN1_INTEGER_get(const ASN1_INTEGER *a);
ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai);
BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn);

int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v);
long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a);
ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai);
BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn);

/* General */
/* given a string, return the correct type, max is the maximum length */
int ASN1_PRINTABLE_type(const unsigned char *s, int max);

int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass);
ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
                            long length, int Ptag, int Pclass);
unsigned long ASN1_tag2bit(int tag);
/* type is one or more of the B_ASN1_ values. */
ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, const unsigned char **pp,
                                 long length, int type);

/* PARSING */
int asn1_Finish(ASN1_CTX *c);
int asn1_const_Finish(ASN1_const_CTX *c);

/* SPECIALS */
int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
                    int *pclass, long omax);
int ASN1_check_infinite_end(unsigned char **p, long len);
int ASN1_const_check_infinite_end(const unsigned char **p, long len);
void ASN1_put_object(unsigned char **pp, int constructed, int length,
                     int tag, int xclass);
int ASN1_put_eoc(unsigned char **pp);
int ASN1_object_size(int constructed, int length, int tag);

/* Used to implement other functions */
void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x);

# define ASN1_dup_of(type,i2d,d2i,x) \
    ((type*)ASN1_dup(CHECKED_I2D_OF(type, i2d), \
                     CHECKED_D2I_OF(type, d2i), \
                     CHECKED_PTR_OF(type, x)))

# define ASN1_dup_of_const(type,i2d,d2i,x) \
    ((type*)ASN1_dup(CHECKED_I2D_OF(const type, i2d), \
                     CHECKED_D2I_OF(type, d2i), \
                     CHECKED_PTR_OF(const type, x)))

void *ASN1_item_dup(const ASN1_ITEM *it, void *x);

/* ASN1 alloc/free macros for when a type is only used internally */

# define M_ASN1_new_of(type) (type *)ASN1_item_new(ASN1_ITEM_rptr(type))
# define M_ASN1_free_of(x, type) \
                ASN1_item_free(CHECKED_PTR_OF(type, x), ASN1_ITEM_rptr(type))

# ifndef OPENSSL_NO_FP_API
void *ASN1_d2i_fp(void *(*xnew) (void), d2i_of_void *d2i, FILE *in, void **x);

#  define ASN1_d2i_fp_of(type,xnew,d2i,in,x) \
    ((type*)ASN1_d2i_fp(CHECKED_NEW_OF(type, xnew), \
                        CHECKED_D2I_OF(type, d2i), \
                        in, \
                        CHECKED_PPTR_OF(type, x)))

void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x);
int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x);

#  define ASN1_i2d_fp_of(type,i2d,out,x) \
    (ASN1_i2d_fp(CHECKED_I2D_OF(type, i2d), \
                 out, \
                 CHECKED_PTR_OF(type, x)))

#  define ASN1_i2d_fp_of_const(type,i2d,out,x) \
    (ASN1_i2d_fp(CHECKED_I2D_OF(const type, i2d), \
                 out, \
                 CHECKED_PTR_OF(const type, x)))

int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x);
int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags);
# endif

int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in);

# ifndef OPENSSL_NO_BIO
void *ASN1_d2i_bio(void *(*xnew) (void), d2i_of_void *d2i, BIO *in, void **x);

#  define ASN1_d2i_bio_of(type,xnew,d2i,in,x) \
    ((type*)ASN1_d2i_bio( CHECKED_NEW_OF(type, xnew), \
                          CHECKED_D2I_OF(type, d2i), \
                          in, \
                          CHECKED_PPTR_OF(type, x)))

void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x);
int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x);

#  define ASN1_i2d_bio_of(type,i2d,out,x) \
    (ASN1_i2d_bio(CHECKED_I2D_OF(type, i2d), \
                  out, \
                  CHECKED_PTR_OF(type, x)))

#  define ASN1_i2d_bio_of_const(type,i2d,out,x) \
    (ASN1_i2d_bio(CHECKED_I2D_OF(const type, i2d), \
                  out, \
                  CHECKED_PTR_OF(const type, x)))

int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x);
int ASN1_UTCTIME_print(BIO *fp, const ASN1_UTCTIME *a);
int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIME *a);
int ASN1_TIME_print(BIO *fp, const ASN1_TIME *a);
int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v);
int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags);
int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
                  unsigned char *buf, int off);
int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent);
int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent,
                    int dump);
# endif
const char *ASN1_tag2str(int tag);

/* Used to load and write netscape format cert */

DECLARE_ASN1_FUNCTIONS(NETSCAPE_X509)

int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s);

int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len);
int ASN1_TYPE_get_octetstring(ASN1_TYPE *a, unsigned char *data, int max_len);
int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num,
                                  unsigned char *data, int len);
int ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a, long *num,
                                  unsigned char *data, int max_len);

STACK_OF(OPENSSL_BLOCK) *ASN1_seq_unpack(const unsigned char *buf, int len,
                                         d2i_of_void *d2i,
                                         void (*free_func) (OPENSSL_BLOCK));
unsigned char *ASN1_seq_pack(STACK_OF(OPENSSL_BLOCK) *safes, i2d_of_void *i2d,
                             unsigned char **buf, int *len);
void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i);
void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it);
ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_void *i2d,
                              ASN1_OCTET_STRING **oct);

# define ASN1_pack_string_of(type,obj,i2d,oct) \
    (ASN1_pack_string(CHECKED_PTR_OF(type, obj), \
                      CHECKED_I2D_OF(type, i2d), \
                      oct))

ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it,
                            ASN1_OCTET_STRING **oct);

void ASN1_STRING_set_default_mask(unsigned long mask);
int ASN1_STRING_set_default_mask_asc(const char *p);
unsigned long ASN1_STRING_get_default_mask(void);
int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
                       int inform, unsigned long mask);
int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
                        int inform, unsigned long mask,
                        long minsize, long maxsize);

ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out,
                                    const unsigned char *in, int inlen,
                                    int inform, int nid);
ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid);
int ASN1_STRING_TABLE_add(int, long, long, unsigned long, unsigned long);
void ASN1_STRING_TABLE_cleanup(void);

/* ASN1 template functions */

/* Old API compatible functions */
ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it);
void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it);
ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **val, const unsigned char **in,
                          long len, const ASN1_ITEM *it);
int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it);
int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out,
                       const ASN1_ITEM *it);

void ASN1_add_oid_module(void);

ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf);
ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf);

/* ASN1 Print flags */

/* Indicate missing OPTIONAL fields */
# define ASN1_PCTX_FLAGS_SHOW_ABSENT             0x001
/* Mark start and end of SEQUENCE */
# define ASN1_PCTX_FLAGS_SHOW_SEQUENCE           0x002
/* Mark start and end of SEQUENCE/SET OF */
# define ASN1_PCTX_FLAGS_SHOW_SSOF               0x004
/* Show the ASN1 type of primitives */
# define ASN1_PCTX_FLAGS_SHOW_TYPE               0x008
/* Don't show ASN1 type of ANY */
# define ASN1_PCTX_FLAGS_NO_ANY_TYPE             0x010
/* Don't show ASN1 type of MSTRINGs */
# define ASN1_PCTX_FLAGS_NO_MSTRING_TYPE         0x020
/* Don't show field names in SEQUENCE */
# define ASN1_PCTX_FLAGS_NO_FIELD_NAME           0x040
/* Show structure names of each SEQUENCE field */
# define ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME  0x080
/* Don't show structure name even at top level */
# define ASN1_PCTX_FLAGS_NO_STRUCT_NAME          0x100

int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
                    const ASN1_ITEM *it, const ASN1_PCTX *pctx);
ASN1_PCTX *ASN1_PCTX_new(void);
void ASN1_PCTX_free(ASN1_PCTX *p);
unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p);
void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags);
unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p);
void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags);
unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p);
void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags);
unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p);
void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags);
unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p);
void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags);

BIO_METHOD *BIO_f_asn1(void);

BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it);

int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
                        const ASN1_ITEM *it);
int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
                              const char *hdr, const ASN1_ITEM *it);
int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
                     int ctype_nid, int econt_nid,
                     STACK_OF(X509_ALGOR) *mdalgs, const ASN1_ITEM *it);
ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it);
int SMIME_crlf_copy(BIO *in, BIO *out, int flags);
int SMIME_text(BIO *in, BIO *out);

/* BEGIN ERROR CODES */
/*
 * The following lines are auto generated by the script mkerr.pl. Any changes
 * made after this point may be overwritten when the script is next run.
 */

void ERR_load_ASN1_strings(void);

/* Error codes for the ASN1 functions. */

/* Function codes. */
# define ASN1_F_A2D_ASN1_OBJECT                           100
# define ASN1_F_A2I_ASN1_ENUMERATED                       101
# define ASN1_F_A2I_ASN1_INTEGER                          102
# define ASN1_F_A2I_ASN1_STRING                           103
# define ASN1_F_APPEND_EXP                                176
# define ASN1_F_ASN1_BIT_STRING_SET_BIT                   183
# define ASN1_F_ASN1_CB                                   177
# define ASN1_F_ASN1_CHECK_TLEN                           104
# define ASN1_F_ASN1_COLLATE_PRIMITIVE                    105
# define ASN1_F_ASN1_COLLECT                              106
# define ASN1_F_ASN1_D2I_EX_PRIMITIVE                     108
# define ASN1_F_ASN1_D2I_FP                               109
# define ASN1_F_ASN1_D2I_READ_BIO                         107
# define ASN1_F_ASN1_DIGEST                               184
# define ASN1_F_ASN1_DO_ADB                               110
# define ASN1_F_ASN1_DUP                                  111
# define ASN1_F_ASN1_ENUMERATED_SET                       112
# define ASN1_F_ASN1_ENUMERATED_TO_BN                     113
# define ASN1_F_ASN1_EX_C2I                               204
# define ASN1_F_ASN1_FIND_END                             190
# define ASN1_F_ASN1_GENERALIZEDTIME_ADJ                  216
# define ASN1_F_ASN1_GENERALIZEDTIME_SET                  185
# define ASN1_F_ASN1_GENERATE_V3                          178
# define ASN1_F_ASN1_GET_OBJECT                           114
# define ASN1_F_ASN1_HEADER_NEW                           115
# define ASN1_F_ASN1_I2D_BIO                              116
# define ASN1_F_ASN1_I2D_FP                               117
# define ASN1_F_ASN1_INTEGER_SET                          118
# define ASN1_F_ASN1_INTEGER_TO_BN                        119
# define ASN1_F_ASN1_ITEM_D2I_FP                          206
# define ASN1_F_ASN1_ITEM_DUP                             191
# define ASN1_F_ASN1_ITEM_EX_COMBINE_NEW                  121
# define ASN1_F_ASN1_ITEM_EX_D2I                          120
# define ASN1_F_ASN1_ITEM_I2D_BIO                         192
# define ASN1_F_ASN1_ITEM_I2D_FP                          193
# define ASN1_F_ASN1_ITEM_PACK                            198
# define ASN1_F_ASN1_ITEM_SIGN                            195
# define ASN1_F_ASN1_ITEM_SIGN_CTX                        220
# define ASN1_F_ASN1_ITEM_UNPACK                          199
# define ASN1_F_ASN1_ITEM_VERIFY                          197
# define ASN1_F_ASN1_MBSTRING_NCOPY                       122
# define ASN1_F_ASN1_OBJECT_NEW                           123
# define ASN1_F_ASN1_OUTPUT_DATA                          214
# define ASN1_F_ASN1_PACK_STRING                          124
# define ASN1_F_ASN1_PCTX_NEW                             205
# define ASN1_F_ASN1_PKCS5_PBE_SET                        125
# define ASN1_F_ASN1_SEQ_PACK                             126
# define ASN1_F_ASN1_SEQ_UNPACK                           127
# define ASN1_F_ASN1_SIGN                                 128
# define ASN1_F_ASN1_STR2TYPE                             179
# define ASN1_F_ASN1_STRING_SET                           186
# define ASN1_F_ASN1_STRING_TABLE_ADD                     129
# define ASN1_F_ASN1_STRING_TYPE_NEW                      130
# define ASN1_F_ASN1_TEMPLATE_EX_D2I                      132
# define ASN1_F_ASN1_TEMPLATE_NEW                         133
# define ASN1_F_ASN1_TEMPLATE_NOEXP_D2I                   131
# define ASN1_F_ASN1_TIME_ADJ                             217
# define ASN1_F_ASN1_TIME_SET                             175
# define ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING             134
# define ASN1_F_ASN1_TYPE_GET_OCTETSTRING                 135
# define ASN1_F_ASN1_UNPACK_STRING                        136
# define ASN1_F_ASN1_UTCTIME_ADJ                          218
# define ASN1_F_ASN1_UTCTIME_SET                          187
# define ASN1_F_ASN1_VERIFY                               137
# define ASN1_F_B64_READ_ASN1                             209
# define ASN1_F_B64_WRITE_ASN1                            210
# define ASN1_F_BIO_NEW_NDEF                              208
# define ASN1_F_BITSTR_CB                                 180
# define ASN1_F_BN_TO_ASN1_ENUMERATED                     138
# define ASN1_F_BN_TO_ASN1_INTEGER                        139
# define ASN1_F_C2I_ASN1_BIT_STRING                       189
# define ASN1_F_C2I_ASN1_INTEGER                          194
# define ASN1_F_C2I_ASN1_OBJECT                           196
# define ASN1_F_COLLECT_DATA                              140
# define ASN1_F_D2I_ASN1_BIT_STRING                       141
# define ASN1_F_D2I_ASN1_BOOLEAN                          142
# define ASN1_F_D2I_ASN1_BYTES                            143
# define ASN1_F_D2I_ASN1_GENERALIZEDTIME                  144
# define ASN1_F_D2I_ASN1_HEADER                           145
# define ASN1_F_D2I_ASN1_INTEGER                          146
# define ASN1_F_D2I_ASN1_OBJECT                           147
# define ASN1_F_D2I_ASN1_SET                              148
# define ASN1_F_D2I_ASN1_TYPE_BYTES                       149
# define ASN1_F_D2I_ASN1_UINTEGER                         150
# define ASN1_F_D2I_ASN1_UTCTIME                          151
# define ASN1_F_D2I_AUTOPRIVATEKEY                        207
# define ASN1_F_D2I_NETSCAPE_RSA                          152
# define ASN1_F_D2I_NETSCAPE_RSA_2                        153
# define ASN1_F_D2I_PRIVATEKEY                            154
# define ASN1_F_D2I_PUBLICKEY                             155
# define ASN1_F_D2I_RSA_NET                               200
# define ASN1_F_D2I_RSA_NET_2                             201
# define ASN1_F_D2I_X509                                  156
# define ASN1_F_D2I_X509_CINF                             157
# define ASN1_F_D2I_X509_PKEY                             159
# define ASN1_F_DO_BUF                                    221
# define ASN1_F_I2D_ASN1_BIO_STREAM                       211
# define ASN1_F_I2D_ASN1_BOOLEAN                          223
# define ASN1_F_I2D_ASN1_OBJECT                           222
# define ASN1_F_I2D_ASN1_SET                              188
# define ASN1_F_I2D_ASN1_TIME                             160
# define ASN1_F_I2D_DSA_PUBKEY                            161
# define ASN1_F_I2D_EC_PUBKEY                             181
# define ASN1_F_I2D_PRIVATEKEY                            163
# define ASN1_F_I2D_PUBLICKEY                             164
# define ASN1_F_I2D_RSA_NET                               162
# define ASN1_F_I2D_RSA_PUBKEY                            165
# define ASN1_F_LONG_C2I                                  166
# define ASN1_F_OID_MODULE_INIT                           174
# define ASN1_F_PARSE_TAGGING                             182
# define ASN1_F_PKCS5_PBE2_SET_IV                         167
# define ASN1_F_PKCS5_PBE_SET                             202
# define ASN1_F_PKCS5_PBE_SET0_ALGOR                      215
# define ASN1_F_PKCS5_PBKDF2_SET                          219
# define ASN1_F_SMIME_READ_ASN1                           212
# define ASN1_F_SMIME_TEXT                                213
# define ASN1_F_X509_CINF_NEW                             168
# define ASN1_F_X509_CRL_ADD0_REVOKED                     169
# define ASN1_F_X509_INFO_NEW                             170
# define ASN1_F_X509_NAME_ENCODE                          203
# define ASN1_F_X509_NAME_EX_D2I                          158
# define ASN1_F_X509_NAME_EX_NEW                          171
# define ASN1_F_X509_NEW                                  172
# define ASN1_F_X509_PKEY_NEW                             173

/* Reason codes. */
# define ASN1_R_ADDING_OBJECT                             171
# define ASN1_R_ASN1_PARSE_ERROR                          203
# define ASN1_R_ASN1_SIG_PARSE_ERROR                      204
# define ASN1_R_AUX_ERROR                                 100
# define ASN1_R_BAD_CLASS                                 101
# define ASN1_R_BAD_OBJECT_HEADER                         102
# define ASN1_R_BAD_PASSWORD_READ                         103
# define ASN1_R_BAD_TAG                                   104
# define ASN1_R_BMPSTRING_IS_WRONG_LENGTH                 214
# define ASN1_R_BN_LIB                                    105
# define ASN1_R_BOOLEAN_IS_WRONG_LENGTH                   106
# define ASN1_R_BUFFER_TOO_SMALL                          107
# define ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER           108
# define ASN1_R_CONTEXT_NOT_INITIALISED                   217
# define ASN1_R_DATA_IS_WRONG                             109
# define ASN1_R_DECODE_ERROR                              110
# define ASN1_R_DECODING_ERROR                            111
# define ASN1_R_DEPTH_EXCEEDED                            174
# define ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED         198
# define ASN1_R_ENCODE_ERROR                              112
# define ASN1_R_ERROR_GETTING_TIME                        173
# define ASN1_R_ERROR_LOADING_SECTION                     172
# define ASN1_R_ERROR_PARSING_SET_ELEMENT                 113
# define ASN1_R_ERROR_SETTING_CIPHER_PARAMS               114
# define ASN1_R_EXPECTING_AN_INTEGER                      115
# define ASN1_R_EXPECTING_AN_OBJECT                       116
# define ASN1_R_EXPECTING_A_BOOLEAN                       117
# define ASN1_R_EXPECTING_A_TIME                          118
# define ASN1_R_EXPLICIT_LENGTH_MISMATCH                  119
# define ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED              120
# define ASN1_R_FIELD_MISSING                             121
# define ASN1_R_FIRST_NUM_TOO_LARGE                       122
# define ASN1_R_HEADER_TOO_LONG                           123
# define ASN1_R_ILLEGAL_BITSTRING_FORMAT                  175
# define ASN1_R_ILLEGAL_BOOLEAN                           176
# define ASN1_R_ILLEGAL_CHARACTERS                        124
# define ASN1_R_ILLEGAL_FORMAT                            177
# define ASN1_R_ILLEGAL_HEX                               178
# define ASN1_R_ILLEGAL_IMPLICIT_TAG                      179
# define ASN1_R_ILLEGAL_INTEGER                           180
# define ASN1_R_ILLEGAL_NESTED_TAGGING                    181
# define ASN1_R_ILLEGAL_NULL                              125
# define ASN1_R_ILLEGAL_NULL_VALUE                        182
# define ASN1_R_ILLEGAL_OBJECT                            183
# define ASN1_R_ILLEGAL_OPTIONAL_ANY                      126
# define ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE          170
# define ASN1_R_ILLEGAL_TAGGED_ANY                        127
# define ASN1_R_ILLEGAL_TIME_VALUE                        184
# define ASN1_R_INTEGER_NOT_ASCII_FORMAT                  185
# define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG                128
# define ASN1_R_INVALID_BIT_STRING_BITS_LEFT              220
# define ASN1_R_INVALID_BMPSTRING_LENGTH                  129
# define ASN1_R_INVALID_DIGIT                             130
# define ASN1_R_INVALID_MIME_TYPE                         205
# define ASN1_R_INVALID_MODIFIER                          186
# define ASN1_R_INVALID_NUMBER                            187
# define ASN1_R_INVALID_OBJECT_ENCODING                   216
# define ASN1_R_INVALID_SEPARATOR                         131
# define ASN1_R_INVALID_TIME_FORMAT                       132
# define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH            133
# define ASN1_R_INVALID_UTF8STRING                        134
# define ASN1_R_IV_TOO_LARGE                              135
# define ASN1_R_LENGTH_ERROR                              136
# define ASN1_R_LIST_ERROR                                188
# define ASN1_R_MIME_NO_CONTENT_TYPE                      206
# define ASN1_R_MIME_PARSE_ERROR                          207
# define ASN1_R_MIME_SIG_PARSE_ERROR                      208
# define ASN1_R_MISSING_EOC                               137
# define ASN1_R_MISSING_SECOND_NUMBER                     138
# define ASN1_R_MISSING_VALUE                             189
# define ASN1_R_MSTRING_NOT_UNIVERSAL                     139
# define ASN1_R_MSTRING_WRONG_TAG                         140
# define ASN1_R_NESTED_ASN1_STRING                        197
# define ASN1_R_NESTED_TOO_DEEP                           219
# define ASN1_R_NON_HEX_CHARACTERS                        141
# define ASN1_R_NOT_ASCII_FORMAT                          190
# define ASN1_R_NOT_ENOUGH_DATA                           142
# define ASN1_R_NO_CONTENT_TYPE                           209
# define ASN1_R_NO_DEFAULT_DIGEST                         201
# define ASN1_R_NO_MATCHING_CHOICE_TYPE                   143
# define ASN1_R_NO_MULTIPART_BODY_FAILURE                 210
# define ASN1_R_NO_MULTIPART_BOUNDARY                     211
# define ASN1_R_NO_SIG_CONTENT_TYPE                       212
# define ASN1_R_NULL_IS_WRONG_LENGTH                      144
# define ASN1_R_OBJECT_NOT_ASCII_FORMAT                   191
# define ASN1_R_ODD_NUMBER_OF_CHARS                       145
# define ASN1_R_PRIVATE_KEY_HEADER_MISSING                146
# define ASN1_R_SECOND_NUMBER_TOO_LARGE                   147
# define ASN1_R_SEQUENCE_LENGTH_MISMATCH                  148
# define ASN1_R_SEQUENCE_NOT_CONSTRUCTED                  149
# define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG              192
# define ASN1_R_SHORT_LINE                                150
# define ASN1_R_SIG_INVALID_MIME_TYPE                     213
# define ASN1_R_STREAMING_NOT_SUPPORTED                   202
# define ASN1_R_STRING_TOO_LONG                           151
# define ASN1_R_STRING_TOO_SHORT                          152
# define ASN1_R_TAG_VALUE_TOO_HIGH                        153
# define ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 154
# define ASN1_R_TIME_NOT_ASCII_FORMAT                     193
# define ASN1_R_TOO_LONG                                  155
# define ASN1_R_TYPE_NOT_CONSTRUCTED                      156
# define ASN1_R_TYPE_NOT_PRIMITIVE                        218
# define ASN1_R_UNABLE_TO_DECODE_RSA_KEY                  157
# define ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY          158
# define ASN1_R_UNEXPECTED_EOC                            159
# define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH           215
# define ASN1_R_UNKNOWN_FORMAT                            160
# define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM          161
# define ASN1_R_UNKNOWN_OBJECT_TYPE                       162
# define ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE                   163
# define ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM               199
# define ASN1_R_UNKNOWN_TAG                               194
# define ASN1_R_UNKOWN_FORMAT                             195
# define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE           164
# define ASN1_R_UNSUPPORTED_CIPHER                        165
# define ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM          166
# define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE               167
# define ASN1_R_UNSUPPORTED_TYPE                          196
# define ASN1_R_WRONG_PUBLIC_KEY_TYPE                     200
# define ASN1_R_WRONG_TAG                                 168
# define ASN1_R_WRONG_TYPE                                169

# ifdef  __cplusplus
}
# endif
#endif
openssl/modes.h000064400000020722151733316630007522 0ustar00/* ====================================================================
 * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
 *
 * Rights for redistribution and usage in source and binary
 * forms are granted according to the OpenSSL license.
 */

#include <stddef.h>

#ifdef  __cplusplus
extern "C" {
#endif
typedef void (*block128_f) (const unsigned char in[16],
                            unsigned char out[16], const void *key);

typedef void (*cbc128_f) (const unsigned char *in, unsigned char *out,
                          size_t len, const void *key,
                          unsigned char ivec[16], int enc);

typedef void (*ctr128_f) (const unsigned char *in, unsigned char *out,
                          size_t blocks, const void *key,
                          const unsigned char ivec[16]);

typedef void (*ccm128_f) (const unsigned char *in, unsigned char *out,
                          size_t blocks, const void *key,
                          const unsigned char ivec[16],
                          unsigned char cmac[16]);

void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out,
                           size_t len, const void *key,
                           unsigned char ivec[16], block128_f block);
void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out,
                           size_t len, const void *key,
                           unsigned char ivec[16], block128_f block);

void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out,
                           size_t len, const void *key,
                           unsigned char ivec[16],
                           unsigned char ecount_buf[16], unsigned int *num,
                           block128_f block);

void CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out,
                                 size_t len, const void *key,
                                 unsigned char ivec[16],
                                 unsigned char ecount_buf[16],
                                 unsigned int *num, ctr128_f ctr);

void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out,
                           size_t len, const void *key,
                           unsigned char ivec[16], int *num,
                           block128_f block);

void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out,
                           size_t len, const void *key,
                           unsigned char ivec[16], int *num,
                           int enc, block128_f block);
void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out,
                             size_t length, const void *key,
                             unsigned char ivec[16], int *num,
                             int enc, block128_f block);
void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out,
                             size_t bits, const void *key,
                             unsigned char ivec[16], int *num,
                             int enc, block128_f block);

size_t CRYPTO_cts128_encrypt_block(const unsigned char *in,
                                   unsigned char *out, size_t len,
                                   const void *key, unsigned char ivec[16],
                                   block128_f block);
size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out,
                             size_t len, const void *key,
                             unsigned char ivec[16], cbc128_f cbc);
size_t CRYPTO_cts128_decrypt_block(const unsigned char *in,
                                   unsigned char *out, size_t len,
                                   const void *key, unsigned char ivec[16],
                                   block128_f block);
size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out,
                             size_t len, const void *key,
                             unsigned char ivec[16], cbc128_f cbc);

size_t CRYPTO_nistcts128_encrypt_block(const unsigned char *in,
                                       unsigned char *out, size_t len,
                                       const void *key,
                                       unsigned char ivec[16],
                                       block128_f block);
size_t CRYPTO_nistcts128_encrypt(const unsigned char *in, unsigned char *out,
                                 size_t len, const void *key,
                                 unsigned char ivec[16], cbc128_f cbc);
size_t CRYPTO_nistcts128_decrypt_block(const unsigned char *in,
                                       unsigned char *out, size_t len,
                                       const void *key,
                                       unsigned char ivec[16],
                                       block128_f block);
size_t CRYPTO_nistcts128_decrypt(const unsigned char *in, unsigned char *out,
                                 size_t len, const void *key,
                                 unsigned char ivec[16], cbc128_f cbc);

typedef struct gcm128_context GCM128_CONTEXT;

GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block);
void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block);
void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const unsigned char *iv,
                         size_t len);
int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const unsigned char *aad,
                      size_t len);
int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx,
                          const unsigned char *in, unsigned char *out,
                          size_t len);
int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx,
                          const unsigned char *in, unsigned char *out,
                          size_t len);
int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx,
                                const unsigned char *in, unsigned char *out,
                                size_t len, ctr128_f stream);
int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx,
                                const unsigned char *in, unsigned char *out,
                                size_t len, ctr128_f stream);
int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const unsigned char *tag,
                         size_t len);
void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len);
void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx);

typedef struct ccm128_context CCM128_CONTEXT;

void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx,
                        unsigned int M, unsigned int L, void *key,
                        block128_f block);
int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx, const unsigned char *nonce,
                        size_t nlen, size_t mlen);
void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx, const unsigned char *aad,
                       size_t alen);
int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx, const unsigned char *inp,
                          unsigned char *out, size_t len);
int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx, const unsigned char *inp,
                          unsigned char *out, size_t len);
int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx, const unsigned char *inp,
                                unsigned char *out, size_t len,
                                ccm128_f stream);
int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx, const unsigned char *inp,
                                unsigned char *out, size_t len,
                                ccm128_f stream);
size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx, unsigned char *tag, size_t len);

typedef struct xts128_context XTS128_CONTEXT;

int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx,
                          const unsigned char iv[16],
                          const unsigned char *inp, unsigned char *out,
                          size_t len, int enc);

size_t CRYPTO_128_wrap(void *key, const unsigned char *iv,
                       unsigned char *out,
                       const unsigned char *in, size_t inlen,
                       block128_f block);

size_t CRYPTO_128_unwrap(void *key, const unsigned char *iv,
                         unsigned char *out,
                         const unsigned char *in, size_t inlen,
                         block128_f block);
size_t CRYPTO_128_wrap_pad(void *key, const unsigned char *icv,
                           unsigned char *out, const unsigned char *in,
                           size_t inlen, block128_f block);
size_t CRYPTO_128_unwrap_pad(void *key, const unsigned char *icv,
                             unsigned char *out, const unsigned char *in,
                             size_t inlen, block128_f block);

#ifdef  __cplusplus
}
#endif
openssl/rsa.h000064400000073275151733316630007213 0ustar00/* crypto/rsa/rsa.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#ifndef HEADER_RSA_H
# define HEADER_RSA_H

# include <openssl/asn1.h>

# ifndef OPENSSL_NO_BIO
#  include <openssl/bio.h>
# endif
# include <openssl/crypto.h>
# include <openssl/ossl_typ.h>
# ifndef OPENSSL_NO_DEPRECATED
#  include <openssl/bn.h>
# endif

# ifdef OPENSSL_NO_RSA
#  error RSA is disabled.
# endif

#ifdef  __cplusplus
extern "C" {
#endif

/* Declared already in ossl_typ.h */
/* typedef struct rsa_st RSA; */
/* typedef struct rsa_meth_st RSA_METHOD; */

struct rsa_meth_st {
    const char *name;
    int (*rsa_pub_enc) (int flen, const unsigned char *from,
                        unsigned char *to, RSA *rsa, int padding);
    int (*rsa_pub_dec) (int flen, const unsigned char *from,
                        unsigned char *to, RSA *rsa, int padding);
    int (*rsa_priv_enc) (int flen, const unsigned char *from,
                         unsigned char *to, RSA *rsa, int padding);
    int (*rsa_priv_dec) (int flen, const unsigned char *from,
                         unsigned char *to, RSA *rsa, int padding);
    /* Can be null */
    int (*rsa_mod_exp) (BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
    /* Can be null */
    int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
                       const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
    /* called at new */
    int (*init) (RSA *rsa);
    /* called at free */
    int (*finish) (RSA *rsa);
    /* RSA_METHOD_FLAG_* things */
    int flags;
    /* may be needed! */
    char *app_data;
    /*
     * New sign and verify functions: some libraries don't allow arbitrary
     * data to be signed/verified: this allows them to be used. Note: for
     * this to work the RSA_public_decrypt() and RSA_private_encrypt() should
     * *NOT* be used RSA_sign(), RSA_verify() should be used instead. Note:
     * for backwards compatibility this functionality is only enabled if the
     * RSA_FLAG_SIGN_VER option is set in 'flags'.
     */
    int (*rsa_sign) (int type,
                     const unsigned char *m, unsigned int m_length,
                     unsigned char *sigret, unsigned int *siglen,
                     const RSA *rsa);
    int (*rsa_verify) (int dtype, const unsigned char *m,
                       unsigned int m_length, const unsigned char *sigbuf,
                       unsigned int siglen, const RSA *rsa);
    /*
     * If this callback is NULL, the builtin software RSA key-gen will be
     * used. This is for behavioural compatibility whilst the code gets
     * rewired, but one day it would be nice to assume there are no such
     * things as "builtin software" implementations.
     */
    int (*rsa_keygen) (RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
};

struct rsa_st {
    /*
     * The first parameter is used to pickup errors where this is passed
     * instead of aEVP_PKEY, it is set to 0
     */
    int pad;
    long version;
    const RSA_METHOD *meth;
    /* functional reference if 'meth' is ENGINE-provided */
    ENGINE *engine;
    BIGNUM *n;
    BIGNUM *e;
    BIGNUM *d;
    BIGNUM *p;
    BIGNUM *q;
    BIGNUM *dmp1;
    BIGNUM *dmq1;
    BIGNUM *iqmp;
    /* be careful using this if the RSA structure is shared */
    CRYPTO_EX_DATA ex_data;
    int references;
    int flags;
    /* Used to cache montgomery values */
    BN_MONT_CTX *_method_mod_n;
    BN_MONT_CTX *_method_mod_p;
    BN_MONT_CTX *_method_mod_q;
    /*
     * all BIGNUM values are actually in the following data, if it is not
     * NULL
     */
    char *bignum_data;
    BN_BLINDING *blinding;
    BN_BLINDING *mt_blinding;
};

# ifndef OPENSSL_RSA_MAX_MODULUS_BITS
#  define OPENSSL_RSA_MAX_MODULUS_BITS   16384
# endif

# define OPENSSL_RSA_FIPS_MIN_MODULUS_BITS 1024

# ifndef OPENSSL_RSA_SMALL_MODULUS_BITS
#  define OPENSSL_RSA_SMALL_MODULUS_BITS 3072
# endif
# ifndef OPENSSL_RSA_MAX_PUBEXP_BITS

/* exponent limit enforced for "large" modulus only */
#  define OPENSSL_RSA_MAX_PUBEXP_BITS    64
# endif

# define RSA_3   0x3L
# define RSA_F4  0x10001L

# define RSA_METHOD_FLAG_NO_CHECK        0x0001/* don't check pub/private
                                                * match */

# define RSA_FLAG_CACHE_PUBLIC           0x0002
# define RSA_FLAG_CACHE_PRIVATE          0x0004
# define RSA_FLAG_BLINDING               0x0008
# define RSA_FLAG_THREAD_SAFE            0x0010
/*
 * This flag means the private key operations will be handled by rsa_mod_exp
 * and that they do not depend on the private key components being present:
 * for example a key stored in external hardware. Without this flag
 * bn_mod_exp gets called when private key components are absent.
 */
# define RSA_FLAG_EXT_PKEY               0x0020

/*
 * This flag in the RSA_METHOD enables the new rsa_sign, rsa_verify
 * functions.
 */
# define RSA_FLAG_SIGN_VER               0x0040

/*
 * new with 0.9.6j and 0.9.7b; the built-in
 * RSA implementation now uses blinding by
 * default (ignoring RSA_FLAG_BLINDING),
 * but other engines might not need it
 */
# define RSA_FLAG_NO_BLINDING            0x0080
/*
 * new with 0.9.8f; the built-in RSA
 * implementation now uses constant time
 * operations by default in private key operations,
 * e.g., constant time modular exponentiation,
 * modular inverse without leaking branches,
 * division without leaking branches. This
 * flag disables these constant time
 * operations and results in faster RSA
 * private key operations.
 */
# define RSA_FLAG_NO_CONSTTIME           0x0100
# ifdef OPENSSL_USE_DEPRECATED
/* deprecated name for the flag*/
/*
 * new with 0.9.7h; the built-in RSA
 * implementation now uses constant time
 * modular exponentiation for secret exponents
 * by default. This flag causes the
 * faster variable sliding window method to
 * be used for all exponents.
 */
#  define RSA_FLAG_NO_EXP_CONSTTIME RSA_FLAG_NO_CONSTTIME
# endif

# define EVP_PKEY_CTX_set_rsa_padding(ctx, pad) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, \
                                pad, NULL)

# define EVP_PKEY_CTX_get_rsa_padding(ctx, ppad) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, \
                                EVP_PKEY_CTRL_GET_RSA_PADDING, 0, ppad)

# define EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, len) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \
                                (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \
                                EVP_PKEY_CTRL_RSA_PSS_SALTLEN, \
                                len, NULL)

# define EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx, plen) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \
                                (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \
                                EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN, \
                                0, plen)

# define EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \
                                EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL)

# define EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp) \
        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \
                                EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pubexp)

# define  EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md)  \
                EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \
                        EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, \
                                EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)md)

# define  EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md)  \
                EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,  \
                                EVP_PKEY_CTRL_RSA_OAEP_MD, 0, (void *)md)

# define  EVP_PKEY_CTX_get_rsa_mgf1_md(ctx, pmd) \
                EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \
                        EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, \
                                EVP_PKEY_CTRL_GET_RSA_MGF1_MD, 0, (void *)pmd)

# define  EVP_PKEY_CTX_get_rsa_oaep_md(ctx, pmd) \
                EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,  \
                                EVP_PKEY_CTRL_GET_RSA_OAEP_MD, 0, (void *)pmd)

# define  EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, l, llen) \
                EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,  \
                                EVP_PKEY_CTRL_RSA_OAEP_LABEL, llen, (void *)l)

# define  EVP_PKEY_CTX_get0_rsa_oaep_label(ctx, l)       \
                EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,  \
                                EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL, 0, (void *)l)

# define EVP_PKEY_CTRL_RSA_PADDING       (EVP_PKEY_ALG_CTRL + 1)
# define EVP_PKEY_CTRL_RSA_PSS_SALTLEN   (EVP_PKEY_ALG_CTRL + 2)

# define EVP_PKEY_CTRL_RSA_KEYGEN_BITS   (EVP_PKEY_ALG_CTRL + 3)
# define EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP (EVP_PKEY_ALG_CTRL + 4)
# define EVP_PKEY_CTRL_RSA_MGF1_MD       (EVP_PKEY_ALG_CTRL + 5)

# define EVP_PKEY_CTRL_GET_RSA_PADDING           (EVP_PKEY_ALG_CTRL + 6)
# define EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN       (EVP_PKEY_ALG_CTRL + 7)
# define EVP_PKEY_CTRL_GET_RSA_MGF1_MD           (EVP_PKEY_ALG_CTRL + 8)

# define EVP_PKEY_CTRL_RSA_OAEP_MD       (EVP_PKEY_ALG_CTRL + 9)
# define EVP_PKEY_CTRL_RSA_OAEP_LABEL    (EVP_PKEY_ALG_CTRL + 10)

# define EVP_PKEY_CTRL_GET_RSA_OAEP_MD   (EVP_PKEY_ALG_CTRL + 11)
# define EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 12)

# define RSA_PKCS1_PADDING       1
# define RSA_SSLV23_PADDING      2
# define RSA_NO_PADDING          3
# define RSA_PKCS1_OAEP_PADDING  4
# define RSA_X931_PADDING        5
/* EVP_PKEY_ only */
# define RSA_PKCS1_PSS_PADDING   6

# define RSA_PKCS1_PADDING_SIZE  11

# define RSA_set_app_data(s,arg)         RSA_set_ex_data(s,0,arg)
# define RSA_get_app_data(s)             RSA_get_ex_data(s,0)

RSA *RSA_new(void);
RSA *RSA_new_method(ENGINE *engine);
int RSA_size(const RSA *rsa);

/* Deprecated version */
# ifndef OPENSSL_NO_DEPRECATED
RSA *RSA_generate_key(int bits, unsigned long e, void
                       (*callback) (int, int, void *), void *cb_arg);
# endif                         /* !defined(OPENSSL_NO_DEPRECATED) */

/* New version */
int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1,
                       BIGNUM *q2, const BIGNUM *Xp1, const BIGNUM *Xp2,
                       const BIGNUM *Xp, const BIGNUM *Xq1,
                       const BIGNUM *Xq2, const BIGNUM *Xq,
                       const BIGNUM *e, BN_GENCB *cb);
int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e,
                             BN_GENCB *cb);

int RSA_check_key(const RSA *);
        /* next 4 return -1 on error */
int RSA_public_encrypt(int flen, const unsigned char *from,
                       unsigned char *to, RSA *rsa, int padding);
int RSA_private_encrypt(int flen, const unsigned char *from,
                        unsigned char *to, RSA *rsa, int padding);
int RSA_public_decrypt(int flen, const unsigned char *from,
                       unsigned char *to, RSA *rsa, int padding);
int RSA_private_decrypt(int flen, const unsigned char *from,
                        unsigned char *to, RSA *rsa, int padding);
void RSA_free(RSA *r);
/* "up" the RSA object's reference count */
int RSA_up_ref(RSA *r);

int RSA_flags(const RSA *r);

void RSA_set_default_method(const RSA_METHOD *meth);
const RSA_METHOD *RSA_get_default_method(void);
const RSA_METHOD *RSA_get_method(const RSA *rsa);
int RSA_set_method(RSA *rsa, const RSA_METHOD *meth);

/* This function needs the memory locking malloc callbacks to be installed */
int RSA_memory_lock(RSA *r);

/* these are the actual SSLeay RSA functions */
const RSA_METHOD *RSA_PKCS1_SSLeay(void);

const RSA_METHOD *RSA_null_method(void);

DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPublicKey)
DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPrivateKey)

typedef struct rsa_pss_params_st {
    X509_ALGOR *hashAlgorithm;
    X509_ALGOR *maskGenAlgorithm;
    ASN1_INTEGER *saltLength;
    ASN1_INTEGER *trailerField;
} RSA_PSS_PARAMS;

DECLARE_ASN1_FUNCTIONS(RSA_PSS_PARAMS)

typedef struct rsa_oaep_params_st {
    X509_ALGOR *hashFunc;
    X509_ALGOR *maskGenFunc;
    X509_ALGOR *pSourceFunc;
} RSA_OAEP_PARAMS;

DECLARE_ASN1_FUNCTIONS(RSA_OAEP_PARAMS)

# ifndef OPENSSL_NO_FP_API
int RSA_print_fp(FILE *fp, const RSA *r, int offset);
# endif

# ifndef OPENSSL_NO_BIO
int RSA_print(BIO *bp, const RSA *r, int offset);
# endif

# ifndef OPENSSL_NO_RC4
int i2d_RSA_NET(const RSA *a, unsigned char **pp,
                int (*cb) (char *buf, int len, const char *prompt,
                           int verify), int sgckey);
RSA *d2i_RSA_NET(RSA **a, const unsigned char **pp, long length,
                 int (*cb) (char *buf, int len, const char *prompt,
                            int verify), int sgckey);

int i2d_Netscape_RSA(const RSA *a, unsigned char **pp,
                     int (*cb) (char *buf, int len, const char *prompt,
                                int verify));
RSA *d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length,
                      int (*cb) (char *buf, int len, const char *prompt,
                                 int verify));
# endif

/*
 * The following 2 functions sign and verify a X509_SIG ASN1 object inside
 * PKCS#1 padded RSA encryption
 */
int RSA_sign(int type, const unsigned char *m, unsigned int m_length,
             unsigned char *sigret, unsigned int *siglen, RSA *rsa);
int RSA_verify(int type, const unsigned char *m, unsigned int m_length,
               const unsigned char *sigbuf, unsigned int siglen, RSA *rsa);

/*
 * The following 2 function sign and verify a ASN1_OCTET_STRING object inside
 * PKCS#1 padded RSA encryption
 */
int RSA_sign_ASN1_OCTET_STRING(int type,
                               const unsigned char *m, unsigned int m_length,
                               unsigned char *sigret, unsigned int *siglen,
                               RSA *rsa);
int RSA_verify_ASN1_OCTET_STRING(int type, const unsigned char *m,
                                 unsigned int m_length, unsigned char *sigbuf,
                                 unsigned int siglen, RSA *rsa);

int RSA_blinding_on(RSA *rsa, BN_CTX *ctx);
void RSA_blinding_off(RSA *rsa);
BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *ctx);

int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen,
                                 const unsigned char *f, int fl);
int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen,
                                   const unsigned char *f, int fl,
                                   int rsa_len);
int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen,
                                 const unsigned char *f, int fl);
int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen,
                                   const unsigned char *f, int fl,
                                   int rsa_len);
int PKCS1_MGF1(unsigned char *mask, long len, const unsigned char *seed,
               long seedlen, const EVP_MD *dgst);
int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
                               const unsigned char *f, int fl,
                               const unsigned char *p, int pl);
int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
                                 const unsigned char *f, int fl, int rsa_len,
                                 const unsigned char *p, int pl);
int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
                                    const unsigned char *from, int flen,
                                    const unsigned char *param, int plen,
                                    const EVP_MD *md, const EVP_MD *mgf1md);
int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
                                      const unsigned char *from, int flen,
                                      int num, const unsigned char *param,
                                      int plen, const EVP_MD *md,
                                      const EVP_MD *mgf1md);
int RSA_padding_add_SSLv23(unsigned char *to, int tlen,
                           const unsigned char *f, int fl);
int RSA_padding_check_SSLv23(unsigned char *to, int tlen,
                             const unsigned char *f, int fl, int rsa_len);
int RSA_padding_add_none(unsigned char *to, int tlen, const unsigned char *f,
                         int fl);
int RSA_padding_check_none(unsigned char *to, int tlen,
                           const unsigned char *f, int fl, int rsa_len);
int RSA_padding_add_X931(unsigned char *to, int tlen, const unsigned char *f,
                         int fl);
int RSA_padding_check_X931(unsigned char *to, int tlen,
                           const unsigned char *f, int fl, int rsa_len);
int RSA_X931_hash_id(int nid);

int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash,
                         const EVP_MD *Hash, const unsigned char *EM,
                         int sLen);
int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM,
                              const unsigned char *mHash, const EVP_MD *Hash,
                              int sLen);

int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash,
                              const EVP_MD *Hash, const EVP_MD *mgf1Hash,
                              const unsigned char *EM, int sLen);

int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
                                   const unsigned char *mHash,
                                   const EVP_MD *Hash, const EVP_MD *mgf1Hash,
                                   int sLen);

int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
                         CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
int RSA_set_ex_data(RSA *r, int idx, void *arg);
void *RSA_get_ex_data(const RSA *r, int idx);

RSA *RSAPublicKey_dup(RSA *rsa);
RSA *RSAPrivateKey_dup(RSA *rsa);

/*
 * If this flag is set the RSA method is FIPS compliant and can be used in
 * FIPS mode. This is set in the validated module method. If an application
 * sets this flag in its own methods it is its responsibility to ensure the
 * result is compliant.
 */

# define RSA_FLAG_FIPS_METHOD                    0x0400

/*
 * If this flag is set the operations normally disabled in FIPS mode are
 * permitted it is then the applications responsibility to ensure that the
 * usage is compliant.
 */

# define RSA_FLAG_NON_FIPS_ALLOW                 0x0400
/*
 * Application has decided PRNG is good enough to generate a key: don't
 * check.
 */
# define RSA_FLAG_CHECKED                        0x0800

/* BEGIN ERROR CODES */
/*
 * The following lines are auto generated by the script mkerr.pl. Any changes
 * made after this point may be overwritten when the script is next run.
 */
void ERR_load_RSA_strings(void);

/* Error codes for the RSA functions. */

/* Function codes. */
# define RSA_F_CHECK_PADDING_MD                           140
# define RSA_F_DO_RSA_PRINT                               146
# define RSA_F_INT_RSA_VERIFY                             145
# define RSA_F_MEMORY_LOCK                                100
# define RSA_F_OLD_RSA_PRIV_DECODE                        147
# define RSA_F_PKEY_RSA_CTRL                              143
# define RSA_F_PKEY_RSA_CTRL_STR                          144
# define RSA_F_PKEY_RSA_SIGN                              142
# define RSA_F_PKEY_RSA_VERIFY                            154
# define RSA_F_PKEY_RSA_VERIFYRECOVER                     141
# define RSA_F_RSA_ALGOR_TO_MD                            157
# define RSA_F_RSA_BUILTIN_KEYGEN                         129
# define RSA_F_RSA_CHECK_KEY                              123
# define RSA_F_RSA_CMS_DECRYPT                            258
# define RSA_F_RSA_EAY_PRIVATE_DECRYPT                    101
# define RSA_F_RSA_EAY_PRIVATE_ENCRYPT                    102
# define RSA_F_RSA_EAY_PUBLIC_DECRYPT                     103
# define RSA_F_RSA_EAY_PUBLIC_ENCRYPT                     104
# define RSA_F_RSA_GENERATE_KEY                           105
# define RSA_F_RSA_GENERATE_KEY_EX                        155
# define RSA_F_RSA_ITEM_VERIFY                            156
# define RSA_F_RSA_MEMORY_LOCK                            130
# define RSA_F_RSA_MGF1_TO_MD                             159
# define RSA_F_RSA_NEW_METHOD                             106
# define RSA_F_RSA_NULL                                   124
# define RSA_F_RSA_NULL_MOD_EXP                           131
# define RSA_F_RSA_NULL_PRIVATE_DECRYPT                   132
# define RSA_F_RSA_NULL_PRIVATE_ENCRYPT                   133
# define RSA_F_RSA_NULL_PUBLIC_DECRYPT                    134
# define RSA_F_RSA_NULL_PUBLIC_ENCRYPT                    135
# define RSA_F_RSA_PADDING_ADD_NONE                       107
# define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP                 121
# define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1            160
# define RSA_F_RSA_PADDING_ADD_PKCS1_PSS                  125
# define RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1             158
# define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1               108
# define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2               109
# define RSA_F_RSA_PADDING_ADD_SSLV23                     110
# define RSA_F_RSA_PADDING_ADD_X931                       127
# define RSA_F_RSA_PADDING_CHECK_NONE                     111
# define RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP               122
# define RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1          161
# define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1             112
# define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2             113
# define RSA_F_RSA_PADDING_CHECK_SSLV23                   114
# define RSA_F_RSA_PADDING_CHECK_X931                     128
# define RSA_F_RSA_PRINT                                  115
# define RSA_F_RSA_PRINT_FP                               116
# define RSA_F_RSA_PRIVATE_DECRYPT                        157
# define RSA_F_RSA_PRIVATE_ENCRYPT                        148
# define RSA_F_RSA_PRIV_DECODE                            137
# define RSA_F_RSA_PRIV_ENCODE                            138
# define RSA_F_RSA_PSS_TO_CTX                             162
# define RSA_F_RSA_PUBLIC_DECRYPT                         149
# define RSA_F_RSA_PUBLIC_ENCRYPT                         153
# define RSA_F_RSA_PUB_DECODE                             139
# define RSA_F_RSA_SETUP_BLINDING                         136
# define RSA_F_RSA_SET_DEFAULT_METHOD                     150
# define RSA_F_RSA_SET_METHOD                             151
# define RSA_F_RSA_SIGN                                   117
# define RSA_F_RSA_SIGN_ASN1_OCTET_STRING                 118
# define RSA_F_RSA_VERIFY                                 119
# define RSA_F_RSA_VERIFY_ASN1_OCTET_STRING               120
# define RSA_F_RSA_VERIFY_PKCS1_PSS                       126
# define RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1                  152

/* Reason codes. */
# define RSA_R_ALGORITHM_MISMATCH                         100
# define RSA_R_BAD_E_VALUE                                101
# define RSA_R_BAD_FIXED_HEADER_DECRYPT                   102
# define RSA_R_BAD_PAD_BYTE_COUNT                         103
# define RSA_R_BAD_SIGNATURE                              104
# define RSA_R_BLOCK_TYPE_IS_NOT_01                       106
# define RSA_R_BLOCK_TYPE_IS_NOT_02                       107
# define RSA_R_DATA_GREATER_THAN_MOD_LEN                  108
# define RSA_R_DATA_TOO_LARGE                             109
# define RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE                110
# define RSA_R_DATA_TOO_LARGE_FOR_MODULUS                 132
# define RSA_R_DATA_TOO_SMALL                             111
# define RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE                122
# define RSA_R_DIGEST_DOES_NOT_MATCH                      166
# define RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY                 112
# define RSA_R_DMP1_NOT_CONGRUENT_TO_D                    124
# define RSA_R_DMQ1_NOT_CONGRUENT_TO_D                    125
# define RSA_R_D_E_NOT_CONGRUENT_TO_1                     123
# define RSA_R_FIRST_OCTET_INVALID                        133
# define RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE        144
# define RSA_R_INVALID_DIGEST                             160
# define RSA_R_INVALID_DIGEST_LENGTH                      143
# define RSA_R_INVALID_HEADER                             137
# define RSA_R_INVALID_KEYBITS                            145
# define RSA_R_INVALID_LABEL                              161
# define RSA_R_INVALID_MESSAGE_LENGTH                     131
# define RSA_R_INVALID_MGF1_MD                            156
# define RSA_R_INVALID_OAEP_PARAMETERS                    162
# define RSA_R_INVALID_PADDING                            138
# define RSA_R_INVALID_PADDING_MODE                       141
# define RSA_R_INVALID_PSS_PARAMETERS                     157
# define RSA_R_INVALID_PSS_SALTLEN                        146
# define RSA_R_INVALID_SALT_LENGTH                        158
# define RSA_R_INVALID_TRAILER                            139
# define RSA_R_INVALID_X931_DIGEST                        142
# define RSA_R_IQMP_NOT_INVERSE_OF_Q                      126
# define RSA_R_KEY_SIZE_TOO_SMALL                         120
# define RSA_R_LAST_OCTET_INVALID                         134
# define RSA_R_MODULUS_TOO_LARGE                          105
# define RSA_R_NON_FIPS_RSA_METHOD                        149
# define RSA_R_NON_FIPS_METHOD                            149
# define RSA_R_NO_PUBLIC_EXPONENT                         140
# define RSA_R_NULL_BEFORE_BLOCK_MISSING                  113
# define RSA_R_N_DOES_NOT_EQUAL_P_Q                       127
# define RSA_R_OAEP_DECODING_ERROR                        121
# define RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE         150
# define RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE   148
# define RSA_R_PADDING_CHECK_FAILED                       114
# define RSA_R_PKCS_DECODING_ERROR                        159
# define RSA_R_P_NOT_PRIME                                128
# define RSA_R_Q_NOT_PRIME                                129
# define RSA_R_RSA_OPERATIONS_NOT_SUPPORTED               130
# define RSA_R_SLEN_CHECK_FAILED                          136
# define RSA_R_SLEN_RECOVERY_FAILED                       135
# define RSA_R_SSLV3_ROLLBACK_ATTACK                      115
# define RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 116
# define RSA_R_UNKNOWN_ALGORITHM_TYPE                     117
# define RSA_R_UNKNOWN_DIGEST                             163
# define RSA_R_UNKNOWN_MASK_DIGEST                        151
# define RSA_R_UNKNOWN_PADDING_TYPE                       118
# define RSA_R_UNKNOWN_PSS_DIGEST                         152
# define RSA_R_UNSUPPORTED_ENCRYPTION_TYPE                164
# define RSA_R_UNSUPPORTED_LABEL_SOURCE                   165
# define RSA_R_UNSUPPORTED_MASK_ALGORITHM                 153
# define RSA_R_UNSUPPORTED_MASK_PARAMETER                 154
# define RSA_R_UNSUPPORTED_SIGNATURE_TYPE                 155
# define RSA_R_VALUE_MISSING                              147
# define RSA_R_WRONG_SIGNATURE_LENGTH                     119

#ifdef  __cplusplus
}
#endif
#endif
openssl/rc4.h000064400000007337151733316630007112 0ustar00/* crypto/rc4/rc4.h */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#ifndef HEADER_RC4_H
# define HEADER_RC4_H

# include <openssl/opensslconf.h>/* OPENSSL_NO_RC4, RC4_INT */
# ifdef OPENSSL_NO_RC4
#  error RC4 is disabled.
# endif

# include <stddef.h>

#ifdef  __cplusplus
extern "C" {
#endif

typedef struct rc4_key_st {
    RC4_INT x, y;
    RC4_INT data[256];
} RC4_KEY;

const char *RC4_options(void);
void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data);
void private_RC4_set_key(RC4_KEY *key, int len, const unsigned char *data);
void RC4(RC4_KEY *key, size_t len, const unsigned char *indata,
         unsigned char *outdata);

#ifdef  __cplusplus
}
#endif

#endif