comparison scripts/miscellaneous/edit.m @ 15526:1353ca03266f

add ability to edit multiple files (bug #37573) * edit.m (edit): Change handling of input arguments. Replace with varargin. Use statusvar and statsval to handle status changes. Handle multiple files by calling edit recursively on each file.
author Richard Crozier <richard.crozier@yahoo.co.uk>
date Mon, 15 Oct 2012 09:44:30 +0100
parents 5d3a684236b0
children 8b04a7d67d8a
comparison
equal deleted inserted replaced
15500:96b7343b8a41 15526:1353ca03266f
144 ## Author: Paul Kienzle <pkienzle@users.sf.net> 144 ## Author: Paul Kienzle <pkienzle@users.sf.net>
145 145
146 ## Original version by Paul Kienzle distributed as free software in the 146 ## Original version by Paul Kienzle distributed as free software in the
147 ## public domain. 147 ## public domain.
148 148
149 function ret = edit (file, state) 149 function ret = edit (varargin)
150 150
151 ## Pick up globals or default them. 151 ## Pick up globals or default them.
152 152
153 persistent FUNCTION = struct ("EDITOR", cstrcat (EDITOR (), " %s"), 153 persistent FUNCTION = struct ("EDITOR", cstrcat (EDITOR (), " %s"),
154 "HOME", fullfile (default_home, "octave"), 154 "HOME", fullfile (default_home, "octave"),
155 "AUTHOR", default_user(1), 155 "AUTHOR", default_user(1),
156 "EMAIL", [], 156 "EMAIL", [],
157 "LICENSE", "GPL", 157 "LICENSE", "GPL",
158 "MODE", "async", 158 "MODE", "async",
159 "EDITINPLACE", false); 159 "EDITINPLACE", false);
160 ## Make sure the state variables survive "clear functions". 160 ## Make sure the stateval variables survive "clear functions".
161 mlock; 161 mlock;
162 162
163 if (nargin == 2) 163 if (nargin == 1)
164 switch (toupper (file)) 164 ## User has supplied one arg, this can be a single file name
165 ## or a cell array of strings containing multiple files to be
166 ## opened
167 if (iscellstr(varargin{1}))
168 ## If first arg is a cell array of strings, it becomes the
169 ## list of files to be edited
170 editfilelist = varargin{1};
171 elseif (ischar(varargin{1}))
172 ## If first arg is a string, create a cell array of strings
173 ## of length one (by copying the input cell array)
174 editfilelist = varargin(1);
175 else
176 error('edit: expected file to be a string or cell array of strings');
177 endif
178 elseif (nargin == 2)
179 ## User has supplied two arguments, these could be two file
180 ## names, or a combination of editor state name and new value
181 ## for that state, so first check for the various states
182 statevar = varargin{1};
183 stateval = varargin{2};
184 switch (toupper (statevar))
165 case "EDITOR" 185 case "EDITOR"
166 FUNCTION.EDITOR = state; 186 FUNCTION.EDITOR = stateval;
187 return
167 case "HOME" 188 case "HOME"
168 if (! isempty (state) && state(1) == "~") 189 if (! isempty (stateval) && stateval(1) == "~")
169 state = [ default_home, state(2:end) ]; 190 stateval = [ default_home, stateval(2:end) ];
170 endif 191 endif
171 FUNCTION.HOME = state; 192 FUNCTION.HOME = stateval;
193 return
172 case "AUTHOR" 194 case "AUTHOR"
173 FUNCTION.AUTHOR = state; 195 FUNCTION.AUTHOR = stateval;
196 return
174 case "EMAIL" 197 case "EMAIL"
175 FUNCTION.EMAIL = state; 198 FUNCTION.EMAIL = stateval;
199 return
176 case "LICENSE" 200 case "LICENSE"
177 FUNCTION.LICENSE = state; 201 FUNCTION.LICENSE = stateval;
202 return
178 case "MODE" 203 case "MODE"
179 if (strcmp (state, "sync") || strcmp (state, "async")) 204 if (strcmp (stateval, "sync") || strcmp (stateval, "async"))
180 FUNCTION.MODE = state; 205 FUNCTION.MODE = stateval;
181 else 206 else
182 error ('edit: expected "edit MODE sync|async"'); 207 error ('edit: expected "edit MODE sync|async"');
183 endif 208 endif
209 return
184 case "EDITINPLACE" 210 case "EDITINPLACE"
185 if (ischar (state)) 211 if (ischar (stateval))
186 if (strcmpi (state, "true")) 212 if (strcmpi (stateval, "true"))
187 state = true; 213 stateval = true;
188 elseif (strcmpi (state, "false")) 214 elseif (strcmpi (stateval, "false"))
189 state = false; 215 stateval = false;
190 else 216 else
191 state = eval (state); 217 stateval = eval (stateval);
192 endif 218 endif
193 endif 219 endif
194 FUNCTION.EDITINPLACE = state; 220 FUNCTION.EDITINPLACE = stateval;
221 return
195 case "GET" 222 case "GET"
196 if (isfield (FUNCTION, toupper (state))) 223 if (isfield (FUNCTION, toupper (stateval)))
197 ret = FUNCTION.(toupper (state)); 224 ret = FUNCTION.(toupper (stateval));
198 else 225 else
199 ret = FUNCTION; 226 ret = FUNCTION;
200 endif 227 endif
228 return
201 otherwise 229 otherwise
202 error ('edit: expected "edit EDITOR|HOME|AUTHOR|EMAIL|LICENSE|MODE val"'); 230 ## If none of the states match, assume both inputs are
231 ## actually both file names to be opened
232 editfilelist = varargin;
203 endswitch 233 endswitch
204 return 234 elseif (nargin > 2)
235 if (iscellstr(varargin))
236 editfilelist = varargin;
237 else
238 error('edit: if supplying more than one input all inputs must be strings containing fiel names to open.');
239 endif
205 endif 240 endif
206 241
207 ## Start the editor without a file if no file is given. 242 ## Start the editor without a file if no file is given.
208 if (nargin < 1) 243 if (nargin < 1)
209 if (exist (FUNCTION.HOME, "dir") == 7 && (isunix () || ! ispc ())) 244 if (exist (FUNCTION.HOME, "dir") == 7 && (isunix () || ! ispc ()))
214 system (sprintf (FUNCTION.EDITOR,""), [], FUNCTION.MODE); 249 system (sprintf (FUNCTION.EDITOR,""), [], FUNCTION.MODE);
215 endif 250 endif
216 return; 251 return;
217 endif 252 endif
218 253
219 ## Check whether the user is trying to edit a builtin of compiled function. 254 if (numel(editfilelist) > 1)
220 switch (exist (file)) 255
221 case {3, 5} 256 ## Call edit on each of the files in the list if there are more than 1
222 error ("edit: unable to edit a built-in or compiled function"); 257 for i = 1:numel(editfilelist)
223 endswitch 258 edit(editfilelist{i});
224 259 endfor
225 ## Checks for whether the file is 260
226 ## absolute or relative should be handled inside file_in_loadpath. 261 else
227 ## That way, it will be possible to look up files correctly given 262
228 ## partial path information. For example, you should be able to 263 ## Only one file name was supplied, get it from the cell array
229 ## edit a particular overloaded function by doing any one of 264 file = editfilelist{1};
230 ## 265
231 ## edit classname/foo 266 ## Check whether the user is trying to edit a builtin or compiled function.
232 ## edit classname/foo.m 267 switch (exist (file))
233 ## edit @classname/foo 268 case {3, 5}
234 ## edit @classname/foo.m 269 error ("edit: unable to edit a built-in or compiled function");
235 ## 270 endswitch
236 ## This functionality is needed for other functions as well (at least 271
237 ## help and type; there may be more). So the place to fix that is in 272 ## Checks for whether the file is
238 ## file_in_loadpath, possibly with some help from the load_path class. 273 ## absolute or relative should be handled inside file_in_loadpath.
239 274 ## That way, it will be possible to look up files correctly given
240 ## The code below includes a portion that serves as a place-holder for 275 ## partial path information. For example, you should be able to
241 ## the changes suggested above. 276 ## edit a particular overloaded function by doing any one of
242 277 ##
243 ## Create list of explicit and implicit file names. 278 ## edit classname/foo
244 filelist = {file}; 279 ## edit classname/foo.m
245 ## If file has no extension, add file.m and file.cc to the list. 280 ## edit @classname/foo
246 idx = rindex (file, "."); 281 ## edit @classname/foo.m
247 if (idx == 0) 282 ##
248 ## Create the list of files to look for 283 ## This functionality is needed for other functions as well (at least
284 ## help and type; there may be more). So the place to fix that is in
285 ## file_in_loadpath, possibly with some help from the load_path class.
286
287 ## The code below includes a portion that serves as a place-holder for
288 ## the changes suggested above.
289
290 ## Create list of explicit and implicit file names.
249 filelist = {file}; 291 filelist = {file};
250 if (isempty (regexp (file, '\.m$'))) 292 ## If file has no extension, add file.m and file.cc to the list.
251 ## No ".m" at the end of the file, add to the list. 293 idx = rindex (file, ".");
252 filelist{end+1} = cat (2, file, ".m"); 294 if (idx == 0)
253 endif 295 ## Create the list of files to look for
254 if (isempty (regexp (file, '\.cc$'))) 296 filelist = {file};
255 ## No ".cc" at the end of the file, add to the list. 297 if (isempty (regexp (file, '\.m$')))
256 filelist{end+1} = cat (2, file, ".cc"); 298 ## No ".m" at the end of the file, add to the list.
257 endif 299 filelist{end+1} = cat (2, file, ".m");
300 endif
301 if (isempty (regexp (file, '\.cc$')))
302 ## No ".cc" at the end of the file, add to the list.
303 filelist{end+1} = cat (2, file, ".cc");
304 endif
305 endif
306
307 ## If the file includes a path, it may be an overloaded function.
308 if (! strcmp (file, "@") && index (file, filesep))
309 ## No "@" at the beginning of the file, add to the list.
310 numfiles = numel (filelist);
311 for n = 1:numfiles
312 filelist{n+numfiles} = cat (2, "@", filelist{n});
313 endfor
314 endif
315
316 ## Search the entire path for the 1st instance of a file in the list.
317 fileandpath = "";
318 for n = 1:numel (filelist)
319 filetoedit = file_in_path (path, filelist{n});
320 if (! isempty (filetoedit))
321 ## The path is explicitly included.
322 fileandpath = filetoedit;
323 break;
324 endif
325 endfor
326
327 if (! isempty (fileandpath))
328 ## If the file exists, then edit it.
329 if (FUNCTION.EDITINPLACE)
330 ## Edit in place even if it is protected.
331 system (sprintf (FUNCTION.EDITOR, cstrcat ("\"", fileandpath, "\"")),
332 [], FUNCTION.MODE);
333 return;
334 else
335 ## If the file is modifiable in place then edit it, otherwise make
336 ## a copy in HOME and then edit it.
337 fid = fopen (fileandpath, "r+t");
338 if (fid < 0)
339 from = fileandpath;
340 fileandpath = cstrcat (FUNCTION.HOME, from (rindex (from, filesep):end));
341 [status, msg] = copyfile (from, fileandpath, 1);
342 if (status == 0)
343 error (msg);
344 endif
345 else
346 fclose (fid);
347 endif
348 system (sprintf (FUNCTION.EDITOR, cstrcat ("\"", fileandpath, "\"")),
349 [], FUNCTION.MODE);
350 return;
351 endif
352 endif
353
354 ## If editing a new file that is neither a m-file or an oct-file,
355 ## just edit it.
356 fileandpath = file;
357 idx = rindex (file, ".");
358 name = file(1:idx-1);
359 ext = file(idx+1:end);
360 switch (ext)
361 case {"cc", "m"}
362 0;
363 otherwise
364 system (sprintf (FUNCTION.EDITOR, cstrcat ("\"", fileandpath, "\"")),
365 [], FUNCTION.MODE);
366 return;
367 endswitch
368
369 ## The file doesn't exist in path so create it, put in the function
370 ## template and edit it.
371
372 ## Guess the email name if it was not given.
373 if (isempty (FUNCTION.EMAIL))
374 host = getenv ("HOSTNAME");
375 if (isempty (host) && ispc ())
376 host = getenv ("COMPUTERNAME");
377 endif
378 if (isempty (host))
379 [status, host] = system ("uname -n");
380 ## trim newline from end of hostname
381 if (! isempty (host))
382 host = host(1:end-1);
383 endif
384 endif
385 if (isempty (host))
386 FUNCTION.EMAIL = " ";
387 else
388 FUNCTION.EMAIL = cstrcat ("<", default_user(0), "@", host, ">");
389 endif
390 endif
391
392 ## Fill in the revision string.
393 now = localtime (time);
394 revs = cstrcat ("Created: ", strftime ("%Y-%m-%d", now));
395
396 ## Fill in the copyright string.
397 copyright = cstrcat (strftime ("Copyright (C) %Y ", now), FUNCTION.AUTHOR);
398
399 ## Fill in the author tag field.
400 author = cstrcat ("Author: ", FUNCTION.AUTHOR, " ", FUNCTION.EMAIL);
401
402 ## Fill in the header.
403 uclicense = toupper (FUNCTION.LICENSE);
404 switch (uclicense)
405 case "GPL"
406 head = cstrcat (copyright, "\n\n", "\
407 This program is free software; you can redistribute it and/or modify\n\
408 it under the terms of the GNU General Public License as published by\n\
409 the Free Software Foundation; either version 3 of the License, or\n\
410 (at your option) any later version.\n\
411 \n\
412 This program is distributed in the hope that it will be useful,\n\
413 but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
414 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\
415 GNU General Public License for more details.\n\
416 \n\
417 You should have received a copy of the GNU General Public License\n\
418 along with Octave; see the file COPYING. If not, see\n\
419 <http://www.gnu.org/licenses/>.\
420 ");
421 tail = cstrcat (author, "\n", revs);
422
423 case "BSD"
424 head = cstrcat (copyright, "\n\n", "\
425 This program is free software; redistribution and use in source and\n\
426 binary forms, with or without modification, are permitted provided that\n\
427 the following conditions are met:\n\
428 \n\
429 1.Redistributions of source code must retain the above copyright\n\
430 notice, this list of conditions and the following disclaimer.\n\
431 2.Redistributions in binary form must reproduce the above copyright\n\
432 notice, this list of conditions and the following disclaimer in the\n\
433 documentation and/or other materials provided with the distribution.\n\
434 \n\
435 THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n\
436 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
437 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n\
438 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n\
439 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n\
440 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n\
441 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n\
442 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n\
443 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n\
444 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n\
445 SUCH DAMAGE.\
446 ");
447 tail = cstrcat (author, "\n", revs);
448
449 case "PD"
450 head = "";
451 tail = cstrcat (author, "\n", revs, "\n\n",
452 "This program is granted to the public domain.");
453
454 otherwise
455 head = "";
456 tail = cstrcat (copyright, "\n\n", FUNCTION.LICENSE, "\n",
457 author, "\n", revs);
458 endswitch
459
460 ## Generate the function template.
461 exists = exist (name);
462 switch (ext)
463 case {"cc", "C", "cpp"}
464 if (isempty (head))
465 comment = cstrcat ("/*\n", tail, "\n\n*/\n\n");
466 else
467 comment = cstrcat ("/*\n", head, "\n\n", tail, "\n\n*/\n\n");
468 endif
469 ## If we are shadowing an m-file, paste the code for the m-file.
470 if (any (exists == [2, 103]))
471 code = cstrcat ("\\ ", strrep (type (name){1}, "\n", "\n// "));
472 else
473 code = " ";
474 endif
475 body = cstrcat ("#include <octave/oct.h>\n\n",
476 "DEFUN_DLD(", name, ",args,nargout,\"\\\n",
477 name, "\\n\\\n\")\n{\n",
478 " octave_value_list retval;\n",
479 " int nargin = args.length ();\n\n",
480 code, "\n return retval;\n}\n");
481
482 text = cstrcat (comment, body);
483 case "m"
484 ## If we are editing a function defined on the fly, paste the
485 ## code.
486 if (any (exists == [2, 103]))
487 body = type (name){1};
488 else
489 body = cstrcat ("function [ ret ] = ", name, " ()\n\nendfunction\n");
490 endif
491 if (isempty (head))
492 comment = cstrcat ("## ", name, "\n\n",
493 "## ", strrep (tail, "\n", "\n## "), "\n\n");
494 else
495 comment = cstrcat ("## ", strrep (head,"\n","\n## "), "\n\n", ...
496 "## ", name, "\n\n", ...
497 "## ", strrep (tail, "\n", "\n## "), "\n\n");
498 endif
499 text = cstrcat (comment, body);
500 endswitch
501
502 ## Write the initial file (if there is anything to write)
503 fid = fopen (fileandpath, "wt");
504 if (fid < 0)
505 error ("edit: could not create %s", fileandpath);
506 endif
507 fputs (fid, text);
508 fclose (fid);
509
510 ## Finally we are ready to edit it!
511 system (sprintf (FUNCTION.EDITOR, cstrcat ("\"", fileandpath, "\"")),
512 [], FUNCTION.MODE);
513
258 endif 514 endif
259
260 ## If the file includes a path, it may be an overloaded function.
261 if (! strcmp (file, "@") && index (file, filesep))
262 ## No "@" at the beginning of the file, add to the list.
263 numfiles = numel (filelist);
264 for n = 1:numfiles
265 filelist{n+numfiles} = cat (2, "@", filelist{n});
266 endfor
267 endif
268
269 ## Search the entire path for the 1st instance of a file in the list.
270 fileandpath = "";
271 for n = 1:numel (filelist)
272 filetoedit = file_in_path (path, filelist{n});
273 if (! isempty (filetoedit))
274 ## The path is explicitly included.
275 fileandpath = filetoedit;
276 break;
277 endif
278 endfor
279
280 if (! isempty (fileandpath))
281 ## If the file exists, then edit it.
282 if (FUNCTION.EDITINPLACE)
283 ## Edit in place even if it is protected.
284 system (sprintf (FUNCTION.EDITOR, cstrcat ("\"", fileandpath, "\"")),
285 [], FUNCTION.MODE);
286 return;
287 else
288 ## If the file is modifiable in place then edit it, otherwise make
289 ## a copy in HOME and then edit it.
290 fid = fopen (fileandpath, "r+t");
291 if (fid < 0)
292 from = fileandpath;
293 fileandpath = cstrcat (FUNCTION.HOME, from (rindex (from, filesep):end));
294 [status, msg] = copyfile (from, fileandpath, 1);
295 if (status == 0)
296 error (msg);
297 endif
298 else
299 fclose (fid);
300 endif
301 system (sprintf (FUNCTION.EDITOR, cstrcat ("\"", fileandpath, "\"")),
302 [], FUNCTION.MODE);
303 return;
304 endif
305 endif
306
307 ## If editing a new file that is neither a m-file or an oct-file,
308 ## just edit it.
309 fileandpath = file;
310 idx = rindex (file, ".");
311 name = file(1:idx-1);
312 ext = file(idx+1:end);
313 switch (ext)
314 case {"cc", "m"}
315 0;
316 otherwise
317 system (sprintf (FUNCTION.EDITOR, cstrcat ("\"", fileandpath, "\"")),
318 [], FUNCTION.MODE);
319 return;
320 endswitch
321
322 ## The file doesn't exist in path so create it, put in the function
323 ## template and edit it.
324
325 ## Guess the email name if it was not given.
326 if (isempty (FUNCTION.EMAIL))
327 host = getenv ("HOSTNAME");
328 if (isempty (host) && ispc ())
329 host = getenv ("COMPUTERNAME");
330 endif
331 if (isempty (host))
332 [status, host] = system ("uname -n");
333 ## trim newline from end of hostname
334 if (! isempty (host))
335 host = host(1:end-1);
336 endif
337 endif
338 if (isempty (host))
339 FUNCTION.EMAIL = " ";
340 else
341 FUNCTION.EMAIL = cstrcat ("<", default_user(0), "@", host, ">");
342 endif
343 endif
344
345 ## Fill in the revision string.
346 now = localtime (time);
347 revs = cstrcat ("Created: ", strftime ("%Y-%m-%d", now));
348
349 ## Fill in the copyright string.
350 copyright = cstrcat (strftime ("Copyright (C) %Y ", now), FUNCTION.AUTHOR);
351
352 ## Fill in the author tag field.
353 author = cstrcat ("Author: ", FUNCTION.AUTHOR, " ", FUNCTION.EMAIL);
354
355 ## Fill in the header.
356 uclicense = toupper (FUNCTION.LICENSE);
357 switch (uclicense)
358 case "GPL"
359 head = cstrcat (copyright, "\n\n", "\
360 This program is free software; you can redistribute it and/or modify\n\
361 it under the terms of the GNU General Public License as published by\n\
362 the Free Software Foundation; either version 3 of the License, or\n\
363 (at your option) any later version.\n\
364 \n\
365 This program is distributed in the hope that it will be useful,\n\
366 but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
367 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\
368 GNU General Public License for more details.\n\
369 \n\
370 You should have received a copy of the GNU General Public License\n\
371 along with Octave; see the file COPYING. If not, see\n\
372 <http://www.gnu.org/licenses/>.\
373 ");
374 tail = cstrcat (author, "\n", revs);
375
376 case "BSD"
377 head = cstrcat (copyright, "\n\n", "\
378 This program is free software; redistribution and use in source and\n\
379 binary forms, with or without modification, are permitted provided that\n\
380 the following conditions are met:\n\
381 \n\
382 1.Redistributions of source code must retain the above copyright\n\
383 notice, this list of conditions and the following disclaimer.\n\
384 2.Redistributions in binary form must reproduce the above copyright\n\
385 notice, this list of conditions and the following disclaimer in the\n\
386 documentation and/or other materials provided with the distribution.\n\
387 \n\
388 THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n\
389 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
390 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n\
391 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n\
392 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n\
393 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n\
394 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n\
395 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n\
396 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n\
397 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n\
398 SUCH DAMAGE.\
399 ");
400 tail = cstrcat (author, "\n", revs);
401
402 case "PD"
403 head = "";
404 tail = cstrcat (author, "\n", revs, "\n\n",
405 "This program is granted to the public domain.");
406
407 otherwise
408 head = "";
409 tail = cstrcat (copyright, "\n\n", FUNCTION.LICENSE, "\n",
410 author, "\n", revs);
411 endswitch
412
413 ## Generate the function template.
414 exists = exist (name);
415 switch (ext)
416 case {"cc", "C", "cpp"}
417 if (isempty (head))
418 comment = cstrcat ("/*\n", tail, "\n\n*/\n\n");
419 else
420 comment = cstrcat ("/*\n", head, "\n\n", tail, "\n\n*/\n\n");
421 endif
422 ## If we are shadowing an m-file, paste the code for the m-file.
423 if (any (exists == [2, 103]))
424 code = cstrcat ("\\ ", strrep (type (name){1}, "\n", "\n// "));
425 else
426 code = " ";
427 endif
428 body = cstrcat ("#include <octave/oct.h>\n\n",
429 "DEFUN_DLD(", name, ",args,nargout,\"\\\n",
430 name, "\\n\\\n\")\n{\n",
431 " octave_value_list retval;\n",
432 " int nargin = args.length ();\n\n",
433 code, "\n return retval;\n}\n");
434
435 text = cstrcat (comment, body);
436 case "m"
437 ## If we are editing a function defined on the fly, paste the
438 ## code.
439 if (any (exists == [2, 103]))
440 body = type (name){1};
441 else
442 body = cstrcat ("function [ ret ] = ", name, " ()\n\nendfunction\n");
443 endif
444 if (isempty (head))
445 comment = cstrcat ("## ", name, "\n\n",
446 "## ", strrep (tail, "\n", "\n## "), "\n\n");
447 else
448 comment = cstrcat ("## ", strrep (head,"\n","\n## "), "\n\n", ...
449 "## ", name, "\n\n", ...
450 "## ", strrep (tail, "\n", "\n## "), "\n\n");
451 endif
452 text = cstrcat (comment, body);
453 endswitch
454
455 ## Write the initial file (if there is anything to write)
456 fid = fopen (fileandpath, "wt");
457 if (fid < 0)
458 error ("edit: could not create %s", fileandpath);
459 endif
460 fputs (fid, text);
461 fclose (fid);
462
463 ## Finally we are ready to edit it!
464 system (sprintf (FUNCTION.EDITOR, cstrcat ("\"", fileandpath, "\"")),
465 [], FUNCTION.MODE);
466 515
467 endfunction 516 endfunction
468 517
469 function ret = default_home () 518 function ret = default_home ()
470 519