home *** CD-ROM | disk | FTP | other *** search
/ Atari FTP / ATARI_FTP_0693.zip / ATARI_FTP_0693 / Tex / Tex29 / StTeXsrc.zoo / src / file.c < prev    next >
C/C++ Source or Header  |  1988-09-27  |  12KB  |  560 lines

  1.  
  2. /*
  3.  * @(#)file.c 2.6 EPA
  4.  *
  5.  * Copyright 1987,1988 Pat J Monardo
  6.  *
  7.  * Redistribution of this file is permitted through
  8.  * the specifications in the file COPYING.
  9.  *
  10.  * 
  11.  */
  12.  
  13. #include "tex.h"
  14. #include "token.h"
  15. #include "scan.h"
  16. #include "tokenstack.h"
  17. #include "fmt.h"
  18. #include "file.h"
  19.  
  20. char    name_of_file[FILE_NAME_SIZE];
  21. int     name_length;
  22.  
  23. int     area_delimiter;
  24. int     ext_delimiter;
  25.  
  26. str     cur_area;
  27. str     cur_name;
  28. str     cur_ext;
  29.  
  30. bool    name_in_progress;
  31. str     job_area;
  32. str     job_name;
  33. str     log_name;
  34.  
  35. alpha_file      read_file[16];
  36.  
  37. int     read_open[17]; 
  38.  
  39. str     str_dvi;
  40. str     str_log;
  41. str     str_tex;
  42. str     str_tfm;
  43. str     str_fmt;
  44. str     str_texput;
  45.  
  46. bool
  47. begin_name ()
  48. {
  49.     area_delimiter = 0;
  50.     ext_delimiter = 0;
  51. }
  52.  
  53. bool
  54. more_name (c)
  55.     ascii   c;
  56. {
  57.     if (c == ' ') {
  58.         return FALSE;
  59.     } else {
  60. #ifdef atarist
  61.         if (c == '\\') {
  62. #else
  63.         if (c == '/') {
  64. #endif
  65.             area_delimiter = pool_ptr;
  66.             ext_delimiter = 0;
  67.         } else if (c == '.' && ext_delimiter == 0) {
  68.             ext_delimiter = pool_ptr;
  69.         }
  70.         str_room(1);
  71.         append_char(c);
  72.         return TRUE;
  73.     }
  74. }
  75.  
  76. end_name ()
  77. {
  78.     if (str_ptr + 3 > MAX_STRINGS)
  79.         overflow("number of strings", MAX_STRINGS);
  80.     if (area_delimiter == 0) {
  81.         cur_area = null_str;
  82.     } else {
  83.         cur_area = str_ptr;
  84.         incr(str_ptr);
  85.         str_start[str_ptr] = area_delimiter + 1;
  86.     }
  87.     if (ext_delimiter == 0) {
  88.         cur_ext = null_str;
  89.         cur_name = make_str();
  90.     } else {
  91.         cur_name = str_ptr;
  92.         incr(str_ptr);
  93.         str_start[str_ptr] = ext_delimiter;
  94.         cur_ext = make_str();
  95.     }
  96. }
  97.  
  98. #define append_to_name(F) \
  99.     {c = F; name_of_file[k] = xchr[c]; incr(k);}
  100.  
  101. pack_file_name (n, a, e)
  102.     str     n;
  103.     str     a;
  104.     str     e;
  105. {
  106.     ascii   c;
  107.     int     j;
  108.     int     k;
  109.         
  110.     if (length(a) + length(n) + length(e) >= FILE_NAME_SIZE)
  111.         overflow("file name size", FILE_NAME_SIZE);
  112.     k = 0;
  113.     for (j = str_start[a]; j < str_start[a+1]; incr(j))
  114.         append_to_name(str_pool[j]);
  115.     for (j = str_start[n]; j < str_start[n+1]; incr(j))
  116.         append_to_name(str_pool[j]);
  117.     for (j = str_start[e]; j < str_start[e+1]; incr(j))
  118.         append_to_name(str_pool[j]);
  119.     name_length = k;
  120.     name_of_file[k] = NUL;
  121. }
  122.  
  123. print_file_name (n, a, e)
  124.     str     n;
  125.     str     a;
  126.     str     e;
  127. {
  128.     print_str(a);
  129.     print_str(n);
  130.     print_str(e);
  131. }
  132.  
  133. pack_job_name (s)
  134. {
  135.     cur_area = job_area;
  136.     cur_name = job_name;
  137.     cur_ext = s;
  138.     pack_cur_name();
  139. }
  140.  
  141. str
  142. make_name_string ()
  143. {
  144.     int     k;
  145.  
  146.     str_room(name_length);
  147.     for (k = 0; k < name_length; incr(k))
  148.         append_char(xord[name_of_file[k]]);
  149.     return (make_str());
  150. }
  151.  
  152. scan_file_name ()
  153. {
  154.     name_in_progress = TRUE;
  155.     get_nbx_token();
  156.     begin_name();
  157.     loop {
  158.         if (cur_cmd > OTHER_CHAR || cur_chr > 127) {
  159.             back_input();
  160.             break;
  161.         }
  162.         if (!more_name(cur_chr))
  163.             break;
  164.         get_x_token();
  165.     }
  166.     end_name();
  167.     name_in_progress = FALSE;
  168. }
  169.  
  170. prompt_file_name (s, e)
  171.     chrs    s;
  172.     str     e;
  173. {
  174.     int     k;
  175.  
  176.     if (s[0] == 'i' && s[1] == 'n')
  177.         print_nl("! I can't find file `");
  178.     else print_nl("! I can't write on file `");
  179.     print_file_name(cur_name, cur_area, cur_ext);
  180.     print("'.");
  181.     if (e == str_tex)
  182.         show_context();
  183.     print_nl("Please type another ");
  184.     print(s);
  185.     if (interaction < SCROLL_MODE)
  186.         fatal_error("*** (job aborted, file error in nonstop mode)");
  187.     clear_terminal();
  188.     prompt_input(": ");
  189.     begin_name();
  190.     k = first;
  191.     while (buffer[k] == ' ' && k < last)
  192.         incr(k);
  193.     loop {
  194.         if (k == last)
  195.             break;
  196.         if (! more_name(buffer[k]))
  197.             break;
  198.         incr(k);
  199.     }
  200.     end_name();
  201.     if (cur_ext == null_str)
  202.         cur_ext = e;
  203.     pack_cur_name();
  204. }
  205.  
  206. start_input ()
  207. {
  208.     scan_file_name();
  209.     if (cur_ext == null_str)
  210.         cur_ext = str_tex;
  211.     pack_cur_name();
  212.     loop {
  213.         begin_file_reading();
  214.         if (cur_file = a_open_in())
  215.             break;
  216.         end_file_reading();
  217.         if (cur_ext == str_tex) {
  218.             cur_ext = null_str;
  219.             pack_cur_name();
  220.             begin_file_reading();
  221.             if (cur_file = a_open_in())
  222.                 break;
  223.             end_file_reading();
  224.         }
  225.         prompt_file_name("input file name", str_tex);
  226.     }
  227.     name = a_make_name_string(cur_file);
  228.     if (job_name == 0) {
  229.         job_area = cur_area;
  230.         job_name = cur_name;
  231.         open_log_file();
  232.         if (job_area != null_str)
  233.             set_def_area();
  234.     }
  235.     if (term_offset + length(name) > MAX_PRINT_LINE - 2)
  236.         print_ln();
  237.     else if (term_offset > 0 || file_offset > 0)
  238.         print_char(' ');
  239.     print_char('(');
  240.     print_str(name);
  241.     update_terminal(); 
  242.     state = NEW_LINE;
  243.     input_ln(cur_file, FALSE);
  244.     firm_up_the_line();
  245.     if (end_line_char < 0 || end_line_char > 127)
  246.         decr(limit);
  247.     else buffer[limit] = end_line_char;
  248.     first = limit + 1;
  249.     loc = start;
  250.     line = 1;
  251. }
  252.  
  253. open_log_file ()
  254. {
  255.     int     k;
  256.     int     l;
  257.     char    months[37]; 
  258.     int     old_setting;
  259.  
  260.     old_setting = selector;
  261.     if (job_name == 0) {
  262.         job_area = null_str;
  263.         job_name = str_texput;
  264.     }
  265.     pack_job_name(str_log);
  266.     while ((log_file = a_open_out()) == NULL)
  267.         prompt_file_name("transcript file name", str_log);
  268.     log_name = a_make_name_string(log_file);
  269.     selector = LOG_ONLY;
  270.     fputs(banner, log_file);
  271.     if (format_ident == 0)
  272.         print(" (no format preloaded)");
  273.     else print_str(format_ident);
  274.     print_char(' ');
  275.     print_int(day);
  276.     print_char(' ');
  277.     strcpy(months, "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC");
  278.     for (k = 3 * month - 3; k < 3 * month; incr(k))
  279.         putc(months[k], log_file);
  280.     print_char(' ');
  281.     print_int(year);
  282.     print_char(' ');
  283.     print_two(time / 60);
  284.     print_char(':');
  285.     print_two(time % 60);
  286.     input_stack[input_ptr] = cur_input;
  287.     print_nl("**");
  288.     l = input_stack[0].limit_field;
  289.     if (buffer[l] == end_line_char) decr(l);
  290.     for (k = 1; k <= l; incr(k))
  291.         print_char(buffer[k]);
  292.     print_ln();
  293.     selector = old_setting + 2; 
  294. }
  295.  
  296. bool 
  297. open_fmt_file ()
  298. {
  299.     int     j;
  300.     
  301.     j = loc;
  302.     if (buffer[loc] == '&') {
  303.         incr(loc);
  304.         j = loc;
  305.         buffer[last] = ' ';
  306.         while (buffer[j] != ' ') incr(j);
  307.         pack_buffered_name(loc, j);
  308.         if (fmt_file = w_open_in()) goto found;
  309.         wake_up_terminal();
  310.         puts("Sorry, I can't find that format, will try PLAIN.");
  311.         update_terminal();
  312.     }
  313.     strcpy(name_of_file, TeX_format_default);
  314.     name_length = 9;
  315.     if ((fmt_file = w_open_in()) == NULL) {
  316.         puts("I can't find the PLAIN format file!");
  317.         return FALSE;
  318.     }
  319. found: 
  320.     loc = j;
  321.     return TRUE;
  322. }
  323.  
  324. pack_buffered_name (a, b)
  325.     int     a;
  326.     int     b;
  327. {
  328.     ascii   c;
  329.     int     j;
  330.     int     k;
  331.  
  332.     k = 0;
  333.     for (j = a; j < b; incr(j))
  334.         append_to_name(buffer[j]);
  335.     append_to_name(xchr['.']);
  336.     append_to_name(xchr['f']);
  337.     append_to_name(xchr['m']);
  338.     append_to_name(xchr['t']);
  339.     append_to_name(NUL);
  340.     name_length = b - a + 4;
  341. }
  342.  
  343. /* 
  344.  * fixed arrays are used to hold the paths, to avoid any possible problems
  345.  * involving interaction of malloc and undump
  346.  */ 
  347.  
  348. chrs    cur_path;
  349.  
  350. char    input_path[MAX_PATH_CHARS] = default_input_path;
  351. char    font_path[MAX_PATH_CHARS] = default_font_path;
  352. char    format_path[MAX_PATH_CHARS] = default_format_path;
  353.  
  354. set_paths ()
  355. {
  356.     chrs    env_path;
  357.     chrs    getenv();
  358.     
  359.     if (env_path = getenv("TEXINPUTS"))
  360.         copy_path(input_path, env_path, MAX_PATH_CHARS);
  361.     if (env_path = getenv("TEXFONTS"))
  362.         copy_path(font_path, env_path, MAX_PATH_CHARS);
  363.     if (env_path = getenv("TEXFORMATS"))
  364.         copy_path(format_path, env_path, MAX_PATH_CHARS);
  365. }
  366.  
  367. /*
  368.  * copy_path(s1,s2,n) copies at most n characters (including the null)
  369.  * from string s2 to string s1, giving an error message for paths
  370.  * that are too long.
  371.  */
  372.  
  373. copy_path (s1, s2, n)
  374.     chrs        s1;
  375.     chrs        s2;
  376.     int         n;
  377. {
  378.     int         i;
  379.  
  380.     i = 0;
  381.     while (s2[i] != NUL) {
  382.         s1[i] = s2[i];
  383.         incr(i);
  384.         if (i == n) {
  385.             fprintf(stderr, "! Environment search path is too big\n");
  386.             s1[i - 1] = '\0';
  387.             return;
  388.         }
  389.     }
  390.     s1[i] = NUL;
  391. }
  392.  
  393. #define append_to_def_area(C) \
  394.     {if (i == MAX_PATH_CHARS)  \
  395.         overflow("def_area", MAX_PATH_CHARS); \
  396.     def_area[i] = C; \
  397.     incr(i), incr(j);}
  398.  
  399. set_def_area()
  400. {   
  401.     char    c;
  402.     int     i;
  403.     int     j;
  404.     char    def_area[MAX_PATH_CHARS];
  405.  
  406.     i = 0;
  407.     j = str_start[job_area];
  408.     while (j < str_start[job_area + 1])
  409.         append_to_def_area(str_pool[j]);
  410. #ifdef atarist
  411.     append_to_def_area(';');
  412. #else
  413.     append_to_def_area(':');
  414. #endif
  415.     j = 0;
  416.     while ((c = input_path[j]) != NUL)
  417.         append_to_def_area(c);
  418.     append_to_def_area(NUL);
  419.     strcpy(input_path, def_area);
  420. }
  421.  
  422. /*
  423.  *  test_access(amode, file_path)
  424.  *
  425.  *  Test whether or not the file whose name is in the global name_of_file
  426.  *  can be opened for reading according to access mode.
  427.  *
  428.  *  If the filename given in name_of_file does not begin with '/', we try 
  429.  *  prepending all the ':'-separated areanames in the appropriate path to the
  430.  *  filename until access can be made.
  431.  */
  432.  
  433. bool
  434. test_access (amode, file_path)
  435.     int     amode;
  436.     int     file_path;
  437. {
  438.     int     nl;
  439.     bool    ok;
  440.     char    original_name[FILE_NAME_SIZE];
  441.  
  442.     strcpy(original_name, name_of_file);
  443.     nl = name_length;
  444.     switch (file_path)
  445.     {
  446.     case NO_FILE_PATH:
  447.         cur_path = NULL;
  448.         break;
  449.  
  450.     case INPUT_FILE_PATH: 
  451.         cur_path = input_path;
  452.         break;
  453.  
  454.     case FONT_FILE_PATH: 
  455.         cur_path = font_path;
  456.         break;
  457.  
  458.     case FORMAT_FILE_PATH:
  459.         cur_path = format_path;
  460.         break;
  461.     }
  462. #ifdef atarist
  463.     if (
  464.     (name_of_file[0] == '\\')                                ||
  465.     ((name_of_file[0] == '.')  && (name_of_file[1] == '\\')) ||
  466.     ((name_of_file[0] != '\\') && (name_of_file[1] == ':'))  ||
  467.     ((name_of_file[0] != '\\') && (name_of_file[1] == ':') &&
  468.      (name_of_file[2] == '\\'))
  469.        )
  470. #else
  471.     if (name_of_file[0] == '/' ||
  472.         name_of_file[0] == '.' && name_of_file[1] == '/')
  473. #endif
  474.         cur_path = NULL;
  475.     do {
  476.         strcpy(name_of_file, original_name);
  477.         name_length = nl;
  478.         get_real_name();
  479.         switch (amode)
  480.         {
  481.         case READ_ACCESS:
  482.             ok = access(name_of_file, amode) == 0 ? TRUE : FALSE;
  483.             break;
  484.  
  485.         case WRITE_ACCESS:
  486.             ok = fclose(fopen(name_of_file, "w")) == 0;
  487.             break;
  488.         }
  489.     } while (!ok && cur_path != NULL);
  490.     return ok;
  491. }
  492.  
  493. #define append_to_real_name(C) \
  494.     {if (i == FILE_NAME_SIZE) \
  495.         overflow("real_name", FILE_NAME_SIZE); \
  496.     real_name[i] = C; \
  497.     incr(i), incr(j);}
  498.  
  499. get_real_name ()
  500. {
  501.     int     i;
  502.     int     j;
  503.     char    real_name[FILE_NAME_SIZE];
  504.     
  505.     i = j = 0;
  506.     if (cur_path) {
  507. #ifdef atarist
  508.         while (cur_path[j] != ';' && cur_path[j] != NUL)
  509. #else
  510.         while (cur_path[j] != ':' && cur_path[j] != NUL)
  511. #endif
  512.             append_to_real_name(cur_path[j]);
  513.         if (j == 0) {
  514. #ifdef atarist
  515.             append_to_real_name('.');
  516.             append_to_real_name('\\');
  517. #else
  518.             append_to_real_name('.');
  519.             append_to_real_name('/');
  520. #endif
  521.             --j;
  522. #ifdef atarist
  523.         } else if (real_name[j - 1] != '\\') {
  524. #else
  525.         } else if (real_name[j - 1] != '/') {
  526. #endif
  527. #ifdef atarist
  528.             append_to_real_name('\\');
  529. #else
  530.             append_to_real_name('/');
  531. #endif
  532.             --j;
  533.         }
  534.         if (cur_path[j] == NUL)
  535.             cur_path = NULL;
  536.         else cur_path += j;
  537.     }
  538.     j = 0;
  539.     while (j < name_length)
  540.         append_to_real_name(name_of_file[j]);
  541.     append_to_real_name(NUL);
  542.     strcpy(name_of_file, real_name);
  543.     name_length = i - 1;
  544. }
  545.  
  546. init_file ()
  547. {
  548.     int     i;
  549.  
  550.     name_in_progress = FALSE;
  551.     str_tex = make_str_given(".tex");
  552.     str_dvi = make_str_given(".dvi");
  553.     str_log = make_str_given(".log");
  554.     str_tfm = make_str_given(".tfm");
  555.     str_fmt = make_str_given(".fmt");
  556.     str_texput = make_str_given("texput");
  557.     for (i = 0; i <= 16; incr(i)) 
  558.         read_open[i] = CLOSED;
  559. }
  560.