line-reader: New library for reading a file line-by-line.
[pspp] / tests / libpspp / line-reader-test.c
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 2010, 2011 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
16
17 #include <config.h>
18
19 #include "libpspp/line-reader.h"
20
21 #include <errno.h>
22 #include <fcntl.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <unistd.h>
27
28 #include "libpspp/i18n.h"
29 #include "libpspp/str.h"
30
31 #include "gl/error.h"
32 #include "gl/progname.h"
33 #include "gl/xalloc.h"
34
35 static void
36 usage (void)
37 {
38   printf ("usage: %s COMMAND [ARG]...\n"
39           "The available commands are:\n"
40           "  help\n"
41           "    print this usage message\n"
42           "  buffer-size\n"
43           "    print the buffer size, in bytes, on stdout\n"
44           "  read FILE ENCODING\n"
45           "    read FILE encoded in ENCODING and print it in UTF-8\n",
46           program_name);
47   exit (0);
48 }
49
50 static void
51 cmd_read (int argc, char *argv[])
52 {
53   struct line_reader *r;
54   const char *filename;
55   struct string line;
56   char *encoding;
57
58   if (argc != 4)
59     error (1, 0, "bad syntax for `%s' command; use `%s help' for help",
60            argv[1], program_name);
61
62   filename = argv[2];
63
64   r = (!strcmp(filename, "-")
65        ? line_reader_for_fd (argv[3], STDIN_FILENO)
66        : line_reader_for_file (argv[3], filename, O_RDONLY));
67   if (r == NULL)
68     error (1, errno, "line_reader_open failed");
69
70   encoding = xstrdup (line_reader_get_encoding (r));
71   printf ("encoded in %s", encoding);
72   if (line_reader_is_auto (r))
73     printf (" (auto)");
74   printf ("\n");
75
76   ds_init_empty (&line);
77   while (line_reader_read (r, &line, SIZE_MAX))
78     {
79       const char *new_encoding;
80       char *utf8_line;
81
82       new_encoding = line_reader_get_encoding (r);
83       if (strcmp (encoding, new_encoding))
84         {
85           free (encoding);
86           encoding = xstrdup (new_encoding);
87
88           printf ("encoded in %s", encoding);
89           if (line_reader_is_auto (r))
90             printf (" (auto)");
91           printf ("\n");
92         }
93
94       utf8_line = recode_string ("UTF-8", encoding,
95                                  ds_data (&line), ds_length (&line));
96       printf ("\"%s\"\n", utf8_line);
97       free (utf8_line);
98
99       ds_clear (&line);
100     }
101
102   if (!strcmp(filename, "-"))
103     line_reader_free (r);
104   else
105     {
106       if (line_reader_close (r) != 0)
107         error (1, errno, "line_reader_close failed");
108     }
109 }
110
111 int
112 main (int argc, char *argv[])
113 {
114   set_program_name (argv[0]);
115   i18n_init ();
116
117   if (argc < 2)
118     error (1, 0, "missing command name; use `%s help' for help", program_name);
119   else if (!strcmp(argv[1], "help") || !strcmp(argv[1], "--help"))
120     usage ();
121   else if (!strcmp(argv[1], "buffer-size"))
122     printf ("%d\n", LINE_READER_BUFFER_SIZE);
123   else if (!strcmp(argv[1], "read"))
124     cmd_read (argc, argv);
125   else
126     error (1, 0, "unknown command `%s'; use `%s help' for help",
127            argv[1], program_name);
128
129   return 0;
130 }