This is a first attempt to document the grammar used by magic(5), with hopes of eventually incorporating something like this into the manpage. Note: Currently, the parser varies slightly from this, but only in very minor ways, e.g., the strflags maybe separated by '/' characters and at most one strcount is allowed; likewise for regflags. ------------------------------------------------------------------------ magic = 1*query query = line *( 1*level line ) level = ">" ;; Increment the level by 1. ;; The first line of a query is at level 0. line = offset HWS type HWS test HWS message EOL ------------------------------------------------------------------------ offset = absoffset | reloffset | indoffset ;; The offset in the file at which to apply ;; the . absoffset = NUMBER ;; An absolute offset from the start of the file. reloffset = "&" NUMBER ;; The offset relative to the last match offset ;; at one level up. ;; Not allowed at level == 0. indoffset = indoff | relindoff indoff = "(" offset1 [ "." size ] [ op disp ] ")" ;; Read the file at of width . ;; If size is not specified, assume a long. ;; If is given, then preform that ;; operation on the result and the . offset1 = absoffset | reloffset size = byte | leshort | beshort | lelong | belong | melong byte = "B" | "b" | "C" | "c" ;; A one-byte value. leshort = "s" | "h" ;; A two-byte little-endian value. beshort = "S" | "H" ;; A two-byte big-endian value. lelong = "l" ;; A four-byte little-endian value. belong = "L" ;; A four-byte big-endian value. melong = "m" ;; A four-byte middle-endian value. op = [ invert ] ( "+" | "-" | "*" | "/" | "%" | "&" | "|" | "^" ) invert = "~" ;; Flip the bits on result of the . disp = NUMBER | memvalue memvalue = "(" NUMBER ")" ;; NUMBER is interpreted as an absolute or ;; relative offset matching that of . ;; Read the file at the resulting offset with ;; the same size as relindoff = "&" indoff ;; add to the last match offset at ;; one level up. ------------------------------------------------------------------------ type = [ unsigned ] ( numeric | strtype | default ) unsigned = "u" ;; The value is unsigned. ;; This affects the sign extension of numeric ;; types and the '<' and '>' compares. It is ;; intended for numeric types, but allowed on ;; all types. numeric = ( numtype | datatype ) [ nummask ] numtype = byte | short | long | quad byte = "byte" short = "short" | "beshort" | "leshort" long = "long" | "lelong" | "belong" | "melong" quad = "quad" | "lequad" | "bequad" datetype = udate32 | ldate32 | udate64 | ldate64 udate32 = "date" | "bedate" | "ledate" | "medate" ;; UTC dates ldate32 = "ldate" | "beldate" | "leldate" | "meldate" ;; local dates udate64 = "qdate" | "leqdate" | "beqdate" ;; UTC dates ldate64 = "qldate" | "leqldate" | "beqldate" ;; local dates nummask = op NUMBER strtype = regex | search | string8 | string16 regex = "regex" [ "/" 1*regflag ] regflag = "c" | "s" | linecnt linecnt = NUMBER ;; The number of lines to search. If this ;; is missing or zero, the rest of the ;; file is searched. search = "string" [ "/" 1*srchflag ] srchflag = strflag | srchcnt srchcnt = NUMBER ;; The number of search tries. If this ;; is missing or zero, the rest of the ;; file is searched. string8 = ( "string" | "pstring" ) [ "/" 1*strflag ] strflag = "b" | "B" | "c" | "C" string16 = "bestring16" | "lestring16" default = "default" ;; This is intended to be used with the ;; ("x" below). It is matched if ;; there has been no previous match at its ;; level or none since the last default at ;; that level. It is useful for implementing ;; switch-like and if/else constructions. ------------------------------------------------------------------------ test = numtest | strtest | truetest ;; Test to preform on read from file. numtest = [ compare ] NUMBER ;; If compare is missing, "=" is assumed. strtest = [ compare ] STRING ;; If compare is missing, "=" is assumed. ;; Note: If the STRING begins with a ;; character, the field cannot be ;; omitted. compare = "=" | "!" | "<" | ">" | "&" | "^" truetest = "x" ;; This always returns true. ;; To test for the string "x" use "=x". ------------------------------------------------------------------------ message = [ nospflag ] ( STRING | FMT_STRING ) ;; Message to print if test result is true. nospflag = %x08 | "\\b" ;; Do not insert a space before the message. ;; By default, messages are separated by a " ". ------------------------------------------------------------------------ HWS = EOL = NUMBER = STRING = FMTSTR = ------------------------------------------------------------------------