1ca08ab68Smrg/*
2ca08ab68Smrg * fontconfig/fc-pattern/fc-pattern.c
3ca08ab68Smrg *
4ca08ab68Smrg * Copyright © 2003 Keith Packard
5ca08ab68Smrg *
6ca08ab68Smrg * Permission to use, copy, modify, distribute, and sell this software and its
7ca08ab68Smrg * documentation for any purpose is hereby granted without fee, provided that
8ca08ab68Smrg * the above copyright notice appear in all copies and that both that
9ca08ab68Smrg * copyright notice and this permission notice appear in supporting
10ca08ab68Smrg * documentation, and that the name of the author(s) not be used in
11ca08ab68Smrg * advertising or publicity pertaining to distribution of the software without
12ca08ab68Smrg * specific, written prior permission.  The authors make no
13ca08ab68Smrg * representations about the suitability of this software for any purpose.  It
14ca08ab68Smrg * is provided "as is" without express or implied warranty.
15ca08ab68Smrg *
16ca08ab68Smrg * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17ca08ab68Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18ca08ab68Smrg * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19ca08ab68Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20ca08ab68Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21ca08ab68Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22ca08ab68Smrg * PERFORMANCE OF THIS SOFTWARE.
23ca08ab68Smrg */
24ca08ab68Smrg
25ca08ab68Smrg#ifdef HAVE_CONFIG_H
26ca08ab68Smrg#include <config.h>
27ca08ab68Smrg#else
28ca08ab68Smrg#ifdef linux
29ca08ab68Smrg#define HAVE_GETOPT_LONG 1
30ca08ab68Smrg#endif
31ca08ab68Smrg#define HAVE_GETOPT 1
32ca08ab68Smrg#endif
33ca08ab68Smrg
34ca08ab68Smrg#include <fontconfig/fontconfig.h>
35ca08ab68Smrg#include <stdio.h>
36ca08ab68Smrg#include <stdlib.h>
37ca08ab68Smrg#include <string.h>
38a32e9e42Smrg#include <locale.h>
39a32e9e42Smrg
40a4e54154Smrg#ifdef HAVE_UNISTD_H
41a4e54154Smrg#include <unistd.h>
42a4e54154Smrg#endif
43a4e54154Smrg
44a32e9e42Smrg#ifdef ENABLE_NLS
45a32e9e42Smrg#include <libintl.h>
46a32e9e42Smrg#define _(x)		(dgettext(GETTEXT_PACKAGE, x))
47a32e9e42Smrg#else
48a32e9e42Smrg#define dgettext(d, s)	(s)
49a32e9e42Smrg#define _(x)		(x)
50a32e9e42Smrg#endif
51ca08ab68Smrg
52ca08ab68Smrg#ifndef HAVE_GETOPT
53ca08ab68Smrg#define HAVE_GETOPT 0
54ca08ab68Smrg#endif
55ca08ab68Smrg#ifndef HAVE_GETOPT_LONG
56ca08ab68Smrg#define HAVE_GETOPT_LONG 0
57ca08ab68Smrg#endif
58ca08ab68Smrg
59ca08ab68Smrg#if HAVE_GETOPT_LONG
60ca08ab68Smrg#undef  _GNU_SOURCE
61ca08ab68Smrg#define _GNU_SOURCE
62ca08ab68Smrg#include <getopt.h>
63ca08ab68Smrgstatic const struct option longopts[] = {
64ca08ab68Smrg    {"config", 0, 0, 'c'},
65ca08ab68Smrg    {"default", 0, 0, 'd'},
66ca08ab68Smrg    {"format", 1, 0, 'f'},
67ca08ab68Smrg    {"version", 0, 0, 'V'},
68ca08ab68Smrg    {"help", 0, 0, 'h'},
69ca08ab68Smrg    {NULL,0,0,0},
70ca08ab68Smrg};
71ca08ab68Smrg#else
72ca08ab68Smrg#if HAVE_GETOPT
73ca08ab68Smrgextern char *optarg;
74ca08ab68Smrgextern int optind, opterr, optopt;
75ca08ab68Smrg#endif
76ca08ab68Smrg#endif
77ca08ab68Smrg
78ca08ab68Smrgstatic void
79ca08ab68Smrgusage (char *program, int error)
80ca08ab68Smrg{
81ca08ab68Smrg    FILE *file = error ? stderr : stdout;
82ca08ab68Smrg#if HAVE_GETOPT_LONG
83a32e9e42Smrg    fprintf (file, _("usage: %s [-cdVh] [-f FORMAT] [--config] [--default] [--verbose] [--format=FORMAT] [--version] [--help] [pattern] {element...}\n"),
84ca08ab68Smrg	     program);
85ca08ab68Smrg#else
86a32e9e42Smrg    fprintf (file, _("usage: %s [-cdVh] [-f FORMAT] [pattern] {element...}\n"),
87ca08ab68Smrg	     program);
88ca08ab68Smrg#endif
89a32e9e42Smrg    fprintf (file, _("List best font matching [pattern]\n"));
90ca08ab68Smrg    fprintf (file, "\n");
91ca08ab68Smrg#if HAVE_GETOPT_LONG
92a32e9e42Smrg    fprintf (file, _("  -c, --config         perform config substitution on pattern\n"));
93a32e9e42Smrg    fprintf (file, _("  -d, --default        perform default substitution on pattern\n"));
94a32e9e42Smrg    fprintf (file, _("  -f, --format=FORMAT  use the given output format\n"));
95a32e9e42Smrg    fprintf (file, _("  -V, --version        display font config version and exit\n"));
96a32e9e42Smrg    fprintf (file, _("  -h, --help           display this help and exit\n"));
97ca08ab68Smrg#else
98a32e9e42Smrg    fprintf (file, _("  -c,        (config)  perform config substitution on pattern\n"));
99a32e9e42Smrg    fprintf (file, _("  -d,        (default) perform default substitution on pattern\n"));
100a32e9e42Smrg    fprintf (file, _("  -f FORMAT  (format)  use the given output format\n"));
101a32e9e42Smrg    fprintf (file, _("  -V         (version) display font config version and exit\n"));
102a32e9e42Smrg    fprintf (file, _("  -h         (help)    display this help and exit\n"));
103ca08ab68Smrg#endif
104ca08ab68Smrg    exit (error);
105ca08ab68Smrg}
106ca08ab68Smrg
107ca08ab68Smrgint
108ca08ab68Smrgmain (int argc, char **argv)
109ca08ab68Smrg{
110ca08ab68Smrg    int		do_config = 0, do_default = 0;
111ca08ab68Smrg    FcChar8     *format = NULL;
112ca08ab68Smrg    int		i;
113ca08ab68Smrg    FcObjectSet *os = 0;
114ca08ab68Smrg    FcPattern   *pat;
115ca08ab68Smrg#if HAVE_GETOPT_LONG || HAVE_GETOPT
116ca08ab68Smrg    int		c;
117ca08ab68Smrg
118a32e9e42Smrg    setlocale (LC_ALL, "");
119ca08ab68Smrg#if HAVE_GETOPT_LONG
120ca08ab68Smrg    while ((c = getopt_long (argc, argv, "cdf:Vh", longopts, NULL)) != -1)
121ca08ab68Smrg#else
122ca08ab68Smrg    while ((c = getopt (argc, argv, "cdf:Vh")) != -1)
123ca08ab68Smrg#endif
124ca08ab68Smrg    {
125ca08ab68Smrg	switch (c) {
126ca08ab68Smrg	case 'c':
127ca08ab68Smrg	    do_config = 1;
128ca08ab68Smrg	    break;
129ca08ab68Smrg	case 'd':
130ca08ab68Smrg	    do_default = 1;
131ca08ab68Smrg	    break;
132ca08ab68Smrg	case 'f':
133ca08ab68Smrg	    format = (FcChar8 *) strdup (optarg);
134ca08ab68Smrg	    break;
135ca08ab68Smrg	case 'V':
136ca08ab68Smrg	    fprintf (stderr, "fontconfig version %d.%d.%d\n",
137ca08ab68Smrg		     FC_MAJOR, FC_MINOR, FC_REVISION);
138ca08ab68Smrg	    exit (0);
139ca08ab68Smrg	case 'h':
140ca08ab68Smrg	    usage (argv[0], 0);
141ca08ab68Smrg	default:
142ca08ab68Smrg	    usage (argv[0], 1);
143ca08ab68Smrg	}
144ca08ab68Smrg    }
145ca08ab68Smrg    i = optind;
146ca08ab68Smrg#else
147ca08ab68Smrg    i = 1;
148ca08ab68Smrg#endif
149ca08ab68Smrg
150ca08ab68Smrg    if (argv[i])
151ca08ab68Smrg    {
152ca08ab68Smrg	pat = FcNameParse ((FcChar8 *) argv[i]);
1536fc018e4Smrg	if (!pat)
1546fc018e4Smrg	{
155a32e9e42Smrg	    fprintf (stderr, _("Unable to parse the pattern\n"));
1566fc018e4Smrg	    return 1;
1576fc018e4Smrg	}
158ca08ab68Smrg	while (argv[++i])
159ca08ab68Smrg	{
160ca08ab68Smrg	    if (!os)
161ca08ab68Smrg		os = FcObjectSetCreate ();
162ca08ab68Smrg	    FcObjectSetAdd (os, argv[i]);
163ca08ab68Smrg	}
164ca08ab68Smrg    }
165ca08ab68Smrg    else
166ca08ab68Smrg	pat = FcPatternCreate ();
167ca08ab68Smrg
168ca08ab68Smrg    if (!pat)
169ca08ab68Smrg	return 1;
170ca08ab68Smrg
171ca08ab68Smrg    if (do_config)
172ca08ab68Smrg      FcConfigSubstitute (0, pat, FcMatchPattern);
173ca08ab68Smrg    if (do_default)
174ca08ab68Smrg      FcDefaultSubstitute (pat);
175ca08ab68Smrg
176ca08ab68Smrg    if (os)
177ca08ab68Smrg    {
178ca08ab68Smrg      FcPattern *new;
179ca08ab68Smrg      new = FcPatternFilter (pat, os);
180ca08ab68Smrg      FcPatternDestroy (pat);
181ca08ab68Smrg      pat = new;
182ca08ab68Smrg    }
183ca08ab68Smrg
184ca08ab68Smrg    if (format)
185ca08ab68Smrg    {
186ca08ab68Smrg	FcChar8 *s;
187ca08ab68Smrg
188ca08ab68Smrg	s = FcPatternFormat (pat, format);
189ca08ab68Smrg	if (s)
190ca08ab68Smrg	{
191ca08ab68Smrg	    printf ("%s", s);
192ca08ab68Smrg	    FcStrFree (s);
193ca08ab68Smrg	}
194ca08ab68Smrg    }
195ca08ab68Smrg    else
196ca08ab68Smrg    {
197ca08ab68Smrg	FcPatternPrint (pat);
198ca08ab68Smrg    }
199ca08ab68Smrg
200ca08ab68Smrg    FcPatternDestroy (pat);
201ca08ab68Smrg
202ca08ab68Smrg    if (os)
203ca08ab68Smrg	FcObjectSetDestroy (os);
204ca08ab68Smrg
205ca08ab68Smrg    FcFini ();
206ca08ab68Smrg
207ca08ab68Smrg    return 0;
208ca08ab68Smrg}
209