annotate main/general/src/packfields.cc @ 9687:9df0cf7217ae octave-forge

general: update licenses to GPLv3+ and DESCRIPTION to mention non GPL code
author carandraug
date Tue, 13 Mar 2012 22:39:03 +0000
parents 3720f436cb20
children 9227bea976f1
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
9687
9df0cf7217ae general: update licenses to GPLv3+ and DESCRIPTION to mention non GPL code
carandraug
parents: 6618
diff changeset
1 // Copyright (C) 2009 VZLU Prague
9df0cf7217ae general: update licenses to GPLv3+ and DESCRIPTION to mention non GPL code
carandraug
parents: 6618
diff changeset
2 //
9df0cf7217ae general: update licenses to GPLv3+ and DESCRIPTION to mention non GPL code
carandraug
parents: 6618
diff changeset
3 // This program is free software; you can redistribute it and/or modify it under
9df0cf7217ae general: update licenses to GPLv3+ and DESCRIPTION to mention non GPL code
carandraug
parents: 6618
diff changeset
4 // the terms of the GNU General Public License as published by the Free Software
9df0cf7217ae general: update licenses to GPLv3+ and DESCRIPTION to mention non GPL code
carandraug
parents: 6618
diff changeset
5 // Foundation; either version 3 of the License, or (at your option) any later
9df0cf7217ae general: update licenses to GPLv3+ and DESCRIPTION to mention non GPL code
carandraug
parents: 6618
diff changeset
6 // version.
9df0cf7217ae general: update licenses to GPLv3+ and DESCRIPTION to mention non GPL code
carandraug
parents: 6618
diff changeset
7 //
9df0cf7217ae general: update licenses to GPLv3+ and DESCRIPTION to mention non GPL code
carandraug
parents: 6618
diff changeset
8 // This program is distributed in the hope that it will be useful, but WITHOUT
9df0cf7217ae general: update licenses to GPLv3+ and DESCRIPTION to mention non GPL code
carandraug
parents: 6618
diff changeset
9 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
9df0cf7217ae general: update licenses to GPLv3+ and DESCRIPTION to mention non GPL code
carandraug
parents: 6618
diff changeset
10 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
9df0cf7217ae general: update licenses to GPLv3+ and DESCRIPTION to mention non GPL code
carandraug
parents: 6618
diff changeset
11 // details.
9df0cf7217ae general: update licenses to GPLv3+ and DESCRIPTION to mention non GPL code
carandraug
parents: 6618
diff changeset
12 //
9df0cf7217ae general: update licenses to GPLv3+ and DESCRIPTION to mention non GPL code
carandraug
parents: 6618
diff changeset
13 // You should have received a copy of the GNU General Public License along with
9df0cf7217ae general: update licenses to GPLv3+ and DESCRIPTION to mention non GPL code
carandraug
parents: 6618
diff changeset
14 // this program; if not, see <http://www.gnu.org/licenses/>.
6060
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
15
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
16 #include <octave/oct.h>
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
17 #include <octave/utils.h>
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
18 #include <octave/symtab.h>
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
19 #include <octave/oct-map.h>
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
20
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
21 DEFUN_DLD (packfields, args, ,
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
22 "-*- texinfo -*-\n\
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
23 @deftypefn {Loadable Function} packfields (struct, var1, var2, @dots{})\n\
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
24 Inserts the named variables @var{var1}, @var{var2}, @dots{} as fields into @var{struct}.\n\
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
25 @var{struct} can be a scalar structure or user class.\n\
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
26 This is equivalent to the code:\n\
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
27 @example\n\
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
28 struct.var1 = var1;\n\
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
29 struct.var2 = var2;\n\
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
30 : \n\
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
31 @end example\n\
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
32 but more efficient and more concise.\n\
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
33 @seealso{unpackfields, struct}\n\
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
34 @end deftypefn")
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
35 {
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
36 int nargin = args.length ();
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
37
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
38 if (nargin > 0)
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
39 {
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
40 std::string struct_name = args (0).string_value ();
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
41 string_vector fld_names(nargin-1);
6618
3720f436cb20 make packfields 3.2.x compatible
highegg
parents: 6060
diff changeset
42 //octave_value_list fld_vals(nargin-1);
3720f436cb20 make packfields 3.2.x compatible
highegg
parents: 6060
diff changeset
43 // FIXME: workaround for 3.2.4.
3720f436cb20 make packfields 3.2.x compatible
highegg
parents: 6060
diff changeset
44 octave_value_list fld_vals (nargin-1, octave_value ());
6060
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
45
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
46 if (! error_state && ! valid_identifier (struct_name))
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
47 error ("packfields: invalid variable name: %s", struct_name.c_str ());
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
48
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
49 for (octave_idx_type i = 0; i < nargin-1; i++)
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
50 {
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
51 if (error_state)
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
52 break;
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
53
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
54 std::string fld_name = args(i+1).string_value ();
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
55
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
56 if (error_state)
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
57 break;
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
58
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
59 if (valid_identifier (fld_name))
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
60 {
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
61 fld_names(i) = fld_name;
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
62 octave_value fld_val = symbol_table::varval (fld_name);
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
63 if (fld_val.is_defined ())
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
64 fld_vals(i) = fld_val;
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
65 else
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
66 error ("packfields: variable %s not defined", fld_name.c_str ());
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
67 }
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
68 else
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
69 error ("packfields: invalid field name: %s", fld_name.c_str ());
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
70 }
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
71
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
72 if (! error_state)
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
73 {
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
74 // Force the symbol to be inserted in caller's scope.
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
75 symbol_table::symbol_record& rec = symbol_table::insert (struct_name);
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
76
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
77 octave_value& struct_ref = rec.varref ();
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
78
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
79 // If not defined, use struct ().
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
80 if (! struct_ref.is_defined ())
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
81 struct_ref = Octave_map (dim_vector (1, 1));
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
82
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
83 if (struct_ref.is_map ())
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
84 {
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
85 // Fast code for a built-in struct.
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
86 Octave_map map = struct_ref.map_value ();
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
87
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
88 if (map.numel () == 1)
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
89 {
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
90 // Do the actual work.
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
91 struct_ref = octave_value (); // Unshare map.
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
92 for (octave_idx_type i = 0; i < nargin-1; i++)
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
93 map.assign (fld_names(i), fld_vals(i));
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
94 struct_ref = map;
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
95 }
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
96 else
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
97 error ("packfields: structure must have singleton dimensions");
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
98 }
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
99 else
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
100 {
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
101 // General case.
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
102 struct_ref.make_unique ();
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
103 std::list<octave_value_list> idx (1);
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
104
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
105 for (octave_idx_type i = 0; i < nargin-1; i++)
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
106 {
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
107 idx.front () = args(i+1); // Save one string->octave_value conversion.
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
108 struct_ref = struct_ref.subsasgn (".", idx, fld_vals (i));
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
109
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
110 if (error_state)
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
111 break;
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
112 }
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
113 }
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
114 }
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
115 }
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
116 else
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
117 print_usage ();
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
118
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
119 return octave_value_list ();
ebf5d29e209d add packfields and unpackfields
highegg
parents:
diff changeset
120 }