#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <ctype.h>
#include <string.h>
#include "filesrch.h"
#include "subfont.h"
#include "newobj.h"
#include "errormsg.h"
static char *real_sfd_name;
static FILE *sfd;
Boolean
init_sfd(Font *fnt, Boolean fatal)
{
real_sfd_name = TeX_search_sfd_file(&(fnt->sfdname));
if (!real_sfd_name)
{
if (fatal)
oops("Cannot find subfont definition file `%s'.", fnt->sfdname);
else
{
warning("Cannot find subfont definition file `%s'.", fnt->sfdname);
return False;
}
}
sfd = fopen(real_sfd_name, "rt");
if (sfd == NULL)
{
if (fatal)
oops("Cannot open subfont definition file `%s'.", fnt->sfdname);
else
{
warning("Cannot open subfont definition file `%s'.", fnt->sfdname);
return False;
}
}
return True;
}
Boolean
get_sfd(Font *fnt)
{
long i, offset;
long begin, end = -1;
char *buffer, *oldbuffer, *bufp, *bufp2, *bufp3;
for (i = 0; i < 256; i++)
fnt->sf_code[i] = -1;
again:
buffer = get_line(sfd);
if (!buffer)
oops("Error reading subfont definition file `%s'.", real_sfd_name);
if (!*buffer)
return False;
oldbuffer = newstring(buffer);
bufp = buffer;
offset = 0;
while (*bufp)
{
if (*bufp == '#')
{
bufp++;
break;
}
bufp++;
}
*(--bufp) = '\0';
bufp = buffer;
while (isspace(*bufp))
bufp++;
if (*bufp == '\0')
{
free(buffer);
free(oldbuffer);
goto again;
}
while (*bufp && !isspace(*bufp))
bufp++;
*(bufp++) = '\0';
while (isspace(*bufp))
bufp++;
if (*bufp == '\0')
oops("Invalid subfont entry in `%s'.", real_sfd_name);
if (fnt->subfont_name)
free(fnt->subfont_name);
fnt->subfont_name = newstring(buffer);
while (1)
{
bufp3 = bufp;
begin = strtol(bufp, &bufp2, 0);
if (bufp == bufp2 || begin < 0 || begin > 0xFFFF)
boops(oldbuffer, bufp - buffer,
"Invalid subfont range or offset entry.");
if (*bufp2 == ':')
{
offset = begin;
if (offset > 0xFF)
boops(oldbuffer, bufp - buffer, "Invalid subfont offset.");
bufp = bufp2 + 1;
while (isspace(*bufp))
bufp++;
continue;
}
else if (*bufp2 == '_')
{
bufp = bufp2 + 1;
if (!isdigit(*bufp))
boops(oldbuffer, bufp - buffer, "Invalid subfont range entry.");
end = strtol(bufp, &bufp2, 0);
if (bufp == bufp2 || end < 0 || end > 0xFFFFL)
boops(oldbuffer, bufp - buffer, "Invalid subfont range entry.");
if (*bufp2 && !isspace(*bufp2))
boops(oldbuffer, bufp2 - buffer, "Invalid subfont range entry.");
if (end < begin)
boops(oldbuffer, bufp - buffer, "End of subfont range too small.");
if (offset + (end - begin) > 255)
boops(oldbuffer, bufp3 - buffer,
"Subfont range too large for current offset (%i).", offset);
}
else if (isspace(*bufp2) || !*bufp2)
end = begin;
else
boops(oldbuffer, bufp2 - buffer, "Invalid subfont range entry.");
for (i = begin; i <= end; i++)
{
if (fnt->sf_code[offset] != -1)
boops(oldbuffer, bufp3 - buffer, "Overlapping subfont ranges.");
fnt->sf_code[offset++] = i;
}
bufp = bufp2;
while (isspace(*bufp))
bufp++;
if (!*bufp)
break;
}
free(buffer);
free(oldbuffer);
return True;
}
void
close_sfd(void)
{
if (sfd)
fclose(sfd);
}
void
handle_sfd(char *s, int *sfd_begin, int *postfix_begin)
{
size_t len;
int i;
Boolean have_atsign;
have_atsign = False;
len = strlen(s);
*sfd_begin = -1;
*postfix_begin = -1;
for (i = 0; s[i]; i++)
{
if (s[i] == '@')
{
if (have_atsign)
{
*postfix_begin = i + 1;
s[i] = '\0';
break;
}
have_atsign = True;
*sfd_begin = i + 1;
s[i] = '\0';
}
}
if (*sfd_begin != -1 &&
(*postfix_begin == -1 || *postfix_begin < *sfd_begin + 2))
oops("Invalid subfont definition file name.");
if (*postfix_begin > -1)
for (i = *postfix_begin; s[i]; i++)
if (s[i] == '/' || s[i] == ':' || s[i] == '\\' || s[i] == '@')
oops("`/', `:', `\\', and `@' not allowed after second `@'.");
}