/* -*- mode: c -*-
 * $Id: regexmatch.gcc,v 1.4 2000/12/24 05:43:53 doug Exp $
 * http://www.bagley.org/~doug/shootout/
 */

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <pcre.h>
#include <string.h>

#define MAXLINES   100
#define MAXLINELEN 132

char *pattern = 
"(?:^|[^\\d\\(])"        
"(\\()?"            
"(\\d\\d\\d)"            
"(?(1)\\))"            
"[ ]"                
"(\\d\\d\\d)"            
"[ -]"                
"(\\d\\d\\d\\d)"        
"\\D"                
;


int
main(int argc, char *argv[]) {
    int NUM = ((argc == 2) ? atoi(argv[1]) : 1);
    int count;
    char *cptr = "";
    char **phones;
    pcre *re;
    int erroffset;
    const char *errptr;
    int n, lines = 0;
    char num[256];
    int i, j, k, matchlen;
    char *matchoffset;
    int nmatches;
    int *ovec, ovecsize;
    pcre_extra *study;

    phones = (char **)malloc(MAXLINES * sizeof(char *));
    if (!phones) {
    fprintf(stderr, "malloc for phones array failed\n");
    exit(1);
    }
    lines = 0;
    while (cptr) {
    phones[lines] = (char *)malloc(MAXLINELEN);
    if (!phones[lines]) {
        fprintf(stderr, "malloc to hold line #%d failed\n", lines);
        exit(1);
    }
    cptr = fgets(phones[lines], MAXLINELEN, stdin);
    lines++;
    if (lines > MAXLINES) {
        fprintf(stderr, "MAXLINES is too small\n");
        exit(1);
    }
    }

    re = pcre_compile(pattern, 0, &errptr, &erroffset, NULL);
    if (!re) {
    fprintf(stderr, "can't open compile regexp\n");
    exit(1);
    }

    study = pcre_study(re, 0, &errptr);

    if (pcre_fullinfo(re, NULL, PCRE_INFO_CAPTURECOUNT, &nmatches) != 0) {
    fprintf(stderr, "pcre_fullinfo failed\n");
    exit(1);
    }
    nmatches++;            

    ovecsize = sizeof(int) * nmatches * 3;
    ovec = (int *)malloc(ovecsize);
    if (!ovec) {
    fprintf(stderr, "malloc for ovec array failed\n");
    exit(1);
    }

    count = 0;
    while (NUM--) {
    for (i=0; i<lines; i++) {
        n = pcre_exec(re, study,
              phones[i], strlen(phones[i]), 0,
              0, ovec, ovecsize);
        if (n == nmatches) {
        
        k = 2*2;    
        
        j = 0;
        num[j++] = '(';
        matchoffset = phones[i] + ovec[k];
        matchlen = ovec[k+1] - ovec[k];
        strncpy(num+j, matchoffset, matchlen);
        j += matchlen; k += 2;
        num[j++] = ')';
        
        num[j++] = ' ';
        
        matchoffset = phones[i] + ovec[k];
        matchlen = ovec[k+1] - ovec[k];
        strncpy(num+j, matchoffset, matchlen);
        j += matchlen; k += 2;
        
        num[j++] = '-';
        
        matchoffset = phones[i] + ovec[k];
        matchlen = ovec[k+1] - ovec[k];
        strncpy(num+j, matchoffset, matchlen);
        j += matchlen; k += 2;
        
        num[j] = 0;
        if (0 == NUM) {
            count++;
            printf("%d: %s\n", count, num);
        }
        }
    }
    }

    for (i=0; i<MAXLINES; i++) {
    free(phones[i]);
    }
    free(phones);
    free(ovec);

    return(0);
}