1/*
2 * fontconfig/fc-list/fc-list.c
3 *
4 * Copyright © 2002 Keith Packard
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 the author(s) not be used in
11 * advertising or publicity pertaining to distribution of the software without
12 * specific, written prior permission.  The authors make no
13 * representations about the suitability of this software for any purpose.  It
14 * is provided "as is" without express or implied warranty.
15 *
16 * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18 * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22 * PERFORMANCE OF THIS SOFTWARE.
23 */
24
25#ifdef HAVE_CONFIG_H
26#include <config.h>
27#else
28#ifdef linux
29#define HAVE_GETOPT_LONG 1
30#endif
31#define HAVE_GETOPT 1
32#endif
33#include <fontconfig/fontconfig.h>
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37#include <locale.h>
38
39#ifdef HAVE_UNISTD_H
40#include <unistd.h>
41#endif
42
43#ifdef ENABLE_NLS
44#include <libintl.h>
45#define _(x)		(dgettext(GETTEXT_PACKAGE, x))
46#else
47#define dgettext(d, s)	(s)
48#define _(x)		(x)
49#endif
50
51#ifndef HAVE_GETOPT
52#define HAVE_GETOPT 0
53#endif
54#ifndef HAVE_GETOPT_LONG
55#define HAVE_GETOPT_LONG 0
56#endif
57
58#if HAVE_GETOPT_LONG
59#undef  _GNU_SOURCE
60#define _GNU_SOURCE
61#include <getopt.h>
62const struct option longopts[] = {
63    {"verbose", 0, 0, 'v'},
64    {"brief", 0, 0, 'b'},
65    {"format", 1, 0, 'f'},
66    {"quiet", 0, 0, 'q'},
67    {"version", 0, 0, 'V'},
68    {"help", 0, 0, 'h'},
69    {NULL,0,0,0},
70};
71#else
72#if HAVE_GETOPT
73extern char *optarg;
74extern int optind, opterr, optopt;
75#endif
76#endif
77
78static void
79usage (char *program, int error)
80{
81    FILE *file = error ? stderr : stdout;
82#if HAVE_GETOPT_LONG
83    fprintf (file, _("usage: %s [-vbqVh] [-f FORMAT] [--verbose] [--brief] [--format=FORMAT] [--quiet] [--version] [--help] [pattern] {element ...} \n"),
84	     program);
85#else
86    fprintf (file, _("usage: %s [-vbqVh] [-f FORMAT] [pattern] {element ...} \n"),
87	     program);
88#endif
89    fprintf (file, _("List fonts matching [pattern]\n"));
90    fprintf (file, "\n");
91#if HAVE_GETOPT_LONG
92    fprintf (file, _("  -v, --verbose        display entire font pattern verbosely\n"));
93    fprintf (file, _("  -b, --brief          display entire font pattern briefly\n"));
94    fprintf (file, _("  -f, --format=FORMAT  use the given output format\n"));
95    fprintf (file, _("  -q, --quiet          suppress all normal output, exit 1 if no fonts matched\n"));
96    fprintf (file, _("  -V, --version        display font config version and exit\n"));
97    fprintf (file, _("  -h, --help           display this help and exit\n"));
98#else
99    fprintf (file, _("  -v         (verbose) display entire font pattern verbosely\n"));
100    fprintf (file, _("  -b         (brief)   display entire font pattern briefly\n"));
101    fprintf (file, _("  -f FORMAT  (format)  use the given output format\n"));
102    fprintf (file, _("  -q,        (quiet)   suppress all normal output, exit 1 if no fonts matched\n"));
103    fprintf (file, _("  -V         (version) display font config version and exit\n"));
104    fprintf (file, _("  -h         (help)    display this help and exit\n"));
105#endif
106    exit (error);
107}
108
109int
110main (int argc, char **argv)
111{
112    int			verbose = 0;
113    int			brief = 0;
114    int			quiet = 0;
115    const FcChar8	*format = NULL;
116    int			nfont = 0;
117    int			i;
118    FcObjectSet		*os = 0;
119    FcFontSet		*fs;
120    FcPattern		*pat;
121#if HAVE_GETOPT_LONG || HAVE_GETOPT
122    int			c;
123
124    setlocale (LC_ALL, "");
125#if HAVE_GETOPT_LONG
126    while ((c = getopt_long (argc, argv, "vbf:qVh", longopts, NULL)) != -1)
127#else
128    while ((c = getopt (argc, argv, "vbf:qVh")) != -1)
129#endif
130    {
131	switch (c) {
132	case 'v':
133	    verbose = 1;
134	    break;
135	case 'b':
136	    brief = 1;
137	    break;
138	case 'f':
139	    format = (FcChar8 *) strdup (optarg);
140	    break;
141	case 'q':
142	    quiet = 1;
143	    break;
144	case 'V':
145	    fprintf (stderr, "fontconfig version %d.%d.%d\n",
146		     FC_MAJOR, FC_MINOR, FC_REVISION);
147	    exit (0);
148	case 'h':
149	    usage (argv[0], 0);
150	default:
151	    usage (argv[0], 1);
152	}
153    }
154    i = optind;
155#else
156    i = 1;
157#endif
158
159    if (argv[i])
160    {
161	pat = FcNameParse ((FcChar8 *) argv[i]);
162	if (!pat)
163	{
164	    fprintf (stderr, _("Unable to parse the pattern\n"));
165	    return 1;
166	}
167	while (argv[++i])
168	{
169	    if (!os)
170		os = FcObjectSetCreate ();
171	    FcObjectSetAdd (os, argv[i]);
172	}
173    }
174    else
175	pat = FcPatternCreate ();
176    if (quiet && !os)
177	os = FcObjectSetCreate ();
178    if (!verbose && !brief && !format && !os)
179	os = FcObjectSetBuild (FC_FAMILY, FC_STYLE, FC_FILE, (char *) 0);
180    if (!format)
181        format = (const FcChar8 *) "%{=fclist}\n";
182    fs = FcFontList (0, pat, os);
183    if (os)
184	FcObjectSetDestroy (os);
185    if (pat)
186	FcPatternDestroy (pat);
187
188    if (!quiet && fs)
189    {
190	int	j;
191
192	for (j = 0; j < fs->nfont; j++)
193	{
194	    if (verbose || brief)
195	    {
196		if (brief)
197		{
198		    FcPatternDel (fs->fonts[j], FC_CHARSET);
199		    FcPatternDel (fs->fonts[j], FC_LANG);
200		}
201		FcPatternPrint (fs->fonts[j]);
202	    }
203	    else
204	    {
205	        FcChar8 *s;
206
207		s = FcPatternFormat (fs->fonts[j], format);
208		if (s)
209		{
210		    printf ("%s", s);
211		    FcStrFree (s);
212		}
213	    }
214	}
215    }
216
217    if (fs) {
218	nfont = fs->nfont;
219	FcFontSetDestroy (fs);
220    }
221
222    FcFini ();
223
224    return quiet ? (nfont == 0 ? 1 : 0) : 0;
225}
226