commit bf23ac8c74dbe0ad5720ba4c742369e3eafbab85
Author: Marc Dequènes (Duck) <Duck@DuckCorp.org>
Date:   Thu Jul 30 23:44:29 2009 +0200

    [evol] begining of the error abstraction with a simplied exception list, with translation using gettext (no translations yet)

diff --git a/Rakefile b/Rakefile
new file mode 100644
index 0000000..5aab234
--- /dev/null
+++ b/Rakefile
@@ -0,0 +1,23 @@
+# to allow in-place run
+$: << File.join(File.dirname(__FILE__), ".", "lib")
+
+ENV['LC_ALL'] = "C"
+
+require 'rake'
+require 'gettext/utils'
+require 'lib/ldap_shadows/config'
+require 'lib/ldap_shadows/info'
+
+namespace :i18n do
+desc "Create mo-files for l10n"
+  task :makemo do
+    GetText.create_mofiles(true, "po", LdapShadows::Config::L10N_DIR)
+  end
+
+  desc "Update pot/po files to match new version."
+  task :updatepo do
+    GetText.update_pofiles("ldapshadows",
+      Dir.glob("lib/**/*.{rb,rhtml}") + Dir.glob("bin/*"),
+      LdapShadows::PRODUCT + " " + LdapShadows::VERSION)
+  end
+end
diff --git a/bin/shadowwalker b/bin/shadowwalker
index 3a30aee..a0f981f 100755
--- a/bin/shadowwalker
+++ b/bin/shadowwalker
@@ -21,6 +21,9 @@
 # to allow in-place run for test
 $: << File.join(File.dirname(__FILE__), "..", "lib")
 
+# get locale from shell
+locale = ENV['LANGUAGE'] || ENV['LC_ALL'] || ENV['LC_MESSAGES'] || ENV['LANG']
+
 require 'ldap_shadows'
 require 'ldap_shadows/display_utils'
 require 'yaml'
@@ -28,6 +31,7 @@ require 'cmdparse2'
 
 include LdapShadows
 
+set_locale(locale)
 
 config_str = IO.read(File.join(LdapShadows::Config::CFG_DIR, "test.conf"))
 config = YAML.load(config_str)
@@ -76,8 +80,8 @@ begin
   end
   $ldapctl.load_relations
 rescue ActiveLdap::Error => e
-  STDERR.puts "LDAP connection error: " + e.to_s
-  exit 3
+  STDERR.puts _("LDAP connection error: %s") % e.to_s
+  exit 2
 end
 
 
@@ -97,19 +101,12 @@ class Command < CmdParse::Command
   protected
 
   def params_shift_location(args)
-    if args.empty?
-      STDERR.puts "syntax error: no location name given"
-      exit 1
-    end
+    raise SyntaxError, _("no location name given") if args.empty?
 
     location = args.shift.downcase
-    if location =~ /^([a-zA-Z]+)\/(.+)$/
-      loc_obj_hdl = $1
-      loc_item_hdl = $2
-    else
-      STDERR.puts "syntax error: bad location"
-      exit 1
-    end
+    raise SyntaxError, _("bad location") unless location =~ /^([a-zA-Z]+)\/(.+)$/
+    loc_obj_hdl = $1
+    loc_item_hdl = $2
 
     split_args = [loc_obj_hdl, loc_item_hdl]
     loc_obj_klass = params_shift_object(split_args)
@@ -119,25 +116,16 @@ class Command < CmdParse::Command
   end
 
   def params_shift_object(args)
-    if args.empty?
-      STDERR.puts "syntax error: no object name given"
-      exit 1
-    end
+    raise SyntaxError, _("no object name given") if args.empty?
 
     obj_hdl = args.shift.downcase.singularize
     obj_klass = $ldapctl.find_klass(obj_hdl)
-    if obj_klass.nil?
-      STDERR.puts "No such object '#{obj_hdl}'."
-      exit 2
-    end
+    raise PreProcessingError, _("No such object '%s'") % obj_hdl if obj_klass.nil?
     obj_klass
   end
 
   def params_shift_item(obj_klass, args, with_expert = false)
-    if args.empty?
-      STDERR.puts "syntax error: no item name given"
-      exit 1
-    end
+    raise SyntaxError, _("no item name given") if args.empty?
 
     attr_list = ["*"]
     attr_list << "+" if $program_options[:expert] and with_expert # add operational attributes if expert
@@ -146,8 +134,7 @@ class Command < CmdParse::Command
     begin
       item = obj_klass.find(item_hdl, :attributes => attr_list)
     rescue ActiveLdap::EntryNotFound
-      STDERR.puts "No such item '#{obj_klass.handle}/#{item_hdl}'"
-      exit 2
+      raise PreProcessingError, _("No such item '%s/%s'") % [obj_klass.handle, item_hdl]
     end
     item
   end
@@ -167,10 +154,7 @@ class ListCommand < Command
   end
 
   def execute (args)
-    if args.size < 1
-      STDERR.puts "syntax error: no object name given"
-      exit 1
-    end
+    raise SyntaxError, _("no object name given") if args.empty?
 
     obj_hdl = args.shift.downcase.singularize
     case obj_hdl
@@ -219,8 +203,7 @@ class ListCommand < Command
             end
           end
         else
-          STDERR.puts "No such subobject '#{subobj_hdl}'."
-          exit 2
+          raise PreProcessingError, _("No such subobject '%s'") % subobj_hdl
         end
       end
     end
@@ -252,12 +235,11 @@ class ShowCommand < Command
       field_name, file_no = field_info.split("#")
 
       unless item.has_field?(field_name)
-        STDERR.puts "No such field '#{field_name}' in object '#{obj_klass.handle}'."
-        exit 2
+        raise PreProcessingError, _("No such field '%s' in object '%s'") % [field_name, obj_klass.handle]
       end
       unless item.attribute_present?(field_name)
-        STDERR.puts "Field '#{field_name}' in item '#{obj_klass.handle}/#{item.name}' is not present."
-        exit 2
+        raise PreProcessingError, _("Field '%s' in item '%s/%s' is not present") %
+          [field_name, obj_klass.handle, item.name]
       end
 
       field_data = item.send(field_name, true)
@@ -273,18 +255,18 @@ class ShowCommand < Command
 
         field_single = attr_info.single_value?
         if file_no.nil? and not field_single
-          STDERR.puts "Field '#{field_name}' in object '#{obj_klass.handle}' has multiple values, but you didn't select one."
-          exit 2
+          raise PreProcessingError, _("Field '%s' in object '%s' has multiple values, but you didn't select one") %
+            [field_name, obj_klass.handle]
         end
 
         file_no = 0 if file_no.nil?
         if file_no > 0 and field_single
-          STDERR.puts "Field '#{field_name}' in object '#{obj_klass.handle}' has only a single value"
-          exit 2
+          raise PreProcessingError, _("Field '%s' in object '%s' has only a single value") %
+            [field_name, obj_klass.handle]
         end
         if file_no < 0 or file_no >= field_data.size
-          STDERR.puts "Field '#{field_name}' in object '#{obj_klass.handle}' doesn't have such file number '#{file_no}' (select in range [0, #{field_data.size - 1}])"
-          exit 2
+          raise PreProcessingError, _("Field '%s' in object '%s' doesn't have such file number '%s' (select in range [0, %s])") %
+            [field_name, obj_klass.handle, file_no, field_data.size - 1]
         end
 
         result = field_data[file_no]
@@ -301,8 +283,7 @@ class ShowCommand < Command
       else
         file_name = args.shift
         if File.exists?(file_name)
-          STDERR.puts "File '#{file_name}' already exists, and i won't overwrite it."
-          exit 2
+          raise PreProcessingError, _("File '%s' already exists, and i won't overwrite it") % file_name
         end
 
         begin
@@ -310,8 +291,7 @@ class ShowCommand < Command
             fp.write result
           end
         rescue
-          STDERR.puts "Cannot save file: " + $!
-          exit 3
+          raise ProcessingError, _("Cannot save file: %s") % $!
         end
 
         puts "File saved."
@@ -354,8 +334,7 @@ class TreeCommand < Command
       (gconfig[:tree_objects] || []).each do |obj_hdl|
         obj_klass = $ldapctl.find_klass(obj_hdl.downcase)
         unless obj_klass
-          STDERR.puts "Location object '#{obj_hdl}' not defined."
-          exit 2
+          raise PreProcessingError, _("Location object '%s' not defined") % obj_hdl
         end
 
         obj_klass.find(:all, :base => search_base, :scope => :sub).each do |obj|
@@ -399,16 +378,13 @@ class ModCommand < Command
 
     modification_done = false
     args.each do |mod_info|
-      mod_info =~ /^([a-zA-Z]*(?::[a-zA-Z]+)?)(=|\+=|-=)(.*)$/
+      unless mod_info =~ /^([a-zA-Z]*(?::[a-zA-Z]+)?)(=|\+=|-=)(.*)$/
+        raise SyntaxError, _("modification parameter '%s' is invalid") % mod_info
+      end
       key = $1
       op = $2
       val = $3
 
-      if key.nil? or op.nil?
-        STDERR.puts "Syntax error in modification parameters: invalid field name, or missing/unknown operator, or empty value" 
-        exit 1
-      end
-
       if key.index(":")
         type, field = key.split(":")
       else
@@ -419,67 +395,57 @@ class ModCommand < Command
       case type
       when nil
         unless item.has_field?(field)
-          STDERR.puts "No such field '#{field}' in object '#{obj_klass.handle}'." 
-          exit 2
+          raise PreProcessingError, _("No such field '%s' in object '%s'") % [field, obj_klass.handle]
         end
 
         attr_info = ActiveLdap::Base.schema.attribute(field)
         if attr_info.read_only?
-          STDERR.puts "The field '#{field}' cannot be modified (read only), skipping."
-          next
+          raise PreProcessingError, _("The field '%s' cannot be modified (read only)") % field
         end
 
         if attr_info.binary?
           unless File.exists?(val)
-            STDERR.puts "The field '#{field}' contains binary data, you must provide a filename instead of a direct value."
-            exit 2
+            raise PreProcessingError, _("The field '%s' contains binary data, you must provide a filename instead of a direct value") % field
           end
 
           begin
             val = File.read(val)
           rescue
-            STDERR.puts "The file for the binary field '#{field}' cannot be read: " + $!
-            exit 2
+            raise PreProcessingError, _("The file for the binary field '%s' cannot be read: ") % [field, $!]
           end
         end
         old_val = item.send(field, true)
       when 'rel'
         unless item.relations.include?(field)
-          STDERR.puts "No such relation '#{field}' for object '#{obj_klass.handle}'." 
-          exit 2
+          raise PreProcessingError, _("No such relation '%s' for object '%s'") % [field, obj_klass.handle]
         end
 
         rel_info = item.info_for_relation(field)
         if rel_info[:read_only]
-          STDERR.puts "The relation '#{field}' cannot be modified (read only), skipping."
-          next
+          raise PreProcessingError, _("The relation '%s' cannot be modified (read only)") % field
         end
 
         # fetch remote object in relation, which will be the real 'val'
         foreign_item_list = rel_info[:foreign_klass].find(:all, val)
         if foreign_item_list.empty?
-          STDERR.puts "Foreign item '#{val}' for relation '#{field}' not found."
-          exit 2
+          raise PreProcessingError, _("Foreign item '%s' for relation '%s' not found") % [val, field]
         end
         if foreign_item_list.size > 1
-          STDERR.puts "Ambiguous item '#{val}' for relation '#{field}' (#{foreign_item_list.size} possible items)"
-          exit 4
+          raise WeirdError, _("Ambiguous item '%s' for relation '%s' (%s possible items)") %
+            [val, field, foreign_item_list.size]
         end
         val = foreign_item_list.first
       when ''
         case field
         when 'aspects'
           unless item.class.possible_aspects.include?(val)
-            STDERR.puts "No such aspect '#{val}' for object '#{obj_klass.handle}'."
-            exit 2
+            raise PreProcessingError, _("No such aspect '%s' for object '%s'") [val, obj_klass.handle]
           end
         else
-          STDERR.puts "Unknown core field '#{field}'"
-          exit 2
+          raise PreProcessingError, _("Unknown core field '%s'") % field
         end
       else
-        STDERR.puts "Unknown type '#{type}' for field '#{field}'."
-        exit 2
+        raise PreProcessingError, _("Unknown type '%s' for field '%s'") % [type, field]
       end
 
       # if val is nil or the latest value is removed, then the atribute is removed from the object,
@@ -487,24 +453,21 @@ class ModCommand < Command
       case op
       when '='
         if type == '' and field == 'aspects'
-          STDERR.puts "The equality operator is not possible for aspects."
-          exit 2
+          raise PreProcessingError, _("The equality operator is not possible for aspects")
         end
         item.send(field + "=", [val])
       when '+='
         case type
         when nil
           if attr_info.single_value?
-            STDERR.puts "The field '#{field}' cannot hold more than one value."
-            exit 3
+            raise PreProcessingError, _("The field '%s' cannot hold more than one value") % field
           end
 
           new_val = old_val << val
           item.send(field + "=", new_val)
         when 'rel'
           if rel_info[:single_value]
-            STDERR.puts "The relation '#{field}' cannot hold more than one foreign item."
-            exit 3
+            raise PreProcessingError, _("The relation '%s' cannot hold more than one foreign item") % field
           end
 
           item.send(field) << val
@@ -527,9 +490,6 @@ class ModCommand < Command
             item.remove_aspect(val)
           end
         end
-      else
-        STDERR.puts "Syntax error in modification parameters: wrong operator"
-        exit 1
       end
       modification_done = true
     end
@@ -542,21 +502,17 @@ class ModCommand < Command
       # and exceptions caught in a centralized place in this file.
       missing_fields = []
       unless missing_fields.empty?
-        STDERR.puts "Cannot save the modifications; the following fields are missing:"
+        miss_str = []
         missing_fields.each do |field|
           str = Translator.translate_field_name(field)
           str += " [#{field}]" if $program_options[:handles]
-          puts "  - #{str}"
+          miss_str << str
         end
-        exit 2
+        raise PreProcessingError, _("Cannot save the modifications; the following fields are missing: %s") %
+          miss_str.join(", ")
       end
 
-      begin
-        item.save!
-      rescue ActiveLdap::OperationNotPermitted => e
-        STDERR.puts "You don't have enough rights to modify--at least--one of these attributes."
-        exit 3
-      end
+      item.save!
 
       puts "Modification done."
     else
@@ -607,10 +563,7 @@ class CreateCommand < Command
   def execute (args)
     obj_klass = params_shift_object(args)
 
-    if args.empty?
-      STDERR.puts "syntax error: no item name given"
-      exit 1
-    end
+    raise SyntaxError, _("no item name given") if args.empty?
     item_hdl = args.shift.downcase
 
     loc_obj_klass, loc_item = params_shift_location(args)
@@ -619,41 +572,32 @@ class CreateCommand < Command
     item.base = loc_item.dn_obj - obj_klass.base_obj
 
     args.each do |param|
-      param =~ /^([a-zA-Z]+)=(.*)$/
+      raise SyntaxError, _("creation parameter '%s' is invalid") % param unless param =~ /^([a-zA-Z]+)=(.*)$/
       key = $1
       val = $2
 
       val = nil if val == ''
 
-      if key.nil?
-        STDERR.puts "Syntax error in creation parameters: invalid field name"
-        exit 1
-      end
-
       field = key
 
       unless item.has_field?(field)
-        STDERR.puts "No such field '#{field}' in object '#{obj_klass.handle}'."
-        exit 2
+        raise PreProcessingError, _("No such field '%s' in object '%s'") % [field, obj_klass.handle]
       end
 
       attr_info = ActiveLdap::Base.schema.attribute(field)
       if attr_info.read_only?
-        STDERR.puts "The field '#{field}' cannot be modified (read only), skipping."
-        next
+        raise PreProcessingError, _("The field '%s' cannot be modified (read only)") % field
       end
 
       if attr_info.binary?
         unless File.exists?(val)
-          STDERR.puts "The field '#{field}' contains binary data, you must provide a filename instead of a direct value."
-          exit 2
+          raise PreProcessingError, _("The field '%s' contains binary data, you must provide a filename instead of a direct value") % field
         end
 
         begin
           val = File.read(val)
         rescue
-          STDERR.puts "The file for the binary field '#{field}' cannot be read: " + $!
-          exit 2
+          raise PreProcessingError, _("The file for the binary field '%s' cannot be read: %s") % [field, $!]
         end
       end
 
@@ -662,13 +606,14 @@ class CreateCommand < Command
 
     missing_fields = item.missing_attributes
     unless missing_fields.empty?
-      STDERR.puts "Cannot save the new item; the following fields are missing:"
+      miss_str = []
       missing_fields.each do |field|
         str = Translator.translate_field_name(field)
         str += " [#{field}]" if $program_options[:handles]
-        puts "  - #{str}"
+        miss_str << str
       end
-      exit 2
+      raise PreProcessingError, _("Cannot save the new item; the following fields are missing: %s") %
+        miss_str.join(", ")
     end
 
     item.save!
@@ -679,14 +624,23 @@ cmdparser.add_command(CreateCommand.new)
 
 begin
   cmdparser.parse
+rescue SyntaxError => e
+  STDERR.puts _("Syntax error: %s") % e.to_s
+  exit 1
+rescue PreProcessingError => e
+  STDERR.puts _("Preprocessing error: %s") % e.to_s
+  exit 2
 rescue ActiveLdap::EntryInvalid => e
-  # work around activeldap#26758
+  # work around activeldap#26758 (for english output only :-/)
   STDERR.puts e.to_s.sub(/invalid format: .*: required syntax:/, "invalid format. required syntax:")
   exit 3
 rescue ActiveLdap::OperationNotPermitted => e
-  STDERR.puts "You don't have enough rights for this operation."
+  STDERR.puts _("You don't have enough rights for this operation")
   exit 3
 rescue ActiveLdap::Error => e
-  STDERR.puts "LDAP error: " + e.to_s
+  STDERR.puts _("LDAP error: %s") % e.to_s
   exit 3
+rescue WeirdError =>e
+  STDERR.puts _("Weird error: %s") % e.to_s
+  exit 4
 end
diff --git a/lib/ldap_shadows.rb b/lib/ldap_shadows.rb
index dce0b82..af2f18d 100644
--- a/lib/ldap_shadows.rb
+++ b/lib/ldap_shadows.rb
@@ -19,5 +19,15 @@
 require 'ldap_shadows/info'
 require 'ldap_shadows/config'
 require 'ldap_shadows/lang_additions'
+require 'ldap_shadows/exceptions'
 require 'ldap_shadows/controller'
+require 'gettext'
 
+
+module LdapShadows
+  include GetText
+  ENV['LC_ALL'] = "C"
+  bindtextdomain('ldapshadows', {:path => Config::L10N_DIR, :charset => "UTF-8"})
+  # default locale
+  set_locale('en')
+end
diff --git a/lib/ldap_shadows/exceptions.rb b/lib/ldap_shadows/exceptions.rb
new file mode 100644
index 0000000..990cb6c
--- /dev/null
+++ b/lib/ldap_shadows/exceptions.rb
@@ -0,0 +1,43 @@
+#--
+# LdapShadows, a Medium-level LDAP Access Library and Tool.
+# Copyright (c) 2009 Marc Dequènes (Duck) <Duck@DuckCorp.org>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#++
+
+
+module LdapShadows
+  class Error < StandardError
+  end
+
+  # when arguments are missing or abviously not well formated
+  class SyntaxError < Error
+  end
+
+  # when arguments, configuration, and database, don't get on well
+  # (when called with a proper object name which don't exist in the
+  #  config for example)
+  class PreProcessingError < Error
+  end
+
+  # when one of the needed operations fail
+  # (unreadable config file, database error, ...)
+  class ProcessingError < Error
+  end
+
+  # for strange things
+  # (like when fetching contradictory data)
+  class WeirdError < Error
+  end
+end
diff --git a/po/ldapshadows.pot b/po/ldapshadows.pot
new file mode 100644
index 0000000..1cac731
--- /dev/null
+++ b/po/ldapshadows.pot
@@ -0,0 +1,181 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: LDAP Shadows 0.1.0~dev\n"
+"POT-Creation-Date: 2009-07-30 23:34+0200\n"
+"PO-Revision-Date: 2009-07-30 23:34+0200\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
+
+#: lib/ldap_shadows/object.rb:89
+msgid "%{fn} is required attribute by objectClass '%s'"
+msgstr ""
+
+#: lib/ldap_shadows/object.rb:91
+msgid "%{fn} is required attribute by objectClass '%s': aliases: %s"
+msgstr ""
+
+#: bin/shadowwalker:83
+msgid "LDAP connection error: %s"
+msgstr ""
+
+#: bin/shadowwalker:104
+msgid "no location name given"
+msgstr ""
+
+#: bin/shadowwalker:107
+msgid "bad location"
+msgstr ""
+
+#: bin/shadowwalker:119 bin/shadowwalker:157
+msgid "no object name given"
+msgstr ""
+
+#: bin/shadowwalker:123
+msgid "No such object '%s'"
+msgstr ""
+
+#: bin/shadowwalker:128 bin/shadowwalker:566
+msgid "no item name given"
+msgstr ""
+
+#: bin/shadowwalker:137
+msgid "No such item '%s/%s'"
+msgstr ""
+
+#: bin/shadowwalker:206
+msgid "No such subobject '%s'"
+msgstr ""
+
+#: bin/shadowwalker:238 bin/shadowwalker:398 bin/shadowwalker:584
+msgid "No such field '%s' in object '%s'"
+msgstr ""
+
+#: bin/shadowwalker:241
+msgid "Field '%s' in item '%s/%s' is not present"
+msgstr ""
+
+#: bin/shadowwalker:258
+msgid "Field '%s' in object '%s' has multiple values, but you didn't select one"
+msgstr ""
+
+#: bin/shadowwalker:264
+msgid "Field '%s' in object '%s' has only a single value"
+msgstr ""
+
+#: bin/shadowwalker:268
+msgid "Field '%s' in object '%s' doesn't have such file number '%s' (select in range [0, %s])"
+msgstr ""
+
+#: bin/shadowwalker:286
+msgid "File '%s' already exists, and i won't overwrite it"
+msgstr ""
+
+#: bin/shadowwalker:294
+msgid "Cannot save file: %s"
+msgstr ""
+
+#: bin/shadowwalker:337
+msgid "Location object '%s' not defined"
+msgstr ""
+
+#: bin/shadowwalker:382
+msgid "modification parameter '%s' is invalid"
+msgstr ""
+
+#: bin/shadowwalker:403 bin/shadowwalker:589
+msgid "The field '%s' cannot be modified (read only)"
+msgstr ""
+
+#: bin/shadowwalker:408 bin/shadowwalker:594
+msgid "The field '%s' contains binary data, you must provide a filename instead of a direct value"
+msgstr ""
+
+#: bin/shadowwalker:414
+msgid "The file for the binary field '%s' cannot be read: "
+msgstr ""
+
+#: bin/shadowwalker:420
+msgid "No such relation '%s' for object '%s'"
+msgstr ""
+
+#: bin/shadowwalker:425
+msgid "The relation '%s' cannot be modified (read only)"
+msgstr ""
+
+#: bin/shadowwalker:431
+msgid "Foreign item '%s' for relation '%s' not found"
+msgstr ""
+
+#: bin/shadowwalker:434
+msgid "Ambiguous item '%s' for relation '%s' (%s possible items)"
+msgstr ""
+
+#: bin/shadowwalker:442
+msgid "No such aspect '%s' for object '%s'"
+msgstr ""
+
+#: bin/shadowwalker:445
+msgid "Unknown core field '%s'"
+msgstr ""
+
+#: bin/shadowwalker:448
+msgid "Unknown type '%s' for field '%s'"
+msgstr ""
+
+#: bin/shadowwalker:456
+msgid "The equality operator is not possible for aspects"
+msgstr ""
+
+#: bin/shadowwalker:463
+msgid "The field '%s' cannot hold more than one value"
+msgstr ""
+
+#: bin/shadowwalker:470
+msgid "The relation '%s' cannot hold more than one foreign item"
+msgstr ""
+
+#: bin/shadowwalker:511
+msgid "Cannot save the modifications; the following fields are missing: %s"
+msgstr ""
+
+#: bin/shadowwalker:575
+msgid "creation parameter '%s' is invalid"
+msgstr ""
+
+#: bin/shadowwalker:600
+msgid "The file for the binary field '%s' cannot be read: %s"
+msgstr ""
+
+#: bin/shadowwalker:615
+msgid "Cannot save the new item; the following fields are missing: %s"
+msgstr ""
+
+#: bin/shadowwalker:628
+msgid "Syntax error: %s"
+msgstr ""
+
+#: bin/shadowwalker:631
+msgid "Preprocessing error: %s"
+msgstr ""
+
+#: bin/shadowwalker:638
+msgid "You don't have enough rights for this operation"
+msgstr ""
+
+#: bin/shadowwalker:641
+msgid "LDAP error: %s"
+msgstr ""
+
+#: bin/shadowwalker:644
+msgid "Weird error: %s"
+msgstr ""
