home *** CD-ROM | disk | FTP | other *** search
/ Mega Top 1 / os2_top1.zip / os2_top1 / APPS / TEKST / CMTEX330 / SOURCE / FILEIO.C < prev    next >
C/C++ Source or Header  |  1993-01-17  |  11KB  |  646 lines

  1.  
  2. /*
  3.  * %Y%:%M%:%I%:%Q%
  4.  *
  5.  * Copyright 1987,1988,1991 Pat J Monardo
  6.  *
  7.  * Redistribution of this file is permitted through
  8.  * the specifications in the file COPYING.
  9.  *
  10.  *
  11.  */
  12.  
  13. #ifndef lint
  14. static char *sccsid = "%A%";
  15. #endif
  16.  
  17. #include <sys/types.h>
  18. #ifdef quad
  19. #undef quad
  20. #endif
  21. #include <sys/stat.h>
  22.  
  23. #include "tex.h"
  24.  
  25. int    name_length;
  26. str    name_of_file;
  27. str    name_str;
  28. str    area_str;
  29. str    ext_str;
  30.  
  31. str    cur_name;
  32. str    cur_area;
  33. str    cur_ext;
  34.  
  35. str    job_area;
  36. str    job_name;
  37.  
  38. bool    name_in_progress;
  39. bool    log_opened;
  40.  
  41. int    area_delimiter;
  42. int    ext_delimiter;
  43. int    path_delimiter;
  44.  
  45. file    read_file[16];
  46.  
  47. int    read_open[17]; 
  48.  
  49. str    str_dvi;
  50. str    str_log;
  51. str    str_tex;
  52. str    str_tfm;
  53. str    str_texput;
  54.  
  55. void
  56. begin_name ()
  57. {
  58.     name_str = name_of_file;
  59.     area_str = null_str;
  60.     ext_str = null_str;
  61. }
  62.         
  63. #define append_to_name(C) \
  64.     {if (name_str - name_of_file == MAX_STR_SIZE) \
  65.         overflow("file name", MAX_STR_SIZE); \
  66.     *name_str++ = C;}
  67.  
  68. bool
  69. more_name (c)
  70.     int    c;
  71. {
  72.     if (c == ' ') {
  73.         return FALSE;
  74.     } else {
  75.         append_to_name(c);
  76.         if (c == area_delimiter) {
  77.             area_str = name_str;
  78.             ext_str = null_str;
  79.         } else if (c == ext_delimiter && ext_str == null_str) {
  80.             ext_str = name_str - 1;
  81.         }
  82.         return TRUE;
  83.     }
  84. }
  85.  
  86. void
  87. end_name ()
  88. {
  89.     int    n;
  90.  
  91.     if (area_str == null_str) {
  92.         cur_area = null_str;
  93.         area_str = name_of_file;
  94.     } else {
  95.         n = area_str - name_of_file;
  96.         cur_area = new_str(n);
  97.         strncpy(cur_area, name_of_file, n);
  98.     }
  99.     if (ext_str == null_str) {
  100.         cur_ext = null_str;
  101.         ext_str = name_str;
  102.     } else {
  103.         n = name_str - ext_str;
  104.         cur_ext = new_str(n);
  105.         strncpy(cur_ext, ext_str, n);
  106.     }
  107.     n = ext_str - area_str;
  108.     if (n == 0) {
  109.         cur_name = null_str;
  110.     } else {
  111.         cur_name = new_str(n);
  112.         strncpy(cur_name, area_str, n);
  113.     }    
  114. }
  115.  
  116. void
  117. scan_file_name ()
  118. {
  119.     name_in_progress = TRUE;
  120.     get_nbx_token();
  121.     begin_name();
  122.     loop {
  123.         if (cur_cmd > OTHER_CHAR || cur_chr > 255) {
  124.             back_input();
  125.             break;
  126.         }
  127.         if (!more_name(cur_chr)) {
  128.             break;
  129.         }
  130.         get_x_token();
  131.     }
  132.     end_name();
  133.     name_in_progress = FALSE;
  134. }
  135.  
  136.  
  137. void
  138. pack_file_name (n, a, e)
  139.     str    n;
  140.     str    a;
  141.     str    e;
  142. {
  143.     str    s;
  144.  
  145.     name_str = name_of_file;
  146.     for (s = a; *s; incr(s)) {
  147.         append_to_name(*s);
  148.     }
  149.     for (s = n; *s; incr(s)) {
  150.         append_to_name(*s);
  151.     }
  152.     for (s = e; *s; incr(s)) {
  153.         append_to_name(*s);
  154.     }
  155.     append_to_name(NUL);
  156.     name_length = name_str - name_of_file;
  157. }
  158.  
  159. void
  160. pack_job_name (s)
  161.     str    s;
  162. {
  163.     cur_area = job_area;
  164.     cur_name = job_name;
  165.     cur_ext = s;
  166.     pack_cur_name();
  167. }
  168.  
  169. void
  170. print_file_name (n, a, e)
  171.     str    n;
  172.     str    a;
  173.     str    e;
  174. {
  175.     print(a);
  176.     print(n);
  177.     print(e);
  178. }
  179.  
  180. str
  181. make_name_str ()
  182. {
  183.     str    s;
  184.  
  185.     s = new_str(name_length);
  186.     strcpy(s, name_of_file);
  187.  
  188.     return (s);
  189. }
  190.  
  191. void
  192. prompt_file_name (s, e)
  193.     str    s;
  194.     str    e;
  195. {
  196.     str    t;
  197.  
  198.     if (s[0] == 'i' && s[1] == 'n') {
  199.         print_nl("! I can't find file `");
  200.     } else {
  201.         print_nl("! I can't write on file `");
  202.     }
  203.     print_file_name(cur_name, cur_area, cur_ext);
  204.     print("'.");
  205.     if (e == str_tex) {
  206.         show_context();
  207.     }
  208.     print_nl("Please type another ");
  209.     print(s);
  210.     if (interaction < SCROLL_MODE) {
  211.         fatal_error("*** (job aborted, file error in nonstop mode)");
  212.     }
  213.     clear_terminal();
  214.     prompt_input(": ");
  215.     begin_name();
  216.     t = cur_str;
  217.     while (*t == ' ' && t < cur_str_ptr) {
  218.         incr(t);
  219.     }
  220.     while (t < cur_str_ptr && more_name(*t)) {
  221.         incr(t);
  222.     }
  223.     end_name();
  224.     if (cur_ext == null_str) {
  225.         cur_ext = e;
  226.     }
  227.     pack_cur_name();
  228.     flush_str();
  229. }
  230.  
  231. void
  232. start_input ()
  233. {
  234.     int    save_selector;
  235.  
  236.     scan_file_name();
  237.     if (cur_ext == null_str) {
  238.         cur_ext = str_tex;
  239.     }
  240.     pack_cur_name();
  241.     loop {
  242.         begin_file_reading();
  243.         if (cur_file = a_open_in()) {
  244.             break;
  245.         }
  246.         end_file_reading();
  247.         if (cur_ext == str_tex) {
  248.             cur_ext = null_str;
  249.             pack_cur_name();
  250.             begin_file_reading();
  251.             if (cur_file = a_open_in()) {
  252.                 break;
  253.             }
  254.             end_file_reading();
  255.         }
  256.         prompt_file_name("input file name", str_tex);
  257.     }
  258.     name = make_name_str();
  259.     if (job_name == null_str) {
  260.         job_area = cur_area;
  261.         job_name = cur_name;
  262.         open_log_file();
  263.         save_selector = selector;
  264.         selector = NEW_STRING;
  265.         print(" (preloaded format=");
  266.         print(job_name);
  267.         print(" ");
  268.         print_int(year % 100);
  269.         print(".");
  270.         print_int(month);
  271.         print(".");
  272.         print_int(day);
  273.         print(")");
  274.         format_ident = make_str();
  275.         selector = save_selector;
  276.     }
  277.     if (term_offset + str_length(name) > MAX_PRINT_LINE - 2) {
  278.         print_ln();
  279.     } else if (term_offset > 0 || file_offset > 0) {
  280.         print(" ");
  281.     }
  282.     incr(open_parens);
  283.     print("(");
  284.     print(name);
  285.     update_terminal(); 
  286.     state = NEW_LINE;
  287.     line = 1;
  288.     index = 18;
  289.     input_ln(cur_file);
  290.     firm_up_the_line();
  291.     if (end_line_char_active) {
  292.         *++limit = end_line_char;
  293.     }
  294.     next = buffer;
  295. }
  296.  
  297. FILE *
  298. a_open_in ()
  299. {
  300.     if (test_access(READ_ACCESS, INPUT_FILE_PATH)) {
  301.         return (fopen(name_of_file, "r"));
  302.     }
  303.     return null_file;
  304. }
  305.  
  306. FILE *
  307. a_open_out ()
  308. {
  309.     if (test_access(WRITE_ACCESS, NO_FILE_PATH)) {
  310.         return (fopen(name_of_file, "w"));
  311.     }
  312.     return null_file;
  313. }
  314.  
  315. FILE *
  316. b_open_in ()
  317. {
  318.     if (test_access(READ_ACCESS, FONT_FILE_PATH)) {
  319.         return (fopen(name_of_file, "rb"));
  320.     }
  321.     return null_file;
  322. }
  323.  
  324. FILE *
  325. b_open_out ()
  326. {
  327.     if (test_access(WRITE_ACCESS, NO_FILE_PATH)) {
  328.         return (fopen(name_of_file, "wb"));
  329.     }
  330.     return null_file;
  331. }
  332.  
  333. bool 
  334. input_ln (f)
  335.     file    f;
  336. {
  337.     int    c;
  338.  
  339.     next = buffer;
  340.     limit = next - 1;
  341.     c = getc(f);
  342.     if (feof(f)) {
  343.         return FALSE;
  344.     }
  345.     loop {
  346.         if (c == EOLN || c == EOF) {
  347.             break;
  348.         }
  349.         if ((*next = xord[c]) != ' ') {
  350.             limit = next;
  351.         }
  352.         if (++next >= buffer + BUF_SIZE) {
  353.             overflow("buffer size", BUF_SIZE);
  354.         }
  355.         c = getc(f);
  356.     }
  357.     next = buffer;
  358.     return TRUE;
  359. }
  360.  
  361. void
  362. term_input ()
  363. {
  364.     int    c;
  365.     str    s;
  366.  
  367.     update_terminal();
  368.     flush_str();
  369.     loop {
  370.         c = getc(term_in);
  371.         if (c == EOLN) {
  372.             break;
  373.         }
  374.         if (c == EOF) {
  375.             fatal_error("! End of file on the terminal");
  376.         }
  377.         append_char(xord[c]);
  378.         if (cur_str_ptr >= cur_str_end) {
  379.             overflow("str size", MAX_STR_SIZE);
  380.         }
  381.     }
  382.     term_offset = 0;
  383.     decr(selector);
  384.     if (cur_str_ptr != cur_str) {
  385.         for (s = cur_str; s < cur_str_ptr; incr(s)) {
  386.             print_char(*s);
  387.         }
  388.     }
  389.     print_ln();
  390.     incr(selector);
  391. }
  392.  
  393. bool
  394. init_terminal ()
  395. {
  396.     loop {
  397.         fputs("**", term_out);
  398.         update_terminal();
  399.         if (!input_ln(term_in)) {
  400.             fputs("\n! End of file on the terminal...why?\n",
  401.                 term_out);
  402.             return FALSE;
  403.         }
  404.         next = buffer;
  405.         while (next <= limit && *next == ' ') {
  406.             incr(next);
  407.         }
  408.         if (next <= limit) {
  409.             return TRUE;
  410.         }
  411.         fputs("Please type the name of your input file.\n", term_out);
  412.     }
  413. }
  414.  
  415. void
  416. open_log_file ()
  417. {
  418.     int    k;
  419.     byte    *s;
  420.     byte    *t;
  421.     char    *months; 
  422.     int    old_setting;
  423.  
  424.     old_setting = selector;
  425.     if (job_name == null_str) {
  426.         job_area = null_str;
  427.         job_name = str_texput;
  428.     }
  429.     pack_job_name(str_log);
  430.     while ((log_file = a_open_out()) == null_file) {
  431.         if (interaction < SCROLL_MODE) {
  432.             print_err("I can't write on file `");
  433.             print_file_name(cur_name, cur_area, cur_ext);
  434.             print("'.");
  435.             job_name = null_str;
  436.             history = FATAL_ERROR_STOP;
  437.             jump_out();
  438.         }
  439.         prompt_file_name("transcript file name", str_log);
  440.     }
  441.     log_name = make_name_str();
  442.     selector = LOG_ONLY;
  443.     log_opened = TRUE;
  444.     fputs(banner, log_file);
  445.     if (format_ident == null_str) {
  446.         print(" (no format preloaded)");
  447.     } else {
  448.         print(format_ident);
  449.     }
  450.     print(" ");
  451.     print_int(day);
  452.     print(" ");
  453.     months = "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC";
  454.     for (k = 3 * month - 3; k < 3 * month; incr(k)) {
  455.         putc(months[k], log_file);
  456.     }
  457.     print(" ");
  458.     print_int(year);
  459.     print(" ");
  460.     print_two(time / 60);
  461.     print(":");
  462.     print_two(time % 60);
  463.     *input_ptr = cur_input;
  464.     print_nl("**");
  465.     s = input_stack[0].obj_field.f.buf_field;
  466.     t = input_stack[0].obj_field.f.limit_field;
  467.     if (*t == end_line_char) {
  468.         decr(t);
  469.     }
  470.     while (s <= t) {
  471.         print_char(*s++);
  472.     }
  473.     print_ln();
  474.     selector = old_setting + 2; 
  475. }
  476.  
  477. str    cur_path;
  478. str    input_path = default_input_path;
  479. str     font_path = default_font_path;
  480.  
  481. void
  482. set_paths ()
  483. {
  484.     str    env_path;
  485.     str    getenv();
  486.  
  487.     if (env_path = getenv("TEXINPUTS")) {
  488.         input_path = env_path;
  489.     }
  490.     if (env_path = getenv("TEXFONTS")) {
  491.         font_path = env_path;
  492.     }
  493. }
  494.  
  495. /*
  496. **    test_access(amode, file_path)
  497. **
  498. **  Test whether or not the file whose name is in the global name_of_file
  499. **  can be opened for reading according to access mode.
  500. **
  501. **  If the filename given in name_of_file does not begin with '/', we try 
  502. **  prepending all the ':'-separated areanames in the appropriate path to the
  503. **  filename until access can be made.
  504. */
  505.  
  506. bool
  507. test_access (amode, file_path)
  508.     int    amode;
  509.     int    file_path;
  510. {
  511.     int    nl;
  512.     bool    ok;
  513.     char    original_name[MAX_STR_SIZE];
  514.  
  515.     strcpy(original_name, name_of_file);
  516.     nl = name_length;
  517.     switch (file_path)
  518.     {
  519.     case NO_FILE_PATH:
  520.         cur_path = null_str;
  521.         break;
  522.  
  523.     case INPUT_FILE_PATH: 
  524.         cur_path = input_path;
  525.         break;
  526.  
  527.     case FONT_FILE_PATH: 
  528.         cur_path = font_path;
  529.         break;
  530.  
  531.     }
  532. #ifdef    OS2
  533.         /*
  534.      * Watch for file names that begin with a '/', './' or
  535.      * have the form 'x:', where "x" is any alphabetic character
  536.      */
  537.     if (name_of_file[0] == '/' 
  538.         || (name_of_file[0] == '.' && name_of_file[1] == '/')
  539.         || (isalpha(name_of_file[0]) && name_of_file[1] == ':')) {
  540. #else
  541.     if (name_of_file[0] == '/' ||
  542.         name_of_file[0] == '.' && name_of_file[1] == '/') {
  543. #endif
  544.         cur_path = null_str;
  545.     }
  546.     do {
  547.         strcpy(name_of_file, original_name);
  548.         name_length = nl;
  549.         if (get_real_name()) {
  550.             switch (amode)
  551.             {
  552.             case READ_ACCESS: {
  553.                 FILE *fp = fopen(name_of_file, "r");
  554.                 ok = fp != (FILE *) 0;
  555.                 if (ok) {
  556.                     struct stat st;
  557.                     fstat(fileno(fp), &st);
  558.                     fclose(fp);
  559.                     ok = (st.st_mode & S_IFMT) == S_IFREG;
  560.                 }
  561.                 break;
  562.                 }
  563.  
  564.             case WRITE_ACCESS: {
  565.                 FILE *fp = fopen(name_of_file, "w");
  566.                 ok = fp != (FILE *) 0;
  567.                 if (ok)
  568.                     fclose(fp);
  569.                 break;
  570.                 }
  571.             }
  572.         } else {
  573.             ok = FALSE;
  574.         }
  575.     } while (!ok && cur_path != null_str);
  576.     return ok;
  577. }
  578.  
  579. #define append_to_real_name(C) \
  580.     {if (k == MAX_STR_SIZE) \
  581.         overflow("real_name", MAX_STR_SIZE); \
  582.     real_name[k++] = C;}
  583.  
  584. get_real_name ()
  585. {
  586.     int    k;
  587.     str    s;
  588.     char    real_name[MAX_STR_SIZE];
  589.     
  590.     real_name[k = 0] = NUL;
  591.     s = cur_path;
  592.     while (*s && *s != path_delimiter) {
  593.         append_to_real_name(*s);
  594.         incr(s);
  595.     }
  596.     if (*s == NUL) {
  597.         cur_path = null_str;
  598.     } else {
  599.         cur_path = ++s;
  600.     }
  601.     if (k && real_name[k - 1] != area_delimiter) {
  602.         append_to_real_name(area_delimiter);
  603.     }
  604.     if (*(s = name_of_file)) {
  605.         while (*s) {
  606.             append_to_real_name(*s);
  607.             incr(s);
  608.         }
  609.     }
  610.     name_length = k;
  611.     append_to_real_name(NUL);
  612.     strcpy(name_of_file, real_name);
  613.     return k;
  614. }
  615.  
  616. void
  617. _fileio_init ()
  618. {
  619.     int    i;
  620.  
  621.     job_name = null_str;
  622.     name_in_progress = FALSE;
  623.     log_opened = FALSE;
  624.     for (i = 0; i <= 16; incr(i)) {
  625.         read_open[i] = CLOSED;
  626.     }
  627. }
  628.  
  629. void
  630. _fileio_init_once ()
  631. {
  632.     name_of_file = new_str(MAX_STR_SIZE);
  633.     area_delimiter = '/';
  634.     ext_delimiter = '.';
  635. #ifdef    OS2
  636.     path_delimiter = ';';
  637. #else    
  638.     path_delimiter = ':';
  639. #endif
  640.     str_texput = "texput";
  641.     str_tex = ".tex";
  642.     str_dvi = ".dvi";
  643.     str_log = ".log";
  644.     str_tfm = ".tfm";
  645. }
  646.