+###--------------------------------------------------------------------------
+### Utilities.
+
+def fill_in_fields(fno_user, fno_passwd, fno_map, user, passwd, args):
+ """
+ Return a vector of filled-in fields.
+
+ The FNO_... arguments give field numbers: FNO_USER and FNO_PASSWD give the
+ positions for the username and password fields, respectively; and FNO_MAP
+ is a sequence of (NAME, POS) pairs. The USER and PASSWD arguments give the
+ actual user name and password values; ARGS are the remaining arguments,
+ maybe in the form `NAME=VALUE'.
+ """
+
+ ## Prepare the result vector, and set up some data structures.
+ n = 2 + len(fno_map)
+ fmap = {}
+ rmap = map(int, xrange(n))
+ ok = True
+ if fno_user >= n or fno_passwd >= n: ok = False
+ for k, i in fno_map:
+ fmap[k] = i
+ rmap[i] = "`%s'" % k
+ if i >= n: ok = False
+ if not ok:
+ raise U.ExpectedError, \
+ (500, "Fields specified aren't contiguous")
+
+ ## Prepare the new record's fields.
+ f = [None]*n
+ f[fno_user] = user
+ f[fno_passwd] = passwd
+
+ for a in args:
+ if '=' in a:
+ k, v = a.split('=', 1)
+ try: i = fmap[k]
+ except KeyError: raise U.ExpectedError, (400, "Unknown field `%s'" % k)
+ else:
+ for i in xrange(n):
+ if f[i] is None: break
+ else:
+ raise U.ExpectedError, (500, "All fields already populated")
+ v = a
+ if f[i] is not None:
+ raise U.ExpectedError, (400, "Field %s is already set" % rmap[i])
+ f[i] = v
+
+ ## Check that the vector of fields is properly set up.
+ for i in xrange(n):
+ if f[i] is None:
+ raise U.ExpectedError, (500, "Field %s is unset" % rmap[i])
+
+ ## Done.
+ return f
+