edit_var (X-mas present)

From: Manfred Hanke <Manfred.Hanke_at_email.domain.hidden>
Date: Fri, 25 Dec 2009 18:20:13 +0100
Dear all,

this is meant as a Christmas present for all S-Lang (& jed) users.

I hope that the edit_var function will turn out to be similiarly useful 
for interactively editing variables (especially complex nested data 
structures) as the edit_par function is for ISIS model parameters. 
Enjoy!
A few features are still missing. For example, different integer data 
types (Char_Type, Integer_Type, Long_Type, ...) are not distinguished 
yet.

Merry Christmas and then a Happy New Year 2010, too!
Cheers,

Manfred

-- 
Manfred Hanke      Manfred.Hanke(at)sternwarte.uni-erlangen.de
Dr. Karl Remeis-Observatory,  University of Erlangen-Nuremberg
Sternwartstrasse 7,      96049 Bamberg, Germany
phone: ++49 951 95222-34                fax: ++49 951 95222-22
  web: http://pulsar.sternwarte.uni-erlangen.de/hanke
--


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
private define assoc_has_default_value(hash, defaultvalref)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
{
  variable min_char =  32;  % ' '
  variable max_char = 126;  % '~'

  % find a string that is no key of hash
  variable N = 0;
  variable key = "";
  while(assoc_key_exists(hash, key))
  {
    N++;
    variable a = UChar_Type[N];
    a[*] = min_char;
    key = "";
    loop(N)  key += char(min_char);
    while(assoc_key_exists(hash, key))
    { variable i = -1;
      do i++, a[i] = min_char+((a[i]-min_char+1) mod (max_char-min_char+1));
      while(a[i]==min_char && i<N-1);
      if(a[i]==min_char && i==N-1)
	break;
      key = "";
      _for i (N-1, 0, -1)
        key += char(a[i]);
    }
  }

  try _at_email.domain.hidden  catch AnyError: return 0;
  return 1;
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
private define datatype_to_string();
private define datatype_to_string(val)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
{
  variable i, last, type = typeof(val);
  variable indent = qualifier("indent", 0);
  variable sp = "";  loop(indent)  sp += "  ";
  variable fold = (indent>0);  % qualifier_exists("fold");

  indent++;
  switch(type)
  { case String_Type or case BString_Type:
      sprintf("\"%S\"%s", val, (type==BString_Type ? "B" : ""));  % 
left on stack
  }
  { case Array_Type or case List_Type:
      (type==Array_Type ? "[" : "{") + sprintf(" %% %S", val) + (fold ? 
" %{{{" : "") + "\n";  % left on stack
      last = length(val)-1;
      _for i (0, last, 1)
        () + sp+"  "
           + datatype_to_string(val[i]; indent=indent)
	   + (i<last ? "," : "") + "\n";  % left on stack
      () + (fold ? "%}}}\n" : "") + sp+ (type==Array_Type ? "]" : "}"); 
  % left on stack
  }
  { is_struct_type(val):  % also works with typedef'ed struct's
      sprintf("struct { %% %S", val) + (fold ? " %{{{" : "") + "\n";  % 
left on stack
      variable field = get_struct_field_names(val);
      last = length(field)-1;
      _for i (0, last, 1)
        () + sp+"  " + field[i] + " = "
           + datatype_to_string(get_struct_field(val, field[i]); indent=indent)
	   + (i<last ? "," : "") + "\n";  % left on stack
      () + (fold ? "%}}}\n" : "") + sp + "}";  % left on stack
  }
  { case Assoc_Type:
      variable defval;
      "($0=Assoc_Type[" + string(_typeof(assoc_get_values(val)))
                        + (assoc_has_default_value(val, &defval) ? ", 
"+datatype_to_string(defval; indent=indent) : "")
	                + "]," + (fold ? " %{{{" : "") + "\n";  % left on stack
      variable key = assoc_get_keys(val);
      last = length(key)-1;
      _for i (0, last, 1)
        () + sp+"  $0[\""+key[i]+"\"] = "
           + datatype_to_string(val[key[i]]; indent=indent)
	   + ",\n";  % left on stack
      () + (fold ? "%}}}\n" : "") + sp + "$0)";  % left on stack
  }
  { % else: (Void_Type, Null_Type, Integer_Type, Double_Type, Complex_Type)
      sprintf("%S", val);  % left on stack
  }
}


%%%%%%%%%%%%%%%
define edit_var(x)
%%%%%%%%%%%%%%%
%!%+
%\function{edit_var}
%\synopsis{allows to edit S-Lang variables in an editor}
%\usage{edit_var(&x);
%\altusage{Any_Type y = edit_var(Any_Type x);}
%}
%\description
%    edit_var supports the following data types:
%    - Undefined_Type (=Void_Type), Null_Type,
%    - Integer_Type, Double_Type, Complex_Type
%    - String_Type, BString_Type
%    as well as
%    - Array_Type
%    - Assoc_Type
%    - Struct_Type
%    - List_Type
%    in a recursive way. (Circular linked list
%    are currently not supported.)
%
%    S-Lang code defining the variable x is shown
%    in the editor specified by the EDITOR environ-
%    ment variable or jed, if EDITOR is undefined.
%    edit_var uses jed's folding mode (one should
%    run 'Buffers' => 'Folding' => 'Enable Folding')
%    for nested data structures, which can hence be
%    very easily investigated.
%
%    The S-Lang code for x can be modified. After
%    saving the temporary file and closing the editor,
%    the file is evaluated, which should return an
%    S-Lang object that is either stored in x
%    (if passed by reference) or returned.
%!%-
{
  variable is_ref = (typeof(x)==Ref_Type);
  variable xx = ( is_ref ? _at_email.domain.hidden  variable t = typeof(xx);

  variable tmpfile = qualifier("tmpfile", 
sprintf("/tmp/edit_var_%d_%d", getuid(), getpid()));
  variable fp = fopen(tmpfile, "w");
  ()=fputs("% -*- mode: SLang; mode: fold -*-\n\n"
	   +(t==List_Type ? "($0=" : "")
	   +datatype_to_string(xx)
	   +(t==List_Type ? ", $0)" : ""),
	   fp);
  ()=fclose(fp);

  variable e = getenv("EDITOR");  if(e==NULL)  e = "jed";
  if(system(e+" "+tmpfile))
    if(is_ref)  return;  else  return x;

  try(e)  ()=evalfile(tmpfile);  % S-Lang code produces return value 
that is left on stack
  catch AnyError:
  {
    vmessage("\"%s\" exception:\n%s\n%s:%d", e.descr, e.message, 
e.file, e.line);
    if(is_ref)  return;  else  return NULL;
  }
  finally ()=remove(tmpfile);

  if(is_ref)  _at_email.domain.hidden}

----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.


================================================================================================
This message and any attachments are intended for the use of the addressee or addressees only. The
unauthorised disclosure, use, dissemination or copying (either in whole or in part) of its content
is prohibited. If you received this message in error, please delete it from your system and notify
the sender. E-mails can be altered and their integrity cannot be guaranteed. ESA shall not be liable
for any e-mail if modified.
=================================================================================================


----
You received this message because you are
subscribed to the isis-users list.
To unsubscribe, send a message to
isis-users-request_at_email.domain.hiddenwith the first line of the message as:
unsubscribe

Received on Fri Dec 25 2009 - 13:14:27 EST

This archive was generated by hypermail 2.2.0 : Mon Jan 04 2010 - 12:21:16 EST