home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / octave-1.1.1p1-base.tgz / octave-1.1.1p1-base.tar / fsf / octave / src / symtab.cc < prev    next >
C/C++ Source or Header  |  1995-02-03  |  21KB  |  1,164 lines

  1. // symtab.cc                                            -*- C++ -*-
  2. /*
  3.  
  4. Copyright (C) 1992, 1993, 1994, 1995 John W. Eaton
  5.  
  6. This file is part of Octave.
  7.  
  8. Octave is free software; you can redistribute it and/or modify it
  9. under the terms of the GNU General Public License as published by the
  10. Free Software Foundation; either version 2, or (at your option) any
  11. later version.
  12.  
  13. Octave is distributed in the hope that it will be useful, but WITHOUT
  14. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16. for more details.
  17.  
  18. You should have received a copy of the GNU General Public License
  19. along with Octave; see the file COPYING.  If not, write to the Free
  20. Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  
  22. */
  23.  
  24. #ifdef HAVE_CONFIG_H
  25. #include "config.h"
  26. #endif
  27.  
  28. #include "symtab.h"
  29. #include "error.h"
  30. #include "variables.h"
  31. #include "utils.h"
  32. #include "user-prefs.h"
  33. #include "tree-base.h"
  34. #include "tree-expr.h"
  35. #include "tree-const.h"
  36.  
  37. extern "C"
  38. {
  39. #include "fnmatch.h"
  40. }
  41.  
  42. // Variables and functions.
  43.  
  44. symbol_def::symbol_def (void)
  45. {
  46.   init_state ();
  47. }
  48.  
  49. symbol_def::symbol_def (tree_constant *t)
  50. {
  51.   init_state ();
  52.   definition = t;
  53.   type = USER_VARIABLE;
  54. }
  55.  
  56. symbol_def::symbol_def (tree_builtin *t, unsigned fcn_type)
  57. {
  58.   init_state ();
  59.   definition = t;
  60.   type = BUILTIN_FUNCTION | fcn_type;
  61. }
  62.  
  63. symbol_def::symbol_def (tree_function *t, unsigned fcn_type)
  64. {
  65.   init_state ();
  66.   definition = t;
  67.   type = USER_FUNCTION | fcn_type;
  68. }
  69.  
  70. void
  71. symbol_def::init_state (void)
  72. {
  73.   type = UNKNOWN;
  74.   eternal = 0;
  75.   read_only = 0;
  76.  
  77.   help_string = 0;
  78.   definition = 0;
  79.   next_elem = 0;
  80.   count = 0;
  81. }
  82.  
  83. symbol_def::~symbol_def (void)
  84. {
  85.   delete [] help_string;
  86.   delete definition;
  87. }
  88.  
  89. int
  90. symbol_def::is_variable (void) const
  91. {
  92.   return (type & USER_VARIABLE || type & BUILTIN_VARIABLE);
  93. }
  94.  
  95. int
  96. symbol_def::is_function (void) const
  97. {
  98.   return (type & USER_FUNCTION || type & BUILTIN_FUNCTION);
  99. }
  100.  
  101. int
  102. symbol_def::is_user_variable (void) const
  103. {
  104.   return (type & USER_VARIABLE);
  105. }
  106.  
  107. int
  108. symbol_def::is_text_function (void) const
  109. {
  110.   return (type & TEXT_FUNCTION);
  111. }
  112.  
  113. int
  114. symbol_def::is_mapper_function (void) const
  115. {
  116.   return (type & MAPPER_FUNCTION);
  117. }
  118.  
  119. int
  120. symbol_def::is_user_function (void) const
  121. {
  122.   return (type & USER_FUNCTION);
  123. }
  124.  
  125. int
  126. symbol_def::is_builtin_variable (void) const
  127. {
  128.   return (type & BUILTIN_VARIABLE);
  129. }
  130.  
  131. int
  132. symbol_def::is_builtin_function (void) const
  133. {
  134.   return (type & BUILTIN_FUNCTION);
  135. }
  136.  
  137. void
  138. symbol_def::define (tree_constant *t)
  139. {
  140.   definition = t;
  141.   if (! is_builtin_variable ())
  142.     type = USER_VARIABLE;
  143. }
  144.  
  145. void
  146. symbol_def::define (tree_builtin *t, unsigned fcn_type)
  147. {
  148.   definition = t;
  149.   type = BUILTIN_FUNCTION | fcn_type;
  150. }
  151.  
  152. void
  153. symbol_def::define (tree_function *t, unsigned fcn_type)
  154. {
  155.   definition = t;
  156.   type = USER_FUNCTION | fcn_type;
  157. }
  158.  
  159. void
  160. symbol_def::protect (void)
  161. {
  162.   read_only = 1;
  163. }
  164.  
  165. void
  166. symbol_def::unprotect (void)
  167. {
  168.   read_only = 0;
  169.  
  170. }
  171.  
  172. void
  173. symbol_def::make_eternal (void)
  174. {
  175.   eternal = 1;
  176. }
  177.  
  178. tree_fvc *
  179. symbol_def::def (void) const
  180. {
  181.   return definition;
  182. }
  183.  
  184. char *
  185. symbol_def::help (void) const
  186. {
  187.   return help_string;
  188. }
  189.  
  190. void
  191. symbol_def::document (const char *h)
  192. {
  193.   delete [] help_string;
  194.   help_string = strsave (h);
  195. }
  196.  
  197. int
  198. maybe_delete (symbol_def *def)
  199. {
  200.   int count = 0;
  201.   if (def && def->count > 0)
  202.     {
  203.       def->count--;
  204.       count = def->count;
  205.       if (def->count == 0)
  206.     delete def;
  207.     }
  208.   return count;
  209. }
  210.  
  211. // Individual records in a symbol table.
  212.  
  213. symbol_record::symbol_record (void)
  214. {
  215.   init_state ();
  216. }
  217.  
  218. symbol_record::symbol_record (const char *n, symbol_record *nxt)
  219. {
  220.   init_state ();
  221.   nm = strsave (n);
  222.   next_elem = nxt;
  223. }
  224.  
  225. void
  226. symbol_record::init_state (void)
  227. {
  228.   formal_param = 0;
  229.   linked_to_global = 0;
  230.   nm = 0;
  231.   sv_fcn = 0;
  232.   definition = 0;
  233.   next_elem = 0;
  234. }
  235.  
  236. symbol_record::~symbol_record (void)
  237. {
  238.   delete [] nm;
  239. }
  240.  
  241. char *
  242. symbol_record::name (void) const
  243. {
  244.   return nm;
  245. }
  246.  
  247. char *
  248. symbol_record::help (void) const
  249. {
  250.   return definition ? definition->help () : 0;
  251. }
  252.  
  253. tree_fvc *
  254. symbol_record::def (void) const
  255. {
  256.   return definition ? definition->def () : 0;
  257. }
  258.  
  259. void
  260. symbol_record::rename (const char *new_name)
  261. {
  262.   delete [] nm;
  263.   nm = strsave (new_name);
  264. }
  265.  
  266. int
  267. symbol_record::is_function (void) const
  268. {
  269.   return definition ? definition->is_function () : 0;
  270. }
  271.  
  272. int
  273. symbol_record::is_text_function (void) const
  274. {
  275.   return definition ? definition->is_text_function () : 0;
  276. }
  277.  
  278. int
  279. symbol_record::is_mapper_function (void) const
  280. {
  281.   return definition ? definition->is_mapper_function () : 0;
  282. }
  283.  
  284. int
  285. symbol_record::is_user_function (void) const
  286. {
  287.   return definition ? definition->is_user_function () : 0;
  288. }
  289.  
  290. int
  291. symbol_record::is_builtin_function (void) const
  292. {
  293.   return definition ? definition->is_builtin_function () : 0;
  294. }
  295.  
  296. int
  297. symbol_record::is_variable (void) const
  298. {
  299.   return definition ? definition->is_variable () : 0;
  300. }
  301.  
  302. int
  303. symbol_record::is_user_variable (void) const
  304. {
  305.   return definition ? definition->is_user_variable () : 0;
  306. }
  307.  
  308. int
  309. symbol_record::is_builtin_variable (void) const
  310. {
  311.   return definition ? definition->is_builtin_variable () : 0;
  312. }
  313.  
  314. unsigned
  315. symbol_record::type (void) const
  316. {
  317.   return definition ? definition->type : 0;
  318. }
  319.  
  320. int
  321. symbol_record::is_defined (void) const
  322. {
  323.   return definition ? (definition->def () != 0) : 0;
  324. }
  325.  
  326. int
  327. symbol_record::is_read_only (void) const
  328. {
  329.   return definition ? definition->read_only : 0;
  330. }
  331.  
  332. int
  333. symbol_record::is_eternal (void) const
  334. {
  335.   return definition ? definition->eternal : 0;
  336. }
  337.  
  338. void
  339. symbol_record::protect (void)
  340. {
  341.   if (definition)
  342.     {
  343.       definition->protect ();
  344.  
  345.       if (! is_defined ())
  346.     warning ("protecting undefined variable `%s'", nm);
  347.     }
  348. }
  349.  
  350. void
  351. symbol_record::unprotect (void)
  352. {
  353.   if (definition)
  354.     definition->unprotect ();
  355. }
  356.  
  357. void
  358. symbol_record::make_eternal (void)
  359. {
  360.   if (definition)
  361.     {
  362.       definition->make_eternal ();
  363.  
  364.       if (! is_defined ())
  365.     warning ("giving eternal life to undefined variable `%s'", nm);
  366.     }
  367. }
  368.  
  369. void
  370. symbol_record::set_sv_function (sv_Function f)
  371. {
  372.   sv_fcn = f;
  373. }
  374.  
  375. int
  376. symbol_record::define (tree_constant *t)
  377. {
  378.   if (is_variable () && read_only_error ())
  379.     return 0;
  380.  
  381.   tree_fvc *saved_def = 0;
  382.   if (! definition)
  383.     {
  384.       definition = new symbol_def ();
  385.       definition->count = 1;
  386.     }
  387.   else if (is_function ())
  388.     {
  389.       symbol_def *new_def = new symbol_def ();
  390.       push_def (new_def);
  391.       definition->count = 1;
  392.     }
  393.   else if (is_variable ())
  394.     {
  395.       saved_def = definition->def ();
  396.     }
  397.  
  398.   definition->define (t);
  399.  
  400.   if (sv_fcn && sv_fcn () < 0)
  401.     {
  402. // Would be nice to be able to avoid this cast.  XXX FIXME XXX
  403.       definition->define ((tree_constant *) saved_def);
  404.       delete t;
  405.       return 0;
  406.     }
  407.  
  408.   delete saved_def;
  409.  
  410.   return 1;
  411. }
  412.  
  413. int
  414. symbol_record::define (tree_builtin *t, int text_fcn)
  415. {
  416.   if (read_only_error ())
  417.     return 0;
  418.  
  419.   if (is_variable ())
  420.     {
  421.       symbol_def *old_def = pop_def ();
  422.       maybe_delete (old_def);
  423.     }
  424.  
  425.   if (is_function ())
  426.     {
  427.       symbol_def *old_def = pop_def ();
  428.       maybe_delete (old_def);
  429.     }
  430.  
  431.   unsigned fcn_type = text_fcn ? symbol_def::TEXT_FUNCTION
  432.     : ((t && t->is_mapper_function ()) ? symbol_def::MAPPER_FUNCTION
  433.        : symbol_def::UNKNOWN);
  434.  
  435.   symbol_def *new_def = new symbol_def (t, fcn_type);
  436.   push_def (new_def);
  437.   definition->count = 1;
  438.  
  439.   return 1;
  440. }
  441.  
  442. int
  443. symbol_record::define (tree_function *t, int text_fcn)
  444. {
  445.   if (read_only_error ())
  446.     return 0;
  447.  
  448.   if (is_variable ())
  449.     {
  450.       symbol_def *old_def = pop_def ();
  451.       maybe_delete (old_def);
  452.     }
  453.  
  454.   if (is_function ())
  455.     {
  456.       symbol_def *old_def = pop_def ();
  457.       maybe_delete (old_def);
  458.     }
  459.  
  460.   unsigned fcn_type = text_fcn ? symbol_def::TEXT_FUNCTION
  461.     : symbol_def::UNKNOWN;
  462.  
  463.   symbol_def *new_def = new symbol_def (t, fcn_type);
  464.   push_def (new_def);
  465.   definition->count = 1;
  466.  
  467.   return 1;
  468. }
  469.  
  470. int
  471. symbol_record::define_as_fcn (tree_constant *t)
  472. {
  473.   if (is_variable () && read_only_error ())
  474.     return 0;
  475.  
  476.   if (is_variable ())
  477.     {
  478.       symbol_def *old_def = pop_def ();
  479.       maybe_delete (old_def);
  480.     }
  481.  
  482.   if (is_function ())
  483.     {
  484.       symbol_def *old_def = pop_def ();
  485.       maybe_delete (old_def);
  486.     }
  487.  
  488.   symbol_def *new_def = new symbol_def (t);
  489.   push_def (new_def);
  490.   definition->count = 1;
  491.   definition->type = symbol_def::BUILTIN_FUNCTION;
  492.  
  493.   return 1;
  494. }
  495.  
  496. int
  497. symbol_record::define_builtin_var (tree_constant *t)
  498. {
  499.   define (t);
  500.   if (is_variable ())
  501.     definition->type = symbol_def::BUILTIN_VARIABLE;
  502.   return 1;
  503. }
  504.  
  505. void
  506. symbol_record::document (const char *h)
  507. {
  508.   if (definition)
  509.     {
  510.       definition->document (h);
  511.  
  512.       if (! is_defined ())
  513.     warning ("documenting undefined variable `%s'", nm);
  514.     }
  515. }
  516.  
  517. int
  518. symbol_record::clear (void)
  519. {
  520.   int count = 0;
  521.   if (linked_to_global)
  522.     {
  523.       count = maybe_delete (definition);
  524.       definition = 0;
  525.       linked_to_global = 0;
  526.     }
  527.   else
  528.     {
  529.       symbol_def *old_def = pop_def ();
  530.       count = maybe_delete (old_def);
  531.     }
  532.   return count;
  533. }
  534.  
  535. void
  536. symbol_record::alias (symbol_record *s, int force)
  537. {
  538.   sv_fcn = s->sv_fcn;
  539.  
  540.   if (force && ! s->definition)
  541.     {
  542.       s->definition = new symbol_def ();
  543.       definition = s->definition;
  544.       definition->count = 2; // Yes, this is correct.
  545.     }
  546.   else if (s->definition)
  547.     {
  548.       definition = s->definition;
  549.       definition->count++;
  550.     }
  551. }
  552.  
  553. void
  554. symbol_record::mark_as_formal_parameter (void)
  555. {
  556.   formal_param = 1;
  557. }
  558.  
  559. int
  560. symbol_record::is_formal_parameter (void) const
  561. {
  562.   return formal_param;
  563. }
  564.  
  565. void
  566. symbol_record::mark_as_linked_to_global (void)
  567. {
  568.   linked_to_global = 1;
  569. }
  570.  
  571. int
  572. symbol_record::is_linked_to_global (void) const
  573. {
  574.   return linked_to_global;
  575. }
  576.  
  577. symbol_record *
  578. symbol_record::next (void) const
  579. {
  580.   return next_elem;
  581. }
  582.  
  583. void
  584. symbol_record::chain (symbol_record *s)
  585. {
  586.   next_elem = s;
  587. }
  588.  
  589. void
  590. symbol_record::push_context (void)
  591. {
  592.   context.push (definition);
  593.   definition = 0;
  594.  
  595.   global_link_context.push ((unsigned) linked_to_global);
  596.   linked_to_global = 0;
  597. }
  598.  
  599. void
  600. symbol_record::pop_context (void)
  601. {
  602.   assert (! context.empty ());
  603.  
  604.   if (is_variable ())
  605.     {
  606.       symbol_def *old_def = pop_def ();
  607.       maybe_delete (old_def);
  608.     }
  609.  
  610.   if (is_function ())
  611.     {
  612.       symbol_def *old_def = pop_def ();
  613.       maybe_delete (old_def);
  614.     }
  615.  
  616.   definition = context.pop ();
  617.   linked_to_global = global_link_context.pop ();
  618. }
  619.  
  620. int
  621. symbol_record::read_only_error (void)
  622. {
  623.   if (is_read_only ())
  624.     {
  625.       if (is_variable ())
  626.     {
  627.       if (user_pref.read_only_constants)
  628.         {
  629.           if (user_pref.read_only_constants < 0)
  630.         {
  631.           ::warning ("redefinition of constant `%s'", nm);
  632.           return 0;
  633.         }
  634.           else
  635.         ::error ("can't redefine read-only constant `%s'", nm);
  636.         }
  637.     }
  638.       else if (is_function ())
  639.     {
  640.       ::error ("can't redefine read-only function `%s'", nm);
  641.     }
  642.       else
  643.     {
  644.       ::error ("can't redefine read-only symbol `%s'", nm);
  645.     }
  646.  
  647.       return 1;
  648.     }
  649.   else
  650.     return 0;
  651. }
  652.  
  653. void
  654. symbol_record::push_def (symbol_def *sd)
  655. {
  656.   if (! sd)
  657.     return;
  658.  
  659.   sd->next_elem = definition;
  660.   definition = sd;
  661. }
  662.  
  663. symbol_def *
  664. symbol_record::pop_def (void)
  665. {
  666.   symbol_def *top = definition;
  667.   if (definition)
  668.     definition = definition->next_elem;
  669.   return top;
  670. }
  671.  
  672. // A structure for handling verbose information about a symbol_record.
  673.  
  674. symbol_record_info::symbol_record_info (void)
  675. {
  676.   init_state ();
  677. }
  678.  
  679. symbol_record_info::symbol_record_info (const symbol_record& sr)
  680. {
  681.   init_state ();
  682.  
  683.   type = sr.type ();
  684.  
  685.   if (sr.is_variable () && sr.is_defined ())
  686.     {
  687. // Would be nice to avoid this cast.  XXX FIXME XXX
  688.       tree_constant *tmp = (tree_constant *) sr.def ();
  689.       if (tmp->is_real_scalar ())
  690.     const_type = SR_INFO_SCALAR;
  691.       else if (tmp->is_complex_scalar ())
  692.     const_type = SR_INFO_COMPLEX_SCALAR;
  693.       else if (tmp->is_real_matrix ())
  694.     const_type = SR_INFO_MATRIX;
  695.       else if (tmp->is_complex_matrix ())
  696.     const_type = SR_INFO_COMPLEX_MATRIX;
  697.       else if (tmp->is_range ())
  698.     const_type = SR_INFO_RANGE;
  699.       else if (tmp->is_string ())
  700.     const_type = SR_INFO_STRING;
  701.  
  702.       nr = tmp->rows ();
  703.       nc = tmp->columns ();
  704.  
  705.       symbol_def *sr_def = sr.definition;
  706.       symbol_def *hidden_def = sr_def->next_elem;
  707.       if (hidden_def)
  708.     {
  709.       if (hidden_def->is_user_function ())
  710.         hides = SR_INFO_USER_FUNCTION;
  711.       else if (hidden_def->is_builtin_function ())
  712.         hides = SR_INFO_BUILTIN_FUNCTION;
  713.     }
  714.     }
  715.  
  716.   eternal = sr.is_eternal ();
  717.   read_only = sr.is_read_only ();
  718.  
  719.   nm = strsave (sr.name ());
  720.  
  721.   initialized = 1;
  722. }
  723.  
  724. symbol_record_info::symbol_record_info (const symbol_record_info& s)
  725. {
  726.   type = s.type;
  727.   const_type = s.const_type;
  728.   hides = s.hides;
  729.   eternal = s.eternal;
  730.   read_only = s.read_only;
  731.   nr = s.nr;
  732.   nc = s.nc;
  733.   nm = strsave (s.nm);
  734.   initialized = s.initialized;
  735. }
  736.  
  737. symbol_record_info::~symbol_record_info (void)
  738. {
  739.   delete nm;
  740. }
  741.  
  742. symbol_record_info&
  743. symbol_record_info::operator = (const symbol_record_info& s)
  744. {
  745.   if (this != &s)
  746.     {
  747.       delete nm;
  748.       type = s.type;
  749.       const_type = s.const_type;
  750.       hides = s.hides;
  751.       eternal = s.eternal;
  752.       read_only = s.read_only;
  753.       nr = s.nr;
  754.       nc = s.nc;
  755.       nm = strsave (s.nm);
  756.       initialized = s.initialized;
  757.     }
  758.   return *this;
  759. }
  760.  
  761. int
  762. symbol_record_info::is_defined (void) const
  763. {
  764.   return initialized;
  765. }
  766.  
  767. int
  768. symbol_record_info::is_read_only (void) const
  769. {
  770.   return read_only;
  771. }
  772.  
  773. int
  774. symbol_record_info::is_eternal (void) const
  775. {
  776.   return eternal;
  777. }
  778.  
  779. int
  780. symbol_record_info::hides_fcn (void) const
  781. {
  782.   return (hides & SR_INFO_USER_FUNCTION);
  783. }
  784.  
  785. int
  786. symbol_record_info::hides_builtin (void) const
  787. {
  788.   return (hides & SR_INFO_BUILTIN_FUNCTION);
  789. }
  790.  
  791. char *
  792. symbol_record_info::type_as_string (void) const
  793. {
  794.   if (type == symbol_def::USER_FUNCTION)
  795.     return "user function";
  796.   else if (type == symbol_def::BUILTIN_FUNCTION)
  797.     return "builtin function";
  798.   else
  799.     {
  800.       if (const_type == SR_INFO_SCALAR)
  801.     return "real scalar";
  802.       else if (const_type == SR_INFO_COMPLEX_SCALAR)
  803.     return "complex scalar";
  804.       else if (const_type == SR_INFO_MATRIX)
  805.     return "real matrix";
  806.       else if (const_type == SR_INFO_COMPLEX_MATRIX)
  807.     return "complex matrix";
  808.       else if (const_type == SR_INFO_RANGE)
  809.     return "range";
  810.       else if (const_type == SR_INFO_STRING)
  811.     return "string";
  812.       else
  813.     return "";
  814.     }
  815. }
  816.  
  817. int
  818. symbol_record_info::is_function (void) const
  819. {
  820.   return (type == symbol_def::USER_FUNCTION
  821.       || type == symbol_def::BUILTIN_FUNCTION);
  822. }
  823.  
  824. int
  825. symbol_record_info::rows (void) const
  826. {
  827.   return nr;
  828. }
  829.  
  830. int
  831. symbol_record_info::columns (void) const
  832. {
  833.   return nc;
  834. }
  835.  
  836. char *
  837. symbol_record_info::name (void) const
  838. {
  839.   return nm;
  840. }
  841.  
  842. void
  843. symbol_record_info::init_state (void)
  844. {
  845.   initialized = 0;
  846.   type = symbol_def::UNKNOWN;
  847.   const_type = SR_INFO_UNKNOWN;
  848.   hides = SR_INFO_NONE;
  849.   eternal = 0;
  850.   read_only = 0;
  851.   nr = -1;
  852.   nc = -1;
  853.   nm = 0;
  854. }
  855.  
  856. // A symbol table.
  857.  
  858. symbol_table::symbol_table (void)
  859. {
  860. }
  861.  
  862. symbol_record *
  863. symbol_table::lookup (const char *nm, int insert, int warn)
  864. {
  865.   int index = hash (nm) & HASH_MASK;
  866.  
  867.   symbol_record *ptr = table[index].next ();
  868.  
  869.   while (ptr)
  870.     {
  871.       if (strcmp (ptr->name (), nm) == 0)
  872.     return ptr;
  873.       ptr = ptr->next ();
  874.     }
  875.  
  876.   if (insert)
  877.     {
  878.       symbol_record *new_sym;
  879.       new_sym = new symbol_record (nm, table[index].next ());
  880.       table[index].chain (new_sym);
  881.       return new_sym;
  882.     }
  883.   else if (warn)
  884.     warning ("lookup: symbol`%s' not found", nm);
  885.  
  886.   return 0;
  887. }
  888.  
  889. void
  890. symbol_table::rename (const char *old_name, const char *new_name)
  891. {
  892.   int index = hash (old_name) & HASH_MASK;
  893.  
  894.   symbol_record *prev = &table[index];
  895.   symbol_record *ptr = prev->next ();
  896.  
  897.   while (ptr)
  898.     {
  899.       if (strcmp (ptr->name (), old_name) == 0)
  900.     {
  901.       prev->chain (ptr->next ());
  902.  
  903.       index = hash (new_name) & HASH_MASK;
  904.       table[index].chain (ptr);
  905.       ptr->rename (new_name);
  906.  
  907.       return;
  908.     }
  909.  
  910.       prev = ptr;
  911.       ptr = ptr->next ();
  912.     }
  913.  
  914.   error ("unable to rename `%s' to `%s', old_name, new_name");
  915. }
  916.  
  917. void
  918. symbol_table::clear (int clear_user_functions)
  919. {
  920.   for (int i = 0; i < HASH_TABLE_SIZE; i++)
  921.     {
  922.       symbol_record *ptr = table[i].next ();
  923.  
  924.       while (ptr)
  925.     {
  926.       if (ptr->is_user_variable ()
  927.           || (clear_user_functions && ptr->is_user_function ()))
  928.         {
  929.           ptr->clear ();
  930.         }
  931.  
  932.       ptr = ptr->next ();
  933.     }
  934.     }
  935. }
  936.  
  937. int
  938. symbol_table::clear (const char *nm, int clear_user_functions)
  939. {
  940.   int index = hash (nm) & HASH_MASK;
  941.  
  942.   symbol_record *ptr = table[index].next ();
  943.  
  944.   while (ptr)
  945.     {
  946.       if (strcmp (ptr->name (), nm) == 0
  947.       && (ptr->is_user_variable ()
  948.           || (clear_user_functions && ptr->is_user_function ())))
  949.     {
  950.       ptr->clear ();
  951.       return 1;
  952.     }
  953.       ptr = ptr->next ();
  954.     }
  955.  
  956.   return 0;
  957. }
  958.  
  959. int
  960. symbol_table::size (void) const
  961. {
  962.   int count = 0;
  963.   for (int i = 0; i < HASH_TABLE_SIZE; i++)
  964.     {
  965.       symbol_record *ptr = table[i].next ();
  966.       while (ptr)
  967.     {
  968.       count++;
  969.       ptr = ptr->next ();
  970.     }
  971.     }
  972.   return count;
  973. }
  974.  
  975. static inline int
  976. pstrcmp (char **a, char **b)
  977. {
  978.   return strcmp (*a, *b);
  979. }
  980.  
  981. static inline int
  982. symbol_record_info_cmp (symbol_record_info *a, symbol_record_info *b)
  983. {
  984.   return strcmp (a->name (), b->name ());
  985. }
  986.  
  987. static int
  988. matches_patterns (const char *name, char **pats, int npats)
  989. {
  990.   while (npats-- > 0)
  991.     {
  992.       if (fnmatch (*pats, name, __FNM_FLAGS) == 0)
  993.     return 1;
  994.  
  995.       pats++;
  996.     }
  997.  
  998.   return 0;
  999. }
  1000.  
  1001. // This function should probably share code with symbol_table::list.
  1002. // XXX FIXME XXX
  1003.  
  1004. symbol_record_info *
  1005. symbol_table::long_list (int& count, char **pats, int npats, int sort,
  1006.              unsigned type, unsigned scope) const 
  1007. {
  1008.   count = 0;
  1009.   int n = size ();
  1010.   if (n == 0)
  1011.     return 0;
  1012.  
  1013.   symbol_record_info *symbols = new symbol_record_info [n+1];
  1014.   for (int i = 0; i < HASH_TABLE_SIZE; i++)
  1015.     {
  1016.       symbol_record *ptr = table[i].next ();
  1017.       while (ptr)
  1018.     {
  1019.       assert (count < n);
  1020.  
  1021.       unsigned my_scope = ptr->is_linked_to_global () + 1; // Tricky...
  1022.  
  1023.       unsigned my_type = ptr->type ();
  1024.  
  1025.       char *my_name = ptr->name ();
  1026.  
  1027.       if ((type & my_type) && (scope & my_scope)
  1028.           && (npats == 0 || matches_patterns (my_name, pats, npats)))
  1029.         symbols[count++] = symbol_record_info (*ptr);
  1030.  
  1031.       ptr = ptr->next ();
  1032.     }
  1033.     }
  1034.   symbols[count] = symbol_record_info ();
  1035.  
  1036.   if (sort && symbols)
  1037.     qsort ((void *) symbols, count, sizeof (symbol_record_info),
  1038.        (int (*)(const void*, const void*)) symbol_record_info_cmp);
  1039.  
  1040.   return symbols;
  1041. }
  1042.  
  1043. char **
  1044. symbol_table::list (int& count, char **pats, int npats, int sort,
  1045.             unsigned type, unsigned scope) const
  1046. {
  1047.   count = 0;
  1048.   int n = size ();
  1049.   if (n == 0)
  1050.     return 0;
  1051.  
  1052.   char **symbols = new char * [n+1];
  1053.   for (int i = 0; i < HASH_TABLE_SIZE; i++)
  1054.     {
  1055.       symbol_record *ptr = table[i].next ();
  1056.       while (ptr)
  1057.     {
  1058.       assert (count < n);
  1059.  
  1060.       unsigned my_scope = ptr->is_linked_to_global () + 1; // Tricky...
  1061.  
  1062.       unsigned my_type = ptr->type ();
  1063.  
  1064.       char *my_name = ptr->name ();
  1065.  
  1066.       if ((type & my_type) && (scope & my_scope)
  1067.           && (npats == 0 || matches_patterns (my_name, pats, npats)))
  1068.         symbols[count++] = strsave (ptr->name ());
  1069.  
  1070.       ptr = ptr->next ();
  1071.     }
  1072.     }
  1073.   symbols[count] = 0;
  1074.  
  1075.   if (sort && symbols)
  1076.     qsort ((void **) symbols, count, sizeof (char *),
  1077.        (int (*)(const void*, const void*)) pstrcmp);
  1078.  
  1079.   return symbols;
  1080. }
  1081.  
  1082. symbol_record **
  1083. symbol_table::glob (int& count, char *pat, unsigned type,
  1084.             unsigned scope) const
  1085. {
  1086.   count = 0;
  1087.   int n = size ();
  1088.   if (n == 0)
  1089.     return 0;
  1090.  
  1091.   symbol_record **symbols = new symbol_record * [n+1];
  1092.   for (int i = 0; i < HASH_TABLE_SIZE; i++)
  1093.     {
  1094.       symbol_record *ptr = table[i].next ();
  1095.       while (ptr)
  1096.     {
  1097.       assert (count < n);
  1098.  
  1099.       unsigned my_scope = ptr->is_linked_to_global () + 1; // Tricky...
  1100.  
  1101.       unsigned my_type = ptr->type ();
  1102.  
  1103.       if ((type & my_type) && (scope & my_scope)
  1104.           && fnmatch (pat, ptr->name (), __FNM_FLAGS) == 0)
  1105.         {
  1106.           symbols[count++] = ptr;
  1107.         }
  1108.  
  1109.       ptr = ptr->next ();
  1110.     }
  1111.     }
  1112.   symbols[count] = 0;
  1113.  
  1114.   return symbols;
  1115. }
  1116.  
  1117. void
  1118. symbol_table::push_context (void)
  1119. {
  1120.   for (int i = 0; i < HASH_TABLE_SIZE; i++)
  1121.     {
  1122.       symbol_record *ptr = table[i].next ();
  1123.  
  1124.       while (ptr)
  1125.     {
  1126.       ptr->push_context ();
  1127.       ptr = ptr->next ();
  1128.     }
  1129.     }
  1130. }
  1131.  
  1132. void
  1133. symbol_table::pop_context (void)
  1134. {
  1135.   for (int i = 0; i < HASH_TABLE_SIZE; i++)
  1136.     {
  1137.       symbol_record *ptr = table[i].next ();
  1138.  
  1139.       while (ptr)
  1140.     {
  1141.       ptr->pop_context ();
  1142.       ptr = ptr->next ();
  1143.     }
  1144.     }
  1145. }
  1146.  
  1147. // Chris Torek's fave hash function.
  1148.  
  1149. unsigned int
  1150. symbol_table::hash (const char *str)
  1151. {
  1152.   unsigned h = 0;
  1153.   while (*str)
  1154.     h = h * 33 + *str++;
  1155.   return h;
  1156. }
  1157.  
  1158. /*
  1159. ;;; Local Variables: ***
  1160. ;;; mode: C++ ***
  1161. ;;; page-delimiter: "^/\\*" ***
  1162. ;;; End: ***
  1163. */
  1164.