function [config, rc] = mfs_new_config(msg, conf, ls, controls)

# usage: [config, rc] = mfs_new_config(msg, conf, ls, controls)
#
# Input  msg        File handle of message file
#        conf(:)    Structure array with configurations
#        ls         Structure with lifting surfaces
#        controls   Structure with control surfacces
#                   (empty if there aren't any)
#
# Output config     Structure with configurations
#        rc         Return code: 0 = no errors
#                                1 = errors
#
# The function builds the structure config from the input data.
#
# The following fields are defined:
#
# config.nconf                  Number of configurations
#       .ncntrl                 Number of control surfaces
#       .nlinc(nconf)           Number of linear constraints
#       .names{:}               Configuration names
#       .qdyn(:)                Dynamic pressure
#       .ax(:)                  Linear acceleration
#       .ay(:)                  Linear acceleration
#       .az(:)                  Linear acceleration
#       .racce(:)               Roll acceleration
#       .pacce(:)               Pitch acceleration
#       .yacce(:)               Yaw acceleration
#       .alpha(:)               Angles of attack
#       .beta(:)                Sideslip angle
#       .pitch(:)               Pitch rate
#       .yaw(:)                 Yaw rate
#       .roll(:)                Roll rate
#       .cntls.<cntnam>(:)      Control surface angles
#       .tpdef.<tpnam>          n-th bit is 1 if trim parameter
#                               <tpname> is defined for n-th
#                               configuration
#       .lincon{nconf}          Definition of linear constraints
#
# --------------------------------------------------------------------

# Check arguments

  if (nargin != 4 || nargout != 2)
     print_usage();
  end

# Initialize

  rc     = 0;
  config = struct();
  cntnam = [];

  nconf = length(conf);
  nlinc = zeros(1, nconf);
  islin = 0;
  names = cell(1, nconf);

  qdyn  = ones(1, nconf);
  ax    = zeros(1, nconf);
  ay    = zeros(1, nconf);
  az    = zeros(1, nconf);
  racce = zeros(1, nconf);
  pacce = zeros(1, nconf);
  yacce = zeros(1, nconf);
  alpha = zeros(1, nconf);
  beta  = zeros(1, nconf);
  pitch = zeros(1, nconf);
  yaw   = zeros(1, nconf);
  roll  = zeros(1, nconf);

  tpdef = struct("ax", 0, "ay", 0, "az", 0, "racce", 0, "pacce", 0,
                 "yacce", 0, "alpha", 0, "beta", 0, "pitch", 0, 
                 "yaw", 0, "roll", 0);

  config.nconf  = nconf;
  config.ncntrl = 0;

  cntls = struct();

  if (controls.ncntrl)
     fldnam = fieldnames(controls);
     cntnam = fldnam(2 : end);
     ncntrl = controls.ncntrl;
     cntval = zeros(1, nconf);
     config.ncntrl = ncntrl;
     for n = 1 : ncntrl
         cntls = setfield(cntls, cntnam{n}, cntval);
         tpdef = setfield(tpdef, cntnam{n}, 0);
     end
  else
     ncntrl = 0;
  end

# Process the definitions

  for n = 1 : nconf
      for [val, key] = conf(n)
          if (! isempty(val))
              switch key
              case "name"
                 names{n} = val;
              case "qdyn"
                 if (val > 0)
                    qdyn(n) = val;
                 else
                    rc = 1;
                    fprintf(msg, "*E* Configuration no. %5d: ", n);
                    fprintf(msg, "Dynamic pressure is not positive\n");
                 end
              case "ax"
                 ax(n) = val;
                 tpdef.ax = bitset(tpdef.ax, n);
              case "ay"
                 ay(n) = val;
                 tpdef.ay = bitset(tpdef.ay, n);
              case "az"
                 az(n) = val;
                 tpdef.az = bitset(tpdef.az, n);
              case "pacce"
                 pacce(n) = val;
                 tpdef.pacce = bitset(tpdef.pacce, n);
              case "yacce"
                 yacce(n) = val;
                 tpdef.yacce = bitset(tpdef.yacce, n);
              case "racce"
                 racce(n) = val;
                 tpdef.racce = bitset(tpdef.racce, n);
              case "alpha"
                 alpha(n) = val * pi / 180;
                 tpdef.alpha = bitset(tpdef.alpha, n);
              case "beta"
                 beta(n) = val * pi / 180;
                 tpdef.beta = bitset(tpdef.beta, n);
              case "pitch"
                 pitch(n) = val;
                 tpdef.pitch = bitset(tpdef.pitch, n);
              case "yaw"
                 yaw(n) = val;
                 tpdef.yaw = bitset(tpdef.yaw, n);
              case "roll"
                 roll(n) = val;
                 tpdef.roll = bitset(tpdef.roll, n);
              case cntnam
                 angles = getfield(cntls, key);
                 angles(n) = pi * val / 180;
                 cntls = setfield(cntls, key, angles);
                 def   = bitset(getfield(tpdef, key), n);
                 tpdef = setfield(tpdef, key, def);
              case "lincon"
                 nlinc(n) = length(val);                 
                 islin    = 1;
              otherwise
                 rc = 1;
                 fprintf(msg, "*E* Configuration no. %5d: ", n);
                 fprintf(msg, "Illegal field \"%s\"\n", key);
              end
          end
      end
      if (isempty(names{n}))
         rc = 1;
         fprintf(msg, "*E* Configuration no. %5d: ", n);
         fprintf(msg, "Definition of name missing\n");
      end
  end

  if (rc) return; end

  cntls = orderfields(cntls);

  config.nlinc = nlinc;
  config.names = names;
  config.qdyn  = qdyn;
  config.ax    = ax;
  config.ay    = ay;
  config.az    = az;
  config.pacce = pacce;
  config.yacce = yacce;
  config.racce = racce;
  config.alpha = alpha;
  config.beta  = beta;
  config.pitch = pitch;
  config.yaw   = yaw;
  config.roll  = roll;
  config.cntls = cntls;
  config.tpdef = tpdef;

  tp  = fieldnames(tpdef)';
  ntp = length(tp);

# Process linear constraints

  if (islin)

     lc = cell(1, nconf);
     tpi = [tp, "rhs"];

     for n = 1 : nconf
         if (nlinc(n))
            for m = 1 : nlinc(n)
                c = conf(n).lincon{m};
                for [val, key] = c
                    if (! ismember(key, tpi))
                       rc = 1;
                       fprintf(msg, "*E* Configuration no. %5d:\n", n);
                       fprintf(msg, "    lincon{%d} references undefined ", m);
                       fprintf(msg, "trim parameter %s\n", key); 
                    end
                end
            end
         end
         lc{n} = conf(n).lincon;
     end

     config.lincon = lc;

  end

end
