Blame view

mimeview/mimetypes.l 5.35 KB
Sergey Poznyakoff authored
1
%top {
2
/* GNU Mailutils -- a suite of utilities for electronic mail
3
   Copyright (C) 2005, 2007, 2009-2012, 2014-2016 Free Software
4
   Foundation, Inc.
5 6 7

   GNU Mailutils is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
8
   the Free Software Foundation; either version 3, or (at your option)
9 10 11 12 13 14 15 16
   any later version.

   GNU Mailutils is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
17
   along with GNU Mailutils.  If not, see <http://www.gnu.org/licenses/>. */
18 19 20 21

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
Sergey Poznyakoff authored
22
}
23

Sergey Poznyakoff authored
24
%{
25 26 27
#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>
28 29
#include <mimeview.h>
#include <mimetypes-decl.h>  
30
#include <mailutils/io.h>
31

32
static int line_num;
33
static char *file_name;
34 35
static int file_name_alloc; 
 
36
static mu_opool_t pool;
37 38 39 40 41 42 43 44 45 46
static int prev_state;
 
static unsigned 
digit_to_number (char c)
{
  return (unsigned) (c >= '0' && c <= '9' ? c-'0' :
                     c >= 'A' && c <= 'Z' ? c-'A'+10 :
                     c-'a'+10);
}
%}
47 48 49 50

%option nounput
%option noinput
	  
51 52 53 54 55 56 57 58 59 60 61 62 63
%x ARGS HEX
X [0-9a-fA-F]
IDENT [a-zA-Z_\.][a-zA-Z0-9_\.-]*
WS [ \t]*
%%
     /* Comments */
<INITIAL>#.*\n       { line_num++; }
<INITIAL>#.*         /* end-of-file comment */;
     /* Tokens */
\\\n                 { line_num++; }
\n                   { line_num++; return EOL; }
{WS}                 ;
{IDENT}              {
64 65 66
  mu_opool_append (pool, yytext, yyleng);
  mu_opool_append_char (pool, 0);
  yylval.string.ptr = mu_opool_finish (pool, &yylval.string.len);
67 68 69
  return IDENT;
}
<INITIAL>{IDENT}"("           {
70 71 72
  mu_opool_append (pool, yytext, yyleng-1);
  mu_opool_append_char (pool, 0);
  yylval.string.ptr = mu_opool_finish (pool, &yylval.string.len);
73 74 75 76
  BEGIN(ARGS);
  return IDENT_L;
}
<INITIAL,ARGS>\"[^\\"\n]*\"        {
77 78 79
  mu_opool_append (pool, yytext+1, yyleng-2);
  mu_opool_append_char (pool, 0);
  yylval.string.ptr = mu_opool_finish (pool, &yylval.string.len);
80 81 82 83 84 85 86
  return STRING;
}
<INITIAL,ARGS>"<" {
  prev_state = YYSTATE;
  BEGIN(HEX);
}
<ARGS>[^ \t<\\\n),]+/[),] {
87 88 89
  mu_opool_append (pool, yytext, yyleng);
  mu_opool_append_char (pool, 0);
  yylval.string.ptr = mu_opool_finish (pool, &yylval.string.len);
90 91 92
  return STRING;
}
<ARGS>[^ \t<\\\n),]+< {
93
  mu_opool_append (pool, yytext, yyleng);
94 95 96
  prev_state = YYSTATE;
  BEGIN(HEX);
}
97
<INITIAL>[^ \t<\\\n)+,&]/[ \t\\\n)+,&] {
98 99 100
  mu_opool_append (pool, yytext, yyleng);
  mu_opool_append_char (pool, 0);
  yylval.string.ptr = mu_opool_finish (pool, &yylval.string.len);
101 102 103
  return STRING;
}
<ARGS>[^ \t<\\\n),]/[ \t\\\n] {
104 105 106
  mu_opool_append (pool, yytext, yyleng);
  mu_opool_append_char (pool, 0);
  yylval.string.ptr = mu_opool_finish (pool, &yylval.string.len);
107 108 109
  return STRING;
}
<HEX>{X}{X} {
Sergey Poznyakoff authored
110
  int c = digit_to_number (yytext[0])*16 + digit_to_number (yytext[1]);
111
  mu_opool_append_char (pool, c);
112 113 114
}
<HEX>">"/[ \t\\\n,)] {
  BEGIN(prev_state);
115 116
  mu_opool_append_char (pool, 0);
  yylval.string.ptr = mu_opool_finish (pool, &yylval.string.len);
117 118 119 120 121 122 123 124 125 126
  return STRING;
}
<HEX>">" {
  BEGIN(prev_state);
}
  /* Special cases: && and ||. Docs don't say anything about them, but
     I've found them in my mime.types file...         --Sergey */
"&&"  return '+';
"||"  return ',';
  /* Operators */
127
"!"|"+"|","|"("|")"|"/"  return yytext[0];
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
<ARGS>","        return yytext[0];
<ARGS>")"        { BEGIN(INITIAL); return yytext[0]; }
<INITIAL,ARGS,HEX>. {
 fprintf (stderr, "Invalid character '%c', state %d\n", yytext[0], YYSTATE);
 abort();
}
%%

void
mimetypes_lex_debug (int level)
{
  yy_flex_debug = level;
}

int
mimetypes_open (const char *name)
{
  struct stat st;
  if (stat (name, &st))
    {
148
      mu_error (_("cannot stat `%s': %s"), name, mu_strerror (errno));
149 150 151 152 153
      return -1;
    }
  
  if (S_ISDIR (st.st_mode))
    {
154
      file_name = mu_make_file_name (name, "mime.types");
155 156 157 158
      file_name_alloc = 1;
    }
  else
    {
159
      file_name = (char*) name;
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
      file_name_alloc = 0;
    }
  
  yyin = fopen (file_name, "r");
  if (!yyin)
    {
      mu_error (_("Cannot open `%s': %s"), file_name, mu_strerror (errno));
      if (file_name_alloc)
	{
	  free (file_name);
	  file_name_alloc = 0;
	}
      return -1;
    }
  line_num = 1;
Sergey Poznyakoff authored
175
  mu_opool_create (&pool, MU_OPOOL_ENOMEMABRT);
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
  return 0;
}

void
mimetypes_close ()
{
  fclose (yyin);
  if (file_name_alloc)
    {
      free (file_name);
      file_name_alloc = 0;
    }
}

int
yyerror (char *s)
{
Sergey Poznyakoff authored
193
  mu_error ("%s:%d: %s", file_name, line_num, s);
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
  return 0;
}

int
yywrap ()
{
  return 1;
}

struct mimetypes_string
mimetypes_append_string2 (struct mimetypes_string *s1,
			  char c,
			  struct mimetypes_string *s2)
{
  struct mimetypes_string r;

  r.len = s1->len + s2->len + 1;
211 212 213 214 215
  mu_opool_append (pool, s1->ptr, s1->len);
  mu_opool_append_char (pool, c);
  mu_opool_append (pool, s2->ptr, s2->len);
  mu_opool_append_char (pool, 0);
  r.ptr = mu_opool_finish (pool, NULL);
216 217 218 219 220 221
  return r;
}

struct mimetypes_string *     
mimetypes_string_dup (struct mimetypes_string *s)
{
222 223
  mu_opool_append (pool, s, sizeof *s);
  return mu_opool_finish (pool, NULL);
224 225 226 227 228
}

void *
mimetypes_malloc (size_t size)
{
229 230
  mu_opool_alloc (pool, size);
  return mu_opool_finish (pool, NULL);
231 232 233 234 235 236 237 238 239
}

void
reset_lex ()
{
  BEGIN(INITIAL);
}