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