/*
 * regular expression pattern matching routines < rege.h >
 *
 * 正規表現によるパターンマッチングルーチン
 *
 * Copyright 1996,1998 (c) Taiji Yamada, AIHARA Electrical Engineering Co.,Ltd.
 */
#ifndef _REGE_H_
#define _REGE_H_

/*
 * 構文の規則を表すマスク
 */
typedef unsigned long rege_syntax_t;

#define REGE_BS_BRACES           (1<<0) /* \{\} を繰り返し指定とする */
#define REGE_BS_PARENS           (1<<1) /* \(\) をグループ指定とする */
#define REGE_BS_PLUS_QM          (1<<2) /* \+,\? を並び指定とする */
#define REGE_BS_VBAR             (1<<3) /* \| を選択オペレータとする */
#define REGE_CONTEXT_INDEP_OPS   (1<<4) /* *,+,?,{,^,$ は常にアンカー */ /* ! */
#define REGE_CONTEXT_INVALID_OPS (1<<5) /* *,+,?,{,^,$ で不正なアンカー禁止 */ /* ! */
#define REGE_DOT_NEWLINE         (1<<6) /* . を改行にマッチさせる */
#define REGE_DOT_NOT_NULL        (1<<7) /* . をナル文字にマッチさせない */
#define REGE_IGNORE_EMPTY_RANGES (1<<8) /* [z-a] のような不正なレンジを無視 */
#define REGE_HAT_LISTS_NEWLINE   (1<<9) /* [^] で改行にマッチする */
#define REGE_IGNORE_CASE        (1<<10) /* 大文字小文字を区別しない */
#define REGE_LIMITED_OPS        (1<<11) /* +,?,| を非オペレータとする */
#define REGE_NEWLINE_ALT        (1<<12) /* 改行を選択オペレータとする */
#define REGE_NO_BS_ESC_IN_LISTS (1<<13) /* [] 中でメタエスケープ禁止 */
#define REGE_NO_BS_REFS         (1<<14) /* 後方参照を禁止 */ /* ! */
#define REGE_NO_INTERVALS       (1<<15) /* 繰り返し指定を禁止 */
#define REGE_NO_MATCH_BOL       (1<<16) /* 行頭オペレータのマッチを禁止 */
#define REGE_NO_MATCH_EOL       (1<<17) /* 行末オペレータのマッチを禁止 */
#define REGE_NO_XCHAR_CLASSES   (1<<18) /* 拡張キャラクタクラス [::] を禁止 */ /* ! */
#define REGE_UNMATCH_RPAREN_ORD (1<<19) /* 孤立した ) を許す */ /* ! */

/*
 * さまざまな構文の規則のためのコンビニエンスマスク
 */
#define REGE_SYNTAX_PERL 0

#define REGE_SYNTAX_AWK \
(REGE_BS_BRACES |\
 REGE_DOT_NOT_NULL |\
 REGE_HAT_LISTS_NEWLINE |\
 REGE_NO_BS_ESC_IN_LISTS |\
 REGE_NO_BS_REFS |\
 REGE_NO_INTERVALS |\
 REGE_NO_XCHAR_CLASSES |\
 REGE_UNMATCH_RPAREN_ORD)

#define REGE_SYNTAX_POSIX_AWK \
(REGE_CONTEXT_INDEP_OPS |\
 REGE_DOT_NEWLINE |\
 REGE_DOT_NOT_NULL |\
 REGE_HAT_LISTS_NEWLINE |\
 REGE_UNMATCH_RPAREN_ORD)

#define REGE_SYNTAX_GREP \
(REGE_BS_BRACES |\
 REGE_BS_PARENS |\
 REGE_BS_PLUS_QM |\
 REGE_BS_VBAR |\
 REGE_IGNORE_EMPTY_RANGES |\
 REGE_NEWLINE_ALT |\
 REGE_NO_BS_ESC_IN_LISTS)

#define REGE_SYNTAX_EGREP \
(REGE_BS_BRACES |\
 REGE_CONTEXT_INDEP_OPS |\
 REGE_IGNORE_EMPTY_RANGES |\
 REGE_NEWLINE_ALT |\
 REGE_NO_BS_ESC_IN_LISTS |\
 REGE_NO_INTERVALS)

#define REGE_SYNTAX_POSIX_EGREP \
(REGE_CONTEXT_INDEP_OPS |\
 REGE_IGNORE_EMPTY_RANGES |\
 REGE_NEWLINE_ALT |\
 REGE_NO_BS_ESC_IN_LISTS)

#define REGE_SYNTAX_ED REGE_SYNTAX_POSIX_BASIC

#define REGE_SYNTAX_SED REGE_SYNTAX_POSIX_BASIC

#define REGE_SYNTAX_POSIX_BASIC \
(REGE_BS_BRACES |\
 REGE_BS_PARENS |\
 REGE_BS_PLUS_QM |\
 REGE_BS_VBAR |\
 REGE_DOT_NEWLINE |\
 REGE_DOT_NOT_NULL |\
 REGE_HAT_LISTS_NEWLINE |\
 REGE_NO_BS_ESC_IN_LISTS)

#define REGE_SYNTAX_POSIX_EXTENDED \
(REGE_CONTEXT_INDEP_OPS |\
 REGE_DOT_NEWLINE |\
 REGE_DOT_NOT_NULL |\
 REGE_HAT_LISTS_NEWLINE |\
 REGE_NO_BS_ESC_IN_LISTS |\
 REGE_UNMATCH_RPAREN_ORD)

#define REGE_SYNTAX_EMACS \
(REGE_BS_BRACES |\
 REGE_BS_PARENS |\
 REGE_BS_VBAR |\
 REGE_IGNORE_EMPTY_RANGES |\
 REGE_HAT_LISTS_NEWLINE |\
 REGE_NO_BS_ESC_IN_LISTS |\
 REGE_NO_INTERVALS |\
 REGE_NO_XCHAR_CLASSES)

/*
 * エラー処理
 */
typedef enum {
  REGE_NOERROR,
  REGE_NOMATCH,
  REGE_BADPAT,
  REGE_ECOLLATE,
  REGE_ECTYPE,
  REGE_EESCAPE,
  REGE_ESUBREG,
  REGE_EBRACK,
  REGE_EPAREN,
  REGE_EBRACE,
  REGE_BADBR,
  REGE_ERANGE,
  REGE_ESPACE,
  REGE_BADRPT,
  REGE_EEND,
  REGE_ESIZE,
  REGE_ERPAREN,
} rege_errcode_t;
extern char *rege_error(rege_errcode_t errcode);

/*
 * 正規表現のコンパイルのための型
 */
typedef struct {
  rege_syntax_t syntax;         /* 構文規則 */
  rege_errcode_t errcode;       /* エラーコード */
  char *trans_table;            /* 変換表 */
  void *buffer;                 /* コンパイルイメージ */
} rege_t;

/*
 * 正規表現をコンパイル
 */
extern rege_t *rege_compile(char *pattern, rege_syntax_t syntax, char *trans_table);

/*
 * 文字列 string に対してパターンマッチングを行なう
 */
extern void rege_match(rege_t *rege, char *string, size_t size, char **from, char **to);

/*
 * 文字列 string に対してパターンマッチングを行なう '^', '$' は無視
 */
extern void rege_next_match(rege_t *rege, char *string, size_t size, char **from, char **to);

/*
 * 正規表現のコンパイルのための型を解放する
 */
extern void rege_free(rege_t *rege);

#endif /* _REGE_H_ */
