X-Git-Url: http://git.indexdata.com/?p=idzebra-moved-to-github.git;a=blobdiff_plain;f=include%2Fidzebra%2Fapi.h;h=88d9fecd334761e1fd07f9f8bbdf9d3f36273965;hp=d3a9d4b36c17b0ecdc7687652309771c0de6f0e6;hb=c944571888712854653be0d2debf903b8651c8e2;hpb=004bd919116b88cd6dfd0594de51bde7d62296be diff --git a/include/idzebra/api.h b/include/idzebra/api.h index d3a9d4b..88d9fec 100644 --- a/include/idzebra/api.h +++ b/include/idzebra/api.h @@ -1,4 +1,4 @@ -/* $Id: api.h,v 1.16 2005-03-17 08:31:53 adam Exp $ +/* $Id: api.h,v 1.31 2005-12-09 11:33:32 adam Exp $ Copyright (C) 1995-2005 Index Data ApS @@ -24,9 +24,8 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA \brief Zebra API Return codes: - Most functions return an int. Unix-like, 0 means OK, - non-zero means an error. The error info should be available - via zebra_errCode and friends. + Most functions return ZEBRA_RES, where ZEBRA_FAIL indicates + failure; ZEBRA_OK indicates success. */ #ifndef IDZEBRA_API_H @@ -49,7 +48,7 @@ typedef struct { long stime; } ZebraTransactionStatus; -/* Retrieval Record Descriptor */ +/** Retrieval Record Descriptor */ typedef struct { int errCode; /* non-zero if error when fetching this */ char *errString; /* error string */ @@ -62,7 +61,7 @@ typedef struct { int score; } ZebraRetrievalRecord; -/* Scan Term Descriptor */ +/** Scan Term Descriptor */ typedef struct { int occurrences; /* scan term occurrences */ char *term; /* scan term string */ @@ -84,10 +83,11 @@ typedef struct zebra_service *ZebraService; This function is a simplified version of zebra_start_res. */ -YAZ_EXPORT ZebraService zebra_start(const char *configName); +YAZ_EXPORT +ZebraService zebra_start(const char *configName); -/** \fn ZebraService zebra_start_res(const char *configName, - Res def_res, Res over_res) +/** \fn ZebraService zebra_start_res(const char *configName, \ + Res def_res, Res over_res) \brief starts a Zebra service with resources. \param configName name of configuration file \param def_res default resources @@ -100,88 +100,97 @@ YAZ_EXPORT ZebraService zebra_start_res(const char *configName, Res def_res, Res over_res); -/** \fn int zebra_stop(ZebraService zs) - \brief stops a Zebra service. - \param zs service handle - - Frees resources used by the service. +/** + \brief stops a Zebra service. + \param zs service handle + + Frees resources used by the service. */ YAZ_EXPORT -int zebra_stop(ZebraService zs); +ZEBRA_RES zebra_stop(ZebraService zs); -/** \fn void zebra_filter_info(ZebraService zs, void *cd, - void(*cb)(void *cd, const char *name)) - \brief lists enabled Zebra filters - \param zs service handle - \param cd callback parameter (opaque) - \param cb callback function +/** + \brief Lists enabled Zebra filters + \param zs service handle + \param cd callback parameter (opaque) + \param cb callback function */ YAZ_EXPORT void zebra_filter_info(ZebraService zs, void *cd, void (*cb)(void *cd, const char *name)); -/** \fn ZebraHandle zebra_open(ZebraService zs) - \brief creates a Zebra session handle within service. - \param zs service handle. - - There should be one handle for each thread doing something - with zebra, be that searching or indexing. In simple apps - one handle is sufficient +/** + \brief Creates a Zebra session handle within service. + \param zs service handle. + + There should be one handle for each thread doing something + with zebra, be that searching or indexing. In simple apps + one handle is sufficient */ -YAZ_EXPORT ZebraHandle zebra_open(ZebraService zs); +YAZ_EXPORT +ZebraHandle zebra_open(ZebraService zs, Res res); -/** \fn int zebra_close(ZebraHandle zh) - \brief destroys Zebra session handle. - \param zh zebra session handle. +/** + \brief Destroys Zebra session handle. + \param zh zebra session handle. */ -YAZ_EXPORT int zebra_close(ZebraHandle zh); +YAZ_EXPORT +ZEBRA_RES zebra_close(ZebraHandle zh); -/** \fn int zebra_errCode(ZebraHandle zh) - \brief returns error code for last error - \param zh zebra session handle. +/** + \brief Returns error code for last error + \param zh zebra session handle. */ -YAZ_EXPORT int zebra_errCode(ZebraHandle zh); +YAZ_EXPORT +int zebra_errCode(ZebraHandle zh); -/** \fn const char *zebra_errString(ZebraHandle zh) - \brief returns error string for last error - \param zh zebra session handle. +/** + \brief Returns error string for last error + \param zh zebra session handle. */ -YAZ_EXPORT const char *zebra_errString(ZebraHandle zh); +YAZ_EXPORT +const char *zebra_errString(ZebraHandle zh); -/** \fn char *zebra_errAdd(ZebraHandle zh) - \brief returns additional info for last error - \param zh zebra session handle. +/** + \brief Returns additional info for last error + \param zh zebra session handle. */ -YAZ_EXPORT char *zebra_errAdd(ZebraHandle zh); +YAZ_EXPORT +char *zebra_errAdd(ZebraHandle zh); -/** \fn int zebra_result(ZebraHandle zh, int *code, char **addinfo) - \brief returns error code and additional info for last error - \param zh zebra session handle. - \param code pointer to returned error code - \param addinfo pointer to returned additional info +/** + \brief Returns error code and additional info for last error + \param zh zebra session handle. + \param code pointer to returned error code + \param addinfo pointer to returned additional info */ -YAZ_EXPORT int zebra_result(ZebraHandle zh, int *code, char **addinfo); +YAZ_EXPORT +void zebra_result(ZebraHandle zh, int *code, char **addinfo); -/** \fn void zebra_clearError(ZebraHandle zh) - \brief clears last error. - \param zh zebra session handle. - */ -YAZ_EXPORT void zebra_clearError(ZebraHandle zh); +/** + \brief Set limit before Zebra does approx hit count + \param zh session handle + \param approx_limit the limit + + Results will be approximiate if hit count is greater than the + limit specified. By default there is a high-limit (no limit). +*/ +ZEBRA_RES zebra_set_approx_limit(ZebraHandle zh, zint approx_limit); -/** \fn int zebra_search_PQF(ZebraHandle zh, const char *pqf_query, - const char *setname, int *hits) - \brief Search using PQF Query - \param zh session handle - \param pqf_query query - \param setname name of resultset - \param hits of hits is returned +/** + \brief Search using PQF Query + \param zh session handle + \param pqf_query query + \param setname name of resultset + \param hits of hits is returned */ -YAZ_EXPORT int zebra_search_PQF(ZebraHandle zh, const char *pqf_query, - const char *setname, zint *hits); +YAZ_EXPORT +ZEBRA_RES zebra_search_PQF(ZebraHandle zh, const char *pqf_query, + const char *setname, zint *hits); -/** \fn int zebra_search_RPN(ZebraHandle zh, ODR o, Z_RPNQuery *query, - const char *setname, zint *hits) +/** \fn ZEBRA_RES zebra_search_RPN(ZebraHandle zh, ODR o, Z_RPNQuery *query, \ + const char *setname, zint *hits) \brief Search using RPN Query \param zh session handle \param o ODR handle @@ -189,14 +198,16 @@ YAZ_EXPORT int zebra_search_PQF(ZebraHandle zh, const char *pqf_query, \param setname name of resultset \param hits number of hits is returned */ -YAZ_EXPORT int zebra_search_RPN(ZebraHandle zh, ODR o, Z_RPNQuery *query, - const char *setname, zint *hits); +YAZ_EXPORT +ZEBRA_RES zebra_search_RPN(ZebraHandle zh, ODR o, Z_RPNQuery *query, + const char *setname, zint *hits); /** - \fn int zebra_records_retrieve(ZebraHandle zh, ODR stream, - const char *setname, Z_RecordComposition *comp, oid_value input_format, - int num_recs, ZebraRetrievalRecord *recs) - \brief retrieve records from result set (after search) + \fn ZEBRA_RES zebra_records_retrieve(ZebraHandle zh, ODR stream, \ + const char *setname, Z_RecordComposition *comp, \ + oid_value input_format, int num_recs, \ + ZebraRetrievalRecord *recs) + \brief Retrieve records from result set (after search) \param zh session handle \param stream allocate records returned using this ODR \param setname name of result set to retrieve records from @@ -205,30 +216,68 @@ YAZ_EXPORT int zebra_search_RPN(ZebraHandle zh, ODR o, Z_RPNQuery *query, \param num_recs number of records to retrieve \param recs store records in this structure (size is num_recs) */ -YAZ_EXPORT int zebra_records_retrieve(ZebraHandle zh, ODR stream, - const char *setname, Z_RecordComposition *comp, - oid_value input_format, - int num_recs, ZebraRetrievalRecord *recs); - +YAZ_EXPORT +ZEBRA_RES zebra_records_retrieve(ZebraHandle zh, ODR stream, + const char *setname, + Z_RecordComposition *comp, + oid_value input_format, + int num_recs, + ZebraRetrievalRecord *recs); /** - \fn int zebra_deleteResultSet(ZebraHandle zh, int function, - int num_setnames, char **setnames, int *statuses) - \brief delete one or more resultsets + \brief Deletes one or more resultsets \param zh session handle \param function Z_DeleteResultSetRequest_{list,all} \param num_setnames number of result sets \param setnames result set names \param statuses status result */ -YAZ_EXPORT int zebra_deleteResultSet(ZebraHandle zh, int function, - int num_setnames, char **setnames, - int *statuses); +YAZ_EXPORT +int zebra_deleteResultSet(ZebraHandle zh, int function, + int num_setnames, char **setnames, + int *statuses); + + +/** + \brief returns number of term info terms assocaited with result set + \param zh session handle + \param setname result set name + \param num_terms number of terms returned in this integer + + This function is used in conjunction with zebra_result_set_term_info. + If operation was successful, ZEBRA_OK is returned; otherwise + ZEBRA_FAIL is returned (typically non-existing setname) +*/ +YAZ_EXPORT +ZEBRA_RES zebra_result_set_term_no(ZebraHandle zh, const char *setname, + int *num_terms); + +/** + \brief returns information about a term assocated with a result set + \param zh session handle + \param setname result set name + \param no the term we want to know about (0=first, 1=second,..) + \param count the number of occurrences of this term, aka hits (output) + \param approx about hits: 0=exact,1=approx (output) + \param termbuf buffer for term string (intput, output) + \param termlen size of termbuf (input=max, output=actual length) + \param term_ref_id if non-NULL *term_ref_id holds term reference + + Returns information about one search term associated with result set. + Use zebra_result_set_term_no to read total number of terms associated + with result set. If this function can not return information, + due to no out of range or bad result set name, ZEBRA_FAIL is + returned. + The passed termbuf must be able to hold at least *termlen characters. + Upon completion, *termlen holds actual length of search term. +*/ +YAZ_EXPORT +ZEBRA_RES zebra_result_set_term_info(ZebraHandle zh, const char *setname, + int no, zint *count, int *approx, + char *termbuf, size_t *termlen, + const char **term_ref_id); /** - \fn int zebra_scan(ZebraHandle zh, ODR stream, - Z_AttributesPlusTerm *zapt, oid_value attributeset, - int *position, int *num_entries, ZebraScanEntry **list, int *is_partial) \brief performs Scan (Z39.50 style) \param zh session handle \param stream ODR handle for result @@ -236,32 +285,45 @@ YAZ_EXPORT int zebra_deleteResultSet(ZebraHandle zh, int function, \param attributeset Attributeset for Attribute plus Term \param position input/output position \param num_entries number of terms requested / returned - \param list list of resulting terms (ODR allocated) + \param entries list of resulting terms (ODR allocated) \param is_partial upon return 1=partial, 0=complete + \param setname limit scan by this set (NULL means no limit) */ -YAZ_EXPORT int zebra_scan(ZebraHandle zh, ODR stream, - Z_AttributesPlusTerm *zapt, - oid_value attributeset, - int *position, int *num_entries, - ZebraScanEntry **list, - int *is_partial); - - +YAZ_EXPORT ZEBRA_RES zebra_scan(ZebraHandle zh, ODR stream, + Z_AttributesPlusTerm *zapt, + oid_value attributeset, + int *position, int *num_entries, + ZebraScanEntry **entries, + int *is_partial, + const char *setname); + +/** + \brief performs Scan (taking PQF string) + \param zh session handle + \param stream ODR handle for result + \param query PQF scan query + \param position input/output position + \param num_entries number of terms requested / returned + \param entries list of resulting terms (ODR allocated) + \param is_partial upon return 1=partial, 0=complete + \param setname limit scan by this set (NULL means no limit) +*/ +YAZ_EXPORT +ZEBRA_RES zebra_scan_PQF(ZebraHandle zh, ODR stream, const char *query, + int *position, int *num_entries, ZebraScanEntry **entries, + int *is_partial, const char *setname); + /** - \fn int zebra_auth(ZebraHandle zh, const char *user, const char *pass) \brief authenticate user. Returns 0 if OK, != 0 on failure \param zh session handle \param user user name \param pass password */ -YAZ_EXPORT int zebra_auth(ZebraHandle zh, const char *user, const char *pass); - +YAZ_EXPORT +ZEBRA_RES zebra_auth(ZebraHandle zh, const char *user, const char *pass); /** - \fn int zebra_string_norm(ZebraHandle zh, unsigned reg_id, - const char *input_str, int input_len, - char *output_str, int output_len) - \brief normalize zebra term for register (subject to change!) + \brief Normalize zebra term for register (subject to change!) \param zh session handle \param reg_id register ID, 'w', 'p',.. \param input_str input string buffer @@ -269,118 +331,139 @@ YAZ_EXPORT int zebra_auth(ZebraHandle zh, const char *user, const char *pass); \param output_str output string buffer \param output_len output string length */ -YAZ_EXPORT int zebra_string_norm(ZebraHandle zh, unsigned reg_id, - const char *input_str, int input_len, - char *output_str, int output_len); +YAZ_EXPORT +int zebra_string_norm(ZebraHandle zh, unsigned reg_id, const char *input_str, + int input_len, char *output_str, int output_len); /** - \fn int zebra_create_database(ZebraHandle zh, const char *db) - \brief creates a database + \brief Creates a database \param zh session handle \param db database to be created */ -YAZ_EXPORT int zebra_create_database(ZebraHandle zh, const char *db); +YAZ_EXPORT +ZEBRA_RES zebra_create_database(ZebraHandle zh, const char *db); /** - \fn int zebra_drop_database(ZebraHandle zh, const char *db) - \brief deletes a database (drop) + \brief Deletes a database (drop) \param zh session handle \param db database to be deleted */ -YAZ_EXPORT int zebra_drop_database(ZebraHandle zh, const char *db); +YAZ_EXPORT +ZEBRA_RES zebra_drop_database(ZebraHandle zh, const char *db); -YAZ_EXPORT int zebra_admin_shutdown(ZebraHandle zh); -YAZ_EXPORT int zebra_admin_start(ZebraHandle zh); +YAZ_EXPORT +ZEBRA_RES zebra_admin_shutdown(ZebraHandle zh); -YAZ_EXPORT int zebra_shutdown(ZebraService zs); +YAZ_EXPORT +ZEBRA_RES zebra_admin_start(ZebraHandle zh); -YAZ_EXPORT int zebra_admin_import_begin(ZebraHandle zh, const char *database, - const char *record_type); +YAZ_EXPORT +ZEBRA_RES zebra_shutdown(ZebraService zs); -YAZ_EXPORT int zebra_admin_import_segment(ZebraHandle zh, - Z_Segment *segment); +YAZ_EXPORT +ZEBRA_RES zebra_admin_import_begin(ZebraHandle zh, const char *database, + const char *record_type); -YAZ_EXPORT int zebra_admin_import_end(ZebraHandle zh); +YAZ_EXPORT +ZEBRA_RES zebra_admin_import_segment(ZebraHandle zh, + Z_Segment *segment); -YAZ_EXPORT int zebra_admin_exchange_record(ZebraHandle zh, - const char *rec_buf, - size_t rec_len, - const char *recid_buf, size_t recid_len, - int action); +YAZ_EXPORT +ZEBRA_RES zebra_admin_import_end(ZebraHandle zh); -YAZ_EXPORT int zebra_begin_trans(ZebraHandle zh, int rw); -YAZ_EXPORT int zebra_end_trans(ZebraHandle zh); -YAZ_EXPORT int zebra_end_transaction(ZebraHandle zh, ZebraTransactionStatus *stat); +YAZ_EXPORT +ZEBRA_RES zebra_admin_exchange_record(ZebraHandle zh, + const char *rec_buf, + size_t rec_len, + const char *recid_buf, size_t recid_len, + int action); -YAZ_EXPORT int zebra_commit(ZebraHandle zh); -YAZ_EXPORT int zebra_clean(ZebraHandle zh); +YAZ_EXPORT +ZEBRA_RES zebra_begin_trans(ZebraHandle zh, int rw); + +YAZ_EXPORT +ZEBRA_RES zebra_end_trans(ZebraHandle zh); + +YAZ_EXPORT +ZEBRA_RES zebra_end_transaction(ZebraHandle zh, + ZebraTransactionStatus *stat); + +YAZ_EXPORT +ZEBRA_RES zebra_commit(ZebraHandle zh); + +YAZ_EXPORT +ZEBRA_RES zebra_clean(ZebraHandle zh); + +YAZ_EXPORT +ZEBRA_RES zebra_init(ZebraHandle zh); + +YAZ_EXPORT +ZEBRA_RES zebra_compact(ZebraHandle zh); -YAZ_EXPORT int zebra_init(ZebraHandle zh); -YAZ_EXPORT int zebra_compact(ZebraHandle zh); YAZ_EXPORT int zebra_repository_update(ZebraHandle zh, const char *path); YAZ_EXPORT int zebra_repository_delete(ZebraHandle zh, const char *path); YAZ_EXPORT int zebra_repository_show(ZebraHandle zh, const char *path); YAZ_EXPORT int zebra_add_record(ZebraHandle zh, const char *buf, int buf_size); -YAZ_EXPORT int zebra_insert_record(ZebraHandle zh, - const char *recordType, - SYSNO *sysno, const char *match, const char *fname, - const char *buf, int buf_size, - int force_update); -YAZ_EXPORT int zebra_update_record(ZebraHandle zh, - const char *recordType, - SYSNO *sysno, const char *match, const char *fname, - const char *buf, int buf_size, - int force_update); -YAZ_EXPORT int zebra_delete_record(ZebraHandle zh, - const char *recordType, - SYSNO *sysno, const char *match, const char *fname, - const char *buf, int buf_size, - int force_update); - -YAZ_EXPORT int zebra_resultSetTerms(ZebraHandle zh, const char *setname, - int no, zint *count, - int *type, char *out, size_t *len); +YAZ_EXPORT +ZEBRA_RES zebra_insert_record(ZebraHandle zh, + const char *recordType, + SYSNO *sysno, const char *match, + const char *fname, + const char *buf, int buf_size, + int force_update); +YAZ_EXPORT +ZEBRA_RES zebra_update_record(ZebraHandle zh, + const char *recordType, + SYSNO *sysno, const char *match, + const char *fname, + const char *buf, int buf_size, + int force_update); +YAZ_EXPORT +ZEBRA_RES zebra_delete_record(ZebraHandle zh, + const char *recordType, + SYSNO *sysno, const char *match, const char *fname, + const char *buf, int buf_size, + int force_update); -YAZ_EXPORT int zebra_sort(ZebraHandle zh, ODR stream, - int num_input_setnames, - const char **input_setnames, - const char *output_setname, - Z_SortKeySpecList *sort_sequence, - int *sort_status); +YAZ_EXPORT +ZEBRA_RES zebra_sort(ZebraHandle zh, ODR stream, + int num_input_setnames, + const char **input_setnames, + const char *output_setname, + Z_SortKeySpecList *sort_sequence, + int *sort_status); YAZ_EXPORT -int zebra_select_databases(ZebraHandle zh, int num_bases, - const char **basenames); +ZEBRA_RES zebra_select_databases(ZebraHandle zh, int num_bases, + const char **basenames); YAZ_EXPORT -int zebra_select_database(ZebraHandle zh, const char *basename); +ZEBRA_RES zebra_select_database(ZebraHandle zh, const char *basename); YAZ_EXPORT -int zebra_shadow_enable(ZebraHandle zh, int value); +void zebra_shadow_enable(ZebraHandle zh, int value); YAZ_EXPORT int zebra_register_statistics(ZebraHandle zh, int dumpdict); YAZ_EXPORT -int zebra_record_encoding(ZebraHandle zh, const char *encoding); - -YAZ_EXPORT -int zebra_record_encoding(ZebraHandle zh, const char *encoding); +ZEBRA_RES zebra_record_encoding(ZebraHandle zh, const char *encoding); YAZ_EXPORT -int zebra_octet_term_encoding(ZebraHandle zh, const char *encoding); +ZEBRA_RES zebra_octet_term_encoding(ZebraHandle zh, const char *encoding); /* Resources */ YAZ_EXPORT -int zebra_set_resource(ZebraHandle zh, const char *name, const char *value); +void zebra_set_resource(ZebraHandle zh, const char *name, const char *value); YAZ_EXPORT const char *zebra_get_resource(ZebraHandle zh, - const char *name, const char *defaultvalue); + const char *name, const char *defaultvalue); -YAZ_EXPORT void zebra_pidfname(ZebraService zs, char *path); +YAZ_EXPORT +void zebra_pidfname(ZebraService zs, char *path); typedef struct { char *term; @@ -406,5 +489,91 @@ void zebra_meta_records_destroy(ZebraHandle zh, ZebraMetaRecord *records, YAZ_EXPORT struct BFiles_struct *zebra_get_bfs(ZebraHandle zh); + +YAZ_EXPORT +ZEBRA_RES zebra_set_limit(ZebraHandle zh, int complement_flag, zint *ids); + YAZ_END_CDECL + +/** \mainpage Zebra + * + * \section intro_sec Introduction + * + * Zebra is a search engine for structure data, such as XML, MARC + * and others. + * + * API users should read the api.h for all the public definitions. + * + * The remaining sections briefly describe each of + * Zebra major modules/components. + * + * \section util Base Utilities + * + * The Zebra utilities (util.h) defines fundamental types and a few + * utilites for Zebra. + * + * \section res Resources + * + * The resources system (res.h) is a manager of configuration + * resources. The resources can be viewed as a simple database. + * Resources can be read from a configurtion file, they can be + * read or written by an application. Resources can also be written, + * but that facility is not currently in use. + * + * \section bfile Bfiles + * + * The Bfiles (bfile.h) provides a portable interface to the + * local file system. It also provides a facility for safe updates + * (shadow updates). All file system access is handle by this module + * (except for trival reads of configuration files). + * + * \section dict Dictionary + * + * The Zebra dictionary (dict.h) maps a search term (key) to a value. The + * value is a reference to the list of records identifers in which + * the term occurs. Zebra uses an ISAM data structure for the list + * of term occurrences. The Dictionary uses \ref bfile. + * + * \section isam ISAM + * + * Zebra maintains an ISAM for each term where each ISAM is a list + * of record identifiers corresponding to the records in which the + * term occur. Unlike traditional ISAM systems, the Zebra ISAM + * is compressed. The ISAM system uses \ref bfile. + * + * Zebra has more than one ISAM system. The old and stable ISAM system + * is named isamc (see isamc.h). Another version isams is a write-once + * isam system that is quite compact - suitable for CD-ROMs (isams.h). + * The newest ISAM system, isamb, is implemented as a B-Tree (see isamb.h). + * + * \section data1 Data-1 + * + * The data1 (data1.h) module deals with structured documents. The module can + * can read, modify and write documents. The document structure was + * originally based on GRS-1 - a Z39.50 v3 structure that predates + * DOM. These days the data1 structure may describe XML/SGML as well. + * The data1, like DOM, is a tree structure. Each node in the tree + * can be of type element, text (cdata), preprocessing instruction, + * comment. Element nodes can point to attribute nodes. + * + * \section recctrl Record Control + * + * The record control module (recctrl.h) is responsible for + * managing the various record types ("classes" or filters). + * + * \section rset Result-Set + * + * The Result-Set module (rset.h) defines an interface that all + * Zebra Search Results must implement. Each operation (AND, OR, ..) + * correspond to an implementation of that interface. + * + * \section dfa DFA + * + * DFA (dfa.h) Deterministic Finite Automa is a regular expression engine. + * The module compiles a regular expression to a DFA. The DFA can then + * be used in various application to perform fast match against the + * origianl expression. The \ref Dict uses DFA to perform lookup + * using regular expressions. + */ + #endif