/**********************************************************************
 *
 *  Projet  : DilibUnix
 *  Module  : RegExp
 *  Fichier : RegExp.h
 *  Auteur  : J. Ducloy / F. Parmentier
 *  $Id: RegExp.h,v 1.3 2004/01/27 14:26:21 parmentf Exp $
 *
 **********************************************************************
 * 
 *     Copyright (C) 1975 CRIN - CNRS & INRIA Lorraine
 *
 **********************************************************************/

#ifndef _ILIB_REG_EXP_H
#define _ILIB_REG_EXP_H

#include <sys/types.h> 
#include <regex.h>     /* Advanced Regular Expressions */

typedef struct {
  regex_t *preg;
} RegExp;

RegExp* RegExpCreate(char *strInput);
void    RegExpFree(RegExp *re);
char*   RegExpFind(RegExp *re, char *str);
char*   RegExpExtract(RegExp *re, char *str);
char*   RegExpAfter(RegExp *re, char *str);
char*   RegExpBefore(RegExp *re, char *str);

extern char*   RegExpLoc1;
extern char*   RegExpLoc2;
#define RegExpAfterStr RegExpLoc2
int     RegExpExec();

/*************** analyseur de liste avec separateur *********************/

typedef struct RegExpSepAnalysorSS
{
  RegExp *re;
  char   *str;
  char   *currentLoc;   /* if NULL => end od string */
  char   *nextSep;       /* if NULL => currentLoc = lastToken */
  char   *nextToken;
  char   *currentToken; /* to be freed at next call
                           if NULL => no string to free */
} RegExpSepAnalysor;

RegExpSepAnalysor *RegExpSepAnalysorCreate();
char              *RegExpSepAnalysorNextToken();
RegExpSepAnalysor *RegExpSepAnalysorInit();

/*        Macros (obligatoires pour decharger l'utilisateur
                 de la gestion des liberations         */
/*        Deprecated                                   */

#define RegExpIf(re,str,blocIf,blocElse)                       \
        {if (RegExpExec(re,str))                               \
         { char* yyText;                                       \
	   char* yyAfter;                                      \
	   char* yyBefore;                                     \
	   char* yyFound;                                      \
	   int yyLen;                                          \
	   int yyPos;                                          \
	   yyFound=RegExpLoc1;                                 \
	   yyAfter=RegExpLoc2;                                 \
           yyLen=RegExpLoc2-RegExpLoc1;                        \
	   yyText=(char*)malloc(yyLen+1);yyText[0]='\0';              \
	   strncat(yyText, RegExpLoc1, yyLen);                 \
	   yyPos=RegExpLoc1-str;                               \
	   yyBefore=(char*)malloc(yyPos+1);yyBefore[0]='\0';          \
	   strncat(yyBefore, str, yyPos);                      \
           blocIf;                                             \
	   free (yyText);                                      \
	   free (yyBefore);                                    \
         }                                                     \
	else blocElse;                                         \
      }                                                        \

#define RegExpIf_Ba(re,str,beforeStr,afterStr,blocIf,blocElse)   \
        {if (RegExpExec(re,str))                                \
         { char* beforeStr;                                     \
	   char* afterStr;                                      \
	   unsigned RegExp_pos;                                 \
	   afterStr=RegExpLoc2;                                 \
	   RegExp_pos=RegExpLoc1-str;                           \
	   beforeStr=(char*)malloc(RegExp_pos+1);               \
	   beforeStr[0]='\0';                                   \
	   strncat(beforeStr, str, RegExp_pos);                 \
           blocIf;                                              \
	   free (beforeStr);                                    \
         }                                                      \
	else blocElse;                                          \
      }                                  
                       
#define RegExpIf_Bt(re,str,beforeStr,textPtr,blocIf,blocElse)   \
        {if (RegExpExec(re,str))                                \
         { char* beforeStr;                                     \
	   char* textPtr;                                       \
	   unsigned RegExp_pos;                                 \
	   textPtr=RegExpLoc1;                                  \
	   RegExp_pos=RegExpLoc1-str;                           \
	   beforeStr=(char*)malloc(RegExp_pos+1);               \
	   beforeStr[0]='\0';                                   \
	   strncat(beforeStr, str, (int)RegExp_pos);            \
           blocIf;                                              \
	   free (beforeStr);                                    \
         }                                                      \
	else blocElse;                                          \
      }                                                         

#define RegExpIf_Ta(re,str,textStr,afterStr,blocIf,blocElse)   \
        {if (RegExpExec(re,str))                                \
         { char* textStr;                                       \
	   char* afterStr;                                      \
	   unsigned RegExp_pos;                                 \
	   afterStr=RegExpLoc2;                                 \
	   RegExp_pos=RegExpLoc2-RegExpLoc1;                    \
	   textStr=(char*)malloc(RegExp_pos+1);                 \
	   textStr[0]='\0';                                     \
	   strncat(textStr, RegExpLoc1, RegExp_pos);            \
           blocIf;                                              \
	   free (textStr);                                      \
         }                                                      \
	else blocElse;                                          \
      }                                                         \

#define RegExpIf_BTa(re,str,beforeStr,textStr,afterStr,blocIf,blocElse)   \
        {if (RegExpExec(re,str))                                \
         { char* textStr;                                       \
	   char* afterStr;                                      \
	   char* beforeStr;                                     \
	   unsigned RegExp_pos;                                 \
	   afterStr=RegExpLoc2;                                 \
	   RegExp_pos=RegExpLoc2-RegExpLoc1;                    \
	   textStr=(char*)malloc(RegExp_pos+1);                 \
	   textStr[0]='\0';                                     \
	   strncat(textStr, RegExpLoc1, RegExp_pos);            \
	   RegExp_pos=RegExpLoc1-str;                           \
	   beforeStr=(char*)malloc(RegExp_pos+1);               \
	   beforeStr[0]='\0';                                   \
	   strncat(beforeStr, str, RegExp_pos);                 \
           blocIf;                                              \
	   free (textStr);                                      \
	   free (beforeStr);                                    \
         }                                                      \
	else blocElse;                                          \
      }                                                         \

#define RegExpDoBySep(re,str,token,block)                     \
       {                                                      \
	  RegExpSepAnalysor *RegExpSA;                        \
	  char *token;                                        \
	  RegExpSA=RegExpSepAnalysorCreate();                 \
          RegExpSepAnalysorInit(RegExpSA,re,str);             \
          while(token=RegExpSepAnalysorNextToken(RegExpSA))   \
               block;                                         \
	  free(RegExpSA);                                     \
       }

#define RegExpStrDoBySep(re,s,t,b)        \
{                                     \
   static firstCall=0;                \
   static RegExp *reSep;              \
   if (firstCall==0)                  \
     {                                \
       firstCall=1;                   \
       reSep=RegExpCreate(re);        \
     }                                \
   RegExpDoBySep(reSep,s,t,b)         \
}

#endif /* _ILIB_REG_EXP_H */

