comparison src/variables.cc @ 605:4f65175911a6

[project @ 1994-08-13 20:10:39 by jwe]
author jwe
date Sat, 13 Aug 1994 20:10:39 +0000
parents 80a8a79ea6e4
children 14b2a186a5c0
comparison
equal deleted inserted replaced
604:1acdc9e50cd2 605:4f65175911a6
23 23
24 #ifdef HAVE_CONFIG_H 24 #ifdef HAVE_CONFIG_H
25 #include "config.h" 25 #include "config.h"
26 #endif 26 #endif
27 27
28 #if 0
29 #include <ctype.h>
30 #include <iostream.h>
31
32 #include "mappers.h"
33 #endif
34
28 #include <sys/types.h> 35 #include <sys/types.h>
29 #ifdef HAVE_UNISTD_H 36 #ifdef HAVE_UNISTD_H
30 #include <unistd.h> 37 #include <unistd.h>
31 #endif 38 #endif
32 #include <ctype.h>
33 #include <float.h> 39 #include <float.h>
34 #include <string.h> 40 #include <string.h>
35 #include <fstream.h>
36 #include <iostream.h>
37 #include <strstream.h> 41 #include <strstream.h>
38 42
43 #include "defaults.h"
44 #include "version.h"
39 #include "octave-hist.h" 45 #include "octave-hist.h"
40 #include "unwind-prot.h" 46 #include "unwind-prot.h"
47 #include "variables.h"
41 #include "user-prefs.h" 48 #include "user-prefs.h"
49 #include "statdefs.h"
42 #include "tree-base.h" 50 #include "tree-base.h"
43 #include "tree-expr.h" 51 #include "tree-expr.h"
44 #include "tree-const.h" 52 #include "tree-const.h"
45 #include "variables.h" 53 #include "dirfns.h"
46 #include "statdefs.h"
47 #include "defaults.h"
48 #include "version.h"
49 #include "mappers.h"
50 #include "oct-obj.h" 54 #include "oct-obj.h"
51 #include "sysdep.h" 55 #include "sysdep.h"
52 #include "dirfns.h"
53 #include "symtab.h" 56 #include "symtab.h"
54 #include "octave.h" 57 #include "octave.h"
58 #include "pager.h"
55 #include "error.h" 59 #include "error.h"
56 #include "pager.h" 60 #include "defun.h"
57 #include "utils.h" 61 #include "utils.h"
58 #include "defun.h" 62 #include "parse.h"
59 #include "input.h" 63 #include "input.h"
60 #include "parse.h"
61 #include "help.h" 64 #include "help.h"
62 #include "lex.h" 65 #include "lex.h"
63 66
64 extern "C" 67 extern "C"
65 { 68 {
66 #include <readline/readline.h> 69 #include <readline/readline.h>
67 #include <readline/tilde.h>
68 70
69 #include "fnmatch.h" 71 #include "fnmatch.h"
70 } 72 }
71
72 #if SIZEOF_SHORT == 4
73 #define FOUR_BYTE_TYPE short
74 #elif SIZEOF_INT == 4
75 #define FOUR_BYTE_TYPE int
76 #elif SIZEOF_LONG == 4
77 #define FOUR_BYTE_TYPE long
78 #else
79 LOSE! LOSE!
80 #endif
81 73
82 // Symbol table for symbols at the top level. 74 // Symbol table for symbols at the top level.
83 symbol_table *top_level_sym_tab = 0; 75 symbol_table *top_level_sym_tab = 0;
84 76
85 // Symbol table for the current scope. 77 // Symbol table for the current scope.
125 return (sr && sr->is_text_function ()); 117 return (sr && sr->is_text_function ());
126 } 118 }
127 119
128 // Is this function globally in this scope? 120 // Is this function globally in this scope?
129 121
130 static int 122 int
131 is_globally_visible (const char *name) 123 is_globally_visible (const char *name)
132 { 124 {
133 symbol_record *sr = curr_sym_tab->lookup (name, 0, 0); 125 symbol_record *sr = curr_sym_tab->lookup (name, 0, 0);
134 return (sr && sr->is_linked_to_global ()); 126 return (sr && sr->is_linked_to_global ());
135 }
136
137 // Is this name a valid identifier?
138
139 static int
140 valid_identifier (char *s)
141 {
142 if (! s || ! (isalnum (*s) || *s == '_'))
143 return 0;
144
145 while (*++s != '\0')
146 if (! (isalnum (*s) || *s == '_'))
147 return 0;
148
149 return 1;
150 } 127 }
151 128
152 // Is this tree_constant a valid function? 129 // Is this tree_constant a valid function?
153 130
154 tree_fvc * 131 tree_fvc *
830 symbol_record *csr = curr_sym_tab->lookup (id_name, 1, 0); 807 symbol_record *csr = curr_sym_tab->lookup (id_name, 1, 0);
831 csr->alias (gsr); 808 csr->alias (gsr);
832 } 809 }
833 } 810 }
834 811
835 // Loading variables from files. 812 // Help stuff. Shouldn't this go in help.cc?
836
837 // Extract a keyword and its value from a file. Input should look
838 // something like:
839 //
840 // #[ \t]*keyword[ \t]*:[ \t]*string-value\n
841 //
842 // Returns a pointer to new storage. The caller is responsible for
843 // deleting it.
844
845 static char *
846 extract_keyword (istream& is, char *keyword)
847 {
848 ostrstream buf;
849
850 char *retval = 0;
851
852 char c;
853 while (is.get (c))
854 {
855 if (c == '#')
856 {
857 while (is.get (c) && (c == ' ' || c == '\t' || c == '#'))
858 ; // Skip whitespace and comment characters.
859
860 if (isalpha (c))
861 buf << c;
862
863 while (is.get (c) && isalpha (c))
864 buf << c;
865
866 buf << ends;
867 char *tmp = buf.str ();
868 int match = (strncmp (tmp, keyword, strlen (keyword)) == 0);
869 delete [] tmp;
870
871 if (match)
872 {
873 ostrstream value;
874 while (is.get (c) && (c == ' ' || c == '\t' || c == ':'))
875 ; // Skip whitespace and the colon.
876
877 if (c != '\n')
878 {
879 value << c;
880 while (is.get (c) && c != '\n')
881 value << c;
882 }
883 value << ends;
884 retval = value.str ();
885 break;
886 }
887 }
888 }
889 return retval;
890 }
891
892 static int
893 extract_keyword (istream& is, char *keyword, int& value)
894 {
895 ostrstream buf;
896
897 int status = 0;
898 value = 0;
899
900 char c;
901 while (is.get (c))
902 {
903 if (c == '#')
904 {
905 while (is.get (c) && (c == ' ' || c == '\t' || c == '#'))
906 ; // Skip whitespace and comment characters.
907
908 if (isalpha (c))
909 buf << c;
910
911 while (is.get (c) && isalpha (c))
912 buf << c;
913
914 buf << ends;
915 char *tmp = buf.str ();
916 int match = (strncmp (tmp, keyword, strlen (keyword)) == 0);
917 delete [] tmp;
918
919 if (match)
920 {
921 while (is.get (c) && (c == ' ' || c == '\t' || c == ':'))
922 ; // Skip whitespace and the colon.
923
924 is.putback (c);
925 if (c != '\n')
926 is >> value;
927 if (is)
928 status = 1;
929 while (is.get (c) && c != '\n')
930 ; // Skip to beginning of next line;
931 break;
932 }
933 }
934 }
935 return status;
936 }
937
938 // Skip white space and comments.
939
940 static void
941 skip_comments (istream& is)
942 {
943 char c = '\0';
944 while (is.get (c))
945 {
946 if (c == ' ' || c == '\t' || c == '\n')
947 ; // Skip whitespace on way to beginning of next line.
948 else
949 break;
950 }
951
952 for (;;)
953 {
954 if (is && c == '#')
955 while (is.get (c) && c != '\n')
956 ; // Skip to beginning of next line, ignoring everything.
957 else
958 break;
959 }
960 }
961
962 static tree_constant
963 load_variable (istream& is, int& is_global)
964 {
965 tree_constant retval;
966
967 is_global = 0;
968
969 // Look for type keyword
970
971 char *tag = extract_keyword (is, "type");
972
973 if (tag && *tag)
974 {
975 char *ptr = strchr (tag, ' ');
976 if (ptr)
977 {
978 *ptr = '\0';
979 is_global = (strncmp (tag, "global", 6) == 0);
980 *ptr = ' ';
981 if (is_global)
982 ptr++;
983 else
984 ptr = tag;
985 }
986 else
987 ptr = tag;
988
989 if (strncmp (ptr, "scalar", 6) == 0)
990 {
991 double tmp;
992 is >> tmp;
993 if (is)
994 retval = tmp;
995 else
996 error ("failed to load scalar constant");
997 }
998 else if (strncmp (ptr, "matrix", 6) == 0)
999 {
1000 int nr = 0, nc = 0;
1001
1002 if (extract_keyword (is, "rows", nr) && nr > 0
1003 && extract_keyword (is, "columns", nc) && nc > 0)
1004 {
1005 Matrix tmp (nr, nc);
1006 is >> tmp;
1007 if (is)
1008 retval = tmp;
1009 else
1010 error ("failed to load matrix constant");
1011 }
1012 else
1013 error ("failed to extract number of rows and columns");
1014 }
1015 else if (strncmp (ptr, "complex scalar", 14) == 0)
1016 {
1017 Complex tmp;
1018 is >> tmp;
1019 if (is)
1020 retval = tmp;
1021 else
1022 error ("failed to load complex scalar constant");
1023 }
1024 else if (strncmp (ptr, "complex matrix", 14) == 0)
1025 {
1026 int nr = 0, nc = 0;
1027
1028 if (extract_keyword (is, "rows", nr) && nr > 0
1029 && extract_keyword (is, "columns", nc) && nc > 0)
1030 {
1031 ComplexMatrix tmp (nr, nc);
1032 is >> tmp;
1033 if (is)
1034 retval = tmp;
1035 else
1036 error ("failed to load complex matrix constant");
1037 }
1038 else
1039 error ("failed to extract number of rows and columns");
1040 }
1041 else if (strncmp (ptr, "string", 6) == 0)
1042 {
1043 int len;
1044 if (extract_keyword (is, "length", len) && len > 0)
1045 {
1046 char *tmp = new char [len+1];
1047 is.get (tmp, len+1, EOF);
1048 if (is)
1049 retval = tmp;
1050 else
1051 error ("failed to load string constant");
1052 }
1053 else
1054 error ("failed to extract string length");
1055 }
1056 else if (strncmp (ptr, "range", 5) == 0)
1057 {
1058 skip_comments (is); // # base, limit, range comment added by save().
1059 Range tmp;
1060 is >> tmp;
1061 if (is)
1062 retval = tmp;
1063 else
1064 error ("failed to load range constant");
1065 }
1066 else
1067 error ("unknown constant type `%s'", tag);
1068 }
1069 else
1070 error ("failed to extract keyword specifying value type");
1071
1072 delete [] tag;
1073
1074 return retval;
1075 }
1076
1077 static void
1078 install_loaded_variable (int force, char *nm, const tree_constant& tc,
1079 int global)
1080 {
1081 // Is there already a symbol by this name? If so, what is it?
1082
1083 symbol_record *lsr = curr_sym_tab->lookup (nm, 0, 0);
1084
1085 int is_undefined = 1;
1086 int is_variable = 0;
1087 int is_function = 0;
1088 int is_global = 0;
1089
1090 if (lsr)
1091 {
1092 is_undefined = ! lsr->is_defined ();
1093 is_variable = lsr->is_variable ();
1094 is_function = lsr->is_function ();
1095 is_global = lsr->is_linked_to_global ();
1096 }
1097
1098 // Try to read data for this name.
1099
1100 if (tc.is_undefined ())
1101 {
1102 error ("load: unable to load variable `%s'", nm);
1103 return;
1104 }
1105
1106 symbol_record *sr = 0;
1107
1108 if (global)
1109 {
1110 if (is_global || is_undefined)
1111 {
1112 if (force || is_undefined)
1113 {
1114 lsr = curr_sym_tab->lookup (nm, 1, 0);
1115 link_to_global_variable (lsr);
1116 sr = lsr;
1117 }
1118 else
1119 {
1120 warning ("load: global variable name `%s' exists.", nm);
1121 warning ("use `load -force' to overwrite");
1122 }
1123 }
1124 else if (is_function)
1125 {
1126 if (force)
1127 {
1128 lsr = curr_sym_tab->lookup (nm, 1, 0);
1129 link_to_global_variable (lsr);
1130 sr = lsr;
1131 }
1132 else
1133 {
1134 warning ("load: `%s' is currently a function in this scope", nm);
1135 warning ("`load -force' will load variable and hide function");
1136 }
1137 }
1138 else if (is_variable)
1139 {
1140 if (force)
1141 {
1142 lsr = curr_sym_tab->lookup (nm, 1, 0);
1143 link_to_global_variable (lsr);
1144 sr = lsr;
1145 }
1146 else
1147 {
1148 warning ("load: local variable name `%s' exists.", nm);
1149 warning ("use `load -force' to overwrite");
1150 }
1151 }
1152 else
1153 panic_impossible ();
1154 }
1155 else
1156 {
1157 if (is_global)
1158 {
1159 if (force || is_undefined)
1160 {
1161 lsr = curr_sym_tab->lookup (nm, 1, 0);
1162 link_to_global_variable (lsr);
1163 sr = lsr;
1164 }
1165 else
1166 {
1167 warning ("load: global variable name `%s' exists.", nm);
1168 warning ("use `load -force' to overwrite");
1169 }
1170 }
1171 else if (is_function)
1172 {
1173 if (force)
1174 {
1175 lsr = curr_sym_tab->lookup (nm, 1, 0);
1176 link_to_global_variable (lsr);
1177 sr = lsr;
1178 }
1179 else
1180 {
1181 warning ("load: `%s' is currently a function in this scope", nm);
1182 warning ("`load -force' will load variable and hide function");
1183 }
1184 }
1185 else if (is_variable || is_undefined)
1186 {
1187 if (force || is_undefined)
1188 {
1189 lsr = curr_sym_tab->lookup (nm, 1, 0);
1190 sr = lsr;
1191 }
1192 else
1193 {
1194 warning ("load: local variable name `%s' exists.", nm);
1195 warning ("use `load -force' to overwrite");
1196 }
1197 }
1198 else
1199 panic_impossible ();
1200 }
1201
1202 if (sr)
1203 {
1204 tree_constant *tmp_tc = new tree_constant (tc);
1205 sr->define (tmp_tc);
1206 return;
1207 }
1208 else
1209 error ("load: unable to load variable `%s'", nm);
1210
1211 return;
1212 }
1213
1214 // XXX FIXME XXX -- need to check stream states in more places.
1215
1216 static char *
1217 read_ascii_data (istream& stream, const char *filename, int& global,
1218 tree_constant& tc)
1219 {
1220 // Read name for this entry or break on EOF.
1221
1222 char *nm = extract_keyword (stream, "name");
1223
1224 if (! nm)
1225 return 0;
1226
1227 if (! *nm)
1228 {
1229 error ("load: empty name keyword found in file `%s'", filename);
1230 delete [] nm;
1231 return 0;
1232 }
1233
1234
1235 if (! valid_identifier (nm))
1236 {
1237 error ("load: bogus identifier `%s' found in file `%s'", nm, filename);
1238 delete [] nm;
1239 return 0;
1240 }
1241
1242 tc = load_variable (stream, global);
1243
1244 if (error_state)
1245 {
1246 error ("reading file %s", filename);
1247 return 0;
1248 }
1249
1250 return nm;
1251 }
1252
1253 static void
1254 swap_2_bytes (char *t)
1255 {
1256 char tmp = t[0];
1257 t[0] = t[1];
1258 t[1] = tmp;
1259 }
1260
1261 static void
1262 swap_4_bytes (char *t)
1263 {
1264 char tmp = t[0];
1265 t[0] = t[3];
1266 t[3] = tmp;
1267
1268 tmp = t[1];
1269 t[1] = t[2];
1270 t[2] = tmp;
1271 }
1272
1273 static void
1274 swap_8_bytes (char *t)
1275 {
1276 char tmp = t[0];
1277 t[0] = t[7];
1278 t[7] = tmp;
1279
1280 tmp = t[1];
1281 t[1] = t[6];
1282 t[6] = tmp;
1283
1284 tmp = t[2];
1285 t[2] = t[5];
1286 t[5] = tmp;
1287
1288 tmp = t[3];
1289 t[3] = t[4];
1290 t[4] = tmp;
1291 }
1292
1293 static char *floating_point_format[] =
1294 {
1295 "IEEE little endian",
1296 "IEEE big endian",
1297 "VAX D floating",
1298 "VAX G floating",
1299 "Cray",
1300 0,
1301 };
1302
1303 static char *
1304 read_binary_data (istream& stream, const char *filename, int& global,
1305 tree_constant& tc)
1306 {
1307 global = 0;
1308
1309 FOUR_BYTE_TYPE mopt, nr, nc, imag, len;
1310
1311 int swap = 0;
1312
1313 stream.read (&mopt, 4);
1314
1315 if (mopt > 9999)
1316 {
1317 swap = 1;
1318 swap_4_bytes ((char *) &mopt);
1319 }
1320
1321 if (mopt > 9999)
1322 {
1323 error ("load: can't read binary file");
1324 return 0;
1325 }
1326
1327 stream.read (&nr, 4);
1328 stream.read (&nc, 4);
1329 stream.read (&imag, 4);
1330 stream.read (&len, 4);
1331
1332 if (swap)
1333 {
1334 swap_4_bytes ((char *) &nr);
1335 swap_4_bytes ((char *) &nc);
1336 swap_4_bytes ((char *) &imag);
1337 swap_4_bytes ((char *) &len);
1338 }
1339
1340 int type = mopt % 10; // Full, sparse, etc.
1341 mopt /= 10; // Eliminate first digit.
1342 int prec = mopt % 10; // double, float, int, etc.
1343 mopt /= 100; // Skip unused third digit too.
1344 int mach = mopt % 10; // IEEE, VAX, etc.
1345
1346 if (mach < 0 || mach > 4)
1347 {
1348 error ("load: unrecognized binary format!");
1349 return 0;
1350 }
1351
1352 #if defined (IEEE_LITTLE_ENDIAN)
1353 if (mach != 0)
1354 {
1355 error ("load: can't convert from %s to %s yet",
1356 floating_point_format [mach], floating_point_format [0]);
1357 return 0;
1358 }
1359 #elif defined (IEEE_BIG_ENDIAN)
1360 if (mach != 1)
1361 {
1362 error ("load: can't convert from %s to %s yet",
1363 floating_point_format [mach], floating_point_format [1]);
1364 return 0;
1365 }
1366 #elif defined (VAX_D_FLOAT)
1367 if (mach != 2)
1368 {
1369 error ("load: can't convert from %s to %s yet",
1370 floating_point_format [mach], floating_point_format [2]);
1371 return 0;
1372 }
1373 #elif defined (VAX_G_FLOAT)
1374 if (mach != 3)
1375 {
1376 error ("load: can't convert from %s to %s yet",
1377 floating_point_format [mach], floating_point_format [3]);
1378 return 0;
1379 }
1380 #else
1381 LOSE! LOSE!
1382 #endif
1383
1384 if (prec != 0)
1385 {
1386 error ("load: can only read binary files with data stored as doubles");
1387 return 0;
1388 }
1389
1390 if (type != 0 && type != 1)
1391 {
1392 error ("load: can't read sparse matrices");
1393 return 0;
1394 }
1395
1396 if (imag && type == 1)
1397 {
1398 error ("load: encountered complex matrix with string flag set!");
1399 return 0;
1400 }
1401
1402 char *name = new char [len];
1403 stream.read (name, len);
1404
1405 int dlen = nr * nc;
1406 if (dlen < 0)
1407 {
1408 error ("load: matrix with negative size!");
1409 return 0;
1410 }
1411
1412 // This could probably be faster...
1413
1414 // XXX FIXME XXX -- 8 is magic here!
1415
1416 Matrix re (nr, nc);
1417 stream.read (re.fortran_vec (), dlen * 8);
1418
1419 if (imag)
1420 {
1421 Matrix im (nr, nc);
1422 stream.read (im.fortran_vec (), dlen * 8);
1423
1424 ComplexMatrix ctmp (nr, nc);
1425
1426 for (int j = 0; j < nc; j++)
1427 for (int i = 0; i < nr; i++)
1428 ctmp.elem (i, j) = Complex (re.elem (i, j), im.elem (i, j));
1429
1430 tc = ctmp;
1431 }
1432 else
1433 tc = re;
1434
1435 // If we were going to do it, this is probably where we would convert
1436 // the raw data to the proper floating point format.
1437
1438 if (type == 1)
1439 tc = tc.convert_to_str ();
1440
1441 return name;
1442 }
1443
1444 DEFUN_TEXT ("load", Fload, Sload, -1, 1,
1445 "load [-force] [-binary] file\n
1446 \n\
1447 load variables from a file")
1448 {
1449 Octave_object retval;
1450
1451 DEFINE_ARGV("load");
1452
1453 argc--;
1454 argv++;
1455
1456 int force = 0;
1457 int binary = 0;
1458
1459 while (argc > 0)
1460 {
1461 if (strcmp (*argv, "-force") == 0)
1462 {
1463 force++;
1464 argc--;
1465 argv++;
1466 }
1467 else if (strcmp (*argv, "-binary") == 0)
1468 {
1469 binary++;
1470 argc--;
1471 argv++;
1472 }
1473 else
1474 break;
1475 }
1476
1477 if (argc < 1)
1478 {
1479 error ("load: you must specify a single file to read");
1480 DELETE_ARGV;
1481 return retval;
1482 }
1483
1484 static istream stream;
1485 static ifstream file;
1486 if (strcmp (*argv, "-") == 0)
1487 {
1488 stream = cin;
1489 }
1490 else
1491 {
1492 char *fname = tilde_expand (*argv);
1493
1494 unsigned mode = ios::in;
1495 if (binary)
1496 mode |= ios::bin;
1497
1498 file.open (fname, mode);
1499
1500 if (! file)
1501 {
1502 error ("load: couldn't open input file `%s'", *argv);
1503 DELETE_ARGV;
1504 return retval;
1505 }
1506 stream = file;
1507 }
1508
1509 int count = 0;
1510 for (;;)
1511 {
1512 int global = 0;
1513 tree_constant tc;
1514
1515 char *name = 0;
1516 delete [] name;
1517
1518
1519 if (binary)
1520 name = read_binary_data (stream, *argv, global, tc);
1521 else
1522 name = read_ascii_data (stream, *argv, global, tc);
1523
1524 if (! error_state && name && tc.is_defined ())
1525 {
1526 count++;
1527 install_loaded_variable (force, name, tc, global);
1528 }
1529 else
1530 {
1531 if (count == 0)
1532 error ("load: are you sure `%s' is an Octave data file?", *argv);
1533
1534 break;
1535 }
1536 }
1537
1538 if (file);
1539 file.close ();
1540
1541 DELETE_ARGV;
1542
1543 return retval;
1544 }
1545
1546 // Return nonzero if PATTERN has any special globbing chars in it.
1547
1548 static int
1549 glob_pattern_p (char *pattern)
1550 {
1551 char *p = pattern;
1552 char c;
1553 int open = 0;
1554
1555 while ((c = *p++) != '\0')
1556 {
1557 switch (c)
1558 {
1559 case '?':
1560 case '*':
1561 return 1;
1562
1563 case '[': // Only accept an open brace if there is a close
1564 open++; // brace to match it. Bracket expressions must be
1565 continue; // complete, according to Posix.2
1566
1567 case ']':
1568 if (open)
1569 return 1;
1570 continue;
1571
1572 case '\\':
1573 if (*p++ == '\0')
1574 return 0;
1575
1576 default:
1577 continue;
1578 }
1579 }
1580
1581 return 0;
1582 }
1583
1584 DEFUN_TEXT ("save", Fsave, Ssave, -1, 1,
1585 "save file [var ...]\n\
1586 \n\
1587 save variables in a file")
1588 {
1589 Octave_object retval;
1590
1591 DEFINE_ARGV("save");
1592
1593 if (argc < 2)
1594 {
1595 print_usage ("save");
1596 DELETE_ARGV;
1597 return retval;
1598 }
1599
1600 argc--;
1601 argv++;
1602
1603 static ostream stream;
1604 static ofstream file;
1605 if (strcmp (*argv, "-") == 0)
1606 {
1607 // XXX FIXME XXX -- should things intended for the screen end up in a
1608 // tree_constant (string)?
1609 stream = cout;
1610 }
1611 else if (argc == 1 && glob_pattern_p (*argv)) // Guard against things
1612 { // like `save a*',
1613 print_usage ("save"); // which are probably
1614 DELETE_ARGV; // mistakes...
1615 return retval;
1616 }
1617 else
1618 {
1619 char *fname = tilde_expand (*argv);
1620 file.open (fname);
1621 if (! file)
1622 {
1623 error ("save: couldn't open output file `%s'", *argv);
1624 DELETE_ARGV;
1625 return retval;
1626 }
1627 stream = file;
1628
1629 }
1630
1631 int prec = user_pref.save_precision;
1632
1633 if (argc == 1)
1634 {
1635 int count;
1636 char **vars = curr_sym_tab->list (count, 0,
1637 symbol_def::USER_VARIABLE,
1638 SYMTAB_ALL_SCOPES);
1639
1640 for (int i = 0; i < count; i++)
1641 curr_sym_tab->save (stream, vars[i],
1642 is_globally_visible (vars[i]), prec);
1643
1644 delete [] vars;
1645 }
1646 else
1647 {
1648 while (--argc > 0)
1649 {
1650 argv++;
1651
1652 int count;
1653 char **lvars = curr_sym_tab->list (count, 0,
1654 symbol_def::USER_VARIABLE);
1655
1656 int saved_or_error = 0;
1657 int i;
1658 for (i = 0; i < count; i++)
1659 {
1660 if (fnmatch (*argv, lvars[i], __FNM_FLAGS) == 0
1661 && curr_sym_tab->save (stream, lvars[i],
1662 is_globally_visible (lvars[i]),
1663 prec) != 0)
1664 saved_or_error++;
1665 }
1666
1667 char **bvars = global_sym_tab->list (count, 0,
1668 symbol_def::BUILTIN_VARIABLE);
1669
1670 for (i = 0; i < count; i++)
1671 {
1672 if (fnmatch (*argv, bvars[i], __FNM_FLAGS) == 0
1673 && global_sym_tab->save (stream, bvars[i], 0, prec) != 0)
1674 saved_or_error++;
1675 }
1676
1677 delete [] lvars;
1678 delete [] bvars;
1679
1680 if (! saved_or_error)
1681 warning ("save: no such variable `%s'", *argv);
1682 }
1683 }
1684
1685 if (file);
1686 file.close ();
1687
1688 DELETE_ARGV;
1689
1690 return retval;
1691 }
1692
1693 // Help stuff.
1694 813
1695 // It's not likely that this does the right thing now. XXX FIXME XXX 814 // It's not likely that this does the right thing now. XXX FIXME XXX
1696 815
1697 char ** 816 char **
1698 make_name_list (void) 817 make_name_list (void)
1888 { 1007 {
1889 show_builtins++; 1008 show_builtins++;
1890 show_functions++; 1009 show_functions++;
1891 show_variables++; 1010 show_variables++;
1892 } 1011 }
1893 else if (strcmp (*argv, "-builtins") == 0 1012 else if (strcmp (*argv, "-builtins") == 0 || strcmp (*argv, "-b") == 0)
1894 || strcmp (*argv, "-b") == 0)
1895 show_builtins++; 1013 show_builtins++;
1896 else if (strcmp (*argv, "-functions") == 0 1014 else if (strcmp (*argv, "-functions") == 0 || strcmp (*argv, "-f") == 0)
1897 || strcmp (*argv, "-f") == 0)
1898 show_functions++; 1015 show_functions++;
1899 else if (strcmp (*argv, "-long") == 0 1016 else if (strcmp (*argv, "-long") == 0 || strcmp (*argv, "-l") == 0)
1900 || strcmp (*argv, "-l") == 0) 1017 show_verbose++;
1901 show_verbose++; 1018 else if (strcmp (*argv, "-variables") == 0 || strcmp (*argv, "-v") == 0)
1902 else if (strcmp (*argv, "-variables") == 0
1903 || strcmp (*argv, "-v") == 0)
1904 show_variables++; 1019 show_variables++;
1905 else 1020 else
1906 warning ("%s: unrecognized option `%s'", my_name, *argv); 1021 warning ("%s: unrecognized option `%s'", my_name, *argv);
1907 } 1022 }
1908 1023
2209 ""); 1324 "");
2210 1325
2211 DEFVAR ("commas_in_literal_matrix", SBV_commas_in_literal_matrix, "", 1326 DEFVAR ("commas_in_literal_matrix", SBV_commas_in_literal_matrix, "",
2212 0, 0, 1, commas_in_literal_matrix, 1327 0, 0, 1, commas_in_literal_matrix,
2213 "control auto-insertion of commas in literal matrices"); 1328 "control auto-insertion of commas in literal matrices");
1329
1330 DEFVAR ("default_save_format", SBV_default_save_format, "ascii",
1331 0, 0, 1, sv_default_save_format,
1332 "default format for files created with save, may be either\n\
1333 \"binary\" or \"text\"");
2214 1334
2215 DEFVAR ("do_fortran_indexing", SBV_do_fortran_indexing, "false", 0, 0, 1335 DEFVAR ("do_fortran_indexing", SBV_do_fortran_indexing, "false", 0, 0,
2216 1, do_fortran_indexing, 1336 1, do_fortran_indexing,
2217 "allow single indices for matrices"); 1337 "allow single indices for matrices");
2218 1338