aboutsummaryrefslogtreecommitdiff
path: root/tiff-tables.awk
blob: 29b462bc55b03fc3e9b83da82e650a79f5611f8f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#!/usr/bin/awk -f
BEGIN {
	FS = ", *"
	print "// Generated by tiff-tables.awk. DO NOT MODIFY."
	print ""
	print "#ifndef TIFF_TABLES_CONSTANTS_ONLY"
	print "#include <stddef.h>"
	print "#include <stdint.h>"
	print ""
	print "struct tiff_value {"
	print "\tconst char *name;"
	print "\tuint16_t value;"
	print "};"
	print ""
	print "struct tiff_entry {"
	print "\tconst char *name;"
	print "\tuint16_t tag;"
	print "\tstruct tiff_value *values;"
	print "};"
	print "#endif"
}

{
	# Remember and strip consecutive comments.
	if (match($0, /#/))
		comment[++comments] = substr($0, RSTART + 1)
	else if (!/[[:space:]]/)
		comments = 0

	sub(/#.*$/, "")
	sub(/[[:space:]]*$/, "")
}

# Converts arbitrary strings to C identifiers (when running in the C locale).
function identifize(s) {
	# Regard parenthesised text as comments.
	while (match(s, /[[:space:]]\([^)]+\)/)) {
		comment[++comments] = substr(s, RSTART, RLENGTH)
		s = substr(s, 1, RSTART - 1) substr(s, RSTART + RLENGTH)
	}

	# Capitalize words (toupper is POSIX), removing spaces and dashes between.
	while (match(s, /[-[:space:]]./)) {
		s = substr(s, 1, RSTART - 1) \
			toupper(substr(s, RSTART + 1, 1)) \
			substr(s, RSTART + RLENGTH)
	}

	# Replace any remaining non-identifier characters with underscores.
	gsub(/[^[:alnum:]]/, "_", s)
	return s
}

function flushcomments(prefix,    i, acc) {
	for (i = 1; i <= comments; i++)
		acc = acc prefix comment[i] "\n"
	comments = 0
	return acc
}

function flushvalues() {
	if (values) {
		allvalues = allvalues "enum " fieldname " {\n" values "};\n\n"
		values = ""
		fields = fields "\n\t\t{}\n\t}},"
	} else if (fields) {
		fields = fields " NULL},"
	}
}

function flushsection() {
	if (section) {
		flushvalues()
		print "};\n\n" allvalues "#ifndef TIFF_TABLES_CONSTANTS_ONLY"
		print "static struct tiff_entry " \
			  sectionsnakecase "_entries[] = {" fields "\n\t{}\n};"
		print "#endif"
	}
}

# Section marker
/^= / {
	flushsection()
	section = identifize(substr($0, 3))
	sectionsnakecase = tolower(substr($0, 3))
	gsub(/[^[:alnum:]]/, "_", sectionsnakecase)
	fields = ""
	allvalues = ""
	print "\n" flushcomments("//") "enum {"
}

# Field
section && /^[^\t=]/ {
	flushvalues()
	fieldname = section "_" identifize($2)
	fields = fields "\n\t{\"" $2 "\", " fieldname ","
	print flushcomments("\t//") "\t" fieldname " = " $1 ","
}

# Value
section && /^\t/ {
	sub(/^\t*/, "")
	valuename = fieldname "_" identifize($2)
	if (!values)
		fields = fields " (struct tiff_value[]) {"
	values = values flushcomments("\t//") "\t" valuename " = " $1 ",\n"
	fields = fields "\n\t\t{\"" $2 "\", " valuename "},"
}

END {
	flushsection()
}