1BEGIN {
2    name_found = 1
3    SECTION_DOC = 0
4    PUBLIC_DOC = 1
5    PRIVATE_DOC = 2
6}
7
8function log_msg(severity, msg)
9{
10    printf "%s (%d): %s: %s %s\n", FILENAME, FNR, severity, doc_name, msg
11}
12
13function log_error(msg)
14{
15    log_msg("ERROR", msg)
16}
17
18function log_warning(msg)
19{
20    log_msg("WARNING", msg)
21}
22
23/^\/\*\*$/ {
24    in_doc = 1
25    doc_line = 0
26}
27
28/^(\/\*\*$| \*[ \t]| \*$| \*\*\/$)/ {
29    valid_doc = 1
30}
31
32in_doc {
33    if (!valid_doc)
34	log_error("bad line: '" $0 "'")
35    valid_doc = 0
36
37    doc_line++
38    if (doc_line == 2) {
39	# new doc name. Did we find the previous one?
40	# (macros are not expected to be found in the same place as
41	# their documentation)
42	if (!name_found && doc_name !~ /CAIRO_/)
43	    log_warning("not found")
44	doc_name = $2
45	if (doc_name ~ /^SECTION:.*$/) {
46	    doc_type = SECTION_DOC
47	    name_found = 1
48	} else if (tolower(doc_name) ~ /^cairo_[a-z0-9_]*:$/) {
49	    doc_type = PUBLIC_DOC
50	    name_found = 0
51	    real_name = substr(doc_name, 1, length(doc_name) - 1)
52	} else if (tolower(doc_name) ~ /^_[a-z0-9_]*:$/) {
53	    doc_type = PRIVATE_DOC
54	    name_found = 0
55	    real_name = substr(doc_name, 1, length(doc_name) - 1)
56	} else {
57	    log_error("invalid doc id (should be 'cairo_...:')")
58	    name_found = 1
59	}
60    }
61}
62
63!in_doc {
64    regex = "(^|[ \\t\\*])" real_name "([ ;()]|$)"
65    if ($0 ~ regex)
66	name_found = 1
67}
68
69/^ \* Since: ([0-9]*.[0-9]*|TBD)$/ {
70    if (doc_has_since != 0) {
71	log_error("Duplicate 'Since' field")
72    }
73    doc_has_since = doc_line
74}
75
76/^ \*\*\// {
77    if (doc_type == PUBLIC_DOC) {
78	if (!doc_has_since) {
79	    # private types can start with cairo_
80	    if (doc_name ~ /^cairo_.*_t:$/)
81		log_warning("missing 'Since' field (is it a private type?)")
82	    else
83		log_error("missing 'Since' field")
84	} else if (doc_has_since != doc_line - 1)
85	    log_warning("misplaced 'Since' field (should be right before the end of the comment)")
86    } else {
87	if (doc_has_since)
88	    log_warning("'Since' field in non-public element")
89    }
90
91    in_doc = 0
92    doc_has_since = 0
93    doc_type = 0
94}
95
96/\*\// {
97    if (in_doc) {
98	in_doc = 0
99 	log_error("documentation comment not closed with **/")
100    }
101}
102
103END {
104    if (!name_found)
105	log_warning("not found")
106}
107