Commit 44ae83d0 44ae83d0d7776b365cee4cdc7f1d61e19513c951 by Sergey Poznyakoff

Switch mimeview to new locus and linetracker

* include/mailutils/locus.h (mu_stream_print_locus_point): New proto.
(mu_locus_range_copy): New proto.
* include/mailutils/yyloc.h (mu_file_print_locus_point)
(mu_file_print_locus_range): New protos.
(YY_LOCATION_PRINT): Redo using mu_file_print_locus_range.
* libmailutils/locus/filprloc.c: New file.
* libmailutils/locus/genprloc.c: New file.
* libmailutils/locus/strprloc.c: New file.
* libmailutils/locus/Makefile.am: Add new files.
* libmailutils/locus/debug.c (mu_stream_print_locus_range): Remove.
Declared elsewhere.
* libmailutils/locus/linetrack.c: use mu_locus_point_set_file,
instead of mu_locus_point_init.
* libmailutils/locus/locus.c: Likewise.
(mu_locus_range_copy)P: New function.
* mimeview/mimetypes.l: Provide rule for \n in ARGSTRING
Always print diagnostics before returning BOGUS
(lex_next_rule): Rewrite.  Print verbose diagnostics if app.trace6 is set.
(mimetypes_close): Deinitialize yylloc.
* mimeview/mimetypes.y: Catch the BOGUS token.
Adjust conflict expectation.
Properly reference assigned loci.
(mimetypes_parse): Return 1 if any errors detected.
* mimeview/mimeview.c: Use debug category app instead of mime.
* mimeview/tests/testsuite.at: Add new tests.
* libmailutils/stream/logstream.c (_log_done): Deinitialize
locus range.
1 parent 8ee676ca
......@@ -41,6 +41,8 @@ void mu_locus_point_deinit (struct mu_locus_point *pt);
int mu_locus_point_copy (struct mu_locus_point *dest,
struct mu_locus_point const *src);
int mu_locus_range_copy (struct mu_locus_range *dest,
struct mu_locus_range const *src);
void mu_locus_range_deinit (struct mu_locus_range *lr);
static inline int
......@@ -74,7 +76,8 @@ int mu_linetrack_locus (struct mu_linetrack *trk, struct mu_locus_point *lp);
int mu_linetrack_stat (mu_linetrack_t trk, struct mu_linetrack_stat *st);
int mu_linetrack_at_bol (struct mu_linetrack *trk);
void mu_stream_print_locus_point (mu_stream_t stream,
struct mu_locus_point const *lpt);
void mu_stream_print_locus_range (mu_stream_t stream,
struct mu_locus_range const *loc);
......
void mu_file_print_locus_point (FILE *,
struct mu_locus_point const *lpt);
void mu_file_print_locus_range (FILE *,
struct mu_locus_range const *loc);
#define YYLTYPE struct mu_locus_range
#define YYLLOC_DEFAULT(Current, Rhs, N) \
do \
......@@ -14,29 +19,7 @@
} \
} while (0)
#define YY_LOCATION_PRINT(File, Loc) \
do \
{ \
if (!mu_locus_point_same_file (&(Loc).beg, &(Loc).end)) \
fprintf (File, "%s:%u.%u-%s:%u.%u", \
(Loc).beg.mu_file, \
(Loc).beg.mu_line, (Loc).beg.mu_col, \
(Loc).end.mu_file, \
(Loc).end.mu_line, (Loc).end.mu_col); \
else if ((Loc).beg.mu_line != (Loc).end.mu_line) \
fprintf (File, "%s:%u.%u-%u.%u", \
(Loc).beg.mu_file, \
(Loc).beg.mu_line, (Loc).beg.mu_col, \
(Loc).end.mu_line, (Loc).end.mu_col); \
else if ((Loc).beg.mu_col != (Loc).end.mu_col) \
fprintf (File, "%s:%u.%u-%u", \
(Loc).beg.mu_file, \
(Loc).beg.mu_line, (Loc).beg.mu_col, \
(Loc).end.mu_col); \
else \
fprintf (File, "%s:%u.%u", \
(Loc).beg.mu_file, \
(Loc).beg.mu_line, (Loc).beg.mu_col); \
} while (0)
mu_file_print_locus_range (File, &(Loc))
......
......@@ -21,7 +21,11 @@ liblocus_la_SOURCES = \
ident.c\
debug.c\
linetrack.c\
locus.c
locus.c\
filprloc.c\
strprloc.c
EXTRA_DIST = genprloc.c
AM_CPPFLAGS = @MU_LIB_COMMON_INCLUDES@ -I/libmailutils
......
......@@ -9,50 +9,6 @@
#include <mailutils/stdstream.h>
void
mu_stream_print_locus_range (mu_stream_t stream,
struct mu_locus_range const *loc)
{
if (loc->beg.mu_col == 0)
{
if (loc->end.mu_file
&& (!mu_locus_point_same_file (&loc->beg, &loc->end)
|| loc->beg.mu_line != loc->end.mu_line))
mu_stream_printf (stream, "%s:%u-%u",
loc->beg.mu_file,
loc->beg.mu_line,
loc->end.mu_line);
else
mu_stream_printf (stream, "%s:%u",
loc->beg.mu_file,
loc->beg.mu_line);
}
else
{
if (loc->end.mu_file
&& !mu_locus_point_same_file (&loc->beg, &loc->end))
mu_stream_printf (stream, "%s:%u.%u-%s:%u.%u",
loc->beg.mu_file,
loc->beg.mu_line, loc->beg.mu_col,
loc->end.mu_file,
loc->end.mu_line, loc->end.mu_col);
else if (loc->end.mu_file && loc->beg.mu_line != loc->end.mu_line)
mu_stream_printf (stream, "%s:%u.%u-%u.%u",
loc->beg.mu_file,
loc->beg.mu_line, loc->beg.mu_col,
loc->end.mu_line, loc->end.mu_col);
else if (loc->end.mu_file && loc->beg.mu_col != loc->end.mu_col)
mu_stream_printf (stream, "%s:%u.%u-%u",
loc->beg.mu_file,
loc->beg.mu_line, loc->beg.mu_col,
loc->end.mu_col);
else
mu_stream_printf (stream, "%s:%u.%u",
loc->beg.mu_file,
loc->beg.mu_line, loc->beg.mu_col);
}
}
void
mu_stream_vlprintf (mu_stream_t stream,
struct mu_locus_range const *loc,
char const *fmt, va_list ap)
......
#include <stdio.h>
#define STREAM_TYPE FILE*
#define STREAM_PRINTF fprintf
#define PRINT_LOCUS_POINT mu_file_print_locus_point
#define PRINT_LOCUS_RANGE mu_file_print_locus_range
#include "genprloc.c"
#ifndef STREAM_TYPE
# error "STREAM_TYPE not defined"
#endif
#ifndef PRINT_LOCUS_POINT
# error "PRINT_LOCUS_POINT not defined"
#endif
#ifndef PRINT_LOCUS_RANGE
# error "PRINT_LOCUS_RANGE not defined"
#endif
#ifndef STREAM_PRINTF
# error "STREAM_PRINTF not defined"
#endif
#include <mailutils/types.h>
#include <mailutils/locus.h>
void
PRINT_LOCUS_POINT (STREAM_TYPE stream, struct mu_locus_point const *lp)
{
if (lp->mu_file)
{
STREAM_PRINTF (stream, "%s:%u",
lp->mu_file, lp->mu_line);
if (lp->mu_col)
STREAM_PRINTF (stream, ".%u", lp->mu_col);
}
}
void
PRINT_LOCUS_RANGE (STREAM_TYPE stream, struct mu_locus_range const *loc)
{
PRINT_LOCUS_POINT (stream, &loc->beg);
if (loc->end.mu_file)
{
if (!mu_locus_point_same_file (&loc->beg, &loc->end))
{
STREAM_PRINTF (stream, "-");
PRINT_LOCUS_POINT (stream, &loc->end);
}
else if (loc->beg.mu_line != loc->end.mu_line)
{
STREAM_PRINTF (stream, "-");
STREAM_PRINTF (stream, "%u", loc->end.mu_line);
if (loc->end.mu_col)
STREAM_PRINTF (stream, ".%u", loc->end.mu_col);
}
else if (loc->beg.mu_col
&& loc->beg.mu_col != loc->end.mu_col)
{
STREAM_PRINTF (stream, "-");
STREAM_PRINTF (stream, "%u", loc->end.mu_col);
}
}
}
......@@ -196,7 +196,7 @@ int
mu_linetrack_locus (struct mu_linetrack *trk, struct mu_locus_point *lp)
{
lp->mu_line = trk->hline + trk->tos;
return mu_locus_point_init (lp, trk->file_name);
return mu_locus_point_set_file (lp, trk->file_name);
}
int
......
......@@ -39,7 +39,26 @@ mu_locus_point_copy (struct mu_locus_point *dest,
{
dest->mu_col = src->mu_col;
dest->mu_line = src->mu_line;
return mu_locus_point_init (dest, src->mu_file);
return mu_locus_point_set_file (dest, src->mu_file);
}
int
mu_locus_range_copy (struct mu_locus_range *dest,
struct mu_locus_range const *src)
{
int rc;
struct mu_locus_range tmp = MU_LOCUS_RANGE_INITIALIZER;
rc = mu_locus_point_copy (&tmp.beg, &src->beg);
if (rc == 0)
{
rc = mu_locus_point_copy (&tmp.end, &src->end);
if (rc)
mu_locus_point_deinit (&tmp.beg);
else
*dest = tmp;
}
return rc;
}
void
......
#include <mailutils/types.h>
#include <mailutils/locus.h>
#include <mailutils/stream.h>
#define STREAM_TYPE mu_stream_t
#define STREAM_PRINTF mu_stream_printf
#define PRINT_LOCUS_POINT mu_stream_print_locus_point
#define PRINT_LOCUS_RANGE mu_stream_print_locus_range
#include "genprloc.c"
......@@ -305,6 +305,7 @@ static void
_log_done (struct _mu_stream *str)
{
struct _mu_log_stream *sp = (struct _mu_log_stream *)str;
mu_locus_range_deinit (&sp->locrange);
mu_stream_destroy (&sp->transport);
}
......
......@@ -43,6 +43,12 @@ digit_to_number (char c)
}
static void
drop_string (void)
{
mu_opool_clear (pool);
}
static void
finish_string (void)
{
mu_opool_append_char (pool, 0);
......@@ -100,6 +106,11 @@ WS [ \t][ \t]*
BEGIN (RULE);
return TYPE;
}
. {
mu_error (_("type/subtype is missing"));
return BOGUS;
}
}
<RULE>{
......@@ -147,8 +158,7 @@ WS [ \t][ \t]*
{WS} mu_error ("unexpected whitespace in argument list");
\n {
mu_error ("unexpected newline in argument list");
BEGIN (RULE);
return EOL;
return BOGUS;
}
. {
mu_locus_point_copy (&string_beg, &yylloc.beg);
......@@ -190,6 +200,12 @@ WS [ \t][ \t]*
mu_opool_append (pool, yytext, yyleng);
}
\n {
mu_error ("unexpected newline in argument");
drop_string ();
return BOGUS;
}
. {
mu_linetrack_retreat (trk, 1);
yyless (0);
......@@ -207,7 +223,7 @@ mimetypes_open (const char *name)
int mode;
char *filename;
yy_flex_debug = mu_debug_level_p (MU_DEBCAT_MIME, MU_DEBUG_TRACE4);
yy_flex_debug = mu_debug_level_p (MU_DEBCAT_APP, MU_DEBUG_TRACE4);
if (stat (name, &st))
{
......@@ -247,6 +263,7 @@ mimetypes_close ()
int mode;
fclose (yyin);
mu_locus_range_deinit (&yylloc);
mu_linetrack_destroy (&trk);
mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
MU_IOCTL_LOGSTREAM_GET_MODE, &mode);
......@@ -290,8 +307,10 @@ void
lex_next_rule (void)
{
int c;
if (yy_flex_debug)
int dbg = yy_flex_debug
|| mu_debug_level_p (MU_DEBCAT_APP, MU_DEBUG_TRACE6);
if (dbg)
{
YY_LOCATION_PRINT (stderr, yylloc);
fprintf (stderr, ": started error recovery\n");
......@@ -299,19 +318,14 @@ lex_next_rule (void)
while ((c = input ()) != EOF)
{
char ch = c;
mu_linetrack_advance (trk, &yylloc, &ch, 1);
if (c == '\n')
{
continue;
}
else if (mu_linetrack_at_bol (trk) && !(c == ' ' || c == '\t'))
if (!mu_isspace (c) && mu_linetrack_at_bol (trk))
{
mu_linetrack_retreat (trk, 1);
unput (c);
break;
}
mu_linetrack_advance (trk, &yylloc, &ch, 1);
}
if (yy_flex_debug)
if (dbg)
{
struct mu_locus_range lr = MU_LOCUS_RANGE_INITIALIZER;
mu_linetrack_locus (trk, &lr.beg);
......@@ -321,4 +335,5 @@ lex_next_rule (void)
}
BEGIN (RULE);
unput ('\n');
mu_linetrack_retreat (trk, 1);
}
......
......@@ -122,10 +122,11 @@ struct rule_tab
};
static mu_list_t rule_list;
static size_t errors;
%}
%locations
%expect 12
%expect 15
%token <string> TYPE IDENT
%token <string> STRING
......@@ -165,16 +166,21 @@ rule_line: /* empty */
p->type = $1.ptr;
p->node = $2;
p->priority = $3;
p->loc.beg = @1.beg;
p->loc.end = @3.end;
mu_locus_point_copy (&p->loc.beg, &@1.beg);
mu_locus_point_copy (&p->loc.end, &@3.end);
#if 0
YY_LOCATION_PRINT (stderr, p->loc);
fprintf (stderr, ": rule %s\n", p->type);
#endif
mu_list_append (rule_list, p);
}
| BOGUS
{
YYERROR;
}
| error
{
errors++;
if (arg_list)
mu_list_destroy (&arg_list);
arg_list = NULL;
......@@ -228,6 +234,10 @@ stmt : '!' stmt
$$ = make_suffix_node (&$1, &@1);
}
| function
| BOGUS
{
YYERROR;
}
;
priority : PRIORITY '(' arglist ')'
......@@ -280,6 +290,10 @@ arglist : arg
;
arg : STRING
| BOGUS
{
YYERROR;
}
;
%%
......@@ -290,10 +304,10 @@ mimetypes_parse (const char *name)
int rc;
if (mimetypes_open (name))
return 1;
yydebug = mu_debug_level_p (MU_DEBCAT_MIME, MU_DEBUG_TRACE3);
yydebug = mu_debug_level_p (MU_DEBCAT_APP, MU_DEBUG_TRACE3);
rc = yyparse ();
mimetypes_close ();
return rc || rule_list == NULL;
return rc || errors;
}
static struct node *
......@@ -301,7 +315,7 @@ make_node (enum node_type type, struct mu_locus_range const *loc)
{
struct node *p = mimetypes_malloc (sizeof *p);
p->type = type;
p->loc = *loc;
mu_locus_range_copy (&p->loc, loc);
return p;
}
......@@ -333,7 +347,7 @@ make_suffix_node (struct mimetypes_string *suffix,
node->v.suffix = *suffix;
return node;
}
struct builtin_tab
{
char *name;
......@@ -759,7 +773,7 @@ check_suffix (char *suf)
void
mime_debug (int lev, struct mu_locus_range const *loc, char const *fmt, ...)
{
if (mu_debug_level_p (MU_DEBCAT_MIME, lev))
if (mu_debug_level_p (MU_DEBCAT_APP, lev))
{
va_list ap;
......
......@@ -66,7 +66,7 @@ cli_debug (struct mu_parseopt *po, struct mu_option *opt,
lev = MU_DEBUG_LEVEL_UPTO (MU_DEBUG_TRACE2);
else
{
mu_debug_get_category_level (MU_DEBCAT_MIME, &lev);
mu_debug_get_category_level (MU_DEBCAT_APP, &lev);
for (; *arg; arg++)
{
switch (*arg)
......@@ -88,7 +88,7 @@ cli_debug (struct mu_parseopt *po, struct mu_option *opt,
}
}
}
mu_debug_set_category_level (MU_DEBCAT_MIME, lev);
mu_debug_set_category_level (MU_DEBCAT_APP, lev);
}
static void
......@@ -222,11 +222,11 @@ display_file (const char *file, const char *type)
argv[5] = (char*) mimeview_file;
argv[6] = NULL;
if (mu_debug_level_p (MU_DEBCAT_MIME, MU_DEBUG_TRACE0))
if (mu_debug_level_p (MU_DEBCAT_APP, MU_DEBUG_TRACE0))
{
char *string;
mu_argcv_string (6, argv, &string);
mu_debug (MU_DEBCAT_MIME, MU_DEBUG_TRACE0,
mu_debug (MU_DEBCAT_APP, MU_DEBUG_TRACE0,
(_("executing %s...\n"), string));
free (string);
}
......@@ -247,7 +247,7 @@ display_file (const char *file, const char *type)
{
display_stream_mailcap (mimeview_file, mimeview_stream, hdr,
no_ask_types, interactive, dry_run,
MU_DEBCAT_MIME);
MU_DEBCAT_APP);
mu_header_destroy (&hdr);
}
}
......@@ -264,9 +264,9 @@ main (int argc, char **argv)
if (dry_run)
{
mu_debug_level_t lev;
mu_debug_get_category_level (MU_DEBCAT_MIME, &lev);
mu_debug_get_category_level (MU_DEBCAT_APP, &lev);
lev |= MU_DEBUG_LEVEL_UPTO (MU_DEBUG_TRACE2);
mu_debug_set_category_level (MU_DEBCAT_MIME, lev);
mu_debug_set_category_level (MU_DEBCAT_APP, lev);
}
if (argc == 0 && !lint)
......
......@@ -40,8 +40,8 @@ $2: $4
m4_pushdef([build_expect],[__build_expect([],m4_shift(m4_shift($@)))])
# MIMETEST(NAME,TYPES,FILE,CONTENT,RES)
m4_pushdef([MIMETEST],[
# MIMEIDENTIFY(NAME,TYPES,FILE,CONTENT,RES)
m4_pushdef([MIMEIDENTIFY],[
AT_SETUP([$1])
AT_KEYWORDS([mimeview])
AT_CHECK([
......@@ -55,17 +55,29 @@ mimeview MIMEVIEW_OPTIONS --identify -f mime.types select_args($@)
AT_CLEANUP
])
m4_pushdef([MIMETEST],[
AT_SETUP([$1])
AT_KEYWORDS([mimeview])
AT_CHECK([
AT_DATA([mime.types],[$2
])
mimeview MIMEVIEW_OPTIONS --debug-level=app.=trace6 -t -f mime.types
],
m4_shift(m4_shift($@)))
AT_CLEANUP
])
dnl ------------------------------------------------------------
AT_INIT
AT_TESTED([mimeview])
MUT_VERSION([mimeview])
MIMETEST([default],
MIMEIDENTIFY([default],
[application/octet-stream],
[input], [], [application/octet-stream])
MIMETEST([suffixes],
MIMEIDENTIFY([suffixes],
[foo/x-bar bar baz
foo/x-qux qux quux
],
......@@ -74,13 +86,13 @@ foo/x-qux qux quux
[a.quux], [], [foo/x-qux],
[a.qx], [], [unknown])
MIMETEST([default ordering],
MIMEIDENTIFY([default ordering],
[text/foo bar
text/bar bar
],
[a.bar], [], [text/bar])
MIMETEST([priority],
MIMEIDENTIFY([priority],
[text/bar bar
text/foo bar priority(20)
],
......@@ -89,7 +101,7 @@ text/foo bar priority(20)
AT_BANNER([Functions])
# match("pattern") Pattern match on filename
MIMETEST([match],
MIMEIDENTIFY([match],
[application/x-csource match(*.c)
],
[a.c],[],[application/x-csource],
......@@ -97,7 +109,7 @@ MIMETEST([match],
# ascii(offset,length) True if bytes are valid printable ASCII
# (CR, NL, TAB, BS, 32-126)
MIMETEST([ascii],
MIMEIDENTIFY([ascii],
[application/x-bar ascii(16,6)
],
[one],[-seek 16 -string foobar -int 100],[application/x-bar],
......@@ -105,7 +117,7 @@ MIMETEST([ascii],
# printable(offset,length) True if bytes are printable 8-bit chars
# (CR, NL, TAB, BS, 32-126, 128-254)
MIMETEST([printable],
MIMEIDENTIFY([printable],
[application/x-bar printable(16,6)
],
[one],[-seek 16 -string foobar -int 100],[application/x-bar],
......@@ -113,14 +125,14 @@ MIMETEST([printable],
[three],[-seek 16 -string fooba -byte 127],[unknown])
# regex(offset,"regex") True if bytes match regular expression
MIMETEST([regex],
MIMEIDENTIFY([regex],
[application/pdf regex(0,^[[\n\r]]*%PDF)
],
[one],[-byte 10 -byte 10 -byte 13 -byte 10 -string %PDF],[application/pdf],
[two],[-byte 10 -byte 10 -byte 13 -byte 7 -string %PDF],[unknown])
# string(offset,"string") True if bytes are identical to string
MIMETEST([string],
MIMEIDENTIFY([string],
[application/x-foo string(5,FOO)
],
[one],[-seek 5 -string FOO],[application/x-foo],
......@@ -128,28 +140,28 @@ MIMETEST([string],
# istring(offset,"string") True if bytes are identical to
# case-insensitive string
MIMETEST([istring],
MIMEIDENTIFY([istring],
[application/x-foo istring(5,FOO)
],
[one],[-seek 5 -string foO],[application/x-foo],
[two],[-seek 4 -string FOO],[unknown])
# char(offset,value) True if byte is identical
MIMETEST([char],
MIMEIDENTIFY([char],
[application/x-foo char(5,15)
],
[one],[-seek 5 -byte 15],[application/x-foo],
[two],[-seek 5 -byte 1],[unknown])
# short(offset,value) True if 16-bit integer is identical
MIMETEST([short],
MIMEIDENTIFY([short],
[application/x-foo short(5,1600)
],
[one],[-seek 5 -short 1600],[application/x-foo],
[two],[-seek 5 -short 1601],[unknown])
# int(offset,value) True if 32-bit integer is identical
MIMETEST([int],
MIMEIDENTIFY([int],
[application/x-foo int(5,16578)
],
[one],[-seek 5 -int 16578],[application/x-foo],
......@@ -159,13 +171,13 @@ MIMETEST([int],
# FIXME
# contains(offset,range,"string") True if the range contains the string
MIMETEST([contains],
MIMEIDENTIFY([contains],
[application/x-foo contains(10,1024,"TESTSTRING")
],
[one],[-seek 512 -string TESTSTRING],[application/x-foo],
[two],[-seek 512 -string TEST],[unknown])
MIMETEST([argument strings],
MIMEIDENTIFY([argument strings],
[application/x-foo string(0,"FOO")
application/x-bar string(0,'B A R')
application/x-baz string(0,"B A"Z<1B0103>BAZ)
......@@ -176,7 +188,7 @@ application/x-qux string(0,<1B>45" Q "<01>)
[three],[-string "B AZ" -byte 0x1b -byte 0x01 -byte 0x03 -string BAZ],[application/x-baz],
[four],[-byte 0x1b -string '45 Q ' -byte 0x01],[application/x-qux])
MIMETEST([logical or],
MIMEIDENTIFY([logical or],
[text/x-bar bar baz string(0,bar) printable(3,10)
],
[one.bar],[],[text/x-bar],
......@@ -185,16 +197,53 @@ MIMETEST([logical or],
[bar],[-seek 3 -string teststring],[text/x-bar],
[baz],[-seek 3 -string test -byte 0 -string tring],[unknown])
MIMETEST([logical and],
MIMEIDENTIFY([logical and],
[text/x-foo bar + string(0,bar<10>) + printable(4,10)
],
[one.bar],[-string bar -byte 0x10 -string TESTSTRING],[text/x-foo],
[one],[-string bar -byte 0x10 -string TESTSTRING],[unknown],
[two.bar],[-string bar -byte 0x13 -byte 0x10 -string TEST],[unknown])
MIMETEST([grouping],
MIMEIDENTIFY([grouping],
[text/x-foo bar (string(0,bar) + printable(4,10))
],
[one.bar],[-string foo],[text/x-foo],
[two.baz],[-string bar -byte 0x10 -string TESTSTRING],[text/x-foo],
[three],[-string bar -byte 0x13 -byte 0x10 -string TESTSTRING],[unknown])
MIMETEST([error recovery],
[text/x-foo bar (string(0,bar) + printable(4,10))
string(10,baz)
application/x-baz
],
[1],
[],
[mimeview: mime.types:2.1: type/subtype is missing
mime.types:2.1: started error recovery
mime.types:3: finished error recovery
])
MIMETEST([multiple error recovery],
[text/x-foo bar (string(0,bar) + printable(4,10))
string(10,baz)
application/x-baz baz
image/jpeg jpeg jpg jpe string(0,<FFD8FF>) &&\
(char(3,0xe0) char(3,0xe1) char(3,0xe2) char(3,0xe3)\
char(3,0xe4) char(3,0xe5) char(3,0xe6) char(3,0xe7)
char(3,0xe8) char(3,0xe9) char(3,0xea) char(3,0xeb)\
char(3,0xec) char(3,0xed) char(3,0xee) char(3,0xef))
image/tiff tiff tif string(0,MM<002A>) string(0,II<2A00>)
],
[1],
[],
[mimeview: mime.types:2.1: type/subtype is missing
mime.types:2.1: started error recovery
mime.types:3: finished error recovery
mimeview: mime.types:6.63: syntax error
mime.types:6.63: started error recovery
mime.types:9: finished error recovery
])
m4_popdef([MIMETEST])
m4_popdef([MIMEIDENTIFY])
\ No newline at end of file
......