Mercurial > hg > octave-nkf
comparison libinterp/parse-tree/oct-parse.in.yy @ 16203:127cccb037bf
move more global parser and lexer variables to classes
* pt-check.h, pt-check.cc (tree_checker::file_name): New data member.
(tree_checker::gripe): Use it instead of curr_fcn_file_name.
* input.h, input.cc, octave.cc (input_from_command_line_file):
Delete global variable and all uses.
* parse.h, oct-parse.in.yy (input_from_startup_file): Delete global
variable and all uses.
* input.h, input.cc, lex.h, lex.ll (curr_fcn_file_name,
curr_fcn_file_full_name): Declare as members of lexical_feedback
class. Rename to fcn_file_name and fcn_file_full_name. Change all
uses.
* oct-parse.in.yy (parse_fcn_file): New arg, file. Set
curr_lexer->fcn_file_name and curr_lexer->fcn_file_full_name here.
(load_fcn_from_file): Pass short file name to parse_fcn_file.
* octave.cc (execute_command_line_file): Not here.
* lex.h, lex.ll (lexical_feedback::force_script): New data member.
* oct-parse.in.yy (parse_fcn_file): Set it here.
* lex.h, lex.ll (lexical_feedback::input_from_terminal,
lexical_feedback::input_from_file): New functions.
* lex.ll (octave_lexer::handle_keyword): Set reading_fcn_file,
reading_classdef_file, and reading_script_file.
* lex.h, lex.ll (lexical_feedback::token_count): New variable.
(COUNT_TOK_AND_RETURN): Increment it here. Don't count '\n' as a
token.
* lex.h, lex.ll (lexical_feedback::help_text):
New variable.
* parse.h, parse.in.yy (help_buf): Delete global variable and all uses.
(octave_parser::frob_function, octave_parser::make_script): Use help_text.
* lex.ll (octave_lexer::process_comment): Cache doc string directly in
help_text variable.
(looks_like_copyright): Move here from parse.in.yy.
* lex.h, lex.ll (octave_lexer::prep_for_file): New function.
(octave_lexer::prep_for_function_file,
octave_lexer::prep_for_script_file): Delete.
* parse.in.yy (INPUT_FILE_BEGIN): New start state. Delete
SCRIPT_FILE_BEGIN and FCN_FILE_BEGIN. Tentatively set
curr_lexer->reading_script_file to true.
(parse_fcn_file): Call curr_lexer->prep_for_file.
Don't call gobble_leading_whitespace. Don't attempt to determine
function script, or classdef file status here.
* parse.in.yy (INPUT_FILE): New token.
(SCRIPT_FILE, FUNCTION_FILE): Delete.
* lex.ll (octave_lexer::display_token): Update.
* parse.in.yy (nl, opt_nl): New non-terminals.
(function_file): Delete rule.
(file): Rename from script_file. Allow opt_nl before opt_list.
Don't make script if reading fcn file.
* parse.in.yy (text_getc, class stdio_stream_reader, skip_white_space,
looking_at_classdef_keyword, gobble_leading_white_space,
looking_at_function_keyword): Delete.
(get_help_from_file): Parse file to get help instead of calling
gobble_leading_white_space
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 06 Mar 2013 14:36:19 -0500 |
parents | 810a71122c25 |
children | a8f9eb92fa6e 0467d68ca891 |
comparison
equal
deleted
inserted
replaced
16202:7ce484126bb2 | 16203:127cccb037bf |
---|---|
93 #define fclose GNULIB_NAMESPACE::fclose | 93 #define fclose GNULIB_NAMESPACE::fclose |
94 #define fprintf GNULIB_NAMESPACE::fprintf | 94 #define fprintf GNULIB_NAMESPACE::fprintf |
95 #define malloc GNULIB_NAMESPACE::malloc | 95 #define malloc GNULIB_NAMESPACE::malloc |
96 #endif | 96 #endif |
97 | 97 |
98 // Buffer for help text snagged from function files. | |
99 std::stack<std::string> help_buf; | |
100 | |
101 // TRUE means we are using readline. | 98 // TRUE means we are using readline. |
102 // (--no-line-editing) | 99 // (--no-line-editing) |
103 bool line_editing = true; | 100 bool line_editing = true; |
104 | 101 |
105 // TRUE means we printed messages about reading startup files. | 102 // TRUE means we printed messages about reading startup files. |
106 bool reading_startup_message_printed = false; | 103 bool reading_startup_message_printed = false; |
107 | |
108 // TRUE means input is coming from startup file. | |
109 bool input_from_startup_file = false; | |
110 | 104 |
111 // Keep track of symbol table information when parsing functions. | 105 // Keep track of symbol table information when parsing functions. |
112 symtab_context parser_symtab_context; | 106 symtab_context parser_symtab_context; |
113 | 107 |
114 // List of autoloads (function -> file mapping). | 108 // List of autoloads (function -> file mapping). |
236 %token <tok_val> SUPERCLASSREF | 230 %token <tok_val> SUPERCLASSREF |
237 %token <tok_val> GET SET | 231 %token <tok_val> GET SET |
238 | 232 |
239 // Other tokens. | 233 // Other tokens. |
240 %token END_OF_INPUT LEXICAL_ERROR | 234 %token END_OF_INPUT LEXICAL_ERROR |
241 %token FCN SCRIPT_FILE FUNCTION_FILE CLASSDEF | 235 %token FCN INPUT_FILE CLASSDEF |
242 // %token VARARGIN VARARGOUT | 236 // %token VARARGIN VARARGOUT |
243 %token CLOSE_BRACE | 237 %token CLOSE_BRACE |
244 | 238 |
245 // Nonterminals we construct. | 239 // Nonterminals we construct. |
246 %type <comment_type> stash_comment function_beg classdef_beg | 240 %type <comment_type> stash_comment function_beg classdef_beg |
247 %type <comment_type> properties_beg methods_beg events_beg enum_beg | 241 %type <comment_type> properties_beg methods_beg events_beg enum_beg |
248 %type <sep_type> sep_no_nl opt_sep_no_nl sep opt_sep opt_comma | 242 %type <sep_type> sep_no_nl opt_sep_no_nl nl opt_nl sep opt_sep opt_comma |
249 %type <tree_type> input | 243 %type <tree_type> input |
250 %type <tree_constant_type> string constant magic_colon | 244 %type <tree_constant_type> string constant magic_colon |
251 %type <tree_anon_fcn_handle_type> anon_fcn_handle | 245 %type <tree_anon_fcn_handle_type> anon_fcn_handle |
252 %type <tree_fcn_handle_type> fcn_handle | 246 %type <tree_fcn_handle_type> fcn_handle |
253 %type <tree_matrix_type> matrix_rows matrix_rows1 | 247 %type <tree_matrix_type> matrix_rows matrix_rows1 |
265 %type <tree_parameter_list_type> param_list param_list1 param_list2 | 259 %type <tree_parameter_list_type> param_list param_list1 param_list2 |
266 %type <tree_parameter_list_type> return_list return_list1 | 260 %type <tree_parameter_list_type> return_list return_list1 |
267 %type <tree_parameter_list_type> superclasses opt_superclasses | 261 %type <tree_parameter_list_type> superclasses opt_superclasses |
268 %type <tree_command_type> command select_command loop_command | 262 %type <tree_command_type> command select_command loop_command |
269 %type <tree_command_type> jump_command except_command function | 263 %type <tree_command_type> jump_command except_command function |
270 %type <tree_command_type> script_file classdef | 264 %type <tree_command_type> file classdef |
271 %type <tree_command_type> function_file function_list | |
272 %type <tree_if_command_type> if_command | 265 %type <tree_if_command_type> if_command |
273 %type <tree_if_clause_type> elseif_clause else_clause | 266 %type <tree_if_clause_type> elseif_clause else_clause |
274 %type <tree_if_command_list_type> if_cmd_list1 if_cmd_list | 267 %type <tree_if_command_list_type> if_cmd_list1 if_cmd_list |
275 %type <tree_switch_command_type> switch_command | 268 %type <tree_switch_command_type> switch_command |
276 %type <tree_switch_case_type> switch_case default_case | 269 %type <tree_switch_case_type> switch_case default_case |
327 { | 320 { |
328 curr_parser.stmt_list = $1; | 321 curr_parser.stmt_list = $1; |
329 promptflag = 1; | 322 promptflag = 1; |
330 YYACCEPT; | 323 YYACCEPT; |
331 } | 324 } |
332 | function_file | |
333 { YYACCEPT; } | |
334 | simple_list parse_error | 325 | simple_list parse_error |
335 { ABORT_PARSE; } | 326 { ABORT_PARSE; } |
336 | parse_error | 327 | parse_error |
337 { ABORT_PARSE; } | 328 { ABORT_PARSE; } |
338 ; | 329 ; |
759 { $$ = $1; } | 750 { $$ = $1; } |
760 | except_command | 751 | except_command |
761 { $$ = $1; } | 752 { $$ = $1; } |
762 | function | 753 | function |
763 { $$ = $1; } | 754 { $$ = $1; } |
764 | script_file | 755 | file |
765 { $$ = $1; } | 756 { $$ = $1; } |
766 | classdef | 757 | classdef |
767 { $$ = $1; } | 758 { $$ = $1; } |
768 ; | 759 ; |
769 | 760 |
842 } | 833 } |
843 ; | 834 ; |
844 | 835 |
845 if_cmd_list1 : expression opt_sep opt_list | 836 if_cmd_list1 : expression opt_sep opt_list |
846 { | 837 { |
847 $1->mark_braindead_shortcircuit (curr_fcn_file_full_name); | 838 $1->mark_braindead_shortcircuit (curr_lexer->fcn_file_full_name); |
848 | 839 |
849 $$ = curr_parser.start_if_command ($1, $3); | 840 $$ = curr_parser.start_if_command ($1, $3); |
850 } | 841 } |
851 | if_cmd_list1 elseif_clause | 842 | if_cmd_list1 elseif_clause |
852 { | 843 { |
855 } | 846 } |
856 ; | 847 ; |
857 | 848 |
858 elseif_clause : ELSEIF stash_comment opt_sep expression opt_sep opt_list | 849 elseif_clause : ELSEIF stash_comment opt_sep expression opt_sep opt_list |
859 { | 850 { |
860 $4->mark_braindead_shortcircuit (curr_fcn_file_full_name); | 851 $4->mark_braindead_shortcircuit (curr_lexer->fcn_file_full_name); |
861 | 852 |
862 $$ = curr_parser.make_elseif_clause ($1, $4, $6, $2); | 853 $$ = curr_parser.make_elseif_clause ($1, $4, $6, $2); |
863 } | 854 } |
864 ; | 855 ; |
865 | 856 |
914 // Looping | 905 // Looping |
915 // ======= | 906 // ======= |
916 | 907 |
917 loop_command : WHILE stash_comment expression opt_sep opt_list END | 908 loop_command : WHILE stash_comment expression opt_sep opt_list END |
918 { | 909 { |
919 $3->mark_braindead_shortcircuit (curr_fcn_file_full_name); | 910 $3->mark_braindead_shortcircuit (curr_lexer->fcn_file_full_name); |
920 | 911 |
921 if (! ($$ = curr_parser.make_while_command ($1, $3, $5, $6, $2))) | 912 if (! ($$ = curr_parser.make_while_command ($1, $3, $5, $6, $2))) |
922 ABORT_PARSE; | 913 ABORT_PARSE; |
923 } | 914 } |
924 | DO stash_comment opt_sep opt_list UNTIL expression | 915 | DO stash_comment opt_sep opt_list UNTIL expression |
1011 | 1002 |
1012 symbol_table::set_scope (symbol_table::alloc_scope ()); | 1003 symbol_table::set_scope (symbol_table::alloc_scope ()); |
1013 | 1004 |
1014 curr_parser.function_scopes.push_back (symbol_table::current_scope ()); | 1005 curr_parser.function_scopes.push_back (symbol_table::current_scope ()); |
1015 | 1006 |
1016 if (! curr_lexer->reading_script_file && curr_parser.curr_fcn_depth == 1 | 1007 if (! curr_lexer->reading_script_file |
1008 && curr_parser.curr_fcn_depth == 1 | |
1017 && ! curr_parser.parsing_subfunctions) | 1009 && ! curr_parser.parsing_subfunctions) |
1018 curr_parser.primary_fcn_scope = symbol_table::current_scope (); | 1010 curr_parser.primary_fcn_scope = symbol_table::current_scope (); |
1019 | 1011 |
1020 if (curr_lexer->reading_script_file && curr_parser.curr_fcn_depth > 1) | 1012 if (curr_lexer->reading_script_file |
1013 && curr_parser.curr_fcn_depth > 1) | |
1021 curr_parser.bison_error ("nested functions not implemented in this context"); | 1014 curr_parser.bison_error ("nested functions not implemented in this context"); |
1022 } | 1015 } |
1023 ; | 1016 ; |
1024 | 1017 |
1025 // =========================== | 1018 // =========================== |
1115 $1->append (new tree_decl_elt ($3)); | 1108 $1->append (new tree_decl_elt ($3)); |
1116 $$ = $1; | 1109 $$ = $1; |
1117 } | 1110 } |
1118 ; | 1111 ; |
1119 | 1112 |
1120 // =========== | 1113 // ======================= |
1121 // Script file | 1114 // Script or function file |
1122 // =========== | 1115 // ======================= |
1123 | 1116 |
1124 script_file : SCRIPT_FILE opt_list END_OF_INPUT | 1117 file : INPUT_FILE opt_nl opt_list END_OF_INPUT |
1125 { | 1118 { |
1126 tree_statement *end_of_script | 1119 if (! curr_lexer->reading_fcn_file) |
1127 = curr_parser.make_end ("endscript", | 1120 { |
1128 curr_lexer->input_line_number, | 1121 tree_statement *end_of_script |
1129 curr_lexer->current_input_column); | 1122 = curr_parser.make_end ("endscript", |
1130 | 1123 curr_lexer->input_line_number, |
1131 curr_parser.make_script ($2, end_of_script); | 1124 curr_lexer->current_input_column); |
1125 | |
1126 curr_parser.make_script ($3, end_of_script); | |
1127 } | |
1132 | 1128 |
1133 $$ = 0; | 1129 $$ = 0; |
1134 } | 1130 } |
1135 ; | |
1136 | |
1137 // ============= | |
1138 // Function file | |
1139 // ============= | |
1140 | |
1141 function_file : FUNCTION_FILE function_list opt_sep END_OF_INPUT | |
1142 { $$ = 0; } | |
1143 ; | |
1144 | |
1145 function_list : function | |
1146 | function_list sep function | |
1147 ; | 1131 ; |
1148 | 1132 |
1149 // =================== | 1133 // =================== |
1150 // Function definition | 1134 // Function definition |
1151 // =================== | 1135 // =================== |
1152 | 1136 |
1153 function_beg : push_fcn_symtab FCN stash_comment | 1137 function_beg : push_fcn_symtab FCN stash_comment |
1154 { | 1138 { |
1155 $$ = $3; | 1139 $$ = $3; |
1156 | 1140 if (curr_lexer->reading_classdef_file |
1157 if (curr_lexer->reading_classdef_file || curr_lexer->parsing_classdef) | 1141 || curr_lexer->parsing_classdef) |
1158 curr_lexer->maybe_classdef_get_set_method = true; | 1142 curr_lexer->maybe_classdef_get_set_method = true; |
1159 } | 1143 } |
1160 ; | 1144 ; |
1161 | 1145 |
1162 function : function_beg function1 | 1146 function : function_beg function1 |
1436 ; | 1420 ; |
1437 | 1421 |
1438 opt_sep_no_nl : // empty | 1422 opt_sep_no_nl : // empty |
1439 { $$ = 0; } | 1423 { $$ = 0; } |
1440 | sep_no_nl | 1424 | sep_no_nl |
1425 { $$ = $1; } | |
1426 ; | |
1427 | |
1428 opt_nl : // empty | |
1429 { $$ = 0; } | |
1430 | nl | |
1431 { $$ = $1; } | |
1432 ; | |
1433 | |
1434 nl : '\n' | |
1435 { $$ = '\n'; } | |
1436 | nl '\n' | |
1441 { $$ = $1; } | 1437 { $$ = $1; } |
1442 ; | 1438 ; |
1443 | 1439 |
1444 sep : ',' | 1440 sep : ',' |
1445 { $$ = ','; } | 1441 { $$ = ','; } |
1665 octave_parser::maybe_warn_assign_as_truth_value (tree_expression *expr) | 1661 octave_parser::maybe_warn_assign_as_truth_value (tree_expression *expr) |
1666 { | 1662 { |
1667 if (expr->is_assignment_expression () | 1663 if (expr->is_assignment_expression () |
1668 && expr->paren_count () < 2) | 1664 && expr->paren_count () < 2) |
1669 { | 1665 { |
1670 if (curr_fcn_file_full_name.empty ()) | 1666 if (curr_lexer->fcn_file_full_name.empty ()) |
1671 warning_with_id | 1667 warning_with_id |
1672 ("Octave:assign-as-truth-value", | 1668 ("Octave:assign-as-truth-value", |
1673 "suggest parenthesis around assignment used as truth value"); | 1669 "suggest parenthesis around assignment used as truth value"); |
1674 else | 1670 else |
1675 warning_with_id | 1671 warning_with_id |
1676 ("Octave:assign-as-truth-value", | 1672 ("Octave:assign-as-truth-value", |
1677 "suggest parenthesis around assignment used as truth value near line %d, column %d in file '%s'", | 1673 "suggest parenthesis around assignment used as truth value near line %d, column %d in file '%s'", |
1678 expr->line (), expr->column (), curr_fcn_file_full_name.c_str ()); | 1674 expr->line (), expr->column (), curr_lexer->fcn_file_full_name.c_str ()); |
1679 } | 1675 } |
1680 } | 1676 } |
1681 | 1677 |
1682 // Maybe print a warning about switch labels that aren't constants. | 1678 // Maybe print a warning about switch labels that aren't constants. |
1683 | 1679 |
1684 void | 1680 void |
1685 octave_parser::maybe_warn_variable_switch_label (tree_expression *expr) | 1681 octave_parser::maybe_warn_variable_switch_label (tree_expression *expr) |
1686 { | 1682 { |
1687 if (! expr->is_constant ()) | 1683 if (! expr->is_constant ()) |
1688 { | 1684 { |
1689 if (curr_fcn_file_full_name.empty ()) | 1685 if (curr_lexer->fcn_file_full_name.empty ()) |
1690 warning_with_id ("Octave:variable-switch-label", | 1686 warning_with_id ("Octave:variable-switch-label", |
1691 "variable switch label"); | 1687 "variable switch label"); |
1692 else | 1688 else |
1693 warning_with_id | 1689 warning_with_id |
1694 ("Octave:variable-switch-label", | 1690 ("Octave:variable-switch-label", |
1695 "variable switch label near line %d, column %d in file '%s'", | 1691 "variable switch label near line %d, column %d in file '%s'", |
1696 expr->line (), expr->column (), curr_fcn_file_full_name.c_str ()); | 1692 expr->line (), expr->column (), curr_lexer->fcn_file_full_name.c_str ()); |
1697 } | 1693 } |
1698 } | 1694 } |
1699 | 1695 |
1700 static tree_expression * | 1696 static tree_expression * |
1701 fold (tree_binary_expression *e) | 1697 fold (tree_binary_expression *e) |
1953 | 1949 |
1954 tree_anon_fcn_handle *retval | 1950 tree_anon_fcn_handle *retval |
1955 = new tree_anon_fcn_handle (param_list, ret_list, body, fcn_scope, l, c); | 1951 = new tree_anon_fcn_handle (param_list, ret_list, body, fcn_scope, l, c); |
1956 // FIXME: Stash the filename. This does not work and produces | 1952 // FIXME: Stash the filename. This does not work and produces |
1957 // errors when executed. | 1953 // errors when executed. |
1958 //retval->stash_file_name (curr_fcn_file_name); | 1954 //retval->stash_file_name (curr_lexer->fcn_file_name); |
1959 | 1955 |
1960 return retval; | 1956 return retval; |
1961 } | 1957 } |
1962 | 1958 |
1963 // Build a binary expression. | 1959 // Build a binary expression. |
2577 | 2573 |
2578 void | 2574 void |
2579 octave_parser::make_script (tree_statement_list *cmds, | 2575 octave_parser::make_script (tree_statement_list *cmds, |
2580 tree_statement *end_script) | 2576 tree_statement *end_script) |
2581 { | 2577 { |
2582 std::string doc_string; | |
2583 | |
2584 if (! help_buf.empty ()) | |
2585 { | |
2586 doc_string = help_buf.top (); | |
2587 help_buf.pop (); | |
2588 } | |
2589 | |
2590 if (! cmds) | 2578 if (! cmds) |
2591 cmds = new tree_statement_list (); | 2579 cmds = new tree_statement_list (); |
2592 | 2580 |
2593 cmds->append (end_script); | 2581 cmds->append (end_script); |
2594 | 2582 |
2595 octave_user_script *script | 2583 octave_user_script *script |
2596 = new octave_user_script (curr_fcn_file_full_name, curr_fcn_file_name, | 2584 = new octave_user_script (curr_lexer->fcn_file_full_name, |
2597 cmds, doc_string); | 2585 curr_lexer->fcn_file_name, |
2586 cmds, curr_lexer->help_text); | |
2587 | |
2588 curr_lexer->help_text = ""; | |
2598 | 2589 |
2599 octave_time now; | 2590 octave_time now; |
2600 | 2591 |
2601 script->stash_fcn_file_time (now); | 2592 script->stash_fcn_file_time (now); |
2602 | 2593 |
2655 // file. Matlab doesn't provide a diagnostic (it ignores the stated | 2646 // file. Matlab doesn't provide a diagnostic (it ignores the stated |
2656 // name). | 2647 // name). |
2657 if (! autoloading && curr_lexer->reading_fcn_file | 2648 if (! autoloading && curr_lexer->reading_fcn_file |
2658 && curr_fcn_depth == 1 && ! parsing_subfunctions) | 2649 && curr_fcn_depth == 1 && ! parsing_subfunctions) |
2659 { | 2650 { |
2660 // FIXME -- should curr_fcn_file_name already be | 2651 // FIXME -- should curr_lexer->fcn_file_name already be |
2661 // preprocessed when we get here? It seems to only be a | 2652 // preprocessed when we get here? It seems to only be a |
2662 // problem with relative file names. | 2653 // problem with relative file names. |
2663 | 2654 |
2664 std::string nm = curr_fcn_file_name; | 2655 std::string nm = curr_lexer->fcn_file_name; |
2665 | 2656 |
2666 size_t pos = nm.find_last_of (file_ops::dir_sep_chars ()); | 2657 size_t pos = nm.find_last_of (file_ops::dir_sep_chars ()); |
2667 | 2658 |
2668 if (pos != std::string::npos) | 2659 if (pos != std::string::npos) |
2669 nm = curr_fcn_file_name.substr (pos+1); | 2660 nm = curr_lexer->fcn_file_name.substr (pos+1); |
2670 | 2661 |
2671 if (nm != id_name) | 2662 if (nm != id_name) |
2672 { | 2663 { |
2673 warning_with_id | 2664 warning_with_id |
2674 ("Octave:function-name-clash", | 2665 ("Octave:function-name-clash", |
2675 "function name '%s' does not agree with function file name '%s'", | 2666 "function name '%s' does not agree with function file name '%s'", |
2676 id_name.c_str (), curr_fcn_file_full_name.c_str ()); | 2667 id_name.c_str (), curr_lexer->fcn_file_full_name.c_str ()); |
2677 | 2668 |
2678 id_name = nm; | 2669 id_name = nm; |
2679 } | 2670 } |
2680 } | 2671 } |
2681 | 2672 |
2682 if (curr_lexer->reading_fcn_file || curr_lexer->reading_classdef_file || autoloading) | 2673 if (curr_lexer->reading_fcn_file || curr_lexer->reading_classdef_file || autoloading) |
2683 { | 2674 { |
2684 octave_time now; | 2675 octave_time now; |
2685 | 2676 |
2686 fcn->stash_fcn_file_name (curr_fcn_file_full_name); | 2677 fcn->stash_fcn_file_name (curr_lexer->fcn_file_full_name); |
2687 fcn->stash_fcn_file_time (now); | 2678 fcn->stash_fcn_file_time (now); |
2688 fcn->mark_as_system_fcn_file (); | 2679 fcn->mark_as_system_fcn_file (); |
2689 | 2680 |
2690 if (fcn_file_from_relative_lookup) | 2681 if (fcn_file_from_relative_lookup) |
2691 fcn->mark_relative (); | 2682 fcn->mark_relative (); |
2692 | 2683 |
2693 if (curr_fcn_depth > 1 || parsing_subfunctions) | 2684 if (curr_fcn_depth > 1 || parsing_subfunctions) |
2694 { | 2685 { |
2695 fcn->stash_parent_fcn_name (curr_fcn_file_name); | 2686 fcn->stash_parent_fcn_name (curr_lexer->fcn_file_name); |
2696 | 2687 |
2697 if (curr_fcn_depth > 1) | 2688 if (curr_fcn_depth > 1) |
2698 fcn->stash_parent_fcn_scope (function_scopes[function_scopes.size ()-2]); | 2689 fcn->stash_parent_fcn_scope (function_scopes[function_scopes.size ()-2]); |
2699 else | 2690 else |
2700 fcn->stash_parent_fcn_scope (primary_fcn_scope); | 2691 fcn->stash_parent_fcn_scope (primary_fcn_scope); |
2716 | 2707 |
2717 if (fs && fs.is_newer (now)) | 2708 if (fs && fs.is_newer (now)) |
2718 warning_with_id ("Octave:future-time-stamp", | 2709 warning_with_id ("Octave:future-time-stamp", |
2719 "time stamp for '%s' is in the future", nm.c_str ()); | 2710 "time stamp for '%s' is in the future", nm.c_str ()); |
2720 } | 2711 } |
2721 else if (! (input_from_tmp_history_file || input_from_startup_file) | 2712 else if (! input_from_tmp_history_file |
2713 && ! curr_lexer->force_script | |
2722 && curr_lexer->reading_script_file | 2714 && curr_lexer->reading_script_file |
2723 && curr_fcn_file_name == id_name) | 2715 && curr_lexer->fcn_file_name == id_name) |
2724 { | 2716 { |
2725 warning ("function '%s' defined within script file '%s'", | 2717 warning ("function '%s' defined within script file '%s'", |
2726 id_name.c_str (), curr_fcn_file_full_name.c_str ()); | 2718 id_name.c_str (), curr_lexer->fcn_file_full_name.c_str ()); |
2727 } | 2719 } |
2728 | 2720 |
2729 fcn->stash_function_name (id_name); | 2721 fcn->stash_function_name (id_name); |
2730 fcn->stash_fcn_location (curr_lexer->input_line_number, | 2722 fcn->stash_fcn_location (curr_lexer->input_line_number, |
2731 curr_lexer->current_input_column); | 2723 curr_lexer->current_input_column); |
2732 | 2724 |
2733 if (! help_buf.empty () && curr_fcn_depth == 1 | 2725 if (! curr_lexer->help_text.empty () && curr_fcn_depth == 1 |
2734 && ! parsing_subfunctions) | 2726 && ! parsing_subfunctions) |
2735 { | 2727 { |
2736 fcn->document (help_buf.top ()); | 2728 fcn->document (curr_lexer->help_text); |
2737 | 2729 |
2738 help_buf.pop (); | 2730 curr_lexer->help_text = ""; |
2739 } | 2731 } |
2740 | 2732 |
2741 if (curr_lexer->reading_fcn_file && curr_fcn_depth == 1 | 2733 if (curr_lexer->reading_fcn_file && curr_fcn_depth == 1 |
2742 && ! parsing_subfunctions) | 2734 && ! parsing_subfunctions) |
2743 primary_fcn_ptr = fcn; | 2735 primary_fcn_ptr = fcn; |
2945 retval = new tree_persistent_command (lst, l, c); | 2937 retval = new tree_persistent_command (lst, l, c); |
2946 else | 2938 else |
2947 { | 2939 { |
2948 if (curr_lexer->reading_script_file) | 2940 if (curr_lexer->reading_script_file) |
2949 warning ("ignoring persistent declaration near line %d of file '%s'", | 2941 warning ("ignoring persistent declaration near line %d of file '%s'", |
2950 l, curr_fcn_file_full_name.c_str ()); | 2942 l, curr_lexer->fcn_file_full_name.c_str ()); |
2951 else | 2943 else |
2952 warning ("ignoring persistent declaration near line %d", l); | 2944 warning ("ignoring persistent declaration near line %d", l); |
2953 } | 2945 } |
2954 break; | 2946 break; |
2955 | 2947 |
3030 | 3022 |
3031 if (tmp->is_expression ()) | 3023 if (tmp->is_expression ()) |
3032 warning_with_id | 3024 warning_with_id |
3033 ("Octave:missing-semicolon", | 3025 ("Octave:missing-semicolon", |
3034 "missing semicolon near line %d, column %d in file '%s'", | 3026 "missing semicolon near line %d, column %d in file '%s'", |
3035 tmp->line (), tmp->column (), curr_fcn_file_full_name.c_str ()); | 3027 tmp->line (), tmp->column (), curr_lexer->fcn_file_full_name.c_str ()); |
3036 } | 3028 } |
3037 } | 3029 } |
3038 | 3030 |
3039 tree_statement_list * | 3031 tree_statement_list * |
3040 octave_parser::set_stmt_print_flag (tree_statement_list *list, char sep, | 3032 octave_parser::set_stmt_print_flag (tree_statement_list *list, char sep, |
3098 | 3090 |
3099 std::ostringstream output_buf; | 3091 std::ostringstream output_buf; |
3100 | 3092 |
3101 if (curr_lexer->reading_fcn_file || curr_lexer->reading_script_file || curr_lexer->reading_classdef_file) | 3093 if (curr_lexer->reading_fcn_file || curr_lexer->reading_script_file || curr_lexer->reading_classdef_file) |
3102 output_buf << "parse error near line " << curr_lexer->input_line_number | 3094 output_buf << "parse error near line " << curr_lexer->input_line_number |
3103 << " of file " << curr_fcn_file_full_name; | 3095 << " of file " << curr_lexer->fcn_file_full_name; |
3104 else | 3096 else |
3105 output_buf << "parse error:"; | 3097 output_buf << "parse error:"; |
3106 | 3098 |
3107 if (s && strcmp (s, "parse error") != 0) | 3099 if (s && strcmp (s, "parse error") != 0) |
3108 output_buf << "\n\n " << s; | 3100 output_buf << "\n\n " << s; |
3150 | 3142 |
3151 if (f) | 3143 if (f) |
3152 fclose (static_cast<FILE *> (f)); | 3144 fclose (static_cast<FILE *> (f)); |
3153 } | 3145 } |
3154 | 3146 |
3155 static bool | |
3156 looks_like_copyright (const std::string& s) | |
3157 { | |
3158 bool retval = false; | |
3159 | |
3160 if (! s.empty ()) | |
3161 { | |
3162 size_t offset = s.find_first_not_of (" \t"); | |
3163 | |
3164 retval = (s.substr (offset, 9) == "Copyright" || s.substr (offset, 6) == "Author"); | |
3165 } | |
3166 | |
3167 return retval; | |
3168 } | |
3169 | |
3170 static int | |
3171 text_getc (FILE *f) | |
3172 { | |
3173 int c = gnulib::getc (f); | |
3174 | |
3175 // Convert CRLF into just LF and single CR into LF. | |
3176 | |
3177 if (c == '\r') | |
3178 { | |
3179 c = gnulib::getc (f); | |
3180 | |
3181 if (c != '\n') | |
3182 { | |
3183 ungetc (c, f); | |
3184 c = '\n'; | |
3185 } | |
3186 } | |
3187 | |
3188 return c; | |
3189 } | |
3190 | |
3191 class | |
3192 stdio_stream_reader : public stream_reader | |
3193 { | |
3194 public: | |
3195 | |
3196 stdio_stream_reader (FILE *f_arg, int& l, int& c) | |
3197 : stream_reader (), f (f_arg), line_num (l), column_num (c) | |
3198 { } | |
3199 | |
3200 int getc (void) | |
3201 { | |
3202 char c = ::text_getc (f); | |
3203 | |
3204 if (c == '\n') | |
3205 { | |
3206 line_num++; | |
3207 column_num = 0; | |
3208 } | |
3209 else | |
3210 { | |
3211 // FIXME -- try to be smarter about tabs? | |
3212 column_num++; | |
3213 } | |
3214 | |
3215 return c; | |
3216 } | |
3217 | |
3218 int ungetc (int c) | |
3219 { | |
3220 if (c == '\n') | |
3221 { | |
3222 line_num--; | |
3223 column_num = 0; | |
3224 } | |
3225 else | |
3226 { | |
3227 // FIXME -- try to be smarter about tabs? | |
3228 column_num--; | |
3229 } | |
3230 | |
3231 return ::ungetc (c, f); | |
3232 } | |
3233 | |
3234 private: | |
3235 | |
3236 FILE *f; | |
3237 | |
3238 int& line_num; | |
3239 | |
3240 int& column_num; | |
3241 | |
3242 // No copying! | |
3243 | |
3244 stdio_stream_reader (const stdio_stream_reader&); | |
3245 | |
3246 stdio_stream_reader & operator = (const stdio_stream_reader&); | |
3247 }; | |
3248 | |
3249 static bool | |
3250 skip_white_space (stream_reader& reader) | |
3251 { | |
3252 int c = 0; | |
3253 | |
3254 while ((c = reader.getc ()) != EOF) | |
3255 { | |
3256 switch (c) | |
3257 { | |
3258 case ' ': | |
3259 case '\t': | |
3260 case '\n': | |
3261 break; | |
3262 | |
3263 default: | |
3264 reader.ungetc (c); | |
3265 goto done; | |
3266 } | |
3267 } | |
3268 | |
3269 done: | |
3270 | |
3271 return (c == EOF); | |
3272 } | |
3273 | |
3274 static bool | |
3275 looking_at_classdef_keyword (FILE *ffile) | |
3276 { | |
3277 bool status = false; | |
3278 | |
3279 long pos = gnulib::ftell (ffile); | |
3280 | |
3281 char buf [10]; | |
3282 gnulib::fgets (buf, 10, ffile); | |
3283 size_t len = strlen (buf); | |
3284 if (len > 8 && strncmp (buf, "classdef", 8) == 0 | |
3285 && ! (isalnum (buf[8]) || buf[8] == '_')) | |
3286 status = true; | |
3287 | |
3288 gnulib::fseek (ffile, pos, SEEK_SET); | |
3289 | |
3290 return status; | |
3291 } | |
3292 | |
3293 static std::string | |
3294 gobble_leading_white_space (FILE *ffile, bool& eof, int& line_num, | |
3295 int& column_num) | |
3296 { | |
3297 std::string help_txt; | |
3298 | |
3299 eof = false; | |
3300 | |
3301 // TRUE means we have already cached the help text. | |
3302 bool have_help_text = false; | |
3303 | |
3304 std::string txt; | |
3305 | |
3306 stdio_stream_reader stdio_reader (ffile, line_num, column_num); | |
3307 | |
3308 while (true) | |
3309 { | |
3310 eof = skip_white_space (stdio_reader); | |
3311 | |
3312 if (eof) | |
3313 break; | |
3314 | |
3315 txt = CURR_LEXER->grab_comment_block (stdio_reader, true, eof); | |
3316 | |
3317 if (txt.empty ()) | |
3318 break; | |
3319 | |
3320 if (! (have_help_text || looks_like_copyright (txt))) | |
3321 { | |
3322 help_txt = txt; | |
3323 have_help_text = true; | |
3324 } | |
3325 | |
3326 octave_comment_buffer::append (txt); | |
3327 | |
3328 if (eof) | |
3329 break; | |
3330 } | |
3331 | |
3332 return help_txt; | |
3333 } | |
3334 | |
3335 static std::string | |
3336 gobble_leading_white_space (FILE *ffile, bool& eof) | |
3337 { | |
3338 int line_num = 1; | |
3339 int column_num = 1; | |
3340 | |
3341 return gobble_leading_white_space (ffile, eof, line_num, column_num); | |
3342 } | |
3343 | |
3344 static bool | |
3345 looking_at_function_keyword (FILE *ffile) | |
3346 { | |
3347 bool status = false; | |
3348 | |
3349 long pos = gnulib::ftell (ffile); | |
3350 | |
3351 char buf [10]; | |
3352 gnulib::fgets (buf, 10, ffile); | |
3353 size_t len = strlen (buf); | |
3354 if (len > 8 && strncmp (buf, "function", 8) == 0 | |
3355 && ! (isalnum (buf[8]) || buf[8] == '_')) | |
3356 status = true; | |
3357 | |
3358 gnulib::fseek (ffile, pos, SEEK_SET); | |
3359 | |
3360 return status; | |
3361 } | |
3362 | |
3363 static octave_function * | 3147 static octave_function * |
3364 parse_fcn_file (const std::string& ff, const std::string& dispatch_type, | 3148 parse_fcn_file (const std::string& full_file, const std::string& file, |
3149 const std::string& dispatch_type, | |
3365 bool require_file, bool force_script, bool autoload, | 3150 bool require_file, bool force_script, bool autoload, |
3366 bool relative_lookup, const std::string& warn_for) | 3151 bool relative_lookup, const std::string& warn_for) |
3367 { | 3152 { |
3368 unwind_protect frame; | 3153 unwind_protect frame; |
3369 | 3154 |
3384 | 3169 |
3385 command_history::ignore_entries (); | 3170 command_history::ignore_entries (); |
3386 | 3171 |
3387 FILE *ffile = 0; | 3172 FILE *ffile = 0; |
3388 | 3173 |
3389 if (! ff.empty ()) | 3174 if (! full_file.empty ()) |
3390 ffile = gnulib::fopen (ff.c_str (), "rb"); | 3175 ffile = gnulib::fopen (full_file.c_str (), "rb"); |
3391 | 3176 |
3392 frame.add_fcn (safe_fclose, ffile); | 3177 frame.add_fcn (safe_fclose, ffile); |
3393 | 3178 |
3394 if (ffile) | 3179 if (ffile) |
3395 { | 3180 { |
3397 | 3182 |
3398 // octave_parser constructor sets this for us. | 3183 // octave_parser constructor sets this for us. |
3399 frame.protect_var (CURR_LEXER); | 3184 frame.protect_var (CURR_LEXER); |
3400 | 3185 |
3401 octave_parser curr_parser (ffile); | 3186 octave_parser curr_parser (ffile); |
3402 | |
3403 curr_parser.curr_lexer->reading_fcn_file = true; | |
3404 | 3187 |
3405 curr_parser.curr_class_name = dispatch_type; | 3188 curr_parser.curr_class_name = dispatch_type; |
3406 curr_parser.autoloading = autoload; | 3189 curr_parser.autoloading = autoload; |
3407 curr_parser.fcn_file_from_relative_lookup = relative_lookup; | 3190 curr_parser.fcn_file_from_relative_lookup = relative_lookup; |
3408 | 3191 |
3409 std::string help_txt | 3192 // Do this with an unwind-protect cleanup function so that |
3410 = gobble_leading_white_space | 3193 // the forced variables will be unmarked in the event of an |
3411 (ffile, eof, | 3194 // interrupt. |
3412 curr_parser.curr_lexer->input_line_number, | 3195 symbol_table::scope_id scope = symbol_table::top_scope (); |
3413 curr_parser.curr_lexer->current_input_column); | 3196 frame.add_fcn (symbol_table::unmark_forced_variables, scope); |
3414 | 3197 |
3415 if (! help_txt.empty ()) | 3198 curr_parser.curr_lexer->force_script = force_script; |
3416 help_buf.push (help_txt); | 3199 curr_parser.curr_lexer->prep_for_file (); |
3417 | 3200 curr_parser.curr_lexer->parsing_class_method = ! dispatch_type.empty (); |
3418 if (! eof) | 3201 |
3419 { | 3202 curr_parser.curr_lexer->fcn_file_name = file; |
3420 std::string file_type; | 3203 curr_parser.curr_lexer->fcn_file_full_name = full_file; |
3421 | 3204 |
3422 frame.protect_var (Vecho_executing_commands); | 3205 int status = curr_parser.run (); |
3423 | 3206 |
3424 Vecho_executing_commands = ECHO_OFF; | 3207 fcn_ptr = curr_parser.primary_fcn_ptr; |
3425 | 3208 |
3426 if (! force_script && looking_at_function_keyword (ffile)) | 3209 if (status != 0) |
3427 { | 3210 error ("parse error while reading file %s", full_file.c_str ()); |
3428 file_type = "function"; | |
3429 } | |
3430 else | |
3431 { | |
3432 curr_parser.curr_lexer->reading_fcn_file = false; | |
3433 | |
3434 if (! force_script && looking_at_classdef_keyword (ffile)) | |
3435 { | |
3436 file_type = "classdef"; | |
3437 | |
3438 curr_parser.curr_lexer->reading_classdef_file = true; | |
3439 | |
3440 // FIXME -- Should classdef files be handled as | |
3441 // scripts or separately? Currently, without | |
3442 // setting up for reading script files, parsing | |
3443 // classdef files fails. | |
3444 curr_parser.curr_lexer->reading_script_file = true; | |
3445 } | |
3446 else | |
3447 { | |
3448 file_type = "script"; | |
3449 | |
3450 curr_parser.curr_lexer->reading_script_file = true; | |
3451 } | |
3452 } | |
3453 | |
3454 // Do this with an unwind-protect cleanup function so that | |
3455 // the forced variables will be unmarked in the event of an | |
3456 // interrupt. | |
3457 symbol_table::scope_id scope = symbol_table::top_scope (); | |
3458 frame.add_fcn (symbol_table::unmark_forced_variables, scope); | |
3459 | |
3460 if (! help_txt.empty ()) | |
3461 help_buf.push (help_txt); | |
3462 | |
3463 if (curr_parser.curr_lexer->reading_script_file) | |
3464 curr_parser.curr_lexer->prep_for_script_file (); | |
3465 else | |
3466 curr_parser.curr_lexer->prep_for_function_file (); | |
3467 | |
3468 curr_parser.curr_lexer->parsing_class_method = ! dispatch_type.empty (); | |
3469 | |
3470 int status = curr_parser.run (); | |
3471 | |
3472 fcn_ptr = curr_parser.primary_fcn_ptr; | |
3473 | |
3474 if (status != 0) | |
3475 error ("parse error while reading %s file %s", | |
3476 file_type.c_str (), ff.c_str ()); | |
3477 } | |
3478 else | |
3479 { | |
3480 int l = curr_parser.curr_lexer->input_line_number; | |
3481 int c = curr_parser.curr_lexer->current_input_column; | |
3482 | |
3483 tree_statement *end_of_script | |
3484 = curr_parser.make_end ("endscript", l, c); | |
3485 | |
3486 curr_parser.make_script (0, end_of_script); | |
3487 | |
3488 fcn_ptr = curr_parser.primary_fcn_ptr; | |
3489 } | |
3490 } | 3211 } |
3491 else if (require_file) | 3212 else if (require_file) |
3492 error ("no such file, '%s'", ff.c_str ()); | 3213 error ("no such file, '%s'", full_file.c_str ()); |
3493 else if (! warn_for.empty ()) | 3214 else if (! warn_for.empty ()) |
3494 error ("%s: unable to open file '%s'", warn_for.c_str (), ff.c_str ()); | 3215 error ("%s: unable to open file '%s'", warn_for.c_str (), |
3216 full_file.c_str ()); | |
3495 | 3217 |
3496 return fcn_ptr; | 3218 return fcn_ptr; |
3497 } | 3219 } |
3498 | 3220 |
3499 std::string | 3221 std::string |
3500 get_help_from_file (const std::string& nm, bool& symbol_found, | 3222 get_help_from_file (const std::string& nm, bool& symbol_found, |
3501 std::string& file) | 3223 std::string& full_file) |
3502 { | 3224 { |
3503 std::string retval; | 3225 std::string retval; |
3504 | 3226 |
3505 file = fcn_file_in_path (nm); | 3227 full_file = fcn_file_in_path (nm); |
3228 | |
3229 std::string file = full_file; | |
3230 | |
3231 size_t file_len = file.length (); | |
3232 | |
3233 if ((file_len > 4 && file.substr (file_len-4) == ".oct") | |
3234 || (file_len > 4 && file.substr (file_len-4) == ".mex") | |
3235 || (file_len > 2 && file.substr (file_len-2) == ".m")) | |
3236 { | |
3237 file = octave_env::base_pathname (file); | |
3238 file = file.substr (0, file.find_last_of ('.')); | |
3239 | |
3240 size_t pos = file.find_last_of (file_ops::dir_sep_str ()); | |
3241 if (pos != std::string::npos) | |
3242 file = file.substr (pos+1); | |
3243 } | |
3506 | 3244 |
3507 if (! file.empty ()) | 3245 if (! file.empty ()) |
3508 { | 3246 { |
3509 symbol_found = true; | 3247 symbol_found = true; |
3510 | 3248 |
3511 FILE *fptr = gnulib::fopen (file.c_str (), "r"); | 3249 octave_function *fcn |
3512 | 3250 = parse_fcn_file (full_file, file, "", true, false, false, false, ""); |
3513 if (fptr) | 3251 |
3252 if (fcn) | |
3514 { | 3253 { |
3515 unwind_protect frame; | 3254 retval = fcn->doc_string (); |
3516 frame.add_fcn (safe_fclose, fptr); | 3255 |
3517 | 3256 delete fcn; |
3518 bool eof; | |
3519 retval = gobble_leading_white_space (fptr, eof); | |
3520 | |
3521 if (retval.empty ()) | |
3522 { | |
3523 octave_function *fcn = parse_fcn_file (file, "", true, | |
3524 false, false, | |
3525 false, ""); | |
3526 | |
3527 if (fcn) | |
3528 { | |
3529 retval = fcn->doc_string (); | |
3530 | |
3531 delete fcn; | |
3532 } | |
3533 } | |
3534 } | 3257 } |
3535 } | 3258 } |
3536 | 3259 |
3537 return retval; | 3260 return retval; |
3538 } | 3261 } |
3631 } | 3354 } |
3632 else if (len > 4 && file.substr (len-4, len-1) == ".mex") | 3355 else if (len > 4 && file.substr (len-4, len-1) == ".mex") |
3633 { | 3356 { |
3634 // Temporarily load m-file version of mex-file, if it exists, | 3357 // Temporarily load m-file version of mex-file, if it exists, |
3635 // to get the help-string to use. | 3358 // to get the help-string to use. |
3636 frame.protect_var (curr_fcn_file_name); | |
3637 frame.protect_var (curr_fcn_file_full_name); | |
3638 | |
3639 curr_fcn_file_name = nm; | |
3640 curr_fcn_file_full_name = file.substr (0, len - 2); | |
3641 | 3359 |
3642 octave_function *tmpfcn = parse_fcn_file (file.substr (0, len - 2), | 3360 octave_function *tmpfcn = parse_fcn_file (file.substr (0, len - 2), |
3643 dispatch_type, false, | 3361 nm, dispatch_type, false, |
3644 autoload, autoload, | 3362 autoload, autoload, |
3645 relative_lookup, ""); | 3363 relative_lookup, ""); |
3646 | 3364 |
3647 retval = octave_dynamic_loader::load_mex (nm, file, relative_lookup); | 3365 retval = octave_dynamic_loader::load_mex (nm, file, relative_lookup); |
3648 | 3366 |
3650 retval->document (tmpfcn->doc_string ()); | 3368 retval->document (tmpfcn->doc_string ()); |
3651 delete tmpfcn; | 3369 delete tmpfcn; |
3652 } | 3370 } |
3653 else if (len > 2) | 3371 else if (len > 2) |
3654 { | 3372 { |
3655 // These are needed by yyparse. | 3373 retval = parse_fcn_file (file, nm, dispatch_type, true, autoload, |
3656 | |
3657 frame.protect_var (curr_fcn_file_name); | |
3658 frame.protect_var (curr_fcn_file_full_name); | |
3659 | |
3660 curr_fcn_file_name = nm; | |
3661 curr_fcn_file_full_name = file; | |
3662 | |
3663 retval = parse_fcn_file (file, dispatch_type, true, autoload, | |
3664 autoload, relative_lookup, ""); | 3374 autoload, relative_lookup, ""); |
3665 } | 3375 } |
3666 | 3376 |
3667 if (retval) | 3377 if (retval) |
3668 { | 3378 { |
3828 | 3538 |
3829 file_full_name = octave_env::make_absolute (file_full_name); | 3539 file_full_name = octave_env::make_absolute (file_full_name); |
3830 | 3540 |
3831 unwind_protect frame; | 3541 unwind_protect frame; |
3832 | 3542 |
3833 frame.protect_var (curr_fcn_file_name); | |
3834 frame.protect_var (curr_fcn_file_full_name); | |
3835 | |
3836 curr_fcn_file_name = file_name; | |
3837 curr_fcn_file_full_name = file_full_name; | |
3838 | |
3839 if (source_call_depth.find (file_full_name) == source_call_depth.end ()) | 3543 if (source_call_depth.find (file_full_name) == source_call_depth.end ()) |
3840 source_call_depth[file_full_name] = -1; | 3544 source_call_depth[file_full_name] = -1; |
3841 | 3545 |
3842 frame.protect_var (source_call_depth[file_full_name]); | 3546 frame.protect_var (source_call_depth[file_full_name]); |
3843 | 3547 |
3862 frame.add_fcn (octave_call_stack::pop); | 3566 frame.add_fcn (octave_call_stack::pop); |
3863 } | 3567 } |
3864 | 3568 |
3865 if (! error_state) | 3569 if (! error_state) |
3866 { | 3570 { |
3867 octave_function *fcn = parse_fcn_file (file_full_name, "", | 3571 octave_function *fcn = parse_fcn_file (file_full_name, file_name, |
3868 require_file, true, false, | 3572 "", require_file, true, |
3869 false, warn_for); | 3573 false, false, warn_for); |
3870 | 3574 |
3871 if (! error_state) | 3575 if (! error_state) |
3872 { | 3576 { |
3873 if (fcn && fcn->is_user_script ()) | 3577 if (fcn && fcn->is_user_script ()) |
3874 { | 3578 { |