summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/pdftexdir/mapfile.c
diff options
context:
space:
mode:
authorMartin Schröder <martin@oneiros.de>2006-12-26 23:37:34 +0000
committerMartin Schröder <martin@oneiros.de>2006-12-26 23:37:34 +0000
commit812aa90acbef4930ae356ab194f3f2a8f573f6e4 (patch)
treea1b8b3d895238994c60580df9e6f0619b2034923 /Build/source/texk/web2c/pdftexdir/mapfile.c
parente3bba99884ce591c9485122e96fff7071fc7c112 (diff)
Import pdftex 1.40-rc4, which also changes the signature of
print_version_and_exit, and adds a new library (libs/obsdcompat). git-svn-id: svn://tug.org/texlive/trunk@2959 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/pdftexdir/mapfile.c')
-rw-r--r--Build/source/texk/web2c/pdftexdir/mapfile.c958
1 files changed, 351 insertions, 607 deletions
diff --git a/Build/source/texk/web2c/pdftexdir/mapfile.c b/Build/source/texk/web2c/pdftexdir/mapfile.c
index 758290127ca..296eb57e92a 100644
--- a/Build/source/texk/web2c/pdftexdir/mapfile.c
+++ b/Build/source/texk/web2c/pdftexdir/mapfile.c
@@ -1,5 +1,5 @@
/*
-Copyright (c) 1996-2005 Han The Thanh, <thanh@pdftex.org>
+Copyright (c) 1996-2006 Han The Thanh, <thanh@pdftex.org>
This file is part of pdfTeX.
@@ -17,19 +17,15 @@ You should have received a copy of the GNU General Public License
along with pdfTeX; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-$Id: //depot/Build/source.development/TeX/texk/web2c/pdftexdir/mapfile.c#30 $
+$Id: mapfile.c,v 1.1 2006/12/14 01:21:33 hahe Exp hahe $
-source code indentation by "indent -kr -nut"
*/
#include <math.h>
#include "ptexlib.h"
#include <kpathsea/c-auto.h>
#include <kpathsea/c-memstr.h>
-#include "avlstuff.h"
-
-static const char perforce_id[] =
- "$Id: //depot/Build/source.development/TeX/texk/web2c/pdftexdir/mapfile.c#30 $";
+#include <string.h>
#define FM_BUF_SIZE 1024
@@ -41,70 +37,61 @@ static FILE *fm_file;
#define fm_getchar() xgetc(fm_file)
#define fm_eof() feof(fm_file)
-enum _mode { FM_DUPIGNORE, FM_REPLACE, FM_DELETE };
-enum _ltype { MAPFILE, MAPLINE };
-enum _tfmavail { TFM_UNCHECKED, TFM_FOUND, TFM_NOTFOUND };
+typedef enum { FM_DUPIGNORE, FM_REPLACE, FM_DELETE } updatemode;
+typedef enum { MAPFILE, MAPLINE } maptype;
typedef struct mitem {
- int mode; /* FM_DUPIGNORE or FM_REPLACE or FM_DELETE */
- int type; /* map file or map line */
+ updatemode mode; /* FM_DUPIGNORE or FM_REPLACE or FM_DELETE */
+ maptype type; /* map file or map line */
char *line; /* pointer to map file name or map line */
int lineno; /* line number in map file */
- struct mitem *next; /* pointer to next item, or NULL */
} mapitem;
-mapitem *miptr, *mapitems = NULL;
+mapitem *mitem = NULL;
-fm_entry *fm_cur;
static const char nontfm[] = "<nontfm>";
-static fm_entry *loaded_tfm_found;
-static fm_entry *avail_tfm_found;
-static fm_entry *non_tfm_found;
-static fm_entry *not_avail_tfm_found;
-
-#define read_field(r, q, buf) do { \
- for (q = buf; *r != ' ' && *r != 10; *q++ = *r++); \
- *q = 0; \
- skip (r, ' '); \
+
+#define read_field(r, q, buf) do { \
+ q = buf; \
+ while (*r != ' ' && *r != '\0') \
+ *q++ = *r++; \
+ *q = '\0'; \
+ skip (r, ' '); \
} while (0)
-#define set_field(F) do { \
- if (q > buf) \
- fm->F = xstrdup(buf); \
- if (*r == 10) \
- goto done; \
+#define set_field(F) do { \
+ if (q > buf) \
+ fm->F = xstrdup(buf); \
+ if (*r == '\0') \
+ goto done; \
} while (0)
-static fm_entry *new_fm_entry(void)
+fm_entry *new_fm_entry(void)
{
fm_entry *fm;
fm = xtalloc(1, fm_entry);
fm->tfm_name = NULL;
+ fm->sfd_name = NULL;
fm->ps_name = NULL;
- fm->flags = 0;
+ fm->fd_flags = 4;
fm->ff_name = NULL;
- fm->subset_tag = NULL;
- fm->encoding = NULL;
- fm->tfm_num = getnullfont();
- fm->tfm_avail = TFM_UNCHECKED;
+ fm->encname = NULL;
fm->type = 0;
fm->slant = 0;
fm->extend = 0;
- fm->ff_objnum = 0;
- fm->fn_objnum = 0;
- fm->fd_objnum = 0;
- fm->charset = NULL;
- fm->all_glyphs = false;
fm->links = 0;
+ fm->pid = -1;
+ fm->eid = -1;
+ fm->subfont = NULL;
+ fm->in_use = false;
return fm;
}
-static void delete_fm_entry(fm_entry * fm)
+void delete_fm_entry(fm_entry * fm)
{
xfree(fm->tfm_name);
+ xfree(fm->sfd_name);
xfree(fm->ps_name);
xfree(fm->ff_name);
- xfree(fm->subset_tag);
- xfree(fm->charset);
xfree(fm);
}
@@ -130,36 +117,13 @@ static fm_entry *dummy_fm_entry()
return (fm_entry *) & const_fm_entry;
}
-char *mk_base_tfm(char *tfmname, int *i)
-{
- static char buf[SMALL_BUF_SIZE];
- char *p = tfmname, *r = strend(p) - 1, *q = r;
- while (q > p && isdigit(*q))
- --q;
- if (!(q > p) || q == r || (*q != '+' && *q != '-'))
- return NULL;
- check_buf(q - p + 1, SMALL_BUF_SIZE);
- strncpy(buf, p, (unsigned) (q - p));
- buf[q - p] = 0;
- *i = atoi(q);
- return buf;
-}
-
-static fmentryptr fmlookup(internalfontnumber);
-
-boolean hasfmentry(internalfontnumber f)
-{
- if (pdffontmap[f] == NULL)
- pdffontmap[f] = fmlookup(f);
- assert(pdffontmap[f] != NULL);
- return pdffontmap[f] != (fmentryptr) dummy_fm_entry();
-}
/**********************************************************************/
struct avl_table *tfm_tree = NULL;
struct avl_table *ps_tree = NULL;
struct avl_table *ff_tree = NULL;
+struct avl_table *encname_tree = NULL;
/* AVL sort fm_entry into tfm_tree by tfm_name */
@@ -169,27 +133,17 @@ static int comp_fm_entry_tfm(const void *pa, const void *pb, void *p)
((const fm_entry *) pb)->tfm_name);
}
-#define cmp_return(a, b) \
- if (a > b) \
- return 1; \
- if (a < b) \
- return -1
-
/* AVL sort fm_entry into ps_tree by ps_name, slant, and extend */
static int comp_fm_entry_ps(const void *pa, const void *pb, void *p)
{
- const fm_entry *p1 = (const fm_entry *) pa, *p2 =
- (const fm_entry *) pb;
int i;
+ const fm_entry *p1 = (const fm_entry *) pa, *p2 = (const fm_entry *) pb;
assert(p1->ps_name != NULL && p2->ps_name != NULL);
if ((i = strcmp(p1->ps_name, p2->ps_name)) != 0)
return i;
cmp_return(p1->slant, p2->slant);
cmp_return(p1->extend, p2->extend);
- if (p1->tfm_name != NULL && p2->tfm_name != NULL &&
- (i = strcmp(p1->tfm_name, p2->tfm_name)) != 0)
- return i;
return 0;
}
@@ -203,20 +157,21 @@ static int comp_ff_entry(const void *pa, const void *pb, void *p)
static void create_avl_trees()
{
- if (tfm_tree == NULL) {
- tfm_tree = avl_create(comp_fm_entry_tfm, NULL, &avl_xallocator);
- assert(tfm_tree != NULL);
- }
- if (ps_tree == NULL) {
- ps_tree = avl_create(comp_fm_entry_ps, NULL, &avl_xallocator);
- assert(ps_tree != NULL);
- }
- if (ff_tree == NULL) {
- ff_tree = avl_create(comp_ff_entry, NULL, &avl_xallocator);
- assert(ff_tree != NULL);
- }
+ assert(tfm_tree == NULL);
+ tfm_tree = avl_create(comp_fm_entry_tfm, NULL, &avl_xallocator);
+ assert(tfm_tree != NULL);
+ assert(ps_tree == NULL);
+ ps_tree = avl_create(comp_fm_entry_ps, NULL, &avl_xallocator);
+ assert(ps_tree != NULL);
+ assert(ff_tree == NULL);
+ ff_tree = avl_create(comp_ff_entry, NULL, &avl_xallocator);
+ assert(ff_tree != NULL);
+ assert(encname_tree == NULL);
+ encname_tree = avl_create(comp_string_entry, NULL, &avl_xallocator);
+ assert(encname_tree != NULL);
}
+/**********************************************************************/
/*
The function avl_do_entry() is not completely symmetrical with regards
to tfm_name and ps_name handling, e. g. a duplicate tfm_name gives a
@@ -224,28 +179,30 @@ to tfm_name and ps_name handling, e. g. a duplicate tfm_name gives a
with the original version.
*/
-static int avl_do_entry(fm_entry * fp, int mode)
+int avl_do_entry(fm_entry * fm, int mode)
{
- fm_entry *p, *p2;
+ fm_entry *p;
void *a;
void **aa;
- struct avl_traverser trav;
/* handle tfm_name link */
- if (strcmp(fp->tfm_name, nontfm) != 0) {
- p = (fm_entry *) avl_find(tfm_tree, fp);
+ if (strcmp(fm->tfm_name, nontfm) != 0) {
+ p = (fm_entry *) avl_find(tfm_tree, fm);
if (p != NULL) {
- if (mode == FM_DUPIGNORE) {
+ switch (mode) {
+ case FM_DUPIGNORE:
pdftex_warn
("fontmap entry for `%s' already exists, duplicates ignored",
- fp->tfm_name);
+ fm->tfm_name);
goto exit;
- } else { /* mode == FM_REPLACE / FM_DELETE */
- if (fontused[p->tfm_num]) {
+ break;
+ case FM_REPLACE:
+ case FM_DELETE:
+ if (fm->in_use) {
pdftex_warn
("fontmap entry for `%s' has been used, replace/delete not allowed",
- fp->tfm_name);
+ fm->tfm_name);
goto exit;
}
a = avl_delete(tfm_tree, p);
@@ -253,54 +210,70 @@ static int avl_do_entry(fm_entry * fp, int mode)
unset_tfmlink(p);
if (!has_pslink(p))
delete_fm_entry(p);
+ break;
+ default:
+ assert(0);
}
}
if (mode != FM_DELETE) {
- aa = avl_probe(tfm_tree, fp);
+ aa = avl_probe(tfm_tree, fm);
assert(aa != NULL);
- set_tfmlink(fp);
+ set_tfmlink(fm);
}
}
/* handle ps_name link */
- if (fp->ps_name != NULL) {
- assert(fp->tfm_name != NULL);
- p = (fm_entry *) avl_find(ps_tree, fp);
+ if (fm->ps_name != NULL) {
+ p = (fm_entry *) avl_find(ps_tree, fm);
if (p != NULL) {
- if (mode == FM_DUPIGNORE) {
- pdftex_warn
- ("ps_name entry for `%s' already exists, duplicates ignored",
- fp->ps_name);
+ switch (mode) {
+ case FM_DUPIGNORE:
goto exit;
- } else { /* mode == FM_REPLACE / FM_DELETE */
- if (fontused[p->tfm_num]) {
- /* REPLACE/DELETE not allowed */
- pdftex_warn
- ("fontmap entry for `%s' has been used, replace/delete not allowed",
- p->tfm_name);
+ break;
+ case FM_REPLACE:
+ case FM_DELETE:
+ if (fm->in_use)
goto exit;
- }
a = avl_delete(ps_tree, p);
assert(a != NULL);
unset_pslink(p);
if (!has_tfmlink(p))
delete_fm_entry(p);
+ break;
+ default:
+ assert(0);
}
}
- if (mode != FM_DELETE) {
- aa = avl_probe(ps_tree, fp);
+ if (mode != FM_DELETE && is_t1fontfile(fm) && is_included(fm)) {
+ aa = avl_probe(ps_tree, fm);
assert(aa != NULL);
- set_pslink(fp);
+ set_pslink(fm);
}
}
exit:
- if (!has_tfmlink(fp) && !has_pslink(fp)) /* e. g. after FM_DELETE */
+ if (!has_tfmlink(fm) && !has_pslink(fm)) /* e. g. after FM_DELETE */
return 1; /* deallocation of fm_entry structure required */
else
return 0;
}
+/* add the encoding name to an AVL tree. this has nothing to do with writeenc.c */
+
+char *add_encname(char *s)
+{
+ char *p;
+ void **aa;
+ assert(s != NULL);
+ assert(encname_tree != NULL);
+ if ((p = (char *) avl_find(encname_tree, s)) == NULL) { /* encoding name not yet registered */
+ p = xstrdup(s);
+ aa = avl_probe(encname_tree, p);
+ assert(aa != NULL);
+ }
+ return p;
+}
+
/**********************************************************************/
/* consistency check for map entry, with warn flag */
@@ -308,64 +281,79 @@ int check_fm_entry(fm_entry * fm, boolean warn)
{
int a = 0;
assert(fm != NULL);
- if (fm->ps_name != NULL) {
- if (is_basefont(fm)) {
- if (is_fontfile(fm) && !is_included(fm)) {
- if (warn)
- pdftex_warn
- ("invalid entry for `%s': font file must be included or omitted for base fonts",
- fm->tfm_name);
- a += 1;
- }
- } else { /* not a base font */
- /* if no font file given, drop this entry */
- if (!is_fontfile(fm)) {
- if (warn)
- pdftex_warn
- ("invalid entry for `%s': font file missing",
- fm->tfm_name);
- a += 2;
- }
- }
+
+ if (is_fontfile(fm) && !is_included(fm)) {
+ if (warn)
+ pdftex_warn
+ ("ambiguous entry for `%s': font file present but not included, "
+ "will be treated as font file not present", fm->tfm_name);
+ xfree(fm->ff_name);
+ /* do not set variable |a| as this entry will be still accepted */
}
+
+ /* if both ps_name and font file are missing, drop this entry */
+ if (fm->ps_name == NULL && !is_fontfile(fm)) {
+ if (warn)
+ pdftex_warn
+ ("invalid entry for `%s': both ps_name and font file missing",
+ fm->tfm_name);
+ a += 1;
+ }
+
+ /* TrueType fonts cannot be reencoded without subsetting */
if (is_truetype(fm) && is_reencoded(fm) && !is_subsetted(fm)) {
if (warn)
pdftex_warn
("invalid entry for `%s': only subsetted TrueType font can be reencoded",
fm->tfm_name);
- a += 4;
+ a += 2;
}
- if ((fm->slant != 0 || fm->extend != 0) &&
- (!is_included(fm) || is_truetype(fm))) {
+
+ /* SlantFont and ExtendFont can be used only with Type1 fonts */
+ if ((fm->slant != 0 || fm->extend != 0)
+ && !(is_t1fontfile(fm) && is_included(fm))) {
if (warn)
pdftex_warn
- ("invalid entry for `%s': SlantFont/ExtendFont can be used only with embedded T1 fonts",
+ ("invalid entry for `%s': SlantFont/ExtendFont can be used only with embedded Type1 fonts",
fm->tfm_name);
- a += 8;
+ a += 4;
}
+
+ /* the value of SlantFont and ExtendFont must be reasonable */
if (abs(fm->slant) > 1000) {
if (warn)
pdftex_warn
("invalid entry for `%s': too big value of SlantFont (%g)",
fm->tfm_name, fm->slant / 1000.0);
- a += 16;
+ a += 8;
}
if (abs(fm->extend) > 2000) {
if (warn)
pdftex_warn
("invalid entry for `%s': too big value of ExtendFont (%g)",
fm->tfm_name, fm->extend / 1000.0);
+ a += 16;
+ }
+
+ /* subfonts must be used with subsetted non-reencoded TrueType fonts */
+ if (fm->pid != -1 &&
+ !(is_truetype(fm) && is_subsetted(fm) && !is_reencoded(fm))) {
+ if (warn)
+ pdftex_warn
+ ("invalid entry for `%s': PidEid can be used only with subsetted non-reencoded TrueType fonts",
+ fm->tfm_name);
a += 32;
}
+
return a;
}
/**********************************************************************/
/* returns true if s is one of the 14 std. font names; speed-trimmed. */
-boolean check_basefont(char *s)
+boolean check_std_t1font(char *s)
{
- static const char *basefont_names[] = {
+ static const char *std_t1font_names[] = {
"Courier", /* 0:7 */
"Courier-Bold", /* 1:12 */
"Courier-Oblique", /* 2:15 */
@@ -382,10 +370,11 @@ boolean check_basefont(char *s)
"ZapfDingbats" /* 13:12 */
};
static const int index[] =
- { -1, -1, -1, -1, -1, -1, 8, 0, -1, 4, 10, 9, -1, -1, 5, 2, 12, 6,
- -1, 3, -1, 7
+ { -1, -1, -1, -1, -1, -1, 8, 0, -1, 4, 10, 9, -1, -1, 5, 2, 12, 6, -1,
+ 3, -1, 7
};
- int n = strlen(s), k = -1;
+ const size_t n = strlen(s);
+ int k = -1;
if (n > 21)
return false;
if (n == 12) { /* three names have length 12 */
@@ -404,43 +393,42 @@ boolean check_basefont(char *s)
}
} else
k = index[n];
- if (k > -1 && strcmp(basefont_names[k], s) == 0)
+ if (k > -1 && strcmp(std_t1font_names[k], s) == 0)
return true;
return false;
};
+
/**********************************************************************/
-static void fm_scan_line(mapitem * mitem)
+static void fm_scan_line()
{
int a, b, c, j, u = 0, v = 0;
float d;
- char fm_line[FM_BUF_SIZE], buf[FM_BUF_SIZE];
fm_entry *fm;
+ char fm_line[FM_BUF_SIZE], buf[FM_BUF_SIZE];
char *p, *q, *r, *s;
- p = fm_line;
switch (mitem->type) {
case MAPFILE:
+ p = fm_line;
do {
c = fm_getchar();
append_char_to_buf(c, p, fm_line, FM_BUF_SIZE);
}
while (c != 10);
+ *(--p) = '\0';
+ r = fm_line;
break;
case MAPLINE:
- s = mitem->line;
- while ((c = *s++) != 0)
- append_char_to_buf(c, p, fm_line, FM_BUF_SIZE);
+ r = mitem->line; /* work on string from makecstring() */
break;
default:
assert(0);
}
- append_eol(p, fm_line, FM_BUF_SIZE);
- if (is_cfg_comment(*fm_line))
+ if (*r == '\0' || is_cfg_comment(*r))
return;
- r = fm_line;
- read_field(r, q, buf);
fm = new_fm_entry();
+ read_field(r, q, buf);
set_field(tfm_name);
p = r;
read_field(r, q, buf);
@@ -448,18 +436,17 @@ static void fm_scan_line(mapitem * mitem)
set_field(ps_name);
else
r = p; /* unget the field */
- if (isdigit(*r)) { /* font flags given */
- fm->flags = atoi(r);
+ if (isdigit(*r)) { /* font descriptor /Flags given */
+ fm->fd_flags = atoi(r);
while (isdigit(*r))
r++;
- } else
- fm->flags = 4; /* treat as Symbol font */
+ }
while (1) { /* loop through "specials", encoding, font file */
skip(r, ' ');
switch (*r) {
- case 10:
+ case '\0':
goto done;
- case '"': /* opening quote */
+ case '"': /* opening quote */
r++;
u = v = 0;
do {
@@ -468,20 +455,18 @@ static void fm_scan_line(mapitem * mitem)
s = r + j; /* jump behind number, eat also blanks, if any */
if (*(s - 1) == 'E' || *(s - 1) == 'e')
s--; /* e. g. 0.5ExtendFont: %f = 0.5E */
- if (strncmp(s, "SlantFont", strlen("SlantFont")) == 0) {
+ if (str_prefix(s, "SlantFont")) {
d *= 1000.0; /* correct rounding also for neg. numbers */
fm->slant = (integer) (d > 0 ? d + 0.5 : d - 0.5);
r = s + strlen("SlantFont");
- } else
- if (strncmp(s, "ExtendFont", strlen("ExtendFont"))
- == 0) {
+ } else if (str_prefix(s, "ExtendFont")) {
d *= 1000.0;
fm->extend = (integer) (d > 0 ? d + 0.5 : d - 0.5);
if (fm->extend == 1000)
fm->extend = 0;
r = s + strlen("ExtendFont");
} else { /* unknown name */
- for (r = s; *r != ' ' && *r != '"' && *r != 10; r++); /* jump over name */
+ for (r = s; *r != ' ' && *r != '"' && *r != '\0'; r++); /* jump over name */
c = *r; /* remember char for temporary end of string */
*r = '\0';
pdftex_warn
@@ -490,7 +475,7 @@ static void fm_scan_line(mapitem * mitem)
*r = c;
}
} else
- for (; *r != ' ' && *r != '"' && *r != 10; r++);
+ for (; *r != ' ' && *r != '"' && *r != '\0'; r++);
}
while (*r == ' ');
if (*r == '"') /* closing quote */
@@ -502,7 +487,14 @@ static void fm_scan_line(mapitem * mitem)
goto bad_line;
}
break;
- default: /* encoding or font file specification */
+ case 'P': /* handle cases for subfonts like 'PidEid=3,1' */
+ if (sscanf(r, "PidEid=%i, %i %n", &a, &b, &c) >= 2) {
+ fm->pid = a;
+ fm->eid = b;
+ r += c;
+ break;
+ }
+ default: /* encoding or font file specification */
a = b = 0;
if (*r == '<') {
a = *r++;
@@ -511,9 +503,8 @@ static void fm_scan_line(mapitem * mitem)
}
read_field(r, q, buf);
/* encoding, formats: '8r.enc' or '<8r.enc' or '<[8r.enc' */
- if (strlen(buf) > 4
- && strcasecmp(strend(buf) - 4, ".enc") == 0) {
- fm->encoding = add_enc(buf);
+ if (strlen(buf) > 4 && strcasecmp(strend(buf) - 4, ".enc") == 0) {
+ fm->encname = add_encname(buf);
u = v = 0; /* u, v used if intervening blank: "<< foo" */
} else if (strlen(buf) > 0) { /* file name given */
/* font file, formats:
@@ -536,11 +527,17 @@ static void fm_scan_line(mapitem * mitem)
}
}
done:
- if (fm->ps_name != NULL && check_basefont(fm->ps_name))
- set_basefont(fm);
- if (is_fontfile(fm)
- && strcasecmp(strend(fm_fontfile(fm)) - 4, ".ttf") == 0)
- set_truetype(fm);
+ if (fm->ps_name != NULL && check_std_t1font(fm->ps_name))
+ set_std_t1font(fm);
+ if (is_fontfile(fm)) {
+ if (strcasecmp(strend(fm_fontfile(fm)) - 4, ".ttf") == 0)
+ set_truetype(fm);
+ else if (strcasecmp(strend(fm_fontfile(fm)) - 4, ".otf") == 0)
+ set_opentype(fm);
+ else
+ set_type1(fm);
+ } else
+ set_type1(fm); /* assume a builtin font is Type1 */
if (check_fm_entry(fm, true) != 0)
goto bad_line;
/*
@@ -548,6 +545,8 @@ static void fm_scan_line(mapitem * mitem)
fm points to a valid, freshly filled-out fm_entry structure.
Now follows the actual work of registering/deleting.
*/
+ if (handle_subfont_fm(fm, mitem->mode)) /* is this a subfont? */
+ return;
if (avl_do_entry(fm, mitem->mode) == 0) /* if success */
return;
bad_line:
@@ -558,111 +557,49 @@ static void fm_scan_line(mapitem * mitem)
void fm_read_info()
{
- mapitem *tmp;
- create_avl_trees();
- while (mapitems != NULL) {
- assert(mapitems->line != NULL);
- mapitems->lineno = 1;
- switch (mapitems->type) {
- case MAPFILE:
- set_cur_file_name(mapitems->line);
- if (!fm_open()) {
- pdftex_warn("cannot open font map file");
- } else {
- cur_file_name = (char *) nameoffile + 1;
- tex_printf("{%s", cur_file_name);
- while (!fm_eof()) {
- fm_scan_line(mapitems);
- mapitems->lineno++;
- }
- fm_close();
- tex_printf("}");
- fm_file = NULL;
+ if (tfm_tree == NULL)
+ create_avl_trees();
+ if (mitem->line == NULL) /* nothing to do */
+ return;
+ mitem->lineno = 1;
+ switch (mitem->type) {
+ case MAPFILE:
+ set_cur_file_name(mitem->line);
+ if (!fm_open()) {
+ pdftex_warn("cannot open font map file");
+ } else {
+ cur_file_name = (char *) nameoffile + 1;
+ tex_printf("{%s", cur_file_name);
+ while (!fm_eof()) {
+ fm_scan_line();
+ mitem->lineno++;
}
- break;
- case MAPLINE:
- cur_file_name = NULL; /* makes pdftex_warn() shorter */
- fm_scan_line(mapitems);
- break;
- default:
- assert(0);
+ fm_close();
+ tex_printf("}");
+ fm_file = NULL;
}
- tmp = mapitems;
- mapitems = mapitems->next;
- xfree(tmp->line);
- xfree(tmp);
+ break;
+ case MAPLINE:
+ cur_file_name = NULL; /* makes pdftex_warn() shorter */
+ fm_scan_line();
+ break;
+ default:
+ assert(0);
}
+ mitem->line = NULL; /* done with this line */
cur_file_name = NULL;
return;
}
/**********************************************************************/
-/*
-char *mk_exname(char *basename, int e)
-{
- static char buf[SMALL_BUF_SIZE];
- char *p = basename, *r;
- if ((r = strrchr(p, '.')) == NULL)
- r = strend(p);
- check_buf(r - p + strlen(r) + 10, SMALL_BUF_SIZE);
- strncpy(buf, p, (unsigned) (r - p));
- sprintf(buf + (r - p), "%+i", e);
- strcat(buf, r);
- return buf;
-}
-*/
-
-internalfontnumber tfmoffm(fmentryptr fm_pt)
-{
- return ((fm_entry *) fm_pt)->tfm_num;
-}
-
-static fm_entry *mk_ex_fm(internalfontnumber f, fm_entry * basefm, int ex)
-{
- fm_entry *fm;
- integer e = basefm->extend;
- if (e == 0)
- e = 1000;
- fm = new_fm_entry();
- fm->flags = basefm->flags;
- fm->encoding = basefm->encoding;
- fm->type = basefm->type;
- fm->slant = basefm->slant;
- fm->extend = roundxnoverd(e, 1000 + ex, 1000); /* modify ExtentFont to simulate expansion */
- if (fm->extend == 1000)
- fm->extend = 0;
- fm->tfm_name = xstrdup(makecstring(fontname[f]));
- if (basefm->ps_name != NULL)
- fm->ps_name = xstrdup(basefm->ps_name);
- fm->ff_name = xstrdup(basefm->ff_name);
- fm->ff_objnum = pdfnewobjnum();
- fm->tfm_num = f;
- fm->tfm_avail = TFM_FOUND;
- assert(strcmp(fm->tfm_name, nontfm) != 0);
- return fm;
-}
-
-static void init_fm(fm_entry * fm, internalfontnumber f)
-{
- if (fm->fd_objnum == 0 && !no_font_desc(fm))
- fm->fd_objnum = pdfnewobjnum();
- if (fm->ff_objnum == 0 && is_included(fm))
- fm->ff_objnum = pdfnewobjnum();
- if (fm->tfm_num == getnullfont()) {
- fm->tfm_num = f;
- fm->tfm_avail = TFM_FOUND;
- }
-}
-
static fmentryptr fmlookup(internalfontnumber f)
{
- char *tfm, *p;
- fm_entry *fm, *exfm;
+ char *tfm;
+ fm_entry *fm;
fm_entry tmp;
- int ai, e;
- if (tfm_tree == NULL || mapitems != NULL)
- fm_read_info();
+ if (tfm_tree == NULL)
+ fm_read_info(); /* only to read default map file */
tfm = makecstring(fontname[f]);
assert(strcmp(tfm, nontfm) != 0);
@@ -670,251 +607,70 @@ static fmentryptr fmlookup(internalfontnumber f)
tmp.tfm_name = tfm;
fm = (fm_entry *) avl_find(tfm_tree, &tmp);
if (fm != NULL) {
- init_fm(fm, f);
+ fm->in_use = true;
return (fmentryptr) fm;
}
- tfm = mk_base_tfm(makecstring(fontname[f]), &e);
- if (tfm == NULL) /* not an expanded font, nothing to do */
- return (fmentryptr) dummy_fm_entry();
-
- tmp.tfm_name = tfm;
- fm = (fm_entry *) avl_find(tfm_tree, &tmp);
- if (fm != NULL) { /* found an entry with the base tfm name, e.g. cmr10 */
- if (!is_t1fontfile(fm) || !is_included(fm)) {
- pdftex_warn
- ("font %s cannot be expanded (not an included Type1 font)",
- tfm);
- return (fmentryptr) dummy_fm_entry();
- }
- exfm = mk_ex_fm(f, fm, e); /* copies all fields from fm except tfm name */
- init_fm(exfm, f);
- ai = avl_do_entry(exfm, FM_DUPIGNORE);
- assert(ai == 0);
- return (fmentryptr) exfm;
- }
return (fmentryptr) dummy_fm_entry();
}
-/*
- Early check whether a font file exists. Used e. g. for replacing fonts
- of embedded PDF files: Without font file, the font within the embedded
- PDF-file is used. Search tree ff_tree is used in 1st instance, as it
- may be faster than the kpse_find_file(), and kpse_find_file() is called
- only once per font file name + expansion parameter. This might help
- keeping speed, if many PDF pages with same fonts are to be embedded.
-
- The ff_tree contains only font files, which are actually needed,
- so this tree typically is much smaller than the tfm_tree or ps_tree.
-*/
-
-ff_entry *check_ff_exist(fm_entry * fm)
+boolean hasfmentry(internalfontnumber f)
{
- ff_entry *ff;
- ff_entry tmp;
- char *ex_ffname;
- void **aa;
-
- assert(fm->ff_name != NULL);
- tmp.ff_name = fm->ff_name;
- ff = (ff_entry *) avl_find(ff_tree, &tmp);
- if (ff == NULL) { /* not yet in database */
- ff = new_ff_entry();
- ff->ff_name = xstrdup(fm->ff_name);
- if (is_truetype(fm))
- ff->ff_path =
- kpse_find_file(fm->ff_name, kpse_truetype_format, 0);
- else
- ff->ff_path =
- kpse_find_file(fm->ff_name, kpse_type1_format, 0);
- aa = avl_probe(ff_tree, ff);
- assert(aa != NULL);
- }
- return ff;
+ if (pdffontmap[f] == NULL)
+ pdffontmap[f] = fmlookup(f);
+ assert(pdffontmap[f] != NULL);
+ return pdffontmap[f] != (fmentryptr) dummy_fm_entry();
}
-/**********************************************************************/
-static boolean used_tfm(fm_entry * p)
+/* check whether a map entry is valid for font replacement */
+static boolean fm_valid_for_font_replacement(fm_entry * fm)
{
- internalfontnumber f;
- strnumber s;
ff_entry *ff;
- /* check if the font file is not a TrueType font */
- /* font replacement makes sense only for included Type1 files */
- if (is_truetype(p) || !is_included(p))
- return false;
+ assert(fm != NULL);
+ assert(is_fontfile(fm)); /* ps_tree should contain only entries with font file */
+ assert(is_type1(fm)); /* ps_tree should contain only Type1 entries */
- /* check if the font file is available */
- ff = check_ff_exist(p);
- if (ff->ff_path == NULL)
+ ff = check_ff_exist(fm->ff_name, false);
+ assert(ff != NULL);
+ if (ff->ff_path == NULL) /* ...there is no font file available */
return false;
-
- /* check whether this font has been used */
- if (fontused[p->tfm_num])
- return true;
- assert(p->tfm_name != NULL);
-
- /* check whether we didn't find a loaded font yet,
- * and this font has been loaded */
- if (loaded_tfm_found == NULL && strcmp(p->tfm_name, nontfm) != 0) {
- s = maketexstring(p->tfm_name);
- if ((f = tfmlookup(s, 0)) != getnullfont()) {
- loaded_tfm_found = p;
- if (pdffontmap[f] == NULL)
- pdffontmap[f] = (fmentryptr) p;
- if (p->tfm_num == getnullfont())
- p->tfm_num = f;
- assert(p->tfm_num == f);
- /* don't call flushstr() here as it has been called by tfmlookup() */
- } else
- flushstr(s);
- }
-
- /* check whether we didn't find either a loaded or a loadable font yet,
- * and this font is loadable */
- if (avail_tfm_found == NULL && loaded_tfm_found == NULL &&
- strcmp(p->tfm_name, nontfm) != 0) {
- if (p->tfm_avail == TFM_UNCHECKED) {
- if (kpse_find_file(p->tfm_name, kpse_tfm_format, 0) != NULL) {
- avail_tfm_found = p;
- p->tfm_avail = TFM_FOUND;
- } else {
- p->tfm_avail = TFM_NOTFOUND;
- if (not_avail_tfm_found == NULL)
- not_avail_tfm_found = p;
- }
- }
- }
-
- /* check whether the current entry is a <nontfm> entry */
- if (non_tfm_found == NULL && strcmp(p->tfm_name, nontfm) == 0)
- non_tfm_found = p;
-
- return false;
+ return true; /* all tests passed */
}
-/* lookup_ps_name looks for an entry with a given ps name + slant + extend;
- * return NULL if not found.
- *
- * As there may exist several such entries, we need to select the `right'
- * one. We do so by checking all such entries and return the first one that
- * fulfils the following criteria (in descending priority):
- *
- * - the tfm has been used (some char from this font has been typeset)
- * - the tfm has been loaded (but not used yet)
- * - the tfm can be loaded (but not loaded yet)
- * - the tfm is present in map files, but cannot be loaded. In this case a
- * dummy tfm can be loaded instead, and a warning should be written out
+/**********************************************************************/
+/*
+ * lookup fontmap by ps_name;
+ * used for Type1 font replacement when embedding of PDF files
*/
-static fm_entry *lookup_ps_name(fm_entry * fm)
+fm_entry *lookup_fontmap(char *ps_name)
{
- fm_entry *p, *p2;
- struct avl_traverser t, t2;
- strnumber s;
- int a;
-
- loaded_tfm_found = NULL;
- avail_tfm_found = NULL;
- non_tfm_found = NULL;
- not_avail_tfm_found = NULL;
-
- assert(fm->tfm_name == NULL);
- p = (fm_entry *) avl_t_find(&t, ps_tree, fm);
- if (p == NULL)
- return NULL;
- t2 = t;
- p2 = avl_t_prev(&t2);
-
- /* search forward */
- do {
- if (used_tfm(p))
- return p;
- p = avl_t_next(&t);
- }
- while (p != NULL && comp_fm_entry_ps(fm, p, NULL) == 0);
-
- /* search backward */
- while (p2 != NULL && comp_fm_entry_ps(fm, p2, NULL) == 0) {
- if (used_tfm(p2))
- return p2;
- p2 = avl_t_prev(&t2);
- }
-
- if (loaded_tfm_found != NULL)
- p = loaded_tfm_found;
- else if (avail_tfm_found != NULL) {
- p = avail_tfm_found;
- p->tfm_num = readfontinfo(getnullcs(), maketexstring(p->tfm_name),
- getnullstr(), -1000);
- p->tfm_avail = TFM_FOUND;
- } else if (non_tfm_found != NULL) {
- p = non_tfm_found;
- p->tfm_num = newdummyfont();
- p->tfm_avail = TFM_FOUND;
- } else if (not_avail_tfm_found != NULL) {
- p = not_avail_tfm_found;
- pdftex_warn("`%s' not loadable, use a dummy tfm instead",
- p->tfm_name);
- p2 = new_fm_entry();
- p2->flags = p->flags;
- p2->encoding = p->encoding;
- p2->type = p->type;
- p2->slant = p->slant;
- p2->extend = p->extend;
- p2->tfm_name = xstrdup(nontfm);
- p2->ps_name = xstrdup(p->ps_name);
- if (p->ff_name != NULL)
- p2->ff_name = xstrdup(p->ff_name);
- p2->tfm_num = newdummyfont();
- p2->tfm_avail = TFM_FOUND;
- a = avl_do_entry(p2, FM_DUPIGNORE);
- assert(a == 0);
- p = p2;
- } else
- return NULL;
- assert(p->tfm_num != getnullfont());
- return p;
-}
-
-/* Lookup fontmap for /BaseFont entries of embedded PDF-files;
- * return dummy_fm_entry() if not found */
-
-fm_entry *lookup_fontmap(char *bname)
-{
- fm_entry *fm, *fmx;
- fm_entry tmp, tmpx;
- ff_entry *ff;
- char buf[SMALL_BUF_SIZE];
+ fm_entry *fm, *fm2, tmp;
char *a, *b, *c, *d, *e, *s;
- strnumber str;
- int i, sl, ex, ai;
- if (tfm_tree == NULL || mapitems != NULL)
- fm_read_info();
- if (bname == NULL)
- return NULL;
- if (strlen(bname) >= SMALL_BUF_SIZE)
- pdftex_fail("Font name too long: `%s'", bname);
- strcpy(buf, bname); /* keep bname untouched for later */
- s = buf;
- if (strlen(buf) > 7) { /* check for subsetted name tag */
+ int i, sl, ex;
+ struct avl_traverser t, t2;
+ if (tfm_tree == NULL)
+ fm_read_info(); /* only to read default map file */
+ assert(ps_name != NULL);
+ s = ps_name;
+ if (strlen(ps_name) > 7) { /* check for subsetted name tag */
for (i = 0; i < 6; i++, s++)
if (*s < 'A' || *s > 'Z')
break;
if (i == 6 && *s == '+')
s++; /* if name tag found, skip behind it */
else
- s = buf;
+ s = ps_name;
}
/*
- Scan -Slant_<slant> and -Extend_<extend> font name extensions;
- three valid formats:
- <fontname>-Slant_<slant>
- <fontname>-Slant_<slant>-Extend_<extend>
- <fontname>-Extend_<extend>
- Slant entry must come _before_ Extend entry
+ * Scan -Slant_<slant> and -Extend_<extend> font name extensions;
+ * three valid formats:
+ * <fontname>-Slant_<slant>
+ * <fontname>-Slant_<slant>-Extend_<extend>
+ * <fontname>-Extend_<extend>
+ * Slant entry must come _before_ Extend entry
*/
tmp.slant = 0;
@@ -924,7 +680,7 @@ fm_entry *lookup_fontmap(char *bname)
sl = (int) strtol(b, &e, 10);
if ((e != b) && (e == strend(b))) {
tmp.slant = sl;
- *a = 0; /* bname string ends before "-Slant_" */
+ *a = '\0'; /* ps_name string ends before "-Slant_" */
} else {
if (e != b) { /* only if <slant> is valid number */
if ((c = strstr(e, "-Extend_")) != NULL) {
@@ -933,7 +689,7 @@ fm_entry *lookup_fontmap(char *bname)
if ((e != d) && (e == strend(d))) {
tmp.slant = sl;
tmp.extend = ex;
- *a = 0; /* bname string ends before "-Slant_" */
+ *a = '\0'; /* ps_name string ends before "-Slant_" */
}
}
}
@@ -944,166 +700,148 @@ fm_entry *lookup_fontmap(char *bname)
ex = (int) strtol(b, &e, 10);
if ((e != b) && (e == strend(b))) {
tmp.extend = ex;
- *a = 0; /* bname string ends before "-Extend_" */
+ *a = '\0'; /* ps_name string ends before "-Extend_" */
}
}
}
tmp.ps_name = s;
- tmp.tfm_name = NULL;
- fm = lookup_ps_name(&tmp);
- if (fm != NULL) {
- if (!(is_type1(fm) && is_included(fm))) {
- pdftex_warn
- ("PS name '%s' is found but ignored (not an included Type1 font)",
- tmp.ps_name);
- return NULL;
- }
- i = fm->tfm_num;
- assert(i != getnullfont());
- if (pdffontmap[i] == NULL)
- pdffontmap[i] = (fmentryptr) fm;
- if (fm->ff_objnum == 0 && is_included(fm))
- fm->ff_objnum = pdfnewobjnum();
- if (!fontused[i])
- pdfinitfont(i);
- return fm;
- }
-/*
- The following code snipplet handles fonts with "Slant" and "Extend"
- name extensions in embedded PDF files, which don't yet have an
- fm_entry. If such a font is found (e. g. CMR10-Extend_1020), and no
- fm_entry for this is found in the ps_tree (e. g. ps_name = "CMR10",
- extend = 1020), and if an unextended base font (e. g. CMR10) is found,
- a new <nontfm> fm_entry is created and put into the ps_tree. Then
- the lookup_fontmap() function is (recursively) called again, which
- then should find the new fm_entry. The same can be done manually by
- a map entry e. g.:
-
- \pdfmapline{+<nontfm> CMR10 "1.02 ExtendFont" <cmr10.pfb}
-
- This would also match the embedded font CMR10-Extend_1020, and replace
- it by an extended copy of cmr10.pfb. -- But not by an expanded version;
- no MM files (e.g. cmr10+20.pfb) would be used.
-*/
- tmpx.ps_name = s;
- tmpx.tfm_name = NULL;
- tmpx.slant = 0;
- tmpx.extend = 0;
-/* fm = (fm_entry *) avl_find(ps_tree, &tmpx); */
- fm = lookup_ps_name(&tmpx);
- if (fm != NULL) {
- if (is_truetype(fm) || !is_included(fm))
- return NULL;
- ff = check_ff_exist(fm);
- if (ff->ff_path == NULL)
- return NULL;
- fmx = new_fm_entry();
- fmx->flags = fm->flags;
- fmx->encoding = fm->encoding;
- fmx->type = fm->type;
- fmx->slant = tmp.slant;
- fmx->extend = tmp.extend;
- fmx->tfm_name = xstrdup(nontfm);
- fmx->ps_name = xstrdup(s);
- fmx->ff_name = xstrdup(fm->ff_name);
- ai = avl_do_entry(fmx, FM_DUPIGNORE);
- assert(ai == 0);
- fm = lookup_fontmap(bname); /* new try */
- assert(fm != NULL);
- return fm;
+ fm = (fm_entry *) avl_t_find(&t, ps_tree, &tmp);
+ if (fm == NULL)
+ return NULL; /* no entry found */
+
+ /* at this point we know there is at least one fm_entry with given ps_name;
+ * we test all such entries and return the first one that is valid for font
+ * replacement */
+
+ t2 = t;
+ fm2 = (fm_entry *) avl_t_prev(&t2);
+
+ /* search forward */
+ do {
+ if (fm_valid_for_font_replacement(fm))
+ return fm;
+ fm = (fm_entry *) avl_t_next(&t);
+ } while (fm != NULL && comp_fm_entry_ps(fm, &tmp, NULL) == 0);
+
+ /* search backward */
+ while (fm2 != NULL && comp_fm_entry_ps(fm2, &tmp, NULL) == 0) {
+ if (fm_valid_for_font_replacement(fm2))
+ return fm2;
+ fm2 = (fm_entry *) avl_t_prev(&t2);
}
+
return NULL;
}
/**********************************************************************/
/*
-Add map file name or map line contents to the linked list "mapitems".
-Items not beginning with [+-=] flush list with pending items. Leading
-blanks and blanks immediately following [+-=] are ignored.
-*/
+ * Process map file given by its name or map line contents. Items not
+ * beginning with [+-=] flush default map file, if it has not yet been
+ * read. Leading blanks and blanks immediately following [+-=] are
+ * ignored.
+ */
-char *add_map_item(char *s, int type)
+void process_map_item(char *s, int type)
{
char *p;
- int l; /* length of map item (without [+-=]) */
- mapitem *tmp;
int mode;
- for (; *s == ' '; s++); /* ignore leading blanks */
+ if (*s == ' ')
+ s++; /* ignore leading blank */
switch (*s) {
- case '+': /* +mapfile.map, +mapline */
+ case '+': /* +mapfile.map, +mapline */
mode = FM_DUPIGNORE; /* insert entry, if it is not duplicate */
s++;
break;
- case '=': /* =mapfile.map, =mapline */
+ case '=': /* =mapfile.map, =mapline */
mode = FM_REPLACE; /* try to replace earlier entry */
s++;
break;
- case '-': /* -mapfile.map, -mapline */
+ case '-': /* -mapfile.map, -mapline */
mode = FM_DELETE; /* try to delete entry */
s++;
break;
default:
- mode = FM_DUPIGNORE; /* also flush pending list */
- while (mapitems != NULL) {
- tmp = mapitems;
- mapitems = mapitems->next;
- xfree(tmp->line);
- xfree(tmp);
- }
+ mode = FM_DUPIGNORE; /* like +, but also: */
+ mitem->line = NULL; /* flush default map file name */
}
- for (; *s == ' '; s++); /* ignore blanks after [+-=] */
+ if (*s == ' ')
+ s++; /* ignore blank after [+-=] */
p = s; /* map item starts here */
- switch (type) { /* find end of map item */
- case MAPFILE:
- for (; *p != 0 && *p != ' ' && *p != 10; p++);
+ switch (type) {
+ case MAPFILE: /* remove blank at end */
+ while (*p != '\0' && *p != ' ')
+ p++;
+ *p = '\0';
break;
- case MAPLINE: /* blanks allowed */
- for (; *p != 0 && *p != 10; p++);
+ case MAPLINE: /* blank at end allowed */
break;
default:
assert(0);
}
- l = p - s;
- if (l > 0) { /* only if real item to add */
- tmp = xtalloc(1, mapitem);
- if (mapitems == NULL)
- mapitems = tmp; /* start new list */
- else
- miptr->next = tmp;
- miptr = tmp;
- miptr->mode = mode;
- miptr->type = type;
- miptr->line = xtalloc(l + 1, char);
- *(miptr->line) = 0;
- strncat(miptr->line, s, l);
- miptr->next = NULL;
+ if (mitem->line != NULL) /* read default map file first */
+ fm_read_info();
+ if (*s != '\0') { /* only if real item to process */
+ mitem->mode = mode;
+ mitem->type = type;
+ mitem->line = s;
+ fm_read_info();
}
- return p;
}
void pdfmapfile(integer t)
{
- add_map_item(makecstring(tokenstostring(t)), MAPFILE);
+ process_map_item(makecstring(tokenstostring(t)), MAPFILE);
flushstr(lasttokensstring);
}
void pdfmapline(integer t)
{
- add_map_item(makecstring(tokenstostring(t)), MAPLINE);
+ process_map_item(makecstring(tokenstostring(t)), MAPLINE);
flushstr(lasttokensstring);
}
void pdfinitmapfile(string map_name)
{
- if (mapitems == NULL) {
- mapitems = xtalloc(1, mapitem);
- miptr = mapitems;
- miptr->mode = FM_DUPIGNORE;
- miptr->type = MAPFILE;
- miptr->line = xstrdup(map_name);
- miptr->next = NULL;
+ assert(mitem == NULL);
+ mitem = xtalloc(1, mapitem);
+ mitem->mode = FM_DUPIGNORE;
+ mitem->type = MAPFILE;
+ mitem->line = xstrdup(map_name);
+}
+
+/**********************************************************************/
+/*
+ * Early check whether a font file exists. Search tree ff_tree is used
+ * in 1st instance, as it may be faster than the kpse_find_file(), and
+ * kpse_find_file() is called only once per font file name + expansion
+ * parameter. This might help keeping speed, if many PDF pages with
+ * same fonts are to be embedded.
+ *
+ * The ff_tree contains only font files, which are actually needed,
+ * so this tree typically is much smaller than the tfm_tree or ps_tree.
+ */
+
+ff_entry *check_ff_exist(char *ff_name, boolean is_tt)
+{
+ ff_entry *ff;
+ ff_entry tmp;
+ void **aa;
+
+ assert(ff_name != NULL);
+ tmp.ff_name = ff_name;
+ ff = (ff_entry *) avl_find(ff_tree, &tmp);
+ if (ff == NULL) { /* not yet in database */
+ ff = new_ff_entry();
+ ff->ff_name = xstrdup(ff_name);
+ if (is_tt)
+ ff->ff_path = kpse_find_file(ff_name, kpse_truetype_format, 0);
+ else
+ ff->ff_path = kpse_find_file(ff_name, kpse_type1_format, 0);
+ aa = avl_probe(ff_tree, ff);
+ assert(aa != NULL);
}
+ return ff;
}
/**********************************************************************/
@@ -1138,12 +876,18 @@ static void destroy_ff_entry(void *pa, void *pb)
void fm_free(void)
{
- if (tfm_tree != NULL)
+ if (tfm_tree != NULL) {
avl_destroy(tfm_tree, destroy_fm_entry_tfm);
- if (ps_tree != NULL)
+ tfm_tree = NULL;
+ }
+ if (ps_tree != NULL) {
avl_destroy(ps_tree, destroy_fm_entry_ps);
- if (ff_tree != NULL)
+ ps_tree = NULL;
+ }
+ if (ff_tree != NULL) {
avl_destroy(ff_tree, destroy_ff_entry);
+ ff_tree = NULL;
+ }
}
/**********************************************************************/