summaryrefslogtreecommitdiff
path: root/src/check-doc-syntax.awk
diff options
context:
space:
mode:
Diffstat (limited to 'src/check-doc-syntax.awk')
-rw-r--r--src/check-doc-syntax.awk106
1 files changed, 106 insertions, 0 deletions
diff --git a/src/check-doc-syntax.awk b/src/check-doc-syntax.awk
new file mode 100644
index 000000000..1fa8b8d22
--- /dev/null
+++ b/src/check-doc-syntax.awk
@@ -0,0 +1,106 @@
+BEGIN {
+ name_found = 1
+ SECTION_DOC = 0
+ PUBLIC_DOC = 1
+ PRIVATE_DOC = 2
+}
+
+function log_msg(severity, msg)
+{
+ printf "%s (%d): %s: %s %s\n", FILENAME, FNR, severity, doc_name, msg
+}
+
+function log_error(msg)
+{
+ log_msg("ERROR", msg)
+}
+
+function log_warning(msg)
+{
+ log_msg("WARNING", msg)
+}
+
+/^\/\*\*$/ {
+ in_doc = 1
+ doc_line = 0
+}
+
+/^(\/\*\*$| \*[ \t]| \*$| \*\*\/$)/ {
+ valid_doc = 1
+}
+
+in_doc {
+ if (!valid_doc)
+ log_error("bad line: '" $0 "'")
+ valid_doc = 0
+
+ doc_line++
+ if (doc_line == 2) {
+ # new doc name. Did we find the previous one?
+ # (macros are not expected to be found in the same place as
+ # their documentation)
+ if (!name_found && doc_name !~ /CAIRO_/)
+ log_warning("not found")
+ doc_name = $2
+ if (doc_name ~ /^SECTION:.*$/) {
+ doc_type = SECTION_DOC
+ name_found = 1
+ } else if (tolower(doc_name) ~ /^cairo_[a-z0-9_]*:$/) {
+ doc_type = PUBLIC_DOC
+ name_found = 0
+ real_name = substr(doc_name, 1, length(doc_name) - 1)
+ } else if (tolower(doc_name) ~ /^_[a-z0-9_]*:$/) {
+ doc_type = PRIVATE_DOC
+ name_found = 0
+ real_name = substr(doc_name, 1, length(doc_name) - 1)
+ } else {
+ log_error("invalid doc id (should be 'cairo_...:')")
+ name_found = 1
+ }
+ }
+}
+
+!in_doc {
+ regex = "(^|[ \\t\\*])" real_name "([ ;()]|$)"
+ if ($0 ~ regex)
+ name_found = 1
+}
+
+/^ \* Since: ([0-9]*.[0-9]*|TBD)$/ {
+ if (doc_has_since != 0) {
+ log_error("Duplicate 'Since' field")
+ }
+ doc_has_since = doc_line
+}
+
+/^ \*\*\// {
+ if (doc_type == PUBLIC_DOC) {
+ if (!doc_has_since) {
+ # private types can start with cairo_
+ if (doc_name ~ /^cairo_.*_t:$/)
+ log_warning("missing 'Since' field (is it a private type?)")
+ else
+ log_error("missing 'Since' field")
+ } else if (doc_has_since != doc_line - 1)
+ log_warning("misplaced 'Since' field (should be right before the end of the comment)")
+ } else {
+ if (doc_has_since)
+ log_warning("'Since' field in non-public element")
+ }
+
+ in_doc = 0
+ doc_has_since = 0
+ doc_type = 0
+}
+
+/\*\// {
+ if (in_doc) {
+ in_doc = 0
+ log_error("documentation comment not closed with **/")
+ }
+}
+
+END {
+ if (!name_found)
+ log_warning("not found")
+}