CnUnix

[알림판목록 I] [알림판목록 II] [글목록][이 전][다 음]
[ CnUnix ] in KIDS
글 쓴 이(By): LEEIDE (jjunior)
날 짜 (Date): 2002년 4월  1일 월요일 오후 03시 26분 53초
제 목(Title): GNU regular expression 함수[질문]


안녕하세요.

regular expression에 대한 함수들 중에서 GNU 계열 함수를 사용하고 
있습니다만, 혹시 써보신분이 있으시면 도움을 좀 받았으면 합니다.
POSIX계열이 아닌 GNU 계열의 함수입니다.
re_compile_pattern
re_match
위의 두 함수를 사용해 보신 분을 급하게 찾습니다.

#include <stdio.h>
#include <sys/types.h>
#include <regex.h>
#include <limits.h>
#include <stdlib.h>


#define BUFFER_SIZE   4096
void print_pattern_info (pattern, pattern_buffer_ptr)
const char *pattern;
struct re_pattern_buffer *pattern_buffer_ptr;
{
        printf("  Pattern:  `%s'.\n", pattern);
        printf("  Compiled pattern:  \n");

        printf("\tbuffer : %s\n", pattern_buffer_ptr->buffer);
        printf("\tallocated : %ld\n", pattern_buffer_ptr->allocated);
        printf("\tused : %ld\n", pattern_buffer_ptr->used);
        printf("\tsyntax : ?\n");
        printf("\tfastmap : %s\n", pattern_buffer_ptr->fastmap);
        printf("\ttranslate : %s\n", pattern_buffer_ptr->translate);
        printf("\tre_nsub : %d\n", pattern_buffer_ptr->re_nsub);
        printf("\tcan_be_null : %d\n", pattern_buffer_ptr->can_be_null);
        printf("\tregs_allocated : %d\n", 
pattern_buffer_ptr->can_be_null);
        printf("\tfastmap_accurate : %d\n", 
pattern_buffer_ptr->fastmap_accurate);
        printf("\tno_sub : %d\n", pattern_buffer_ptr->no_sub);
        printf("\tnot_bol : %d\n", pattern_buffer_ptr->not_bol);
        printf("\tnot_eol : %d\n", pattern_buffer_ptr->not_eol);
        printf("\tnewline_anchor : %d\n", 
pattern_buffer_ptr->newline_anchor);
}


void grep( const char* pattern, FILE* f )
{
        char            buffer[BUFFER_SIZE], b2[BUFFER_SIZE];
        struct re_pattern_buffer        pat_buffer;
        struct re_registers             regs;
        reg_syntax_t                    syntax;
        int             iRet, i;
        const char      *error;

        printf("pattern : %s\n", pattern);
        error = re_compile_pattern(pattern, strlen(pattern), &pat_buffer);
        if (error != NULL)
        {
                printf("error : %s\n", error);
                return;
        }
        print_pattern_info(pattern, &pat_buffer);
//      pat_buffer.no_sub = 1;
//      pat_buffer.not_bol = 1;
//      pat_buffer.not_eol = 1;
        pat_buffer.newline_anchor = 0;
//      syntax = re_set_syntax(RE_SYNTAX_EGREP);
//      syntax = re_set_syntax(_RE_SYNTAX_POSIX_COMMON);
        re_set_syntax(_RE_SYNTAX_POSIX_COMMON);
//      pat_buffer.syntax = syntax;

        while( fgets( buffer, BUFFER_SIZE, f ) != NULL ) {
                if (buffer[strlen(buffer)-1] == '\n')
                        buffer[strlen(buffer)-1] = '\0';
                if (strlen(buffer) == 0) continue;
                printf("Buffer : %s\n", buffer);

                iRet = re_match(&pat_buffer, buffer, strlen(buffer), 0, 
&regs);
                printf("=======================================\n");
                print_pattern_info(pattern, &pat_buffer);
                printf("---------------------------------------\n");
                switch (iRet)
                {
                        case -1 :
                                        printf("\tNo match found.\n");
                                        break;
                        case -2 :
                                        printf("\tInternal Error 
occurred\n");
                                        break;
                        default :
                                        printf("\tTotal %d characters 
matched.\n", iRet);
                                        for(i=0; regs.start[i] != -1; i++)
                                        {
                                                strncpy(b2, 
buffer+regs.start[i], regs.end[i]-reg
s.start[i]);
                                                
b2[regs.end[i]-regs.start[i]] = '\0';
                                                printf("\tb2[%d] : 
|%s|\n", i, b2);
                                                printf("\t(%d, %d)\n", 
regs.start[i], regs.end[i]
);
                                        }
                                        break;
                }
                printf("=======================================\n\n\n");
        }
        regfree( &pat_buffer );

        return;
}


int main(int argc, char *argv[])
{
        FILE    *fp;

        if (argc == 3)
        {
                if ( (fp = fopen(argv[2], "r")) == NULL)
                {
                        fprintf(stderr, "Error: Can't open input 
file(%s)\n", argv[2]);
                        exit(0);
                }

                grep(argv[1], fp);

        }
        else
        {
                fprintf(stderr, "Usage : %s <pattern> <input file>\n", 
argv[0]);
                exit(0);
        }
        return 0;
}



=====================================================

위의 프로그램은 command line argument의 argv[1]으로 패턴을 입력받아 
argv[2]의 파일에서 매치된 패턴을 출력해주는 테스트용 프로그램입니다.
이 프로그램을 독립적으로 실행시킬때는 정규식을 제대로 잡아줍니다만,
개발중인 다른 프로그램에 붙였더니 re_compile_pattern에 들어가서 프로그램
스택을 깨버리더군요.
무슨 문제가 있는것인지... 

우선 GNU regex의 경우 어디에 있는 모듈을 불러서 링킹을 하는지조차 
불확실합니다. 추측으로는 Linux 배포판에 같이 붙어 오는게 아닌가 
생각합니다.
사용하는 시스템은 RedHat 7.1이고 gcc는 3.0.2 입니다.



[알림판목록 I] [알림판목록 II] [글 목록][이 전][다 음]
키 즈 는 열 린 사 람 들 의 모 임 입 니 다.