comparison src/variables.cc @ 581:bc813f5eb025

[project @ 1994-08-07 01:02:15 by jwe]
author jwe
date Sun, 07 Aug 1994 01:02:15 +0000
parents 94fd73d1a0bc
children 4057f845c1ee
comparison
equal deleted inserted replaced
580:b0204e676508 581:bc813f5eb025
34 #include <string.h> 34 #include <string.h>
35 #include <fstream.h> 35 #include <fstream.h>
36 #include <iostream.h> 36 #include <iostream.h>
37 #include <strstream.h> 37 #include <strstream.h>
38 38
39 #include "statdefs.h" 39 #include "octave-hist.h"
40 #include "unwind-prot.h"
41 #include "user-prefs.h"
40 #include "tree-const.h" 42 #include "tree-const.h"
41 #include "variables.h" 43 #include "variables.h"
44 #include "statdefs.h"
45 #include "defaults.h"
46 #include "version.h"
42 #include "mappers.h" 47 #include "mappers.h"
43 #include "user-prefs.h" 48 #include "oct-obj.h"
44 #include "version.h" 49 #include "sysdep.h"
50 #include "dirfns.h"
45 #include "symtab.h" 51 #include "symtab.h"
46 #include "defaults.h" 52 #include "octave.h"
47 #include "dirfns.h" 53 #include "error.h"
48 #include "pager.h" 54 #include "pager.h"
49 #include "sysdep.h"
50 #include "octave.h"
51 #include "oct-obj.h"
52 #include "error.h"
53 #include "utils.h" 55 #include "utils.h"
56 #include "defun.h"
57 #include "input.h"
58 #include "parse.h"
54 #include "tree.h" 59 #include "tree.h"
55 #include "help.h" 60 #include "help.h"
56 #include "defun.h" 61 #include "lex.h"
57 62
58 extern "C" 63 extern "C"
59 { 64 {
65 #include <readline/readline.h>
60 #include <readline/tilde.h> 66 #include <readline/tilde.h>
61 67
62 #include "fnmatch.h" 68 #include "fnmatch.h"
63 } 69 }
64 70
65 // Symbol table for symbols at the top level. 71 // Symbol table for symbols at the top level.
66 symbol_table *top_level_sym_tab; 72 symbol_table *top_level_sym_tab = 0;
67 73
68 // Symbol table for the current scope. 74 // Symbol table for the current scope.
69 symbol_table *curr_sym_tab; 75 symbol_table *curr_sym_tab = 0;
70 76
71 // Symbol table for global symbols. 77 // Symbol table for global symbols.
72 symbol_table *global_sym_tab; 78 symbol_table *global_sym_tab = 0;
73 79
74 void 80 void
75 initialize_symbol_tables (void) 81 initialize_symbol_tables (void)
76 { 82 {
77 global_sym_tab = new symbol_table (); 83 if (! global_sym_tab)
78 84 global_sym_tab = new symbol_table ();
79 top_level_sym_tab = new symbol_table (); 85
86 if (! top_level_sym_tab)
87 top_level_sym_tab = new symbol_table ();
80 88
81 curr_sym_tab = top_level_sym_tab; 89 curr_sym_tab = top_level_sym_tab;
82 } 90 }
83 91
84 /* 92 // Is there a corresponding function file that is newer than the
85 * Is there a corresponding function file that is newer than the 93 // symbol definition?
86 * symbol definition? 94
87 */
88 int 95 int
89 symbol_out_of_date (symbol_record *sr) 96 symbol_out_of_date (symbol_record *sr)
90 { 97 {
91 int ignore = user_pref.ignore_function_time_stamp; 98 int ignore = user_pref.ignore_function_time_stamp;
92 99
109 return 1; 116 return 1;
110 } 117 }
111 } 118 }
112 } 119 }
113 return 0; 120 return 0;
121 }
122
123 static void
124 gobble_leading_white_space (FILE *ffile)
125 {
126 int in_comment = 0;
127 int c;
128 while ((c = getc (ffile)) != EOF)
129 {
130 if (in_comment)
131 {
132 if (c == '\n')
133 in_comment = 0;
134 }
135 else
136 {
137 if (c == ' ' || c == '\t' || c == '\n')
138 continue;
139 else if (c == '%' || c == '#')
140 in_comment = 1;
141 else
142 {
143 ungetc (c, ffile);
144 break;
145 }
146 }
147 }
148 }
149
150 static int
151 is_function_file (FILE *ffile)
152 {
153 int status = 0;
154
155 gobble_leading_white_space (ffile);
156
157 long pos = ftell (ffile);
158
159 char buf [10];
160 fgets (buf, 10, ffile);
161 int len = strlen (buf);
162 if (len > 8 && strncmp (buf, "function", 8) == 0
163 && ! (isalnum (buf[8]) || buf[8] == '_'))
164 status = 1;
165
166 fseek (ffile, pos, SEEK_SET);
167
168 return status;
169 }
170
171 static int
172 parse_fcn_file (int exec_script, char *ff)
173 {
174 begin_unwind_frame ("parse_fcn_file");
175
176 int script_file_executed = 0;
177
178 assert (ff);
179
180 // Open function file and parse.
181
182 int old_reading_fcn_file_state = reading_fcn_file;
183
184 unwind_protect_ptr (rl_instream);
185 unwind_protect_ptr (ff_instream);
186
187 unwind_protect_int (using_readline);
188 unwind_protect_int (input_line_number);
189 unwind_protect_int (current_input_column);
190 unwind_protect_int (reading_fcn_file);
191
192 using_readline = 0;
193 reading_fcn_file = 1;
194 input_line_number = 0;
195 current_input_column = 1;
196
197 FILE *ffile = get_input_from_file (ff, 0);
198
199 if (ffile)
200 {
201 // Check to see if this file defines a function or is just a list of
202 // commands.
203
204 if (is_function_file (ffile))
205 {
206 unwind_protect_int (echo_input);
207 unwind_protect_int (saving_history);
208 unwind_protect_int (reading_fcn_file);
209
210 echo_input = 0;
211 saving_history = 0;
212 reading_fcn_file = 1;
213
214 YY_BUFFER_STATE old_buf = current_buffer ();
215 YY_BUFFER_STATE new_buf = create_buffer (ffile);
216
217 add_unwind_protect (restore_input_buffer, (void *) old_buf);
218 add_unwind_protect (delete_input_buffer, (void *) new_buf);
219
220 switch_to_buffer (new_buf);
221
222 unwind_protect_ptr (curr_sym_tab);
223
224 reset_parser ();
225
226 int status = yyparse ();
227
228 if (status != 0)
229 {
230 error ("parse error while reading function file %s", ff);
231 global_sym_tab->clear (curr_fcn_file_name);
232 }
233 }
234 else if (exec_script)
235 {
236 // The value of `reading_fcn_file' will be restored to the proper value
237 // when we unwind from this frame.
238 reading_fcn_file = old_reading_fcn_file_state;
239
240 unwind_protect_int (reading_script_file);
241 reading_script_file = 1;
242
243 parse_and_execute (ffile, 1);
244
245 script_file_executed = 1;
246 }
247 fclose (ffile);
248 }
249
250 run_unwind_frame ("parse_fcn_file");
251
252 return script_file_executed;
253 }
254
255 int
256 load_fcn_from_file (symbol_record *sym_rec, int exec_script)
257 {
258 int script_file_executed = 0;
259
260 char *nm = sym_rec->name ();
261
262 curr_fcn_file_name = nm;
263
264 char *oct_file = oct_file_in_path (curr_fcn_file_name);
265
266 int loaded_oct_file = 0;
267
268 if (oct_file)
269 {
270 cerr << "found: " << oct_file << "\n";
271
272 delete [] oct_file;
273
274 // XXX FIXME XXX -- this is where we try to link to an external
275 // object...
276 loaded_oct_file = 1;
277 }
278
279 if (! loaded_oct_file)
280 {
281 char *ff = fcn_file_in_path (curr_fcn_file_name);
282
283 if (ff)
284 {
285 script_file_executed = parse_fcn_file (exec_script, ff);
286 delete [] ff;
287 }
288
289 if (! (error_state || script_file_executed))
290 force_link_to_function (nm);
291 }
292
293 return script_file_executed;
294 }
295
296 int
297 lookup (symbol_record *sym_rec, int exec_script)
298 {
299 int script_file_executed = 0;
300
301 if (! sym_rec->is_linked_to_global ())
302 {
303 if (sym_rec->is_defined ())
304 {
305 if (sym_rec->is_function () && symbol_out_of_date (sym_rec))
306 {
307 script_file_executed = load_fcn_from_file (sym_rec, exec_script);
308 }
309 }
310 else if (! sym_rec->is_formal_parameter ())
311 {
312 link_to_builtin_or_function (sym_rec);
313
314 if (! sym_rec->is_defined ())
315 {
316 script_file_executed = load_fcn_from_file (sym_rec, exec_script);
317 }
318 else if (sym_rec->is_function () && symbol_out_of_date (sym_rec))
319 {
320 script_file_executed = load_fcn_from_file (sym_rec, exec_script);
321 }
322 }
323 }
324
325 return script_file_executed;
326 }
327
328 // Get the symbol record for the given name that is visible in the
329 // current scope. Reread any function definitions that appear to be
330 // out of date. If a function is available in a file but is not
331 // currently loaded, this will load it and insert the name in the
332 // current symbol table.
333
334 symbol_record *
335 lookup_by_name (const char *nm, int exec_script)
336 {
337 symbol_record *sym_rec = curr_sym_tab->lookup (nm, 1, 0);
338
339 lookup (sym_rec, exec_script);
340
341 return sym_rec;
114 } 342 }
115 343
116 void 344 void
117 document_symbol (const char *name, const char *help) 345 document_symbol (const char *name, const char *help)
118 { 346 {
235 tmp = new tree_constant (nargout); 463 tmp = new tree_constant (nargout);
236 sr->define (tmp); 464 sr->define (tmp);
237 sr->protect (); 465 sr->protect ();
238 } 466 }
239 467
240 /* 468 // Give a global variable a definition. This will insert the symbol
241 * Give a global variable a definition. This will insert the symbol 469 // in the global table if necessary.
242 * in the global table if necessary. 470
243 */
244 void 471 void
245 bind_builtin_variable (const char *varname, tree_constant *val, 472 bind_builtin_variable (const char *varname, tree_constant *val,
246 int protect, int eternal, sv_Function sv_fcn, 473 int protect, int eternal, sv_Function sv_fcn,
247 const char *help) 474 const char *help)
248 { 475 {
272 499
273 if (help) 500 if (help)
274 sr->document (help); 501 sr->document (help);
275 } 502 }
276 503
277 /* 504 // Look for the given name in the global symbol table. If it refers
278 * Look for the given name in the global symbol table. If it refers 505 // to a string, return a new copy. If not, return 0;
279 * to a string, return a new copy. If not, return 0; 506
280 */
281 char * 507 char *
282 builtin_string_variable (const char *name) 508 builtin_string_variable (const char *name)
283 { 509 {
284 symbol_record *sr = global_sym_tab->lookup (name, 0, 0); 510 symbol_record *sr = global_sym_tab->lookup (name, 0, 0);
285 511
304 } 530 }
305 531
306 return retval; 532 return retval;
307 } 533 }
308 534
309 /* 535 // Look for the given name in the global symbol table. If it refers
310 * Look for the given name in the global symbol table. If it refers 536 // to a real scalar, place the value in d and return 0. Otherwise,
311 * to a real scalar, place the value in d and return 0. Otherwise, 537 // return -1.
312 * return -1. 538
313 */
314 int 539 int
315 builtin_real_scalar_variable (const char *name, double& d) 540 builtin_real_scalar_variable (const char *name, double& d)
316 { 541 {
317 int status = -1; 542 int status = -1;
318 symbol_record *sr = global_sym_tab->lookup (name, 0, 0); 543 symbol_record *sr = global_sym_tab->lookup (name, 0, 0);
336 } 561 }
337 562
338 return status; 563 return status;
339 } 564 }
340 565
341 /* 566 // Make the definition of the symbol record sr be the same as the
342 * Make the definition of the symbol record sr be the same as the 567 // definition of the global variable of the same name, creating it if
343 * definition of the global variable of the same name, creating it if 568 // it doesn't already exist.
344 * it doesn't already exist. 569
345 */
346 void 570 void
347 link_to_global_variable (symbol_record *sr) 571 link_to_global_variable (symbol_record *sr)
348 { 572 {
349 if (sr->is_linked_to_global ()) 573 if (sr->is_linked_to_global ())
350 return; 574 return;
380 604
381 sr->alias (gsr, 1); 605 sr->alias (gsr, 1);
382 sr->mark_as_linked_to_global (); 606 sr->mark_as_linked_to_global ();
383 } 607 }
384 608
385 /* 609 // Make the definition of the symbol record sr be the same as the
386 * Make the definition of the symbol record sr be the same as the 610 // definition of the builtin variable of the same name.
387 * definition of the builtin variable of the same name. 611
388 */
389 void 612 void
390 link_to_builtin_variable (symbol_record *sr) 613 link_to_builtin_variable (symbol_record *sr)
391 { 614 {
392 symbol_record *tmp_sym = global_sym_tab->lookup (sr->name (), 0, 0); 615 symbol_record *tmp_sym = global_sym_tab->lookup (sr->name (), 0, 0);
393 616
394 if (tmp_sym && tmp_sym->is_builtin_variable ()) 617 if (tmp_sym && tmp_sym->is_builtin_variable ())
395 sr->alias (tmp_sym); 618 sr->alias (tmp_sym);
396 } 619 }
397 620
398 /* 621 // Make the definition of the symbol record sr be the same as the
399 * Make the definition of the symbol record sr be the same as the 622 // definition of the builtin variable or function, or user function of
400 * definition of the builtin variable or function, or user function of 623 // the same name, provided that the name has not been used as a formal
401 * the same name, provided that the name has not been used as a formal 624 // parameter.
402 * parameter. 625
403 */
404 void 626 void
405 link_to_builtin_or_function (symbol_record *sr) 627 link_to_builtin_or_function (symbol_record *sr)
406 { 628 {
407 symbol_record *tmp_sym = global_sym_tab->lookup (sr->name (), 0, 0); 629 symbol_record *tmp_sym = global_sym_tab->lookup (sr->name (), 0, 0);
408 630
410 && (tmp_sym->is_builtin_variable () || tmp_sym->is_function ()) 632 && (tmp_sym->is_builtin_variable () || tmp_sym->is_function ())
411 && ! tmp_sym->is_formal_parameter ()) 633 && ! tmp_sym->is_formal_parameter ())
412 sr->alias (tmp_sym); 634 sr->alias (tmp_sym);
413 } 635 }
414 636
415 /* 637 // Force a link to a function in the current symbol table. This is
416 * Force a link to a function in the current symbol table. This is 638 // used just after defining a function to avoid different behavior
417 * used just after defining a function to avoid different behavior 639 // depending on whether or not the function has been evaluated after
418 * depending on whether or not the function has been evaluated after 640 // being defined.
419 * being defined. 641 //
420 * 642 // Return without doing anything if there isn't a function with the
421 * Return without doing anything if there isn't a function with the 643 // given name defined in the global symbol table.
422 * given name defined in the global symbol table. 644
423 */
424 void 645 void
425 force_link_to_function (const char *id_name) 646 force_link_to_function (const char *id_name)
426 { 647 {
427 symbol_record *gsr = global_sym_tab->lookup (id_name, 1, 0); 648 symbol_record *gsr = global_sym_tab->lookup (id_name, 1, 0);
428 if (gsr->is_function ()) 649 if (gsr->is_function ())
454 retval = (double) (sr && sr->is_linked_to_global ()); 675 retval = (double) (sr && sr->is_linked_to_global ());
455 676
456 return retval; 677 return retval;
457 } 678 }
458 679
459 /* 680 // Extract a keyword and its value from a file. Input should look
460 * Extract a keyword and its value from a file. Input should look 681 // something like:
461 * something like: 682 //
462 * 683 // #[ \t]*keyword[ \t]*:[ \t]*string-value\n
463 * #[ \t]*keyword[ \t]*:[ \t]*string-value\n 684 //
464 * 685 // Returns a pointer to new storage. The caller is responsible for
465 * Returns a pointer to new storage. The caller is responsible for 686 // deleting it.
466 * deleting it. 687
467 */
468 char * 688 char *
469 extract_keyword (istream& is, char *keyword) 689 extract_keyword (istream& is, char *keyword)
470 { 690 {
471 ostrstream buf; 691 ostrstream buf;
472 692
556 } 776 }
557 } 777 }
558 return status; 778 return status;
559 } 779 }
560 780
561 /* 781 // Skip trailing white space and
562 * Skip trailing white space and 782
563 */
564 void 783 void
565 skip_comments (istream& is) 784 skip_comments (istream& is)
566 { 785 {
567 char c = '\0'; 786 char c = '\0';
568 while (is.get (c)) 787 while (is.get (c))
581 else 800 else
582 break; 801 break;
583 } 802 }
584 } 803 }
585 804
586 /* 805 // Is `s' a valid identifier?
587 * Is `s' a valid identifier? 806
588 */
589 int 807 int
590 valid_identifier (char *s) 808 valid_identifier (char *s)
591 { 809 {
592 if (! s || ! (isalnum (*s) || *s == '_')) 810 if (! s || ! (isalnum (*s) || *s == '_'))
593 return 0; 811 return 0;
644 } 862 }
645 863
646 return retval; 864 return retval;
647 } 865 }
648 866
649 /* 867 // Is this variable a builtin?
650 * Is this variable a builtin? 868
651 */
652 int 869 int
653 is_builtin_variable (const char *name) 870 is_builtin_variable (const char *name)
654 { 871 {
655 symbol_record *sr = global_sym_tab->lookup (name, 0, 0); 872 symbol_record *sr = global_sym_tab->lookup (name, 0, 0);
656 return (sr && sr->is_builtin_variable ()); 873 return (sr && sr->is_builtin_variable ());
657 } 874 }
658 875
659 /* 876 // Is this tree_constant a valid function?
660 * Is this tree_constant a valid function? 877
661 */
662 tree_fvc * 878 tree_fvc *
663 is_valid_function (const tree_constant& arg, char *warn_for, int warn) 879 is_valid_function (const tree_constant& arg, char *warn_for, int warn)
664 { 880 {
665 tree_fvc *ans = 0; 881 tree_fvc *ans = 0;
666 882
673 889
674 char *fcn_name = arg.string_value (); 890 char *fcn_name = arg.string_value ();
675 symbol_record *sr = global_sym_tab->lookup (fcn_name, 0, 0); 891 symbol_record *sr = global_sym_tab->lookup (fcn_name, 0, 0);
676 892
677 if (sr && symbol_out_of_date (sr)) 893 if (sr && symbol_out_of_date (sr))
678 { 894 load_fcn_from_file (sr, 0);
679 tree_identifier tmp (sr);
680 tmp.load_fcn_from_file (0);
681 }
682 else 895 else
683 { 896 {
684 sr = global_sym_tab->lookup (fcn_name, 1, 0); 897 sr = global_sym_tab->lookup (fcn_name, 1, 0);
685 tree_identifier tmp (sr); 898 load_fcn_from_file (sr, 0);
686 tmp.load_fcn_from_file (0);
687 } 899 }
688 900
689 ans = sr->def (); 901 ans = sr->def ();
690 if (! ans || ! sr->is_function ()) 902 if (! ans || ! sr->is_function ())
691 { 903 {
696 } 908 }
697 909
698 return ans; 910 return ans;
699 } 911 }
700 912
701 /* 913 // Does this function take the right number of arguments?
702 * Does this function take the right number of arguments? 914
703 */
704 int 915 int
705 takes_correct_nargs (tree_fvc *fcn, int expected_nargin, char *warn_for, 916 takes_correct_nargs (tree_fvc *fcn, int expected_nargin, char *warn_for,
706 int warn) 917 int warn)
707 { 918 {
708 int nargin = fcn->max_expected_args () - 1; 919 int nargin = fcn->max_expected_args () - 1;
970 DEFVAR ("warn_divide_by_zero", SBV_warn_divide_by_zero, "true", 0, 0, 1181 DEFVAR ("warn_divide_by_zero", SBV_warn_divide_by_zero, "true", 0, 0,
971 1, warn_divide_by_zero, 1182 1, warn_divide_by_zero,
972 "on IEEE machines, allow divide by zero errors to be suppressed"); 1183 "on IEEE machines, allow divide by zero errors to be suppressed");
973 } 1184 }
974 1185
975 /* 1186 // List variable names.
976 * List variable names. 1187
977 */
978 static void 1188 static void
979 print_symbol_info_line (ostrstream& output_buf, const symbol_record_info& s) 1189 print_symbol_info_line (ostrstream& output_buf, const symbol_record_info& s)
980 { 1190 {
981 output_buf << (s.is_read_only () ? " -" : " w"); 1191 output_buf << (s.is_read_only () ? " -" : " w");
982 output_buf << (s.is_eternal () ? "- " : "d "); 1192 output_buf << (s.is_eternal () ? "- " : "d ");
1373 DELETE_ARGV; 1583 DELETE_ARGV;
1374 1584
1375 return retval; 1585 return retval;
1376 } 1586 }
1377 1587
1378 /* 1588 // Return nonzero if PATTERN has any special globbing chars in it.
1379 * Return nonzero if PATTERN has any special globbing chars in it. 1589
1380 */
1381 static int 1590 static int
1382 glob_pattern_p (char *pattern) 1591 glob_pattern_p (char *pattern)
1383 { 1592 {
1384 char *p = pattern; 1593 char *p = pattern;
1385 char c; 1594 char c;
1528 DELETE_ARGV; 1737 DELETE_ARGV;
1529 1738
1530 return retval; 1739 return retval;
1531 } 1740 }
1532 1741
1533 DEFUN_TEXT ("who", Fwho, Swho, -1, 1, 1742 static Octave_object
1534 "who [-all] [-builtins] [-functions] [-long] [-variables]\n\ 1743 do_who (int argc, char **argv, int nargout)
1535 \n\
1536 List currently defined symbol(s). Options may be shortened to one\n\
1537 character, but may not be combined.")
1538 { 1744 {
1539 Octave_object retval; 1745 Octave_object retval;
1540
1541 DEFINE_ARGV("who");
1542 1746
1543 int show_builtins = 0; 1747 int show_builtins = 0;
1544 int show_functions = (curr_sym_tab == top_level_sym_tab); 1748 int show_functions = (curr_sym_tab == top_level_sym_tab);
1545 int show_variables = 1; 1749 int show_variables = 1;
1546 int show_verbose = 0; 1750 int show_verbose = 0;
1626 output_buf << "\n"; 1830 output_buf << "\n";
1627 1831
1628 output_buf << ends; 1832 output_buf << ends;
1629 maybe_page_output (output_buf); 1833 maybe_page_output (output_buf);
1630 1834
1835 return retval;
1836 }
1837
1838 DEFUN_TEXT ("who", Fwho, Swho, -1, 1,
1839 "who [-all] [-builtins] [-functions] [-long] [-variables]\n\
1840 \n\
1841 List currently defined symbol(s). Options may be shortened to one\n\
1842 character, but may not be combined.")
1843 {
1844 Octave_object retval;
1845
1846 DEFINE_ARGV("who");
1847
1848 retval = do_who (argc, argv, nargout);
1849
1631 DELETE_ARGV; 1850 DELETE_ARGV;
1851
1852 return retval;
1853 }
1854
1855 DEFUN_TEXT ("whos", Fwhos, Swhos, -1, 1,
1856 "whos [-all] [-builtins] [-functions] [-long] [-variables]\n\
1857 \n\
1858 List currently defined symbol(s). Options may be shortened to one\n\
1859 character, but may not be combined.")
1860 {
1861 Octave_object retval;
1862
1863 Octave_object tmp_args = args;
1864 tmp_args(args.length ()) = "-long";
1865
1866 int argc = tmp_args.length ();
1867 char **argv = make_argv (tmp_args, "whos");
1868
1869 if (error_state)
1870 return retval;
1871
1872 retval = do_who (argc, argv, nargout);
1873
1874 while (--argc >= 0)
1875 delete [] argv[argc];
1876 delete [] argv;
1632 1877
1633 return retval; 1878 return retval;
1634 } 1879 }
1635 1880
1636 // XXX FIXME XXX -- should these really be here? 1881 // XXX FIXME XXX -- should these really be here?
1683 oi = strconcat (oh, "/info/"); 1928 oi = strconcat (oh, "/info/");
1684 return oi; 1929 return oi;
1685 #endif 1930 #endif
1686 } 1931 }
1687 1932
1688 /* 1933 // Handle OCTAVE_PATH from the environment like TeX handles TEXINPUTS.
1689 * Handle OCTAVE_PATH from the environment like TeX handles TEXINPUTS. 1934 // If the path starts with `:', prepend the standard path. If it ends
1690 * If the path starts with `:', prepend the standard path. If it ends 1935 // with `:' append the standard path. If it begins and ends with
1691 * with `:' append the standard path. If it begins and ends with 1936 // `:', do both (which is useless, but the luser asked for it...).
1692 * `:', do both (which is useless, but the luser asked for it...). 1937 //
1693 * 1938 // This function may eventually be called more than once, so be
1694 * This function may eventually be called more than once, so be 1939 // careful not to create memory leaks.
1695 * careful not to create memory leaks. 1940
1696 */
1697 char * 1941 char *
1698 default_path (void) 1942 default_path (void)
1699 { 1943 {
1700 static char *pathstring = 0; 1944 static char *pathstring = 0;
1701 delete [] pathstring; 1945 delete [] pathstring;