66624ae090e53848b7acca0296b066dca908f732
[debian/amanda] / recover-src / uscan.l
1 /*
2  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3  * Copyright (c) 1991-2000 University of Maryland at College Park
4  * All Rights Reserved.
5  *
6  * Permission to use, copy, modify, distribute, and sell this software and its
7  * documentation for any purpose is hereby granted without fee, provided that
8  * the above copyright notice appear in all copies and that both that
9  * copyright notice and this permission notice appear in supporting
10  * documentation, and that the name of U.M. not be used in advertising or
11  * publicity pertaining to distribution of the software without specific,
12  * written prior permission.  U.M. makes no representations about the
13  * suitability of this software for any purpose.  It is provided "as is"
14  * without express or implied warranty.
15  *
16  * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
18  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22  *
23  * Authors: the Amanda Development Team.  Its members are listed in a
24  * file named AUTHORS, in the root directory of this distribution.
25  */
26 /*
27  * $Id: uscan.l,v 1.22 2004/02/11 13:03:29 martinea Exp $
28  *
29  * lexer for amrecover interactive language
30  */
31 %{
32 #include "amanda.h"
33 #undef ECHO
34 #include "uparse.h"
35
36 #define YY_NO_UNPUT
37
38 #define DATE_ALLOC_SIZE         sizeof("YYYY-MM-DD")    /* includes null */
39
40 extern void yyerror P((char *s));
41 extern int  yyparse P((void));
42 static int  ll_parse_date P((int type, char *text));
43 %}
44
45 %x quotedstring
46
47 %{
48 static char *string_buf = NULL;
49 %}
50
51 %%
52
53 %{
54     /* literal keyword tokens */
55 %}
56
57 listdisk        { return LISTDISK; }
58 sethost { return SETHOST; }
59 setdisk { return SETDISK; }
60 setdate { return SETDATE; }
61 setmode { return SETMODE; }
62 settape { return SETTAPE; }
63 cd      { return CD; }
64 cdx     { return CDX; }
65 quit    { return QUIT; }
66 exit    { return QUIT; }
67 history { return DHIST; }
68 ls      { return LS; }
69 add     { return ADD; }
70 addx    { return ADDX; }
71 list    { return LIST; }
72 delete  { return DELETE; }
73 deletex { return DELETEX; }
74 pwd     { return PWD; }
75 clear   { return CLEAR; }
76 help    { return HELP; }
77 \?      { return HELP; }
78 lcd     { return LCD; }
79 lpwd    { return LPWD; }
80 extract { return EXTRACT; }
81 smb     { return SMB; }
82 tar     { return TAR; }
83 mode    { return MODE; }
84
85 %{
86     /* dates */
87 %}
88
89 ---[0-9]+               { return ll_parse_date(1, yytext); }
90 --[0-9]+-[0-9]+         { return ll_parse_date(2, yytext); }
91 [0-9]+-[0-9]+-[0-9]+    { return ll_parse_date(3, yytext); }
92
93 %{
94     /* file names */
95 %}
96
97 [^ \t\r"]+              {
98   yylval.strval = stralloc(yytext); return PATH;
99 }
100
101 %{
102     /* quoted file names */
103 %}
104
105 \"               { if(string_buf != NULL) {printf("ERROR:string_buf != NULL: %s\n",string_buf);}; BEGIN(quotedstring); }
106
107 <quotedstring>\"        { /* saw closing quote - all done */
108   BEGIN(INITIAL);
109   if(string_buf) {
110     yylval.strval = string_buf;
111     string_buf = NULL;
112   } else {
113     yylval.strval = "";
114   }
115   return PATH;
116 }
117
118 <quotedstring>\\\" {
119   /* escaped quote */
120   strappend(string_buf, "\\\"");
121 }
122
123 <quotedstring>\n        {
124   /* error - unterminated string constant */
125   yyerror("unterminated string");
126   amfree(string_buf);
127 }
128
129 <quotedstring>[^\\\n\"]+        { strappend(string_buf, yytext); }
130
131 %{
132     /* whitespace */
133 %}
134
135 [ \t\r]+        ;     /* whitespace */
136
137 %{
138     /* anything else */
139     /* everything should have been handled by now, so this rule is disabled */
140 %}
141
142 %{
143 #if 0
144 .       { yyerror("invalid character"); }
145 #endif
146 %}
147
148 %%
149
150 int process_line(line)
151 char *line;
152 {
153     YY_BUFFER_STATE b;
154     int result;
155
156     b = yy_scan_string(line);           /* tell lex to scan lineread */
157     result = yyparse();                 /* parse lineread and act */
158     yy_delete_buffer(b);
159     return result;
160 }
161
162 static int ll_parse_date(type, text)
163 int type;
164 char *text;
165 {
166     time_t now;
167     struct tm *t;
168     int y, m, d;
169     int ret;
170
171     now = time((time_t *)NULL);
172     t = localtime(&now);
173     y = 1900+t->tm_year;
174     m = t->tm_mon+1;
175     d = t->tm_mday;
176     if(type == 1) {
177         sscanf(text, "---%d", &d);
178     } else if(type == 2) {
179         sscanf(text, "--%d-%d", &m, &d);
180     } else {
181         sscanf(text, "%d-%d-%d", &y, &m, &d);
182         if(y < 70) {
183             y += 2000;
184         } else if(y < 100) {
185             y += 1900;
186         }
187     }
188     ret = PATH;                         /* cause a parse error */
189     if(y < 1000 || y > 9999) {
190         yyerror("invalid year");
191     } else if(m < 1 || m > 12) {
192         yyerror("invalid month");
193     } else if(d < 1 || d > 31) {
194         yyerror("invalid day");
195     } else {
196         yylval.strval = alloc(DATE_ALLOC_SIZE);
197         snprintf(yylval.strval, DATE_ALLOC_SIZE, "%04d-%02d-%02d", y, m, d);
198         ret = DATE;
199     }
200     return ret;
201 }
202
203 int yywrap() {
204   return 1;
205 }