12c393a42Smrg/*
2a6844aabSmrg * fontconfig/fc-list/fc-list.c
32c393a42Smrg *
42c393a42Smrg * Copyright © 2002 Keith Packard
52c393a42Smrg *
62c393a42Smrg * Permission to use, copy, modify, distribute, and sell this software and its
72c393a42Smrg * documentation for any purpose is hereby granted without fee, provided that
82c393a42Smrg * the above copyright notice appear in all copies and that both that
92c393a42Smrg * copyright notice and this permission notice appear in supporting
10ca08ab68Smrg * documentation, and that the name of the author(s) not be used in
112c393a42Smrg * advertising or publicity pertaining to distribution of the software without
12ca08ab68Smrg * specific, written prior permission.  The authors make no
132c393a42Smrg * representations about the suitability of this software for any purpose.  It
142c393a42Smrg * is provided "as is" without express or implied warranty.
152c393a42Smrg *
16a6844aabSmrg * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
172c393a42Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18a6844aabSmrg * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
192c393a42Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
202c393a42Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
212c393a42Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
222c393a42Smrg * PERFORMANCE OF THIS SOFTWARE.
232c393a42Smrg */
242c393a42Smrg
252c393a42Smrg#ifdef HAVE_CONFIG_H
262c393a42Smrg#include <config.h>
272c393a42Smrg#else
282c393a42Smrg#ifdef linux
292c393a42Smrg#define HAVE_GETOPT_LONG 1
302c393a42Smrg#endif
312c393a42Smrg#define HAVE_GETOPT 1
322c393a42Smrg#endif
33a4e54154Smrg#include <fontconfig/fontconfig.h>
34a4e54154Smrg#include <stdio.h>
35a4e54154Smrg#include <stdlib.h>
36a4e54154Smrg#include <string.h>
37a4e54154Smrg#include <locale.h>
38a4e54154Smrg
39a4e54154Smrg#ifdef HAVE_UNISTD_H
40a4e54154Smrg#include <unistd.h>
41a4e54154Smrg#endif
422c393a42Smrg
43a32e9e42Smrg#ifdef ENABLE_NLS
44a32e9e42Smrg#include <libintl.h>
45a32e9e42Smrg#define _(x)		(dgettext(GETTEXT_PACKAGE, x))
46a32e9e42Smrg#else
47a32e9e42Smrg#define dgettext(d, s)	(s)
48a32e9e42Smrg#define _(x)		(x)
49a32e9e42Smrg#endif
50a32e9e42Smrg
512c393a42Smrg#ifndef HAVE_GETOPT
522c393a42Smrg#define HAVE_GETOPT 0
532c393a42Smrg#endif
542c393a42Smrg#ifndef HAVE_GETOPT_LONG
552c393a42Smrg#define HAVE_GETOPT_LONG 0
562c393a42Smrg#endif
572c393a42Smrg
582c393a42Smrg#if HAVE_GETOPT_LONG
592c393a42Smrg#undef  _GNU_SOURCE
602c393a42Smrg#define _GNU_SOURCE
612c393a42Smrg#include <getopt.h>
622c393a42Smrgconst struct option longopts[] = {
632c393a42Smrg    {"verbose", 0, 0, 'v'},
64a32e9e42Smrg    {"brief", 0, 0, 'b'},
65a6844aabSmrg    {"format", 1, 0, 'f'},
66a6844aabSmrg    {"quiet", 0, 0, 'q'},
67a6844aabSmrg    {"version", 0, 0, 'V'},
68a6844aabSmrg    {"help", 0, 0, 'h'},
692c393a42Smrg    {NULL,0,0,0},
702c393a42Smrg};
712c393a42Smrg#else
722c393a42Smrg#if HAVE_GETOPT
732c393a42Smrgextern char *optarg;
742c393a42Smrgextern int optind, opterr, optopt;
752c393a42Smrg#endif
762c393a42Smrg#endif
772c393a42Smrg
78a6844aabSmrgstatic void
79a6844aabSmrgusage (char *program, int error)
802c393a42Smrg{
81a6844aabSmrg    FILE *file = error ? stderr : stdout;
822c393a42Smrg#if HAVE_GETOPT_LONG
83a32e9e42Smrg    fprintf (file, _("usage: %s [-vbqVh] [-f FORMAT] [--verbose] [--brief] [--format=FORMAT] [--quiet] [--version] [--help] [pattern] {element ...} \n"),
842c393a42Smrg	     program);
852c393a42Smrg#else
86a32e9e42Smrg    fprintf (file, _("usage: %s [-vbqVh] [-f FORMAT] [pattern] {element ...} \n"),
872c393a42Smrg	     program);
882c393a42Smrg#endif
89a32e9e42Smrg    fprintf (file, _("List fonts matching [pattern]\n"));
90a6844aabSmrg    fprintf (file, "\n");
912c393a42Smrg#if HAVE_GETOPT_LONG
92a32e9e42Smrg    fprintf (file, _("  -v, --verbose        display entire font pattern verbosely\n"));
93a32e9e42Smrg    fprintf (file, _("  -b, --brief          display entire font pattern briefly\n"));
94a32e9e42Smrg    fprintf (file, _("  -f, --format=FORMAT  use the given output format\n"));
95a32e9e42Smrg    fprintf (file, _("  -q, --quiet          suppress all normal output, exit 1 if no fonts matched\n"));
96a32e9e42Smrg    fprintf (file, _("  -V, --version        display font config version and exit\n"));
97a32e9e42Smrg    fprintf (file, _("  -h, --help           display this help and exit\n"));
982c393a42Smrg#else
99a32e9e42Smrg    fprintf (file, _("  -v         (verbose) display entire font pattern verbosely\n"));
100a32e9e42Smrg    fprintf (file, _("  -b         (brief)   display entire font pattern briefly\n"));
101a32e9e42Smrg    fprintf (file, _("  -f FORMAT  (format)  use the given output format\n"));
102a32e9e42Smrg    fprintf (file, _("  -q,        (quiet)   suppress all normal output, exit 1 if no fonts matched\n"));
103a32e9e42Smrg    fprintf (file, _("  -V         (version) display font config version and exit\n"));
104a32e9e42Smrg    fprintf (file, _("  -h         (help)    display this help and exit\n"));
1052c393a42Smrg#endif
106a6844aabSmrg    exit (error);
1072c393a42Smrg}
1082c393a42Smrg
1092c393a42Smrgint
1102c393a42Smrgmain (int argc, char **argv)
1112c393a42Smrg{
112ca08ab68Smrg    int			verbose = 0;
113a32e9e42Smrg    int			brief = 0;
114ca08ab68Smrg    int			quiet = 0;
115ca08ab68Smrg    const FcChar8	*format = NULL;
116ca08ab68Smrg    int			nfont = 0;
117ca08ab68Smrg    int			i;
118ca08ab68Smrg    FcObjectSet		*os = 0;
119ca08ab68Smrg    FcFontSet		*fs;
120ca08ab68Smrg    FcPattern		*pat;
1212c393a42Smrg#if HAVE_GETOPT_LONG || HAVE_GETOPT
122ca08ab68Smrg    int			c;
1232c393a42Smrg
124a32e9e42Smrg    setlocale (LC_ALL, "");
1252c393a42Smrg#if HAVE_GETOPT_LONG
126a32e9e42Smrg    while ((c = getopt_long (argc, argv, "vbf:qVh", longopts, NULL)) != -1)
1272c393a42Smrg#else
128a32e9e42Smrg    while ((c = getopt (argc, argv, "vbf:qVh")) != -1)
1292c393a42Smrg#endif
1302c393a42Smrg    {
1312c393a42Smrg	switch (c) {
132a6844aabSmrg	case 'v':
133a6844aabSmrg	    verbose = 1;
134a6844aabSmrg	    break;
135a32e9e42Smrg	case 'b':
136a32e9e42Smrg	    brief = 1;
137a32e9e42Smrg	    break;
138a6844aabSmrg	case 'f':
139a6844aabSmrg	    format = (FcChar8 *) strdup (optarg);
140a6844aabSmrg	    break;
141a6844aabSmrg	case 'q':
142a6844aabSmrg	    quiet = 1;
143a6844aabSmrg	    break;
1442c393a42Smrg	case 'V':
145a6844aabSmrg	    fprintf (stderr, "fontconfig version %d.%d.%d\n",
1462c393a42Smrg		     FC_MAJOR, FC_MINOR, FC_REVISION);
1472c393a42Smrg	    exit (0);
148a6844aabSmrg	case 'h':
149a6844aabSmrg	    usage (argv[0], 0);
1502c393a42Smrg	default:
151a6844aabSmrg	    usage (argv[0], 1);
1522c393a42Smrg	}
1532c393a42Smrg    }
1542c393a42Smrg    i = optind;
1552c393a42Smrg#else
1562c393a42Smrg    i = 1;
1572c393a42Smrg#endif
1582c393a42Smrg
1592c393a42Smrg    if (argv[i])
1602c393a42Smrg    {
1612c393a42Smrg	pat = FcNameParse ((FcChar8 *) argv[i]);
1626fc018e4Smrg	if (!pat)
1636fc018e4Smrg	{
164a32e9e42Smrg	    fprintf (stderr, _("Unable to parse the pattern\n"));
1656fc018e4Smrg	    return 1;
1666fc018e4Smrg	}
1672c393a42Smrg	while (argv[++i])
1682c393a42Smrg	{
1692c393a42Smrg	    if (!os)
1702c393a42Smrg		os = FcObjectSetCreate ();
1712c393a42Smrg	    FcObjectSetAdd (os, argv[i]);
1722c393a42Smrg	}
1732c393a42Smrg    }
1742c393a42Smrg    else
1752c393a42Smrg	pat = FcPatternCreate ();
176a6844aabSmrg    if (quiet && !os)
177a6844aabSmrg	os = FcObjectSetCreate ();
178a32e9e42Smrg    if (!verbose && !brief && !format && !os)
179ca08ab68Smrg	os = FcObjectSetBuild (FC_FAMILY, FC_STYLE, FC_FILE, (char *) 0);
180ca08ab68Smrg    if (!format)
181ca08ab68Smrg        format = (const FcChar8 *) "%{=fclist}\n";
1822c393a42Smrg    fs = FcFontList (0, pat, os);
183a6844aabSmrg    if (os)
184a6844aabSmrg	FcObjectSetDestroy (os);
1852c393a42Smrg    if (pat)
1862c393a42Smrg	FcPatternDestroy (pat);
1872c393a42Smrg
188a6844aabSmrg    if (!quiet && fs)
1892c393a42Smrg    {
1902c393a42Smrg	int	j;
1912c393a42Smrg
1922c393a42Smrg	for (j = 0; j < fs->nfont; j++)
1932c393a42Smrg	{
194a32e9e42Smrg	    if (verbose || brief)
195a6844aabSmrg	    {
196a32e9e42Smrg		if (brief)
197a32e9e42Smrg		{
198a32e9e42Smrg		    FcPatternDel (fs->fonts[j], FC_CHARSET);
199a32e9e42Smrg		    FcPatternDel (fs->fonts[j], FC_LANG);
200a32e9e42Smrg		}
201a6844aabSmrg		FcPatternPrint (fs->fonts[j]);
202a6844aabSmrg	    }
203ca08ab68Smrg	    else
204a6844aabSmrg	    {
205a6844aabSmrg	        FcChar8 *s;
206a6844aabSmrg
207a6844aabSmrg		s = FcPatternFormat (fs->fonts[j], format);
208a6844aabSmrg		if (s)
209a6844aabSmrg		{
210a6844aabSmrg		    printf ("%s", s);
211ca08ab68Smrg		    FcStrFree (s);
212a6844aabSmrg		}
213a6844aabSmrg	    }
2142c393a42Smrg	}
215a6844aabSmrg    }
216a6844aabSmrg
217a6844aabSmrg    if (fs) {
218a6844aabSmrg	nfont = fs->nfont;
2192c393a42Smrg	FcFontSetDestroy (fs);
2202c393a42Smrg    }
2212c393a42Smrg
2222c393a42Smrg    FcFini ();
2232c393a42Smrg
224a6844aabSmrg    return quiet ? (nfont == 0 ? 1 : 0) : 0;
2252c393a42Smrg}
226