1### Copyright (c) 2007, Tyzx Corporation. All rights reserved.
2
3function g = g_cmd (g, varargin)
4### g = g_cmd (g, <command or gnuplot_object or option>,...)
5###
6### Adds plotting commands to g. Each command is either a string that will be
7### passed to gnuplot, or a "gnuplot_object" whose commands will be executed
8### (in the right directory). gnuplot_objects are instantiated (see
9### _g_instantiate) before being insterted in the command list.
10###
11### OPTIONS:
12### "-at", <num>  : Insert subsequent sequence of commands (until next "-at"
13###                 option, or end of commands) after position <num>, rather
14###                 than end of g's command list. Use <num> = 0 to insert at
15###                 beginning.
16###
17### see also: g_new ...
18
19  _g_check (g);
20  if nargout<1, error ("g_cmd called in void context"); endif
21
22  ## Position at which commands are inserted
23  insert_pos      = length (g.cmds);
24
25  ## Should I force multiplot? (checked at end)
26  force_multiplot = 0;
27
28  i = 1;
29  while i <=length(varargin)
30				# ####################################
31    if ischar (varargin{i})	# Command is a string
32
33      cmds = varargin{i++};
34
35      if cmds(1)=="-"		# It's an option
36	switch cmds
37	  case "-at", insert_pos = varargin{i++};
38	  otherwise   error ("Unknown option '%s'",cmds);
39	endswitch
40	continue;
41      endif
42
43				# Command is printf format
44      labelEnd = _g_istoken (cmds, "printf:");
45      if labelEnd
46      ##if length(cmds)>2 && all (cmds(1:2) == ("printf:")(1:2))
47
48      ## labelEnd = index (cmds, ":");
49	## if !labelEnd, error ("malformed print directive : '%s'",cmds); endif
50
51	label = cmds(1:labelEnd);
52				# Search for end of args
53
54				# Check if user provided it
55	firstPrintArg = i;
56	lastPrintArg = i;
57	nPrintArgs = -1;
58
59	if labelEnd < length(cmds)
60				# !!! \d does not work
61	  [numSta,numEnd] = regexp (cmds(labelEnd+1:end),'^[0-9]+:');
62	  if !isempty(numSta),
63	    nPrintArgs = str2num (cmds(labelEnd+(numSta:numEnd-1)));
64	    labelEnd += numEnd;
65	    lastPrintArg = firstPrintArg + nPrintArgs - 1;
66	    i = lastPrintArg + 1;
67	  endif
68	endif
69
70	if nPrintArgs < 0	# Not provided: search for end label
71
72	  label = ["/",label];	# End label
73	  while lastPrintArg<=length(varargin)                  \
74		&& (   !ischar (varargin{lastPrintArg})         \
75		    || !strcmp (varargin{lastPrintArg}, label))
76	    lastPrintArg++;
77	  endwhile
78
79	  if lastPrintArg > length(varargin)
80	    warning ("g_cmd_PRINTF_NOT_CLOSED",\
81		     "Can't find closing label for '%s'",cmds);
82	    i = lastPrintArg;
83	  else
84	    i = lastPrintArg + 1;
85	    lastPrintArg--;
86	  endif
87	endif
88	if firstPrintArg <= lastPrintArg
89	  spf_format = cmds(labelEnd+1:end);
90
91          cmds = sprintf (spf_format, varargin{firstPrintArg:lastPrintArg});
92	else
93	  cmds = cmds(labelEnd+1:end);
94        endif
95				# now, cmds is plain string
96      endif			# EOF process printf arguments
97
98				# ####################################
99				# Add plain string command
100      ##g.cmds = {g.cmds{:}, cmds};
101      while cmds(end) == "\n"
102        printf ("g_cmd: removing newline at end of command\n");
103	cmds = cmds(1:end-1);
104      end
105      if index (cmds, "\n")
106        printf ("g_cmd: Warning: there's a newline in command\n");
107      endif
108      ##cmds = [cmds,"\n"]
109      g.cmds = csplice (g.cmds, insert_pos++, 0, {cmds});
110
111				# ####################################
112				# Command is a gnuplot_object:
113				# Instantiate it and insert its commands (making
114				# sure they are executed in the right directory)
115    elseif isstruct (varargin{i})
116
117      if _g_check (varargin{i})
118
119	g2 = _g_instantiate (varargin{i++});
120
121	if 1 ## && struct_contains (g2, "local") && g2.local
122
123	  g.owns = {g.owns{:}, g2.dir};
124	  g.owns = {g.owns{:}, g2.owns{:}};
125	endif
126
127				# remove multiplot commands from g2.cmds: they
128				# would erase what was plotted until now
129	if 1
130	  i1 = i2 = 1;
131	  for i1 = 1:length(g2.cmds)
132	    if isempty (regexp (g2.cmds{i1}, 'set\s+multiplot'))
133	      g2.cmds{i2++} = g2.cmds{i1};
134	    endif
135	  endfor
136	  g2.cmds = {g2.cmds{1:i2-1}};
137	endif
138	if 0
139	  g.cmds = {g.cmds{:}, \
140	 	   ["cd '",g2.dir,"'"],\
141	 		 g2.cmds{:},\
142	 	   ["cd '",g.dir,"'"]};
143	endif
144	if 1
145	  #printf ("Insert at %i\n",insert_pos);
146	  #g2.cmds
147	  #g.cmds
148	  g.cmds = csplice (g.cmds, insert_pos, 0, \
149			   {["cd '",g2.dir,"'"],   \
150			    g2.cmds{:},             \
151			    ["cd '",g.dir,"'"]\
152			    });
153	  insert_pos += 2 + length (g2.cmds);
154	  #g.cmds
155	  ##printf ("After insert\n");
156	  #g
157	  #keyboard
158	endif
159	force_multiplot = 1;
160      else
161	error ("Command %i is a struct but not a 'gnuplot_object'\n", i);
162      endif
163    else
164      error ("Command %i is neither string nor struct, but a",\
165	     i, typeinfo (varargin{i}));
166    endif
167  endwhile
168  if force_multiplot		# Make sure there's a multiplot command at the
169				# top
170    i = 1;
171    while i <= length (g.cmds)	# Check for existing set multiplot
172      if regexp (g.cmds{i}, 'set\s+multiplot')
173	break
174      endif
175      i++;
176    endwhile
177    if i > length (g.cmds)	# If there's none, put one at the head.
178
179      multiplot_cmd = "set multiplot";
180      if struct_contains (g.values, "title")
181	multiplot_cmd = [multiplot_cmd," '",g.values.title,"'"];
182      endif
183      g.cmds = {multiplot_cmd,\
184	       g.cmds{:}};
185    endif
186  endif
187endfunction
188