BNF 4.9 KB

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