@@ -51,7 +51,7 @@ static struct option longopts[] =
5151static void usage (FILE * s , const char * prog_name )
5252{
5353 fprintf (s ,
54- "usage: %s [OPTIONS]\n"
54+ "usage: %s [OPTIONS] [file ...] \n"
5555"options:\n"
5656" -1 Only parse the first statement or client-command.\n"
5757" --ast, -a Dump the AST to stdout.\n"
@@ -64,6 +64,8 @@ static void usage(FILE *s, const char *prog_name)
6464" the entire input first (note: will result in inconsistent\n"
6565" formatting of AST dumps).\n"
6666" --version Output the version of cypher-lint and libcypher-parser\n"
67+ "\n"
68+ "If no input files are specified, then input is read from standard input.\n"
6769"\n" ,
6870 prog_name );
6971}
@@ -80,18 +82,19 @@ struct lint_config
8082};
8183
8284
83- static int process (FILE * stream , struct lint_config * config );
84- static int process_streamed (FILE * stream , struct lint_config * config ,
85- cypher_parser_config_t * cp_config ,
85+ static int process (FILE * stream , const char * filename ,
86+ struct lint_config * config );
87+ static int process_streamed (FILE * stream , const char * filename ,
88+ struct lint_config * config , cypher_parser_config_t * cp_config ,
8689 const struct cypher_parser_colorization * error_colorization ,
8790 const struct cypher_parser_colorization * output_colorization );
88- static int process_all (FILE * stream , struct lint_config * config ,
89- cypher_parser_config_t * cp_config ,
91+ static int process_all (FILE * stream , const char * filename ,
92+ struct lint_config * config , cypher_parser_config_t * cp_config ,
9093 const struct cypher_parser_colorization * error_colorization ,
9194 const struct cypher_parser_colorization * output_colorization );
9295static int parse_callback (void * data , cypher_parse_segment_t * segment );
93- static void print_error (const cypher_parse_error_t * error ,
94- const struct cypher_parser_colorization * colorization );
96+ static void print_error (const cypher_parse_error_t * error , const char * filename ,
97+ const struct cypher_parser_colorization * colorization );
9598
9699
97100int main (int argc , char * argv [])
@@ -169,9 +172,45 @@ int main(int argc, char *argv[])
169172 config .stream = true;
170173 }
171174
172- if (process ( stdin , & config ) )
175+ if (argc > 0 )
173176 {
174- goto cleanup ;
177+ int err = 0 ;
178+ for (; argc > 0 ; -- argc , ++ argv )
179+ {
180+ int res ;
181+ if (strcmp (* argv , "-" ) == 0 )
182+ {
183+ res = process (stdin , "<stdin>" , & config );
184+ }
185+ else
186+ {
187+ FILE * stream = fopen (* argv , "r" );
188+ if (stream == NULL )
189+ {
190+ fprintf (stderr , "%s: %s: %s\n" , prog_name , * argv ,
191+ strerror (errno ));
192+ goto cleanup ;
193+ }
194+ res = process (stream , * argv , & config );
195+ if (res < 0 )
196+ {
197+ goto cleanup ;
198+ }
199+ fclose (stream );
200+ }
201+ err |= res ;
202+ }
203+ if (err )
204+ {
205+ goto cleanup ;
206+ }
207+ }
208+ else
209+ {
210+ if (process (stdin , NULL , & config ))
211+ {
212+ goto cleanup ;
213+ }
175214 }
176215
177216 result = EXIT_SUCCESS ;
@@ -181,7 +220,7 @@ int main(int argc, char *argv[])
181220}
182221
183222
184- int process (FILE * stream , struct lint_config * config )
223+ int process (FILE * stream , const char * filename , struct lint_config * config )
185224{
186225 cypher_parser_config_t * cp_config = cypher_parser_new_config ();
187226 if (cp_config == NULL )
@@ -202,9 +241,9 @@ int process(FILE *stream, struct lint_config *config)
202241 config -> colorize_output ? cypher_parser_ansi_colorization : NULL ;
203242
204243 int err = (config -> stream )?
205- process_streamed (stream , config , cp_config ,
244+ process_streamed (stream , filename , config , cp_config ,
206245 error_colorization , output_colorization ) :
207- process_all (stream , config , cp_config ,
246+ process_all (stream , filename , config , cp_config ,
208247 error_colorization , output_colorization );
209248
210249 int errsv = errno ;
@@ -216,20 +255,22 @@ int process(FILE *stream, struct lint_config *config)
216255
217256struct parse_callback_data
218257{
258+ const char * filename ;
219259 struct lint_config * config ;
220260 const struct cypher_parser_colorization * error_colorization ;
221261 const struct cypher_parser_colorization * output_colorization ;
222262 unsigned int nerrors ;
223263};
224264
225265
226- int process_streamed (FILE * stream , struct lint_config * config ,
227- cypher_parser_config_t * cp_config ,
266+ int process_streamed (FILE * stream , const char * filename ,
267+ struct lint_config * config , cypher_parser_config_t * cp_config ,
228268 const struct cypher_parser_colorization * error_colorization ,
229269 const struct cypher_parser_colorization * output_colorization )
230270{
231271 struct parse_callback_data callback_data =
232- { .config = config ,
272+ { .filename = filename ,
273+ .config = config ,
233274 .error_colorization = error_colorization ,
234275 .output_colorization = output_colorization ,
235276 .nerrors = 0
@@ -256,7 +297,7 @@ int parse_callback(void *data, cypher_parse_segment_t *segment)
256297 const cypher_parse_error_t * error ;
257298 for (; (error = cypher_parse_segment_get_error (segment , i )) != NULL ; ++ i )
258299 {
259- print_error (error , cbdata -> error_colorization );
300+ print_error (error , cbdata -> filename , cbdata -> error_colorization );
260301 }
261302
262303 cbdata -> nerrors += i ;
@@ -272,8 +313,8 @@ int parse_callback(void *data, cypher_parse_segment_t *segment)
272313}
273314
274315
275- int process_all (FILE * stream , struct lint_config * config ,
276- cypher_parser_config_t * cp_config ,
316+ int process_all (FILE * stream , const char * filename ,
317+ struct lint_config * config , cypher_parser_config_t * cp_config ,
277318 const struct cypher_parser_colorization * error_colorization ,
278319 const struct cypher_parser_colorization * output_colorization )
279320{
@@ -291,14 +332,21 @@ int process_all(FILE *stream, struct lint_config *config,
291332 const cypher_parse_error_t * error ;
292333 for (; (error = cypher_parse_result_get_error (result , i )) != NULL ; ++ i )
293334 {
294- print_error (error , error_colorization );
335+ print_error (error , filename , error_colorization );
295336 }
296337
297- if (config -> dump_ast && cypher_parse_result_fprint_ast (result , stdout ,
298- config -> width , output_colorization , 0 ) < 0 )
338+ if (config -> dump_ast )
299339 {
300- perror ("cypher_parse_result_fprint_ast" );
301- goto cleanup ;
340+ if (filename != NULL )
341+ {
342+ printf ("%s:\n" , filename );
343+ }
344+ if (cypher_parse_result_fprint_ast (result , stdout ,
345+ config -> width , output_colorization , 0 ) < 0 )
346+ {
347+ perror ("cypher_parse_result_fprint_ast" );
348+ goto cleanup ;
349+ }
302350 }
303351
304352 err = (cypher_parse_result_nerrors (result ) == 0 )? 0 : 1 ;
@@ -312,15 +360,14 @@ int process_all(FILE *stream, struct lint_config *config,
312360}
313361
314362
315- void print_error (const cypher_parse_error_t * error ,
363+ void print_error (const cypher_parse_error_t * error , const char * filename ,
316364 const struct cypher_parser_colorization * colorization )
317365{
318366 struct cypher_input_position pos = cypher_parse_error_position (error );
319367 const char * msg = cypher_parse_error_message (error );
320368 const char * context = cypher_parse_error_context (error );
321369 unsigned int offset = cypher_parse_error_context_offset (error );
322- fprintf (stderr , "%s %s(line %u, column %u, offset %zu)%s%s\n" , msg ,
323- colorization -> error_message [0 ], pos .line , pos .column , pos .offset ,
324- colorization -> error_message [1 ], (context == NULL )? "" : ":" );
370+ fprintf (stderr , "%s:%u:%u: %s\n" , (filename != NULL )? filename : "<stdin>" ,
371+ pos .line , pos .column , msg );
325372 fprintf (stderr , "%s\n%*.*s^\n" , context , offset , offset , " " );
326373}
0 commit comments