home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Datafile PD-CD 3
/
PDCD_3.iso
/
tex
/
texsrc1
/
Src
/
lib
/
c
/
texmf
< prev
next >
Wrap
Text File
|
1993-05-09
|
22KB
|
808 lines
/* Hand-coded routines for TeX or Metafont in C. This code was (mostly)
written by Tim Morgan, drawing from other Unix ports of TeX. */
/* Either `texd.h' or `mfd.h' will include `../common/texmf.h'. */
/* Instantiate data in `texd.h' or `mfd.h' here. */
#define EXTERN
#ifdef TeX
#include "texd.h"
#define dump_default_var TEXformatdefault
#define dump_default " plain.fmt"
#define dump_format " %s.fmt"
#define dump_ext_length 4
#define dump_default_length formatdefaultlength
#define virgin_program "virtex"
#define main_program texbody
#define edit_value tex_edit_value
#define edit_var "TEXEDIT"
#else /* not TeX */
#include "mfd.h"
#define dump_default_var MFbasedefault
#define dump_default " plain.base"
#define dump_format " %s.base"
#define dump_ext_length 5
#define dump_default_length basedefaultlength
#define virgin_program "virmf"
#define main_program main_body
#define edit_value mf_edit_value
#define edit_var "MFEDIT"
#endif /* not TeX */
#include "c-ctype.h"
#include "c-pathch.h"
/* For `struct tm'. */
#include <time.h>
extern struct tm *localtime ();
/* Catch interrupts. */
#include <signal.h>
#ifdef FUNNY_CORE_DUMP
void funny_core_dump ();
#endif
/* ridderbusch.pad@nixdorf.com says this is necessary. */
#ifdef ATARI_ST
int _stksize = -1L;
#endif
/* The main program, etc. */
/* What we were invoked as and with. */
static char *program_name = NULL;
static int gargc;
char **gargv;
/* The entry point: set up for reading the command line, which will
happen in `topenin', then call the main body. */
int
main (ac, av)
int ac;
char *av[];
{
char custom_default[PATH_MAX];
gargc = ac;
gargv = av;
dump_default_var = dump_default;
dump_default_length = strlen (dump_default + 1);
#ifndef INI
if (readyalready != 314159)
{
program_name = strrchr (av[0], PATH_SEP);
if (program_name == NULL)
program_name = av[0];
else
program_name++;
if (strcmp (program_name, virgin_program) != 0)
{
/* TeX or Metafont adds the space at the end of the name. */
(void) sprintf (custom_default, dump_format, program_name);
dump_default_var = custom_default;
dump_default_length = strlen (program_name) + dump_ext_length;
}
}
#endif /* not INI */
main_program ();
}
/* This is supposed to ``open the terminal for input'', but what we
really do is copy command line arguments into TeX's or Metafont's
buffer, so they can handle them. If nothing is available, or we've
been called already (and hence, gargc==0), we return with
`last=first'. */
void
topenin ()
{
register int i;
buffer[first] = 0; /* So the first `strcat' will work. */
if (gargc > 1)
{ /* We have command line arguments. */
for (i = 1; i < gargc; i++)
{
(void) strcat ((char *) &buffer[first], gargv[i]);
(void) strcat ((char *) &buffer[first], " ");
}
gargc = 0; /* Don't do this again. */
}
/* Find the end of the buffer. */
for (last = first; buffer[last]; ++last)
;
/* Make `last' be one past the last non-blank non-formfeed character
in `buffer'. */
for (--last; last >= first
&& ISSPACE (buffer[last]) && buffer[last] != '\f'; --last)
;
last++;
/* One more time, this time converting to TeX's internal character
representation. */
#ifdef NONASCII
for (i = first; i < last; i++)
buffer[i] = xord[buffer[i]];
#endif
}
/* All our interrupt handler has to do is set TeX's or Metafont's global
variable `interrupt'; then they will do everything needed. */
#ifdef RISCOS
RETSIGTYPE
catch_interrupt (int s)
#else
static RETSIGTYPE
catch_interrupt ()
#endif
{
interrupt = 1;
(void) signal (SIGINT, catch_interrupt);
}
/* Besides getting the date and time here, we also set up the interrupt
handler, for no particularly good reason. It's just that since the
`fix_date_and_time' routine is called early on (section 1337 in TeX,
``Get the first line of input and prepare to start''), this is as
good a place as any. */
void
get_date_and_time (minutes, day, month, year)
integer *minutes, *day, *month, *year;
{
time_t clock = time ((time_t *) 0);
struct tm *tmptr = localtime (&clock);
*minutes = tmptr->tm_hour * 60 + tmptr->tm_min;
*day = tmptr->tm_mday;
*month = tmptr->tm_mon + 1;
*year = tmptr->tm_year + 1900;
{
RETSIGTYPE (*old_handler) ();
if ((old_handler = signal (SIGINT, catch_interrupt)) != SIG_DFL)
(void) signal (SIGINT, old_handler);
}
}
/* I/O for TeX and Metafont. */
/* Read a line of input as efficiently as possible while still looking
like Pascal. We set `last' to `first' and return `false' if we get
to eof. Otherwise, we return `true' and set last = first +
length(line except trailing whitespace). */
boolean
input_line (f)
FILE *f;
{
register int i;
last = first;
while (last < bufsize && (i = getc (f)) != EOF && i != '\n')
buffer[last++] = i;
if (i == EOF && last == first)
return false;
/* We didn't get the whole line because our buffer was too small. */
if (i != EOF && i != '\n')
{
(void) fprintf (stderr,
"! Unable to read an entire line---bufsize=%d.\n",
bufsize);
(void) fprintf (stderr, "Please ask a wizard to enlarge me.\n");
uexit (1);
}
buffer[last] = ' ';
if (last >= maxbufstack)
maxbufstack = last;
/* Trim trailing whitespace. */
while (last > first
&& isblank (buffer[last - 1]) && buffer[last - 1] != '\r')
--last;
/* Don't bother using xord if we don't need to. */
#ifdef NONASCII
for (i = first; i <= last; i++)
buffer[i] = xord[buffer[i]];
#endif
return true;
}
/* This string specifies what the `e' option does in response to an
error message. */
static char *edit_value = EDITOR;
/* This procedure is due to sjc@s1-c. TeX (or Metafont) calls it when
the user types `e' in response to an error, invoking a text editor on
the erroneous source file. FNSTART is how far into FILENAME the
actual filename starts; FNLENGTH is how long the filename is.
See ../site.h for how to set the default, and how to override it. */
void
calledit (filename, fnstart, fnlength, linenumber)
ASCIIcode *filename;
poolpointer fnstart;
integer fnlength, linenumber;
{
char *temp, *command;
char c;
int sdone, ddone, i;
sdone = ddone = 0;
filename += fnstart;
/* Close any open input files, since we're going to kill the job. */
for (i = 1; i <= inopen; i++)
(void) fclose (inputfile[i]);
/* Replace the default with the value of the appropriate environment
variable, if it's set. */
temp = getenv (edit_var);
if (temp != NULL)
edit_value = temp;
/* Construct the command string. The `11' is the maximum length an
integer might be. */
command = (string) xmalloc (strlen (edit_value) + fnlength + 11);
/* So we can construct it as we go. */
temp = command;
while ((c = *edit_value++) != 0)
{
if (c == '%')
{
switch (c = *edit_value++)
{
case 'd':
if (ddone)
{
(void) fprintf (stderr,
"! `%%d' cannot appear twice in editor command.\n");
uexit (1);
}
(void) sprintf (temp, "%d", linenumber);
while (*temp != '\0')
temp++;
ddone = 1;
break;
case 's':
if (sdone)
{
(void) fprintf(stderr,
"! `%%s' cannot appear twice in editor command.\n");
uexit (1);
}
for (i =0; i < fnlength; i++)
*temp++ = Xchr (filename[i]);
sdone = 1;
break;
case '\0':
*temp++ = '%';
/* Back up to the null to force termination. */
edit_value--;
break;
default:
*temp++ = '%';
*temp++ = c;
break;
}
}
else
*temp++ = c;
}
*temp = 0;
/* Execute the command. */
if (system (command) != 0)
fprintf (stderr, "! Trouble executing `%s'.\n", comma