1 
2 /* Web Polygraph       http://www.web-polygraph.org/
3  * Copyright 2003-2011 The Measurement Factory
4  * Licensed under the Apache License, Version 2.0 */
5 
6 #include "base/polygraph.h"
7 
8 #include <ctype.h>
9 #include "xstd/h/iostream.h"
10 #include "xstd/h/iomanip.h"
11 
12 #include "xstd/String.h"
13 #include "logextractors/matchAndPrint.h"
14 
15 // format:
16 //		<name>: <body>\n
17 // or
18 //		<name>:\n
19 //		<multiline-body>
20 //		\n
21 
22 
23 typedef void (*MatchAndPrintEntry)(ostream &os, const char *start, const char *body_start, const char *end);
24 
25 static
NameStart(const char * pos,const char * name,const char * & start)26 bool NameStart(const char *pos, const char *name, const char *&start) {
27 	start = strstr(pos, name);
28 	return start != 0;
29 }
30 
31 static
MatchAndPrintDriver(ostream & os,const char * buf,const Array<String * > & names,MatchAndPrintEntry mape)32 int MatchAndPrintDriver(ostream &os, const char *buf, const Array<String*> &names, MatchAndPrintEntry mape) {
33 	int matchCount = 0;
34 
35 	for (int i = 0; i < names.count(); ++i) {
36 		const String name = *names[i];
37 		int nameMatchCount = 0;
38 		const char *pos = buf;
39 		const char *start;
40 		while (NameStart(pos, name.cstr(), start)) {
41 			// check the start of the name
42 			if (start > pos && !isspace(start[-1])) {
43 				pos = start+1;
44 				continue;
45 			}
46 
47 			// check the end of the name
48 			pos = start + name.len();
49 			if (!(*pos == '.' || *pos == ':'))
50 				continue;
51 
52 			// seek to the end of the name
53 			pos = strchr(pos, ':');
54 			if (!pos)
55 				break;
56 			pos++;
57 			const char *body_start = pos;
58 
59 			// find the end of the object
60 			const char *end = strstr(pos, "\n");
61 			if (end) {
62 				if (end == pos)
63 					end = strstr(end, "\n\n");
64 				if (end) {
65 					mape(os, start, body_start, end);
66 					nameMatchCount++;
67 					pos = end;
68 				}
69 			}
70 		}
71 		if (!nameMatchCount)
72 			cerr << "warning: found no objects named `" << name << "'" << endl;
73 		else
74 			matchCount++;
75 	}
76 
77 	return matchCount;
78 }
79 
80 static
mapeWithTags(ostream & os,const char * start,const char *,const char * end)81 void mapeWithTags(ostream &os, const char *start, const char *, const char *end) {
82 	os.write(start, end-start);
83 	os << endl;
84 }
85 
86 static
mapeBodies(ostream & os,const char *,const char * body_start,const char * end)87 void mapeBodies(ostream &os, const char *, const char *body_start, const char *end) {
88 	while (body_start < end && isspace(*body_start)) ++body_start;
89 	os.write(body_start, end-body_start);
90 	os << ' ';
91 }
92 
93 static
mapeTags(ostream & os,const char * start,const char * body_start,const char *)94 void mapeTags(ostream &os, const char *start, const char *body_start, const char *) {
95 	os.write(start, body_start-start - 1);
96 	os << ' ';
97 }
98 
99 
MatchAndPrint(ostream & os,const char * buf,const Array<String * > & names)100 int MatchAndPrint(ostream &os, const char *buf, const Array<String*> &names) {
101 	if (!names.count()) {
102 		os << buf;
103 		return -1;
104 	}
105 	return MatchAndPrintDriver(os, buf, names, &mapeWithTags);
106 }
107 
MatchAndPrintBodies(ostream & os,const char * buf,const Array<String * > & names)108 int MatchAndPrintBodies(ostream &os, const char *buf, const Array<String*> &names) {
109 	const int res = MatchAndPrintDriver(os, buf, names, &mapeBodies);
110 	os << endl;
111 	return res;
112 }
113 
MatchAndPrintHeader(ostream & os,const char * buf,const Array<String * > & names)114 int MatchAndPrintHeader(ostream &os, const char *buf, const Array<String*> &names) {
115 	os << '#';
116 	const int res = MatchAndPrintDriver(os, buf, names, &mapeTags);
117 	os << endl;
118 	return res;
119 }
120 
121