home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #4 / amigaacscoverdisc1998-041998.iso / utilities / shareware / dev / ucb_logoppc / source / files.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-02-20  |  12.7 KB  |  571 lines

  1. /*
  2.  *      files.c         logo file management module             dvb
  3.  *
  4.  * Copyright (C) 1993 by the Regents of the University of California
  5.  *
  6.  *      This program is free software; you can redistribute it and/or modify
  7.  *      it under the terms of the GNU General Public License as published by
  8.  *      the Free Software Foundation; either version 2 of the License, or
  9.  *      (at your option) any later version.
  10.  *
  11.  *      This program is distributed in the hope that it will be useful,
  12.  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *      GNU General Public License for more details.
  15.  *
  16.  *      You should have received a copy of the GNU General Public License
  17.  *      along with this program; if not, write to the Free Software
  18.  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  *
  20.  */
  21.  
  22. #ifdef WIN32
  23. #include <windows.h>
  24. #endif /* WIN32 */
  25.  
  26. #include "logo.h"
  27. #include "globals.h"
  28.  
  29. #ifdef HAVE_TERMIO_H
  30. #include <termio.h>
  31. #else
  32. #ifdef HAVE_SGTTY_H
  33. #include <sgtty.h>
  34. #endif
  35. #endif
  36.  
  37. #ifdef HAVE_UNISTD_H
  38. #include <unistd.h>
  39. #endif
  40.  
  41. #ifdef mac
  42. #include <console.h>
  43. #endif
  44. #ifdef ibm
  45. #ifndef _MSC_VER
  46. #include <bios.h>
  47. #ifndef __ZTC__
  48. #include <alloc.h>
  49. #endif /* ZTC */
  50. #endif /* MSC_VER */
  51. extern int getch(), kbhit();
  52. #ifdef __ZTC__
  53. #include <conio.h>
  54. #endif
  55. #endif
  56.  
  57. #if defined(__PPC__) && defined(AMIGA)
  58.  
  59. #define __USE_SYSBASE
  60. #include <proto/exec.h>
  61. #include <proto/dos.h>
  62. #include <powerup/ppclib/interface.h>
  63. #include <powerup/gcclib/powerup_protos.h>
  64.  
  65. #define AllocVec(n, f) PPCAllocVec(n, f)
  66. #define FreeVec(b)     PPCFreeVec(b)
  67.  
  68. #endif
  69.  
  70. NODE *file_list = NULL;
  71. NODE *reader_name = NIL, *writer_name = NIL;
  72.  
  73. FILE *open_file(NODE *arg, char *access) {
  74.     char *fnstr;
  75.     FILE *tstrm;
  76.  
  77.     arg = cnv_node_to_strnode(arg);
  78.     if (arg == UNBOUND) return(NULL);
  79.     fnstr = (char *) malloc((size_t)getstrlen(arg) + 1);
  80.     if (fnstr == NULL) {
  81.    err_logo(FILE_ERROR, make_static_strnode("Not enough memory"));
  82.    return NULL;
  83.     }
  84.     noparity_strnzcpy(fnstr, getstrptr(arg), getstrlen(arg));
  85.     tstrm = fopen(fnstr, access);
  86.     free(fnstr);
  87.     return(tstrm);
  88. }
  89.  
  90. NODE *ldribble(NODE *arg) {
  91.     if (dribblestream != NULL)
  92.    err_logo(ALREADY_DRIBBLING, NIL);
  93.     else {
  94.    dribblestream = open_file(car(arg), "w+");
  95.    if (dribblestream == NULL) err_logo(FILE_ERROR, NIL);
  96.     }
  97.     return(UNBOUND);
  98. }
  99.  
  100. NODE *lnodribble(NODE *args) {
  101.     if (dribblestream != NULL) {
  102.    fclose(dribblestream);
  103.    dribblestream = NULL;
  104.     }
  105.     return(UNBOUND);
  106. }
  107.  
  108. FILE *find_file(NODE *arg, BOOLEAN remove) {
  109.     NODE *t, *prev = NIL;
  110.     FILE *fp = NULL;
  111.  
  112.     t = file_list;
  113.     while (t != NIL) {
  114.    if (compare_node(arg, car(t), FALSE) == 0) {
  115.        fp = (FILE *)t->n_obj;
  116.        if (remove) {
  117.       t->n_obj = NIL;
  118.       if (prev == NIL)
  119.           file_list = cdr(t);
  120.       else
  121.           setcdr(prev, cdr(t));
  122.        }
  123.        break;
  124.    }
  125.    prev = t;
  126.    t = cdr(t);
  127.     }
  128.     return fp;
  129. }
  130.  
  131. NODE *lopen(NODE *arg, char *mode) {
  132.     FILE *tmp;
  133.  
  134.     arg = car(arg);
  135.     if (find_file(arg, FALSE) != NULL)
  136.    err_logo(FILE_ERROR, make_static_strnode("File already open"));
  137.     else if ((tmp = open_file(arg, mode)) != NULL) {
  138.    push(arg, file_list);
  139.    file_list->n_obj = (NODE *)tmp;
  140.     }
  141.     else
  142.    err_logo(FILE_ERROR, make_static_strnode("I can't open that file"));
  143.     return(UNBOUND);
  144. }
  145.  
  146. NODE *lopenread(NODE *arg) {
  147.     return(lopen(arg,"r"));
  148. }
  149.  
  150. NODE *lopenwrite(NODE *arg) {
  151.     return(lopen(arg,"w"));
  152. }
  153.  
  154. NODE *lopenappend(NODE *arg) {
  155.     return(lopen(arg,"a"));
  156. }
  157.  
  158. NODE *lopenupdate(NODE *arg) {
  159.     return(lopen(arg,"a+"));
  160. }
  161.  
  162. NODE *lallopen(NODE *args) {
  163.     return(file_list);
  164. }
  165.  
  166. NODE *lclose(NODE *arg) {
  167.     FILE *tmp;
  168.  
  169.     if ((tmp = find_file(car(arg), TRUE)) == NULL)
  170.    err_logo(FILE_ERROR, make_static_strnode("File not open"));
  171.     else
  172.    fclose(tmp);
  173.     return(UNBOUND);
  174. }
  175.  
  176. NODE *lsetwrite(NODE *arg) {
  177.     FILE *tmp;
  178.  
  179.     if (car(arg) == NIL) {
  180.    writestream = stdout;
  181.    writer_name = NIL;
  182.     }
  183.     else if ((tmp = find_file(car(arg), FALSE)) != NULL) {
  184.    writestream = tmp;
  185.    writer_name = car(arg);
  186.     }
  187.     else
  188.    err_logo(FILE_ERROR, make_static_strnode("File not open"));
  189.     return(UNBOUND);
  190. }
  191.  
  192. NODE *lsetread(NODE *arg) {
  193.     FILE *tmp;
  194.  
  195.     if (car(arg) == NIL) {
  196.    readstream = stdin;
  197.    reader_name = NIL;
  198.     }
  199.     else if ((tmp = find_file(car(arg), FALSE)) != NULL) {
  200.    readstream = tmp;
  201.    reader_name = car(arg);
  202.     }
  203.     else
  204.    err_logo(FILE_ERROR, make_static_strnode("File not open"));
  205.     return(UNBOUND);
  206. }
  207.  
  208. NODE *lreader(NODE *args) {
  209.     return(reader_name);
  210. }
  211.  
  212. NODE *lwriter(NODE *args) {
  213.     return(writer_name);
  214. }
  215.  
  216. NODE *lerasefile(NODE *arg) {
  217.     char *fnstr;
  218.  
  219.     arg = cnv_node_to_strnode(car(arg));
  220.     if (arg == UNBOUND) return(UNBOUND);
  221.     fnstr = malloc((size_t)getstrlen(arg) + 1);
  222.     if (fnstr == NULL) {
  223.    err_logo(FILE_ERROR, make_static_strnode("Not enough memory"));
  224.    return UNBOUND;
  225.     }
  226.     strnzcpy(fnstr, getstrptr(arg), getstrlen(arg));
  227.     unlink(fnstr);
  228.     free(fnstr);
  229.     return(UNBOUND);
  230. }
  231.  
  232. NODE *lsave(NODE *arg) {
  233.     FILE *tmp;
  234.  
  235.     tmp = writestream;
  236.     writestream = open_file(car(arg), "w+");
  237.     if (writestream != NULL) {
  238.    setcar(arg, cons(lcontents(NIL), NIL));
  239.    lpo(car(arg));
  240.    fclose(writestream);
  241.     }
  242.     else
  243.    err_logo(FILE_ERROR, make_static_strnode("Could not open file"));
  244.     writestream = tmp;
  245.     return(UNBOUND);
  246. }
  247.  
  248. void runstartup(NODE *oldst) {
  249.     NODE *st;
  250.  
  251.     st = valnode__caseobj(Startup);
  252.     if (st != oldst && st != NIL && is_list(st)) {
  253.    val_status = 0;
  254.    eval_driver(st);
  255.     }
  256. }
  257.  
  258. void silent_load(NODE *arg, char *prefix) {
  259.     FILE *tmp_stream;
  260.     NODE *tmp_line, *exec_list;
  261.     char load_path[200];
  262.     NODE *st = valnode__caseobj(Startup);
  263.     int sv_val_status = val_status;
  264.  
  265.     /* This procedure is called three ways:
  266.      *    silent_load(NIL,*argv) loads *argv
  267.      *    silent_load(proc,logolib)     loads logolib/proc
  268.      *    silent_load(proc,NULL) loads proc.lg
  269.      * The "/" or ".lg" is supplied by this procedure as needed.
  270.      */
  271.  
  272.     /*
  273.      * In the case that this procedure is called to load a procedure from the
  274.      * logo library, it must first truncate the name of the procedure to
  275.      * eight characters, to find the filename (so as to be compatible with
  276.      * MS-DOS)
  277.      */
  278.  
  279.     if (prefix == NULL && arg == NIL) return;
  280.     strcpy(load_path, (prefix == NULL ? "" :
  281.               (arg == NIL ? prefix : addsep(prefix))));
  282.     if (arg != NIL) {
  283.    arg = cnv_node_to_strnode(arg);
  284.    if (arg == UNBOUND) return;
  285.    if (!strncmp(getstrptr(arg), ".", getstrlen(arg))) return;
  286.    noparitylow_strnzcpy(load_path + (int)strlen(load_path),
  287.               getstrptr(arg), getstrlen(arg));
  288.    if (prefix == NULL)
  289.      strcat(load_path, ".lg");
  290. #ifdef WIN32
  291.    else
  292.      strcpy(load_path, eight_dot_three(load_path));
  293. #endif
  294.     }
  295.     tmp_stream = loadstream;
  296.     tmp_line = current_line;
  297.     loadstream = fopen(load_path, "r");
  298.     if (loadstream != NULL) {
  299.    while (!feof(loadstream) && NOT_THROWING) {
  300.        current_line = reader(loadstream, "");
  301.        exec_list =parser(current_line, TRUE);
  302.        val_status = 0;
  303.        if (exec_list != NIL) eval_driver(exec_list);
  304.    }
  305.    fclose(loadstream);
  306.    runstartup(st);
  307.    val_status = sv_val_status;
  308.     } else if (arg == NIL) ndprintf(stdout,"File not found: %t\n", prefix);
  309.     loadstream = tmp_stream;
  310.     current_line = tmp_line;
  311. }
  312.  
  313. NODE *lload(NODE *arg) {
  314.     FILE *tmp;
  315.     NODE *tmp_line, *exec_list;
  316.     NODE *st = valnode__caseobj(Startup);
  317.     int sv_val_status = val_status;
  318.  
  319.     tmp = loadstream;
  320.     tmp_line = current_line;
  321.     loadstream = open_file(car(arg), "r");
  322.     if (loadstream != NULL) {
  323.    while (!feof(loadstream) && NOT_THROWING) {
  324.        current_line = reader(loadstream, "");
  325.        exec_list = parser(current_line, TRUE);
  326.        val_status = 0;
  327.        if (exec_list != NIL) eval_driver(exec_list);
  328.    }
  329.    fclose(loadstream);
  330.    runstartup(st);
  331.    val_status = sv_val_status;
  332.     } else
  333.    err_logo(FILE_ERROR, make_static_strnode("Could not open file"));
  334.     loadstream = tmp;
  335.     current_line = tmp_line;
  336.     return(UNBOUND);
  337. }
  338.  
  339. NODE *lreadlist(NODE *args) {
  340.     NODE *val;
  341.  
  342.     val = parser(reader(readstream, ""), FALSE);
  343.     if (feof(readstream)) {
  344.    return(Null_Word);
  345.     }
  346.     return(val);
  347. }
  348.  
  349. NODE *lreadword(NODE *args) {
  350.     NODE *val;
  351.  
  352.     val = reader(readstream, "RW"); /* fake prompt flags no auto-continue */
  353.     if (feof(readstream)) {
  354.    return(NIL);
  355.     }
  356.     return(val);
  357. }
  358.  
  359. NODE *lreadchar(NODE *args) {
  360. #ifdef WIN32
  361.     MSG msg;
  362. #endif /* WIN32 */
  363.     char c;
  364.  
  365.     charmode_on();
  366.     input_blocking++;
  367. #ifndef TIOCSTI
  368.     if (!setjmp(iblk_buf))
  369. #endif
  370.     {
  371. #ifdef mac
  372.    csetmode(C_RAW, stdin);
  373.    while ((c = (char)getc(readstream)) == EOF && readstream == stdin);
  374.    csetmode(C_ECHO, stdin);
  375. #else /* !mac */
  376. #ifdef ibm
  377.    if (interactive && readstream==stdin)
  378. #ifndef WIN32
  379.       c = (char)getch();
  380. #else /* WIN32 */
  381.    {
  382.      win32_update_text();
  383.      if (!char_avail)
  384.        while(GetMessage(&msg, NULL, 0, 0))
  385.        {
  386.          TranslateMessage(&msg);
  387.          DispatchMessage(&msg);
  388.          if (char_avail)
  389.       break;
  390.        }
  391.      c = buffered_char;
  392.      char_avail = 0;
  393.    }
  394. #endif /* WIN32 */
  395.    else
  396.       c = (char)getc(readstream);
  397.  
  398.    if (c == 17) { /* control-q */
  399.        to_pending = 0;
  400.        err_logo(STOP_ERROR,NIL);
  401.    }
  402.    if (c == 23) { /* control-w */
  403.  
  404. #if defined(__ZTC__) || defined(WIN32)
  405.        logo_pause(0);
  406. #else
  407.        logo_pause();
  408. #endif
  409.        return(lreadchar(NIL));
  410.    }
  411. #else /* !ibm */
  412. #ifdef AMIGA
  413.    if (readstream==stdin && interactive) {
  414.       Flush(console);
  415.       SetMode(console,1);  /* turn buffering off */
  416.       (void)Read(console,&c,1L);
  417.    } else
  418. #endif
  419.    c = (char)getc(readstream);
  420. #endif /* ibm */
  421. #endif /* mac */
  422.     }
  423.     input_blocking = 0;
  424.     if (feof(readstream)) {
  425.    return(NIL);
  426.     }
  427.     return(make_strnode(&c, (struct string_block *)NULL, 1,
  428.        (getparity(c) ? STRING : BACKSLASH_STRING), strnzcpy));
  429. }
  430.  
  431. NODE *lreadchars(NODE *args) {
  432.     unsigned int c, i;
  433.     struct string_block *strhead = NULL;
  434.     char *strptr= NULL;
  435.     NODETYPES type = STRING;
  436.  
  437.     c = (unsigned int)getint(pos_int_arg(args));
  438.     if (stopping_flag == THROWING) return UNBOUND;
  439.     charmode_on();
  440.     input_blocking++;
  441. #ifndef TIOCSTI
  442.     if (!setjmp(iblk_buf))
  443. #endif
  444.     {
  445.    strhead = malloc((size_t)(c + sizeof(FIXNUM) + 1));
  446.    if (strhead == NULL) {
  447.        err_logo(FILE_ERROR, make_static_strnode("Not enough memory"));
  448.        return UNBOUND;
  449.    }
  450.    strptr = strhead->str_str;
  451.    fread(strptr, 1, (int)c, readstream);
  452.    setstrrefcnt(strhead, 0);
  453.     }
  454.     input_blocking = 0;
  455. #ifndef TIOCSTI
  456.     if (stopping_flag == THROWING) return(UNBOUND);
  457. #endif
  458.     if (feof(readstream)) {
  459.    free(strhead);
  460.    return(NIL);
  461.     }
  462.     for (i = 0; i < c; i++)
  463.    if (getparity(strptr[i])) type = BACKSLASH_STRING;
  464.     return(make_strnode(strptr, strhead, (int)c, type, strnzcpy));
  465. }
  466.  
  467. NODE *leofp(NODE *args) {
  468.     int c;
  469.  
  470.     c = getc(readstream);
  471.     if (c == EOF) return(True);
  472.  
  473.     ungetc(c,readstream);
  474.     return(False);
  475. }
  476.  
  477. NODE *lkeyp(NODE *args) {
  478. #ifdef AMIGA
  479.    if (WaitForChar(console,1L))
  480.       return True;
  481.    else
  482.       return False;
  483. #else
  484.     long nc;
  485.     int c;
  486. #ifdef WIN32
  487.     MSG msg;
  488.     int old_mode;
  489. #endif
  490.  
  491.     if (readstream == stdin && interactive) {
  492.    charmode_on();
  493.    fflush(stdout);
  494. #if defined(__ZTC__) && !defined(WIN32) /* sowings */
  495.    zflush();
  496. #endif
  497.  
  498. #ifdef WIN32
  499.    win32_update_text();
  500. #endif
  501.  
  502. #if defined(mac)
  503.    csetmode(C_RAW, stdin);
  504.    c = ungetc(getc(readstream), readstream);
  505.    csetmode(C_ECHO, stdin);
  506.    return(c == EOF ? False : True);
  507. #elif defined(ibm)
  508. #ifdef WIN32
  509.    old_mode = char_mode;
  510.    char_mode = 1;
  511.    while (PeekMessage(&msg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE))
  512.    {
  513.      TranslateMessage(&msg);
  514.      DispatchMessage(&msg);
  515.      if (char_avail/* ||cur_index */ )
  516.        break;
  517.    }
  518.    char_mode = old_mode;
  519.    return ((char_avail /* ||cur_index */ ) ? True : False);
  520. #else
  521.    return(kbhit() ? True : False);
  522. #endif
  523. #else
  524. #ifdef FIONREAD
  525.    ioctl(0,FIONREAD,(char *)(&nc));
  526. #else
  527.    ndprintf(stdout,"Can't KEYP, no FIONREAD on this system\n");
  528.    nc = 1;    /* pretend there's a char so we don't loop */
  529. #endif
  530.    if (nc > 0)
  531.        return(True);
  532.    else
  533.        return(False);
  534. #endif
  535.     }
  536.     c = getc(readstream);
  537.     if (feof(readstream))
  538.    return(False);
  539.     else {
  540.    ungetc(c, readstream);
  541.    return(True);
  542.     }
  543. #endif /* AMIGA */
  544. }
  545.  
  546. NODE *lreadpos(NODE *args) {
  547.     return(make_intnode(ftell(readstream)));
  548. }
  549.  
  550. NODE *lsetreadpos(NODE *arg) {
  551.     NODE *val = pos_int_arg(arg);
  552.  
  553.     if (NOT_THROWING) {
  554.    fseek(readstream,getint(val),0);
  555.     }
  556.     return(UNBOUND);
  557. }
  558.  
  559. NODE *lwritepos(NODE *args) {
  560.     return(make_intnode(ftell(writestream)));
  561. }
  562.  
  563. NODE *lsetwritepos(NODE *arg) {
  564.     NODE *val = pos_int_arg(arg);
  565.  
  566.     if (NOT_THROWING) {
  567.    fseek(writestream,getint(val),0);
  568.     }
  569.     return(UNBOUND);
  570. }
  571.