home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 3 / PDCD_3.iso / tex / texsrc1 / Src / lib / c / texmf < prev    next >
Text File  |  1993-05-09  |  22KB  |  808 lines

  1. /* Hand-coded routines for TeX or Metafont in C.  This code was (mostly)
  2.    written by Tim Morgan, drawing from other Unix ports of TeX.  */
  3.  
  4. /* Either `texd.h' or `mfd.h' will include `../common/texmf.h'.  */
  5.  
  6. /* Instantiate data in `texd.h' or `mfd.h' here.  */
  7. #define    EXTERN
  8.  
  9. #ifdef TeX
  10. #include "texd.h"
  11. #define dump_default_var TEXformatdefault
  12. #define dump_default " plain.fmt"
  13. #define dump_format " %s.fmt"
  14. #define dump_ext_length 4
  15. #define dump_default_length formatdefaultlength
  16. #define virgin_program "virtex"
  17. #define main_program texbody
  18. #define edit_value tex_edit_value
  19. #define edit_var "TEXEDIT"
  20. #else /* not TeX */
  21. #include "mfd.h"
  22. #define dump_default_var MFbasedefault
  23. #define dump_default " plain.base"
  24. #define dump_format " %s.base"
  25. #define dump_ext_length 5
  26. #define dump_default_length basedefaultlength
  27. #define virgin_program "virmf"
  28. #define main_program main_body
  29. #define edit_value mf_edit_value
  30. #define edit_var "MFEDIT"
  31. #endif /* not TeX */
  32.  
  33. #include "c-ctype.h"
  34. #include "c-pathch.h"
  35.  
  36. /* For `struct tm'.  */
  37. #include <time.h>
  38. extern struct tm *localtime ();
  39.  
  40. /* Catch interrupts.  */
  41. #include <signal.h>
  42.  
  43. #ifdef FUNNY_CORE_DUMP
  44. void funny_core_dump ();
  45. #endif
  46.  
  47. /* ridderbusch.pad@nixdorf.com says this is necessary.  */
  48. #ifdef ATARI_ST
  49. int _stksize = -1L;
  50. #endif
  51.  
  52. /* The main program, etc.  */
  53.  
  54. /* What we were invoked as and with.  */
  55. static char *program_name = NULL;
  56. static int gargc;
  57. char **gargv;
  58.  
  59.  
  60. /* The entry point: set up for reading the command line, which will
  61.    happen in `topenin', then call the main body.  */
  62.  
  63. int
  64. main (ac, av)
  65.   int ac;
  66.   char *av[];
  67. {
  68.   char custom_default[PATH_MAX];
  69.  
  70.   gargc = ac;
  71.   gargv = av;
  72.  
  73.   dump_default_var = dump_default;
  74.   dump_default_length = strlen (dump_default + 1);
  75.  
  76. #ifndef INI
  77.   if (readyalready != 314159)
  78.     {
  79.       program_name = strrchr (av[0], PATH_SEP);
  80.       if (program_name == NULL)
  81.     program_name = av[0];
  82.       else
  83.     program_name++;
  84.       if (strcmp (program_name, virgin_program) != 0)
  85.         {
  86.           /* TeX or Metafont adds the space at the end of the name.  */
  87.           (void) sprintf (custom_default, dump_format, program_name);
  88.           dump_default_var = custom_default;
  89.           dump_default_length = strlen (program_name) + dump_ext_length;
  90.         }
  91.     }
  92. #endif /* not INI */
  93.  
  94.   main_program ();
  95.  
  96.  
  97. /* This is supposed to ``open the terminal for input'', but what we
  98.    really do is copy command line arguments into TeX's or Metafont's
  99.    buffer, so they can handle them.  If nothing is available, or we've
  100.    been called already (and hence, gargc==0), we return with
  101.    `last=first'.  */
  102.  
  103. void
  104. topenin ()
  105. {
  106.   register int i;
  107.  
  108.   buffer[first] = 0;    /* So the first `strcat' will work.  */
  109.  
  110.   if (gargc > 1)
  111.     { /* We have command line arguments.  */
  112.       for (i = 1; i < gargc; i++)
  113.         {
  114.       (void) strcat ((char *) &buffer[first], gargv[i]);
  115.           (void) strcat ((char *) &buffer[first], " ");
  116.     }
  117.       gargc = 0;    /* Don't do this again.  */
  118.     }
  119.  
  120.   /* Find the end of the buffer.  */
  121.   for (last = first; buffer[last]; ++last)
  122.     ;
  123.  
  124.   /* Make `last' be one past the last non-blank non-formfeed character
  125.      in `buffer'.  */
  126.   for (--last; last >= first
  127.        && ISSPACE (buffer[last]) && buffer[last] != '\f'; --last) 
  128.     ;
  129.   last++;
  130.  
  131.   /* One more time, this time converting to TeX's internal character
  132.      representation.  */
  133. #ifdef NONASCII
  134.   for (i = first; i < last; i++)
  135.     buffer[i] = xord[buffer[i]];
  136. #endif
  137. }
  138.  
  139. /* All our interrupt handler has to do is set TeX's or Metafont's global
  140.    variable `interrupt'; then they will do everything needed.  */
  141.  
  142. #ifdef RISCOS
  143. RETSIGTYPE
  144. catch_interrupt (int s) 
  145. #else
  146. static RETSIGTYPE
  147. catch_interrupt ()
  148. #endif
  149. {
  150.   interrupt = 1;
  151.   (void) signal (SIGINT, catch_interrupt);
  152. }
  153.  
  154.  
  155. /* Besides getting the date and time here, we also set up the interrupt
  156.    handler, for no particularly good reason.  It's just that since the
  157.    `fix_date_and_time' routine is called early on (section 1337 in TeX,
  158.    ``Get the first line of input and prepare to start''), this is as
  159.    good a place as any.  */
  160.  
  161. void
  162. get_date_and_time (minutes, day, month, year)
  163.   integer *minutes, *day, *month, *year;
  164. {
  165.   time_t clock = time ((time_t *) 0);
  166.   struct tm *tmptr = localtime (&clock);
  167.  
  168.   *minutes = tmptr->tm_hour * 60 + tmptr->tm_min;
  169.   *day = tmptr->tm_mday;
  170.   *month = tmptr->tm_mon + 1;
  171.   *year = tmptr->tm_year + 1900;
  172.  
  173.   {
  174.     RETSIGTYPE (*old_handler) ();
  175.  
  176.     if ((old_handler = signal (SIGINT, catch_interrupt)) != SIG_DFL)
  177.       (void) signal (SIGINT, old_handler);
  178.   }
  179. }
  180.  
  181. /* I/O for TeX and Metafont.  */
  182.  
  183. /* Read a line of input as efficiently as possible while still looking
  184.    like Pascal.  We set `last' to `first' and return `false' if we get
  185.    to eof.  Otherwise, we return `true' and set last = first +
  186.    length(line except trailing whitespace).  */
  187.  
  188. boolean
  189. input_line (f)
  190.   FILE *f;
  191. {
  192.   register int i;
  193.  
  194.   last = first;
  195.  
  196.   while (last < bufsize && (i = getc (f)) != EOF && i != '\n')
  197.     buffer[last++] = i;
  198.  
  199.   if (i == EOF && last == first)
  200.       return false;
  201.  
  202.   /* We didn't get the whole line because our buffer was too small.  */
  203.   if (i != EOF && i != '\n')
  204.     {
  205.       (void) fprintf (stderr,
  206.                      "! Unable to read an entire line---bufsize=%d.\n",
  207.                      bufsize);
  208.       (void) fprintf (stderr, "Please ask a wizard to enlarge me.\n");
  209.       uexit (1);
  210.     }
  211.  
  212.   buffer[last] = ' ';
  213.   if (last >= maxbufstack)
  214.     maxbufstack = last;
  215.  
  216.   /* Trim trailing whitespace.  */
  217.   while (last > first
  218.          && isblank (buffer[last - 1]) && buffer[last - 1] != '\r')
  219.     --last;
  220.  
  221.   /* Don't bother using xord if we don't need to.  */
  222. #ifdef NONASCII
  223.   for (i = first; i <= last; i++)
  224.      buffer[i] = xord[buffer[i]];
  225. #endif
  226.  
  227.     return true;
  228. }
  229.  
  230. /* This string specifies what the `e' option does in response to an
  231.    error message.  */ 
  232. static char *edit_value = EDITOR;
  233.  
  234. /* This procedure is due to sjc@s1-c.  TeX (or Metafont) calls it when
  235.    the user types `e' in response to an error, invoking a text editor on
  236.    the erroneous source file.  FNSTART is how far into FILENAME the
  237.    actual filename starts; FNLENGTH is how long the filename is.
  238.    
  239.    See ../site.h for how to set the default, and how to override it.  */
  240.  
  241. void
  242. calledit (filename, fnstart, fnlength, linenumber)
  243.   ASCIIcode *filename;
  244.   poolpointer fnstart;
  245.   integer fnlength, linenumber;
  246. {
  247.   char *temp, *command;
  248.   char c;
  249.   int sdone, ddone, i;
  250.  
  251.   sdone = ddone = 0;
  252.   filename += fnstart;
  253.  
  254.   /* Close any open input files, since we're going to kill the job.  */
  255.   for (i = 1; i <= inopen; i++)
  256.     (void) fclose (inputfile[i]);
  257.  
  258.   /* Replace the default with the value of the appropriate environment
  259.      variable, if it's set.  */
  260.   temp = getenv (edit_var);
  261.   if (temp != NULL)
  262.     edit_value = temp;
  263.  
  264.   /* Construct the command string.  The `11' is the maximum length an
  265.      integer might be.  */
  266.   command = (string) xmalloc (strlen (edit_value) + fnlength + 11);
  267.  
  268.   /* So we can construct it as we go.  */
  269.   temp = command;
  270.  
  271.   while ((c = *edit_value++) != 0)
  272.     {
  273.       if (c == '%')
  274.         {
  275.           switch (c = *edit_value++)
  276.             {
  277.         case 'd':
  278.           if (ddone)
  279.                 {
  280.           (void) fprintf (stderr,
  281.                            "! `%%d' cannot appear twice in editor command.\n");
  282.               uexit (1);
  283.         }
  284.               (void) sprintf (temp, "%d", linenumber);
  285.               while (*temp != '\0')
  286.                 temp++;
  287.               ddone = 1;
  288.               break;
  289.  
  290.         case 's':
  291.               if (sdone)
  292.                 {
  293.               (void) fprintf(stderr,
  294.                            "! `%%s' cannot appear twice in editor command.\n");
  295.           uexit (1);
  296.         }
  297.               for (i =0; i < fnlength; i++)
  298.         *temp++ = Xchr (filename[i]);
  299.               sdone = 1;
  300.               break;
  301.  
  302.         case '\0':
  303.               *temp++ = '%';
  304.               /* Back up to the null to force termination.  */
  305.           edit_value--;
  306.           break;
  307.  
  308.         default:
  309.           *temp++ = '%';
  310.           *temp++ = c;
  311.           break;
  312.         }
  313.     }
  314.       else
  315.     *temp++ = c;
  316.     }
  317.  
  318.   *temp = 0;
  319.  
  320.   /* Execute the command.  */
  321.   if (system (command) != 0)
  322.     fprintf (stderr, "! Trouble executing `%s'.\n", comma