pike.git / lib / modules / Stdio.pmod / Terminfo.pmod

version» Context lines:

pike.git/lib/modules/Stdio.pmod/Terminfo.pmod:1: - // $Id: Terminfo.pmod,v 1.16 2003/06/02 18:15:05 mast Exp $ + // $Id: Terminfo.pmod,v 1.17 2003/06/26 23:28:51 nilsson Exp $   #pike __REAL_VERSION__         #if constant(thread_create)   #define LOCK object m_key = mutex->lock()   #define UNLOCK destruct(m_key)   #define MUTEX static private object(Thread.Mutex) mutex = Thread.Mutex();   #else   #define LOCK   #define UNLOCK
pike.git/lib/modules/Stdio.pmod/Terminfo.pmod:144:   }      //! Termcap terminal description object.   class Termcap {       inherit TermMachine;       //!    array(string) aliases;    -  static object(Termcap) parent; +  static Termcap parent;       //! Put termcap string    string tputs(string s)    {    // Delay stuff completely ignored...    sscanf(s, "%*d%s", s);    return s;    }       private static multiset(string) load_cap(string en)
pike.git/lib/modules/Stdio.pmod/Terminfo.pmod:243:    else // weird    {    // ignore    }    }       return clears;    }       //! -  void create(string cap, object(TermcapDB)|void tcdb, int|void maxrecurse) +  void create(string cap, TermcapDB|void tcdb, int|void maxrecurse)    {    int i=0;    while((i=search(cap, "\\\n", i))>=0) {    string capr;    if(2!=sscanf(cap[i..], "\\\n%*[ \t\r]%s", capr))    break;    cap = cap[..i-1]+capr;    }    multiset(string) clears = load_cap(cap);    if(map->tc) {
pike.git/lib/modules/Stdio.pmod/Terminfo.pmod:330:    while (3==sscanf(s, "%s$<%*[0-9.]>%s", pre, post))    s = pre+post;    return s;    }       static private string swab(string s)    {    return Array.map(s/2, reverse)*"";    }    -  static private int load_cap(object(Stdio.File) f, int|void bug_compat) +  static private int load_cap(.File f, int|void bug_compat)    {    int magic, sname, nbool, nnum, nstr, sstr;       if (6!=sscanf(swab(f->read(12)), "%2c%2c%2c%2c%2c%2c",    magic, sname, nbool, nnum, nstr, sstr) ||    magic != 0432)    return 0;    aliases = (f->read(sname)-"\0")/"|";    {    int blen = nbool;
pike.git/lib/modules/Stdio.pmod/Terminfo.pmod:390:    if (!tmp[name])    m_delete(tmp, name);    map += tmp;    }    return 1;    }       //!    void create(string filename)    { -  object(Stdio.File) f = Stdio.File(); +  .File f = .File();    if (!f->open(filename, "r"))    error("Terminfo: unable to open terminfo file \"%s\"\n", filename);    int r = load_cap(f);    f->close();    if (!r)    error("Terminfo: unparsable terminfo file \"%s\"\n", filename);    }   }      class TermcapDB {       MUTEX    -  static private inherit Stdio.File; +  static private inherit .File;       static private string buf=""; -  static private mapping(string:int|object(Termcap)) cache=([]); +  static private mapping(string:int|Termcap) cache=([]);    static private int complete_index=0;       void create(string|void filename)    {    if (!filename) {    string tce = [string]getenv("TERMCAP");    if (tce && sizeof(tce) && tce[0]=='/')    filename = tce;    else    filename = "/etc/termcap";
pike.git/lib/modules/Stdio.pmod/Terminfo.pmod:521:    LOCK;    if(!complete_index) {    rewind();    while(read());    complete_index = 1;    }    UNLOCK;    return sort(indices(cache));    }    -  array(object(Termcap)) _values() +  array(Termcap) _values()    {    array(object|int) res = ({});    mapping(int:string) extra = ([]);    LOCK;    if (complete_index)    res = Array.map(sort(indices(cache)), -  [function(string,mapping(int:string):object(Termcap))] +  [function(string,mapping(int:string):Termcap)]    lambda(string name, mapping(int:string) extra) {    if (!objectp(cache[name]) && !extra[cache[name]])    extra[cache[name]] = readat(cache[name]);    return cache[name];    }, extra);    else {    array(string) resi = ({});    string cap;    int i = 1;    rewind();
pike.git/lib/modules/Stdio.pmod/Terminfo.pmod:554:    o = i++;    extra[o] = cap;    }    res += ({ o }) * sizeof(names);    resi += names;    }    sort(resi, res);    complete_index = 1;    }    UNLOCK; -  return [array(object(Termcap))] +  return [array(Termcap)]    Array.map(res, -  lambda(int|object(Termcap) x, mapping(int:object(Termcap)) y) { +  lambda(int|Termcap x, mapping(int:Termcap) y) {    return objectp(x)? x : y[x];    },    mkmapping(indices(extra),    Array.map(values(extra), -  Termcap, this_object()))); +  Termcap, this)));    }       static private string read_next(string find) // quick search    {    for (;;)    {    int i, j;       if (buf=="" && !more_data()) return 0; // eof   
pike.git/lib/modules/Stdio.pmod/Terminfo.pmod:597:    buf = buf[i+1..];       continue;    }    for(j=-1; (i=search(buf,"\n",j+1))>=0; j=i);    buf = buf[j+1..];    if (!more_data()) return 0; // eof    }    }    -  object(Termcap) load(string term, int|void maxrecurse) +  Termcap load(string term, int|void maxrecurse)    { -  int|string|object(Termcap) cap; +  int|string|Termcap cap;       LOCK;    if (zero_type(cache[term]))    {    if (!complete_index)    {    rewind();    do    cap = read_next(term);    while(cap && search(get_names(cap), term)<0);    }    }    else if (intp(cap=cache[term])) {    rewind(cap);    cap = read();    }    UNLOCK;    if (stringp(cap))    {    array(string) names = get_names(cap); -  if ((cap = Termcap(cap, this_object(), maxrecurse))) +  if ((cap = Termcap(cap, this, maxrecurse)))    {    LOCK;    foreach(names, string name)    cache[name] = [object(Termcap)]cap;    UNLOCK;    }    }    return objectp(cap) && [object(Termcap)]cap;    }    -  object(Termcap) `[](string name) +  Termcap `[](string name)    {    return load(name);    }   }         class TerminfoDB {       MUTEX       static private string dir; -  static private mapping(string:object(Terminfo)) cache = ([]); +  static private mapping(string:Terminfo) cache = ([]);    static private int complete_index=0;       void create(string|void dirname)    {    if (!dirname)    {    foreach (({"/usr/share/lib/terminfo", "/usr/share/termcap",    "/usr/lib/terminfo", "/usr/share/misc/terminfo"}), string dn)    {    .Stat s = file_stat(dn);    if (s && s->type=="dir")    {    dirname = dn;    break;    }    }    if (!dirname) { -  destruct(this_object()); +  destruct(this);    return;    }    }       if(sizeof(dirname)<1 || dirname[-1]!='/')    dirname += "/";       if (!get_dir(dir = dirname))    error("failed to read terminfo dir %O\n", dirname);    }
pike.git/lib/modules/Stdio.pmod/Terminfo.pmod:699:    array(object) _values()    {    return Array.map(_indices(),    [function(string:object(Terminfo))]    lambda(string name) {    return cache[name] ||    Terminfo(dir+name[..0]+"/"+name);    });    }    -  object(Terminfo) load(string term) +  Terminfo load(string term)    { -  object(Terminfo) ti; +  Terminfo ti;       if (!sizeof(term))    return 0;    LOCK;    if (!(ti = cache[term]))    {    if (file_stat(dir+term[..0]+"/"+term))    ti = Terminfo(dir+term[..0]+"/"+term);    if (ti)    cache[term] = ti;    }    UNLOCK;    return ti;    }    -  object(Terminfo) `[](string name) +  Terminfo `[](string name)    {    return load(name);    }   }    - static private object(Termcap) defterm; - static private object(TermcapDB) deftermcap; - static private object(TerminfoDB) defterminfo; + static private Termcap defterm; + static private TermcapDB deftermcap; + static private TerminfoDB defterminfo;    - object(TermcapDB) defaultTermcapDB() + TermcapDB defaultTermcapDB()   { -  object(TermcapDB) tcdb; +  TermcapDB tcdb;    LOCK;    catch { tcdb = deftermcap || (deftermcap = TermcapDB()); };    UNLOCK;    return tcdb;   }    - object(TerminfoDB) defaultTerminfoDB() + TerminfoDB defaultTerminfoDB()   { -  object(TerminfoDB) tidb; +  TerminfoDB tidb;    LOCK;    catch { tidb = defterminfo || (defterminfo = TerminfoDB()); };    UNLOCK;    return tidb;   }      //! Returns the terminal description object for @[term] from the   //! systems termcap database. Returns 0 if not found.   //!   //! @seealso   //! Stdio.Terminfo.getTerm, Stdio.Terminfo.getTerminfo - object(Termcap) getTermcap(string term) + Termcap getTermcap(string term)   { -  object(TermcapDB) tcdb = defaultTermcapDB(); +  TermcapDB tcdb = defaultTermcapDB();    return tcdb && tcdb[term];   }      //! Returns the terminal description object for @[term] from the   //! systems terminfo database. Returns 0 if not found.   //!   //! @seealso   //! Stdio.Terminfo.getTerm, Stdio.Terminfo.getTermcap - object(Terminfo) getTerminfo(string term) + Terminfo getTerminfo(string term)   { -  object(TerminfoDB) tidb = defaultTerminfoDB(); +  TerminfoDB tidb = defaultTerminfoDB();    return tidb && tidb[term];   }      //! Returns an object describing the terminal term. If term is not specified, it will   //! default to @[getenv("TERM")] or if that fails to "dumb".   //!   //! Lookup of terminal information will first be done in the systems terminfo   //! database, and if that fails in the termcap database. If neither database exists, a   //! hardcoded entry for "dumb" will be used.   //!   //! @seealso   //! Stdio.Terminfo.getTerminfo, Stdio.Terminfo.getTermcap, Stdio.getFallbackTerm - object(Termcap) getTerm(string|void term) + Termcap getTerm(string|void term)   {    if (!term) { -  object(Termcap) t = defterm; +  Termcap t = defterm;    if (!t)    {    string tc = [string]getenv("TERMCAP");    if (mixed err = catch {    t = tc && sizeof(tc) && tc[0] != '/' && Termcap(tc);    })    werror("%s", describe_backtrace(err));    if (!t)    t = getTerm(getenv("TERM") || "dumb");    LOCK;
pike.git/lib/modules/Stdio.pmod/Terminfo.pmod:804:    return t;    }    return getTerminfo(term) || getTermcap(term) || getFallbackTerm(term);   }      //! Returns an object describing the fallback terminal for the terminal   //! @[term]. This is usually equvivalent to @[Stdio.Terminfo.getTerm("dumb")].   //!   //! @seealso   //! Stdio.Terminfo.getTerm - static object(Termcap) getFallbackTerm(string term) + static Termcap getFallbackTerm(string term)   {    return (term=="dumb"? Termcap("dumb:\\\n\t:am:co#80:do=^J:") :    getTerm("dumb"));   }      static int is_tty_cache;      int is_tty()   //! Returns 1 if @[Stdio.stdin] is connected to an interactive   //! terminal that can handle backspacing, carriage return without   //! linefeed, and the like.   {    if(!is_tty_cache)    {   #ifdef __NT__    is_tty_cache=1;   #else -  is_tty_cache=!!Stdio.stdin->tcgetattr(); +  is_tty_cache=!!.stdin->tcgetattr();   #endif    if(!is_tty_cache)    {    is_tty_cache=-1;    }else{    switch(getenv("TERM"))    {    case "dumb":    case "emacs":    is_tty_cache=-1;    }    }    }    return is_tty_cache>0;   }