#include <iostream>
#include <regex.h>
#include <string.h>
#define REGEX "@([^(@]+)(\\(\\(property\\(([^)]+)\\)val\\(([^)]+)\\)\\))?"
#define DEBUG 1
using namespace std;
typedef struct {
char* name;
char* property;
char* value;
} item;
int getMatches(char* haystack, item** items){
int l = -1, ats = 0;
while (haystack[++l])
if (haystack[l] == '@')
ats++;
*items = (item*) malloc(ats * sizeof(item));
item* arr = *items;
regex_t needle;
regcomp(&needle, REGEX, REG_ICASE|REG_EXTENDED);
regmatch_t match[5];
int ret;
int x = -1;
while (!(ret = regexec(&needle, haystack, 5, match,0))){
++x;
if (DEBUG) cerr << "MATCH INSTANCE " << x << "\n";
//Get the name
int bufsize = match[1].rm_eo-match[1].rm_so + 1;
arr[x].name = (char *) malloc(bufsize);
if(arr[x].name == NULL)
cerr << "MALLOC FAILED\n";
strncpy(arr[x].name, &(haystack[match[1].rm_so]), bufsize - 1);
arr[x].name[bufsize-1]=0x0;
if (DEBUG) cerr <<" "<<arr[x].name <<'\n';
//if property and value are both valid...
if (!(match[3].rm_so > l || match[3].rm_so<0 || match[3].rm_eo > l || match[3].rm_so< 0
|| match[4].rm_so > l || match[4].rm_so<0 || match[4].rm_eo > l || match[4].rm_so< 0)){
//Get the property
bufsize = match[3].rm_eo-match[3].rm_so + 1;
arr[x].property = (char *) malloc(bufsize);
if(arr[x].property == NULL)
cerr << "MALLOC FAILED\n";
strncpy(arr[x].property, &(haystack[match[3].rm_so]), bufsize - 1);
arr[x].property[bufsize-1]=0x0;
if (DEBUG) cerr <<" "<<arr[x].property<<'\n';
//Get the Value
bufsize = match[4].rm_eo-match[4].rm_so + 1;
arr[x].value = (char *) malloc(bufsize);
if(arr[x].value == NULL)
cerr << "MALLOC FAILED\n";
strncpy(arr[x].value, &(haystack[match[4].rm_so]), bufsize - 1);
arr[x].value[bufsize-1]=0x0;
if (DEBUG) cerr <<" "<<arr[x].value<<'\n';
} else {
arr[x].property = NULL;
arr[x].value = NULL;
}
haystack = &(haystack[match[0].rm_eo]);
l -= match[0].rm_eo;
}
return x+1;
}
int main() {
char* haystack = "MyCarGarage@Mustang((property(PS)val(500))@Porsche((property(PS)val(425))@Corvette@Corsair@Pinto((property(exploded)val(not yet))";
item* matches;
int n = getMatches(haystack, &matches);
cout << "FOUND " << n << " MATCHES:\n\n";
for (int i = 0; i<n; i++){
cout <<'S'<< i << ": "<< matches[i].name<<'\n';
if (matches[i].property != NULL){
cout <<'P'<< i << ": "<< matches[i].property<<'\n';
cout <<'V'<< i << ": "<< matches[i].value<<'\n'; //*/
}
cout <<'\n';
//cout << other[0].name <<'\n';
}
return 0;
}