+2013-04-22 11:20 Christos Zoulas <christos@zoulas.com>
+
+ * The way "default" was implemented was not very useful
+ because the "if something was printed at that level"
+ was not easily controlled by the user, and the format
+ was bound to a string which is too restrictive. Add
+ a "clear" for that level keyword and make "default"
+ void. This way one can do:
+
+ >>13 clear x
+ >>13 lelong 1 foo
+ >>13 lelong 2 bar
+ >>13 default x
+ >>>13 lelong x unknown %x
+
2013-03-25 13:20 Christos Zoulas <christos@zoulas.com>
* disallow strength setting in "name" entries
-.\" $File: magic.man,v 1.77 2013/01/08 01:37:01 christos Exp $
-.Dd January 7, 2013
+.\" $File: magic.man,v 1.78 2013/01/09 13:04:30 christos Exp $
+.Dd April 22, 2013
.Dt MAGIC __FSECTION__
.Os
.\" install as magic.4 on USG, magic.5 on V7, Berkeley and Linux systems.
.It Dv default
This is intended to be used with the test
.Em x
-(which is always true) and a message that is to be used if there are
-no other matches.
+(which is always true) and it has no type.
+It matches when no other test at that continuation level has matched before.
+Clearing that matched tests for a continuation level, can be done using the
+.Dv clear
+test.
+.It Dv clear
+This test is always true and clears the match flag for that continuation level.
+It is intended to be used with the
+.Dv default
+test.
.El
.Pp
For compatibility with the Single
\*[Gt]\*[Gt]\*[Gt]\*[Am](\*[Am]0x54.l-3) string UNACE \eb, ACE self-extracting archive
.Ed
.Pp
-Finally, if you have to deal with offset/length pairs in your file, even the
+If you have to deal with offset/length pairs in your file, even the
second value in a parenthesized expression can be taken from the file itself,
using another set of parentheses.
Note that this additional indirect offset is always relative to the
# these are located 14 and 10 bytes after the section name
\*[Gt]\*[Gt]\*[Gt]\*[Gt](\*[Am]0xe.l+(-4)) string PK\e3\e4 \eb, ZIP self-extracting archive
.Ed
+.Pp
+If you have a list of known avalues at a particular continuation level,
+and you want to provide a switch-like default case:
+.Bd -literal -offset indent
+# clear that continuation level match
+\*[Gt]18 clear
+\*[Gt]18 lelong 1 one
+\*[Gt]18 lelong 2 two
+\*[Gt]18 default x
+# print default match
+\*[Gt]\*[Gt]18 lelong x unmatched 0x%x
+.Ed
.Sh SEE ALSO
.Xr file __CSECTION__
\- the command that reads this file.
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: apprentice.c,v 1.191 2013/02/26 21:02:48 christos Exp $")
+FILE_RCSID("@(#)$File: apprentice.c,v 1.192 2013/03/25 17:20:43 christos Exp $")
#endif /* lint */
#include "magic.h"
{ XX("invalid"), FILE_INVALID, FILE_FMT_NONE },
{ XX("byte"), FILE_BYTE, FILE_FMT_NUM },
{ XX("short"), FILE_SHORT, FILE_FMT_NUM },
- { XX("default"), FILE_DEFAULT, FILE_FMT_STR },
+ { XX("default"), FILE_DEFAULT, FILE_FMT_NONE },
{ XX("long"), FILE_LONG, FILE_FMT_NUM },
{ XX("string"), FILE_STRING, FILE_FMT_STR },
{ XX("date"), FILE_DATE, FILE_FMT_STR },
{ XX("beqwdate"), FILE_BEQWDATE, FILE_FMT_STR },
{ XX("name"), FILE_NAME, FILE_FMT_NONE },
{ XX("use"), FILE_USE, FILE_FMT_NONE },
+ { XX("clear"), FILE_CLEAR, FILE_FMT_NONE },
{ XX_NULL, FILE_INVALID, FILE_FMT_NONE },
};
case FILE_INDIRECT:
case FILE_NAME:
case FILE_USE:
+ case FILE_CLEAR:
break;
default:
if (ms->flags & MAGIC_CHECK)
*/
/*
* file.h - definitions for file(1) program
- * @(#)$File: file.h,v 1.143 2013/01/25 23:07:19 christos Exp $
+ * @(#)$File: file.h,v 1.144 2013/02/18 15:40:59 christos Exp $
*/
#ifndef __file_h__
#define MAXstring 64 /* max len of "string" types */
#define MAGICNO 0xF11E041C
-#define VERSIONNO 10
+#define VERSIONNO 11
#define FILE_MAGICSIZE 248
#define FILE_LOAD 0
#define FILE_BEQWDATE 44
#define FILE_NAME 45
#define FILE_USE 46
-#define FILE_NAMES_SIZE 47 /* size of array to contain all names */
+#define FILE_CLEAR 47
+#define FILE_NAMES_SIZE 48 /* size of array to contain all names */
#define IS_STRING(t) \
((t) == FILE_STRING || \
(t) == FILE_REGEX || \
(t) == FILE_SEARCH || \
(t) == FILE_NAME || \
- (t) == FILE_USE || \
- (t) == FILE_DEFAULT)
+ (t) == FILE_USE)
#define FILE_FMT_NONE 0
#define FILE_FMT_NUM 1 /* "cduxXi" */
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: softmagic.c,v 1.165 2013/03/07 02:22:24 christos Exp $")
+FILE_RCSID("@(#)$File: softmagic.c,v 1.166 2013/04/03 14:38:29 christos Exp $")
#endif /* lint */
#include "magic.h"
#ifdef ENABLE_CONDITIONALS
ms->c.li[cont_level].last_match = 1;
#endif
- if (m->type != FILE_DEFAULT)
- ms->c.li[cont_level].got_match = 1;
- else if (ms->c.li[cont_level].got_match) {
+ if (m->type == FILE_CLEAR)
ms->c.li[cont_level].got_match = 0;
- break;
- }
+ else if (ms->c.li[cont_level].got_match) {
+ if (m->type == FILE_DEFAULT)
+ break;
+ } else
+ ms->c.li[cont_level].got_match = 1;
if ((e = handle_annotation(ms, m)) != 0) {
*returnval = 1;
return e;
break;
case FILE_DEFAULT:
- if (file_printf(ms, m->desc, m->value.s) == -1)
+ case FILE_CLEAR:
+ if (file_printf(ms, "%s", m->desc) == -1)
return -1;
t = ms->offset;
break;
else
return CAST(int32_t, (ms->search.offset + m->vallen));
+ case FILE_CLEAR:
case FILE_DEFAULT:
- return ms->offset;
-
case FILE_INDIRECT:
return ms->offset;
case FILE_REGEX:
case FILE_SEARCH:
case FILE_DEFAULT:
+ case FILE_CLEAR:
case FILE_NAME:
case FILE_USE:
return 1;
return -1;
return 1;
case FILE_DEFAULT: /* nothing to check */
+ case FILE_CLEAR:
default:
break;
}
return matched;
case FILE_DEFAULT:
+ case FILE_CLEAR:
l = 0;
v = 0;
break;