/*->c.xsym  */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <ctype.h>
#include <time.h>
#include <locale.h>




#include "h.os"
#include "h.wimp"
#include "h.sprite"
#include "h.werr"
#include "h.wimpt"
#include "h.bbc"
#include "h.akbd"
#include "h.flex"

#include "h.wos"


#include "h.pr"
#include "h.file"
#include "h.main"

#include "h.serial"
#include "h.serialdev"
#include "h.script"
#include "h.ftp"
#include "h.batch"
#include "h.xmodem"
#include "h.term"
#include "h.vax"

#include "h.vxdef"
#include "h.vxbuff"
#include "h.vxprint"
#include "h.vxkey"
#include "h.mxterm"

#include "h.vtfile"
#include "h.vtprint"
#include "h.vtcol"
#include "h.vtsend"
#include "h.vtchar"
#include "h.vtkey"
#include "h.vtselect"

#include "h.tek"

#include "h.key"


#include "h.xext"
#include "h.xint"



/*****************************************************************************/


fndefn fntable[XFNS]=
{
"addrxalias",(extfn)addrxalias,"IR",PVOID,2,
"addtobatch",(extfn)addtobatch,"R",PINT,1,
"addtxalias",(extfn)addtxalias,"IR",PVOID,2,
"autoanswer",(extfn)xautoanswer,"I",PVOID,1,
"batchgetname",(extfn)batchgetname,"IIIR",PINT,4,
"batchgetstate",(extfn)batchgetstate,"II",PINT,2,
"batchremotename",(extfn)batchremotename,"IIR",PVOID,3,
"batchremove",(extfn)batchremove,"II",PVOID,2,
"batchsetstate",(extfn)batchsetstate,"III",PVOID,3,
"bbc_adval",(extfn)bbcadval,"I",PINT,1,
"bbc_get",(extfn)bbcget,"",PINT,0,
"bbc_inkey",(extfn)bbcinkey,"I",PINT,1,
"bbc_vdu",(extfn)bbcvdu,"I",PVOID,1,
"chars",(extfn)chars,"I",PSTR,1,
"claimdevice",(extfn)getdevice,"II",PINT,2,
"claimkeyboard",(extfn)claimkeyboard,"I",PVOID,1,
"cleartranslatetable",(extfn)cleartranslatetable,"I",PVOID,1,
"clock",(extfn)clock,"",PINT,0,
"confirm",(extfn)xconfirm,"R",PINT,1,
"connect",(extfn)xconnect,"",PVOID,0,
"defmacro",(extfn)defmacro,"RR",PVOID,2,
"delallmacros",(extfn)delallmacros,"",PVOID,0,
"delmacro",(extfn)delmacro,"R",PVOID,1,
"dial",(extfn)xdial,"R",PVOID,1,
"disconnect",(extfn)xdisconnect,"",PVOID,0,
"emptybatch",(extfn)emptybatch,"I",PVOID,1,
"errorbox",(extfn)xerrorbox,"R",PVOID,1,
"exit",(extfn)xexit,"I",PVOID,1,
"fileclose",(extfn)fileclose,"I",PINT,1,
"fileeof",(extfn)fileeof,"I",PINT,1,
"fileerror",(extfn)fileerror,"I",PINT,1,
"filegetc",(extfn)filegetc,"I",PINT,1,
"fileopen",(extfn)fileopen,"RR",PINT,2,
"fileputc",(extfn)fileputc,"II",PINT,2,
"filereadi",(extfn)filereadi,"I",PINT,1,
"filereads",(extfn)filereads,"RI",PINT,2,
"fileseek",(extfn)fileseek,"II",PINT,2,
"filetell",(extfn)filetell,"I",PINT,1,
"filewritei",(extfn)filewritei,"II",PINT,2,
"filewrites",(extfn)filewrites,"RI",PINT,2,
"fx",(extfn)ourfx,"III",PVOID,3,
"getenvs",(extfn)getenvs,"R",PINT,1,
"getprompt",(extfn)ourgetprompt,"RI",PINT,2,
"internal_link",(extfn)internal_link,"I",PINT,1,
"itos",(extfn)itos,"I",PSTR,1,
"itoxs",(extfn)itoxs,"I",PSTR,1,
"kermitbye",(extfn)skermitdobye,"",PVOID,0,
"kermitchangeremdir",(extfn)skermitdochangeremdir,"R",PVOID,1,
"kermitdelete",(extfn)skermitdodelete,"R",PVOID,1,
"kermitfinish",(extfn)skermitdofinish,"",PVOID,0,
"kermitget",(extfn)skermitget,"R",PVOID,1,
"kermitremdir",(extfn)skermitdoremdir,"R",PVOID,1,
"kermitremote",(extfn)skermitdoremote,"R",PVOID,1,
"kermitserver",(extfn)skermitserver,"",PVOID,0,
"kermittype",(extfn)skermitdotype,"R",PVOID,1,
"kgetc",(extfn)kgetc,"I",PINT,1,
"kprints",(extfn)kprints,"R",PVOID,1,
"mids",(extfn)mids,"RII",PSTR,3,
"nextobject",(extfn)xnextobject,"RRR",PINT,3,
"objectexists",(extfn)xobjectexists,"R",PINT,1,
"online",(extfn)sonline,"",PINT,0,
"onlinechange",(extfn)xonlinechange,"I",PVOID,1,
"osclis",(extfn)osclis,"R",PINT,1,
"osversion",(extfn)osversion,"",PINT,0,
"pause",(extfn)pause,"I",PVOID,1,
"printi",(extfn)printi,"I",PVOID,1,
"prints",(extfn)prints,"R",PVOID,1,
"receivefiles",(extfn)receivefiles,"",PVOID,0,
"reconnect",(extfn)xreconnect,"",PVOID,0,
"savescreen",(extfn)savescreen,"RII",PINT,3,
"schar",(extfn)schar,"RI",PINT,2,
"sendfiles",(extfn)sendfiles,"",PVOID,0,
"sendframe",(extfn)xsendframe,"",PVOID,0,
"serialdevcall",(extfn)serialdevcall,"IIII",PINT,4,
"serialdevinit",(extfn)serialdevinit,"I",PVOID,1,
"serialdevread",(extfn)serialdevread,"I",PINT,1,
"setasciirx",(extfn)setasciirx,"RIRIRRI",PVOID,7,
"setasciitx",(extfn)setasciitx,"RIRRRRIIII",PVOID,10,
"setautoredial",(extfn)setautoredial,"III",PVOID,3,
"setband",(extfn)setband,"IIII",PVOID,4,
"setbatch",(extfn)setbatch,"II",PVOID,2,
"setbatchconfig",(extfn)setbatchconfig,"IIIIIIII",PVOID,8,
"setbits",(extfn)setbits,"III",PVOID,3,
"setcampusdefault",(extfn)setcampusdefault,"I",PVOID,1,
"setcampuskeyboard",(extfn)setcampuskeyboard,"I",PVOID,1,
"setcet",(extfn)setcet,"IIRI",PVOID,4,
"setchannel",(extfn)setchannel,"IIII",PVOID,4,
"setchoices",(extfn)setchoices,"IIIII",PVOID,5,
"setcomms",(extfn)setcomms,"I",PVOID,1,
"setcurband",(extfn)setcurband,"I",PVOID,1,
"setdefltalias",(extfn)setdefltalias,"IR",PVOID,2,
"setdefterminal",(extfn)setdefterm,"I",PVOID,1,
"setftp",(extfn)setftp,"I",PVOID,1,
"setftpbuffersize",(extfn)setftpbuffersize,"II",PVOID,2,
"sethearsaytitle",(extfn)sethearsaytitle,"R",PVOID,1,
"setkermit",(extfn)setkermit,"IIIRI",PVOID,5,
"setkermitparam",(extfn)setkermitparam,"IIIRRRIR",PVOID,8,
"setline",(extfn)setline,"III",PVOID,3,
"setlink",(extfn)setlink,"II",PVOID,2,
"setmenusense",(extfn)setmenusense,"I",PVOID,1,
"setmxisomap",(extfn)setmxisomap,"II",PVOID,2,
"setpoll",(extfn)setpoll,"I",PVOID,1,
"setprinter",(extfn)setprinter,"III",PVOID,3,
"setserialdev",(extfn)setserialdev,"RI",PVOID,2,
"setspeed",(extfn)setspeed,"II",PVOID,2,
"setstate",(extfn)setstate,"I",PVOID,1,
"settekback",(extfn)settekback,"I",PVOID,1,
"settekfile",(extfn)settekfile,"II",PVOID,2,
"settekfill",(extfn)settekfill,"I",PVOID,1,
"settekfont",(extfn)settekfont,"RI",PVOID,2,
"settekgeneral",(extfn)settekgeneral,"IIIIII",PVOID,6,
"settekindex",(extfn)settekindex,"IIII",PVOID,4,
"settekline",(extfn)settekline,"I",PVOID,1,
"settekprint",(extfn)settekprint,"IIIIIIIII",PVOID,9,
"settektext",(extfn)settektext,"I",PVOID,1,
"settekversion",(extfn)settekversion,"I",PVOID,1,
"setterminal",(extfn)setxterm,"I",PVOID,1,
"settrap",(extfn)settrap,"IIIRR",PVOID,5,
"setvasscom",(extfn)xsetvasscom,"III",PVOID,3,
"setvtcolour",(extfn)setvtcolour,"IIIIII",PVOID,6,
"setvtdevatt",(extfn)setvtdevatt,"R",PVOID,1,
"setvtdisplay",(extfn)setvtdisplay,"IIIIIIIIIIII",PVOID,12,
"setvtfile",(extfn)setvtfile,"II",PVOID,2,
"setvtgeneral",(extfn)setvtgeneral,"RIII",PVOID,4,
"setvtgrl",(extfn)setvtgrl,"II",PVOID,2,
"setvtident",(extfn)setvtident,"IR",PVOID,2,
"setvtkey",(extfn)setvtkey,"IIIII",PVOID,5,
"setvtkeymap",(extfn)setvtkeymap,"IR",PVOID,2,
"setvtline",(extfn)setvtline,"IIIIII",PVOID,6,
"setvtprint",(extfn)setvtprint,"III",PVOID,3,
"setvtset",(extfn)setvtset,"II",PVOID,2,
"setvttabs",(extfn)setvttabs,"R",PVOID,1,
"setvxbuff",(extfn)setvxbuff,"IIII",PVOID,4,
"setvxcolour",(extfn)setvxcolour,"IIIII",PVOID,5,
"setvxdisplay",(extfn)setvxdisplay,"IIIIII",PVOID,6,
"setvxfile",(extfn)setvxfile,"III",PVOID,3,
"setvxgeneral",(extfn)setvxgeneral,"RIR",PVOID,3,
"setvxkeyboard",(extfn)setvxkeyboard,"II",PVOID,2,
"setvxkeypadcode",(extfn)setvxkeypadcode,"IIR",PVOID,3,
"setvxkeypadstring",(extfn)setvxkeypadstring,"IIR",PVOID,3,
"setvxlanguage",(extfn)setvxlanguage,"II",PVOID,2,
"setvxline",(extfn)setvxline,"IIIIII",PVOID,6,
"setvxprint",(extfn)setvxprint,"IIIIIII",PVOID,7,
"setvxsend",(extfn)setvxsend,"RRRRRIIII",PVOID,9,
"setvxterminator",(extfn)setvxterminator,"IR",PVOID,2,
"setxmodem",(extfn)setxmodem,"I",PVOID,1,
"setymodem",(extfn)setymodem,"II",PVOID,2,
"setzmodem",(extfn)setzmodem,"III",PVOID,3,
"sgetc",(extfn)sgetc,"I",PINT,1,
"slen",(extfn)slen,"R",PINT,1,
"specifydriver",(extfn)specifydriver,"R",PVOID,1,
"spool",(extfn)spool,"I",PVOID,1,
"spoolclose",(extfn)ourspoolclose,"",PVOID,0,
"spoolopen",(extfn)spoolopen,"RI",PINT,2,
"sprinti",(extfn)sprinti,"I",PVOID,1,
"sprints",(extfn)sprints,"R",PVOID,1,
"sputc",(extfn)sputc,"I",PINT,1,
"sreads",(extfn)sreads,"RII",PINT,3,
"sreadtext",(extfn)sreadtext,"RII",PINT,3,
"startscan",(extfn)xstartscan,"",PVOID,0,
"stoi",(extfn)stoi,"R",PINT,1,
"swi13",(extfn)ourswi13,"IIII",PINT,4,
"systems",(extfn)systems,"R",PINT,1,
"talktomodem",(extfn)xtalk2modem,"",PVOID,0,
"tekdump",(extfn)tekdumpscreen,"",PVOID,0,
"termchar",(extfn)termchar,"III",PINT,3,
"termcurs",(extfn)termcurs,"II",PINT,2,
"terminate",(extfn)terminate,"",PVOID,0,
"termline",(extfn)termline,"I",PVOID,1,
"termtab",(extfn)termtab,"III",PVOID,3,
"tprinti",(extfn)tprinti,"I",PVOID,1,
"tprints",(extfn)tprints,"R",PVOID,1,
"tputc",(extfn)tputc,"I",PVOID,1,
"translatetable",(extfn)translatetable,"III",PVOID,3,
"vasscomnegotiate",(extfn)xnegmode,"",PVOID,0,
"vtautoprint",(extfn)vtautoprint,"I",PVOID,1,
"vtcharmap",(extfn)vtcharmap,"III",PVOID,3,
"vtdump",(extfn)vtdumpscreen,"",PVOID,0,
"vtselectcopy",(extfn)vtselectcopy,"",PVOID,0,
"vtselectpaste",(extfn)vtselectpaste,"",PVOID,0,
"vtselectprint",(extfn)vtselectprint,"",PVOID,0,
"vtselectsend",(extfn)vtselectsend,"",PVOID,0,
"vtselectspool",(extfn)vtselectspool,"",PVOID,0,
"vxbuffclose",(extfn)vxbuffclose,"I",PINT,1,
"vxbuffop",(extfn)vxbuffop,"II",PINT,2,
"vxbuffopen",(extfn)vxbuffopen,"R",PINT,1,
"vxbuffseek",(extfn)vxbuffseek,"II",PINT,2,
"vxbuffshow",(extfn)vxbuffshow,"II",PVOID,2,
"vxdump",(extfn)vxdumpscreen,"",PVOID,0,
};


/*****************************************************************************/
/* x symbol table manager */




char    * xsymheap;      /* heap used to store symbol table        */
int       xheapsize;     /* pointer to first free location in heap */
symstk  * xsyms;         /* list of pointers to first entry in each stage */
int       xnsyms;        /* number of stages */




#define NIL_NODE     -1    /* ptr for empty (sub)trees */

typedef int DIR;                      /* type for indexing siblings */

#define        L       ((DIR) 0)
#define        R       ((DIR) 1)

#define        LEFT    sibls[L]       /* left sibling pointer NODE field */
#define        RIGHT   sibls[R]       /* right sibling pointer NODE field */


/*
 * Direction gives direction in which child NODE c is under parent NODE p.
 */

#define        direction(p,c) ((DIR) ((p)->RIGHT==(c)))

/*
 * Cmp_dir gives direction corresponding with compare value v (R iff v > 0).
 */

#define        cmp_dir(v)      ((DIR) ((v) > 0))

/*
 * Siblingp yields ptr to left (d == L) or right (d == R) child of NODE n.
 */

#define        siblingp(n, d)  ((xptr((n))->sibls) + (d))

#define        sibling(n, d)  ((n)->sibls + (d))

/*
 * Parentp yields ptr to parent's ptr to NODE n, or root ptr r if n is 0.
 */


/*

#define        parentp(r, n)   ((xptr((n))->parent) == NIL_NODE ? (r) : \
               siblingp((xptr((n))->parent), direction((xptr((n))->parent), (n))))

 */



/*
 * Dir_bal yields balance value corresponding to DIR d.
 */

#define        dir_bal(d)      ((d) == L ? -1 : 1)








int * parentp(int * rootp,int sb)
{
 symstr * p;
 int    * q;
 int      pa;

 p=xptr(sb);
 pa=p->parent;

 if(pa==NIL_NODE) return(rootp);

 q=siblingp(pa,direction(xptr(pa),sb));

 return(q);
}



/*
 * Balance the subtree rooted at sb that has become to heavy on side d
 * by single rotation of sb and sb_next.
 * Also adjusts sibling pointer of the parent of sb, or *rootp if sb is
 * the top of the entire tree.
 *
 *             sb              sb_next         Single rotation: Adding x or
 *            /  \            /       \        deleting under 3 caused
 *     sb_next    3          1         sb      rotation.  Same holds for mirror
 *     /       \             |        /  \     image.  Single_rotation returns
 *    1                2       ==>   x       2    3    top of new balanced tree.
 *    |                |                     |
 *    x                y                     y
 */

static int single_rotation(int * rootp,int sb,int sb_next,DIR d)
{
 *siblingp(sb,d)=*siblingp(sb_next,!d);
 *siblingp(sb_next,!d)=sb;

 xptr(sb)->balance-=xptr(sb_next)->balance;
 xptr(sb_next)->balance=-xptr(sb)->balance;

 *parentp(rootp,sb)=sb_next;
 xptr(sb_next)->parent=xptr(sb)->parent;
 xptr(sb)->parent=sb_next;
 if(*siblingp(sb,d)!=NIL_NODE)
 xptr((*siblingp(sb,d)))->parent=sb;

 return(sb_next);
}




/*
 * Balance the subtree rooted at sb that has become to heavy on side d
 * by double rotation of sb and sb_next.
 * Also adjusts sibling pointer of the parent of sb, or *rootp if sb is
 * the top of the entire tree.
 *
 *             sb                  sb_next2       Double rotation: Adding x or
 *            /  \                /        \      x', or deleting under 4
 *     sb_next    \            sb_next      sb    caused rotation. Same holds
 *     /       \    \         /       \    /  \   for the mirror image.
 *    1   sb_next2   4  ==>  1         2  3    4  Double_rotation returns top
 *       /        \                    |  |       of new balanced tree.
 *      2          3                   x  x'
 *      |         |
 *      x         x'
 */

static int double_rotation(int * rootp,int sb,int sb_next,DIR d)
{
 int      sb_next2;
 symstr * sb_n2p;
 symstr * sb_np;
 symstr * sbp;

 sb_np=xptr(sb_next);
 sb_next2=*sibling(sb_np,!d);
 sb_n2p=xptr(sb_next2);
 sbp=xptr(sb);

 *sibling(sb_np,!d)=*sibling(sb_n2p,d);
 *sibling(sbp,d)    =*sibling(sb_n2p,!d);
 *sibling(sb_n2p,d)=sb_next;
 *sibling(sb_n2p,!d)=sb;

 if(sb_n2p->balance==sb_np->balance) sb_np->balance=-sb_np->balance;
 else                                sb_np->balance=0;

 if(sb_n2p->balance==sbp->balance)   sbp->balance=-sbp->balance;
 else                                sbp->balance=0;

 sb_n2p->balance=0;

 *parentp(rootp,sb)=sb_next2;
 sb_n2p->parent=sbp->parent;
 sbp->parent=sb_np->parent=sb_next2;

 if(*sibling(sb_np,!d)!=NIL_NODE)
               xptr(*sibling(sb_np,!d))->parent=sb_next;

 if(*sibling(sbp, d) != NIL_NODE)
               xptr(*sibling(sbp,d))->parent=sb;

 return(sb_next2);
}








/*
 * Balance the subtree rooted at sb that has become to heavy on side d.
 * Also adjusts sibling pointer of the parent of sb, or *rootp if sb is
 * the top of the entire tree.
 */

static int balance(int * rootp,int sb,DIR d)
{
 int sb_next=*siblingp(sb,d);

 if(xptr(sb_next)->balance==-dir_bal(d))
               return(double_rotation(rootp,sb,sb_next,d));
 else
               return(single_rotation(rootp,sb,sb_next,d));
}









/*
 * Tsearch adds node key to tree rooted by *rootp, using compar for
 * comparing elements.  It returns the pointer to the NODE in which
 * the (possibly already existing) key pointer resides.
 */


int tsearch(int newnode,int * rootp)
{
 int parent;
 int child;
 DIR d;
 int cmp;
 symstr * childp;
 symstr * nnode;
 symstr * pp;

 nnode=xptr(newnode);

 if(rootp==0) return(NIL_NODE);

 /* find place where key should go */

 parent=NIL_NODE;
 child=*rootp;
 while(child!=NIL_NODE)
 {
  childp=xptr(child);
  if((cmp=strcmp(nnode->key,childp->key))==0) return(child);
  parent=child;
  child=*sibling(childp,cmp_dir(cmp));
 }

 /* create new node and set its parent's sibling pointer */

 nnode->balance=0;
 nnode->parent=parent;
 nnode->LEFT=nnode->RIGHT=NIL_NODE;
 if(parent==NIL_NODE)
 {
  *rootp=newnode;
  return(newnode);                   /* just created tree */
 }

 *siblingp(parent,cmp_dir(cmp))=newnode;
 child=newnode;

 /*
  * Back up until tree is balanced.  This is achieved when either
  * the tree is balanced by rotation or a node's balance becomes 0.
  */

 do
 {
  pp=xptr(parent);
  d=direction(pp,child);
  if(pp->balance==dir_bal(d))
  {
   balance(rootp,parent,d);
   return(newnode);
  }
  else
  if((pp->balance+=dir_bal(d))==0) return(newnode);
  child=parent;
  parent=pp->parent;
 } while(parent!=NIL_NODE);

 return(newnode);
}





/*
 * Tfind searches node key in the tree rooted by *rootp, using compar for
 * comparing elements.  It returns the pointer to the NODE in which
 * the key pointer resides, or 0 if key is not present.
 */


int tfind(char *  key,int rootp)
{
 symstr * nodep;
 int      node;
 int      cmp;

 if(rootp==-1) return(NIL_NODE);

 node=rootp;
 while(node!=NIL_NODE)
 {
  nodep=xptr(node);
  if((cmp=strcmp(key,nodep->key))==0) return(node);
  node=*sibling(nodep,cmp_dir(cmp));
 }

 return(NIL_NODE);
}







/* given a name, add it to table, return offset */

int xadd(char * name,int val,int type,int mode)
{
 symstr * p;
 int      len;
 int      node;

 len=strlen(name)+sizeof(symstr);
 if(len & 0x3) len+=4-(len & 0x3);

 flex_chunk((flex_ptr)&xsymheap,xheapsize+len,XHEAPCHUNK);
 node=xheapsize;
 p=xptr(xheapsize);
 xheapsize+=len;

 strcpy(p->key,name);
 p->type=type;
 p->val=val;
 p->mode=mode;
 p->args=0;
 p->argc=0;

 tsearch(node,&xsyms[xnsyms-1].root);

 return(node);
}





/* given a name, return symbol table offset, or -1 if it does not exist */

int xfind(char * name)
{
 int     stage;
 int     hit;
 int     lo;
 int     hi;
 int     probe;
 int     code;

 for(stage=xnsyms-1;stage>=0;stage--)
  if((hit=tfind(name,xsyms[stage].root))!=-1) return(hit);

 lo=0;
 hi=(sizeof(fntable)/sizeof(fndefn))-1;
 while(1)
 {
  probe=(lo+hi)/2;
  code=strcmp(fntable[probe].name,name);
  if(!code)  return(-(probe+1));
  if(code>0) hi=probe-1;
  else       lo=probe+1;
  if(lo>hi) break;
 }
 return(XSNOTFOUND);
}



/* given a name, return symbol table offset, or -1 if it does not exist */
/* only one stage */

int xfinds(char * name,int stage)
{
 int hit;

 hit=tfind(name,xsyms[stage-1].root);

 return(hit==-1?XSNOTFOUND:hit);
}




/*removes 'stage', and any newer stages too */

void xremstage(int stage)
{
 xnsyms=stage-1;
 xheapsize=xsyms[xnsyms].heap;
 flex_chunk((flex_ptr)&xsyms,xnsyms*sizeof(int),XSYMCHUNK);
 flex_chunk((flex_ptr)&xsymheap,xheapsize,XHEAPCHUNK);
}




/* adds another stage to the symbol table */
/* notice first stage is number 1 */

int xaddstage(void)
{
 xnsyms++;
 flex_chunk((flex_ptr)&xsyms,xnsyms*sizeof(int),XSYMCHUNK);
 xsyms[xnsyms-1].heap=xheapsize;
 xsyms[xnsyms-1].root=NIL_NODE;
 return(xnsyms);
}



/* called once boots symbol table */

void xsymstart(void)
{
 xnsyms=0;
 flex_alloc((flex_ptr)&xsymheap,0);
 flex_alloc((flex_ptr)&xsyms,0);
 xheapsize=0;
}



int symfntype(int argc,int sym,int * mode)
{
 int args;
 int c;

 if(sym<0)
 {
  c=fntable[-(sym+1)].args[argc];

  if(c=='R') 
  {
   *mode=PREF;
   return(PSTR);
  }
  else
  {
   *mode=0;
   if(c=='S') return(PSTR);
   else       return(PINT);
  }
 }
 else
 {
  args=xptr(sym)->args;
  args=(args>>(argc*2)) & 0x3;

/*  dprintf(0,"read argc=%d type=%d\n",argc,args); */

  *mode=((args & 0x2)>>1)+1;
  return((args & 0x1)+1);
 }
}


void setsymfntype(int argc,int sym,int type,int mode)
{
 symstr * sx;
 int      args;

 sx=xptr(sym);
 args=sx->args;

 argc*=2;
 args&=~(3<<argc);
 args|=(((type-1)+((mode-1)<<1))<<argc);

/*  dprintf(0,"set argc=%d type=%d mode=%d\n",argc/2,type,mode); */

 xptr(sym)->args=args;
}


