xref: /netbsd-src/external/bsd/file/dist/src/BNF (revision a77ebd868432a4d7e595fb7709cfc1b8f144789b)
1*a77ebd86SchristosThis is a first attempt to document the grammar used by magic(5), with
2*a77ebd86Schristoshopes of eventually incorporating something like this into the manpage.
3*a77ebd86Schristos
4*a77ebd86SchristosNote: Currently, the parser varies slightly from this, but only in
5*a77ebd86Schristosvery minor ways, e.g., the strflags maybe separated by '/' characters
6*a77ebd86Schristosand at most one strcount is allowed; likewise for regflags.
7*a77ebd86Schristos
8*a77ebd86Schristos------------------------------------------------------------------------
9*a77ebd86Schristosmagic = 1*query
10*a77ebd86Schristos
11*a77ebd86Schristosquery = line *( 1*level line )
12*a77ebd86Schristos
13*a77ebd86Schristoslevel = ">"		;; Increment the level by 1.
14*a77ebd86Schristos			;; The first line of a query is at level 0.
15*a77ebd86Schristos
16*a77ebd86Schristosline = offset HWS type HWS test HWS message EOL
17*a77ebd86Schristos
18*a77ebd86Schristos------------------------------------------------------------------------
19*a77ebd86Schristosoffset = absoffset | reloffset | indoffset
20*a77ebd86Schristos			;; The offset in the file at which to apply
21*a77ebd86Schristos			;; the <test>.
22*a77ebd86Schristos
23*a77ebd86Schristosabsoffset = NUMBER	;; An absolute offset from the start of the file.
24*a77ebd86Schristos
25*a77ebd86Schristosreloffset = "&" NUMBER	;; The offset relative to the last match offset
26*a77ebd86Schristos			;; at one level up.
27*a77ebd86Schristos			;; Not allowed at level == 0.
28*a77ebd86Schristos
29*a77ebd86Schristosindoffset = indoff | relindoff
30*a77ebd86Schristos
31*a77ebd86Schristosindoff = "(" offset1 [ "." size ] [ op disp ] ")"
32*a77ebd86Schristos			;; Read the file at <offset1> of width <size>.
33*a77ebd86Schristos			;; If size is not specified, assume a long.
34*a77ebd86Schristos			;; If <op> is given, then preform that
35*a77ebd86Schristos			;; operation on the result and the <disp>.
36*a77ebd86Schristos
37*a77ebd86Schristosoffset1 = absoffset | reloffset
38*a77ebd86Schristos
39*a77ebd86Schristossize = byte | leshort | beshort | lelong | belong | melong
40*a77ebd86Schristos
41*a77ebd86Schristosbyte = "B" | "b" | "C" | "c"	;; A one-byte value.
42*a77ebd86Schristosleshort = "s" | "h"		;; A two-byte little-endian value.
43*a77ebd86Schristosbeshort = "S" | "H"		;; A two-byte big-endian value.
44*a77ebd86Schristoslelong = "l"			;; A four-byte little-endian value.
45*a77ebd86Schristosbelong = "L"			;; A four-byte big-endian value.
46*a77ebd86Schristosmelong = "m"			;; A four-byte middle-endian value.
47*a77ebd86Schristos
48*a77ebd86Schristosop = [ invert ] ( "+" | "-" | "*" | "/" | "%" | "&" | "|" | "^" )
49*a77ebd86Schristos
50*a77ebd86Schristosinvert = "~"		;; Flip the bits on result of the <op>.
51*a77ebd86Schristos
52*a77ebd86Schristosdisp =  NUMBER | memvalue
53*a77ebd86Schristos
54*a77ebd86Schristosmemvalue = "(" NUMBER ")"
55*a77ebd86Schristos			;; NUMBER is interpreted as an absolute or
56*a77ebd86Schristos			;; relative offset matching that of <offset1>.
57*a77ebd86Schristos			;; Read the file at the resulting offset with
58*a77ebd86Schristos			;; the same size as <offset1>
59*a77ebd86Schristos
60*a77ebd86Schristosrelindoff = "&" indoff	;; add <indoff> to the last match offset at
61*a77ebd86Schristos			;; one level up.
62*a77ebd86Schristos
63*a77ebd86Schristos------------------------------------------------------------------------
64*a77ebd86Schristostype = [ unsigned ] ( numeric | strtype | default )
65*a77ebd86Schristos
66*a77ebd86Schristosunsigned = "u"		;; The value is unsigned.
67*a77ebd86Schristos			;; This affects the sign extension of numeric
68*a77ebd86Schristos			;; types and the '<' and '>' compares.  It is
69*a77ebd86Schristos			;; intended for numeric types, but allowed on
70*a77ebd86Schristos			;; all types.
71*a77ebd86Schristos
72*a77ebd86Schristosnumeric = ( numtype | datatype ) [ nummask ]
73*a77ebd86Schristos
74*a77ebd86Schristosnumtype = byte | short | long | quad
75*a77ebd86Schristos
76*a77ebd86Schristosbyte = "byte"
77*a77ebd86Schristosshort = "short" | "beshort" | "leshort"
78*a77ebd86Schristoslong = "long" | "lelong" | "belong" | "melong"
79*a77ebd86Schristosquad = "quad" | "lequad" | "bequad"
80*a77ebd86Schristos
81*a77ebd86Schristosdatetype = udate32 | ldate32 | udate64 | ldate64
82*a77ebd86Schristos
83*a77ebd86Schristosudate32 = "date" | "bedate" | "ledate" | "medate"	;; UTC dates
84*a77ebd86Schristosldate32 = "ldate" | "beldate" | "leldate" | "meldate"	;; local dates
85*a77ebd86Schristosudate64 = "qdate" | "leqdate" | "beqdate"		;; UTC dates
86*a77ebd86Schristosldate64 = "qldate" | "leqldate" | "beqldate"		;; local dates
87*a77ebd86Schristos
88*a77ebd86Schristosnummask = op NUMBER
89*a77ebd86Schristos
90*a77ebd86Schristosstrtype = regex | search | string8 | string16
91*a77ebd86Schristos
92*a77ebd86Schristosregex = "regex" [ "/" 1*regflag ]
93*a77ebd86Schristos
94*a77ebd86Schristosregflag = "c" | "s" | linecnt
95*a77ebd86Schristos
96*a77ebd86Schristoslinecnt = NUMBER	;; The number of lines to search.  If this
97*a77ebd86Schristos			;; is missing or zero, the rest of the
98*a77ebd86Schristos			;; file is searched.
99*a77ebd86Schristos
100*a77ebd86Schristossearch = "string" [ "/" 1*srchflag ]
101*a77ebd86Schristos
102*a77ebd86Schristossrchflag = strflag | srchcnt
103*a77ebd86Schristos
104*a77ebd86Schristossrchcnt = NUMBER	;; The number of search tries.  If this
105*a77ebd86Schristos			;; is missing or zero, the rest of the
106*a77ebd86Schristos			;; file is searched.
107*a77ebd86Schristos
108*a77ebd86Schristosstring8 = ( "string" | "pstring" ) [ "/" 1*strflag ]
109*a77ebd86Schristos
110*a77ebd86Schristosstrflag = "b" | "B" | "c" | "C"
111*a77ebd86Schristos
112*a77ebd86Schristosstring16 = "bestring16" | "lestring16"
113*a77ebd86Schristos
114*a77ebd86Schristosdefault = "default"	;; This is intended to be used with the
115*a77ebd86Schristos			;; <truetest> ("x" below).  It is matched if
116*a77ebd86Schristos			;; there has been no previous match at its
117*a77ebd86Schristos			;; level or none since the last default at
118*a77ebd86Schristos			;; that level.  It is useful for implementing
119*a77ebd86Schristos			;; switch-like and if/else constructions.
120*a77ebd86Schristos
121*a77ebd86Schristos------------------------------------------------------------------------
122*a77ebd86Schristostest = numtest | strtest | truetest
123*a77ebd86Schristos				;; Test to preform on <type> read from file.
124*a77ebd86Schristos
125*a77ebd86Schristosnumtest = [ compare ] NUMBER	;; If compare is missing, "=" is assumed.
126*a77ebd86Schristos
127*a77ebd86Schristosstrtest = [ compare ] STRING	;; If compare is missing, "=" is assumed.
128*a77ebd86Schristos				;; Note: If the STRING begins with a <compare>
129*a77ebd86Schristos				;; character, the <compare> field cannot be
130*a77ebd86Schristos				;; omitted.
131*a77ebd86Schristos
132*a77ebd86Schristoscompare = "=" | "!" | "<" | ">" | "&" | "^"
133*a77ebd86Schristos
134*a77ebd86Schristostruetest = "x"		;; This always returns true.
135*a77ebd86Schristos			;; To test for the string "x" use "=x".
136*a77ebd86Schristos
137*a77ebd86Schristos------------------------------------------------------------------------
138*a77ebd86Schristosmessage = [ nospflag ] ( STRING | FMT_STRING )
139*a77ebd86Schristos			;; Message to print if test result is true.
140*a77ebd86Schristos
141*a77ebd86Schristosnospflag = %x08 | "\\b"	;; Do not insert a space before the message.
142*a77ebd86Schristos			;; By default, messages are separated by a " ".
143*a77ebd86Schristos
144*a77ebd86Schristos------------------------------------------------------------------------
145*a77ebd86SchristosHWS = <horizontal white space>
146*a77ebd86SchristosEOL = <end of line marker>
147*a77ebd86SchristosNUMBER = <C-style unsigned number>
148*a77ebd86SchristosSTRING = <C-style string without delimiting quotes>
149*a77ebd86SchristosFMTSTR = <printf format string with exactly one % construct>
150*a77ebd86Schristos
151*a77ebd86Schristos------------------------------------------------------------------------
152