Mercurial > octave-nkf
comparison src/symtab.cc @ 4913:c8368716bab3
[project @ 2004-07-23 16:00:48 by jwe]
author | jwe |
---|---|
date | Fri, 23 Jul 2004 16:00:49 +0000 |
parents | 14027e0bafa4 |
children | 1c0442da75fd |
comparison
equal
deleted
inserted
replaced
4912:048db020498c | 4913:c8368716bab3 |
---|---|
45 #include "pt-pr-code.h" | 45 #include "pt-pr-code.h" |
46 #include "symtab.h" | 46 #include "symtab.h" |
47 #include "utils.h" | 47 #include "utils.h" |
48 #include "variables.h" | 48 #include "variables.h" |
49 | 49 |
50 #include "gripes.h" | |
51 #include "lo-mappers.h" | |
52 | |
53 #include "parse.h" | |
54 #include <stdio.h> | |
55 | |
50 unsigned long int symbol_table::symtab_count = 0; | 56 unsigned long int symbol_table::symtab_count = 0; |
51 | 57 |
52 // Should variables be allowed to hide functions of the same name? A | 58 // Should variables be allowed to hide functions of the same name? A |
53 // positive value means yes. A negative value means yes, but print a | 59 // positive value means yes. A negative value means yes, but print a |
54 // warning message. Zero means it should be considered an error. | 60 // warning message. Zero means it should be considered an error. |
55 static int Vvariables_can_hide_functions; | 61 static int Vvariables_can_hide_functions; |
56 | 62 |
57 // Nonzero means we print debugging info about symbol table lookups. | 63 // Nonzero means we print debugging info about symbol table lookups. |
58 static int Vdebug_symtab_lookups; | 64 static int Vdebug_symtab_lookups; |
65 | |
66 // Defines layout for the whos/who -long command | |
67 std::string Vwhos_line_format; | |
59 | 68 |
60 octave_allocator | 69 octave_allocator |
61 symbol_record::symbol_def::allocator (sizeof (symbol_record::symbol_def)); | 70 symbol_record::symbol_def::allocator (sizeof (symbol_record::symbol_def)); |
62 | 71 |
63 #define SYMBOL_DEF symbol_record::symbol_def | 72 #define SYMBOL_DEF symbol_record::symbol_def |
408 linked_to_global = global_link_context.top (); | 417 linked_to_global = global_link_context.top (); |
409 global_link_context.pop (); | 418 global_link_context.pop (); |
410 } | 419 } |
411 } | 420 } |
412 | 421 |
413 void | 422 int |
414 symbol_record::print_symbol_info_line (std::ostream& os) const | 423 symbol_record::dimensions_string_req_first_space (int print_dims) const |
415 { | 424 { |
416 os << (is_read_only () ? " r-" : " rw") | 425 // This method calculates how much space needs to be reserved for the |
417 << (is_static () || is_eternal () ? "-" : "d") | 426 // first part of the dimensions string. |
418 << " " | 427 // Example: mat is a 12x3 matrix |
419 << std::setiosflags (std::ios::left) << std::setw (24) | 428 // ^^ => 2 columns |
420 << type_name () . c_str (); | 429 long dim = 0; |
421 | 430 int first_param_space = 0; |
422 os << std::resetiosflags (std::ios::left); | 431 |
423 | 432 // Calculating dimensions |
424 int nr = rows (); | 433 std::string dim_str = ""; |
425 int nc = columns (); | 434 std::stringstream ss; |
426 | 435 dim_vector dimensions; |
427 if (nr < 0) | 436 |
428 os << " -"; | 437 if (is_variable ()) |
429 else | 438 { |
430 os << std::setiosflags (std::ios::right) << std::setw (7) << nr; | 439 if (is_matrix_type ()) |
431 | 440 { |
432 if (nc < 0) | 441 dimensions = dims (); |
433 os << " -"; | 442 dim = dimensions.length (); |
434 else | 443 } |
435 os << std::setiosflags (std::ios::right) << std::setw (7) << nc; | 444 } |
436 | 445 |
437 os << std::resetiosflags (std::ios::right); | 446 first_param_space = (first_param_space >= 1 ? first_param_space : 1); |
438 | 447 |
439 os << " " << name () << "\n"; | 448 // Preparing dimension string |
449 if ((dim <= print_dims || print_dims < 0) && print_dims != 0) | |
450 { | |
451 // Dimensions string must be printed like this: 2x3x4x2 | |
452 if (dim == 0 || dim == 1) | |
453 first_param_space = 1; // First parameter is 1 | |
454 else | |
455 { | |
456 ss << dimensions (0); | |
457 | |
458 dim_str = ss.str (); | |
459 first_param_space = dim_str.length (); | |
460 } | |
461 } | |
462 else | |
463 { | |
464 // Printing dimension string as: a-D | |
465 ss << dim; | |
466 | |
467 dim_str = ss.str (); | |
468 first_param_space = dim_str.length (); | |
469 } | |
470 | |
471 return first_param_space; | |
472 } | |
473 | |
474 int | |
475 symbol_record::dimensions_string_req_total_space (int print_dims) const | |
476 { | |
477 // This method calculates how much space needs to be reserved for the | |
478 // the dimensions string. | |
479 // Example: mat is a 12x3 matrix | |
480 // ^^^^ => 4 columns | |
481 | |
482 std::string dim_str = ""; | |
483 std::stringstream ss; | |
484 | |
485 ss << make_dimensions_string (print_dims); | |
486 dim_str = ss.str (); | |
487 | |
488 return dim_str.length (); | |
489 } | |
490 | |
491 std::string | |
492 symbol_record::make_dimensions_string (int print_dims) const | |
493 { | |
494 // This method makes the dimensions-string, which is a string that tells | |
495 // how large a object is, dimensionally. | |
496 // Example: mat is a 2x3 matrix | |
497 // ^^^ | |
498 | |
499 long dim = 0; | |
500 | |
501 // Calculating dimensions | |
502 std::string dim_str = ""; | |
503 std::stringstream ss; | |
504 dim_vector dimensions; | |
505 | |
506 if (is_variable ()) | |
507 { | |
508 if (is_matrix_type ()) | |
509 { | |
510 dimensions = dims (); | |
511 dim = dimensions.length (); | |
512 } | |
513 } | |
514 | |
515 // Preparing dimension string | |
516 if ((dim <= print_dims || print_dims < 0) && print_dims != 0) | |
517 { | |
518 // Only printing the dimension string as: axbxc... | |
519 if (dim == 0) | |
520 ss << "1x1"; | |
521 else | |
522 { | |
523 for (int i = 0; i < dim; i++) | |
524 { | |
525 if (i == 0) | |
526 { | |
527 if (dim == 1) | |
528 // Looks like this is not going to happen in Octave, but ... | |
529 ss << "1x" << dimensions (i); | |
530 else | |
531 ss << dimensions (i); | |
532 } | |
533 else if (i < dim && dim != 1) | |
534 ss << "x" << dimensions (i); | |
535 } | |
536 } | |
537 } | |
538 else | |
539 { | |
540 // Printing dimension string as: a-D | |
541 ss << dim << "-D"; | |
542 } | |
543 | |
544 dim_str = ss.str (); | |
545 | |
546 return dim_str; | |
547 } | |
548 | |
549 void | |
550 symbol_record::print_symbol_info_line (std::ostream& os, | |
551 std::list<whos_parameter>& params) const | |
552 { | |
553 // This method prints a line of information on a given symbol | |
554 std::list<whos_parameter>::iterator i = params.begin (); | |
555 while (i != params.end ()) | |
556 { | |
557 whos_parameter param = * i; | |
558 | |
559 if (param.command != '\0') | |
560 { | |
561 // Do the actual printing | |
562 switch (param.modifier) | |
563 { | |
564 case 'l': | |
565 os << std::setiosflags (std::ios::left) << std::setw (param.parameter_length); | |
566 break; | |
567 | |
568 case 'r': | |
569 os << std::setiosflags (std::ios::right) << std::setw (param.parameter_length); | |
570 break; | |
571 | |
572 case 'c': | |
573 if (param.command == 's') | |
574 { | |
575 int front = param.first_parameter_length - | |
576 dimensions_string_req_first_space (param.dimensions); | |
577 int back = param.parameter_length - | |
578 dimensions_string_req_total_space (param.dimensions) - | |
579 front; | |
580 front = (front > 0) ? front : 0; | |
581 back = (back > 0) ? back : 0; | |
582 | |
583 os << std::setiosflags (std::ios::left) | |
584 << std::setw (front) | |
585 << "" << std::resetiosflags (std::ios::left) | |
586 << make_dimensions_string (param.dimensions) | |
587 << std::setiosflags (std::ios::left) | |
588 << std::setw (back) | |
589 << "" << std::resetiosflags (std::ios::left); | |
590 } | |
591 else | |
592 { | |
593 os << std::setiosflags (std::ios::left) | |
594 << std::setw (param.parameter_length); | |
595 } | |
596 break; | |
597 | |
598 default: | |
599 error ("whos_line_format: modifier `%c' unknown", param.modifier); | |
600 os << std::setiosflags (std::ios::right) | |
601 << std::setw (param.parameter_length); | |
602 } | |
603 | |
604 switch (param.command) | |
605 { | |
606 case 'b': | |
607 os << byte_size (); | |
608 break; | |
609 | |
610 case 'e': | |
611 os << numel (); | |
612 break; | |
613 | |
614 case 'n': | |
615 os << name (); | |
616 break; | |
617 | |
618 case 'p': | |
619 { | |
620 std::stringstream ss; | |
621 std::string str; | |
622 | |
623 ss << (is_read_only () ? "r-" : "rw") | |
624 << (is_static () || is_eternal () ? "-" : "d"); | |
625 str = ss.str (); | |
626 | |
627 os << str; | |
628 } | |
629 break; | |
630 | |
631 case 's': | |
632 if (param.modifier != 'c') | |
633 os << make_dimensions_string (param.dimensions); | |
634 break; | |
635 | |
636 case 't': | |
637 os << type_name (); | |
638 break; | |
639 | |
640 default: | |
641 error ("whos_line_format: command `%c' unknown", param.command); | |
642 } | |
643 | |
644 os << std::resetiosflags (std::ios::left) | |
645 << std::resetiosflags (std::ios::right); | |
646 i++; | |
647 } | |
648 else | |
649 { | |
650 os << param.text; | |
651 i++; | |
652 } | |
653 } | |
440 } | 654 } |
441 | 655 |
442 void | 656 void |
443 symbol_record::print_info (std::ostream& os, const std::string& prefix) const | 657 symbol_record::print_info (std::ostream& os, const std::string& prefix) const |
444 { | 658 { |
831 | 1045 |
832 return pattern.match (name); | 1046 return pattern.match (name); |
833 } | 1047 } |
834 | 1048 |
835 Array<symbol_record *> | 1049 Array<symbol_record *> |
1050 symbol_table::subsymbol_list (const string_vector& pats, | |
1051 unsigned int type, unsigned int scope) const | |
1052 { | |
1053 int count = 0; | |
1054 | |
1055 int n = size (); | |
1056 | |
1057 Array<symbol_record *> subsymbols (n); | |
1058 int pats_length = pats.length (); | |
1059 | |
1060 if (n == 0) | |
1061 return subsymbols; | |
1062 | |
1063 // Look for separators like .({ | |
1064 for (int j = 0; j < pats_length; j++) | |
1065 { | |
1066 std::string var_name = pats (j); | |
1067 | |
1068 size_t pos = var_name.find_first_of (".({"); | |
1069 | |
1070 if ((pos != NPOS) && (pos > 0)) | |
1071 { | |
1072 std::string first_name = var_name.substr(0,pos); | |
1073 | |
1074 for (unsigned int i = 0; i < table_size; i++) | |
1075 { | |
1076 symbol_record *ptr = table[i].next (); | |
1077 | |
1078 while (ptr) | |
1079 { | |
1080 assert (count < n); | |
1081 | |
1082 unsigned int my_scope = ptr->is_linked_to_global () + 1; // Tricky... | |
1083 | |
1084 unsigned int my_type = ptr->type (); | |
1085 | |
1086 std::string my_name = ptr->name (); | |
1087 | |
1088 if ((type & my_type) && (scope & my_scope) && (first_name == my_name)) | |
1089 { | |
1090 symbol_record *sym_ptr = new symbol_record (); | |
1091 octave_value value; | |
1092 int parse_status; | |
1093 | |
1094 value = eval_string (var_name, true, parse_status); | |
1095 | |
1096 sym_ptr->define (value); | |
1097 sym_ptr->rename (var_name); | |
1098 subsymbols(count++) = sym_ptr; | |
1099 } | |
1100 | |
1101 ptr = ptr->next (); | |
1102 } | |
1103 } | |
1104 } | |
1105 } | |
1106 | |
1107 subsymbols.resize (count); | |
1108 | |
1109 return subsymbols; | |
1110 } | |
1111 | |
1112 Array<symbol_record *> | |
836 symbol_table::symbol_list (const string_vector& pats, | 1113 symbol_table::symbol_list (const string_vector& pats, |
837 unsigned int type, unsigned int scope) const | 1114 unsigned int type, unsigned int scope) const |
838 { | 1115 { |
839 int count = 0; | 1116 int count = 0; |
840 | 1117 |
857 | 1134 |
858 unsigned int my_type = ptr->type (); | 1135 unsigned int my_type = ptr->type (); |
859 | 1136 |
860 std::string my_name = ptr->name (); | 1137 std::string my_name = ptr->name (); |
861 | 1138 |
862 if ((type & my_type) && (scope & my_scope) | 1139 if ((type & my_type) && (scope & my_scope) && (matches_patterns (my_name, pats))) |
863 && matches_patterns (my_name, pats)) | |
864 symbols(count++) = ptr; | 1140 symbols(count++) = ptr; |
865 | 1141 |
866 ptr = ptr->next (); | 1142 ptr = ptr->next (); |
867 } | 1143 } |
868 } | 1144 } |
904 | 1180 |
905 std::string a_nm = a->name (); | 1181 std::string a_nm = a->name (); |
906 std::string b_nm = b->name (); | 1182 std::string b_nm = b->name (); |
907 | 1183 |
908 return a_nm.compare (b_nm); | 1184 return a_nm.compare (b_nm); |
1185 } | |
1186 | |
1187 void | |
1188 symbol_table::print_descriptor (std::ostream& os, | |
1189 std::list<whos_parameter> params) const | |
1190 { | |
1191 // This method prints a line of information on a given symbol | |
1192 std::list<whos_parameter>::iterator i = params.begin (); | |
1193 OSSTREAM param_buf; | |
1194 | |
1195 while (i != params.end ()) | |
1196 { | |
1197 whos_parameter param = * i; | |
1198 | |
1199 if (param.command != '\0') | |
1200 { | |
1201 // Do the actual printing | |
1202 switch (param.modifier) | |
1203 { | |
1204 case 'l': | |
1205 os << std::setiosflags (std::ios::left) << std::setw (param.parameter_length); | |
1206 param_buf << std::setiosflags (std::ios::left) << std::setw (param.parameter_length); | |
1207 break; | |
1208 | |
1209 case 'r': | |
1210 os << std::setiosflags (std::ios::right) << std::setw (param.parameter_length); | |
1211 param_buf << std::setiosflags (std::ios::right) << std::setw (param.parameter_length); | |
1212 break; | |
1213 | |
1214 case 'c': | |
1215 if (param.command != 's') | |
1216 { | |
1217 os << std::setiosflags (std::ios::left) | |
1218 << std::setw (param.parameter_length); | |
1219 param_buf << std::setiosflags (std::ios::left) | |
1220 << std::setw (param.parameter_length); | |
1221 } | |
1222 break; | |
1223 | |
1224 default: | |
1225 os << std::setiosflags (std::ios::left) << std::setw (param.parameter_length); | |
1226 param_buf << std::setiosflags (std::ios::left) << std::setw (param.parameter_length); | |
1227 } | |
1228 | |
1229 if (param.command == 's' && param.modifier == 'c') | |
1230 { | |
1231 int a, b; | |
1232 | |
1233 if (param.modifier == 'c') | |
1234 { | |
1235 a = param.first_parameter_length - param.balance; | |
1236 a = (a < 0 ? 0 : a); | |
1237 b = param.parameter_length - a - param.text . length (); | |
1238 b = (b < 0 ? 0 : b); | |
1239 os << std::setiosflags (std::ios::left) << std::setw (a) | |
1240 << "" << std::resetiosflags (std::ios::left) << param.text | |
1241 << std::setiosflags (std::ios::left) | |
1242 << std::setw (b) << "" | |
1243 << std::resetiosflags (std::ios::left); | |
1244 param_buf << std::setiosflags (std::ios::left) << std::setw (a) | |
1245 << "" << std::resetiosflags (std::ios::left) << param.line | |
1246 << std::setiosflags (std::ios::left) | |
1247 << std::setw (b) << "" | |
1248 << std::resetiosflags (std::ios::left); | |
1249 } | |
1250 } | |
1251 else | |
1252 { | |
1253 os << param.text; | |
1254 param_buf << param.line; | |
1255 } | |
1256 os << std::resetiosflags (std::ios::left) | |
1257 << std::resetiosflags (std::ios::right); | |
1258 param_buf << std::resetiosflags (std::ios::left) | |
1259 << std::resetiosflags (std::ios::right); | |
1260 i++; | |
1261 } | |
1262 else | |
1263 { | |
1264 os << param.text; | |
1265 param_buf << param.line; | |
1266 i++; | |
1267 } | |
1268 } | |
1269 | |
1270 param_buf << OSSTREAM_ENDS; | |
1271 os << OSSTREAM_C_STR (param_buf); | |
1272 OSSTREAM_FREEZE (param_buf); | |
1273 } | |
1274 | |
1275 std::list<whos_parameter> | |
1276 symbol_table::parse_whos_line_format (Array<symbol_record *>& symbols) const | |
1277 { | |
1278 // This method parses the string whos_line_format, and returns | |
1279 // a parameter list, containing all information needed to print | |
1280 // the given attributtes of the symbols | |
1281 int idx; | |
1282 size_t format_len = Vwhos_line_format.length (); | |
1283 char garbage; | |
1284 std::list<whos_parameter> params; | |
1285 | |
1286 size_t bytes1; | |
1287 int elements1; | |
1288 | |
1289 int len = symbols.length (), i; | |
1290 | |
1291 std::string param_string = "benpst"; | |
1292 Array<int> param_length(param_string.length ()); | |
1293 Array<std::string> param_names(param_string.length ()); | |
1294 size_t pos_b, pos_t, pos_e, pos_n, pos_p, pos_s; | |
1295 | |
1296 pos_b = param_string.find ('b'); // Bytes | |
1297 pos_t = param_string.find ('t'); // (Type aka) Class | |
1298 pos_e = param_string.find ('e'); // Elements | |
1299 pos_n = param_string.find ('n'); // Name | |
1300 pos_p = param_string.find ('p'); // Protected | |
1301 pos_s = param_string.find ('s'); // Size | |
1302 | |
1303 param_names(pos_b) = "Bytes"; | |
1304 param_names(pos_t) = "Class"; | |
1305 param_names(pos_e) = "Elements"; | |
1306 param_names(pos_n) = "Name"; | |
1307 param_names(pos_p) = "Prot"; | |
1308 param_names(pos_s) = "Size"; | |
1309 | |
1310 for (i = 0; i < 6; i++) | |
1311 param_length(i) = param_names(i) . length (); | |
1312 | |
1313 // Calculating necessary spacing for name column, | |
1314 // bytes column, elements column and class column | |
1315 for (i = 0; i < static_cast<int> (len); i++) | |
1316 { | |
1317 std::stringstream ss1, ss2; | |
1318 std::string str; | |
1319 | |
1320 str = symbols(i)->name (); | |
1321 param_length(pos_n) = ((str.length () > static_cast<size_t> (param_length(pos_n))) ? | |
1322 str.length () : param_length(pos_n)); | |
1323 | |
1324 str = symbols(i)->type_name (); | |
1325 param_length(pos_t) = ((str.length () > static_cast<size_t> (param_length(pos_t))) ? | |
1326 str.length () : param_length(pos_t)); | |
1327 | |
1328 elements1 = symbols(i)->numel (); | |
1329 ss1 << elements1; | |
1330 str = ss1.str (); | |
1331 param_length(pos_e) = ((str.length () > static_cast<size_t> (param_length(pos_e))) ? | |
1332 str.length () : param_length(pos_e)); | |
1333 | |
1334 bytes1 = symbols(i)->byte_size (); | |
1335 ss2 << bytes1; | |
1336 str = ss2.str (); | |
1337 param_length(pos_b) = ((str.length () > static_cast<size_t> (param_length(pos_b))) ? | |
1338 str.length () : param_length (pos_b)); | |
1339 } | |
1340 | |
1341 idx = 0; | |
1342 while (static_cast<size_t> (idx) < format_len) | |
1343 { | |
1344 whos_parameter param; | |
1345 param.command = '\0'; | |
1346 | |
1347 if (Vwhos_line_format[idx] == '%') | |
1348 { | |
1349 bool _error = false; | |
1350 param.modifier = 'r'; | |
1351 param.parameter_length = 0; | |
1352 param.dimensions = 8; | |
1353 | |
1354 int a = 0, b = -1, c = 8, balance = 1; | |
1355 unsigned int items; | |
1356 size_t pos; | |
1357 std::string cmd; | |
1358 | |
1359 // Parse one command from whos_line_format | |
1360 cmd = Vwhos_line_format.substr (idx, Vwhos_line_format.length ()); | |
1361 pos = cmd.find (';'); | |
1362 if (pos != NPOS) | |
1363 cmd = cmd.substr (0, pos+1); | |
1364 else | |
1365 error ("parameter without ; in whos_line_format"); | |
1366 | |
1367 idx += cmd.length (); | |
1368 | |
1369 if (cmd.find_first_of ("crl") != 1) | |
1370 items = sscanf (cmd.c_str (), "%c%c:%d:%d:%d:%d;", | |
1371 &garbage, ¶m.command, &a, &b, &c, &balance); | |
1372 else | |
1373 items = sscanf (cmd.c_str (), "%c%c%c:%d:%d:%d:%d;", | |
1374 &garbage, ¶m.modifier, ¶m.command, &a, &b, &c, &balance) - 1; | |
1375 | |
1376 if (items < 2) | |
1377 { | |
1378 error ("whos_line_format: parameter structure without command in whos_line_format"); | |
1379 _error = true; | |
1380 } | |
1381 | |
1382 // Insert data into parameter | |
1383 param.first_parameter_length = 0; | |
1384 pos = param_string.find (param.command); | |
1385 if (pos != NPOS) | |
1386 { | |
1387 param.parameter_length = param_length(pos); | |
1388 param.text = param_names(pos); | |
1389 param.line.assign (param_names (pos).length (), '='); | |
1390 } | |
1391 else | |
1392 { | |
1393 error ("whos_line_format: '%c' is not a command", | |
1394 param.command); | |
1395 _error = true; | |
1396 } | |
1397 | |
1398 if (param.command == 's') | |
1399 { | |
1400 // Have to calculate space needed for printing matrix dimensions | |
1401 // Space needed for Size column is hard to determine in prior, | |
1402 // because it depends on dimensions to be shown. That is why it is | |
1403 // recalculated for each Size-command | |
1404 int j, first = 0, rest = 0, total = 0; | |
1405 param.dimensions = c; | |
1406 | |
1407 for (j = 0; j < len; j++) | |
1408 { | |
1409 int first1 = symbols(j)->dimensions_string_req_first_space (param.dimensions); | |
1410 int total1 = symbols(j)->dimensions_string_req_total_space (param.dimensions); | |
1411 int rest1 = total1 - first1; | |
1412 rest = (rest1 > rest ? rest1 : rest); | |
1413 first = (first1 > first ? first1 : first); | |
1414 total = (total1 > total ? total1 : total); | |
1415 } | |
1416 | |
1417 if (param.modifier == 'c') | |
1418 { | |
1419 if (first < balance) | |
1420 first += balance - first; | |
1421 if (rest + balance < param.parameter_length) | |
1422 rest += param.parameter_length - rest - balance; | |
1423 | |
1424 param.parameter_length = first + rest; | |
1425 param.first_parameter_length = first; | |
1426 param.balance = balance; | |
1427 } | |
1428 else | |
1429 { | |
1430 param.parameter_length = total; | |
1431 param.first_parameter_length = 0; | |
1432 } | |
1433 } | |
1434 else if (param.modifier == 'c') | |
1435 { | |
1436 error ("whos_line_format: modifier 'c' not available for command '%c'", | |
1437 param.command); | |
1438 _error = true; | |
1439 } | |
1440 | |
1441 // What happens if whos_line_format contains negative numbers | |
1442 // at param_length positions? | |
1443 param.balance = ((b < 0) ? 0 : param.balance); | |
1444 param.first_parameter_length = ((b < 0) ? 0 : | |
1445 param.first_parameter_length); | |
1446 param.parameter_length = ((a < 0) ? 0 : | |
1447 (param.parameter_length < | |
1448 param_length (pos_s)) ? | |
1449 param_length (pos_s) : | |
1450 param.parameter_length); | |
1451 | |
1452 // Parameter will not be pushed into parameter list if ... | |
1453 if (! _error) | |
1454 params.push_back (param); | |
1455 } | |
1456 else | |
1457 { | |
1458 // Text string, to be printed as it is ... | |
1459 std::string text; | |
1460 size_t pos; | |
1461 text = Vwhos_line_format.substr (idx, Vwhos_line_format.length ()); | |
1462 pos = text.find ('%'); | |
1463 if (pos != NPOS) | |
1464 text = text.substr (0, pos); | |
1465 | |
1466 // Push parameter into list ... | |
1467 idx += text.length (); | |
1468 param.text=text; | |
1469 param.line.assign (text.length(), ' '); | |
1470 params.push_back (param); | |
1471 } | |
1472 } | |
1473 | |
1474 return params; | |
909 } | 1475 } |
910 | 1476 |
911 int | 1477 int |
912 symbol_table::maybe_list (const char *header, const string_vector& argv, | 1478 symbol_table::maybe_list (const char *header, const string_vector& argv, |
913 std::ostream& os, bool show_verbose, | 1479 std::ostream& os, bool show_verbose, |
914 unsigned type, unsigned scope) | 1480 unsigned type, unsigned scope) |
915 { | 1481 { |
1482 // This method prints information for sets of symbols, but only one set | |
1483 // at a time (like, for instance: all variables, og all | |
1484 // built-in-functions) | |
1485 | |
1486 // This method invokes print_symbol_info_line to print info on every symbol | |
1487 | |
916 int status = 0; | 1488 int status = 0; |
917 | 1489 |
918 if (show_verbose) | 1490 if (show_verbose) |
919 { | 1491 { |
920 Array<symbol_record *> symbols = symbol_list (argv, type, scope); | 1492 // XXX FIXME XXX Should separate argv to lists with and without dots |
921 | 1493 Array<symbol_record *> _symbols = symbol_list (argv, type, scope); |
922 int len = symbols.length (); | 1494 Array<symbol_record *> _subsymbols = subsymbol_list (argv, type, scope); |
1495 | |
1496 int sym_len = _symbols.length (), subsym_len = _subsymbols.length (), | |
1497 len = sym_len + subsym_len; | |
1498 | |
1499 Array<symbol_record *> symbols (len); | |
923 | 1500 |
924 if (len > 0) | 1501 if (len > 0) |
925 { | 1502 { |
926 os << "\n" << header << "\n\n" | 1503 int bytes = 0, elements = 0, i; |
927 << "prot type rows cols name\n" | 1504 std::list<whos_parameter> params; |
928 << "==== ==== ==== ==== ====\n"; | 1505 |
1506 // Joining symbolic tables | |
1507 for (i = 0; i < sym_len; i++) | |
1508 symbols(i) = _symbols(i); | |
1509 | |
1510 for (i = 0; i < subsym_len; i++) | |
1511 symbols(i+sym_len) = _subsymbols(i); | |
1512 | |
1513 os << "\n" << header << "\n\n"; | |
929 | 1514 |
930 symbols.qsort (maybe_list_cmp_fcn); | 1515 symbols.qsort (maybe_list_cmp_fcn); |
931 | 1516 |
932 for (int i = 0; i < len; i++) | 1517 params = parse_whos_line_format (symbols); |
933 symbols(i)->print_symbol_info_line (os); | 1518 |
1519 print_descriptor (os, params); | |
1520 | |
1521 os << "\n"; | |
1522 | |
1523 for (int j = 0; j < len; j++) | |
1524 { | |
1525 symbols(j)->print_symbol_info_line (os, params); | |
1526 elements += symbols(j)->numel (); | |
1527 bytes += symbols(j)->byte_size (); | |
1528 } | |
1529 | |
1530 os << "\nTotal is " << elements | |
1531 << " element" << ((elements > 1) ? "s" : "") << " using " | |
1532 << bytes << " byte" << ((bytes > 1) ? "s" : "") << "\n"; | |
934 | 1533 |
935 status = 1; | 1534 status = 1; |
936 } | 1535 } |
937 } | 1536 } |
938 else | 1537 else |
939 { | 1538 { |
940 string_vector symbols = name_list (argv, 1, type, scope); | 1539 string_vector symbols = name_list (argv, 1, type, scope); |
941 | 1540 |
942 if (! symbols.empty ()) | 1541 if (! symbols.empty ()) |
943 { | 1542 { |
944 os << "\n" << header << "\n\n"; | 1543 os << "\n" << header << "\n\n"; |
945 | 1544 |
946 symbols.list_in_columns (os); | 1545 symbols.list_in_columns (os); |
947 | 1546 |
948 status = 1; | 1547 status = 1; |
1101 | 1700 |
1102 static int | 1701 static int |
1103 debug_symtab_lookups (void) | 1702 debug_symtab_lookups (void) |
1104 { | 1703 { |
1105 Vdebug_symtab_lookups = check_preference ("debug_symtab_lookups"); | 1704 Vdebug_symtab_lookups = check_preference ("debug_symtab_lookups"); |
1705 | |
1706 return 0; | |
1707 } | |
1708 | |
1709 static int | |
1710 whos_line_format (void) | |
1711 { | |
1712 Vwhos_line_format = builtin_string_variable ("whos_line_format"); | |
1106 | 1713 |
1107 return 0; | 1714 return 0; |
1108 } | 1715 } |
1109 | 1716 |
1110 void | 1717 void |
1119 @end defvr"); | 1726 @end defvr"); |
1120 | 1727 |
1121 DEFVAR (debug_symtab_lookups, false, debug_symtab_lookups, | 1728 DEFVAR (debug_symtab_lookups, false, debug_symtab_lookups, |
1122 "-*- texinfo -*-\n\ | 1729 "-*- texinfo -*-\n\ |
1123 @defvr debug_symtab_lookups\n\ | 1730 @defvr debug_symtab_lookups\n\ |
1124 If the value of htis variable is nonzero, print debugging info when\n\ | 1731 If the value of this variable is nonzero, print debugging info when\n\ |
1125 searching for symbols in the symbol tables.\n\ | 1732 searching for symbols in the symbol tables.\n\ |
1126 @end defvr"); | 1733 @end defvr"); |
1127 } | 1734 |
1128 | 1735 DEFVAR (whos_line_format, " %p:4; %ln:6; %cs:16:6:8:1; %rb:12; %lt:-1;\n", whos_line_format, |
1736 "-*- texinfo -*-\n\ | |
1737 @defvr {Built-in Variable} whos_line_format\n\ | |
1738 This string decides in what order attributtes of variables are to be printed.\n\ | |
1739 The following commands are used:\n\ | |
1740 @table @code\n\ | |
1741 @item %b\n\ | |
1742 Prints number of bytes occupied by variables.\n\ | |
1743 @item %e\n\ | |
1744 Prints elements held by variables.\n\ | |
1745 @item %n\n\ | |
1746 Prints variable names.\n\ | |
1747 @item %p\n\ | |
1748 Prints protection attributtes of variables.\n\ | |
1749 @item %s\n\ | |
1750 Prints dimensions of variables.\n\ | |
1751 @item %t\n\ | |
1752 Prints type names of variables.\n\ | |
1753 @end table\n\ | |
1754 \n\ | |
1755 Every command may also have a modifier:\n\ | |
1756 @table @code\n\ | |
1757 @item l\n\ | |
1758 Left alignment.\n\ | |
1759 @item r\n\ | |
1760 Right alignment (this is the default).\n\ | |
1761 @item c\n\ | |
1762 Centered (may only be applied to command %s).\n\ | |
1763 @end table\n\ | |
1764 \n\ | |
1765 A command is composed like this:\n\ | |
1766 %[modifier]<command>[:size_of_parameter[:center-specific[:print_dims[:balance]]]];\n\ | |
1767 \n\ | |
1768 Command and modifier is already explained. Size_of_parameter\n\ | |
1769 tells how many columns the parameter will need for printing.\n\ | |
1770 print_dims tells how many dimensions to print. If number of\n\ | |
1771 dimensions exceeds print_dims, dimensions will be printed like\n\ | |
1772 x-D.\n\ | |
1773 center-specific and print_dims may only be applied to command\n\ | |
1774 %s. A negative value for print_dims will cause Octave to print all\n\ | |
1775 dimensions whatsoever.\n\ | |
1776 balance specifies the offset for printing of the dimensions string.\n\ | |
1777 \n\ | |
1778 Default format is \" %p:4; %ln:6; %cs:16:6:8:1; %rb:12; %lt:-1;\\n\".\n\ | |
1779 @end defvr\n"); | |
1780 } | |
1129 | 1781 |
1130 /* | 1782 /* |
1131 ;;; Local Variables: *** | 1783 ;;; Local Variables: *** |
1132 ;;; mode: C++ *** | 1784 ;;; mode: C++ *** |
1133 ;;; End: *** | 1785 ;;; End: *** |